Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issues #608 / #405 (too many temporary files) by avoiding to call Font.createFont with inputstream #612

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import java.awt.FontFormatException;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.CharacterIterator;

import org.apache.batik.gvt.font.GVTFont;
Expand Down Expand Up @@ -40,13 +44,45 @@ private static int toStyle(Float posture) {
? Font.ITALIC
: Font.PLAIN;
}


// generate a unique name for a given byte array.
private static final String fontHash(byte[] fontBytes) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(fontBytes);
return "openhtmlfont-cache-" + new BigInteger(1, hash).toString(16);
} catch (NoSuchAlgorithmException e) {
return null;
}
}

private static void tryToMoveAtomically(Path from, Path to) throws IOException {
try {
Files.move(from, to, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} catch (AtomicMoveNotSupportedException e) {
Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
}
}

private static final Path TMP_DIR = new File(System.getProperty("java.io.tmpdir")).toPath();

public OpenHtmlGvtFont(byte[] fontBytes, GVTFontFamily family, float size, Float fontWeight, Float fontStyle) throws FontFormatException {
Font font;

try {
font = Font.createFont(Font.TRUETYPE_FONT, new ByteArrayInputStream(fontBytes)).deriveFont(toFontWeight(fontWeight) | toStyle(fontStyle) , size);
String fontName = fontHash(fontBytes);
Path cachedFile = TMP_DIR.resolve(fontName);
//see issue #608 #405, Font.createFont(byte[]..) create for each invocation a temporary file which will be removed on close, this can fill up the
//temporary directory. With the following implementation, we keep the minimal amount of files
if (!Files.exists(cachedFile)) {
Path tmpFile = Files.createTempFile("openhtmlfont", "tobecopied");
Files.write(tmpFile, fontBytes);
tryToMoveAtomically(tmpFile, cachedFile);
Files.delete(tmpFile);
}
File cachedFontFile = cachedFile.toFile();
cachedFontFile.deleteOnExit(); // we ensure to remove the file in case of a previous crash
//
font = Font.createFont(Font.TRUETYPE_FONT, cachedFontFile).deriveFont(toFontWeight(fontWeight) | toStyle(fontStyle) , size);
} catch (IOException e) {
// Shouldn't happen
e.printStackTrace();
Expand Down