You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2014/01/05 16:37:49 UTC

svn commit: r1555529 - in /pdfbox/trunk: fontbox/src/main/java/org/apache/fontbox/cff/ fontbox/src/main/java/org/apache/fontbox/encoding/ pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/

Author: lehmi
Date: Sun Jan  5 15:37:49 2014
New Revision: 1555529

URL: http://svn.apache.org/r1555529
Log:
PDFBOX-1831: rearranged/improved code to support composite glyphs as proposed by John Hewson

Added:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java   (with props)
Removed:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringConverter.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java
Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java Sun Jan  5 15:37:49 2014
@@ -29,7 +29,7 @@ import org.apache.fontbox.cff.encoding.C
  * This class creates all needed AFM font metric data from a CFFFont ready to be read from a AFMPaser.
  * 
  * @author Villu Ruusmann
- * @version $Revision$
+ * 
  */
 public class AFMFormatter
 {
@@ -116,16 +116,14 @@ public class AFMFormatter
     private static List<CharMetric> renderFont(CFFFont font) throws IOException
     {
         List<CharMetric> metrics = new ArrayList<CharMetric>();
-        CharStringRenderer renderer = font.createRenderer();
         Collection<CFFFont.Mapping> mappings = font.getMappings();
         for (CFFFont.Mapping mapping : mappings)
         {
             CharMetric metric = new CharMetric();
             metric.code = mapping.getCode();
             metric.name = mapping.getName();
-            renderer.render(mapping.toType1Sequence());
-            metric.width = renderer.getWidth();
-            metric.bounds = renderer.getBounds();
+            metric.width = mapping.getType1CharString().getWidth();
+            metric.bounds = mapping.getType1CharString().getBounds();
             metrics.add(metric);
         }
         return metrics;

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java Sun Jan  5 15:37:49 2014
@@ -17,13 +17,7 @@
 package org.apache.fontbox.cff;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.fontbox.cff.charset.CFFCharset;
 import org.apache.fontbox.cff.encoding.CFFEncoding;
@@ -32,11 +26,10 @@ import org.apache.fontbox.cff.encoding.C
  * This class represents a CFF/Type2 Font.
  * 
  * @author Villu Ruusmann
- * 
+ * @author John Hewson
  */
 public class CFFFont
 {
-
     private String fontname = null;
     private Map<String, Object> topDict = new LinkedHashMap<String, Object>();
     private Map<String, Object> privateDict = new LinkedHashMap<String, Object>();
@@ -45,6 +38,7 @@ public class CFFFont
     private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
     private IndexData globalSubrIndex = null;
     private IndexData localSubrIndex = null;
+    private Map<String, Type2CharString> charStringCache = new HashMap<String, Type2CharString>();
 
     /**
      * The name of the font.
@@ -220,44 +214,25 @@ public class CFFFont
     /**
      * Return the Width value of the given Glyph identifier.
      * 
-     * @param SID
+     * @param sid SID
      * @return -1 if the SID is missing from the Font.
      * @throws IOException if something went wrong
      * 
      */
-    public int getWidth(int SID) throws IOException
+    public int getWidth(int sid) throws IOException
     {
-        int nominalWidth = privateDict.containsKey("nominalWidthX") ? ((Number) privateDict.get("nominalWidthX"))
-                .intValue() : 0;
-        int defaultWidth = privateDict.containsKey("defaultWidthX") ? ((Number) privateDict.get("defaultWidthX"))
-                .intValue() : 1000;
-
         for (Mapping m : getMappings())
         {
-            if (m.getSID() == SID)
+            if (m.getSID() == sid)
             {
-
-                CharStringRenderer csr = null;
-                if (((Number) getProperty("CharstringType")).intValue() == 2)
-                {
-                    List<Object> lSeq = m.toType2Sequence();
-                    csr = new CharStringRenderer(false);
-                    csr.render(lSeq);
-                }
-                else
-                {
-                    List<Object> lSeq = m.toType1Sequence();
-                    csr = new CharStringRenderer();
-                    csr.render(lSeq);
-                }
-
-                // ---- If the CharString has a Width nominalWidthX must be added,
-                // otherwise it is the default width.
-                return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+                Type1CharString charstring = m.getType1CharString();
+                return charstring.getWidth();
             }
         }
 
-        // ---- SID Width not found, return the nodef width
+        // SID not found, return the nodef width
+        int nominalWidth = getNominalWidthX(sid);
+        int defaultWidth = getDefaultWidthX(sid);
         return getNotDefWidth(defaultWidth, nominalWidth);
     }
 
@@ -271,23 +246,8 @@ public class CFFFont
      */
     protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException
     {
-        CharStringRenderer csr;
-        byte[] glyphDesc = this.getCharStringsDict().get(".notdef");
-        if (((Number) getProperty("CharstringType")).intValue() == 2)
-        {
-            Type2CharStringParser parser = new Type2CharStringParser();
-            List<Object> lSeq = parser.parse(glyphDesc, getGlobalSubrIndex(), getLocalSubrIndex());
-            csr = new CharStringRenderer(false);
-            csr.render(lSeq);
-        }
-        else
-        {
-            Type1CharStringParser parser = new Type1CharStringParser();
-            List<Object> lSeq = parser.parse(glyphDesc, getLocalSubrIndex());
-            csr = new CharStringRenderer();
-            csr.render(lSeq);
-        }
-        return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+        Type1CharString charstring = getType1CharString(".notdef");
+        return charstring.getWidth() != 0 ? charstring.getWidth() + nominalWidth : defaultWidth;
     }
 
     /**
@@ -331,6 +291,25 @@ public class CFFFont
     }
 
     /**
+     * Returns the SID for a given glyph name.
+     * @param name glyph name
+     * @return SID
+     */
+    private int getSIDForName(String name)
+    {
+        int sid = 0; // .notdef
+        for (Mapping m : getMappings())
+        {
+            if (m.getName().equals(name))
+            {
+                sid = m.getSID();
+                break;
+            }
+        }
+      return sid;
+    }
+
+    /**
      * Returns the character strings dictionary.
      * 
      * @return the dictionary
@@ -341,25 +320,65 @@ public class CFFFont
     }
 
     /**
-     * Creates a CharStringConverter for this font.
-     * 
-     * @return the new CharStringConverter
+     * Returns the Type 1 CharString for the character with the given name.
+     *
+     * @return Type 1 CharString
+     * @throws IOException if something went wrong
+     *
      */
-    public CharStringConverter createConverter()
+    public Type1CharString getType1CharString(String name) throws IOException
     {
-        Number defaultWidthX = (Number) getProperty("defaultWidthX");
-        Number nominalWidthX = (Number) getProperty("nominalWidthX");
-        return new CharStringConverter(defaultWidthX.intValue(), nominalWidthX.intValue());
+        return getType1CharString(name, getSIDForName(name));
     }
 
     /**
-     * Creates a CharStringRenderer for this font.
-     * 
-     * @return the new CharStringRenderer
+     * Returns the Type 1 CharString for the character with the given name and SID.
+     *
+     * @return Type 1 CharString
+     */
+    private Type1CharString getType1CharString(String name, int sid) throws IOException
+    {
+        Type2CharString type2 = charStringCache.get(name);
+        if (type2 == null)
+        {
+            Type2CharStringParser parser = new Type2CharStringParser();
+            List<Object> type2seq = parser.parse(charStringsDict.get(name), globalSubrIndex, localSubrIndex);
+            type2 = new Type2CharString(this, type2seq, getDefaultWidthX(sid), getNominalWidthX(sid));
+            charStringCache.put(name, type2);
+        }
+        return type2;
+    }
+
+    /**
+     * Returns the defaultWidthX for the given SID.
+     *
+     * @param sid SID
+     * @return defaultWidthX
+     */
+    protected int getDefaultWidthX(int sid)
+    {
+        Number num = (Number)getProperty("defaultWidthX");
+        if (num == null)
+        {
+            return 1000;
+        }
+        return num.intValue();
+    }
+
+    /**
+     * Returns the nominalWidthX for the given SID.
+     *
+     * @param sid SID
+     * @return defaultWidthX
      */
-    public CharStringRenderer createRenderer()
+    protected int getNominalWidthX(int sid)
     {
-        return new CharStringRenderer();
+        Number num = (Number)getProperty("nominalWidthX");
+        if (num == null)
+        {
+            return 0;
+        }
+        return num.intValue();
     }
 
     /**
@@ -414,7 +433,6 @@ public class CFFFont
 
     /**
      * This class is used for the font mapping.
-     * 
      */
     public class Mapping
     {
@@ -424,27 +442,14 @@ public class CFFFont
         private byte[] mappedBytes;
 
         /**
-         * Converts the mapping into a Type1-sequence.
-         * 
-         * @return the Type1-sequence
+         * Returns the Type 1 CharString for the character.
+         *
+         * @return the Type 1 CharString
          * @throws IOException if an error occurs during reading
          */
-        public List<Object> toType1Sequence() throws IOException
+        public Type1CharString getType1CharString() throws IOException
         {
-            CharStringConverter converter = createConverter();
-            return converter.convert(toType2Sequence());
-        }
-
-        /**
-         * Converts the mapping into a Type2-sequence.
-         * 
-         * @return the Type2-sequence
-         * @throws IOException if an error occurs during reading
-         */
-        public List<Object> toType2Sequence() throws IOException
-        {
-            Type2CharStringParser parser = new Type2CharStringParser();
-            return parser.parse(getBytes(), getGlobalSubrIndex(), getLocalSubrIndex());
+            return CFFFont.this.getType1CharString(mappedName, mappedSID);
         }
 
         /**

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java Sun Jan  5 15:37:49 2014
@@ -22,168 +22,209 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
-public class CFFFontROS extends CFFFont {
-	private String registry;
-	private String ordering;
-	private int supplement;
-
-	private List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String,Object>>();
-	private List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String,Object>>();
-	private CIDKeyedFDSelect fdSelect = null;
-
-	/**
-	 * Returns the registry value.
-	 * @return the registry
-	 */
-	public String getRegistry() {
-		return registry;
-	}
-
-	/**
-	 * Sets the registry value.
-	 * 
-	 * @param registry the registry to set
-	 */
-	public void setRegistry(String registry) {
-		this.registry = registry;
-	}
-
-	/**
-	 * Returns the ordering value.
-	 * 
-	 * @return the ordering
-	 */
-	public String getOrdering() {
-		return ordering;
-	}
-
-	/**
-	 * Sets the ordering value.
-	 * 
-	 * @param ordering the ordering to set
-	 */
-	public void setOrdering(String ordering) {
-		this.ordering = ordering;
-	}
-
-	/**
-	 * Returns the supplement value.
-	 * 
-	 * @return the supplement
-	 */
-	public int getSupplement() {
-		return supplement;
-	}
-
-	/**
-	 * Sets the supplement value.
-	 * 
-	 * @param supplement the supplement to set
-	 */
-	public void setSupplement(int supplement) {
-		this.supplement = supplement;
-	}
-
-	/**
-	 * Returns the font dictionaries.
-	 * 
-	 * @return the fontDict
-	 */
-	public List<Map<String, Object>> getFontDict() {
-		return fontDictionaries;
-	}
-
-	/**
-	 * Sets the font dictionaries.
-	 * 
-	 * @param fontDict the fontDict to set
-	 */
-	public void setFontDict(List<Map<String, Object>> fontDict) {
-		this.fontDictionaries = fontDict;
-	}
-
-	/**
-	 * Returns the private dictionary.
-	 * 
-	 * @return the privDict
-	 */
-	public List<Map<String, Object>> getPrivDict() {
-		return privateDictionaries;
-	}
-
-	/**
-	 * Sets the private dictionary.
-	 * 
-	 * @param privDict the privDict to set
-	 */
-	public void setPrivDict(List<Map<String, Object>> privDict) {
-		this.privateDictionaries = privDict;
-	}
-
-	/**
-	 * Returns the fdSelect value.
-	 * 
-	 * @return the fdSelect
-	 */
-	public CIDKeyedFDSelect getFdSelect() {
-		return fdSelect;
-	}
-
-	/**
-	 * Sets the fdSelect value.
-	 * 
-	 * @param fdSelect the fdSelect to set
-	 */
-	public void setFdSelect(CIDKeyedFDSelect fdSelect) {
-		this.fdSelect = fdSelect;
-	}
-
-	/**
-	 * Returns the Width value of the given Glyph identifier
-	 * 
-	 * @param CID
-	 * @return -1 if the SID is missing from the Font.
-	 * @throws IOException
-	 */
-	public int getWidth(int CID) throws IOException {
-		// ---- search the right FDArray index in the FDSelect according to the Character identifier
-		// 		this index will be used to access the private dictionary which contains useful values 
-		//		to compute width.
-		int fdArrayIndex = this.fdSelect.getFd(CID);
-		if (fdArrayIndex == -1 && CID == 0 ) { // --- notdef char
-			return super.getWidth(CID);
-		} else if (fdArrayIndex == -1) {
-			return 1000;
-		}
-		
-		Map<String, Object> fontDict = this.fontDictionaries.get(fdArrayIndex);
-		Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
-
-		int nominalWidth = privDict.containsKey("nominalWidthX") ? ((Number)privDict.get("nominalWidthX")).intValue() : 0;
-		int defaultWidth = privDict.containsKey("defaultWidthX") ? ((Number)privDict.get("defaultWidthX")).intValue() : 1000 ;
-
-		for (Mapping m : getMappings() ){
-			if (m.getSID() == CID) {
-
-				CharStringRenderer csr = null;
-				Number charStringType = (Number)getProperty("CharstringType");
-				if ( charStringType.intValue() == 2 ) {
-					List<Object> lSeq = m.toType2Sequence();
-					csr = new CharStringRenderer(false);
-					csr.render(lSeq);
-				} else {
-					List<Object> lSeq = m.toType1Sequence();
-					csr = new CharStringRenderer();
-					csr.render(lSeq);
-				}
-
-				// ---- If the CharString has a Width nominalWidthX must be added, 
-				//	    otherwise it is the default width.
-				return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
-			}
-		}
-
-		// ---- CID Width not found, return the notdef width
-		return getNotDefWidth(defaultWidth, nominalWidth);
-	}
-}
+/**
+ * This class represents a CID-Keyed CFF/Type2 Font.
+ *
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class CFFFontROS extends CFFFont
+{
+    private String registry;
+    private String ordering;
+    private int supplement;
+
+    private List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String,Object>>();
+    private List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String,Object>>();
+    private CIDKeyedFDSelect fdSelect = null;
+
+    /**
+     * Returns the registry value.
+     * * @return the registry
+     */
+    public String getRegistry() 
+    {
+        return registry;
+    }
+
+    /**
+     * Sets the registry value.
+     *
+     * @param registry the registry to set
+     */
+    public void setRegistry(String registry) 
+    {
+        this.registry = registry;
+    }
+
+    /**
+     * Returns the ordering value.
+     *
+     * @return the ordering
+     */
+    public String getOrdering() 
+    {
+        return ordering;
+    }
+
+    /**
+     * Sets the ordering value.
+     *
+     * @param ordering the ordering to set
+     */
+    public void setOrdering(String ordering) 
+    {
+        this.ordering = ordering;
+    }
+
+    /**
+     * Returns the supplement value.
+     *
+     * @return the supplement
+     */
+    public int getSupplement() 
+    {
+        return supplement;
+    }
+
+    /**
+     * Sets the supplement value.
+     *
+     * @param supplement the supplement to set
+     */
+    public void setSupplement(int supplement) 
+    {
+        this.supplement = supplement;
+    }
+
+    /**
+     * Returns the font dictionaries.
+     *
+     * @return the fontDict
+     */
+    public List<Map<String, Object>> getFontDict() 
+    {
+        return fontDictionaries;
+    }
+
+    /**
+     * Sets the font dictionaries.
+     *
+     * @param fontDict the fontDict to set
+     */
+    public void setFontDict(List<Map<String, Object>> fontDict)
+    {
+        this.fontDictionaries = fontDict;
+    }
+
+    /**
+     * Returns the private dictionary.
+     *
+     * @return the privDict
+     */
+    public List<Map<String, Object>> getPrivDict() 
+    {
+        return privateDictionaries;
+    }
+
+    /**
+     * Sets the private dictionary.
+     *
+     * @param privDict the privDict to set
+     */
+    public void setPrivDict(List<Map<String, Object>> privDict) 
+    {
+        this.privateDictionaries = privDict;
+    }
+
+    /**
+     * Returns the fdSelect value.
+     *
+     * @return the fdSelect
+     */
+    public CIDKeyedFDSelect getFdSelect() 
+    {
+        return fdSelect;
+    }
+
+    /**
+     * Sets the fdSelect value.
+     *
+     * @param fdSelect the fdSelect to set
+     */
+    public void setFdSelect(CIDKeyedFDSelect fdSelect) 
+    {
+        this.fdSelect = fdSelect;
+    }
+
+    /**
+     * Returns the Width value of the given Glyph identifier
+     *
+     * @param cid CID
+     * @return -1 if the CID is missing from the Font.
+     * @throws IOException
+     */
+    public int getWidth(int cid) throws IOException
+    {
+        // search the right FDArray index in the FDSelect according to the Character identifier
+        // this index will be used to access the private dictionary which contains useful values
+        // to compute width.
+        int fdArrayIndex = this.fdSelect.getFd(cid);
+        if (fdArrayIndex == -1 && cid == 0 ) // notdef char
+        {
+            return super.getWidth(cid);
+        }
+        else if (fdArrayIndex == -1)
+        {
+            return 1000;
+        }
+
+        for (Mapping m : getMappings())
+        {
+            if (m.getSID() == cid)
+            {
+                Type1CharString charstring = m.getType1CharString();
+                return charstring.getWidth();
+            }
+        }
+        
+        // CID not found, return the notdef width
+        int nominalWidth = getNominalWidthX(cid);
+        int defaultWidth = getDefaultWidthX(cid);
+        return getNotDefWidth(defaultWidth, nominalWidth);
+    }
+
+    /**
+     * Returns the defaultWidthX for the given CID.
+     *
+     * @param cid CID
+     * @return defaultWidthX
+     */
+    protected int getDefaultWidthX(int cid)
+    {
+        int fdArrayIndex = this.fdSelect.getFd(cid);
+        if (fdArrayIndex == -1)
+        {
+            return 1000;
+        }
+        Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
+        return privDict.containsKey("defaultWidthX") ? ((Number)privDict.get("defaultWidthX")).intValue() : 1000;
+    }
+
+    /**
+     * Returns the nominalWidthX for the given CID.
+     *
+     * @param cid CID
+     * @return defaultWidthX
+     */
+    protected int getNominalWidthX(int cid)
+    {
+        int fdArrayIndex = this.fdSelect.getFd(cid);
+        if (fdArrayIndex == -1)
+        {
+            return 0;
+        }
+        Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
+        return privDict.containsKey("nominalWidthX") ? ((Number)privDict.get("nominalWidthX")).intValue() : 0;
+    }
+}
\ No newline at end of file

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java Sun Jan  5 15:37:49 2014
@@ -21,24 +21,21 @@ import java.util.List;
 
 /**
  * A Handler for CharStringCommands.
- * 
+ *
  * @author Villu Ruusmann
- * @version $Revision$
+ * 
  */
 public abstract class CharStringHandler
 {
-
     /**
      * Handler for a sequence of CharStringCommands.
-     * 
+     *
      * @param sequence of CharStringCommands
-     * 
-     * @return may return a command sequence of a subroutine
+     *
      */
     @SuppressWarnings(value = { "unchecked" })
-    public List<Integer> handleSequence(List<Object> sequence)
+    public void handleSequence(List<Object> sequence)
     {
-        List<Integer> numbers = null;
         int offset = 0;
         int size = sequence.size();
         for (int i = 0; i < size; i++)
@@ -46,30 +43,18 @@ public abstract class CharStringHandler
             Object object = sequence.get(i);
             if (object instanceof CharStringCommand)
             {
-                if (numbers == null)
-                    numbers = (List) sequence.subList(offset, i);
-                else 
-                    numbers.addAll((List) sequence.subList(offset, i));
-                List<Integer> stack = handleCommand(numbers, (CharStringCommand) object);
-                if (stack != null && !stack.isEmpty())
-                    numbers = stack;
-                else
-                    numbers = null;
+                List<Integer> numbers = (List) sequence.subList(offset, i);
+                handleCommand(numbers, (CharStringCommand) object);
                 offset = i + 1;
             }
         }
-        if (numbers != null && !numbers.isEmpty())
-            return numbers;
-        else
-            return null;
     }
+
     /**
      * Handler for CharStringCommands.
-     *  
+     *
      * @param numbers a list of numbers
      * @param command the CharStringCommand
-     * 
-     * @return may return a command sequence of a subroutine
      */
-    public abstract List<Integer> handleCommand(List<Integer> numbers, CharStringCommand command);
+    public abstract void handleCommand(List<Integer> numbers, CharStringCommand command);
 }
\ No newline at end of file

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java Sun Jan  5 15:37:49 2014
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cff;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.encoding.StandardEncoding;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * This class represents and renders a Type 1 CharString.
+ *
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class Type1CharString
+{
+    private static final Log LOG = LogFactory.getLog(Type1CharString.class);
+
+    private CFFFont cffFont;
+    private GeneralPath path = null;
+    private int width = 0;
+    private Point2D leftSideBearing = null;
+    private Point2D referencePoint = null;
+    protected List<Object> type1Sequence;
+
+    /**
+     * Constructs a new Type1CharString object.
+     * @param font Parent CFF font
+     * @param sequence Type 1 char string sequence
+     */
+    public Type1CharString(CFFFont font, List<Object> sequence)
+    {
+        this(font);
+        type1Sequence = sequence;
+    }
+
+    /**
+     * Constructor for use in subclasses.
+     * @param font Parent CFF font
+     */
+    protected Type1CharString(CFFFont font)
+    {
+        cffFont = font;
+    }
+
+    /**
+     * Returns the bounds of the renderer path.
+     * @return the bounds as Rectangle2D
+     */
+    public Rectangle2D getBounds()
+    {
+        if (path == null)
+        {
+            render();
+        }
+        return path.getBounds2D();
+    }
+
+    /**
+     * Returns the advance width of the glyph.
+     * @return the width
+     */
+    public int getWidth()
+    {
+        if (path == null)
+        {
+          render();
+        }
+        return width;
+    }
+
+    /**
+     * Returns the path of the character.
+     * @return the path
+     */
+    public GeneralPath getPath()
+    {
+        //TODO does not need to be lazy anymore?
+        if (path == null)
+        {
+          render();
+        }
+        return path;
+    }
+
+    /**
+     * Returns the Type 1 char string sequence.
+     * @return the Type 1 sequence
+     */
+    public List<Object> getType1Sequence()
+    {
+        return type1Sequence;
+    }
+
+    /**
+     * Renders the Type 1 char string sequence to a GeneralPath.
+     */
+    private void render() 
+    {
+        path = new GeneralPath();
+        leftSideBearing = new Point2D.Float(0, 0);
+        referencePoint = null;
+        width = 0;
+        CharStringHandler handler = new CharStringHandler() {
+            public void handleCommand(List<Integer> numbers, CharStringCommand command)
+            {
+                Type1CharString.this.handleCommand(numbers, command);
+            }
+        };
+        handler.handleSequence(type1Sequence);
+    }
+
+    private void handleCommand(List<Integer> numbers, CharStringCommand command)
+    {
+        String name = CharStringCommand.TYPE1_VOCABULARY.get(command.getKey());
+
+        if ("vmoveto".equals(name))
+        {
+            rmoveTo(0, numbers.get(0));
+        }
+        else if ("rlineto".equals(name))
+        {
+            rlineTo(numbers.get(0), numbers.get(1));
+        }
+        else if ("hlineto".equals(name))
+        {
+            rlineTo(numbers.get(0), 0);
+        }
+        else if ("vlineto".equals(name))
+        {
+            rlineTo(0, numbers.get(0));
+        }
+        else if ("rrcurveto".equals(name))
+        {
+            rrcurveTo(numbers.get(0), numbers.get(1), numbers.get(2), numbers
+                .get(3), numbers.get(4), numbers.get(5));
+        }
+        else if ("closepath".equals(name))
+        {
+            closepath();
+        }
+        else if ("sbw".equals(name))
+        {
+            leftSideBearing = new Point2D.Float(numbers.get(0), numbers.get(1));
+            width = numbers.get(2);
+        }
+        else if ("hsbw".equals(name))
+        {
+            leftSideBearing = new Point2D.Float(numbers.get(0), 0);
+            width = numbers.get(1);
+        }
+        else if ("rmoveto".equals(name))
+        {
+            rmoveTo(numbers.get(0), numbers.get(1));
+        }
+        else if ("hmoveto".equals(name))
+        {
+            rmoveTo(numbers.get(0), 0);
+        }
+        else if ("vhcurveto".equals(name))
+        {
+            rrcurveTo(0, numbers.get(0), numbers.get(1),
+                numbers.get(2), numbers.get(3), 0);
+        }
+        else if ("hvcurveto".equals(name))
+        {
+            rrcurveTo(numbers.get(0), 0, numbers.get(1),
+                numbers.get(2), 0, numbers.get(3));
+        }
+        else if ("seac".equals(name))
+        {
+            seac(numbers.get(0), numbers.get(1), numbers.get(2), numbers.get(3), numbers.get(4));
+        }
+    }
+
+    /**
+     * Relative moveto.
+     */
+    private void rmoveTo(Number dx, Number dy)
+    {
+        Point2D point = referencePoint;
+        if (point == null)
+        {
+            point = path.getCurrentPoint();
+            if (point == null)
+            {
+                point = leftSideBearing;
+            }
+        }
+        referencePoint = null;
+        path.moveTo((float)(point.getX() + dx.doubleValue()),
+                    (float)(point.getY() + dy.doubleValue()));
+    }
+
+    /**
+     * Relative lineto.
+     */
+    private void rlineTo(Number dx, Number dy)
+    {
+        Point2D point = path.getCurrentPoint();
+        path.lineTo((float)(point.getX() + dx.doubleValue()),
+                    (float)(point.getY() + dy.doubleValue()));
+    }
+
+    /**
+     * Relative curveto.
+     */
+    private void rrcurveTo(Number dx1, Number dy1, Number dx2, Number dy2,
+            Number dx3, Number dy3)
+    {
+        Point2D point = path.getCurrentPoint();
+        float x1 = (float) point.getX() + dx1.floatValue();
+        float y1 = (float) point.getY() + dy1.floatValue();
+        float x2 = x1 + dx2.floatValue();
+        float y2 = y1 + dy2.floatValue();
+        float x3 = x2 + dx3.floatValue();
+        float y3 = y2 + dy3.floatValue();
+        path.curveTo(x1, y1, x2, y2, x3, y3);
+    }
+
+    /**
+     * Close path.
+     */
+    private void closepath()
+    {
+        referencePoint = path.getCurrentPoint();
+        path.closePath();
+    }
+
+    /**
+     * Standard Encoding Accented Character
+     *
+     * Makes an accented character from two other characters.
+     */
+    private void seac(Number asb, Number adx, Number ady, Number bchar, Number achar)
+    {
+        // base character
+        String baseName = StandardEncoding.INSTANCE.getName(bchar.intValue());
+        if (baseName != null)
+        {
+            try
+            {
+                Type1CharString base = cffFont.getType1CharString(baseName);
+                path.append(base.getPath().getPathIterator(null), false);
+            }
+            catch (IOException e)
+            {
+                LOG.warn("invalid character in seac command");
+            }
+        }
+        // accent character
+        String accentName = StandardEncoding.INSTANCE.getName(achar.intValue());
+        if (accentName != null)
+        {
+            try
+            {
+                Type1CharString accent = cffFont.getType1CharString(accentName);
+                AffineTransform at = AffineTransform.getTranslateInstance(
+                    leftSideBearing.getX() + adx.floatValue(),
+                    leftSideBearing.getY() + ady.floatValue());
+                path.append(accent.getPath().getPathIterator(at), false);
+            }
+            catch (IOException e)
+            {
+                LOG.warn("invalid character in seac command");
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java Sun Jan  5 15:37:49 2014
@@ -174,7 +174,7 @@ public class Type1FontFormatter
 
         for (CFFFont.Mapping mapping : mappings)
         {
-            byte[] type1Bytes = formatter.format(mapping.toType1Sequence());
+            byte[] type1Bytes = formatter.format(mapping.getType1CharString().getType1Sequence());
 
             byte[] charstringBytes = Type1FontUtil.charstringEncrypt(
                     type1Bytes, 4);

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java Sun Jan  5 15:37:49 2014
@@ -0,0 +1,383 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents a Type 2 CharString by converting it into an equivalent Type 1 CharString.
+ * 
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class Type2CharString extends Type1CharString
+{
+    private int defWidthX = 0;
+    private int nominalWidthX = 0;
+    private int pathCount = 0;
+    private List<Object> type2sequence;
+
+    /**
+     * Constructor.
+     * @param font Parent CFF font
+     * @param sequence Type 2 char string sequence
+     * @param defaultWidthX default width
+     * @param nomWidthX nominal width width
+     */
+    public Type2CharString(CFFFont font, List<Object> sequence, int defaultWidthX, int nomWidthX)
+    {
+        super(font);
+        type2sequence = sequence;
+        defWidthX = defaultWidthX;
+        nominalWidthX = nomWidthX;
+        convertType1ToType2(sequence);
+    }
+
+    /**
+     * Returns the advance width of the glyph.
+     * @return the width
+     */
+    public int getWidth()
+    {
+        int width = super.getWidth();
+        if (width == 0)
+        {
+            return defWidthX;
+        }
+        else
+        {
+            return nominalWidthX + width;
+        }
+    }
+
+    /**
+     * Returns the Type 2 char string sequence.
+     * @return the Type 2 sequence
+     */
+    public List<Object> getType2Sequence()
+    {
+        return type2sequence;
+    }
+
+    /**
+     * Converts a sequence of Type 2 commands into a sequence of Type 1 commands.
+     * @param sequence the Type 2 char string sequence
+     */
+    private void convertType1ToType2(List<Object> sequence)
+    {
+        type1Sequence = new ArrayList<Object>();
+        pathCount = 0;
+        CharStringHandler handler = new CharStringHandler() {
+            public void handleCommand(List<Integer> numbers, CharStringCommand command)
+            {
+                Type2CharString.this.handleCommand(numbers, command);
+            }
+        };
+        handler.handleSequence(sequence);
+    }
+
+    @SuppressWarnings(value = { "unchecked" })
+    private void handleCommand(List<Integer> numbers, CharStringCommand command)
+    {
+        String name = CharStringCommand.TYPE2_VOCABULARY.get(command.getKey());
+
+        if ("hstem".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() % 2 != 0);
+            expandStemHints(numbers, true);
+        }
+        else if ("vstem".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() % 2 != 0);
+            expandStemHints(numbers, false);
+        }
+        else if ("vmoveto".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() > 1);
+            markPath();
+            addCommand(numbers, command);
+        }
+        else if ("rlineto".equals(name))
+        {
+            addCommandList(split(numbers, 2), command);
+        }
+        else if ("hlineto".equals(name))
+        {
+            drawAlternatingLine(numbers, true);
+        }
+        else if ("vlineto".equals(name))
+        {
+            drawAlternatingLine(numbers, false);
+        }
+        else if ("rrcurveto".equals(name))
+        {
+            addCommandList(split(numbers, 6), command);
+        }
+        else if ("endchar".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() == 5);
+            closePath();
+            if (numbers.size() == 4)
+            {
+                // deprecated "seac" operator
+                numbers.add(0, 0);
+                addCommand(numbers, new CharStringCommand(12, 6));
+            }
+            else
+            {
+                addCommand(numbers, command);
+            }
+        }
+        else if ("rmoveto".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() > 2);
+            markPath();
+            addCommand(numbers, command);
+        }
+        else if ("hmoveto".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() > 1);
+            markPath();
+            addCommand(numbers, command);
+        }
+        else if ("vhcurveto".equals(name))
+        {
+            drawAlternatingCurve(numbers, false);
+        }
+        else if ("hvcurveto".equals(name))
+        {
+            drawAlternatingCurve(numbers, true);
+        }
+        else if ("hflex".equals(name))
+        {
+            List<Integer> first = Arrays.asList(numbers.get(0), 0,
+                    numbers.get(1), numbers.get(2), numbers.get(3), 0);
+            List<Integer> second = Arrays.asList(numbers.get(4), 0,
+                    numbers.get(5), -numbers.get(2),
+                    numbers.get(6), 0);
+            addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+        } 
+        else if ("flex".equals(name))
+        {
+            List<Integer> first = numbers.subList(0, 6);
+            List<Integer> second = numbers.subList(6, 12);
+            addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+        }
+        else if ("hflex1".equals(name))
+        {
+            List<Integer> first = Arrays.asList(numbers.get(0), numbers.get(1), 
+                    numbers.get(2), numbers.get(3), numbers.get(4), 0);
+            List<Integer> second = Arrays.asList(numbers.get(5), 0,
+                    numbers.get(6), numbers.get(7), numbers.get(8), 0);
+            addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+        }
+        else if ("flex1".equals(name))
+        {
+            int dx = 0;
+            int dy = 0;
+            for(int i = 0; i < 5; i++)
+            {
+                dx += numbers.get(i * 2);
+                dy += numbers.get(i * 2 + 1);
+            }
+            List<Integer> first = numbers.subList(0, 6);
+            List<Integer> second = Arrays.asList(numbers.get(6), numbers.get(7), numbers.get(8), 
+                    numbers.get(9), (Math.abs(dx) > Math.abs(dy) ? numbers.get(10) : Integer.valueOf(-dx)), 
+                    (Math.abs(dx) > Math.abs(dy) ? Integer.valueOf(-dy) : numbers.get(10)));
+            addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+        }
+        else if ("hstemhm".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() % 2 != 0);
+            expandStemHints(numbers, true);
+        } 
+        else if ("hintmask".equals(name) || "cntrmask".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() % 2 != 0);
+            if (numbers.size() > 0)
+            {
+                expandStemHints(numbers, false);
+            }
+        } 
+        else if ("vstemhm".equals(name))
+        {
+            numbers = clearStack(numbers, numbers.size() % 2 != 0);
+            expandStemHints(numbers, false);
+        } 
+        else if ("rcurveline".equals(name))
+        {
+            addCommandList(split(numbers.subList(0, numbers.size() - 2), 6),
+                    new CharStringCommand(8));
+            addCommand(numbers.subList(numbers.size() - 2, numbers.size()),
+                    new CharStringCommand(5));
+        } 
+        else if ("rlinecurve".equals(name))
+        {
+            addCommandList(split(numbers.subList(0, numbers.size() - 6), 2),
+                    new CharStringCommand(5));
+            addCommand(numbers.subList(numbers.size() - 6, numbers.size()),
+                    new CharStringCommand(8));
+        } 
+        else if ("vvcurveto".equals(name))
+        {
+            drawCurve(numbers, false);
+        } 
+        else if ("hhcurveto".equals(name))
+        {
+            drawCurve(numbers, true);
+        } 
+        else
+        {
+            addCommand(numbers, command);
+        }
+    }
+
+    private List<Integer> clearStack(List<Integer> numbers, boolean flag)
+    {
+        if (type1Sequence.size() == 0)
+        {
+            if (flag)
+            {
+                addCommand(Arrays.asList(0, numbers.get(0) + nominalWidthX),
+                        new CharStringCommand(13));
+
+                numbers = numbers.subList(1, numbers.size());
+            } 
+            else
+            {
+                addCommand(Arrays.asList(0, defWidthX),
+                    new CharStringCommand(13));
+            }
+        }
+        return numbers;
+    }
+
+    private void expandStemHints(List<Integer> numbers, boolean horizontal)
+    {
+        // TODO
+    }
+
+    private void markPath()
+    {
+        if (pathCount > 0)
+        {
+            closePath();
+        }
+        pathCount++;
+    }
+
+    private void closePath()
+    {
+        CharStringCommand command = pathCount > 0 ? (CharStringCommand) type1Sequence
+                .get(type1Sequence.size() - 1)
+                : null;
+
+        CharStringCommand closepathCommand = new CharStringCommand(9);
+        if (command != null && !closepathCommand.equals(command))
+        {
+            addCommand(Collections.<Integer> emptyList(), closepathCommand);
+        }
+    }
+
+    private void drawAlternatingLine(List<Integer> numbers, boolean horizontal)
+    {
+        while (numbers.size() > 0)
+        {
+            addCommand(numbers.subList(0, 1), new CharStringCommand(
+                    horizontal ? 6 : 7));
+            numbers = numbers.subList(1, numbers.size());
+            horizontal = !horizontal;
+        }
+    }
+
+    private void drawAlternatingCurve(List<Integer> numbers, boolean horizontal)
+    {
+        while (numbers.size() > 0)
+        {
+            boolean last = numbers.size() == 5;
+            if (horizontal)
+            {
+                addCommand(Arrays.asList(numbers.get(0), 0,
+                        numbers.get(1), numbers.get(2), last ? numbers.get(4)
+                                : Integer.valueOf(0), numbers.get(3)),
+                        new CharStringCommand(8));
+            } 
+            else
+            {
+                addCommand(Arrays.asList(0, numbers.get(0),
+                        numbers.get(1), numbers.get(2), numbers.get(3),
+                        last ? numbers.get(4) : Integer.valueOf(0)),
+                        new CharStringCommand(8));
+            }
+            numbers = numbers.subList(last ? 5 : 4, numbers.size());
+            horizontal = !horizontal;
+        }
+    }
+
+    private void drawCurve(List<Integer> numbers, boolean horizontal)
+    {
+        while (numbers.size() > 0)
+        {
+            boolean first = numbers.size() % 4 == 1;
+
+            if (horizontal)
+            {
+                addCommand(Arrays.asList(numbers.get(first ? 1 : 0),
+                        first ? numbers.get(0) : Integer.valueOf(0), numbers
+                                .get(first ? 2 : 1),
+                        numbers.get(first ? 3 : 2), numbers.get(first ? 4 : 3),
+                        0), new CharStringCommand(8));
+            } 
+            else
+            {
+                addCommand(Arrays.asList(first ? numbers.get(0) : Integer
+                        .valueOf(0), numbers.get(first ? 1 : 0), numbers
+                        .get(first ? 2 : 1), numbers.get(first ? 3 : 2),
+                        0, numbers.get(first ? 4 : 3)),
+                        new CharStringCommand(8));
+            }
+            numbers = numbers.subList(first ? 5 : 4, numbers.size());
+        }
+    }
+
+    private void addCommandList(List<List<Integer>> numbers, CharStringCommand command)
+    {
+        for (List<Integer> ns : numbers)
+        {
+            addCommand(ns, command);
+        }
+    }
+
+    private void addCommand(List<Integer> numbers, CharStringCommand command)
+    {
+        type1Sequence.addAll(numbers);
+        type1Sequence.add(command);
+    }
+
+    private static <E> List<List<E>> split(List<E> list, int size)
+    {
+        List<List<E>> result = new ArrayList<List<E>>();
+        for (int i = 0; i < list.size() / size; i++)
+        {
+            result.add(list.subList(i * size, (i + 1) * size));
+        }
+        return result;
+    }
+}
\ No newline at end of file

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java Sun Jan  5 15:37:49 2014
@@ -25,8 +25,6 @@ import java.util.Map;
  * This is an interface to a text encoder.
  *
  * @author Ben Litchfield
