You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2014/07/16 11:10:53 UTC

svn commit: r1610947 [1/2] - in /xmlgraphics/fop/trunk: ./ lib/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/fonts/cff/ src/java/org/apache/fop/fonts/truetype/ src/java/org/apache/fop/fonts/type1/ src/java/org/apache/fop/pdf/ src/java/org/apa...

Author: ssteiner
Date: Wed Jul 16 09:10:53 2014
New Revision: 1610947

URL: http://svn.apache.org/r1610947
Log:
Merge font merging

Added:
    xmlgraphics/fop/trunk/lib/fontbox-2.0.0-SNAPSHOT.jar
      - copied unchanged from r1610938, xmlgraphics/fop/branches/Temp_FontMerging/lib/fontbox-2.0.0-SNAPSHOT.jar
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFCFFStream.java
      - copied unchanged from r1610938, xmlgraphics/fop/branches/Temp_FontMerging/src/java/org/apache/fop/pdf/PDFCFFStream.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/RefPDFFont.java
      - copied unchanged from r1610938, xmlgraphics/fop/branches/Temp_FontMerging/src/java/org/apache/fop/pdf/RefPDFFont.java
Removed:
    xmlgraphics/fop/trunk/lib/fontbox-1.8.5.jar
Modified:
    xmlgraphics/fop/trunk/   (props changed)
    xmlgraphics/fop/trunk/findbugs-exclude.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontType.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/cff/CFFDataReader.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFFile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/PostscriptParser.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AbstractPDFStream.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSFontUtils.java
    xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/type1/Type1SubsetFileTestCase.java

Propchange: xmlgraphics/fop/trunk/
------------------------------------------------------------------------------
  Merged /xmlgraphics/fop/branches/Temp_FontMerging:r1600596-1610938

Modified: xmlgraphics/fop/trunk/findbugs-exclude.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/findbugs-exclude.xml?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/findbugs-exclude.xml (original)
+++ xmlgraphics/fop/trunk/findbugs-exclude.xml Wed Jul 16 09:10:53 2014
@@ -6009,4 +6009,11 @@
       <Method name="hasValueOfElementName"/>
       <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/>
    </Match>
+   <Match>
+     <Class name="org.apache.fop.pdf.PDFCFFStream"/>
+     <Or>
+        <Bug pattern="EI_EXPOSE_REP"/>
+        <Bug pattern="EI_EXPOSE_REP2"/>
+     </Or>
+   </Match>
 </FindBugsFilter>

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java Wed Jul 16 09:10:53 2014
@@ -22,9 +22,11 @@ package org.apache.fop.fonts;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -74,6 +76,8 @@ public abstract class CustomFont extends
     private Map<Integer, Map<Integer, Integer>> kerning;
 
     private boolean useKerning = true;
