You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/08/17 22:02:20 UTC

svn commit: r1618516 [2/6] - in /pdfbox/no-awt: examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ fontbox/src/main/java/org/apache/fontbox/afm/ fontbox/src/main/java/org/apache/fontbox/cff/ fontbox/src/main/java/org/apache/fontbox/cff/charset/...

Modified: pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (original)
+++ pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java Sun Aug 17 20:02:18 2014
@@ -16,127 +16,46 @@
  */
 package org.apache.fontbox.cff;
 
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import org.apache.fontbox.afm.FontMetric;
-import org.apache.fontbox.cff.charset.CFFCharset;
-import org.apache.fontbox.cff.encoding.CFFEncoding;
-import org.apache.fontbox.type1.Type1CharStringReader;
-import org.apache.fontbox.type1.Type1Mapping;
+import org.apache.fontbox.util.BoundingBox;
 
 /**
- * This class represents a CFF/Type2 Font.
+ * An Adobe Compact Font Format (CFF) font.
  * 
  * @author Villu Ruusmann
  * @author John Hewson
  */
-public class CFFFont implements Type1CharStringReader
+public abstract class CFFFont
 {
-    private String fontname = null;
-    private Map<String, Object> topDict = new LinkedHashMap<String, Object>();
-    private Map<String, Object> privateDict = new LinkedHashMap<String, Object>();
-    private CFFEncoding fontEncoding = null;
-    private CFFCharset fontCharset = null;
-    private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
-    private IndexData globalSubrIndex = null;
-    private Map<String, Type2CharString> charStringCache = new HashMap<String, Type2CharString>();
-    private FontMetric fontMetric = null;
-    
+    // todo: can we avoid protected variables and make some of these final?
+    protected String fontName;
+    protected final Map<String, Object> topDict = new LinkedHashMap<String, Object>();
+    protected CFFCharset charset;
+    protected final List<byte[]> charStrings = new ArrayList<byte[]>();
+    protected IndexData globalSubrIndex;
+
     /**
      * The name of the font.
-     * 
+     *
      * @return the name of the font
      */
     public String getName()
     {
-        return fontname;
+        return fontName;
     }
 
     /**
      * Sets the name of the font.
-     * 
+     *
      * @param name the name of the font
      */
-    public void setName(String name)
+    void setName(String name)
     {
-        fontname = name;
-    }
-
-    /**
-     * Returns the value for the given name from the dictionary.
-     * 
-     * @param name the name of the value
-     * @return the value of the name if available
-     */
-    public Object getProperty(String name)
-    {
-        Object topDictValue = topDict.get(name);
-        if (topDictValue != null)
-        {
-            return topDictValue;
-        }
-        Object privateDictValue = privateDict.get(name);
-        if (privateDictValue != null)
-        {
-            return privateDictValue;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the string value for the given name from the dictionary.
-     * 
-     * @param name the name of the value
-     * @return the string value of the name if available
-     */
-    public String getPropertyAsString(String name)
-    {
-        Object value = getProperty(name);
-        if (value != null && value instanceof String)
-        {
-            return (String)value;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the float value for the given name from the dictionary.
-     * 
-     * @param name the name of the value
-     * @return the float value of the name if available
-     */
-    public float getPropertyAsFloat(String name, float defaultValue)
-    {
-        Object value = getProperty(name);
-        if (value != null && value instanceof Float)
-        {
-            return (Float)value;
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns the boolean value for the given name from the dictionary.
-     * 
-     * @param name the name of the value
-     * @return the boolean value of the name if available
-     */
-    public boolean getPropertyAsBoolean(String name, boolean defaultValue)
-    {
-        Object value = getProperty(name);
-        if (value != null && value instanceof Boolean)
-        {
-            return (Boolean)value;
-        }
-        return defaultValue;
+        fontName = name;
     }
 
     /**
@@ -164,183 +83,22 @@ public class CFFFont implements Type1Cha
     }
 
     /**
-     * Adds the given key/value pair to the private dictionary.
-     * 
-     * @param name the given key
-     * @param value the given value
+     * Returns the FontMatrix.
      */
-    public void addValueToPrivateDict(String name, Object value)
+    public List<Number> getFontMatrix()
     {
-        if (value != null)
-        {
-            privateDict.put(name, value);
-        }
+        return (List<Number>)topDict.get("FontMatrix");
     }
 
     /**
-     * Returns the private dictionary.
-     * 
-     * @return the dictionary
+     * Returns the FontBBox.
      */
-    public Map<String, Object> getPrivateDict()
+    public BoundingBox getFontBBox()
     {
-        return privateDict;
-    }
-
-    /**
-     * Get the mappings for the font as Type1Mapping
-     *
-     * @return the Type1Mapping
-     */
-    public Collection<? extends Type1Mapping> getType1Mappings()
-    {
-        return getMappings();
-    }
-
-    /**
-     * Get the mapping (code/SID/charname/bytes) for this font.
-     * 
-     * @return mappings for codes &lt; 256 and for codes &gt;= 256
-     */
-    public Collection<CFFFont.Mapping> getMappings()
-    {
-        List<Mapping> mappings = new ArrayList<Mapping>();
-        Set<String> mappedNames = new HashSet<String>();
-        for (CFFEncoding.Entry entry : fontEncoding.getEntries())
-        {
-            String charName = fontCharset.getName(entry.getSID());
-            // Predefined encoding
-            if (charName == null)
-            {
-                continue;
-            }
-            byte[] bytes = charStringsDict.get(charName);
-            if (bytes == null)
-            {
-                continue;
-            }
-            Mapping mapping = createMapping(entry.getCode(), entry.getSID(), charName, bytes);
-            mappings.add(mapping);
-            mappedNames.add(charName);
-        }
-        if (fontEncoding instanceof CFFParser.EmbeddedEncoding)
-        {
-            CFFParser.EmbeddedEncoding embeddedEncoding = (CFFParser.EmbeddedEncoding) fontEncoding;
-
-            for (CFFParser.EmbeddedEncoding.Supplement supplement : embeddedEncoding.getSupplements())
-            {
-                String charName = fontCharset.getName(supplement.getGlyph());
-                if (charName == null)
-                {
-                    continue;
-                }
-                byte[] bytes = charStringsDict.get(charName);
-                if (bytes == null)
-                {
-                    continue;
-                }
-                Mapping mapping = createMapping(supplement.getCode(), supplement.getGlyph(), charName, bytes);
-                mappings.add(mapping);
-                mappedNames.add(charName);
-            }
-        }
-        // XXX
-        int code = 256;
-        for (CFFCharset.Entry entry : fontCharset.getEntries())
-        {
-            String name = entry.getName();
-            if (mappedNames.contains(name))
-            {
-                continue;
-            }
-            byte[] bytes = this.charStringsDict.get(name);
-            if (bytes == null)
-            {
-                continue;
-            }
-            Mapping mapping = createMapping(code++, entry.getSID(), name, bytes);
-            mappings.add(mapping);
-            mappedNames.add(name);
-        }
-        return mappings;
-    }
-
-    /**
-     * Returns a new mapping. Overridden in subclasses.
-     *
-     * @param code chatacter code
-     * @param sid SID
-     * @param name glyph name
-     * @param bytes charstring bytes
-     * @return a new mapping object
-     */
-    protected Mapping createMapping(int code, int sid, String name, byte[] bytes)
-    {
-        Mapping mapping = new Mapping();
-        mapping.setCode(code);
-        mapping.setSID(sid);
-        mapping.setName(name);
-        mapping.setBytes(bytes);
-        return  mapping;
-    }
-
-    /**
-     * Return the Width value of the given Glyph identifier.
-     * 
-     * @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
-    {
-        for (Mapping m : getMappings())
-        {
-            if (m.getSID() == sid)
-            {
-                Type1CharString charstring = m.getType1CharString();
-                return charstring.getWidth();
-            }
-        }
-
-        // SID not found, return the nodef width
-        int nominalWidth = getNominalWidthX(sid);
-        int defaultWidth = getDefaultWidthX(sid);
-        return getNotDefWidth(defaultWidth, nominalWidth);
-    }
-
-    /**
-     * Returns the witdth of the .notdef character.
-     * 
-     * @param defaultWidth default width
-     * @param nominalWidth nominal width
-     * @return the calculated width for the .notdef character
-     * @throws IOException if something went wrong
-     */
-    protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException
-    {
-        Type1CharString charstring = getType1CharString(".notdef");
-        return charstring.getWidth() != 0 ? charstring.getWidth() + nominalWidth : defaultWidth;
-    }
-
-    /**
-     * Returns the CFFEncoding of the font.
-     * 
-     * @return the encoding
-     */
-    public CFFEncoding getEncoding()
-    {
-        return fontEncoding;
-    }
-
-    /**
-     * Sets the CFFEncoding of the font.
-     * 
-     * @param encoding the given CFFEncoding
-     */
-    public void setEncoding(CFFEncoding encoding)
-    {
-        fontEncoding = encoding;
+        List<Number> numbers = (List<Number>)topDict.get("FontBBox");
+        BoundingBox bbox = new BoundingBox(numbers.get(0).floatValue(), numbers.get(1).floatValue(),
+                                           numbers.get(2).floatValue(), numbers.get(3).floatValue());
+        return bbox;
     }
 
     /**
@@ -350,7 +108,7 @@ public class CFFFont implements Type1Cha
      */
     public CFFCharset getCharset()
     {
-        return fontCharset;
+        return charset;
     }
 
     /**
@@ -358,126 +116,19 @@ public class CFFFont implements Type1Cha
      * 
      * @param charset the given CFFCharset
      */
-    public void setCharset(CFFCharset charset)
-    {
-        fontCharset = charset;
-    }
-
-    /**
-     * Returns the FontMetric of the font.
-     * 
-     * @return the font metrics
-     */
-    public FontMetric getFontMetric()
-    {
-        return fontMetric;
-    }
-
-    /**
-     * Sets the FontMetric of the font.
-     * 
-     * @param metric the given FontMetric 
-     */
-    public void setFontMetric(FontMetric metric)
-    {
-        fontMetric = metric;
-    }
-
-    /**
-     * Returns the SID for a given glyph name.
-     * @param name glyph name
-     * @return SID
-     */
-    private int getSIDForName(String name)
+    void setCharset(CFFCharset charset)
     {
-        int sid = 0; // .notdef
-        for (Mapping m : getMappings())
-        {
-            if (m.getName().equals(name))
-            {
-                sid = m.getSID();
-                break;
-            }
-        }
-      return sid;
+        this.charset = charset;
     }
 
     /**
      * Returns the character strings dictionary.
-     * 
-     * @return the dictionary
-     */
-    public Map<String, byte[]> getCharStringsDict()
-    {
-        return charStringsDict;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Type1CharString getType1CharString(String name) throws IOException
-    {
-        return getType1CharString(name, getSIDForName(name));
-    }
-
-    /**
-     * 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(fontname, name);
-            List<Object> type2seq = parser.parse(charStringsDict.get(name), globalSubrIndex, getLocalSubrIndex(sid));
-            type2 = new Type2CharString(this, fontname, name, 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
-     */
-    protected int getNominalWidthX(int sid)
-    {
-        Number num = (Number)getProperty("nominalWidthX");
-        if (num == null)
-        {
-            return 0;
-        }
-        return num.intValue();
-    }
-
-    /**
-     * {@inheritDoc}
+     * @return the dictionary
      */
-    public String toString()
+    List<byte[]> getCharStrings()
     {
-        return getClass().getName() + "[name=" + fontname + ", topDict=" + topDict + ", privateDict=" + privateDict
-                + ", encoding=" + fontEncoding + ", charset=" + fontCharset + ", charStringsDict=" + charStringsDict
-                + "]";
+        return charStrings;
     }
 
     /**
@@ -485,7 +136,7 @@ public class CFFFont implements Type1Cha
      * 
      * @param globalSubrIndexValue the IndexData object containing the global subroutines
      */
-    public void setGlobalSubrIndex(IndexData globalSubrIndexValue)
+    void setGlobalSubrIndex(IndexData globalSubrIndexValue)
     {
         globalSubrIndex = globalSubrIndexValue;
     }
@@ -500,83 +151,11 @@ public class CFFFont implements Type1Cha
         return globalSubrIndex;
     }
 
-    /**
-     * Returns the local subroutine index data.
-     * 
-     * @return the dictionary
-     */
-    protected IndexData getLocalSubrIndex(int sid)
-    {
-        return (IndexData)privateDict.get("Subrs");
-    }
-
-    public class Mapping implements Type1Mapping
+    @Override
+    public String toString()
     {
-        private int mappedCode;
-        private int mappedSID;
-        private String mappedName;
-        private byte[] mappedBytes;
-
-        /**
-         * {@inheritDoc}
-         */
-        public Type1CharString getType1CharString() throws IOException
-        {
-            return CFFFont.this.getType1CharString(mappedName, mappedSID);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public int getCode()
-        {
-            return mappedCode;
-        }
-
-        protected void setCode(int code)
-        {
-            mappedCode = code;
-        }
-
-        /**
-         * Gets the value for the SID.
-         *
-         * @return the SID
-         */
-        public int getSID()
-        {
-            return mappedSID;
-        }
-
-        protected void setSID(int sid)
-        {
-            this.mappedSID = sid;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public String getName()
-        {
-            return mappedName;
-        }
-
-        protected void setName(String name)
-        {
-            this.mappedName = name;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public byte[] getBytes()
-        {
-            return mappedBytes;
-        }
-
-        protected void setBytes(byte[] bytes)
-        {
-            this.mappedBytes = bytes;
-        }
+        return getClass().getName() + "[name=" + fontName + ", topDict=" + topDict
+                + ", charset=" + charset + ", charStrings=" + charStrings
+                + "]";
     }
 }

Copied: pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java (from r1615712, pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/charset/CFFISOAdobeCharset.java)
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java?p2=pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java&p1=pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/charset/CFFISOAdobeCharset.java&r1=1615712&r2=1618516&rev=1618516&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/charset/CFFISOAdobeCharset.java (original)
+++ pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java Sun Aug 17 20:02:18 2014
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.fontbox.cff.charset;
+package org.apache.fontbox.cff;
 
 
 /**
@@ -28,6 +28,7 @@ public class CFFISOAdobeCharset extends 
 
     private CFFISOAdobeCharset()
     {
+        super(false);
     }
 
     /**
@@ -43,233 +44,235 @@ public class CFFISOAdobeCharset extends 
 
     static
     {
-        INSTANCE.register(1, "space");
-        INSTANCE.register(2, "exclam");
-        INSTANCE.register(3, "quotedbl");
-        INSTANCE.register(4, "numbersign");
-        INSTANCE.register(5, "dollar");
-        INSTANCE.register(6, "percent");
-        INSTANCE.register(7, "ampersand");
-        INSTANCE.register(8, "quoteright");
-        INSTANCE.register(9, "parenleft");
-        INSTANCE.register(10, "parenright");
-        INSTANCE.register(11, "asterisk");
-        INSTANCE.register(12, "plus");
-        INSTANCE.register(13, "comma");
-        INSTANCE.register(14, "hyphen");
-        INSTANCE.register(15, "period");
-        INSTANCE.register(16, "slash");
-        INSTANCE.register(17, "zero");
-        INSTANCE.register(18, "one");
-        INSTANCE.register(19, "two");
-        INSTANCE.register(20, "three");
-        INSTANCE.register(21, "four");
-        INSTANCE.register(22, "five");
-        INSTANCE.register(23, "six");
-        INSTANCE.register(24, "seven");
-        INSTANCE.register(25, "eight");
-        INSTANCE.register(26, "nine");
-        INSTANCE.register(27, "colon");
-        INSTANCE.register(28, "semicolon");
-        INSTANCE.register(29, "less");
-        INSTANCE.register(30, "equal");
-        INSTANCE.register(31, "greater");
-        INSTANCE.register(32, "question");
-        INSTANCE.register(33, "at");
-        INSTANCE.register(34, "A");
-        INSTANCE.register(35, "B");
-        INSTANCE.register(36, "C");
-        INSTANCE.register(37, "D");
-        INSTANCE.register(38, "E");
-        INSTANCE.register(39, "F");
-        INSTANCE.register(40, "G");
-        INSTANCE.register(41, "H");
-        INSTANCE.register(42, "I");
-        INSTANCE.register(43, "J");
-        INSTANCE.register(44, "K");
-        INSTANCE.register(45, "L");
-        INSTANCE.register(46, "M");
-        INSTANCE.register(47, "N");
-        INSTANCE.register(48, "O");
-        INSTANCE.register(49, "P");
-        INSTANCE.register(50, "Q");
-        INSTANCE.register(51, "R");
-        INSTANCE.register(52, "S");
-        INSTANCE.register(53, "T");
-        INSTANCE.register(54, "U");
-        INSTANCE.register(55, "V");
-        INSTANCE.register(56, "W");
-        INSTANCE.register(57, "X");
-        INSTANCE.register(58, "Y");
-        INSTANCE.register(59, "Z");
-        INSTANCE.register(60, "bracketleft");
-        INSTANCE.register(61, "backslash");
-        INSTANCE.register(62, "bracketright");
-        INSTANCE.register(63, "asciicircum");
-        INSTANCE.register(64, "underscore");
-        INSTANCE.register(65, "quoteleft");
-        INSTANCE.register(66, "a");
-        INSTANCE.register(67, "b");
-        INSTANCE.register(68, "c");
-        INSTANCE.register(69, "d");
-        INSTANCE.register(70, "e");
-        INSTANCE.register(71, "f");
-        INSTANCE.register(72, "g");
-        INSTANCE.register(73, "h");
-        INSTANCE.register(74, "i");
-        INSTANCE.register(75, "j");
-        INSTANCE.register(76, "k");
-        INSTANCE.register(77, "l");
-        INSTANCE.register(78, "m");
-        INSTANCE.register(79, "n");
-        INSTANCE.register(80, "o");
-        INSTANCE.register(81, "p");
-        INSTANCE.register(82, "q");
-        INSTANCE.register(83, "r");
-        INSTANCE.register(84, "s");
-        INSTANCE.register(85, "t");
-        INSTANCE.register(86, "u");
-        INSTANCE.register(87, "v");
-        INSTANCE.register(88, "w");
-        INSTANCE.register(89, "x");
-        INSTANCE.register(90, "y");
-        INSTANCE.register(91, "z");
-        INSTANCE.register(92, "braceleft");
-        INSTANCE.register(93, "bar");
-        INSTANCE.register(94, "braceright");
-        INSTANCE.register(95, "asciitilde");
-        INSTANCE.register(96, "exclamdown");
-        INSTANCE.register(97, "cent");
-        INSTANCE.register(98, "sterling");
-        INSTANCE.register(99, "fraction");
-        INSTANCE.register(100, "yen");
-        INSTANCE.register(101, "florin");
-        INSTANCE.register(102, "section");
-        INSTANCE.register(103, "currency");
-        INSTANCE.register(104, "quotesingle");
-        INSTANCE.register(105, "quotedblleft");
-        INSTANCE.register(106, "guillemotleft");
-        INSTANCE.register(107, "guilsinglleft");
-        INSTANCE.register(108, "guilsinglright");
-        INSTANCE.register(109, "fi");
-        INSTANCE.register(110, "fl");
-        INSTANCE.register(111, "endash");
-        INSTANCE.register(112, "dagger");
-        INSTANCE.register(113, "daggerdbl");
-        INSTANCE.register(114, "periodcentered");
-        INSTANCE.register(115, "paragraph");
-        INSTANCE.register(116, "bullet");
-        INSTANCE.register(117, "quotesinglbase");
-        INSTANCE.register(118, "quotedblbase");
-        INSTANCE.register(119, "quotedblright");
-        INSTANCE.register(120, "guillemotright");
-        INSTANCE.register(121, "ellipsis");
-        INSTANCE.register(122, "perthousand");
-        INSTANCE.register(123, "questiondown");
-        INSTANCE.register(124, "grave");
-        INSTANCE.register(125, "acute");
-        INSTANCE.register(126, "circumflex");
-        INSTANCE.register(127, "tilde");
-        INSTANCE.register(128, "macron");
-        INSTANCE.register(129, "breve");
-        INSTANCE.register(130, "dotaccent");
-        INSTANCE.register(131, "dieresis");
-        INSTANCE.register(132, "ring");
-        INSTANCE.register(133, "cedilla");
-        INSTANCE.register(134, "hungarumlaut");
-        INSTANCE.register(135, "ogonek");
-        INSTANCE.register(136, "caron");
-        INSTANCE.register(137, "emdash");
-        INSTANCE.register(138, "AE");
-        INSTANCE.register(139, "ordfeminine");
-        INSTANCE.register(140, "Lslash");
-        INSTANCE.register(141, "Oslash");
-        INSTANCE.register(142, "OE");
-        INSTANCE.register(143, "ordmasculine");
-        INSTANCE.register(144, "ae");
-        INSTANCE.register(145, "dotlessi");
-        INSTANCE.register(146, "lslash");
-        INSTANCE.register(147, "oslash");
-        INSTANCE.register(148, "oe");
-        INSTANCE.register(149, "germandbls");
-        INSTANCE.register(150, "onesuperior");
-        INSTANCE.register(151, "logicalnot");
-        INSTANCE.register(152, "mu");
-        INSTANCE.register(153, "trademark");
-        INSTANCE.register(154, "Eth");
-        INSTANCE.register(155, "onehalf");
-        INSTANCE.register(156, "plusminus");
-        INSTANCE.register(157, "Thorn");
-        INSTANCE.register(158, "onequarter");
-        INSTANCE.register(159, "divide");
-        INSTANCE.register(160, "brokenbar");
-        INSTANCE.register(161, "degree");
-        INSTANCE.register(162, "thorn");
-        INSTANCE.register(163, "threequarters");
-        INSTANCE.register(164, "twosuperior");
-        INSTANCE.register(165, "registered");
-        INSTANCE.register(166, "minus");
-        INSTANCE.register(167, "eth");
-        INSTANCE.register(168, "multiply");
-        INSTANCE.register(169, "threesuperior");
-        INSTANCE.register(170, "copyright");
-        INSTANCE.register(171, "Aacute");
-        INSTANCE.register(172, "Acircumflex");
-        INSTANCE.register(173, "Adieresis");
-        INSTANCE.register(174, "Agrave");
-        INSTANCE.register(175, "Aring");
-        INSTANCE.register(176, "Atilde");
-        INSTANCE.register(177, "Ccedilla");
-        INSTANCE.register(178, "Eacute");
-        INSTANCE.register(179, "Ecircumflex");
-        INSTANCE.register(180, "Edieresis");
-        INSTANCE.register(181, "Egrave");
-        INSTANCE.register(182, "Iacute");
-        INSTANCE.register(183, "Icircumflex");
-        INSTANCE.register(184, "Idieresis");
-        INSTANCE.register(185, "Igrave");
-        INSTANCE.register(186, "Ntilde");
-        INSTANCE.register(187, "Oacute");
-        INSTANCE.register(188, "Ocircumflex");
-        INSTANCE.register(189, "Odieresis");
-        INSTANCE.register(190, "Ograve");
-        INSTANCE.register(191, "Otilde");
-        INSTANCE.register(192, "Scaron");
-        INSTANCE.register(193, "Uacute");
-        INSTANCE.register(194, "Ucircumflex");
-        INSTANCE.register(195, "Udieresis");
-        INSTANCE.register(196, "Ugrave");
-        INSTANCE.register(197, "Yacute");
-        INSTANCE.register(198, "Ydieresis");
-        INSTANCE.register(199, "Zcaron");
-        INSTANCE.register(200, "aacute");
-        INSTANCE.register(201, "acircumflex");
-        INSTANCE.register(202, "adieresis");
-        INSTANCE.register(203, "agrave");
-        INSTANCE.register(204, "aring");
-        INSTANCE.register(205, "atilde");
-        INSTANCE.register(206, "ccedilla");
-        INSTANCE.register(207, "eacute");
-        INSTANCE.register(208, "ecircumflex");
-        INSTANCE.register(209, "edieresis");
-        INSTANCE.register(210, "egrave");
-        INSTANCE.register(211, "iacute");
-        INSTANCE.register(212, "icircumflex");
-        INSTANCE.register(213, "idieresis");
-        INSTANCE.register(214, "igrave");
-        INSTANCE.register(215, "ntilde");
-        INSTANCE.register(216, "oacute");
-        INSTANCE.register(217, "ocircumflex");
-        INSTANCE.register(218, "odieresis");
-        INSTANCE.register(219, "ograve");
-        INSTANCE.register(220, "otilde");
-        INSTANCE.register(221, "scaron");
-        INSTANCE.register(222, "uacute");
-        INSTANCE.register(223, "ucircumflex");
-        INSTANCE.register(224, "udieresis");
-        INSTANCE.register(225, "ugrave");
-        INSTANCE.register(226, "yacute");
-        INSTANCE.register(227, "ydieresis");
-        INSTANCE.register(228, "zcaron");
+        int gid = 0;
+        INSTANCE.addSID(gid++, 0, ".notdef");
+        INSTANCE.addSID(gid++, 1, "space");
+        INSTANCE.addSID(gid++, 2, "exclam");
+        INSTANCE.addSID(gid++, 3, "quotedbl");
+        INSTANCE.addSID(gid++, 4, "numbersign");
+        INSTANCE.addSID(gid++, 5, "dollar");
+        INSTANCE.addSID(gid++, 6, "percent");
+        INSTANCE.addSID(gid++, 7, "ampersand");
+        INSTANCE.addSID(gid++, 8, "quoteright");
+        INSTANCE.addSID(gid++, 9, "parenleft");
+        INSTANCE.addSID(gid++, 10, "parenright");
+        INSTANCE.addSID(gid++, 11, "asterisk");
+        INSTANCE.addSID(gid++, 12, "plus");
+        INSTANCE.addSID(gid++, 13, "comma");
+        INSTANCE.addSID(gid++, 14, "hyphen");
+        INSTANCE.addSID(gid++, 15, "period");
+        INSTANCE.addSID(gid++, 16, "slash");
+        INSTANCE.addSID(gid++, 17, "zero");
+        INSTANCE.addSID(gid++, 18, "one");
+        INSTANCE.addSID(gid++, 19, "two");
+        INSTANCE.addSID(gid++, 20, "three");
+        INSTANCE.addSID(gid++, 21, "four");
+        INSTANCE.addSID(gid++, 22, "five");
+        INSTANCE.addSID(gid++, 23, "six");
+        INSTANCE.addSID(gid++, 24, "seven");
+        INSTANCE.addSID(gid++, 25, "eight");
+        INSTANCE.addSID(gid++, 26, "nine");
+        INSTANCE.addSID(gid++, 27, "colon");
+        INSTANCE.addSID(gid++, 28, "semicolon");
+        INSTANCE.addSID(gid++, 29, "less");
+        INSTANCE.addSID(gid++, 30, "equal");
+        INSTANCE.addSID(gid++, 31, "greater");
+        INSTANCE.addSID(gid++, 32, "question");
+        INSTANCE.addSID(gid++, 33, "at");
+        INSTANCE.addSID(gid++, 34, "A");
+        INSTANCE.addSID(gid++, 35, "B");
+        INSTANCE.addSID(gid++, 36, "C");
+        INSTANCE.addSID(gid++, 37, "D");
+        INSTANCE.addSID(gid++, 38, "E");
+        INSTANCE.addSID(gid++, 39, "F");
+        INSTANCE.addSID(gid++, 40, "G");
+        INSTANCE.addSID(gid++, 41, "H");
+        INSTANCE.addSID(gid++, 42, "I");
+        INSTANCE.addSID(gid++, 43, "J");
+        INSTANCE.addSID(gid++, 44, "K");
+        INSTANCE.addSID(gid++, 45, "L");
+        INSTANCE.addSID(gid++, 46, "M");
+        INSTANCE.addSID(gid++, 47, "N");
+        INSTANCE.addSID(gid++, 48, "O");
+        INSTANCE.addSID(gid++, 49, "P");
+        INSTANCE.addSID(gid++, 50, "Q");
+        INSTANCE.addSID(gid++, 51, "R");
+        INSTANCE.addSID(gid++, 52, "S");
+        INSTANCE.addSID(gid++, 53, "T");
+        INSTANCE.addSID(gid++, 54, "U");
+        INSTANCE.addSID(gid++, 55, "V");
+        INSTANCE.addSID(gid++, 56, "W");
+        INSTANCE.addSID(gid++, 57, "X");
+        INSTANCE.addSID(gid++, 58, "Y");
+        INSTANCE.addSID(gid++, 59, "Z");
+        INSTANCE.addSID(gid++, 60, "bracketleft");
+        INSTANCE.addSID(gid++, 61, "backslash");
+        INSTANCE.addSID(gid++, 62, "bracketright");
+        INSTANCE.addSID(gid++, 63, "asciicircum");
+        INSTANCE.addSID(gid++, 64, "underscore");
+        INSTANCE.addSID(gid++, 65, "quoteleft");
+        INSTANCE.addSID(gid++, 66, "a");
+        INSTANCE.addSID(gid++, 67, "b");
+        INSTANCE.addSID(gid++, 68, "c");
+        INSTANCE.addSID(gid++, 69, "d");
+        INSTANCE.addSID(gid++, 70, "e");
+        INSTANCE.addSID(gid++, 71, "f");
+        INSTANCE.addSID(gid++, 72, "g");
+        INSTANCE.addSID(gid++, 73, "h");
+        INSTANCE.addSID(gid++, 74, "i");
+        INSTANCE.addSID(gid++, 75, "j");
+        INSTANCE.addSID(gid++, 76, "k");
+        INSTANCE.addSID(gid++, 77, "l");
+        INSTANCE.addSID(gid++, 78, "m");
+        INSTANCE.addSID(gid++, 79, "n");
+        INSTANCE.addSID(gid++, 80, "o");
+        INSTANCE.addSID(gid++, 81, "p");
+        INSTANCE.addSID(gid++, 82, "q");
+        INSTANCE.addSID(gid++, 83, "r");
+        INSTANCE.addSID(gid++, 84, "s");
+        INSTANCE.addSID(gid++, 85, "t");
+        INSTANCE.addSID(gid++, 86, "u");
+        INSTANCE.addSID(gid++, 87, "v");
+        INSTANCE.addSID(gid++, 88, "w");
+        INSTANCE.addSID(gid++, 89, "x");
+        INSTANCE.addSID(gid++, 90, "y");
+        INSTANCE.addSID(gid++, 91, "z");
+        INSTANCE.addSID(gid++, 92, "braceleft");
+        INSTANCE.addSID(gid++, 93, "bar");
+        INSTANCE.addSID(gid++, 94, "braceright");
+        INSTANCE.addSID(gid++, 95, "asciitilde");
+        INSTANCE.addSID(gid++, 96, "exclamdown");
+        INSTANCE.addSID(gid++, 97, "cent");
+        INSTANCE.addSID(gid++, 98, "sterling");
+        INSTANCE.addSID(gid++, 99, "fraction");
+        INSTANCE.addSID(gid++, 100, "yen");
+        INSTANCE.addSID(gid++, 101, "florin");
+        INSTANCE.addSID(gid++, 102, "section");
+        INSTANCE.addSID(gid++, 103, "currency");
+        INSTANCE.addSID(gid++, 104, "quotesingle");
+        INSTANCE.addSID(gid++, 105, "quotedblleft");
+        INSTANCE.addSID(gid++, 106, "guillemotleft");
+        INSTANCE.addSID(gid++, 107, "guilsinglleft");
+        INSTANCE.addSID(gid++, 108, "guilsinglright");
+        INSTANCE.addSID(gid++, 109, "fi");
+        INSTANCE.addSID(gid++, 110, "fl");
+        INSTANCE.addSID(gid++, 111, "endash");
+        INSTANCE.addSID(gid++, 112, "dagger");
+        INSTANCE.addSID(gid++, 113, "daggerdbl");
+        INSTANCE.addSID(gid++, 114, "periodcentered");
+        INSTANCE.addSID(gid++, 115, "paragraph");
+        INSTANCE.addSID(gid++, 116, "bullet");
+        INSTANCE.addSID(gid++, 117, "quotesinglbase");
+        INSTANCE.addSID(gid++, 118, "quotedblbase");
+        INSTANCE.addSID(gid++, 119, "quotedblright");
+        INSTANCE.addSID(gid++, 120, "guillemotright");
+        INSTANCE.addSID(gid++, 121, "ellipsis");
+        INSTANCE.addSID(gid++, 122, "perthousand");
+        INSTANCE.addSID(gid++, 123, "questiondown");
+        INSTANCE.addSID(gid++, 124, "grave");
+        INSTANCE.addSID(gid++, 125, "acute");
+        INSTANCE.addSID(gid++, 126, "circumflex");
+        INSTANCE.addSID(gid++, 127, "tilde");
+        INSTANCE.addSID(gid++, 128, "macron");
+        INSTANCE.addSID(gid++, 129, "breve");
+        INSTANCE.addSID(gid++, 130, "dotaccent");
+        INSTANCE.addSID(gid++, 131, "dieresis");
+        INSTANCE.addSID(gid++, 132, "ring");
+        INSTANCE.addSID(gid++, 133, "cedilla");
+        INSTANCE.addSID(gid++, 134, "hungarumlaut");
+        INSTANCE.addSID(gid++, 135, "ogonek");
+        INSTANCE.addSID(gid++, 136, "caron");
+        INSTANCE.addSID(gid++, 137, "emdash");
+        INSTANCE.addSID(gid++, 138, "AE");
+        INSTANCE.addSID(gid++, 139, "ordfeminine");
+        INSTANCE.addSID(gid++, 140, "Lslash");
+        INSTANCE.addSID(gid++, 141, "Oslash");
+        INSTANCE.addSID(gid++, 142, "OE");
+        INSTANCE.addSID(gid++, 143, "ordmasculine");
+        INSTANCE.addSID(gid++, 144, "ae");
+        INSTANCE.addSID(gid++, 145, "dotlessi");
+        INSTANCE.addSID(gid++, 146, "lslash");
+        INSTANCE.addSID(gid++, 147, "oslash");
+        INSTANCE.addSID(gid++, 148, "oe");
+        INSTANCE.addSID(gid++, 149, "germandbls");
+        INSTANCE.addSID(gid++, 150, "onesuperior");
+        INSTANCE.addSID(gid++, 151, "logicalnot");
+        INSTANCE.addSID(gid++, 152, "mu");
+        INSTANCE.addSID(gid++, 153, "trademark");
+        INSTANCE.addSID(gid++, 154, "Eth");
+        INSTANCE.addSID(gid++, 155, "onehalf");
+        INSTANCE.addSID(gid++, 156, "plusminus");
+        INSTANCE.addSID(gid++, 157, "Thorn");
+        INSTANCE.addSID(gid++, 158, "onequarter");
+        INSTANCE.addSID(gid++, 159, "divide");
+        INSTANCE.addSID(gid++, 160, "brokenbar");
+        INSTANCE.addSID(gid++, 161, "degree");
+        INSTANCE.addSID(gid++, 162, "thorn");
+        INSTANCE.addSID(gid++, 163, "threequarters");
+        INSTANCE.addSID(gid++, 164, "twosuperior");
+        INSTANCE.addSID(gid++, 165, "registered");
+        INSTANCE.addSID(gid++, 166, "minus");
+        INSTANCE.addSID(gid++, 167, "eth");
+        INSTANCE.addSID(gid++, 168, "multiply");
+        INSTANCE.addSID(gid++, 169, "threesuperior");
+        INSTANCE.addSID(gid++, 170, "copyright");
+        INSTANCE.addSID(gid++, 171, "Aacute");
+        INSTANCE.addSID(gid++, 172, "Acircumflex");
+        INSTANCE.addSID(gid++, 173, "Adieresis");
+        INSTANCE.addSID(gid++, 174, "Agrave");
+        INSTANCE.addSID(gid++, 175, "Aring");
+        INSTANCE.addSID(gid++, 176, "Atilde");
+        INSTANCE.addSID(gid++, 177, "Ccedilla");
+        INSTANCE.addSID(gid++, 178, "Eacute");
+        INSTANCE.addSID(gid++, 179, "Ecircumflex");
+        INSTANCE.addSID(gid++, 180, "Edieresis");
+        INSTANCE.addSID(gid++, 181, "Egrave");
+        INSTANCE.addSID(gid++, 182, "Iacute");
+        INSTANCE.addSID(gid++, 183, "Icircumflex");
+        INSTANCE.addSID(gid++, 184, "Idieresis");
+        INSTANCE.addSID(gid++, 185, "Igrave");
+        INSTANCE.addSID(gid++, 186, "Ntilde");
+        INSTANCE.addSID(gid++, 187, "Oacute");
+        INSTANCE.addSID(gid++, 188, "Ocircumflex");
+        INSTANCE.addSID(gid++, 189, "Odieresis");
+        INSTANCE.addSID(gid++, 190, "Ograve");
+        INSTANCE.addSID(gid++, 191, "Otilde");
+        INSTANCE.addSID(gid++, 192, "Scaron");
+        INSTANCE.addSID(gid++, 193, "Uacute");
+        INSTANCE.addSID(gid++, 194, "Ucircumflex");
+        INSTANCE.addSID(gid++, 195, "Udieresis");
+        INSTANCE.addSID(gid++, 196, "Ugrave");
+        INSTANCE.addSID(gid++, 197, "Yacute");
+        INSTANCE.addSID(gid++, 198, "Ydieresis");
+        INSTANCE.addSID(gid++, 199, "Zcaron");
+        INSTANCE.addSID(gid++, 200, "aacute");
+        INSTANCE.addSID(gid++, 201, "acircumflex");
+        INSTANCE.addSID(gid++, 202, "adieresis");
+        INSTANCE.addSID(gid++, 203, "agrave");
+        INSTANCE.addSID(gid++, 204, "aring");
+        INSTANCE.addSID(gid++, 205, "atilde");
+        INSTANCE.addSID(gid++, 206, "ccedilla");
+        INSTANCE.addSID(gid++, 207, "eacute");
+        INSTANCE.addSID(gid++, 208, "ecircumflex");
+        INSTANCE.addSID(gid++, 209, "edieresis");
+        INSTANCE.addSID(gid++, 210, "egrave");
+        INSTANCE.addSID(gid++, 211, "iacute");
+        INSTANCE.addSID(gid++, 212, "icircumflex");
+        INSTANCE.addSID(gid++, 213, "idieresis");
+        INSTANCE.addSID(gid++, 214, "igrave");
+        INSTANCE.addSID(gid++, 215, "ntilde");
+        INSTANCE.addSID(gid++, 216, "oacute");
+        INSTANCE.addSID(gid++, 217, "ocircumflex");
+        INSTANCE.addSID(gid++, 218, "odieresis");
+        INSTANCE.addSID(gid++, 219, "ograve");
+        INSTANCE.addSID(gid++, 220, "otilde");
+        INSTANCE.addSID(gid++, 221, "scaron");
+        INSTANCE.addSID(gid++, 222, "uacute");
+        INSTANCE.addSID(gid++, 223, "ucircumflex");
+        INSTANCE.addSID(gid++, 224, "udieresis");
+        INSTANCE.addSID(gid++, 225, "ugrave");
+        INSTANCE.addSID(gid++, 226, "yacute");
+        INSTANCE.addSID(gid++, 227, "ydieresis");
+        INSTANCE.addSID(gid++, 228, "zcaron");
     }
 }
\ No newline at end of file

Modified: pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (original)
+++ pdfbox/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java Sun Aug 17 20:02:18 2014
@@ -16,29 +16,13 @@
  */
 package org.apache.fontbox.cff;
 
-import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-
-import org.apache.fontbox.afm.CharMetric;
-import org.apache.fontbox.afm.FontMetric;
-import org.apache.fontbox.cff.CFFFont.Mapping;
-import org.apache.fontbox.cff.charset.CFFCharset;
-import org.apache.fontbox.cff.charset.CFFExpertCharset;
-import org.apache.fontbox.cff.charset.CFFExpertSubsetCharset;
-import org.apache.fontbox.cff.charset.CFFISOAdobeCharset;
-import org.apache.fontbox.cff.encoding.CFFEncoding;
-import org.apache.fontbox.cff.encoding.CFFExpertEncoding;
-import org.apache.fontbox.cff.encoding.CFFStandardEncoding;
-import org.apache.fontbox.util.BoundingBox;
 
 /**
  * This class represents a parser for a CFF font. 
@@ -56,6 +40,7 @@ public class CFFParser
     private IndexData nameIndex = null;
     private IndexData topDictIndex = null;
     private IndexData stringIndex = null;
+    private String debugFontName; // for debugging only
 
     /**
      * Parsing CFF Font using a byte array as input.
@@ -123,7 +108,6 @@ public class CFFParser
         {
             CFFFont font = parseFont(i);
             font.setGlobalSubrIndex(globalSubrIndex);
-            createFontMetrics(font);
             fonts.add(font);
         }
         return fonts;
@@ -330,35 +314,42 @@ public class CFFParser
 
     private CFFFont parseFont(int index) throws IOException
     {
-        CFFFont font = null;
+        // name index
         DataInput nameInput = new DataInput(nameIndex.getBytes(index));
         String name = nameInput.getString();
 
+        // top dict
         CFFDataInput topDictInput = new CFFDataInput(topDictIndex.getBytes(index));
         DictData topDict = readDictData(topDictInput);
+
+        // we dont't support synthetic fonts
         DictData.Entry syntheticBaseEntry = topDict.getEntry("SyntheticBase");
         if (syntheticBaseEntry != null)
         {
             throw new IOException("Synthetic Fonts are not supported");
         }
 
-        DictData.Entry rosEntry = topDict.getEntry("ROS");
-        if (rosEntry != null)
-        {
-            font = new CFFFontROS();
-            ((CFFFontROS) font).setRegistry(readString(rosEntry.getNumber(0).intValue()));
-            ((CFFFontROS) font).setOrdering(readString(rosEntry.getNumber(1).intValue()));
-            ((CFFFontROS) font).setSupplement(rosEntry.getNumber(2).intValue());
+        // determine if this is a Type 1-equivalent font or a CIDFont
+        CFFFont font;
+        boolean isCIDFont = topDict.getEntry("ROS") != null;
+        if (isCIDFont)
+        {
+            font = new CFFCIDFont();
+            DictData.Entry rosEntry = topDict.getEntry("ROS");
+            ((CFFCIDFont) font).setRegistry(readString(rosEntry.getNumber(0).intValue()));
+            ((CFFCIDFont) font).setOrdering(readString(rosEntry.getNumber(1).intValue()));
+            ((CFFCIDFont) font).setSupplement(rosEntry.getNumber(2).intValue());
         }
-
-        if (font == null)
+        else
         {
-            // -- No specific behavior for this font
-            font = new CFFFont();
+            font = new CFFType1Font();
         }
 
+        // name
+        debugFontName = name;
         font.setName(name);
 
+        // top dict
         font.addValueToTopDict("version", getString(topDict, "version"));
         font.addValueToTopDict("Notice", getString(topDict, "Notice"));
         font.addValueToTopDict("Copyright", getString(topDict, "Copyright"));
@@ -371,26 +362,22 @@ public class CFFParser
         font.addValueToTopDict("UnderlineThickness", getNumber(topDict, "UnderlineThickness", 50));
         font.addValueToTopDict("PaintType", getNumber(topDict, "PaintType", 0));
         font.addValueToTopDict("CharstringType", getNumber(topDict, "CharstringType", 2));
-        font.addValueToTopDict(
-                "FontMatrix",
-                getArray(
-                        topDict,
-                        "FontMatrix",
-                        Arrays.<Number> asList(0.001, (double) 0, (double) 0, 0.001, (double) 0, (double) 0)));
+        font.addValueToTopDict("FontMatrix", getArray(topDict, "FontMatrix", Arrays.<Number>asList(
+                                                      0.001, (double) 0, (double) 0, 0.001,
+                                                      (double) 0, (double) 0)));
         font.addValueToTopDict("UniqueID", getNumber(topDict, "UniqueID", null));
-        font.addValueToTopDict(
-                "FontBBox",
-                getArray(
-                        topDict,
-                        "FontBBox",
-                        Arrays.<Number> asList(0, 0, 0, 0)));
+        font.addValueToTopDict("FontBBox", getArray(topDict, "FontBBox",
+                                                    Arrays.<Number> asList(0, 0, 0, 0)));
         font.addValueToTopDict("StrokeWidth", getNumber(topDict, "StrokeWidth", 0));
         font.addValueToTopDict("XUID", getArray(topDict, "XUID", null));
 
+        // charstrings index
         DictData.Entry charStringsEntry = topDict.getEntry("CharStrings");
         int charStringsOffset = charStringsEntry.getNumber(0).intValue();
         input.setPosition(charStringsOffset);
         IndexData charStringsIndex = readIndexData(input);
+
+        // charset
         DictData.Entry charsetEntry = topDict.getEntry("charset");
         CFFCharset charset;
         int charsetId = charsetEntry != null ? charsetEntry.getNumber(0).intValue() : 0;
@@ -409,171 +396,193 @@ public class CFFParser
         else
         {
             input.setPosition(charsetId);
-            charset = readCharset(input, charStringsIndex.getCount());
+            charset = readCharset(input, charStringsIndex.getCount(), isCIDFont);
         }
         font.setCharset(charset);
-        font.getCharStringsDict().put(".notdef", charStringsIndex.getBytes(0));
-        int[] gids = new int[charStringsIndex.getCount()];
-        List<CFFCharset.Entry> glyphEntries = charset.getEntries();
+
+        // charstrings dict
+        font.getCharStrings().add(charStringsIndex.getBytes(0)); // .notdef
         for (int i = 1; i < charStringsIndex.getCount(); i++)
         {
-            CFFCharset.Entry glyphEntry = glyphEntries.get(i - 1);
-            gids[i - 1] = glyphEntry.getSID();
-            font.getCharStringsDict().put(glyphEntry.getName(), charStringsIndex.getBytes(i));
+            byte[] bytes = charStringsIndex.getBytes(i);
+            font.getCharStrings().add(bytes);
         }
-        DictData.Entry encodingEntry = topDict.getEntry("Encoding");
-        CFFEncoding encoding;
-        int encodingId = encodingEntry != null ? encodingEntry.getNumber(0).intValue() : 0;
-        if (encodingId == 0 || rosEntry != null) // --- ROS uses StandardEncoding
-        {
-            encoding = CFFStandardEncoding.getInstance();
-        }
-        else if (encodingId == 1)
+
+        // format-specific dictionaries
+        if (isCIDFont)
         {
-            encoding = CFFExpertEncoding.getInstance();
+            parseCIDFontDicts(topDict, (CFFCIDFont) font, charStringsIndex);
         }
         else
         {
-            input.setPosition(encodingId);
-            encoding = readEncoding(input, gids);
+            parseType1Dicts(topDict, (CFFType1Font) font, charset);
         }
-        font.setEncoding(encoding);
 
-        if (rosEntry != null)
-        {
-            // ---- It is a CIDKeyed Font, The Private Dictionary isn't in the Top Dict But in the Font Dict
-            // ---- Font Dict can be accessed by the FDArray and FDSelect
-            DictData.Entry fdArrayEntry = topDict.getEntry("FDArray");
-            if (fdArrayEntry == null)
-            {
-                throw new IOException("FDArray is missing for a CIDKeyed Font.");
-            }
-
-            int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
-            input.setPosition(fontDictOffset);
-            IndexData fdIndex = readIndexData(input);
-
-            List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String, Object>>();
-            List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String, Object>>();
-            CFFFontROS fontRos = (CFFFontROS) font;
+        return font;
+    }
 
-            for (int i = 0; i < fdIndex.getCount(); ++i)
+    /**
+     * Parse dictionaries specific to a CIDFont.
+     */
+    private void parseCIDFontDicts(DictData topDict, CFFCIDFont font, IndexData charStringsIndex)
+            throws IOException
+    {
+        // In a CIDKeyed Font, the Private dictionary isn't in the Top Dict but in the Font dict
+        // which can be accessed by a lookup using FDArray and FDSelect
+        DictData.Entry fdArrayEntry = topDict.getEntry("FDArray");
+        if (fdArrayEntry == null)
+        {
+            throw new IOException("FDArray is missing for a CIDKeyed Font.");
+        }
+
+        // font dict index
+        int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
+        input.setPosition(fontDictOffset);
+        IndexData fdIndex = readIndexData(input);
+
+        List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String, Object>>();
+        List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String, Object>>();
+
+        for (int i = 0; i < fdIndex.getCount(); ++i)
+        {
+            byte[] bytes = fdIndex.getBytes(i);
+            CFFDataInput fontDictInput = new CFFDataInput(bytes);
+            DictData fontDict = readDictData(fontDictInput);
+
+            // font dict
+            Map<String, Object> fontDictMap = new LinkedHashMap<String, Object>();
+            fontDictMap.put("FontName", getString(fontDict, "FontName"));
+            fontDictMap.put("FontType", getNumber(fontDict, "FontType", 0));
+            fontDictMap.put("FontBBox", getDelta(fontDict, "FontBBox", null));
+            fontDictMap.put("FontMatrix", getDelta(fontDict, "FontMatrix", null));
+            // TODO OD-4 : Add here other keys
+            fontDictionaries.add(fontDictMap);
+
+            // read private dict
+            DictData.Entry privateEntry = fontDict.getEntry("Private");
+            if (privateEntry == null)
             {
-                byte[] b = fdIndex.getBytes(i);
-                CFFDataInput fontDictInput = new CFFDataInput(b);
-                DictData fontDictData = readDictData(fontDictInput);
-
-                Map<String, Object> fontDictMap = new LinkedHashMap<String, Object>();
-                fontDictMap.put("FontName", getString(fontDictData, "FontName"));
-                fontDictMap.put("FontType", getNumber(fontDictData, "FontType", 0));
-                fontDictMap.put("FontBBox", getDelta(fontDictData, "FontBBox", null));
-                fontDictMap.put("FontMatrix", getDelta(fontDictData, "FontMatrix", null));
-                // TODO OD-4 : Add here other keys
-                fontDictionaries.add(fontDictMap);
-
-                DictData.Entry privateEntry = fontDictData.getEntry("Private");
-                // --- Font DICT is invalid without "Private" entry
-                if (privateEntry == null)
-                {
-                    throw new IOException("Missing Private Dictionary");
-                }
-
-                int privateOffset = privateEntry.getNumber(1).intValue();
-                input.setPosition(privateOffset);
-                int privateSize = privateEntry.getNumber(0).intValue();
-                CFFDataInput privateDictData = new CFFDataInput(input.readBytes(privateSize));
-                DictData privateDict = readDictData(privateDictData);
-
-                Map<String, Object> privDict = new LinkedHashMap<String, Object>();
-                privDict.put("BlueValues", getDelta(privateDict, "BlueValues", null));
-                privDict.put("OtherBlues", getDelta(privateDict, "OtherBlues", null));
-                privDict.put("FamilyBlues", getDelta(privateDict, "FamilyBlues", null));
-                privDict.put("FamilyOtherBlues", getDelta(privateDict, "FamilyOtherBlues", null));
-                privDict.put("BlueScale", getNumber(privateDict, "BlueScale", 0.039625));
-                privDict.put("BlueShift", getNumber(privateDict, "BlueShift", 7));
-                privDict.put("BlueFuzz", getNumber(privateDict, "BlueFuzz", 1));
-                privDict.put("StdHW", getNumber(privateDict, "StdHW", null));
-                privDict.put("StdVW", getNumber(privateDict, "StdVW", null));
-                privDict.put("StemSnapH", getDelta(privateDict, "StemSnapH", null));
-                privDict.put("StemSnapV", getDelta(privateDict, "StemSnapV", null));
-                privDict.put("ForceBold", getBoolean(privateDict, "ForceBold", false));
-                privDict.put("LanguageGroup", getNumber(privateDict, "LanguageGroup", 0));
-                privDict.put("ExpansionFactor", getNumber(privateDict, "ExpansionFactor", 0.06));
-                privDict.put("initialRandomSeed", getNumber(privateDict, "initialRandomSeed", 0));
-                privDict.put("defaultWidthX", getNumber(privateDict, "defaultWidthX", 0));
-                privDict.put("nominalWidthX", getNumber(privateDict, "nominalWidthX", 0));
-
-                int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", Integer.valueOf(0));
-                if (localSubrOffset == 0)
-                {
-                    privDict.put("Subrs", new IndexData(0));
-                }
-                else
-                {
-                    input.setPosition(privateOffset + localSubrOffset);
-                    IndexData idx = readIndexData(input);
-                    privDict.put("Subrs", idx);
-                }
-
-                privateDictionaries.add(privDict);
+                throw new IOException("Font DICT invalid without \"Private\" entry");
             }
-
-            fontRos.setFontDict(fontDictionaries);
-            fontRos.setPrivDict(privateDictionaries);
-
-            DictData.Entry fdSelectEntry = topDict.getEntry("FDSelect");
-            int fdSelectPos = fdSelectEntry.getNumber(0).intValue();
-            input.setPosition(fdSelectPos);
-            CIDKeyedFDSelect fdSelect = readFDSelect(input, charStringsIndex.getCount(), fontRos);
-
-            font.addValueToPrivateDict("defaultWidthX", 1000);
-            font.addValueToPrivateDict("nominalWidthX", 0);
-
-            fontRos.setFdSelect(fdSelect);
-
-        }
-        else
-        {
-            DictData.Entry privateEntry = topDict.getEntry("Private");
             int privateOffset = privateEntry.getNumber(1).intValue();
             input.setPosition(privateOffset);
             int privateSize = privateEntry.getNumber(0).intValue();
             CFFDataInput privateDictData = new CFFDataInput(input.readBytes(privateSize));
             DictData privateDict = readDictData(privateDictData);
-            font.addValueToPrivateDict("BlueValues", getDelta(privateDict, "BlueValues", null));
-            font.addValueToPrivateDict("OtherBlues", getDelta(privateDict, "OtherBlues", null));
-            font.addValueToPrivateDict("FamilyBlues", getDelta(privateDict, "FamilyBlues", null));
-            font.addValueToPrivateDict("FamilyOtherBlues", getDelta(privateDict, "FamilyOtherBlues", null));
-            font.addValueToPrivateDict("BlueScale", getNumber(privateDict, "BlueScale", 0.039625));
-            font.addValueToPrivateDict("BlueShift", getNumber(privateDict, "BlueShift", 7));
-            font.addValueToPrivateDict("BlueFuzz", getNumber(privateDict, "BlueFuzz", 1));
-            font.addValueToPrivateDict("StdHW", getNumber(privateDict, "StdHW", null));
-            font.addValueToPrivateDict("StdVW", getNumber(privateDict, "StdVW", null));
-            font.addValueToPrivateDict("StemSnapH", getDelta(privateDict, "StemSnapH", null));
-            font.addValueToPrivateDict("StemSnapV", getDelta(privateDict, "StemSnapV", null));
-            font.addValueToPrivateDict("ForceBold", getBoolean(privateDict, "ForceBold", false));
-            font.addValueToPrivateDict("LanguageGroup", getNumber(privateDict, "LanguageGroup", 0));
-            font.addValueToPrivateDict("ExpansionFactor",
-                    getNumber(privateDict, "ExpansionFactor", 0.06));
-            font.addValueToPrivateDict("initialRandomSeed",
-                    getNumber(privateDict, "initialRandomSeed", 0));
-            font.addValueToPrivateDict("defaultWidthX", getNumber(privateDict, "defaultWidthX", 0));
-            font.addValueToPrivateDict("nominalWidthX", getNumber(privateDict, "nominalWidthX", 0));
 
-            int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", Integer.valueOf(0));
+            // populate private dict
+            Map<String, Object> privDict = new LinkedHashMap<String, Object>();
+            privDict.put("BlueValues", getDelta(privateDict, "BlueValues", null));
+            privDict.put("OtherBlues", getDelta(privateDict, "OtherBlues", null));
+            privDict.put("FamilyBlues", getDelta(privateDict, "FamilyBlues", null));
+            privDict.put("FamilyOtherBlues", getDelta(privateDict, "FamilyOtherBlues", null));
+            privDict.put("BlueScale", getNumber(privateDict, "BlueScale", 0.039625));
+            privDict.put("BlueShift", getNumber(privateDict, "BlueShift", 7));
+            privDict.put("BlueFuzz", getNumber(privateDict, "BlueFuzz", 1));
+            privDict.put("StdHW", getNumber(privateDict, "StdHW", null));
+            privDict.put("StdVW", getNumber(privateDict, "StdVW", null));
+            privDict.put("StemSnapH", getDelta(privateDict, "StemSnapH", null));
+            privDict.put("StemSnapV", getDelta(privateDict, "StemSnapV", null));
+            privDict.put("ForceBold", getBoolean(privateDict, "ForceBold", false));
+            privDict.put("LanguageGroup", getNumber(privateDict, "LanguageGroup", 0));
+            privDict.put("ExpansionFactor", getNumber(privateDict, "ExpansionFactor", 0.06));
+            privDict.put("initialRandomSeed", getNumber(privateDict, "initialRandomSeed", 0));
+            privDict.put("defaultWidthX", getNumber(privateDict, "defaultWidthX", 0));
+            privDict.put("nominalWidthX", getNumber(privateDict, "nominalWidthX", 0));
+            privateDictionaries.add(privDict);
+
+            // local subrs
+            int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", 0);
             if (localSubrOffset == 0)
             {
-                //font.setLocalSubrIndex(new IndexData(0));
-                font.addValueToPrivateDict("Subrs", new IndexData(0));
+                privDict.put("Subrs", new IndexData(0));
             }
             else
             {
                 input.setPosition(privateOffset + localSubrOffset);
-                //font.setLocalSubrIndex(readIndexData(input));
-                font.addValueToPrivateDict("Subrs", readIndexData(input));
+                IndexData idx = readIndexData(input);
+                privDict.put("Subrs", idx);
             }
         }
-        return font;
+
+        // font-dict (FD) select
+        DictData.Entry fdSelectEntry = topDict.getEntry("FDSelect");
+        int fdSelectPos = fdSelectEntry.getNumber(0).intValue();
+        input.setPosition(fdSelectPos);
+        CIDKeyedFDSelect fdSelect = readFDSelect(input, charStringsIndex.getCount(), font);
+
+        // todo: almost certainly erroneous - CIDFonts do not have a top-level private dict
+        //font.addValueToPrivateDict("defaultWidthX", 1000);
+        //font.addValueToPrivateDict("nominalWidthX", 0);
+
+        font.setFontDict(fontDictionaries);
+        font.setPrivDict(privateDictionaries);
+        font.setFdSelect(fdSelect);
+    }
+
+    /**
+     * Parse dictionaries specific to a Type 1-equivalent font.
+     */
+    private void parseType1Dicts(DictData topDict, CFFType1Font font, CFFCharset charset)
+            throws IOException
+    {
+        // encoding
+        DictData.Entry encodingEntry = topDict.getEntry("Encoding");
+        CFFEncoding encoding;
+        int encodingId = encodingEntry != null ? encodingEntry.getNumber(0).intValue() : 0;
+        if (encodingId == 0)
+        {
+            encoding = CFFStandardEncoding.getInstance();
+        }
+        else if (encodingId == 1)
+        {
+            encoding = CFFExpertEncoding.getInstance();
+        }
+        else
+        {
+            input.setPosition(encodingId);
+            encoding = readEncoding(input, charset);
+        }
+        font.setEncoding(encoding);
+
+        // read private dict
+        DictData.Entry privateEntry = topDict.getEntry("Private");
+        int privateOffset = privateEntry.getNumber(1).intValue();
+        input.setPosition(privateOffset);
+        int privateSize = privateEntry.getNumber(0).intValue();
+        CFFDataInput privateDictData = new CFFDataInput(input.readBytes(privateSize));
+        DictData privateDict = readDictData(privateDictData);
+
+        // populate private dict
+        font.addToPrivateDict("BlueValues", getDelta(privateDict, "BlueValues", null));
+        font.addToPrivateDict("OtherBlues", getDelta(privateDict, "OtherBlues", null));
+        font.addToPrivateDict("FamilyBlues", getDelta(privateDict, "FamilyBlues", null));
+        font.addToPrivateDict("FamilyOtherBlues", getDelta(privateDict, "FamilyOtherBlues", null));
+        font.addToPrivateDict("BlueScale", getNumber(privateDict, "BlueScale", 0.039625));
+        font.addToPrivateDict("BlueShift", getNumber(privateDict, "BlueShift", 7));
+        font.addToPrivateDict("BlueFuzz", getNumber(privateDict, "BlueFuzz", 1));
+        font.addToPrivateDict("StdHW", getNumber(privateDict, "StdHW", null));
+        font.addToPrivateDict("StdVW", getNumber(privateDict, "StdVW", null));
+        font.addToPrivateDict("StemSnapH", getDelta(privateDict, "StemSnapH", null));
+        font.addToPrivateDict("StemSnapV", getDelta(privateDict, "StemSnapV", null));
+        font.addToPrivateDict("ForceBold", getBoolean(privateDict, "ForceBold", false));
+        font.addToPrivateDict("LanguageGroup", getNumber(privateDict, "LanguageGroup", 0));
+        font.addToPrivateDict("ExpansionFactor", getNumber(privateDict, "ExpansionFactor", 0.06));
+        font.addToPrivateDict("initialRandomSeed", getNumber(privateDict, "initialRandomSeed", 0));
+        font.addToPrivateDict("defaultWidthX", getNumber(privateDict, "defaultWidthX", 0));
+        font.addToPrivateDict("nominalWidthX", getNumber(privateDict, "nominalWidthX", 0));
+
+        // local subrs
+        int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", 0);
+        if (localSubrOffset == 0)
+        {
+            font.addToPrivateDict("Subrs", new IndexData(0));
+        }
+        else
+        {
+            input.setPosition(privateOffset + localSubrOffset);
+            font.addToPrivateDict("Subrs", readIndexData(input));
+        }
     }
 
     private String readString(int index) throws IOException
@@ -589,7 +598,7 @@ public class CFFParser
         }
         else
         {
-        	// technically this maps to .notdef, but we need a unique glyph name
+        	// technically this maps to .notdef, but we need a unique sid name
         	return "SID" + index;
         }
     }
@@ -597,7 +606,7 @@ public class CFFParser
     private String getString(DictData dict, String name) throws IOException
     {
         DictData.Entry entry = dict.getEntry(name);
-        return (entry != null ? readString(entry.getNumber(0).intValue()) : null);
+        return entry != null ? readString(entry.getNumber(0).intValue()) : null;
     }
 
     private Boolean getBoolean(DictData dict, String name, boolean defaultValue) throws IOException
@@ -626,18 +635,18 @@ public class CFFParser
         return entry != null ? entry.getArray() : defaultValue;
     }
 
-    private CFFEncoding readEncoding(CFFDataInput dataInput, int[] gids) throws IOException
+    private CFFEncoding readEncoding(CFFDataInput dataInput, CFFCharset charset) throws IOException
     {
         int format = dataInput.readCard8();
         int baseFormat = format & 0x7f;
 
         if (baseFormat == 0)
         {
-            return readFormat0Encoding(dataInput, format, gids);
+            return readFormat0Encoding(dataInput, charset, format);
         }
         else if (baseFormat == 1)
         {
-            return readFormat1Encoding(dataInput, format, gids);
+            return readFormat1Encoding(dataInput, charset, format);
         }
         else
         {
@@ -645,16 +654,19 @@ public class CFFParser
         }
     }
 
-    private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+    private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, CFFCharset charset,
+                                                int format) throws IOException
     {
         Format0Encoding encoding = new Format0Encoding();
         encoding.format = format;
         encoding.nCodes = dataInput.readCard8();
         encoding.code = new int[encoding.nCodes];
-        for (int i = 0; i < encoding.code.length; i++)
+        encoding.add(0, 0, ".notdef");
+        for (int gid = 1; gid < encoding.code.length; gid++)
         {
-            encoding.code[i] = dataInput.readCard8();
-            encoding.register(encoding.code[i], gids[i]);
+            encoding.code[gid] = dataInput.readCard8();
+            int sid = charset.getSIDForGID(gid);
+            encoding.add(encoding.code[gid], sid, readString(sid));
         }
         if ((format & 0x80) != 0)
         {
@@ -663,13 +675,15 @@ public class CFFParser
         return encoding;
     }
 
-    private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+    private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, CFFCharset charset,
+                                                int format) throws IOException
     {
         Format1Encoding encoding = new Format1Encoding();
         encoding.format = format;
         encoding.nRanges = dataInput.readCard8();
-        int count = 0;
         encoding.range = new Format1Encoding.Range1[encoding.nRanges];
+        encoding.add(0, 0, ".notdef");
+        int gid = 1;
         for (int i = 0; i < encoding.range.length; i++)
         {
             Format1Encoding.Range1 range = new Format1Encoding.Range1();
@@ -678,9 +692,11 @@ public class CFFParser
             encoding.range[i] = range;
             for (int j = 0; j < 1 + range.nLeft; j++)
             {
-                encoding.register(range.first + j, gids[count + j]);
+                int sid = charset.getSIDForGID(gid);
+                int code = range.first + j;
+                encoding.add(code, sid, readString(sid));
+                gid++;
             }
-            count += 1 + range.nLeft;
         }
         if ((format & 0x80) != 0)
         {
@@ -697,7 +713,8 @@ public class CFFParser
         {
             EmbeddedEncoding.Supplement supplement = new EmbeddedEncoding.Supplement();
             supplement.code = dataInput.readCard8();
-            supplement.glyph = dataInput.readSID();
+            supplement.sid = dataInput.readSID();
+            supplement.name = readString(supplement.sid);
             encoding.supplement[i] = supplement;
         }
     }
@@ -710,7 +727,7 @@ public class CFFParser
      * @return the FDSelect data
      * @throws IOException
      */
-    private CIDKeyedFDSelect readFDSelect(CFFDataInput dataInput, int nGlyphs, CFFFontROS ros) throws IOException
+    private CIDKeyedFDSelect readFDSelect(CFFDataInput dataInput, int nGlyphs, CFFCIDFont ros) throws IOException
     {
         int format = dataInput.readCard8();
         if (format == 0)
@@ -736,7 +753,7 @@ public class CFFParser
      * @return the Format 0 of the FDSelect data
      * @throws IOException
      */
-    private Format0FDSelect readFormat0FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFFontROS ros)
+    private Format0FDSelect readFormat0FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFCIDFont ros)
             throws IOException
     {
         Format0FDSelect fdselect = new Format0FDSelect(ros);
@@ -760,7 +777,7 @@ public class CFFParser
      * @return the Format 3 of the FDSelect data
      * @throws IOException
      */
-    private Format3FDSelect readFormat3FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFFontROS ros)
+    private Format3FDSelect readFormat3FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFCIDFont ros)
             throws IOException
     {
         Format3FDSelect fdselect = new Format3FDSelect(ros);
@@ -791,7 +808,7 @@ public class CFFParser
         private Range3[] range3;
         private int sentinel;
 
-        private Format3FDSelect(CFFFontROS owner)
+        private Format3FDSelect(CFFCIDFont owner)
         {
             super(owner);
         }
@@ -821,7 +838,7 @@ public class CFFParser
                     }
                     else
                     {
-                        // last range reach, the sentinel must be greater than glyph
+                        // last range reach, the sentinel must be greater than sid
                         if (sentinel > glyph)
                         {
                             return range3[i].fd;
@@ -867,25 +884,23 @@ public class CFFParser
         private int format;
         private int[] fds;
 
-        private Format0FDSelect(CFFFontROS owner)
+        private Format0FDSelect(CFFCIDFont owner)
         {
             super(owner);
         }
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see org.apache.fontbox.cff.CIDKeyedFDSelect#getFd(int)
-         */
         @Override
         public int getFd(int glyph)
         {
-            Map<String, byte[]> charString = owner.getCharStringsDict();
-            Set<String> keys = charString.keySet();
-            // ---- search the position of the given glyph
+            // todo: needs to be re-implemented
+            throw new UnsupportedOperationException("not implemented: FDSelect");
+
+            /*Map<String, byte[]> charStrings = null;// owner.getCharStringsDict();
+            Set<String> keys = charStrings.keySet();
+            // search the position of the given sid
             for (Mapping mapping : owner.getMappings())
             {
-                if (mapping.getSID() == glyph && charString.containsKey(mapping.getName()))
+                if (mapping.getSID() == glyph && charStrings.containsKey(mapping.getName()))
                 {
                     int index = 0;
                     for (String str : keys)
@@ -898,7 +913,7 @@ public class CFFParser
                     }
                 }
             }
-            return -1;
+            return -1;*/
         }
 
         @Override
@@ -908,20 +923,21 @@ public class CFFParser
         }
     }
 
-    private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs) throws IOException
+    private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs, boolean isCIDFont)
+            throws IOException
     {
         int format = dataInput.readCard8();
         if (format == 0)
         {
-            return readFormat0Charset(dataInput, format, nGlyphs);
+            return readFormat0Charset(dataInput, format, nGlyphs, isCIDFont);
         }
         else if (format == 1)
         {
-            return readFormat1Charset(dataInput, format, nGlyphs);
+            return readFormat1Charset(dataInput, format, nGlyphs, isCIDFont);
         }
         else if (format == 2)
         {
-            return readFormat2Charset(dataInput, format, nGlyphs);
+            return readFormat2Charset(dataInput, format, nGlyphs, isCIDFont);
         }
         else
         {
@@ -929,25 +945,54 @@ public class CFFParser
         }
     }
 
-    private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+    private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format, int nGlyphs,
+                                              boolean isCIDFont) throws IOException
     {
-        Format0Charset charset = new Format0Charset();
+        Format0Charset charset = new Format0Charset(isCIDFont);
         charset.format = format;
-        charset.glyph = new int[nGlyphs - 1];
-        for (int i = 0; i < charset.glyph.length; i++)
+        charset.glyph = new int[nGlyphs];
+        charset.glyph[0] = 0;
+        if (isCIDFont)
         {
-            charset.glyph[i] = dataInput.readSID();
-            charset.register(charset.glyph[i], readString(charset.glyph[i]));
+            charset.addCID(0, 0);
+        }
+        else
+        {
+            charset.addSID(0, 0, ".notdef");
+        }
+
+        for (int gid = 1; gid < charset.glyph.length; gid++)
+        {
+            int sid = dataInput.readSID();
+            charset.glyph[gid] = sid;
+            if (isCIDFont)
+            {
+                charset.addCID(gid, sid);
+            }
+            else
+            {
+                charset.addSID(gid, sid, readString(sid));
+            }
         }
         return charset;
     }
 
-    private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+    private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format, int nGlyphs,
+                                              boolean isCIDFont) throws IOException
     {
-        Format1Charset charset = new Format1Charset();
+        Format1Charset charset = new Format1Charset(isCIDFont);
         charset.format = format;
         List<Format1Charset.Range1> ranges = new ArrayList<Format1Charset.Range1>();
-        for (int i = 0; i < nGlyphs - 1;)
+        if (isCIDFont)
+        {
+            charset.addCID(0, 0);
+        }
+        else
+        {
+            charset.addSID(0, 0, ".notdef");
+        }
+
+        for (int gid = 1; gid < nGlyphs; gid++)
         {
             Format1Charset.Range1 range = new Format1Charset.Range1();
             range.first = dataInput.readSID();
@@ -955,20 +1000,38 @@ public class CFFParser
             ranges.add(range);
             for (int j = 0; j < 1 + range.nLeft; j++)
             {
-                charset.register(range.first + j, readString(range.first + j));
+                int sid = range.first + j;
+                if (isCIDFont)
+                {
+                    charset.addCID(gid + j, sid);
+                }
+                else
+                {
+                    charset.addSID(gid + j, sid, readString(sid));
+                }
             }
-            i += 1 + range.nLeft;
+            gid += range.nLeft;
         }
         charset.range = ranges.toArray(new Format1Charset.Range1[0]);
         return charset;
     }
 