- * @version $Revision: 1.1 $
- * 
  * 
  */
 public abstract class Encoding
@@ -153,10 +151,8 @@ public abstract class Encoding
      * @param code The character code.
      *
      * @return The name of the character.
-     *
-     * @throws IOException If there is no name for the code.
      */
-    public String getName( int code ) throws IOException
+    public String getName( int code )
     {
         String name = codeToName.get( code );
         if( name == null )

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java Sun Jan  5 15:37:49 2014
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.encoding;
+
+
+/**
+ * Adobe Standard Encoding
+ *
+ * @author Ben Litchfield
+ *
+ */
+public class StandardEncoding extends Encoding
+{
+    /**
+     * Singleton instance of this class.
+     */
+    public static final StandardEncoding INSTANCE = new StandardEncoding();
+
+    /**
+     * Constructor.
+     */
+    public StandardEncoding()
+    {
+        addCharacterEncoding( 0101, "A" );
+        addCharacterEncoding( 0341, "AE" );
+        addCharacterEncoding( 0102, "B" );
+        addCharacterEncoding( 0103, "C" );
+        addCharacterEncoding( 0104, "D" );
+        addCharacterEncoding( 0105, "E" );
+        addCharacterEncoding( 0106, "F" );
+        addCharacterEncoding( 0107, "G" );
+        addCharacterEncoding( 0110, "H" );
+        addCharacterEncoding( 0111, "I" );
+        addCharacterEncoding( 0112, "J" );
+        addCharacterEncoding( 0113, "K" );
+        addCharacterEncoding( 0114, "L" );
+        addCharacterEncoding( 0350, "Lslash" );
+        addCharacterEncoding( 0115, "M" );
+        addCharacterEncoding( 0116, "N" );
+        addCharacterEncoding( 0117, "O" );
+        addCharacterEncoding( 0352, "OE" );
+        addCharacterEncoding( 0351, "Oslash" );
+        addCharacterEncoding( 0120, "P" );
+        addCharacterEncoding( 0121, "Q" );
+        addCharacterEncoding( 0122, "R" );
+        addCharacterEncoding( 0123, "S" );
+        addCharacterEncoding( 0124, "T" );
+        addCharacterEncoding( 0125, "U" );
+        addCharacterEncoding( 0126, "V" );
+        addCharacterEncoding( 0127, "W" );
+        addCharacterEncoding( 0130, "X" );
+        addCharacterEncoding( 0131, "Y" );
+        addCharacterEncoding( 0132, "Z" );
+        addCharacterEncoding( 0141, "a" );
+        addCharacterEncoding( 0302, "acute" );
+        addCharacterEncoding( 0361, "ae" );
+        addCharacterEncoding( 0046, "ampersand" );
+        addCharacterEncoding( 0136, "asciicircum" );
+        addCharacterEncoding( 0176, "asciitilde" );
+        addCharacterEncoding( 0052, "asterisk" );
+        addCharacterEncoding( 0100, "at" );
+        addCharacterEncoding( 0142, "b" );
+        addCharacterEncoding( 0134, "backslash" );
+        addCharacterEncoding( 0174, "bar" );
+        addCharacterEncoding( 0173, "braceleft" );
+        addCharacterEncoding( 0175, "braceright" );
+        addCharacterEncoding( 0133, "bracketleft" );
+        addCharacterEncoding( 0135, "bracketright" );
+        addCharacterEncoding( 0306, "breve" );
+        addCharacterEncoding( 0267, "bullet" );
+        addCharacterEncoding( 0143, "c" );
+        addCharacterEncoding( 0317, "caron" );
+        addCharacterEncoding( 0313, "cedilla" );
+        addCharacterEncoding( 0242, "cent" );
+        addCharacterEncoding( 0303, "circumflex" );
+        addCharacterEncoding( 0072, "colon" );
+        addCharacterEncoding( 0054, "comma" );
+        addCharacterEncoding( 0250, "currency" );
+        addCharacterEncoding( 0144, "d" );
+        addCharacterEncoding( 0262, "dagger" );
+        addCharacterEncoding( 0263, "daggerdbl" );
+        addCharacterEncoding( 0310, "dieresis" );
+        addCharacterEncoding( 0044, "dollar" );
+        addCharacterEncoding( 0307, "dotaccent" );
+        addCharacterEncoding( 0365, "dotlessi" );
+        addCharacterEncoding( 0145, "e" );
+        addCharacterEncoding( 0070, "eight" );
+        addCharacterEncoding( 0274, "ellipsis" );
+        addCharacterEncoding( 0320, "emdash" );
+        addCharacterEncoding( 0261, "endash" );
+        addCharacterEncoding( 0075, "equal" );
+        addCharacterEncoding( 0041, "exclam" );
+        addCharacterEncoding( 0241, "exclamdown" );
+        addCharacterEncoding( 0146, "f" );
+        addCharacterEncoding( 0256, "fi" );
+        addCharacterEncoding( 0065, "five" );
+        addCharacterEncoding( 0257, "fl" );
+        addCharacterEncoding( 0246, "florin" );
+        addCharacterEncoding( 0064, "four" );
+        addCharacterEncoding( 0244, "fraction" );
+        addCharacterEncoding( 0147, "g" );
+        addCharacterEncoding( 0373, "germandbls" );
+        addCharacterEncoding( 0301, "grave" );
+        addCharacterEncoding( 0076, "greater" );
+        addCharacterEncoding( 0253, "guillemotleft" );
+        addCharacterEncoding( 0273, "guillemotright" );
+        addCharacterEncoding( 0254, "guilsinglleft" );
+        addCharacterEncoding( 0255, "guilsinglright" );
+        addCharacterEncoding( 0150, "h" );
+        addCharacterEncoding( 0315, "hungarumlaut" );
+        addCharacterEncoding( 0055, "hyphen" );
+        addCharacterEncoding( 0151, "i" );
+        addCharacterEncoding( 0152, "j" );
+        addCharacterEncoding( 0153, "k" );
+        addCharacterEncoding( 0154, "l" );
+        addCharacterEncoding( 0074, "less" );
+        addCharacterEncoding( 0370, "lslash" );
+        addCharacterEncoding( 0155, "m" );
+        addCharacterEncoding( 0305, "macron" );
+        addCharacterEncoding( 0156, "n" );
+        addCharacterEncoding( 0071, "nine" );
+        addCharacterEncoding( 0043, "numbersign" );
+        addCharacterEncoding( 0157, "o" );
+        addCharacterEncoding( 0372, "oe" );
+        addCharacterEncoding( 0316, "ogonek" );
+        addCharacterEncoding( 0061, "one" );
+        addCharacterEncoding( 0343, "ordfeminine" );
+        addCharacterEncoding( 0353, "ordmasculine" );
+        addCharacterEncoding( 0371, "oslash" );
+        addCharacterEncoding( 0160, "p" );
+        addCharacterEncoding( 0266, "paragraph" );
+        addCharacterEncoding( 0050, "parenleft" );
+        addCharacterEncoding( 0051, "parenright" );
+        addCharacterEncoding( 0045, "percent" );
+        addCharacterEncoding( 0056, "period" );
+        addCharacterEncoding( 0264, "periodcentered" );
+        addCharacterEncoding( 0275, "perthousand" );
+        addCharacterEncoding( 0053, "plus" );
+        addCharacterEncoding( 0161, "q" );
+        addCharacterEncoding( 0077, "question" );
+        addCharacterEncoding( 0277, "questiondown" );
+        addCharacterEncoding( 0042, "quotedbl" );
+        addCharacterEncoding( 0271, "quotedblbase" );
+        addCharacterEncoding( 0252, "quotedblleft" );
+        addCharacterEncoding( 0272, "quotedblright" );
+        addCharacterEncoding( 0140, "quoteleft" );
+        addCharacterEncoding( 0047, "quoteright" );
+        addCharacterEncoding( 0270, "quotesinglbase" );
+        addCharacterEncoding( 0251, "quotesingle" );
+        addCharacterEncoding( 0162, "r" );
+        addCharacterEncoding( 0312, "ring" );
+        addCharacterEncoding( 0163, "s" );
+        addCharacterEncoding( 0247, "section" );
+        addCharacterEncoding( 0073, "semicolon" );
+        addCharacterEncoding( 0067, "seven" );
+        addCharacterEncoding( 0066, "six" );
+        addCharacterEncoding( 0057, "slash" );
+        addCharacterEncoding( 0040, "space" );
+        addCharacterEncoding( 0243, "sterling" );
+        addCharacterEncoding( 0164, "t" );
+        addCharacterEncoding( 0063, "three" );
+        addCharacterEncoding( 0304, "tilde" );
+        addCharacterEncoding( 0062, "two" );
+        addCharacterEncoding( 0165, "u" );
+        addCharacterEncoding( 0137, "underscore" );
+        addCharacterEncoding( 0166, "v" );
+        addCharacterEncoding( 0167, "w" );
+        addCharacterEncoding( 0170, "x" );
+        addCharacterEncoding( 0171, "y" );
+        addCharacterEncoding( 0245, "yen" );
+        addCharacterEncoding( 0172, "z" );
+        addCharacterEncoding( 0060, "zero" );
+    }
+}
\ No newline at end of file

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java Sun Jan  5 15:37:49 2014
@@ -29,7 +29,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fontbox.cff.CFFFont;
 import org.apache.fontbox.cff.CFFFontROS;
-import org.apache.fontbox.cff.CharStringRenderer;
 import org.apache.pdfbox.encoding.Encoding;
 
 /**
@@ -80,14 +79,13 @@ public class CFFGlyph2D implements Glyph
         		codeToName.put(key, encodingCodeToName.get(key));
         	}
         }
-        CharStringRenderer renderer = cffFont.createRenderer();
         int glyphId = 0;
         for (CFFFont.Mapping mapping : mappings)
         {
             GeneralPath glyph = null;
             try
             {
-                glyph = renderer.render(mapping.toType1Sequence());
+                glyph = mapping.getType1CharString().getPath();
             }
             catch (IOException exception)
             {