From 6696559fc657aa3d83b868c337ced59e6a44ca7b Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Mon, 24 Apr 2023 12:27:09 +0100 Subject: [PATCH] FOP-3129: Symbol font was not being mapped to unicode --- .../apache/fop/fonts/truetype/OpenFont.java | 28 ++++++++------ .../fop/fonts/truetype/TTFFileTestCase.java | 37 +++++++++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OpenFont.java b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OpenFont.java index 0d10129f0..95113f407 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OpenFont.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OpenFont.java @@ -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 v = ansiIndex.get(j); @@ -612,6 +602,8 @@ public abstract class OpenFont { + mtxTab.length); } + mapSymbol(encodingID, j, eightBitGlyphs, glyphIdx); + // Also add winAnsiWidth List 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)); } diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java index 061353abb..089be2372 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java @@ -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); + } } -- 2.39.5