-    private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+    private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format, int nGlyphs,
+                                              boolean isCIDFont) throws IOException
     {
-        Format2Charset charset = new Format2Charset();
+        Format2Charset charset = new Format2Charset(isCIDFont);
         charset.format = format;
         charset.range = new Format2Charset.Range2[0];
-        for (int i = 0; i < nGlyphs - 1;)
+        if (isCIDFont)
+        {
+            charset.addSID(0, 0, ".notdef");
+        }
+        else
+        {
+            charset.addCID(0, 0);
+        }
+
+        for (int gid = 1; gid < nGlyphs; gid++)
         {
             Format2Charset.Range2[] newRange = new Format2Charset.Range2[charset.range.length + 1];
             System.arraycopy(charset.range, 0, newRange, 0, charset.range.length);
@@ -979,9 +1042,17 @@ public class CFFParser
             charset.range[charset.range.length - 1] = range;
             for (int j = 0; j < 1 + range.nLeft; j++)
             {
-                charset.register(range.first + j, readString(range.first + j));
+                int sid = range.first + j;
+                if (isCIDFont)
+                {
+                    charset.addCID(gid + j, sid);
+                }
+                else
+                {
+                    charset.addSID(gid + j, sid, readString(sid));
+                }
             }
-            i += 1 + range.nLeft;
+            gid += range.nLeft;
         }
         return charset;
     }
