From: Jeremias Maerki Date: Tue, 26 Jul 2011 18:28:07 +0000 (+0000) Subject: Fixed a bug in TTF subsetting where a composite glyph could get remapped more than... X-Git-Tag: fop-1_1rc1old~194 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=61bbd77c1e09ad8248d23241b91eb9674fa223a9;p=xmlgraphics-fop.git Fixed a bug in TTF subsetting where a composite glyph could get remapped more than once resulting in garbled character. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1151195 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java index ee89d9303..9fcfe72cc 100644 --- a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java +++ b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; /** @@ -469,9 +470,9 @@ public class TTFSubSetFile extends TTFFile { * Returns a List containing the glyph itself plus all glyphs * that this composite glyph uses */ - private List getIncludedGlyphs(FontFileReader in, int glyphOffset, + private List getIncludedGlyphs(FontFileReader in, int glyphOffset, Integer glyphIdx) throws IOException { - List ret = new java.util.ArrayList(); + List ret = new java.util.ArrayList(); ret.add(glyphIdx); int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() + 10; Integer compositeIdx = null; @@ -479,7 +480,7 @@ public class TTFSubSetFile extends TTFFile { boolean moreComposites = true; while (moreComposites) { flags = in.readTTFUShort(offset); - compositeIdx = new Integer(in.readTTFUShort(offset + 2)); + compositeIdx = Integer.valueOf(in.readTTFUShort(offset + 2)); ret.add(compositeIdx); offset += 4; @@ -509,15 +510,28 @@ public class TTFSubSetFile extends TTFFile { } + /** + * We need to remember which composites were already remapped because the value to be + * remapped is being read from the TTF file and being replaced right there. Doing this + * twice would create a bad map the second time. + */ + private Set remappedComposites = null; + /** * Rewrite all compositepointers in glyphindex glyphIdx - * */ - private void remapComposite(FontFileReader in, Map glyphs, - int glyphOffset, + private void remapComposite(FontFileReader in, Map glyphs, + long glyphOffset, Integer glyphIdx) throws IOException { - int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() - + 10; + if (remappedComposites == null) { + remappedComposites = new java.util.HashSet(); + } + TTFMtxEntry mtxEntry = mtxTab[glyphIdx.intValue()]; + long offset = glyphOffset + mtxEntry.getOffset() + 10; + if (remappedComposites.contains(offset)) { + return; + } + remappedComposites.add(offset); Integer compositeIdx = null; int flags = 0; @@ -525,8 +539,8 @@ public class TTFSubSetFile extends TTFFile { while (moreComposites) { flags = in.readTTFUShort(offset); - compositeIdx = new Integer(in.readTTFUShort(offset + 2)); - Integer newIdx = (Integer)glyphs.get(compositeIdx); + compositeIdx = Integer.valueOf(in.readTTFUShort(offset + 2)); + Integer newIdx = glyphs.get(compositeIdx); if (newIdx == null) { // This errormessage would look much better // if the fontname was printed to @@ -538,7 +552,7 @@ public class TTFSubSetFile extends TTFFile { continue; } - in.writeTTFUShort(offset + 2, newIdx.intValue()); + in.writeTTFUShort((int)(offset + 2), newIdx.intValue()); offset += 4; @@ -572,40 +586,41 @@ public class TTFSubSetFile extends TTFFile { * mapping */ private void scanGlyphs(FontFileReader in, - Map glyphs) throws IOException { - TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf"); - Map newComposites = null; - Map allComposites = new java.util.HashMap(); + Map glyphs) throws IOException { + TTFDirTabEntry glyfTable = (TTFDirTabEntry)dirTabs.get("glyf"); + Map newComposites = null; + Set allComposites = new java.util.HashSet(); int newIndex = glyphs.size(); - if (entry != null) { + if (glyfTable != null) { while (newComposites == null || newComposites.size() > 0) { // Inefficient to iterate through all glyphs - newComposites = new java.util.HashMap(); + newComposites = new java.util.HashMap(); - Iterator e = glyphs.keySet().iterator(); - while (e.hasNext()) { - Integer origIndex = (Integer)e.next(); - - if (in.readTTFShort(entry.getOffset() - + mtxTab[origIndex.intValue()].getOffset()) < 0) { + for (int origIndex : glyphs.keySet()) { + short numberOfContours = in.readTTFShort(glyfTable.getOffset() + + mtxTab[origIndex].getOffset()); + if (numberOfContours < 0) { // origIndex is a composite glyph - allComposites.put(origIndex, glyphs.get(origIndex)); - List composites - = getIncludedGlyphs(in, (int)entry.getOffset(), + allComposites.add(origIndex); + List composites + = getIncludedGlyphs(in, (int)glyfTable.getOffset(), origIndex); + if (log.isTraceEnabled()) { + log.trace("Glyph " + origIndex + + " is a composite glyph using the following glyphs: " + + composites); + } + // Iterate through all composites pointed to // by this composite and check if they exists // in the glyphs map, add them if not. - Iterator cps = composites.iterator(); - while (cps.hasNext()) { - Integer cIdx = (Integer)cps.next(); + for (int cIdx : composites) { if (glyphs.get(cIdx) == null && newComposites.get(cIdx) == null) { - newComposites.put(cIdx, - new Integer(newIndex)); + newComposites.put(cIdx, newIndex); newIndex++; } } @@ -613,18 +628,14 @@ public class TTFSubSetFile extends TTFFile { } // Add composites to glyphs - Iterator m = newComposites.keySet().iterator(); - while (m.hasNext()) { - Integer im = (Integer)m.next(); + for (int im : newComposites.keySet()) { glyphs.put(im, newComposites.get(im)); } } // Iterate through all composites to remap their composite index - Iterator ce = allComposites.keySet().iterator(); - while (ce.hasNext()) { - remapComposite(in, glyphs, (int)entry.getOffset(), - (Integer)ce.next()); + for (int glyphIdx : allComposites) { + remapComposite(in, glyphs, glyfTable.getOffset(), glyphIdx); } } else { diff --git a/status.xml b/status.xml index f234edfb5..f9a949f6f 100644 --- a/status.xml +++ b/status.xml @@ -60,6 +60,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Fixed a bug in TTF subsetting where a composite glyph could get + remapped more than once resulting in garbled character. + Fixed a number of bugs concerning Type 1 and other single-byte fonts (glyph width mismatches and overlapping characters).