FOP-3009: Avoid merging fonts with different number of cmap formats

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1889104 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java b/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java
index 10ac275..b68c77c 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java
@@ -105,7 +105,7 @@
             Set<Integer> codeToName = getCodeToName(font.getEncoding()).keySet();
             for (int i = getFirstChar();
                  i <= Math.min(getLastChar(), getFirstChar() + font.getWidths().size()); i++) {
-                if (usesZero || codeToName.contains(i)) {
+                if (usesZero || codeToName.contains(i) || codeToName.isEmpty()) {
                     int w = font.getWidths().get(i - getFirstChar());
                     newWidth.put(i, w);
                 } else {
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java b/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
index 3e2e0ae..288f058 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
@@ -181,11 +181,15 @@
                 }
             } else if (font instanceof PDTrueTypeFont && isSubsetFont(font.getName())) {
                 TrueTypeFont tt = ((PDTrueTypeFont) font).getTrueTypeFont();
-                for (CmapSubtable c : tt.getCmap().getCmaps()) {
+                CmapSubtable[] cmaps = tt.getCmap().getCmaps();
+                for (CmapSubtable c : cmaps) {
                     if (c.getGlyphId(1) > 0) {
                         extra = "cid";
                     }
                 }
+                if (cmaps.length != 2) {
+                    extra += "cmap" + cmaps.length;
+                }
                 return name + extra;
             } else if (font instanceof PDType1CFont) {
                 return getNamePDType1Font(name, (PDType1CFont) font);
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 7f6fdd4..e0dffd0 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
@@ -18,6 +18,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -351,52 +352,50 @@
         }
 
         for (Cmap cmap : cmaps) {
-            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;
+            if (cmap.platformId == 1 && cmaps.size() == 1) {
+                writeUShort(6); //subtableFormat
+                int firstCode = -1;
+                int lastCode = -1;
+                List<Integer> codes = new ArrayList<Integer>();
+                for (Map.Entry<Integer, Integer> g : cmap.glyphIdToCharacterCode.entrySet()) {
+                    if (firstCode < 0) {
+                        firstCode = g.getKey();
+                    }
+                    while (lastCode > 0 && lastCode + 1 < g.getKey()) {
+                        codes.add(0);
+                        lastCode++;
+                    }
+                    codes.add(g.getValue());
+                    lastCode = g.getKey();
+                }
+                writeUShort((codes.size() * 2) + 6); //length
+                writeUShort(0); //version
+                writeUShort(firstCode); //firstCode
+                writeUShort(codes.size()); //entryCount
+                for (int i : codes) {
+                    writeUShort(i);
+                }
+            } 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;
+                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(6); //subtableFormat
-//            int firstCode = -1;
-//            int lastCode = -1;
-//            List<Integer> codes = new ArrayList<Integer>();
-//            for (Map.Entry<Integer, Integer> g : glyphIdToCharacterCode.entrySet()) {
-//                if (firstCode < 0) {
-//                    firstCode = g.getKey();
-//                }
-//                while (lastCode > 0 && lastCode + 1 < g.getKey()) {
-//                    codes.add(0);
-//                    lastCode++;
-//                }
-//                codes.add(g.getValue());
-//
-//                lastCode = g.getKey();
-//            }
-//
-//            writeUShort((codes.size() * 2) + 6); //length
-//            writeUShort(0); //version
-//
-//            writeUShort(firstCode); //firstCode
-//            writeUShort(codes.size()); //entryCount
-//
-//            for (int i : codes) {
-//                writeUShort(i);
-//            }
-
         updateCheckSum(checksum, currentPos - cmapPos, OFTableName.CMAP);
         realSize += currentPos - cmapPos;
     }
diff --git a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
index bbfcc13..f148c9a 100644
--- a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
@@ -152,9 +152,9 @@
         msg = writeText(fi, TTSubset2);
         Assert.assertTrue(msg, msg.contains("(t)-0.168 (e)-0.1523 (s)0.1528 (t)"));
         msg = writeText(fi, TTSubset3);
-        Assert.assertTrue(msg, msg.contains("[<0001>3 <0002>-7 <0003>] TJ"));
+        Assert.assertTrue(msg, msg.contains("[<01>3 <02>-7 <03>] TJ"));
         msg = writeText(fi, TTSubset5);
-        Assert.assertTrue(msg, msg.contains("[<0003>2 <0004>-7 <0007>] TJ"));
+        Assert.assertTrue(msg, msg.contains("[(\u0001)2 (\u0002)-7 (\u0003)] TJ"));
         msg = writeText(fi, TTCID1);
         Assert.assertTrue(msg, msg.contains("<0028003B0034003000420034>"));
         msg = writeText(fi, TTCID2);
@@ -714,4 +714,11 @@
         pdfdoc.output(bos);
         Assert.assertTrue(bos.toString("UTF-8").contains("/Filter /DCTDecode"));
     }
+
+    @Test
+    public void testCmapLengthInName() throws IOException {
+        FontInfo fi = new FontInfo();
+        String msg = writeText(fi, TTSubset3);
+        Assert.assertTrue(msg, msg.contains("/ArialMT_TrueTypecidcmap1"));
+    }
 }