@@ -1110,24 +1181,17 @@ public class CFFParser
      */
     abstract static class EmbeddedEncoding extends CFFEncoding
     {
-
         private int nSups;
         private Supplement[] supplement;
 
-        @Override
-        public boolean isFontSpecific()
-        {
-            return true;
-        }
-
-        List<Supplement> getSupplements()
+        /*List<Supplement> getSupplements()
         {
             if (supplement == null)
             {
-                return Collections.<Supplement> emptyList();
+                return Collections.emptyList();
             }
             return Arrays.asList(supplement);
-        }
+        }*/
 
         /**
          * Inner class representing a supplement for an encoding. 
@@ -1135,22 +1199,28 @@ public class CFFParser
         static class Supplement
         {
             private int code;
-            private int glyph;
+            private int sid;
+            private String name;
 
-            int getCode()
+            public int getCode()
             {
                 return code;
             }
 
-            int getGlyph()
+            public int getSID()
             {
-                return glyph;
+                return sid;
+            }
+
+            public String getName()
+            {
+                return name;
             }
 
             @Override
             public String toString()
             {
-                return getClass().getName() + "[code=" + code + ", glyph=" + glyph + "]";
+                return getClass().getName() + "[code=" + code + ", sid=" + sid + "]";
             }
         }
     }
@@ -1205,14 +1275,13 @@ public class CFFParser
     }
 
     /**
-     * Inner class representing an embedded CFF charset. 
+     * Inner class representing an embedded CFF charset.
      */
     abstract static class EmbeddedCharset extends CFFCharset
     {
-        @Override
-        public boolean isFontSpecific()
+        protected EmbeddedCharset(boolean isCIDFont)
         {
-            return true;
+            super(isCIDFont);
         }
     }
 
@@ -1224,6 +1293,11 @@ public class CFFParser
         private int format;
         private int[] glyph;
 
+        protected Format0Charset(boolean isCIDFont)
+        {
+            super(isCIDFont);
+        }
+
         @Override
         public String toString()
         {
@@ -1239,6 +1313,11 @@ public class CFFParser
         private int format;
         private Range1[] range;
 
+        protected Format1Charset(boolean isCIDFont)
+        {
+            super(isCIDFont);
+        }
+
         @Override
         public String toString()
         {
@@ -1269,6 +1348,11 @@ public class CFFParser
         private int format;
         private Range2[] range;
 
+        protected Format2Charset(boolean isCIDFont)
+        {
+            super(isCIDFont);
+        }
+
         @Override
         public String toString()
         {
@@ -1291,74 +1375,9 @@ public class CFFParser
         }
     }
 
-    private void createFontMetrics(CFFFont font) throws IOException
-    {
-        FontMetric fontMetrics = new FontMetric();
-        fontMetrics.setAFMVersion(2.0f);
-        fontMetrics.setFontName( font.getName() );
-        fontMetrics.setFullName( font.getPropertyAsString("FullName") );
-        fontMetrics.setFamilyName( font.getPropertyAsString("FamilyName") );
-        fontMetrics.setWeight( font.getPropertyAsString("Weight") );
-        CFFEncoding encoding = font.getEncoding();
-        if (encoding.isFontSpecific())
-        {
-            fontMetrics.setEncodingScheme("FontSpecific");
-        }
-        fontMetrics.setUnderlinePosition(font.getPropertyAsFloat("UnderlinePosition", -100));
-        fontMetrics.setUnderlineThickness(font.getPropertyAsFloat("UnderlineThickness", 50));
-        fontMetrics.setItalicAngle(font.getPropertyAsFloat("ItalicAngle", 0));
-        fontMetrics.setFixedPitch(font.getPropertyAsBoolean("isFixedPitch",false) );
-        
-        List<CharMetricSortable> metrics = createCharMetrics(font);
-        Collections.sort(metrics);
-        BoundingBox bounds = null;
-        for (CharMetric metric : metrics)
-        {
-            fontMetrics.addCharMetric(metric);
-            if(bounds == null)
-            {
-                bounds = metric.getBoundingBox();
-            }
-            else
-            {
-                BoundingBox.union(bounds, metric.getBoundingBox(), bounds);
-            }
-        }
-        fontMetrics.setFontBBox(bounds);
-        font.setFontMetric(fontMetrics);
-    }
-
-    private List<CharMetricSortable> createCharMetrics(CFFFont font) throws IOException
-    {
-        List<CharMetricSortable> metrics = new ArrayList<CharMetricSortable>();
-        Collection<CFFFont.Mapping> mappings = font.getMappings();
-        for (CFFFont.Mapping mapping : mappings)
-        {
-            CharMetricSortable metric = new CharMetricSortable();
-            metric.setCharacterCode(mapping.getCode());
-            metric.setName(mapping.getName());
-            metric.setWx(mapping.getType1CharString().getWidth());
-            metric.setBBox(mapping.getType1CharString().getBounds());
-            metrics.add(metric);
-        }
-        return metrics;
-    }
-
-    /**
-     * This class represents the metric of one single character. 
-     */
-    private static class CharMetricSortable extends CharMetric implements Comparable<CharMetric>
+    @Override
+    public String toString()
     {
-        public int compareTo(CharMetric that)
-        {
-            return getCharacterCode() - that.getCharacterCode();
-        }
-        
-        public void setBBox(Rectangle2D rect)
-        {
-            BoundingBox bBox = new BoundingBox((float)rect.getMinX(), (float)rect.getMinY(), (float)rect.getMaxX(), (float)rect.getMaxY());
-            setBoundingBox(bBox);
-        }
+        return getClass().getSimpleName() + "[" + debugFontName + "]";
     }
-
 }