diff options
author | Jeremias Maerki <jeremias@apache.org> | 2006-04-12 07:55:17 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2006-04-12 07:55:17 +0000 |
commit | 027ffa3e6e558b7c446ce3b02c5fd9d663aec9ff (patch) | |
tree | 6238ac18ee0d24735092b5eda24b8fa89f4a7e03 /src | |
parent | 112adcbbd38918874225593ce459fd99f4dae1b2 (diff) | |
download | xmlgraphics-fop-027ffa3e6e558b7c446ce3b02c5fd9d663aec9ff.tar.gz xmlgraphics-fop-027ffa3e6e558b7c446ce3b02c5fd9d663aec9ff.zip |
Bugfix: Fixed a division by zero problem in TTFReader popping up with arialuni.ttf.
Improved the detection of the capHeight and xHeight font metric values for TrueType fonts. Fonts that contain a version 3.0 PostScript table don't contain unicode glyph names. Without an xHeight value, super- and subscript does not work in FOP.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@393410 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/java/org/apache/fop/fonts/truetype/TTFFile.java | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java index d55581098..327917a9e 100644 --- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java +++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java @@ -130,7 +130,7 @@ public class TTFFile { if (n < 0) { long rest1 = n % upem; long storrest = 1000 * rest1; - long ledd2 = rest1 / storrest; + long ledd2 = (storrest != 0 ? rest1 / storrest : 0); ret = -((-1000 * n) / upem - (int)ledd2); } else { ret = (n / upem) * 1000 + ((n % upem) * 1000) / upem; @@ -427,7 +427,7 @@ public class TTFFile { readIndexToLocation(in); readGlyf(in); readName(in); - readPCLT(in); + boolean pcltFound = readPCLT(in); // Read cmap table and fill in ansiwidths boolean valid = readCMAP(in); if (!valid) { @@ -438,6 +438,9 @@ public class TTFFile { // print_max_min(); readKerning(in); + if (!pcltFound) { + guessPCLTValuesFromBBox(); + } return true; } @@ -1020,7 +1023,7 @@ public class TTFFile { * @param in FontFileReader to read from * @throws IOException In case of a I/O problem */ - private final void readPCLT(FontFileReader in) throws IOException { + private final boolean readPCLT(FontFileReader in) throws IOException { TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("PCLT"); if (dirTab != null) { in.seekSet(dirTab.getOffset() + 4 + 4 + 2); @@ -1037,22 +1040,51 @@ public class TTFFile { } else { hasSerifs = true; } + return true; } else { - // Approximate capHeight from height of "H" - // It's most unlikly that a font misses the PCLT table - // This also assumes that psocriptnames exists ("H") - // Should look it up int the cmap (that wouldn't help - // for charsets without H anyway...) - // Same for xHeight with the letter "x" - for (int i = 0; i < mtxTab.length; i++) { - if ("H".equals(mtxTab[i].getName())) { - capHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; - } - if ("x".equals(mtxTab[i].getName())) { - xHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + return false; + } + } + + private void guessPCLTValuesFromBBox() { + // Approximate capHeight from height of "H" + // It's most unlikly that a font misses the PCLT table + // This also assumes that postscriptnames exists ("H") + // Should look it up int the cmap (that wouldn't help + // for charsets without H anyway...) + // Same for xHeight with the letter "x" + boolean capHeightFound = false; + boolean xHeightFound = false; + for (int i = 0; i < mtxTab.length; i++) { + if ("H".equals(mtxTab[i].getName())) { + capHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + capHeightFound = true; + } else if ("x".equals(mtxTab[i].getName())) { + xHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + xHeightFound = true; + } else { + // OpenType Fonts with a version 3.0 "post" table don't have glyph names. + // Use Unicode indices instead. + List unicodeIndex = mtxTab[i].getUnicodeIndex(); + if (unicodeIndex.size() > 0) { + //Only the first index is used + char ch = (char)((Integer)unicodeIndex.get(0)).intValue(); + if (ch == 'H') { + capHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + capHeightFound = true; + } else if (ch == 'x') { + xHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + xHeightFound = true; + } } } } + if (!capHeightFound) { + log.warn("capHeight value could not be determined. The font may not work as expected."); + } + if (!xHeightFound) { + log.warn("xHeight value could not be determined. The font may not work as expected."); + } } /** |