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 < 256 and for codes >= 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 + "]";
}
-
}