FOP-2687: NPE for merge fonts in pdf with accessibility

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1781906 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java b/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java
index d4a339b..db8ba37 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java
@@ -105,9 +105,9 @@
         }
         CMap c = font.getToUnicodeCMap();
         Map<Integer, String> mapping = getMapping(font, c, glyphData.length);
-        //if (glyphData.length > 0 && differentGlyphData(glyphData, mapping)) {
-        //    return null;
-        //}
+        if (glyphData.length > 0) {
+            differentGlyphData(glyphData, mapping);
+        }
         Map<Integer, String> gidToGlyph = new TreeMap<Integer, String>(mapping);
         if (font.font instanceof PDTrueTypeFont) {
             CmapSubtable cmap = ttf.getCmap().getCmaps()[0];
@@ -233,28 +233,31 @@
         return "SID" + index;
     }
 
-//        private boolean differentGlyphData(GlyphData[] data, Map<Integer, String> mapping) throws IOException {
-//            Map<String, Integer> tmpMap = new HashMap<String, Integer>();
-//            for (Map.Entry<Integer, String> entry : mapping.entrySet()) {
-//                if (!tmpMap.containsKey(entry.getValue())) {
-//                    tmpMap.put(entry.getValue(), entry.getKey());
-//                }
-//            }
-//            mapping.clear();
-//            for (Map.Entry<String, Integer> entry : tmpMap.entrySet()) {
-//                mapping.put(entry.getValue(), entry.getKey());
-//            }
-//
-//            for (Map.Entry<Integer, String> n : mapping.entrySet()) {
+        private boolean differentGlyphData(GlyphData[] data, Map<Integer, String> mapping) throws IOException {
+            Map<String, Integer> tmpMap = new HashMap<String, Integer>();
+            for (Map.Entry<Integer, String> entry : mapping.entrySet()) {
+                if (!tmpMap.containsKey(entry.getValue())) {
+                    tmpMap.put(entry.getValue(), entry.getKey());
+                }
+            }
+            mapping.clear();
+            for (Map.Entry<String, Integer> entry : tmpMap.entrySet()) {
+                mapping.put(entry.getValue(), entry.getKey());
+            }
+
+            for (Map.Entry<Integer, String> n : mapping.entrySet()) {
+                if (n.getKey() >= data.length) {
+                    throw new IOException("Mapping not found in glyphData");
+                }
 //                if (data[n.getKey()] != null) {
 //                    if (glyphs.containsKey(n.getValue()) && !glyphs.get(n.getValue()).equals(data[n.getKey()])) {
 //                        return true;
 //                    }
 //                    glyphs.put(n.getValue(), data[n.getKey()]);
 //                }
-//            }
-//            return false;
-//        }
+            }
+            return false;
+        }
 
     private InputStream readFontFile(PDFont font) throws IOException {
         PDFontDescriptor fd = font.getFontDescriptor();
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/FontContainer.java b/src/java/org/apache/fop/render/pdf/pdfbox/FontContainer.java
index 1645916..fb98c0e 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/FontContainer.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/FontContainer.java
@@ -137,4 +137,8 @@
         BoundingBox bb = font.getBoundingBox();
         return new float[] {bb.getLowerLeftX(), bb.getLowerLeftY(), bb.getUpperRightX(), bb.getUpperRightY()};
     }
+
+    public PDFont getFont() {
+        return font;
+    }
 }
diff --git a/test/java/org/apache/fop/render/pdf/FOPPDFSingleMultiByteFontTestCase.java b/test/java/org/apache/fop/render/pdf/FOPPDFSingleMultiByteFontTestCase.java
index ba3d0dc..987317b 100644
--- a/test/java/org/apache/fop/render/pdf/FOPPDFSingleMultiByteFontTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/FOPPDFSingleMultiByteFontTestCase.java
@@ -28,15 +28,20 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.fontbox.cff.CFFFont;
 import org.apache.fontbox.cff.CFFParser;
+import org.apache.fontbox.ttf.GlyphData;
+import org.apache.fontbox.ttf.GlyphTable;
 import org.apache.fontbox.type1.Type1Font;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType2;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
 
 import org.apache.fop.render.pdf.pdfbox.FOPPDFMultiByteFont;
 import org.apache.fop.render.pdf.pdfbox.FOPPDFSingleByteFont;
+import org.apache.fop.render.pdf.pdfbox.FontContainer;
 
 public class FOPPDFSingleMultiByteFontTestCase {
     private COSDictionary getFont(PDDocument doc, String internalname) throws IOException {
@@ -160,4 +165,33 @@
         Assert.assertTrue(multiByteFont.hadMappingOperations());
         pdf.close();
     }
+
+    @Test
+    public void testMappingNotFound() throws IOException {
+        PDDocument pdf = PDDocument.load(new File(PDFBoxAdapterTestCase.TTCID1));
+        final COSDictionary fontDict = getFont(pdf, "C2_0");
+        MyFOPPDFMultiByteFont multiByteFont = new MyFOPPDFMultiByteFont(fontDict, null);
+        PDType0Font font = (PDType0Font) multiByteFont.getFontContainer().getFont();
+        GlyphTable glyphTable = ((PDCIDFontType2)font.getDescendantFont()).getTrueTypeFont().getGlyph();
+        glyphTable.setGlyphs(new GlyphData[glyphTable.getGlyphs().length - 1]);
+        String ex = "";
+        try {
+            multiByteFont.addFont(fontDict);
+        } catch (IOException e) {
+            ex = e.getMessage();
+        }
+        Assert.assertEquals(ex, "Mapping not found in glyphData");
+        pdf.close();
+    }
+
+    private static class MyFOPPDFMultiByteFont extends FOPPDFMultiByteFont {
+        COSDictionary fontData;
+        MyFOPPDFMultiByteFont(COSDictionary fontData, String name) throws IOException {
+            super(fontData, name);
+            this.fontData = fontData;
+        }
+        FontContainer getFontContainer() throws IOException {
+            return getFont(fontData);
+        }
+    }
 }