]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3129: Symbol font was not being mapped to unicode
authorSimon Steiner <ssteiner@apache.org>
Mon, 24 Apr 2023 11:27:09 +0000 (12:27 +0100)
committerSimon Steiner <ssteiner@apache.org>
Mon, 24 Apr 2023 11:27:09 +0000 (12:27 +0100)
fop-core/src/main/java/org/apache/fop/fonts/truetype/OpenFont.java
fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java

index 0d10129f016f0167d302d8f61b8684ee55affa81..95113f40763c2b456360c7e7d63370c2ac26560f 100644 (file)
@@ -557,17 +557,7 @@ public abstract class OpenFont {
                             unicodeMappings.add(new UnicodeMapping(this, glyphIdx, j));
                             mtxTab[glyphIdx].getUnicodeIndex().add(j);
 
-                            if (encodingID == 0 && j >= 0xF020 && j <= 0xF0FF) {
-                                //Experimental: Mapping 0xF020-0xF0FF to 0x0020-0x00FF
-                                //Tested with Wingdings and Symbol TTF fonts which map their
-                                //glyphs in the region 0xF020-0xF0FF.
-                                int mapped = j - 0xF000;
-                                if (!eightBitGlyphs.get(mapped)) {
-                                    //Only map if Unicode code point hasn't been mapped before
-                                    unicodeMappings.add(new UnicodeMapping(this, glyphIdx, mapped));
-                                    mtxTab[glyphIdx].getUnicodeIndex().add(mapped);
-                                }
-                            }
+                            mapSymbol(encodingID, j, eightBitGlyphs, glyphIdx);
 
                             // Also add winAnsiWidth
                             List<Integer> v = ansiIndex.get(j);
@@ -612,6 +602,8 @@ public abstract class OpenFont {
                                                    + mtxTab.length);
                             }
 
+                            mapSymbol(encodingID, j, eightBitGlyphs, glyphIdx);
+
                             // Also add winAnsiWidth
                             List<Integer> v = ansiIndex.get(j);
                             if (v != null) {
@@ -727,6 +719,20 @@ public abstract class OpenFont {
         return true;
     }
 
+    private void mapSymbol(int encodingID, int unicodeIndex, BitSet eightBitGlyphs, int glyphIdx) {
+        if (encodingID == 0 && unicodeIndex >= 0xF020 && unicodeIndex <= 0xF0FF) {
+            /* Experimental: Mapping 0xF020-0xF0FF to 0x0020-0x00FF
+            Tested with Wingdings and Symbol TTF fonts which map their
+            glyphs in the region 0xF020-0xF0FF. */
+            int mapped = unicodeIndex - 0xF000;
+            if (!eightBitGlyphs.get(mapped)) {
+                //Only map if Unicode code point hasn't been mapped before
+                unicodeMappings.add(new UnicodeMapping(this, glyphIdx, mapped));
+                mtxTab[glyphIdx].getUnicodeIndex().add(mapped);
+            }
+        }
+    }
+
     private boolean isInPrivateUseArea(int start, int end) {
         return (isInPrivateUseArea(start) || isInPrivateUseArea(end));
     }
index 061353abb731e5cdab44e715f6e439d56f0e117f..089be2372f6bb5877f4778e146f263bb883e04df 100644 (file)
@@ -617,4 +617,41 @@ public class TTFFileTestCase {
         ttfFile.updateBBoxAndOffset();
         Assert.assertEquals(ttfFile.mtxTab[0].getBoundingBox()[0], 4);
     }
+
+    @Test
+    public void testSymbolCmap() throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(bos);
+        dos.writeShort(0);
+        dos.writeShort(1); //num tables
+        dos.writeShort(3); //cmapPID
+        dos.writeShort(0); //cmapEID
+        dos.writeInt(12); //cmapOffset
+        dos.writeShort(4); //cmapFormat
+        dos.writeShort(0); //skip cmap length
+        dos.writeShort(0); //skip cmap version
+        dos.writeShort(2); //cmapSegCountX2
+        dos.writeShort(0); //cmapSearchRange
+        dos.writeShort(0); //cmapEntrySelector
+        dos.writeShort(0); //cmapRangeShift
+        dos.writeShort(0xF020); //cmapEndCounts
+        dos.writeShort(0); //Skip reservedPad
+        dos.writeShort(0xF020); //cmapStartCounts
+        dos.writeShort(0); //cmapDeltas
+        dos.writeShort(0); //cmapRangeOffsets
+        TTFFile symbolTTFFile = new TTFFile();
+        symbolTTFFile.mtxTab = new OFMtxEntry[0xF020 + 1];
+        symbolTTFFile.mtxTab[0] = new OFMtxEntry();
+        symbolTTFFile.mtxTab[0xF020] = new OFMtxEntry();
+        symbolTTFFile.dirTabs = new HashMap<>();
+        symbolTTFFile.dirTabs.put(OFTableName.CMAP, new OFDirTabEntry());
+        symbolTTFFile.fontFile = new FontFileReader(new ByteArrayInputStream(bos.toByteArray()));
+        symbolTTFFile.initAnsiWidths();
+        symbolTTFFile.readCMAP();
+        Assert.assertEquals(symbolTTFFile.unicodeMappings.get(0).getUnicodeIndex(), 0xF020);
+        Assert.assertEquals(symbolTTFFile.unicodeMappings.get(0).getGlyphIndex(), 0xF020);
+        Assert.assertEquals(symbolTTFFile.unicodeMappings.get(1).getUnicodeIndex(), 32);
+        Assert.assertEquals(symbolTTFFile.unicodeMappings.get(1).getGlyphIndex(), 0xF020);
+        Assert.assertEquals(symbolTTFFile.unicodeMappings.size(), 2);
+    }
 }