You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by ss...@apache.org on 2023/10/24 13:02:26 UTC
[xmlgraphics-fop-pdf-images] branch main updated: FOP-3155: Use format 12 for unicode cmap
This is an automated email from the ASF dual-hosted git repository.
ssteiner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/xmlgraphics-fop-pdf-images.git
The following commit(s) were added to refs/heads/main by this push:
new 8f3e456 FOP-3155: Use format 12 for unicode cmap
8f3e456 is described below
commit 8f3e456c57fb353be3af59fed9ca4a703f4370db
Author: Simon Steiner <ss...@apache.org>
AuthorDate: Tue Oct 24 14:02:13 2023 +0100
FOP-3155: Use format 12 for unicode cmap
---
.../apache/fop/render/pdf/pdfbox/MergeTTFonts.java | 82 +++++++++++++--------
.../pdfbox/FOPPDFSingleMultiByteFontTestCase.java | 23 ++++++
.../render/pdf/pdfbox/PDFBoxAdapterTestCase.java | 1 +
.../apache/fop/render/pdf/pdfbox/ttsubset10.pdf | Bin 0 -> 68997 bytes
4 files changed, 77 insertions(+), 29 deletions(-)
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java b/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
index ea25a3c..d0bcff6 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
@@ -453,34 +453,54 @@ public class MergeTTFonts extends TTFSubSetFile implements MergeFonts {
}
for (Cmap cmap : cmaps) {
- writeUShort(4); //subtableFormat
- int segCount = cmap.glyphIdToCharacterCode.size() + 1;
- writeUShort(16 + (segCount * 8)); //length
- writeUShort(0); //lang
- writeUShort(segCount * 2); //segCountX2
- double searchRange = Math.pow(2, Math.floor(logBase2(segCount))) * 2;
- writeUShort((int) searchRange); //searchRange
- double entrySelector = Math.floor(logBase2(segCount));
- writeUShort((int) entrySelector); //entrySelector
- double rangeShift = (segCount * 2) - searchRange;
- writeUShort((int) rangeShift); //rangeShift
- for (int c : cmap.glyphIdToCharacterCode.keySet()) {
- writeUShort(c); //endCode
- }
- writeUShort(0xFFFF);
- writeUShort(0); //reservedPad
- for (int c : cmap.glyphIdToCharacterCode.keySet()) {
- writeUShort(c); //startCode
- }
- writeUShort(0);
- for (Map.Entry<Integer, Integer> entry : cmap.glyphIdToCharacterCode.entrySet()) {
- writeUShort(entry.getValue() - entry.getKey()); //idDelta
- }
- writeUShort(0);
- for (int g : cmap.glyphIdToCharacterCode.keySet()) {
- writeUShort(0); //idRangeOffsets
+ if (cmap.platformId != 0) {
+ writeUShort(4); //subtableFormat
+ int segCount = cmap.glyphIdToCharacterCode.size() + 1;
+ writeUShort(16 + (segCount * 8)); //length
+ writeUShort(0); //lang
+ writeUShort(segCount * 2); //segCountX2
+ double searchRange = Math.pow(2, Math.floor(logBase2(segCount))) * 2;
+ writeUShort((int) searchRange); //searchRange
+ double entrySelector = Math.floor(logBase2(segCount));
+ writeUShort((int) entrySelector); //entrySelector
+ double rangeShift = (segCount * 2) - searchRange;
+ writeUShort((int) rangeShift); //rangeShift
+ for (int c : cmap.glyphIdToCharacterCode.keySet()) {
+ writeUShort(c); //endCode
+ }
+ writeUShort(0xFFFF);
+ writeUShort(0); //reservedPad
+ for (int c : cmap.glyphIdToCharacterCode.keySet()) {
+ writeUShort(c); //startCode
+ }
+ writeUShort(0);
+ for (Map.Entry<Integer, Integer> entry : cmap.glyphIdToCharacterCode.entrySet()) {
+ writeUShort(entry.getValue() - entry.getKey()); //idDelta
+ }
+ writeUShort(0);
+ for (int g : cmap.glyphIdToCharacterCode.keySet()) {
+ writeUShort(0); //idRangeOffsets
+ }
+ writeUShort(0);
+ } else {
+ writeUShort(12); //subtableFormat
+ writeUShort(0);
+ writeULong(currentPos, (cmap.glyphIdToCharacterCode.size() * 12) + 16);
+ currentPos += 4;
+ writeULong(currentPos, 0);
+ currentPos += 4;
+ writeULong(currentPos, cmap.glyphIdToCharacterCode.size());
+ currentPos += 4;
+
+ for (Map.Entry<Integer, Integer> g : cmap.glyphIdToCharacterCode.entrySet()) {
+ writeULong(currentPos, g.getKey());
+ currentPos += 4;
+ writeULong(currentPos, g.getKey());
+ currentPos += 4;
+ writeULong(currentPos, g.getValue());
+ currentPos += 4;
+ }
}
- writeUShort(0);
}
updateCheckSum(checksum, currentPos - cmapPos, OFTableName.CMAP);
@@ -509,8 +529,12 @@ public class MergeTTFonts extends TTFSubSetFile implements MergeFonts {
int result = 0;
for (int i = 0; i < index; i++) {
Cmap curCmap = cmaps.get(i);
- int segCount = curCmap.glyphIdToCharacterCode.size() + 1;
- result += 16 + (segCount * 8); //length
+ if (curCmap.platformId != 0) {
+ int segCount = curCmap.glyphIdToCharacterCode.size() + 1;
+ result += 16 + (segCount * 8); //length
+ } else {
+ result += (curCmap.glyphIdToCharacterCode.size() * 12) + 16;
+ }
}
return result;
}
diff --git a/test/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleMultiByteFontTestCase.java b/test/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleMultiByteFontTestCase.java
index 8710bda..bba1cf3 100644
--- a/test/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleMultiByteFontTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleMultiByteFontTestCase.java
@@ -28,6 +28,7 @@ import org.junit.Test;
import org.apache.commons.io.IOUtils;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFParser;
+import org.apache.fontbox.ttf.CmapTable;
import org.apache.fontbox.ttf.GlyphData;
import org.apache.fontbox.ttf.GlyphTable;
import org.apache.fontbox.ttf.TTFParser;
@@ -217,4 +218,26 @@ public class FOPPDFSingleMultiByteFontTestCase {
return null;
}
}
+
+ @Test
+ public void testCmapFormat() throws Exception {
+ PDDocument doc = PDFBoxAdapterTestCase.load(PDFBoxAdapterTestCase.TTSubset10);
+ FOPPDFSingleByteFont sbfont = new FOPPDFSingleByteFont(getFont(doc, "F1"), "test");
+ byte[] bytes = IOUtils.toByteArray(sbfont.getInputStream());
+ TrueTypeFont trueTypeFont = new TTFParser().parse(new ByteArrayInputStream(bytes));
+ CmapTable ttfTable = (CmapTable) trueTypeFont.getTableMap().get("cmap");
+ Assert.assertEquals(ttfTable.getCmaps()[0].getPlatformId(), 0);
+ Assert.assertEquals(ttfTable.getCmaps()[1].getPlatformId(), 1);
+ Assert.assertEquals(ttfTable.getCmaps()[2].getPlatformId(), 3);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ bis.skip(ttfTable.getOffset() + 29);
+ Assert.assertEquals(bis.read(), 12); //subtableFormat
+ bis = new ByteArrayInputStream(bytes);
+ bis.skip(ttfTable.getOffset() + 465);
+ Assert.assertEquals(bis.read(), 4); //subtableFormat
+ bis = new ByteArrayInputStream(bytes);
+ bis.skip(ttfTable.getOffset() + 809);
+ Assert.assertEquals(bis.read(), 4); //subtableFormat
+ doc.close();
+ }
}
diff --git a/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
index 7721f4e..791ee25 100644
--- a/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
@@ -112,6 +112,7 @@ public class PDFBoxAdapterTestCase {
protected static final String TTSubset7 = "ttsubset7.pdf";
protected static final String TTSubset8 = "ttsubset8.pdf";
protected static final String TTSubset9 = "ttsubset9.pdf";
+ protected static final String TTSubset10 = "ttsubset10.pdf";
protected static final String CFFCID1 = "cffcid1.pdf";
protected static final String CFFCID2 = "cffcid2.pdf";
protected static final String Type1Subset1 = "t1subset.pdf";
diff --git a/test/resources/org/apache/fop/render/pdf/pdfbox/ttsubset10.pdf b/test/resources/org/apache/fop/render/pdf/pdfbox/ttsubset10.pdf
new file mode 100644
index 0000000..637ea9a
Binary files /dev/null and b/test/resources/org/apache/fop/render/pdf/pdfbox/ttsubset10.pdf differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org