]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fixed a bug in TTF subsetting where a composite glyph could get remapped more than...
authorJeremias Maerki <jeremias@apache.org>
Tue, 26 Jul 2011 18:28:07 +0000 (18:28 +0000)
committerJeremias Maerki <jeremias@apache.org>
Tue, 26 Jul 2011 18:28:07 +0000 (18:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1151195 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
status.xml

index ee89d9303a3db7b67710004abfb422e803661229..9fcfe72cc7dd3aacbc5b1e200da12dadeb51111c 100644 (file)
@@ -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<Integer> getIncludedGlyphs(FontFileReader in, int glyphOffset,
                                      Integer glyphIdx) throws IOException {
-        List ret = new java.util.ArrayList();
+        List<Integer> ret = new java.util.ArrayList<Integer>();
         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<Long> remappedComposites = null;
+
     /**
      * Rewrite all compositepointers in glyphindex glyphIdx
-     *
      */
-    private void remapComposite(FontFileReader in, Map glyphs,
-                                int glyphOffset,
+    private void remapComposite(FontFileReader in, Map<Integer, Integer> glyphs,
+                                long glyphOffset,
                                 Integer glyphIdx) throws IOException {
-        int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset()
-                     + 10;
+        if (remappedComposites == null) {
+            remappedComposites = new java.util.HashSet<Long>();
+        }
+        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<Integer, Integer> glyphs) throws IOException {
+        TTFDirTabEntry glyfTable = (TTFDirTabEntry)dirTabs.get("glyf");
+        Map<Integer, Integer> newComposites = null;
+        Set<Integer> allComposites = new java.util.HashSet<Integer>();
 
         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<Integer, Integer>();
 
-                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<Integer> 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 {
index f234edfb504e36e080e60f203abadbeeb0aa599d..f9a949f6fa3d16d3346b55fd9395c72c32f2676a 100644 (file)
       documents. Example: the fix of marks layering will be such a case when it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Fonts" dev="JM" type="fix">
+        Fixed a bug in TTF subsetting where a composite glyph could get
+        remapped more than once resulting in garbled character.
+      </action>
       <action context="Fonts" dev="JM" type="fix" fixes-bug="50605">
         Fixed a number of bugs concerning Type 1 and other single-byte fonts
         (glyph width mismatches and overlapping characters).