diff options
author | Jeremias Maerki <jeremias@apache.org> | 2003-01-09 13:51:06 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2003-01-09 13:51:06 +0000 |
commit | 76d21bd6181bb35dba61cbfed18d4359e0179835 (patch) | |
tree | ec0ba6b145ae6c8453f2d309006125c31dca2bef /src/org/apache | |
parent | e2446a1cfb1f0f555684bc693cd07924b2ba0e29 (diff) | |
download | xmlgraphics-fop-76d21bd6181bb35dba61cbfed18d4359e0179835.tar.gz xmlgraphics-fop-76d21bd6181bb35dba61cbfed18d4359e0179835.zip |
Fixed bug #15877: ArrayIndexOutOfBoundException with certain TrueType fonts.
Reserved name indexes were not ignored.
Fixed ugly exception handling in TTFReader and PFMReader.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195838 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache')
-rw-r--r-- | src/org/apache/fop/fonts/apps/PFMReader.java | 19 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/apps/TTFReader.java | 24 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/truetype/TTFFile.java | 117 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/truetype/TTFMtxEntry.java | 23 |
4 files changed, 110 insertions, 73 deletions
diff --git a/src/org/apache/fop/fonts/apps/PFMReader.java b/src/org/apache/fop/fonts/apps/PFMReader.java index cb6cfb09c..4d6601a2c 100644 --- a/src/org/apache/fop/fonts/apps/PFMReader.java +++ b/src/org/apache/fop/fonts/apps/PFMReader.java @@ -15,13 +15,13 @@ import java.util.List; import java.util.Iterator; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; //Avalon -import org.apache.avalon.framework.CascadingRuntimeException; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.logger.ConsoleLogger; @@ -199,19 +199,16 @@ public class PFMReader extends AbstractLogEnabled { * @param doc The DOM Document to save. * @param target The target filename for the XML file. */ - public void writeFontXML(org.w3c.dom.Document doc, String target) { + public void writeFontXML(org.w3c.dom.Document doc, String target) + throws TransformerException { getLogger().info("Writing xml font file " + target + "..."); getLogger().info(""); - try { - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); - transformer.transform( - new javax.xml.transform.dom.DOMSource(doc), - new javax.xml.transform.stream.StreamResult(new File(target))); - } catch (Exception e) { - throw new CascadingRuntimeException("Error while serializing XML font metric file", e); - } + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.transform( + new javax.xml.transform.dom.DOMSource(doc), + new javax.xml.transform.stream.StreamResult(new File(target))); } /** diff --git a/src/org/apache/fop/fonts/apps/TTFReader.java b/src/org/apache/fop/fonts/apps/TTFReader.java index 424104bd9..afd10e8fa 100644 --- a/src/org/apache/fop/fonts/apps/TTFReader.java +++ b/src/org/apache/fop/fonts/apps/TTFReader.java @@ -13,13 +13,13 @@ import java.util.List; import java.util.Iterator; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; //Avalon -import org.apache.avalon.framework.CascadingRuntimeException; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.logger.ConsoleLogger; import org.apache.avalon.framework.logger.Logger; @@ -130,7 +130,7 @@ public class TTFReader extends AbstractLogEnabled { TTFReader app = new TTFReader(); app.enableLogging(log); - log.info("TTF Reader v1.1.3"); + log.info("TTF Reader v1.1.4"); if (options.get("-enc") != null) { String enc = (String)options.get("-enc"); @@ -222,19 +222,15 @@ public class TTFReader extends AbstractLogEnabled { * @param doc The DOM Document to save. * @param target The target filename for the XML file. */ - public void writeFontXML(org.w3c.dom.Document doc, String target) { + public void writeFontXML(org.w3c.dom.Document doc, String target) + throws TransformerException { getLogger().info("Writing xml font file " + target + "..."); - try { - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); - transformer.transform( - new javax.xml.transform.dom.DOMSource(doc), - new javax.xml.transform.stream.StreamResult(new File(target))); - } catch (Exception e) { - throw new CascadingRuntimeException( - "Error while serializing XML font metrics file", e); - } + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.transform( + new javax.xml.transform.dom.DOMSource(doc), + new javax.xml.transform.stream.StreamResult(new File(target))); } /** @@ -277,7 +273,7 @@ public class TTFReader extends AbstractLogEnabled { // "Perpetua-Bold", but the TrueType spec says that in the ttf file // it should be "Perpetua,Bold". - String s = stripWhiteSpace(ttf.getPostscriptName()); + String s = stripWhiteSpace(ttf.getPostScriptName()); if (fontName != null) { el.appendChild(doc.createTextNode(stripWhiteSpace(fontName))); diff --git a/src/org/apache/fop/fonts/truetype/TTFFile.java b/src/org/apache/fop/fonts/truetype/TTFFile.java index c62b52b51..1efe0f88c 100644 --- a/src/org/apache/fop/fonts/truetype/TTFFile.java +++ b/src/org/apache/fop/fonts/truetype/TTFFile.java @@ -172,10 +172,12 @@ public class TTFFile extends AbstractLogEnabled { int cmapEntrySelector = in.readTTFUShort(); int cmapRangeShift = in.readTTFUShort(); - getLogger().debug("segCountX2 : " + cmapSegCountX2); - getLogger().debug("searchRange : " + cmapSearchRange); - getLogger().debug("entrySelector: " + cmapEntrySelector); - getLogger().debug("rangeShift : " + cmapRangeShift); + if (getLogger().isDebugEnabled()) { + getLogger().debug("segCountX2 : " + cmapSegCountX2); + getLogger().debug("searchRange : " + cmapSearchRange); + getLogger().debug("entrySelector: " + cmapEntrySelector); + getLogger().debug("rangeShift : " + cmapRangeShift); + } int cmapEndCounts[] = new int[cmapSegCountX2 / 2]; @@ -247,36 +249,44 @@ public class TTFFile extends AbstractLogEnabled { ansiWidth[aIdx.intValue()] = mtxTab[glyphIdx].getWx(); - getLogger().debug("Added width " - + mtxTab[glyphIdx].getWx() - + " uni: " + j - + " ansi: " + aIdx.intValue()); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Added width " + + mtxTab[glyphIdx].getWx() + + " uni: " + j + + " ansi: " + aIdx.intValue()); + } } } - getLogger().debug("Idx: " - + glyphIdx - + " Delta: " + cmapDeltas[i] - + " Unicode: " + j - + " name: " + mtxTab[glyphIdx].getName()); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Idx: " + + glyphIdx + + " Delta: " + cmapDeltas[i] + + " Unicode: " + j + + " name: " + mtxTab[glyphIdx].getName()); + } } else { glyphIdx = (j + cmapDeltas[i]) & 0xffff; if (glyphIdx < mtxTab.length) { mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j)); } else { - getLogger().debug("Glyph " + glyphIdx + if (getLogger().isDebugEnabled()) { + getLogger().debug("Glyph " + glyphIdx + " out of range: " + mtxTab.length); + } } unicodeMapping.add(new UnicodeMapping(glyphIdx, j)); if (glyphIdx < mtxTab.length) { mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j)); } else { - getLogger().debug("Glyph " + glyphIdx + if (getLogger().isDebugEnabled()) { + getLogger().debug("Glyph " + glyphIdx + " out of range: " + mtxTab.length); + } } // Also add winAnsiWidth @@ -393,7 +403,7 @@ public class TTFFile extends AbstractLogEnabled { readHorizontalHeader(in); readHorizontalMetrics(in); initAnsiWidths(); - readPostscript(in); + readPostScript(in); readOS2(in); readIndexToLocation(in); readGlyf(in); @@ -453,7 +463,7 @@ public class TTFFile extends AbstractLogEnabled { * Returns the PostScript name of the font. * @return String The PostScript name */ - public String getPostscriptName() { + public String getPostScriptName() { if ("Regular".equals(subFamilyName) || "Roman".equals(subFamilyName)) { return familyName; } else { @@ -715,7 +725,7 @@ public class TTFFile extends AbstractLogEnabled { throws IOException { seekTab(in, "hmtx", 0); - int mtxSize = (numberOfGlyphs > nhmtx) ? numberOfGlyphs : nhmtx; + int mtxSize = Math.max(numberOfGlyphs, nhmtx); mtxTab = new TTFMtxEntry[mtxSize]; getLogger().debug("*** Widths array: \n"); @@ -726,8 +736,10 @@ public class TTFFile extends AbstractLogEnabled { mtxTab[i].setWx(in.readTTFUShort()); mtxTab[i].setLsb(in.readTTFUShort()); - getLogger().debug(" width[" + i + "] = " - + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";"); + if (getLogger().isDebugEnabled()) { + getLogger().debug(" width[" + i + "] = " + + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";"); + } } if (nhmtx < mtxSize) { @@ -743,12 +755,9 @@ public class TTFFile extends AbstractLogEnabled { /** * Read the "post" table - * containing the postscript names of the glyphs. + * containing the PostScript names of the glyphs. */ - private final void readPostscript(FontFileReader in) throws IOException { - String[] psGlyphsBuffer; - int i, k, l; - + private final void readPostScript(FontFileReader in) throws IOException { seekTab(in, "post", 0); postFormat = in.readTTFLong(); italicAngle = in.readTTFULong(); @@ -756,60 +765,74 @@ public class TTFFile extends AbstractLogEnabled { underlineThickness = in.readTTFShort(); isFixedPitch = in.readTTFULong(); + //Skip memory usage values in.skip(4 * 4); - getLogger().debug("Post format: " + postFormat); + getLogger().debug("PostScript format: " + postFormat); switch (postFormat) { case 0x00010000: - getLogger().debug("Postscript format 1"); - for (i = 0; i < Glyphs.MAC_GLYPH_NAMES.length; i++) { + getLogger().debug("PostScript format 1"); + for (int i = 0; i < Glyphs.MAC_GLYPH_NAMES.length; i++) { mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[i]); } break; case 0x00020000: - getLogger().debug("Postscript format 2"); + getLogger().debug("PostScript format 2"); int numGlyphStrings = 0; - l = in.readTTFUShort(); // Num Glyphs - // short minIndex=256; - for (i = 0; i < l; i++) { // Read indexes + + // Read Number of Glyphs + int l = in.readTTFUShort(); + + // Read indexes + for (int i = 0; i < l; i++) { mtxTab[i].setIndex(in.readTTFUShort()); - // if (minIndex > mtxTab[i].index) - // minIndex=(short)mtxTab[i].index; if (mtxTab[i].getIndex() > 257) { + //Index is not in the Macintosh standard set numGlyphStrings++; } - getLogger().debug("Post index: " + mtxTab[i].getIndex()); + if (getLogger().isDebugEnabled()) { + getLogger().debug("PostScript index: " + mtxTab[i].getIndexAsString()); + } } + // firstChar=minIndex; - psGlyphsBuffer = new String[numGlyphStrings]; - getLogger().debug("Reading " + numGlyphStrings - + " glyphnames" + ", was n num glyphs=" + l); - for (i = 0; i < psGlyphsBuffer.length; i++) { + String[] psGlyphsBuffer = new String[numGlyphStrings]; + if (getLogger().isDebugEnabled()) { + getLogger().debug("Reading " + numGlyphStrings + + " glyphnames, that are not in the standard Macintosh" + + " set. Total number of glyphs=" + l); + } + for (int i = 0; i < psGlyphsBuffer.length; i++) { psGlyphsBuffer[i] = in.readTTFString(in.readTTFUByte()); } - for (i = 0; i < l; i++) { + //Set glyph names + for (int i = 0; i < l; i++) { if (mtxTab[i].getIndex() < NMACGLYPHS) { mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[mtxTab[i].getIndex()]); } else { - k = mtxTab[i].getIndex() - NMACGLYPHS; + if (!mtxTab[i].isIndexReserved()) { + int k = mtxTab[i].getIndex() - NMACGLYPHS; - getLogger().debug(k + " i=" + i + " mtx=" + mtxTab.length - + " ps=" + psGlyphsBuffer.length); + if (getLogger().isDebugEnabled()) { + getLogger().debug(k + " i=" + i + " mtx=" + mtxTab.length + + " ps=" + psGlyphsBuffer.length); + } - mtxTab[i].setName(psGlyphsBuffer[k]); + mtxTab[i].setName(psGlyphsBuffer[k]); + } } } break; case 0x00030000: - // Postscript format 3 contains no glyph names - getLogger().debug("Postscript format 3"); + // PostScript format 3 contains no glyph names + getLogger().debug("PostScript format 3"); break; default: - getLogger().error("Unknown Postscript format: " + postFormat); + getLogger().error("Unknown PostScript format: " + postFormat); } } diff --git a/src/org/apache/fop/fonts/truetype/TTFMtxEntry.java b/src/org/apache/fop/fonts/truetype/TTFMtxEntry.java index 965844cc8..2e5bcdbd3 100644 --- a/src/org/apache/fop/fonts/truetype/TTFMtxEntry.java +++ b/src/org/apache/fop/fonts/truetype/TTFMtxEntry.java @@ -30,7 +30,7 @@ class TTFMtxEntry { * @return String String representation */ public String toString(TTFFile t) { - return "Glyph " + name + " index: " + index + " bbox [ " + return "Glyph " + name + " index: " + getIndexAsString() + " bbox [" + t.convertTTFUnit2PDFUnit(boundingBox[0]) + " " + t.convertTTFUnit2PDFUnit(boundingBox[1]) + " " + t.convertTTFUnit2PDFUnit(boundingBox[2]) + " " @@ -69,6 +69,27 @@ class TTFMtxEntry { public int getIndex() { return index; } + + /** + * Determines whether this index represents a reserved character. + * @return True if it is reserved + */ + public boolean isIndexReserved() { + return (getIndex() >= 32768) && (getIndex() <= 65535); + } + + /** + * Returns a String representation of the index taking into account if + * the index is in the reserved range. + * @return index as String + */ + public String getIndexAsString() { + if (isIndexReserved()) { + return Integer.toString(getIndex()) + " (reserved)"; + } else { + return Integer.toString(getIndex()); + } + } /** * Returns the lsb. |