+    /** the character map, mapping Unicode ranges to glyph indices. */
+    protected List<CMapSegment> cmap = new ArrayList<CMapSegment>();
     private boolean useAdvanced = true;
 
     /**
@@ -82,8 +86,7 @@ public abstract class CustomFont extends
     public CustomFont(InternalResourceResolver resourceResolver) {
         this.resourceResolver = resourceResolver;
     }
-    /** the character map, mapping Unicode ranges to glyph indices. */
-    protected CMapSegment[] cmap;
+
 
     /** {@inheritDoc} */
     public String getFontName() {
@@ -503,8 +506,10 @@ public abstract class CustomFont extends
      * @param cmap the character map
      */
     public void setCMap(CMapSegment[] cmap) {
-        this.cmap = new CMapSegment[cmap.length];
-        System.arraycopy(cmap, 0, this.cmap, 0, cmap.length);
+        this.cmap.clear();
+        for (CMapSegment c : cmap) {
+            this.cmap.add(c);
+        }
     }
 
     /**
@@ -513,9 +518,7 @@ public abstract class CustomFont extends
      * @return the character map
      */
     public CMapSegment[] getCMap() {
-        CMapSegment[] copy = new CMapSegment[cmap.length];
-        System.arraycopy(this.cmap, 0, copy, 0, this.cmap.length);
-        return copy;
+        return cmap.toArray(new CMapSegment[cmap.size()]);
     }
 
     public int getUnderlinePosition(int size) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontType.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontType.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontType.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontType.java Wed Jul 16 09:10:53 2014
@@ -49,6 +49,10 @@ public class FontType {
      */
     public static final FontType TRUETYPE    = new FontType("TrueType", 5);
 
+    public static final FontType TYPE1C       = new FontType("Type1C", 6);
+
+    public static final FontType CIDTYPE0       = new FontType("CIDFontType0", 7);
+
     private final String name;
     private final int value;
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java Wed Jul 16 09:10:53 2014
@@ -20,6 +20,7 @@
 package org.apache.fop.fonts;
 
 import java.awt.Rectangle;
+import java.io.InputStream;
 import java.nio.CharBuffer;
 import java.nio.IntBuffer;
 import java.util.BitSet;
@@ -53,7 +54,7 @@ public class MultiByteFont extends CIDFo
     private int defaultWidth;
     private CIDFontType cidType = CIDFontType.CIDTYPE2;
 
-    private final CIDSet cidSet;
+    protected final CIDSet cidSet;
 
     /* advanced typographic support */
     private GlyphDefinitionTable gdef;
@@ -222,13 +223,13 @@ public class MultiByteFont extends CIDFo
         if (idx < NUM_MOST_LIKELY_GLYPHS && mostLikelyGlyphs[idx] != 0) {
             return mostLikelyGlyphs[idx];
         }
-        for (int i = 0; (i < cmap.length) && retIdx == 0; i++) {
-            if (cmap[i].getUnicodeStart() <= idx
-                    && cmap[i].getUnicodeEnd() >= idx) {
-
-                retIdx = cmap[i].getGlyphStartIndex()
+        for (CMapSegment i : cmap) {
+            if (retIdx == 0
+                    && i.getUnicodeStart() <= idx
+                    && i.getUnicodeEnd() >= idx) {
+                retIdx = i.getGlyphStartIndex()
                     + idx
-                    - cmap[i].getUnicodeStart();
+                    - i.getUnicodeStart();
                 if (idx < NUM_MOST_LIKELY_GLYPHS) {
                     mostLikelyGlyphs[idx] = retIdx;
                 }
@@ -241,14 +242,9 @@ public class MultiByteFont extends CIDFo
      * Add a private use mapping {PU,GI} to the existing character map.
      * N.B. Does not insert in order, merely appends to end of existing map.
      */
-    private synchronized void addPrivateUseMapping(int pu, int gi) {
+    protected synchronized void addPrivateUseMapping(int pu, int gi) {
         assert findGlyphIndex(pu) == SingleByteEncoding.NOT_FOUND_CODE_POINT;
-        CMapSegment[] oldCmap = cmap;
-        int cmapLength = oldCmap.length;
-        CMapSegment[] newCmap = new CMapSegment [ cmapLength + 1 ];
-        System.arraycopy(oldCmap, 0, newCmap, 0, cmapLength);
-        newCmap [ cmapLength ] = new CMapSegment(pu, pu, gi);
-        cmap = newCmap;
+        cmap.add(new CMapSegment(pu, pu, gi));
     }
 
     /**
@@ -306,8 +302,7 @@ public class MultiByteFont extends CIDFo
     // [TBD] - needs optimization, i.e., change from linear search to binary search
     private int findCharacterFromGlyphIndex(int gi, boolean augment) {
         int cc = 0;
-        for (int i = 0, n = cmap.length; i < n; i++) {
-            CMapSegment segment = cmap [ i ];
+        for (CMapSegment segment : cmap) {
             int s = segment.getGlyphStartIndex();
             int e = s + (segment.getUnicodeEnd() - segment.getUnicodeStart());
             if ((gi >= s) && (gi <= e)) {
@@ -330,10 +325,10 @@ public class MultiByteFont extends CIDFo
         bitset.set(0);
         bitset.set(1);
         bitset.set(2);
-        for (int i = 0; i < cmap.length; i++) {
-            int start = cmap[i].getUnicodeStart();
-            int end = cmap[i].getUnicodeEnd();
-            int glyphIndex = cmap[i].getGlyphStartIndex();
+        for (CMapSegment i : cmap) {
+            int start = i.getUnicodeStart();
+            int end = i.getUnicodeEnd();
+            int glyphIndex = i.getGlyphStartIndex();
             while (start++ < end + 1) {
                 bitset.set(glyphIndex++);
             }
@@ -344,10 +339,10 @@ public class MultiByteFont extends CIDFo
     protected char[] getChars() {
         // the width array is set when the font is built
         char[] chars = new char[width.length];
-        for (int i = 0; i < cmap.length; i++) {
-            int start = cmap[i].getUnicodeStart();
-            int end = cmap[i].getUnicodeEnd();
-            int glyphIndex = cmap[i].getGlyphStartIndex();
+        for (CMapSegment i : cmap) {
+            int start = i.getUnicodeStart();
+            int end = i.getUnicodeEnd();
+            int glyphIndex = i.getGlyphStartIndex();
             while (start < end + 1) {
                 chars[glyphIndex++] = (char) start++;
             }
@@ -642,5 +637,12 @@ public class MultiByteFont extends CIDFo
         return cb;
     }
 
+    public Map<Integer, Integer> getWidthsMap() {
+        return null;
+    }
+
+    public InputStream getCmapStream() {
+        return null;
+    }
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/SingleByteFont.java Wed Jul 16 09:10:53 2014
@@ -46,10 +46,10 @@ public class SingleByteFont extends Cust
     /** logger */
     private  static Log log = LogFactory.getLog(SingleByteFont.class);
 
-    private SingleByteEncoding mapping;
+    protected SingleByteEncoding mapping;
     private boolean useNativeEncoding;
 
-    private int[] width;
+    protected int[] width;
 
     private Rectangle[] boundingBoxes;
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/cff/CFFDataReader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/cff/CFFDataReader.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/cff/CFFDataReader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/cff/CFFDataReader.java Wed Jul 16 09:10:53 2014
@@ -580,7 +580,9 @@ public class CFFDataReader {
                     LinkedHashMap<String, DICTEntry> fdEntries = parseDictData(fdData);
                     newFontDict.setByteData(fontDicts.getValuePosition(i), fontDicts.getValueLength(i));
                     DICTEntry fontFDEntry = fdEntries.get("FontName");
-                    newFontDict.setFontName(getString(fontFDEntry.getOperands().get(0).intValue()));
+                    if (fontFDEntry != null) {
+                        newFontDict.setFontName(getString(fontFDEntry.getOperands().get(0).intValue()));
+                    }
                     DICTEntry privateFDEntry = fdEntries.get("Private");
                     if (privateFDEntry != null) {
                         newFontDict = setFDData(privateFDEntry, newFontDict);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/GlyfTable.java Wed Jul 16 09:10:53 2014
@@ -37,7 +37,7 @@ public class GlyfTable {
 
     private final Set<Long> remappedComposites;
 
-    private final Map<Integer, Integer> subset;
+    protected final Map<Integer, Integer> subset;
 
     private final FontFileReader in;
 
@@ -45,10 +45,10 @@ public class GlyfTable {
     private Set<Integer> compositeGlyphs = new TreeSet<Integer>();
 
     /** All the glyphs that are composed, but do not appear in the subset. */
-    private Set<Integer> composedGlyphs = new TreeSet<Integer>();
+    protected Set<Integer> composedGlyphs = new TreeSet<Integer>();
 
-    GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry dirTableEntry,
-            Map<Integer, Integer> glyphs) throws IOException {
+    protected GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry dirTableEntry,
+                        Map<Integer, Integer> glyphs) throws IOException {
         mtxTab = metrics;
         tableOffset = dirTableEntry.getOffset();
         remappedComposites = new HashSet<Long>();
@@ -121,7 +121,7 @@ public class GlyfTable {
      *
      * @throws IOException an I/O error
      */
-    void populateGlyphsWithComposites() throws IOException {
+    protected void populateGlyphsWithComposites() throws IOException {
         for (int indexInOriginal : subset.keySet()) {
             scanGlyphsRecursively(indexInOriginal);
         }
@@ -166,7 +166,7 @@ public class GlyfTable {
      * Adds to the subset, all the glyphs that are composed by a glyph, but do not appear themselves
      * in the subset.
      */
-    private void addAllComposedGlyphsToSubset() {
+    protected void addAllComposedGlyphsToSubset() {
         int newIndex = subset.size();
         for (int composedGlyph : composedGlyphs) {
             subset.put(composedGlyph, newIndex++);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java Wed Jul 16 09:10:53 2014
@@ -24,7 +24,7 @@ import java.util.List;
 /**
  * This class represents a TrueType Mtx Entry.
  */
-class OFMtxEntry {
+public class OFMtxEntry {
 
     private int wx;
     private int lsb;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFFile.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFFile.java Wed Jul 16 09:10:53 2014
@@ -147,7 +147,7 @@ public class OTFFile extends OpenFont {
      * @return The byte data found in the CFF table
      */
     public static byte[] getCFFData(FontFileReader fontFile) throws IOException {
-        byte[] cff = new byte[0];
+        byte[] cff = fontFile.getAllBytes();
         CFFDataInput input = new CFFDataInput(fontFile.getAllBytes());
         input.readBytes(4); //OTTO
         short numTables = input.readShort();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java Wed Jul 16 09:10:53 2014
@@ -49,23 +49,23 @@ import org.apache.fop.fonts.cff.CFFDataR
  */
 public class OTFSubSetFile extends OTFFile {
 
-    private byte[] output;
-    private int currentPos;
+    protected byte[] output;
+    protected int currentPos;
     private int realSize;
 
     /** A map containing each glyph to be included in the subset
       * with their existing and new GID's **/
-    private LinkedHashMap<Integer, Integer> subsetGlyphs;
+    protected LinkedHashMap<Integer, Integer> subsetGlyphs = new LinkedHashMap<Integer, Integer>();
 
     /** A map of the new GID to SID used to construct the charset table **/
-    private LinkedHashMap<Integer, Integer> gidToSID;
+    protected LinkedHashMap<Integer, Integer> gidToSID;
 
-    private CFFIndexData localIndexSubr;
-    private CFFIndexData globalIndexSubr;
+    protected CFFIndexData localIndexSubr;
+    protected CFFIndexData globalIndexSubr;
 
     /** List of subroutines to write to the local / global indexes in the subset font **/
-    private List<byte[]> subsetLocalIndexSubr;
-    private List<byte[]> subsetGlobalIndexSubr;
+    protected List<byte[]> subsetLocalIndexSubr;
+    protected List<byte[]> subsetGlobalIndexSubr;
 
     /** For fonts which have an FDSelect or ROS flag in Top Dict, this is used to store the
      * local subroutine indexes for each group as opposed to the above subsetLocalIndexSubr */
@@ -76,30 +76,30 @@ public class OTFSubSetFile extends OTFFi
     private LinkedHashMap<Integer, FDIndexReference> subsetFDSelect;
 
     /** A list of unique subroutines from the global / local subroutine indexes */
-    private List<Integer> localUniques;
-    private List<Integer> globalUniques;
+    protected List<Integer> localUniques;
+    protected List<Integer> globalUniques;
 
     /** A store of the number of subroutines each global / local subroutine will store **/
-    private int subsetLocalSubrCount;
-    private int subsetGlobalSubrCount;
+    protected int subsetLocalSubrCount;
+    protected int subsetGlobalSubrCount;
 
     /** A list of char string data for each glyph to be stored in the subset font **/
-    private List<byte[]> subsetCharStringsIndex;
+    protected List<byte[]> subsetCharStringsIndex;
 
     /** The embedded name to change in the name table **/
-    private String embeddedName;
+    protected String embeddedName;
 
     /** An array used to hold the string index data for the subset font **/
-    private List<byte[]> stringIndexData = new ArrayList<byte[]>();
+    protected List<byte[]> stringIndexData = new ArrayList<byte[]>();
 
     /** The CFF reader object used to read data and offsets from the original font file */
-    private CFFDataReader cffReader;
+    protected CFFDataReader cffReader;
 
     /** The class used to represent this font **/
     private MultiByteFont mbFont;
 
     /** The number of standard strings in CFF **/
-    private static final int NUM_STANDARD_STRINGS = 391;
+    public static final int NUM_STANDARD_STRINGS = 391;
     /** The operator used to identify a local subroutine reference */
     private static final int LOCAL_SUBROUTINE = 10;
     /** The operator used to identify a global subroutine reference */
@@ -162,7 +162,7 @@ public class OTFSubSetFile extends OTFFi
        return result;
     }
 
-    private void createCFF() throws IOException {
+    protected void createCFF() throws IOException {
         //Header
         writeBytes(cffReader.getHeader());
 
@@ -238,7 +238,7 @@ public class OTFSubSetFile extends OTFFi
         }
     }
 
-    private List<Integer> storeFDStrings(List<Integer> uniqueNewRefs) throws IOException {
+    protected List<Integer> storeFDStrings(List<Integer> uniqueNewRefs) throws IOException {
         ArrayList<Integer> fontNameSIDs = new ArrayList<Integer>();
         List<FontDict> fdFonts = cffReader.getFDFonts();
         for (int i = 0; i < uniqueNewRefs.size(); i++) {
@@ -252,14 +252,13 @@ public class OTFSubSetFile extends OTFFi
         return fontNameSIDs;
     }
 
-    private void writeBytes(byte[] out) {
+    protected void writeBytes(byte[] out) {
         for (int i = 0; i < out.length; i++) {
-            output[currentPos++] = out[i];
-            realSize++;
+            writeByte(out[i]);
         }
     }
 
-    private void writeBytes(byte[] out, int offset, int length) {
+    protected void writeBytes(byte[] out, int offset, int length) {
         for (int i = offset; i < offset + length; i++) {
             output[currentPos++] = out[i];
             realSize++;
@@ -280,7 +279,7 @@ public class OTFSubSetFile extends OTFFi
         }
     }
 
-    private void writeTopDICT() throws IOException {
+    protected void writeTopDICT() throws IOException {
         LinkedHashMap<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
         List<String> topDictStringEntries = Arrays.asList("version", "Notice", "Copyright",
                 "FullName", "FamilyName", "Weight", "PostScript");
@@ -321,7 +320,7 @@ public class OTFSubSetFile extends OTFFi
         writeBytes(cidEntryByteData);
     }
 
-    private void writeCIDCount(DICTEntry dictEntry) throws IOException {
+    protected void writeCIDCount(DICTEntry dictEntry) throws IOException {
         byte[] cidCountByteData = dictEntry.getByteData();
         cidCountByteData = updateOffset(cidCountByteData, 0, dictEntry.getOperandLengths().get(0),
                 subsetGlyphs.size());
@@ -375,7 +374,7 @@ public class OTFSubSetFile extends OTFFi
         writeIndex(stringIndexData);
     }
 
-    private void createCharStringDataCID() throws IOException {
+    protected void createCharStringDataCID() throws IOException {
         CFFIndexData charStringsIndex = cffReader.getCharStringIndex();
 
         FDSelect fontDictionary = cffReader.getFDSelect();
@@ -451,22 +450,22 @@ public class OTFSubSetFile extends OTFFi
                 localUniques = foundLocalUniquesB.get(subsetFDSelect.get(subsetGlyphs.get(gid)).getNewFDIndex());
                 byte[] data = charStringsIndex.getValue(gid);
                 subsetLocalIndexSubr = fdSubrs.get(subsetFDSelect.get(subsetGlyphs.get(gid)).getNewFDIndex());
-                subsetLocalSubrCount = foundLocalUniques.get(
-                        subsetFDSelect.get(subsetGlyphs.get(gid)).getNewFDIndex()).size();
+                subsetLocalSubrCount = foundLocalUniques.get(subsetFDSelect.get(subsetGlyphs.get(gid))
+                        .getNewFDIndex()).size();
                 data = readCharStringData(data, subsetLocalSubrCount);
                 subsetCharStringsIndex.add(data);
             }
         }
     }
 
-    private void writeFDSelect() {
+    protected void writeFDSelect() {
         writeByte(0); //Format
         for (Integer gid : subsetFDSelect.keySet()) {
             writeByte(subsetFDSelect.get(gid).getNewFDIndex());
         }
     }
 
-    private List<Integer> getUsedFDFonts() {
+    protected List<Integer> getUsedFDFonts() {
         List<Integer> uniqueNewRefs = new ArrayList<Integer>();
         for (int gid : subsetFDSelect.keySet()) {
             int fdIndex = subsetFDSelect.get(gid).getOldFDIndex();
@@ -477,7 +476,7 @@ public class OTFSubSetFile extends OTFFi
         return uniqueNewRefs;
     }
 
-    private List<Integer> writeCIDDictsAndSubrs(List<Integer> uniqueNewRefs)
+    protected List<Integer> writeCIDDictsAndSubrs(List<Integer> uniqueNewRefs)
             throws IOException {
         List<Integer> privateDictOffsets = new ArrayList<Integer>();
         List<FontDict> fdFonts = cffReader.getFDFonts();
@@ -499,7 +498,7 @@ public class OTFSubSetFile extends OTFFi
         return privateDictOffsets;
     }
 
-    private int writeFDArray(List<Integer> uniqueNewRefs, List<Integer> privateDictOffsets,
+    protected int writeFDArray(List<Integer> uniqueNewRefs, List<Integer> privateDictOffsets,
             List<Integer> fontNameSIDs)
             throws IOException {
         int offset = currentPos;
@@ -796,7 +795,7 @@ public class OTFSubSetFile extends OTFFi
         return c;
     }
 
-    private int writeIndex(List<byte[]> dataArray) {
+    protected int writeIndex(List<byte[]> dataArray) {
         int hdrTotal = 3;
         //2 byte number of items
         this.writeCard16(dataArray.size());
@@ -939,7 +938,7 @@ public class OTFSubSetFile extends OTFFi
         }
     }
 
-    private void writePrivateDict() throws IOException {
+    protected void writePrivateDict() throws IOException {
         Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
 
         DICTEntry privateEntry = topDICT.get("Private");
@@ -948,7 +947,7 @@ public class OTFSubSetFile extends OTFFi
         }
     }
 
-    private void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
+    protected void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
             int privateDictOffset, int localIndexOffset, int encodingOffset)
             throws IOException {
         Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
@@ -973,18 +972,20 @@ public class OTFSubSetFile extends OTFFi
 
             //Update the local subroutine index offset in the private dict
             DICTEntry subroutines = privateDICT.get("Subrs");
-            int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
-            //Value needs to be converted to -139 etc.
-            int encodeValue = 0;
-            if (subroutines.getOperandLength() == 1) {
-                encodeValue = 139;
+            if (subroutines != null) {
+                int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
+                //Value needs to be converted to -139 etc.
+                int encodeValue = 0;
+                if (subroutines.getOperandLength() == 1) {
+                    encodeValue = 139;
+                }
+                output = updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
+                        (localIndexOffset - privateDictOffset) + encodeValue);
             }
-            output = updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
-                    (localIndexOffset - privateDictOffset) + encodeValue);
         }
     }
 
-    private void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
+    protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
             int charsetOffset, int charStringOffset, int encodingOffset) {
         //Charset offset in the top dict
         DICTEntry charset = topDICT.get("charset");
@@ -1004,7 +1005,7 @@ public class OTFSubSetFile extends OTFFi
         }
     }
 
-    private void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
+    protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
             int charsetOffset, int charStringOffset, int encodingOffset) {
         LinkedHashMap<String, DICTEntry> topDict = cffReader.getTopDictEntries();
 
@@ -1023,7 +1024,7 @@ public class OTFSubSetFile extends OTFFi
         updateFixedOffsets(topDict, topDictDataOffset, charsetOffset, charStringOffset, encodingOffset);
     }
 
-    private byte[] updateOffset(byte[] out, int position, int length, int replacement) {
+    protected byte[] updateOffset(byte[] out, int position, int length, int replacement) {
         switch (length) {
         case 1:
             out[position] = (byte)(replacement & 0xFF);
@@ -1061,7 +1062,7 @@ public class OTFSubSetFile extends OTFFi
      * Appends a byte to the output array,
      * updates currentPost but not realSize
      */
-    private void writeByte(int b) {
+    protected void writeByte(int b) {
         output[currentPos++] = (byte)b;
         realSize++;
     }
@@ -1070,7 +1071,7 @@ public class OTFSubSetFile extends OTFFi
      * Appends a USHORT to the output array,
      * updates currentPost but not realSize
      */
-    private void writeCard16(int s) {
+    protected void writeCard16(int s) {
         byte b1 = (byte)((s >> 8) & 0xff);
         byte b2 = (byte)(s & 0xff);
         writeByte(b1);
@@ -1081,10 +1082,9 @@ public class OTFSubSetFile extends OTFFi
         byte b1 = (byte)((s >> 16) & 0xFF);
         byte b2 = (byte)((s >> 8) & 0xFF);
         byte b3 = (byte)(s & 0xFF);
-        output[currentPos++] = b1;
-        output[currentPos++] = b2;
-        output[currentPos++] = b3;
-        realSize += 3;
+        writeByte(b1);
+        writeByte(b2);
+        writeByte(b3);
     }
 
     /**
@@ -1096,11 +1096,10 @@ public class OTFSubSetFile extends OTFFi
         byte b2 = (byte)((s >> 16) & 0xff);
         byte b3 = (byte)((s >> 8) & 0xff);
         byte b4 = (byte)(s & 0xff);
-        output[currentPos++] = b1;
-        output[currentPos++] = b2;
-        output[currentPos++] = b3;
-        output[currentPos++] = b4;
-        realSize += 4;
+        writeByte(b1);
+        writeByte(b2);
+        writeByte(b3);
+        writeByte(b4);
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/OpenFont.java Wed Jul 16 09:10:53 2014
@@ -168,7 +168,7 @@ public abstract class OpenFont {
     protected List<UnicodeMapping> unicodeMappings;
 
     private int upem;                                // unitsPerEm from "head" table
-    private int nhmtx;                               // Number of horizontal metrics
+    protected int nhmtx;                               // Number of horizontal metrics
     private PostScriptVersion postScriptVersion;
     protected int locaFormat;
     /**
@@ -187,6 +187,7 @@ public abstract class OpenFont {
     protected String notice = "";
     protected final Set<String> familyNames = new HashSet<String>();
     protected String subFamilyName = "";
+    protected boolean cid = true;
 
     private long italicAngle;
     private long isFixedPitch;
@@ -393,7 +394,9 @@ public abstract class OpenFont {
 
         unicodeMappings = new ArrayList<OpenFont.UnicodeMapping>();
 
-        seekTab(fontFile, OFTableName.CMAP, 2);
+        if (!seekTab(fontFile, OFTableName.CMAP, 2)) {
+            return true;
+        }
         int numCMap = fontFile.readTTFUShort();    // Number of cmap subtables
         long cmapUniOffset = 0;
         long symbolMapOffset = 0;
@@ -796,7 +799,9 @@ public abstract class OpenFont {
         int unicodeStart;
         int glyphStart;
         int unicodeEnd;
-
+        if (unicodeMappings.isEmpty()) {
+            return;
+        }
         Iterator<UnicodeMapping> e = unicodeMappings.iterator();
         UnicodeMapping um = e.next();
         UnicodeMapping lastMapping = um;
@@ -1229,7 +1234,7 @@ public abstract class OpenFont {
             }
         }
 
-        if (nhmtx < mtxSize) {
+        if (cid && nhmtx < mtxSize) {
             // Fill in the missing widths
             int lastWidth = mtxTab[nhmtx - 1].getWx();
             for (int i = nhmtx; i < mtxSize; i++) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java Wed Jul 16 09:10:53 2014
@@ -35,21 +35,21 @@ import java.util.SortedSet;
  */
 public class TTFSubSetFile extends TTFFile {
 
-    private byte[] output;
-    private int realSize;
-    private int currentPos;
+    protected byte[] output;
+    protected int realSize;
+    protected int currentPos;
 
     /*
      * Offsets in name table to be filled out by table.
      * The offsets are to the checkSum field
      */
-    private Map<OFTableName, Integer> offsets = new HashMap<OFTableName, Integer>();
+    protected Map<OFTableName, Integer> offsets = new HashMap<OFTableName, Integer>();
 
     private int checkSumAdjustmentOffset;
-    private int locaOffset;
+    protected int locaOffset;
 
     /** Stores the glyph offsets so that we can end strings at glyph boundaries */
-    private int[] glyphOffsets;
+    protected int[] glyphOffsets;
 
     /**
      * Default Constructor
@@ -67,7 +67,7 @@ public class TTFSubSetFile extends TTFFi
     }
 
     /** The dir tab entries in the new subset font. */
-    private Map<OFTableName, OFDirTabEntry> newDirTabs
+    protected Map<OFTableName, OFDirTabEntry> newDirTabs
                         = new HashMap<OFTableName, OFDirTabEntry>();
 
     private int determineTableCount() {
@@ -86,6 +86,9 @@ public class TTFSubSetFile extends TTFFi
             if (hasPrep()) {
                 numTables++;
             }
+            if (!cid) {
+                numTables++; //cmap
+            }
         }
         return numTables;
     }
@@ -93,7 +96,7 @@ public class TTFSubSetFile extends TTFFi
     /**
      * Create the directory table
      */
-    private void createDirectory() {
+    protected void createDirectory() {
         int numTables = determineTableCount();
         // Create the TrueType header
         writeByte((byte)0);
@@ -118,7 +121,9 @@ public class TTFSubSetFile extends TTFFi
         realSize += 2;
         // Create space for the table entries (these must be in ASCII alphabetical order[A-Z] then[a-z])
         writeTableName(OFTableName.OS2);
-
+        if (!cid) {
+            writeTableName(OFTableName.CMAP);
+        }
         if (hasCvt()) {
             writeTableName(OFTableName.CVT);
         }
@@ -162,7 +167,7 @@ public class TTFSubSetFile extends TTFFi
     /**
      * Create an empty loca table without updating checksum
      */
-    private void createLoca(int size) throws IOException {
+    protected void createLoca(int size) throws IOException {
         pad4();
         locaOffset = currentPos;
         int dirTableOffset = offsets.get(OFTableName.LOCA);
@@ -177,8 +182,7 @@ public class TTFSubSetFile extends TTFFi
         if (entry != null) {
             pad4();
             seekTab(in, tableName, 0);
-            System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
-                             0, output, currentPos, (int)entry.getLength());
+            writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
 
             updateCheckSum(currentPos, (int) entry.getLength(), tableName);
             currentPos += (int) entry.getLength();
@@ -192,28 +196,28 @@ public class TTFSubSetFile extends TTFFi
     /**
      * Copy the cvt table as is from original font to subset font
      */
-    private boolean createCvt(FontFileReader in) throws IOException {
+    protected boolean createCvt(FontFileReader in) throws IOException {
         return copyTable(in, OFTableName.CVT);
     }
 
     /**
      * Copy the fpgm table as is from original font to subset font
      */
-    private boolean createFpgm(FontFileReader in) throws IOException {
+    protected boolean createFpgm(FontFileReader in) throws IOException {
         return copyTable(in, OFTableName.FPGM);
     }
 
     /**
      * Copy the name table as is from the original.
      */
-    private boolean createName(FontFileReader in) throws IOException {
+    protected boolean createName(FontFileReader in) throws IOException {
         return copyTable(in, OFTableName.NAME);
     }
 
     /**
      * Copy the OS/2 table as is from the original.
      */
-    private boolean createOS2(FontFileReader in) throws IOException {
+    protected boolean createOS2(FontFileReader in) throws IOException {
         return copyTable(in, OFTableName.OS2);
     }
 
@@ -221,14 +225,13 @@ public class TTFSubSetFile extends TTFFi
      * Copy the maxp table as is from original font to subset font
      * and set num glyphs to size
      */
-    private void createMaxp(FontFileReader in, int size) throws IOException {
+    protected void createMaxp(FontFileReader in, int size) throws IOException {
         OFTableName maxp = OFTableName.MAXP;
         OFDirTabEntry entry = dirTabs.get(maxp);
         if (entry != null) {
             pad4();
             seekTab(in, maxp, 0);
-            System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
-                             0, output, currentPos, (int)entry.getLength());
+            writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
             writeUShort(currentPos + 4, size);
 
             updateCheckSum(currentPos, (int)entry.getLength(), maxp);
@@ -239,7 +242,7 @@ public class TTFSubSetFile extends TTFFi
         }
     }
 
-    private void createPost(FontFileReader in) throws IOException {
+    protected void createPost(FontFileReader in) throws IOException {
         OFTableName post = OFTableName.POST;
         OFDirTabEntry entry = dirTabs.get(post);
         if (entry != null) {
@@ -252,12 +255,12 @@ public class TTFSubSetFile extends TTFFi
                     0, newPostTable, 0, newTableSize);
             // set the post table to Format 3.0
             newPostTable[1] = 0x03;
-            System.arraycopy(newPostTable, 0, output, currentPos, newTableSize);
+            writeBytes(newPostTable);
             updateCheckSum(currentPos, newTableSize, post);
             currentPos += newTableSize;
             realSize += newTableSize;
         } else {
-            throw new IOException("Can't find post table");
+//            throw new IOException("Can't find post table");
         }
     }
 
@@ -265,7 +268,7 @@ public class TTFSubSetFile extends TTFFi
     /**
      * Copy the prep table as is from original font to subset font
      */
-    private boolean createPrep(FontFileReader in) throws IOException {
+    protected boolean createPrep(FontFileReader in) throws IOException {
         return copyTable(in, OFTableName.PREP);
     }
 
@@ -274,13 +277,12 @@ public class TTFSubSetFile extends TTFFi
      * Copy the hhea table as is from original font to subset font
      * and fill in size of hmtx table
      */
-    private void createHhea(FontFileReader in, int size) throws IOException {
+    protected void createHhea(FontFileReader in, int size) throws IOException {
         OFDirTabEntry entry = dirTabs.get(OFTableName.HHEA);
         if (entry != null) {
             pad4();
             seekTab(in, OFTableName.HHEA, 0);
-            System.arraycopy(in.getBytes((int) entry.getOffset(), (int) entry.getLength()), 0,
-                    output, currentPos, (int) entry.getLength());
+            writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
             writeUShort((int) entry.getLength() + currentPos - 2, size);
 
             updateCheckSum(currentPos, (int) entry.getLength(), OFTableName.HHEA);
@@ -298,14 +300,13 @@ public class TTFSubSetFile extends TTFFi
      * checkSumAdjustment to 0, store offset to checkSumAdjustment
      * in checkSumAdjustmentOffset
      */
-    private void createHead(FontFileReader in) throws IOException {
+    protected void createHead(FontFileReader in) throws IOException {
         OFTableName head = OFTableName.HEAD;
         OFDirTabEntry entry = dirTabs.get(head);
         if (entry != null) {
             pad4();
             seekTab(in, head, 0);
-            System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
-                             0, output, currentPos, (int)entry.getLength());
+            writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
 
             checkSumAdjustmentOffset = currentPos + 8;
             output[currentPos + 8] = 0;     // Set checkSumAdjustment to 0
@@ -313,8 +314,9 @@ public class TTFSubSetFile extends TTFFi
             output[currentPos + 10] = 0;
             output[currentPos + 11] = 0;
             output[currentPos + 50] = 0;    // long locaformat
-            output[currentPos + 51] = 1;    // long locaformat
-
+            if (cid) {
+                output[currentPos + 51] = 1;    // long locaformat
+            }
             updateCheckSum(currentPos, (int)entry.getLength(), head);
             currentPos += (int)entry.getLength();
             realSize += (int)entry.getLength();
@@ -361,10 +363,7 @@ public class TTFSubSetFile extends TTFFi
                         glyphLength);
                 int endOffset1 = endOffset;
                 // Copy glyph
-                System.arraycopy(
-                    glyphData, 0,
-                    output, currentPos,
-                    glyphLength);
+                writeBytes(glyphData);
 
 
                 // Update loca table
@@ -402,12 +401,14 @@ public class TTFSubSetFile extends TTFFi
         }
     }
 
-    private int[] buildSubsetIndexToOrigIndexMap(Map<Integer, Integer> glyphs) {
+    protected int[] buildSubsetIndexToOrigIndexMap(Map<Integer, Integer> glyphs) {
         int[] origIndexes = new int[glyphs.size()];
         for (Map.Entry<Integer, Integer> glyph : glyphs.entrySet()) {
             int origIndex = glyph.getKey();
             int subsetIndex = glyph.getValue();
-            origIndexes[subsetIndex] = origIndex;
+            if (origIndexes.length > subsetIndex) {
+                origIndexes[subsetIndex] = origIndex;
+            }
         }
         return origIndexes;
     }
@@ -418,8 +419,8 @@ public class TTFSubSetFile extends TTFFi
      * Integer key and Integer value that maps the original
      * metric (key) to the subset metric (value)
      */
-    private void createHmtx(FontFileReader in,
-                            Map<Integer, Integer> glyphs) throws IOException {
+    protected void createHmtx(FontFileReader in,
+                              Map<Integer, Integer> glyphs) throws IOException {
         OFTableName hmtx = OFTableName.HMTX;
         OFDirTabEntry entry = dirTabs.get(hmtx);
 
@@ -560,7 +561,7 @@ public class TTFSubSetFile extends TTFFi
         ttfOut.endFontStream();
     }
 
-    private void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
+    protected void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
             throws IOException {
         OFDirTabEntry glyfTableInfo = dirTabs.get(OFTableName.GLYF);
         if (glyfTableInfo == null) {
@@ -580,7 +581,7 @@ public class TTFSubSetFile extends TTFFi
         int length = 0;
         try {
             byte[] buf = str.getBytes("ISO-8859-1");
-            System.arraycopy(buf, 0, output, currentPos, buf.length);
+            writeBytes(buf);
             length = buf.length;
             currentPos += length;
         } catch (java.io.UnsupportedEncodingException e) {
@@ -598,11 +599,20 @@ public class TTFSubSetFile extends TTFFi
         output[currentPos++] = b;
     }
 
+    protected void writeBytes(byte[] b) {
+        if (b.length + currentPos > output.length) {
+            byte[] newoutput = new byte[output.length * 2];
+            System.arraycopy(output, 0, newoutput, 0, output.length);
+            output = newoutput;
+        }
+        System.arraycopy(b, 0, output, currentPos, b.length);
+    }
+
     /**
      * Appends a USHORT to the output array,
      * updates currentPost but not realSize
      */
-    private void writeUShort(int s) {
+    protected void writeUShort(int s) {
         byte b1 = (byte)((s >> 8) & 0xff);
         byte b2 = (byte)(s & 0xff);
         writeByte(b1);
@@ -613,7 +623,7 @@ public class TTFSubSetFile extends TTFFi
      * Appends a USHORT to the output array,
      * at the given position without changing currentPos
      */
-    private void writeUShort(int pos, int s) {
+    protected void writeUShort(int pos, int s) {
         byte b1 = (byte)((s >> 8) & 0xff);
         byte b2 = (byte)(s & 0xff);
         output[pos] = b1;
@@ -625,7 +635,7 @@ public class TTFSubSetFile extends TTFFi
      * Appends a ULONG to the output array,
      * at the given position without changing currentPos
      */
-    private void writeULong(int pos, int s) {
+    protected void writeULong(int pos, int s) {
         byte b1 = (byte)((s >> 24) & 0xff);
         byte b2 = (byte)((s >> 16) & 0xff);
         byte b3 = (byte)((s >> 8) & 0xff);
@@ -640,7 +650,7 @@ public class TTFSubSetFile extends TTFFi
      * Create a padding in the fontfile to align
      * on a 4-byte boundary
      */
-    private void pad4() {
+    protected void pad4() {
         int padSize = getPadSize(currentPos);
         if (padSize < 4) {
             for (int i = 0; i < padSize; i++) {
@@ -663,7 +673,7 @@ public class TTFSubSetFile extends TTFFi
     }
 
 
-    private void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
+    protected void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
         int checksum = getCheckSum(output, tableStart, tableSize);
         int offset = offsets.get(tableName);
         int padSize = getPadSize(tableStart +  tableSize);
@@ -673,7 +683,7 @@ public class TTFSubSetFile extends TTFFi
         writeULong(offset + 8, tableSize);
     }
 
-    private static int getCheckSum(byte[] data, int start, int size) {
+    protected static int getCheckSum(byte[] data, int start, int size) {
         // All the tables here are aligned on four byte boundaries
         // Add remainder to size if it's not a multiple of 4
         int remainder = size % 4;
@@ -687,14 +697,16 @@ public class TTFSubSetFile extends TTFFi
             long l = 0;
             for (int j = 0; j < 4; j++) {
                 l <<= 8;
-                l |= data[start + i + j] & 0xff;
+                if (data.length > (start + i + j)) {
+                    l |= data[start + i + j] & 0xff;
+                }
             }
             sum += l;
         }
         return (int) sum;
     }
 
-    private void createCheckSumAdjustment() {
+    protected void createCheckSumAdjustment() {
         long sum = getCheckSum(output, 0, realSize);
         int checksum = (int)(0xb1b0afba - sum);
         writeULong(checkSumAdjustmentOffset, checksum);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/PostscriptParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/PostscriptParser.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/PostscriptParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/PostscriptParser.java Wed Jul 16 09:10:53 2014
@@ -31,7 +31,7 @@ import java.util.Scanner;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-class PostscriptParser {
+public class PostscriptParser {
 
     protected static final Log LOG = LogFactory.getLog(PostscriptParser.class);
     /* Patterns used to identify Postscript elements */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java Wed Jul 16 09:10:53 2014
@@ -51,32 +51,31 @@ public class Type1SubsetFile {
 
     protected static final Log LOG = LogFactory.getLog(Type1SubsetFile.class);
     /* The subset list of char strings */
-    private HashMap<String, byte[]> subsetCharStrings;
+    protected HashMap<String, byte[]> subsetCharStrings;
     /* The list of character names in the subset font */
-    private List<String> charNames;
+    protected List<String> charNames;
     /* A list of unique subroutines references */
-    private LinkedHashMap<Integer, byte[]> uniqueSubs;
+    protected LinkedHashMap<Integer, byte[]> uniqueSubs;
     private SingleByteFont sbfont;
     /* New line character */
-    private String eol = "\n";
+    protected String eol = "\n";
     /* An option to determine whether the subroutines are subset */
-    private boolean subsetSubroutines = true;
+    protected boolean subsetSubroutines = true;
     private byte[] fullFont;
     //List of parsed Postscript elements
-    private List<PSElement> headerSection;
-    private List<PSElement> mainSection;
+    protected List<PSElement> headerSection;
+    protected List<PSElement> mainSection;
     //Determines whether the current font uses standard encoding
-    private boolean standardEncoding;
+    protected boolean standardEncoding;
 
     //Type 1 operators
     private static final int OP_SEAC = 6;
     private static final int OP_CALLSUBR = 10;
     private static final int OP_CALLOTHERSUBR = 16;
 
-    public byte[] createSubset(InputStream in, SingleByteFont sbfont,
-            String fontPrefix) throws IOException {
+    public byte[] createSubset(InputStream in, SingleByteFont sbfont) throws IOException {
         fullFont = IOUtils.toByteArray(in);
-        byte[] subsetFont = createSubset(sbfont, fontPrefix, true);
+        byte[] subsetFont = createSubset(sbfont, true);
         //This should never happen but ensure that subset is shorter than original font
         return (subsetFont.length == 0 || subsetFont.length > fullFont.length)
                 ? fullFont : subsetFont;
@@ -84,17 +83,14 @@ public class Type1SubsetFile {
 
     /**
      * Creates a new subset from the given type 1 font input stream
-     * @param in The type 1 font to subset
      * @param sbfont The font object containing information such as the
      * characters from which to create the subset
-     * @param fontPrefix The prefix used in identifying the subset font
-     * @param allSubroutines This option will force the subset to include all
+     * @param subsetSubroutines This option will force the subset to include all
      * subroutines.
      * @return Returns the subset as a byte array
      * @throws IOException
      */
-    private byte[] createSubset(SingleByteFont sbfont,
-            String fontPrefix, boolean subsetSubroutines) throws IOException {
+    private byte[] createSubset(SingleByteFont sbfont, boolean subsetSubroutines) throws IOException {
         this.subsetSubroutines = subsetSubroutines;
         InputStream in = new ByteArrayInputStream(fullFont);
         //Initialise resources used for the font creation
@@ -132,8 +128,8 @@ public class Type1SubsetFile {
 
         //Process and write the main section
         PSElement charStrings = getElement("/CharStrings", mainSection);
-        int result = readMainSection(mainSection, decoded, subsetEncodingEntries, charStrings);
-        if (result == 0) {
+        boolean result = readMainSection(mainSection, decoded, subsetEncodingEntries, charStrings);
+        if (!result) {
             /* This check handles the case where a font uses a postscript method to return a
              * subroutine index. As there is currently no java postscript interpreter and writing
              * one would be very difficult it prevents us from handling this eventuality. The way
@@ -142,16 +138,16 @@ public class Type1SubsetFile {
             uniqueSubs.clear();
             subsetCharStrings.clear();
             charNames.clear();
-            return createSubset(sbfont, fontPrefix, false);
+            return createSubset(sbfont, false);
         }
 
         //Write header section
-        ByteArrayOutputStream boasHeader = writeHeader(pfbData, encoding, subsetEncodingEntries);
+        ByteArrayOutputStream boasHeader = writeHeader(pfbData, encoding);
 
         ByteArrayOutputStream boasMain = writeMainSection(decoded, mainSection, charStrings);
         byte[] mainSectionBytes = boasMain.toByteArray();
         mainSectionBytes = BinaryCoder.encodeBytes(mainSectionBytes, 55665, 4);
-        boasMain = new ByteArrayOutputStream();
+        boasMain.reset();
         boasMain.write(mainSectionBytes);
 
         ByteArrayOutputStream baosTrailer = new ByteArrayOutputStream();
@@ -160,8 +156,8 @@ public class Type1SubsetFile {
         return stitchFont(boasHeader, boasMain, baosTrailer);
     }
 
-    byte[] stitchFont(ByteArrayOutputStream boasHeader, ByteArrayOutputStream boasMain,
-            ByteArrayOutputStream boasTrailer) throws IOException {
+    protected byte[] stitchFont(ByteArrayOutputStream boasHeader, ByteArrayOutputStream boasMain,
+                                ByteArrayOutputStream boasTrailer) throws IOException {
         int headerLength = boasHeader.size();
         int mainLength = boasMain.size();
 
@@ -205,7 +201,7 @@ public class Type1SubsetFile {
                 /* If no matches are found, create a new entry for the character so
                  * that it can be added even if it's not in the current encoding. */
                 if (matches.size() == 0) {
-                    matches = new ArrayList<String>();
+                    matches.clear();
                     if (glyph == 0) {
                         matches.add("dup 0 /.notdef put");
                     } else {
@@ -237,7 +233,7 @@ public class Type1SubsetFile {
         return subsetEncodingEntries;
     }
 
-    private List<String> searchEntries(HashMap<Integer, String> encodingEntries, int glyph) {
+    protected List<String> searchEntries(HashMap<Integer, String> encodingEntries, int glyph) {
         List<String> matches = new ArrayList<String>();
         for (Entry<Integer, String> entry : encodingEntries.entrySet()) {
             String tag = getEntryPart(entry.getValue(), 3);
@@ -249,15 +245,13 @@ public class Type1SubsetFile {
         return matches;
     }
 
-    private ByteArrayOutputStream writeHeader(PFBData pfbData, PSElement encoding,
-            List<String> subsetEncodingEntries) throws UnsupportedEncodingException,
-            IOException {
+    protected ByteArrayOutputStream writeHeader(PFBData pfbData, PSElement encoding) throws IOException {
         ByteArrayOutputStream boasHeader = new ByteArrayOutputStream();
         boasHeader.write(pfbData.getHeaderSegment(), 0, encoding.getStartPoint() - 1);
 
         if (!standardEncoding) {
             //Write out the new encoding table for the subset font
-            String encodingArray = eol + String.format("/Encoding %d array", 256) + eol
+            String encodingArray = eol + "/Encoding 256 array" + eol
                     + "0 1 255 {1 index exch /.notdef put } for" + eol;
             byte[] encodingDefinition = encodingArray.getBytes("ASCII");
             boasHeader.write(encodingDefinition, 0, encodingDefinition.length);
@@ -287,7 +281,7 @@ public class Type1SubsetFile {
         return boas;
     }
 
-    private int readMainSection(List<PSElement> mainSection, byte[] decoded,
+    private boolean readMainSection(List<PSElement> mainSection, byte[] decoded,
             List<String> subsetEncodingEntries, PSElement charStrings) {
         subsetEncodingEntries.add(0, "dup 0 /.notdef put");
         /* Reads and parses the charStrings section to subset the charString
@@ -322,19 +316,19 @@ public class Type1SubsetFile {
                 /* Recursively scan the charString array for subroutines and if found, copy the
                  * entry to our subset entries and update any references. */
                 charStringEntry = createSubsetCharStrings(decoded, charStringEntry, subroutines,
-                        subsetEncodingEntries, tag);
+                        subsetEncodingEntries);
             }
             if (charStringEntry.length == 0) {
-                return 0;
+                return false;
             }
             charStringEntry = BinaryCoder.encodeBytes(charStringEntry, 4330, skipBytes);
             subsetCharStrings.put(tag, charStringEntry);
         }
-        return 1;
+        return true;
     }
 
     private byte[] createSubsetCharStrings(byte[] decoded, byte[] data, PSFixedArray subroutines,
-            List<String> subsetEncodingEntries, String glyphName) {
+            List<String> subsetEncodingEntries) {
         List<BytesNumber> operands = new ArrayList<BytesNumber>();
         for (int i = 0; i < data.length; i++) {
             int cur = data[i] & 0xFF;
@@ -348,11 +342,11 @@ public class Type1SubsetFile {
                     if (uniqueSubs.get(operands.get(operands.size() - 1).getNumber()) == null) {
                         uniqueSubs.put(operands.get(operands.size() - 1).getNumber(), new byte[0]);
                         data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
-                                glyphName, data, i, 1, -1, operands.get(
+                                data, i, 1, -1, operands.get(
                                         operands.size() - 1).getNumber());
                     } else {
                         data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
-                                glyphName, data, i, 1, getSubrIndex(operands.get(
+                                data, i, 1, getSubrIndex(operands.get(
                                         operands.size() - 1).getNumber()), operands.get(
                                                 operands.size() - 1).getNumber());
                     }
@@ -390,7 +384,7 @@ public class Type1SubsetFile {
                             return new byte[0];
                         }
                         data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
-                                glyphName, data, i, 2, -1, operands.get(0).getNumber());
+                                data, i, 2, -1, operands.get(0).getNumber());
                     }
                 }
                 if (data.length == 0) {
@@ -431,14 +425,14 @@ public class Type1SubsetFile {
     }
 
     private byte[] addSubroutine(PSFixedArray subroutines, List<BytesNumber> operands, byte[] decoded,
-            List<String> subsetEncodingEntries, String glyphName, byte[] data, int i, int opLength,
+            List<String> subsetEncodingEntries, byte[] data, int i, int opLength,
             int existingSubrRef, int subrID) {
         if (existingSubrRef == -1) {
             int[] subrData = subroutines.getBinaryEntryByIndex(subrID);
             byte[] subroutine = getBinaryEntry(subrData, decoded);
             subroutine = BinaryCoder.decodeBytes(subroutine, 4330, 4);
             subroutine = createSubsetCharStrings(decoded, subroutine, subroutines,
-                    subsetEncodingEntries, glyphName);
+                    subsetEncodingEntries);
             if (subroutine.length == 0) {
                 return new byte[0];
             }
@@ -451,8 +445,8 @@ public class Type1SubsetFile {
         return data;
     }
 
-    private ByteArrayOutputStream writeMainSection(byte[] decoded, List<PSElement> mainSection,
-            PSElement charStrings) throws IOException {
+    protected ByteArrayOutputStream writeMainSection(byte[] decoded, List<PSElement> mainSection,
+                                                     PSElement charStrings) throws IOException {
         ByteArrayOutputStream main = new ByteArrayOutputStream();
         PSElement subrs = getElement("/Subrs", mainSection);
 
@@ -470,11 +464,9 @@ public class Type1SubsetFile {
             writeString(eol + String.format("/Subrs %d array", uniqueSubs.size()), main);
             int count = 0;
             for (Entry<Integer, byte[]> entry : uniqueSubs.entrySet()) {
-                byte[] newSubrBytes = (eol + String.format("dup %d %d %s ", count++,
-                        entry.getValue().length, rd)).getBytes("ASCII");
-                newSubrBytes = concatArray(newSubrBytes, entry.getValue());
-                newSubrBytes = concatArray(newSubrBytes, String.format(" %s", np).getBytes("ASCII"));
-                main.write(newSubrBytes);
+                writeString(eol + String.format("dup %d %d %s ", count++, entry.getValue().length, rd), main);
+                main.write(entry.getValue());
+                writeString(" " + np, main);
             }
             writeString(eol + nd, main);
         } else {
@@ -498,8 +490,8 @@ public class Type1SubsetFile {
         return main;
     }
 
-    private String findVariable(byte[] decoded, List<PSElement> elements, String[] matches,
-            String fallback) throws UnsupportedEncodingException {
+    protected String findVariable(byte[] decoded, List<PSElement> elements, String[] matches,
+                                  String fallback) throws UnsupportedEncodingException {
         for (PSElement element : elements) {
             if (element instanceof PSSubroutine) {
                 byte[] var = new byte[element.getEndPoint() - element.getStartPoint()];
@@ -575,8 +567,8 @@ public class Type1SubsetFile {
         sbfont.mapUsedGlyphName(charIndex, charName);
     }
 
-    private void writeString(String entry, ByteArrayOutputStream boas)
-            throws UnsupportedEncodingException, IOException {
+    protected void writeString(String entry, ByteArrayOutputStream boas)
+            throws IOException {
         byte[] byteEntry = entry.getBytes("ASCII");
         boas.write(byteEntry);
     }
@@ -696,7 +688,7 @@ public class Type1SubsetFile {
      * @param decoded The array from which to copy a section of data
      * @return Returns the copy of the data section
      */
-    byte[] getBinaryEntry(int[] position, byte[] decoded) {
+    protected byte[] getBinaryEntry(int[] position, byte[] decoded) {
         int start = position[0];
         int finish = position[1];
         byte[] line = new byte[finish - start];
@@ -704,7 +696,7 @@ public class Type1SubsetFile {
         return line;
     }
 
-    private String getEntryPart(String entry, int part) {
+    protected String getEntryPart(String entry, int part) {
         Scanner s = new Scanner(entry).useDelimiter(" ");
         for (int i = 1; i < part; i++) {
             s.next();
@@ -712,7 +704,7 @@ public class Type1SubsetFile {
         return s.next();
     }
 
-    private PSElement getElement(String elementID, List<PSElement> elements) {
+    protected PSElement getElement(String elementID, List<PSElement> elements) {
         for (PSElement element : elements) {
             if (element.getOperator().equals(elementID)) {
                 return element;
@@ -722,14 +714,6 @@ public class Type1SubsetFile {
     }
 
     /**
-     * Gets the list of subset character names
-     * @return Returns the subset character names
-     */
-    public List<String> getCharNames() {
-        return charNames;
-    }
-
-    /**
      * A class to encode and decode sections of a type 1 font file. See Adobe
      * Type 1 Font Format Section 7.2 for more details.
      */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AbstractPDFStream.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AbstractPDFStream.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AbstractPDFStream.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AbstractPDFStream.java Wed Jul 16 09:10:53 2014
@@ -60,7 +60,7 @@ public abstract class AbstractPDFStream 
         return dictionary;
     }
 
-    protected Object get(String key) {
+    public Object get(String key) {
         return dictionary.get(key);
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java Wed Jul 16 09:10:53 2014
@@ -167,6 +167,8 @@ public class PDFDocument {
 
     private boolean accessibilityEnabled;
 
+    private boolean mergeFontsEnabled;
+
     /**
      * Creates an empty PDF document.
      *
@@ -1082,6 +1084,14 @@ public class PDFDocument {
         return trailerDictionary;
     }
 
+    public boolean isMergeFontsEnabled() {
+        return mergeFontsEnabled;
+    }
+
+    public void setMergeFontsEnabled(boolean mergeFontsEnabled) {
+        this.mergeFontsEnabled = mergeFontsEnabled;
+    }
+
     private interface TrailerOutputHelper {
 
         void outputStructureTreeElements(OutputStream stream) throws IOException;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java Wed Jul 16 09:10:53 2014
@@ -1344,9 +1344,15 @@ public class PDFFactory {
             PDFFont font = null;
 
             font = PDFFont.createFont(fontname, fonttype, subsetFontName, null);
-            getDocument().registerObject(font);
+            if (descriptor instanceof RefPDFFont) {
+                font.setObjectNumber(((RefPDFFont)descriptor).getRef().getObjectNumber());
+                font.setDocument(getDocument());
+                getDocument().addObject(font);
+            } else {
+                getDocument().registerObject(font);
+            }
 
-            if (fonttype == FontType.TYPE0) {
+            if ((fonttype == FontType.TYPE0 || fonttype == FontType.CIDTYPE0)) {
                 font.setEncoding(encoding);
                 CIDFont cidMetrics;
                 if (metrics instanceof LazyFont) {
@@ -1357,16 +1363,30 @@ public class PDFFactory {
                 PDFCIDSystemInfo sysInfo = new PDFCIDSystemInfo(cidMetrics.getRegistry(),
                         cidMetrics.getOrdering(), cidMetrics.getSupplement());
                 sysInfo.setDocument(document);
+                assert pdfdesc instanceof PDFCIDFontDescriptor;
                 PDFCIDFont cidFont = new PDFCIDFont(subsetFontName, cidMetrics.getCIDType(),
                         cidMetrics.getDefaultWidth(), getFontWidths(cidMetrics), sysInfo,
                         (PDFCIDFontDescriptor) pdfdesc);
                 getDocument().registerObject(cidFont);
-                PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
+
+                PDFCMap cmap;
+                if (cidMetrics instanceof MultiByteFont && ((MultiByteFont) cidMetrics).getCmapStream() != null) {
+                    cmap = new PDFCMap("fop-ucs-H", null);
+                    try {
+                        cmap.setData(IOUtils.toByteArray(((MultiByteFont) cidMetrics).getCmapStream()));
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                } else {
+                    cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
                         new PDFCIDSystemInfo("Adobe", "Identity", 0), false);
+                }
                 getDocument().registerObject(cmap);
+                assert font instanceof PDFFontType0;
                 ((PDFFontType0)font).setCMAP(cmap);
                 ((PDFFontType0)font).setDescendantFonts(cidFont);
             } else {
+                assert font instanceof PDFFontNonBase14;
                 PDFFontNonBase14 nonBase14 = (PDFFontNonBase14)font;
                 nonBase14.setDescriptor(pdfdesc);
 
@@ -1432,6 +1452,29 @@ public class PDFFactory {
                     font.setEncoding(mapping.getName());
                     //No ToUnicode CMap necessary if PDF 1.4, chapter 5.9 (page 368) is to be
                     //believed.
+                } else if (mapping.getName().equals("FOPPDFEncoding")) {
+                    String[] charNameMap = mapping.getCharNameMap();
+                    char[] intmap = mapping.getUnicodeCharMap();
+                    PDFArray differences = new PDFArray();
+                    int len = intmap.length;
+                    if (charNameMap.length < len) {
+                        len = charNameMap.length;
+                    }
+                    int last = 0;
+                    for (int i = 0; i < len; i++) {
+                        if (intmap[i] - 1 != last) {
+                            differences.add(intmap[i]);
+                        }
+                        last = intmap[i];
+                        differences.add(new PDFName(charNameMap[i]));
+                    }
+                    PDFEncoding pdfEncoding = new PDFEncoding(singleByteFont.getEncodingName());
+                    getDocument().registerObject(pdfEncoding);
+                    pdfEncoding.setDifferences(differences);
+                    font.setEncoding(pdfEncoding);
+                    if (mapping.getUnicodeCharMap() != null) {
+                        generateToUnicodeCmap(nonBase14, mapping);
+                    }
                 } else {
                     Object pdfEncoding = createPDFEncoding(mapping,
                     singleByteFont.getFontName());
@@ -1495,8 +1538,30 @@ public class PDFFactory {
     private PDFWArray getFontWidths(CIDFont cidFont) {
         // Create widths for reencoded chars
         PDFWArray warray = new PDFWArray();
-        int[] widths = cidFont.getCIDSet().getWidths();
-        warray.addEntry(0, widths);
+        if (cidFont instanceof MultiByteFont && ((MultiByteFont)cidFont).getWidthsMap() != null) {
+            Map<Integer, Integer> map = ((MultiByteFont)cidFont).getWidthsMap();
+            for (Map.Entry<Integer, Integer> cid : map.entrySet()) {
+                warray.addEntry(cid.getKey(), new int[] {cid.getValue()});
+            }
+//            List<Integer> l = new ArrayList<Integer>(map.keySet());
+//            for (int i=0; i<map.size(); i++) {
+//                int cid = l.get(i);
+//                List<Integer> cids = new ArrayList<Integer>();
+//                cids.add(map.get(cid));
+//                while (i<map.size()-1 && l.get(i) + 1 == l.get(i + 1)) {
+//                    cids.add(map.get(l.get(i + 1)));
+//                    i++;
+//                }
+//                int[] cidsints = new int[cids.size()];
+//                for (int j=0; j<cids.size(); j++) {
+//                    cidsints[j] = cids.get(j);
+//                }
+//                warray.addEntry(cid, cidsints);
+//            }
+        } else {
+            int[] widths = cidFont.getCIDSet().getWidths();
+            warray.addEntry(0, widths);
+        }
         return warray;
     }
 
@@ -1526,7 +1591,7 @@ public class PDFFactory {
     private PDFFontDescriptor makeFontDescriptor(FontDescriptor desc, String fontPrefix) {
         PDFFontDescriptor descriptor = null;
 
-        if (desc.getFontType() == FontType.TYPE0) {
+        if (desc.getFontType() == FontType.TYPE0 || desc.getFontType() == FontType.CIDTYPE0) {
             // CID Font
             descriptor = new PDFCIDFontDescriptor(fontPrefix + desc.getEmbedFontName(),
                                             desc.getFontBBox(),
@@ -1610,55 +1675,64 @@ public class PDFFactory {
             in = font.getInputStream();
             if (in == null) {
                 return null;
-            } else {
-                AbstractPDFStream embeddedFont = null;
-                if (desc.getFontType() == FontType.TYPE0) {
-                    MultiByteFont mbfont = (MultiByteFont) font;
-                    FontFileReader reader = new FontFileReader(in);
-                    byte[] fontBytes;
-                    String header = OFFontLoader.readHeader(reader);
-                    boolean isCFF = mbfont.isOTFFile();
-                    if (font.getEmbeddingMode() == EmbeddingMode.FULL) {
-                        fontBytes = reader.getAllBytes();
-                        if (isCFF) {
-                            //Ensure version 1.6 for full OTF CFF embedding
-                            document.setPDFVersion(Version.V1_6);
-                        }
-                    } else {
-                        fontBytes = getFontSubsetBytes(reader, mbfont, header, fontPrefix, desc,
-                                isCFF);
-                    }
-                    embeddedFont = getFontStream(font, fontBytes, isCFF);
-                } else if (desc.getFontType() == FontType.TYPE1) {
-                    if (font.getEmbeddingMode() != EmbeddingMode.SUBSET) {
-                        embeddedFont = fullyEmbedType1Font(in);
-                    } else {
-                        assert font instanceof SingleByteFont;
-                        SingleByteFont sbfont = (SingleByteFont)font;
-                        Type1SubsetFile pfbFile = new Type1SubsetFile();
-                        byte[] subsetData = pfbFile.createSubset(in, sbfont, fontPrefix);
-                        InputStream subsetStream = new ByteArrayInputStream(subsetData);
-                        PFBParser parser = new PFBParser();
-                        PFBData pfb = parser.parsePFB(subsetStream);
-                        embeddedFont = new PDFT1Stream();
-                        ((PDFT1Stream) embeddedFont).setData(pfb);
+            }
+            AbstractPDFStream embeddedFont = null;
+            if (desc.getFontType() == FontType.TYPE0) {
+                MultiByteFont mbfont = (MultiByteFont) font;
+                FontFileReader reader = new FontFileReader(in);
+                byte[] fontBytes;
+                String header = OFFontLoader.readHeader(reader);
+                boolean isCFF = mbfont.isOTFFile();
+                if (font.getEmbeddingMode() == EmbeddingMode.FULL) {
+                    fontBytes = reader.getAllBytes();
+                    if (isCFF) {
+                        //Ensure version 1.6 for full OTF CFF embedding
+                        document.setPDFVersion(Version.V1_6);
                     }
                 } else {
-                    byte[] file = IOUtils.toByteArray(in);
-                    embeddedFont = new PDFTTFStream(file.length);
-                    ((PDFTTFStream) embeddedFont).setData(file, file.length);
+                    fontBytes = getFontSubsetBytes(reader, mbfont, header, fontPrefix, desc,
+                            isCFF);
                 }
-
-                /*
-                embeddedFont.getFilterList().addFilter("flate");
-                if (getDocument().isEncryptionActive()) {
-                    getDocument().applyEncryption(embeddedFont);
+                embeddedFont = getFontStream(font, fontBytes, isCFF);
+            } else if (desc.getFontType() == FontType.TYPE1) {
+                if (font.getEmbeddingMode() != EmbeddingMode.SUBSET) {
+                    embeddedFont = fullyEmbedType1Font(in);
                 } else {
-                    embeddedFont.getFilterList().addFilter("ascii-85");
-                }*/
-
-                return embeddedFont;
+                    assert font instanceof SingleByteFont;
+                    SingleByteFont sbfont = (SingleByteFont)font;
+                    Type1SubsetFile pfbFile = new Type1SubsetFile();
+                    byte[] subsetData = pfbFile.createSubset(in, sbfont);
+                    InputStream subsetStream = new ByteArrayInputStream(subsetData);
+                    PFBParser parser = new PFBParser();
+                    PFBData pfb = parser.parsePFB(subsetStream);
+                    embeddedFont = new PDFT1Stream();
+                    ((PDFT1Stream) embeddedFont).setData(pfb);
+                }
+            } else if (desc.getFontType() == FontType.TYPE1C) {
+                byte[] file = IOUtils.toByteArray(in);
+                PDFCFFStream embeddedFont2 = new PDFCFFStream("Type1C");
+                embeddedFont2.setData(file);
+                return embeddedFont2;
+            } else if (desc.getFontType() == FontType.CIDTYPE0) {
+                byte[] file = IOUtils.toByteArray(in);
+                PDFCFFStream embeddedFont2 = new PDFCFFStream("CIDFontType0C");
+                embeddedFont2.setData(file);
+                return embeddedFont2;
+            } else {
+                byte[] file = IOUtils.toByteArray(in);
+                embeddedFont = new PDFTTFStream(file.length);
+                ((PDFTTFStream) embeddedFont).setData(file, file.length);
             }
+
+            /*
+            embeddedFont.getFilterList().addFilter("flate");
+            if (getDocument().isEncryptionActive()) {
+                getDocument().applyEncryption(embeddedFont);
+            } else {
+                embeddedFont.getFilterList().addFilter("ascii-85");
+            }*/
+
+            return embeddedFont;
         } catch (IOException ioe) {
             log.error("Failed to embed font [" + desc + "] " + desc.getEmbedFontName(), ioe);
             return null;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java Wed Jul 16 09:10:53 2014
@@ -105,10 +105,11 @@ public class PDFFont extends PDFDictiona
     public static PDFFont createFont(String fontname,
                                      FontType subtype, String basefont,
                                      Object encoding) {
-        if (subtype == FontType.TYPE0) {
+        if (subtype == FontType.TYPE0 || subtype == FontType.CIDTYPE0) {
             return new PDFFontType0(fontname, basefont,
                                     encoding);
         } else if ((subtype == FontType.TYPE1)
+                || (subtype == FontType.TYPE1C)
                 || (subtype == FontType.MMTYPE1)) {
             return new PDFFontType1(fontname, basefont,
                                     encoding);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java Wed Jul 16 09:10:53 2014
@@ -102,7 +102,7 @@ public class PDFFontDescriptor extends P
     public void setFontFile(FontType subtype, AbstractPDFStream fontfile) {
         if (subtype == FontType.TYPE1) {
             put("FontFile", fontfile);
-        } else if (fontfile instanceof PDFCFFStreamType0C) {
+        } else if (fontfile instanceof PDFCFFStreamType0C || subtype == FontType.TYPE1C) {
             put("FontFile3", fontfile);
         } else {
             put("FontFile2", fontfile);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java Wed Jul 16 09:10:53 2014
@@ -245,7 +245,7 @@ public abstract class AbstractIFPainter<
         if (log.isTraceEnabled()) {
             log.trace("Using ImageHandler: " + handler.getClass().getName());
         }
-
+        context.putHint("fontinfo", getFontInfo());
         handler.handleImage(context, effImage, rect);
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java Wed Jul 16 09:10:53 2014
@@ -56,6 +56,7 @@ import static org.apache.fop.render.pdf.
 import static org.apache.fop.render.pdf.PDFEncryptionOption.USER_PASSWORD;
 import static org.apache.fop.render.pdf.PDFRendererOption.DISABLE_SRGB_COLORSPACE;
 import static org.apache.fop.render.pdf.PDFRendererOption.FILTER_LIST;
+import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
 import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
@@ -135,6 +136,7 @@ public final class PDFRendererConfig imp
                 configureEncryptionParams(cfg, userAgent, strict);
                 parseAndPut(OUTPUT_PROFILE, cfg);
                 parseAndPut(DISABLE_SRGB_COLORSPACE, cfg);
+                parseAndPut(MERGE_FONTS, cfg);
 
                 parseAndPut(VERSION, cfg);
             } catch (ConfigurationException e) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java Wed Jul 16 09:10:53 2014
@@ -66,6 +66,12 @@ public enum PDFRendererOption implements
             return Boolean.valueOf(value);
         }
     },
+    MERGE_FONTS("merge-fonts", false) {
+        @Override
+        Boolean deserialize(String value) {
+            return Boolean.valueOf(value);
+        }
+    },
     /** Rendering Options key for the ICC profile for the output intent. */
     OUTPUT_PROFILE("output-profile") {
         @Override

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java Wed Jul 16 09:10:53 2014
@@ -31,6 +31,7 @@ import org.apache.fop.pdf.Version;
 
 import static org.apache.fop.render.pdf.PDFRendererOption.DISABLE_SRGB_COLORSPACE;
 import static org.apache.fop.render.pdf.PDFRendererOption.FILTER_LIST;
+import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
 import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
@@ -120,4 +121,8 @@ public final class PDFRendererOptionsCon
     public Version getPDFVersion() {
         return (Version) properties.get(VERSION);
     }
+
+    public Boolean getMergeFontsEnabled() {
+        return (Boolean)properties.get(MERGE_FONTS);
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java Wed Jul 16 09:10:53 2014
@@ -581,6 +581,7 @@ class PDFRenderingUtil {
         }
 
         this.pdfDoc.enableAccessibility(userAgent.isAccessibilityEnabled());
+        pdfDoc.setMergeFontsEnabled(rendererConfig.getMergeFontsEnabled());
 
         return this.pdfDoc;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSFontUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSFontUtils.java?rev=1610947&r1=1610946&r2=1610947&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSFontUtils.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSFontUtils.java Wed Jul 16 09:10:53 2014
@@ -324,7 +324,7 @@ public class PSFontUtils extends org.apa
         boolean embed = true;
         if (font.getEmbeddingMode() == EmbeddingMode.SUBSET) {
             Type1SubsetFile subset = new Type1SubsetFile();
-            byte[] byteSubset = subset.createSubset(fontStream, font, "");
+            byte[] byteSubset = subset.createSubset(fontStream, font);
             fontStream = new ByteArrayInputStream(byteSubset);
         }
         embedType1Font(gen, fontStream);



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org