You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by gb...@apache.org on 2013/03/06 17:46:37 UTC

svn commit: r1453416 [9/16] - in /pdfbox/trunk/preflight: ./ src/main/java/org/apache/pdfbox/preflight/ src/main/java/org/apache/pdfbox/preflight/action/ src/main/java/org/apache/pdfbox/preflight/annotation/ src/main/java/org/apache/pdfbox/preflight/an...

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1.java Wed Mar  6 16:46:35 2013
@@ -29,431 +29,442 @@ import java.util.Map.Entry;
 import org.apache.pdfbox.encoding.Encoding;
 import org.apache.pdfbox.preflight.PreflightConstants;
 
-public class Type1 {
-	/**
-	 * This map links the character identifier to a internal font program label
-	 * which is different from the standard Encoding
-	 */
-	private Map<Integer, String> cidToLabel = new HashMap<Integer, String>(0);
-	/**
-	 * This map links the character label to a character identifier which is
-	 * different from the standard Encoding.
-	 */
-	private Map<String, Integer> labelToCid = new HashMap<String, Integer>(0);
-	/**
-	 * This map link the character label to a container containing Glyph
-	 * description.
-	 */
-	private Map<String, GlyphDescription> labelToMetric = new HashMap<String, GlyphDescription>(0);
-
-	/**
-	 * The character encoding of the Font
-	 */
-	private Encoding encoding = null;
-
-	public Type1(Encoding encoding ) {
-		this.encoding = encoding;
-	}
-
-	void addCidWithLabel(Integer cid, String label) {
-		this.labelToCid.put(label, cid);
-		this.cidToLabel.put(cid, label);
-	}
-
-	void addGlyphDescription(String glyphLabel, GlyphDescription description) {
-		this.labelToMetric.put(glyphLabel, description);
-	}
-
-	void initEncodingWithStandardEncoding() {
-		this.labelToCid.put("/A", 0101);
-		this.labelToCid.put("/AE", 0341);
-		this.labelToCid.put("/B", 0102);
-		this.labelToCid.put("/C", 0103);
-		this.labelToCid.put("/D", 0104);
-		this.labelToCid.put("/E", 0105);
-		this.labelToCid.put("/F", 0106);
-		this.labelToCid.put("/G", 0107);
-		this.labelToCid.put("/H", 0110);
-		this.labelToCid.put("/I", 0111);
-		this.labelToCid.put("/J", 0112);
-		this.labelToCid.put("/K", 0113);
-		this.labelToCid.put("/L", 0114);
-		this.labelToCid.put("/Lslash", 0350);
-		this.labelToCid.put("/M", 0115);
-		this.labelToCid.put("/N", 0116);
-		this.labelToCid.put("/O", 0117);
-		this.labelToCid.put("/OE", 0352);
-		this.labelToCid.put("/Oslash", 0351);
-		this.labelToCid.put("/P", 0120);
-		this.labelToCid.put("/Q", 0121);
-		this.labelToCid.put("/R", 0122);
-		this.labelToCid.put("/S", 0123);
-		this.labelToCid.put("/T", 0124);
-		this.labelToCid.put("/U", 0125);
-		this.labelToCid.put("/V", 0126);
-		this.labelToCid.put("/W", 0127);
-		this.labelToCid.put("/X", 0130);
-		this.labelToCid.put("/Y", 0131);
-		this.labelToCid.put("/Z", 0132);
-		this.labelToCid.put("/a", 0141);
-		this.labelToCid.put("/acute", 0302);
-		this.labelToCid.put("/acute", 0302);
-		this.labelToCid.put("/ae", 0361);
-		this.labelToCid.put("/ampersand", 046);
-		this.labelToCid.put("/asciicircum", 0136);
-		this.labelToCid.put("/asciitilde", 0176);
-		this.labelToCid.put("/asterisk", 052);
-		this.labelToCid.put("/at", 0100);
-		this.labelToCid.put("/b", 0142);
-		this.labelToCid.put("/backslash", 0134);
-		this.labelToCid.put("/bar", 0174);
-		this.labelToCid.put("/braceleft", 0173);
-		this.labelToCid.put("/braceright", 0175);
-		this.labelToCid.put("/bracketleft", 0133);
-		this.labelToCid.put("/bracketright", 0135);
-		this.labelToCid.put("/breve", 0306);
-		this.labelToCid.put("/bullet", 0267);
-		this.labelToCid.put("/c", 0143);
-		this.labelToCid.put("/caron", 0317);
-		this.labelToCid.put("/cedilla", 0313);
-		this.labelToCid.put("/cent", 0242);
-		this.labelToCid.put("/circumflex", 0303);
-		this.labelToCid.put("/colon", 072);
-		this.labelToCid.put("/comma", 054);
-		this.labelToCid.put("/currency", 0250);
-		this.labelToCid.put("/d", 0144);
-		this.labelToCid.put("/dagger", 0262);
-		this.labelToCid.put("/daggerdbl", 0263);
-		this.labelToCid.put("/dieresis", 0310);
-		this.labelToCid.put("/dollar", 044);
-		this.labelToCid.put("/dotaccent", 0307);
-		this.labelToCid.put("/dotlessi", 0365);
-		this.labelToCid.put("/e", 0145);
-		this.labelToCid.put("/eight", 070);
-		this.labelToCid.put("/ellipsis", 274);
-		this.labelToCid.put("/emdash", 0320);
-		this.labelToCid.put("/endash", 0261);
-		this.labelToCid.put("/equal", 075);
-		this.labelToCid.put("/exclam", 041);
-		this.labelToCid.put("/exclamdown", 0241);
-		this.labelToCid.put("/f", 0146);
-		this.labelToCid.put("/fi", 0256);
-		this.labelToCid.put("/five", 0065);
-		this.labelToCid.put("/fl", 0257);
-		this.labelToCid.put("/florin", 0246);
-		this.labelToCid.put("/four", 064);
-		this.labelToCid.put("/fraction", 0244);
-		this.labelToCid.put("/g", 0147);
-		this.labelToCid.put("/germandbls", 0373);
-		this.labelToCid.put("/grave", 0301);
-		this.labelToCid.put("/greater", 0076);
-		this.labelToCid.put("/guillemotleft", 0253);
-		this.labelToCid.put("/guillemotright", 0273);
-		this.labelToCid.put("/guilsinglleft", 0254);
-		this.labelToCid.put("/guilsinglright", 0255);
-		this.labelToCid.put("/h", 0150);
-		this.labelToCid.put("/hungarumlaut", 0315);
-		this.labelToCid.put("/hyphen", 055);
-		this.labelToCid.put("/i", 0151);
-		this.labelToCid.put("/j", 0152);
-		this.labelToCid.put("/k", 0153);
-		this.labelToCid.put("/l", 0154);
-		this.labelToCid.put("/less", 0074);
-		this.labelToCid.put("/lslash", 0370);
-		this.labelToCid.put("/m", 0155);
-		this.labelToCid.put("/macron", 0305);
-		this.labelToCid.put("/n", 0156);
-		this.labelToCid.put("/nine", 071);
-		this.labelToCid.put("/numbersign", 043);
-		this.labelToCid.put("/o", 0157);
-		this.labelToCid.put("/oe", 0372);
-		this.labelToCid.put("/ogonek", 0316);
-		this.labelToCid.put("/one", 061);
-		this.labelToCid.put("/ordfeminine", 0343);
-		this.labelToCid.put("/ordmasculine", 0353);
-		this.labelToCid.put("/oslash", 0371);
-		this.labelToCid.put("/p", 0160);
-		this.labelToCid.put("/paragraph", 0266);
-		this.labelToCid.put("/parenleft", 050);
-		this.labelToCid.put("/parenright", 051);
-		this.labelToCid.put("/percent", 045);
-		this.labelToCid.put("/period", 056);
-		this.labelToCid.put("/periodcentered", 0264);
-		this.labelToCid.put("/perthousand", 0275);
-		this.labelToCid.put("/plus", 0053);
-		this.labelToCid.put("/q", 0161);
-		this.labelToCid.put("/question", 077);
-		this.labelToCid.put("/questiondown", 0277);
-		this.labelToCid.put("/quotedbl", 0042);
-		this.labelToCid.put("/quotedblbase", 0271);
-		this.labelToCid.put("/quotedblleft", 0252);
-		this.labelToCid.put("/quotedblright", 0272);
-		this.labelToCid.put("/quoteleft", 0140);
-		this.labelToCid.put("/quoteright", 047);
-		this.labelToCid.put("/quotesinglbase", 0270);
-		this.labelToCid.put("/quotesingle", 0251);
-		this.labelToCid.put("/r", 0162);
-		this.labelToCid.put("/ring", 0312);
-		this.labelToCid.put("/s", 0163);
-		this.labelToCid.put("/section", 0247);
-		this.labelToCid.put("/semicolon", 0073);
-		this.labelToCid.put("/seven", 0067);
-		this.labelToCid.put("/six", 066);
-		this.labelToCid.put("/slash", 057);
-		this.labelToCid.put("/space", 040);
-		this.labelToCid.put("/sterling", 0243);
-		this.labelToCid.put("/t", 0164);
-		this.labelToCid.put("/three", 063);
-		this.labelToCid.put("/tilde", 0304);
-		this.labelToCid.put("/two", 062);
-		this.labelToCid.put("/u", 0165);
-		this.labelToCid.put("/underscore", 0137);
-		this.labelToCid.put("/v", 0166);
-		this.labelToCid.put("/w", 0167);
-		this.labelToCid.put("/x", 0170);
-		this.labelToCid.put("/y", 0171);
-		this.labelToCid.put("/yen", 0245);
-		this.labelToCid.put("/z", 0172);
-		this.labelToCid.put("/zero", 060);
-		transafertLTOCinCTIL();
-	}
-
-	private void transafertLTOCinCTIL() {
-		for (Entry<String, Integer> entry : this.labelToCid.entrySet()) {
-			this.cidToLabel.put(entry.getValue(), entry.getKey());
-		}
-	}
-
-	void initEncodingWithISOLatin1Encoding() {
-		this.labelToCid.put("/A", 0101);
-		this.labelToCid.put("/AE", 0306);
-		this.labelToCid.put("/Aacute", 0301);
-		this.labelToCid.put("/Acircumflex", 0302);
-		this.labelToCid.put("/Adieresis", 0304);
-		this.labelToCid.put("/Agrave", 0300);
-		this.labelToCid.put("/Aring", 0305);
-		this.labelToCid.put("/Atilde", 0303);
-		this.labelToCid.put("/B", 0102);
-		this.labelToCid.put("/C", 0103);
-		this.labelToCid.put("/Ccedilla", 0307);
-		this.labelToCid.put("/D", 0104);
-		this.labelToCid.put("/E", 0105);
-		this.labelToCid.put("/Eacute", 0311);
-		this.labelToCid.put("/Ecircumflex", 0312);
-		this.labelToCid.put("/Edieresis", 0313);
-		this.labelToCid.put("/Egrave", 0310);
-		this.labelToCid.put("/Eth", 0320);
-		this.labelToCid.put("/F", 0106);
-		this.labelToCid.put("/G", 0107);
-		this.labelToCid.put("/H", 0110);
-		this.labelToCid.put("/I", 0111);
-		this.labelToCid.put("/Iacute", 0315);
-		this.labelToCid.put("/Icircumflex", 0316);
-		this.labelToCid.put("/Idieresis", 0317);
-		this.labelToCid.put("/Igrave", 0314);
-		this.labelToCid.put("/J", 0112);
-		this.labelToCid.put("/K", 0113);
-		this.labelToCid.put("/L", 0114);
-		this.labelToCid.put("/M", 0115);
-		this.labelToCid.put("/N", 0116);
-		this.labelToCid.put("/Ntilde", 0321);
-		this.labelToCid.put("/O", 0117);
-		this.labelToCid.put("/Oacute", 0323);
-		this.labelToCid.put("/Ocircumflex", 0324);
-		this.labelToCid.put("/Odieresis", 0326);
-		this.labelToCid.put("/Ograve", 0322);
-		this.labelToCid.put("/Oslash", 0330);
-		this.labelToCid.put("/Otilde", 0325);
-		this.labelToCid.put("/P", 0120);
-		this.labelToCid.put("/Q", 0121);
-		this.labelToCid.put("/R", 0122);
-		this.labelToCid.put("/S", 0123);
-		this.labelToCid.put("/T", 0124);
-		this.labelToCid.put("/Thorn", 0336);
-		this.labelToCid.put("/U", 0125);
-		this.labelToCid.put("/Uacute", 0332);
-		this.labelToCid.put("/Ucircumflex", 0333);
-		this.labelToCid.put("/Udieresis", 0334);
-		this.labelToCid.put("/Ugrave", 0331);
-		this.labelToCid.put("/V", 0126);
-		this.labelToCid.put("/W", 0127);
-		this.labelToCid.put("/X", 0130);
-		this.labelToCid.put("/Y", 0131);
-		this.labelToCid.put("/Yacute", 0335);
-		this.labelToCid.put("/Z", 0132);
-		this.labelToCid.put("/a", 0141);
-		this.labelToCid.put("/aacute", 0341);
-		this.labelToCid.put("/acircumflex", 0342);
-		this.labelToCid.put("/acute", 0222);
-		this.labelToCid.put("/acute", 0264);
-		this.labelToCid.put("/adieresis", 0344);
-		this.labelToCid.put("/ae", 0346);
-		this.labelToCid.put("/agrave", 0340);
-		this.labelToCid.put("/ampersand", 0046);
-		this.labelToCid.put("/aring", 0345);
-		this.labelToCid.put("/asciicircum", 0136);
-		this.labelToCid.put("/asciitilde", 0176);
-		this.labelToCid.put("/asterisk", 0052);
-		this.labelToCid.put("/at", 0100);
-		this.labelToCid.put("/atilde", 0343);
-		this.labelToCid.put("/b", 0142);
-		this.labelToCid.put("/backslash", 0134);
-		this.labelToCid.put("/bar", 0174);
-		this.labelToCid.put("/braceleft", 0173);
-		this.labelToCid.put("/braceright", 0175);
-		this.labelToCid.put("/bracketleft", 0133);
-		this.labelToCid.put("/bracketright", 0135);
-		this.labelToCid.put("/breve", 0226);
-		this.labelToCid.put("/brokenbar", 0246);
-		this.labelToCid.put("/c", 0143);
-		this.labelToCid.put("/caron", 0237);
-		this.labelToCid.put("/ccedilla", 0347);
-		this.labelToCid.put("/cedilla", 0270);
-		this.labelToCid.put("/cent", 0242);
-		this.labelToCid.put("/circumflex", 0223);
-		this.labelToCid.put("/colon", 0072);
-		this.labelToCid.put("/comma", 0054);
-		this.labelToCid.put("/copyright", 0251);
-		this.labelToCid.put("/currency", 0244);
-		this.labelToCid.put("/d", 0144);
-		this.labelToCid.put("/degree", 0260);
-		this.labelToCid.put("/dieresis", 0250);
-		this.labelToCid.put("/divide", 0367);
-		this.labelToCid.put("/dollar", 0044);
-		this.labelToCid.put("/dotaccent", 0227);
-		this.labelToCid.put("/dotlessi", 0220);
-		this.labelToCid.put("/e", 0145);
-		this.labelToCid.put("/eacute", 0351);
-		this.labelToCid.put("/ecircumflex", 0352);
-		this.labelToCid.put("/edieresis", 0353);
-		this.labelToCid.put("/egrave", 0350);
-		this.labelToCid.put("/eight", 0070);
-		this.labelToCid.put("/equal", 0075);
-		this.labelToCid.put("/eth", 0360);
-		this.labelToCid.put("/exclam", 0041);
-		this.labelToCid.put("/exclamdown", 0241);
-		this.labelToCid.put("/f", 0146);
-		this.labelToCid.put("/five", 0065);
-		this.labelToCid.put("/four", 0064);
-		this.labelToCid.put("/g", 0147);
-		this.labelToCid.put("/germandbls", 0337);
-		this.labelToCid.put("/grave", 0221);
-		this.labelToCid.put("/greater", 0076);
-		this.labelToCid.put("/guillemotleft", 0253);
-		this.labelToCid.put("/guillemotright", 0273);
-		this.labelToCid.put("/h", 0150);
-		this.labelToCid.put("/hungarumlaut", 0235);
-		this.labelToCid.put("/hyphen", 0255);
-		this.labelToCid.put("/i", 0151);
-		this.labelToCid.put("/iacute", 0355);
-		this.labelToCid.put("/icircumflex", 0356);
-		this.labelToCid.put("/idieresis", 0357);
-		this.labelToCid.put("/igrave", 0354);
-		this.labelToCid.put("/j", 0152);
-		this.labelToCid.put("/k", 0153);
-		this.labelToCid.put("/l", 0154);
-		this.labelToCid.put("/less", 0074);
-		this.labelToCid.put("/logicalnot", 0254);
-		this.labelToCid.put("/m", 0155);
-		this.labelToCid.put("/macron", 0257);
-		this.labelToCid.put("/minus", 0055);
-		this.labelToCid.put("/mu", 0265);
-		this.labelToCid.put("/multiply", 0327);
-		this.labelToCid.put("/n", 0156);
-		this.labelToCid.put("/nine", 0071);
-		this.labelToCid.put("/ntilde", 0361);
-		this.labelToCid.put("/numbersign", 0043);
-		this.labelToCid.put("/o", 0157);
-		this.labelToCid.put("/oacute", 0363);
-		this.labelToCid.put("/ocircumflex", 0364);
-		this.labelToCid.put("/odieresis", 0366);
-		this.labelToCid.put("/ogonek", 0236);
-		this.labelToCid.put("/ograve", 0362);
-		this.labelToCid.put("/one", 0061);
-		this.labelToCid.put("/onehalf", 0275);
-		this.labelToCid.put("/onequarter", 0274);
-		this.labelToCid.put("/onesuperior", 0271);
-		this.labelToCid.put("/ordfeminine", 0252);
-		this.labelToCid.put("/ordmasculine", 0272);
-		this.labelToCid.put("/oslash", 0370);
-		this.labelToCid.put("/otilde", 0365);
-		this.labelToCid.put("/p", 0160);
-		this.labelToCid.put("/paragraph", 0266);
-		this.labelToCid.put("/parenleft", 0050);
-		this.labelToCid.put("/parenright", 0051);
-		this.labelToCid.put("/percent", 0045);
-		this.labelToCid.put("/period", 0056);
-		this.labelToCid.put("/periodcentered", 0267);
-		this.labelToCid.put("/plus", 0053);
-		this.labelToCid.put("/plusminus", 0261);
-		this.labelToCid.put("/q", 0161);
-		this.labelToCid.put("/question", 0077);
-		this.labelToCid.put("/questiondown", 0277);
-		this.labelToCid.put("/quotedbl", 0042);
-		this.labelToCid.put("/quoteleft", 0140);
-		this.labelToCid.put("/quoteright", 0047);
-		this.labelToCid.put("/r", 0162);
-		this.labelToCid.put("/registered", 0256);
-		this.labelToCid.put("/ring", 0232);
-		this.labelToCid.put("/s", 0163);
-		this.labelToCid.put("/section", 0247);
-		this.labelToCid.put("/semicolon", 0073);
-		this.labelToCid.put("/seven", 0067);
-		this.labelToCid.put("/six", 0066);
-		this.labelToCid.put("/slash", 0057);
-		this.labelToCid.put("/space", 0040);
-		this.labelToCid.put("/sterling", 0243);
-		this.labelToCid.put("/t", 0164);
-		this.labelToCid.put("/thorn", 0376);
-		this.labelToCid.put("/three", 0063);
-		this.labelToCid.put("/threequarters", 0276);
-		this.labelToCid.put("/threesuperior", 0263);
-		this.labelToCid.put("/tilde", 0224);
-		this.labelToCid.put("/two", 0062);
-		this.labelToCid.put("/twosuperior", 0262);
-		this.labelToCid.put("/u", 0165);
-		this.labelToCid.put("/uacute", 0372);
-		this.labelToCid.put("/ucircumflex", 0373);
-		this.labelToCid.put("/udieresis", 0374);
-		this.labelToCid.put("/ugrave", 0371);
-		this.labelToCid.put("/underscore", 0137);
-		this.labelToCid.put("/v", 0166);
-		this.labelToCid.put("/w", 0167);
-		this.labelToCid.put("/x", 0170);
-		this.labelToCid.put("/y", 0171);
-		this.labelToCid.put("/yacute", 0375);
-		this.labelToCid.put("/ydieresis", 0377);
-		this.labelToCid.put("/yen", 0245);
-		this.labelToCid.put("/z", 0172);
-		this.labelToCid.put("/zero", 0060);
-		transafertLTOCinCTIL();
-	}
-
-	public int getWidthOfCID(int cid) throws GlyphException {
-		String label = getLabelAsName(cid);
-
-		GlyphDescription glyph = this.labelToMetric.get(label);
-		if (glyph != null) {
-			return glyph.getGlyphWidth();
-		}
-
-		throw new GlyphException(PreflightConstants.ERROR_FONTS_GLYPH_MISSING, 
-									cid, 
-									"Missing glyph for the CID " + cid);
-	}
-
-	private String getLabelAsName(int cid) {
-		String label = null;
-
-		try {
-			label = this.encoding.getName(cid);
-		} catch (IOException e) {
-			label = this.cidToLabel.get(cid);
-			if (label == null) {
-				label = Type1Parser.NOTDEF;
-			}
-		}
-
-		return label.charAt(0) == Type1Parser.NAME_START ? label : Type1Parser.NAME_START + label;
-	}
-}
\ No newline at end of file
+public class Type1
+{
+    /**
+     * This map links the character identifier to a internal font program label which is different from the standard
+     * Encoding
+     */
+    private Map<Integer, String> cidToLabel = new HashMap<Integer, String>(0);
+    /**
+     * This map links the character label to a character identifier which is different from the standard Encoding.
+     */
+    private Map<String, Integer> labelToCid = new HashMap<String, Integer>(0);
+    /**
+     * This map link the character label to a container containing Glyph description.
+     */
+    private Map<String, GlyphDescription> labelToMetric = new HashMap<String, GlyphDescription>(0);
+
+    /**
+     * The character encoding of the Font
+     */
+    private Encoding encoding = null;
+
+    public Type1(Encoding encoding)
+    {
+        this.encoding = encoding;
+    }
+
+    void addCidWithLabel(Integer cid, String label)
+    {
+        this.labelToCid.put(label, cid);
+        this.cidToLabel.put(cid, label);
+    }
+
+    void addGlyphDescription(String glyphLabel, GlyphDescription description)
+    {
+        this.labelToMetric.put(glyphLabel, description);
+    }
+
+    void initEncodingWithStandardEncoding()
+    {
+        this.labelToCid.put("/A", 0101);
+        this.labelToCid.put("/AE", 0341);
+        this.labelToCid.put("/B", 0102);
+        this.labelToCid.put("/C", 0103);
+        this.labelToCid.put("/D", 0104);
+        this.labelToCid.put("/E", 0105);
+        this.labelToCid.put("/F", 0106);
+        this.labelToCid.put("/G", 0107);
+        this.labelToCid.put("/H", 0110);
+        this.labelToCid.put("/I", 0111);
+        this.labelToCid.put("/J", 0112);
+        this.labelToCid.put("/K", 0113);
+        this.labelToCid.put("/L", 0114);
+        this.labelToCid.put("/Lslash", 0350);
+        this.labelToCid.put("/M", 0115);
+        this.labelToCid.put("/N", 0116);
+        this.labelToCid.put("/O", 0117);
+        this.labelToCid.put("/OE", 0352);
+        this.labelToCid.put("/Oslash", 0351);
+        this.labelToCid.put("/P", 0120);
+        this.labelToCid.put("/Q", 0121);
+        this.labelToCid.put("/R", 0122);
+        this.labelToCid.put("/S", 0123);
+        this.labelToCid.put("/T", 0124);
+        this.labelToCid.put("/U", 0125);
+        this.labelToCid.put("/V", 0126);
+        this.labelToCid.put("/W", 0127);
+        this.labelToCid.put("/X", 0130);
+        this.labelToCid.put("/Y", 0131);
+        this.labelToCid.put("/Z", 0132);
+        this.labelToCid.put("/a", 0141);
+        this.labelToCid.put("/acute", 0302);
+        this.labelToCid.put("/acute", 0302);
+        this.labelToCid.put("/ae", 0361);
+        this.labelToCid.put("/ampersand", 046);
+        this.labelToCid.put("/asciicircum", 0136);
+        this.labelToCid.put("/asciitilde", 0176);
+        this.labelToCid.put("/asterisk", 052);
+        this.labelToCid.put("/at", 0100);
+        this.labelToCid.put("/b", 0142);
+        this.labelToCid.put("/backslash", 0134);
+        this.labelToCid.put("/bar", 0174);
+        this.labelToCid.put("/braceleft", 0173);
+        this.labelToCid.put("/braceright", 0175);
+        this.labelToCid.put("/bracketleft", 0133);
+        this.labelToCid.put("/bracketright", 0135);
+        this.labelToCid.put("/breve", 0306);
+        this.labelToCid.put("/bullet", 0267);
+        this.labelToCid.put("/c", 0143);
+        this.labelToCid.put("/caron", 0317);
+        this.labelToCid.put("/cedilla", 0313);
+        this.labelToCid.put("/cent", 0242);
+        this.labelToCid.put("/circumflex", 0303);
+        this.labelToCid.put("/colon", 072);
+        this.labelToCid.put("/comma", 054);
+        this.labelToCid.put("/currency", 0250);
+        this.labelToCid.put("/d", 0144);
+        this.labelToCid.put("/dagger", 0262);
+        this.labelToCid.put("/daggerdbl", 0263);
+        this.labelToCid.put("/dieresis", 0310);
+        this.labelToCid.put("/dollar", 044);
+        this.labelToCid.put("/dotaccent", 0307);
+        this.labelToCid.put("/dotlessi", 0365);
+        this.labelToCid.put("/e", 0145);
+        this.labelToCid.put("/eight", 070);
+        this.labelToCid.put("/ellipsis", 274);
+        this.labelToCid.put("/emdash", 0320);
+        this.labelToCid.put("/endash", 0261);
+        this.labelToCid.put("/equal", 075);
+        this.labelToCid.put("/exclam", 041);
+        this.labelToCid.put("/exclamdown", 0241);
+        this.labelToCid.put("/f", 0146);
+        this.labelToCid.put("/fi", 0256);
+        this.labelToCid.put("/five", 0065);
+        this.labelToCid.put("/fl", 0257);
+        this.labelToCid.put("/florin", 0246);
+        this.labelToCid.put("/four", 064);
+        this.labelToCid.put("/fraction", 0244);
+        this.labelToCid.put("/g", 0147);
+        this.labelToCid.put("/germandbls", 0373);
+        this.labelToCid.put("/grave", 0301);
+        this.labelToCid.put("/greater", 0076);
+        this.labelToCid.put("/guillemotleft", 0253);
+        this.labelToCid.put("/guillemotright", 0273);
+        this.labelToCid.put("/guilsinglleft", 0254);
+        this.labelToCid.put("/guilsinglright", 0255);
+        this.labelToCid.put("/h", 0150);
+        this.labelToCid.put("/hungarumlaut", 0315);
+        this.labelToCid.put("/hyphen", 055);
+        this.labelToCid.put("/i", 0151);
+        this.labelToCid.put("/j", 0152);
+        this.labelToCid.put("/k", 0153);
+        this.labelToCid.put("/l", 0154);
+        this.labelToCid.put("/less", 0074);
+        this.labelToCid.put("/lslash", 0370);
+        this.labelToCid.put("/m", 0155);
+        this.labelToCid.put("/macron", 0305);
+        this.labelToCid.put("/n", 0156);
+        this.labelToCid.put("/nine", 071);
+        this.labelToCid.put("/numbersign", 043);
+        this.labelToCid.put("/o", 0157);
+        this.labelToCid.put("/oe", 0372);
+        this.labelToCid.put("/ogonek", 0316);
+        this.labelToCid.put("/one", 061);
+        this.labelToCid.put("/ordfeminine", 0343);
+        this.labelToCid.put("/ordmasculine", 0353);
+        this.labelToCid.put("/oslash", 0371);
+        this.labelToCid.put("/p", 0160);
+        this.labelToCid.put("/paragraph", 0266);
+        this.labelToCid.put("/parenleft", 050);
+        this.labelToCid.put("/parenright", 051);
+        this.labelToCid.put("/percent", 045);
+        this.labelToCid.put("/period", 056);
+        this.labelToCid.put("/periodcentered", 0264);
+        this.labelToCid.put("/perthousand", 0275);
+        this.labelToCid.put("/plus", 0053);
+        this.labelToCid.put("/q", 0161);
+        this.labelToCid.put("/question", 077);
+        this.labelToCid.put("/questiondown", 0277);
+        this.labelToCid.put("/quotedbl", 0042);
+        this.labelToCid.put("/quotedblbase", 0271);
+        this.labelToCid.put("/quotedblleft", 0252);
+        this.labelToCid.put("/quotedblright", 0272);
+        this.labelToCid.put("/quoteleft", 0140);
+        this.labelToCid.put("/quoteright", 047);
+        this.labelToCid.put("/quotesinglbase", 0270);
+        this.labelToCid.put("/quotesingle", 0251);
+        this.labelToCid.put("/r", 0162);
+        this.labelToCid.put("/ring", 0312);
+        this.labelToCid.put("/s", 0163);
+        this.labelToCid.put("/section", 0247);
+        this.labelToCid.put("/semicolon", 0073);
+        this.labelToCid.put("/seven", 0067);
+        this.labelToCid.put("/six", 066);
+        this.labelToCid.put("/slash", 057);
+        this.labelToCid.put("/space", 040);
+        this.labelToCid.put("/sterling", 0243);
+        this.labelToCid.put("/t", 0164);
+        this.labelToCid.put("/three", 063);
+        this.labelToCid.put("/tilde", 0304);
+        this.labelToCid.put("/two", 062);
+        this.labelToCid.put("/u", 0165);
+        this.labelToCid.put("/underscore", 0137);
+        this.labelToCid.put("/v", 0166);
+        this.labelToCid.put("/w", 0167);
+        this.labelToCid.put("/x", 0170);
+        this.labelToCid.put("/y", 0171);
+        this.labelToCid.put("/yen", 0245);
+        this.labelToCid.put("/z", 0172);
+        this.labelToCid.put("/zero", 060);
+        transafertLTOCinCTIL();
+    }
+
+    private void transafertLTOCinCTIL()
+    {
+        for (Entry<String, Integer> entry : this.labelToCid.entrySet())
+        {
+            this.cidToLabel.put(entry.getValue(), entry.getKey());
+        }
+    }
+
+    void initEncodingWithISOLatin1Encoding()
+    {
+        this.labelToCid.put("/A", 0101);
+        this.labelToCid.put("/AE", 0306);
+        this.labelToCid.put("/Aacute", 0301);
+        this.labelToCid.put("/Acircumflex", 0302);
+        this.labelToCid.put("/Adieresis", 0304);
+        this.labelToCid.put("/Agrave", 0300);
+        this.labelToCid.put("/Aring", 0305);
+        this.labelToCid.put("/Atilde", 0303);
+        this.labelToCid.put("/B", 0102);
+        this.labelToCid.put("/C", 0103);
+        this.labelToCid.put("/Ccedilla", 0307);
+        this.labelToCid.put("/D", 0104);
+        this.labelToCid.put("/E", 0105);
+        this.labelToCid.put("/Eacute", 0311);
+        this.labelToCid.put("/Ecircumflex", 0312);
+        this.labelToCid.put("/Edieresis", 0313);
+        this.labelToCid.put("/Egrave", 0310);
+        this.labelToCid.put("/Eth", 0320);
+        this.labelToCid.put("/F", 0106);
+        this.labelToCid.put("/G", 0107);
+        this.labelToCid.put("/H", 0110);
+        this.labelToCid.put("/I", 0111);
+        this.labelToCid.put("/Iacute", 0315);
+        this.labelToCid.put("/Icircumflex", 0316);
+        this.labelToCid.put("/Idieresis", 0317);
+        this.labelToCid.put("/Igrave", 0314);
+        this.labelToCid.put("/J", 0112);
+        this.labelToCid.put("/K", 0113);
+        this.labelToCid.put("/L", 0114);
+        this.labelToCid.put("/M", 0115);
+        this.labelToCid.put("/N", 0116);
+        this.labelToCid.put("/Ntilde", 0321);
+        this.labelToCid.put("/O", 0117);
+        this.labelToCid.put("/Oacute", 0323);
+        this.labelToCid.put("/Ocircumflex", 0324);
+        this.labelToCid.put("/Odieresis", 0326);
+        this.labelToCid.put("/Ograve", 0322);
+        this.labelToCid.put("/Oslash", 0330);
+        this.labelToCid.put("/Otilde", 0325);
+        this.labelToCid.put("/P", 0120);
+        this.labelToCid.put("/Q", 0121);
+        this.labelToCid.put("/R", 0122);
+        this.labelToCid.put("/S", 0123);
+        this.labelToCid.put("/T", 0124);
+        this.labelToCid.put("/Thorn", 0336);
+        this.labelToCid.put("/U", 0125);
+        this.labelToCid.put("/Uacute", 0332);
+        this.labelToCid.put("/Ucircumflex", 0333);
+        this.labelToCid.put("/Udieresis", 0334);
+        this.labelToCid.put("/Ugrave", 0331);
+        this.labelToCid.put("/V", 0126);
+        this.labelToCid.put("/W", 0127);
+        this.labelToCid.put("/X", 0130);
+        this.labelToCid.put("/Y", 0131);
+        this.labelToCid.put("/Yacute", 0335);
+        this.labelToCid.put("/Z", 0132);
+        this.labelToCid.put("/a", 0141);
+        this.labelToCid.put("/aacute", 0341);
+        this.labelToCid.put("/acircumflex", 0342);
+        this.labelToCid.put("/acute", 0222);
+        this.labelToCid.put("/acute", 0264);
+        this.labelToCid.put("/adieresis", 0344);
+        this.labelToCid.put("/ae", 0346);
+        this.labelToCid.put("/agrave", 0340);
+        this.labelToCid.put("/ampersand", 0046);
+        this.labelToCid.put("/aring", 0345);
+        this.labelToCid.put("/asciicircum", 0136);
+        this.labelToCid.put("/asciitilde", 0176);
+        this.labelToCid.put("/asterisk", 0052);
+        this.labelToCid.put("/at", 0100);
+        this.labelToCid.put("/atilde", 0343);
+        this.labelToCid.put("/b", 0142);
+        this.labelToCid.put("/backslash", 0134);
+        this.labelToCid.put("/bar", 0174);
+        this.labelToCid.put("/braceleft", 0173);
+        this.labelToCid.put("/braceright", 0175);
+        this.labelToCid.put("/bracketleft", 0133);
+        this.labelToCid.put("/bracketright", 0135);
+        this.labelToCid.put("/breve", 0226);
+        this.labelToCid.put("/brokenbar", 0246);
+        this.labelToCid.put("/c", 0143);
+        this.labelToCid.put("/caron", 0237);
+        this.labelToCid.put("/ccedilla", 0347);
+        this.labelToCid.put("/cedilla", 0270);
+        this.labelToCid.put("/cent", 0242);
+        this.labelToCid.put("/circumflex", 0223);
+        this.labelToCid.put("/colon", 0072);
+        this.labelToCid.put("/comma", 0054);
+        this.labelToCid.put("/copyright", 0251);
+        this.labelToCid.put("/currency", 0244);
+        this.labelToCid.put("/d", 0144);
+        this.labelToCid.put("/degree", 0260);
+        this.labelToCid.put("/dieresis", 0250);
+        this.labelToCid.put("/divide", 0367);
+        this.labelToCid.put("/dollar", 0044);
+        this.labelToCid.put("/dotaccent", 0227);
+        this.labelToCid.put("/dotlessi", 0220);
+        this.labelToCid.put("/e", 0145);
+        this.labelToCid.put("/eacute", 0351);
+        this.labelToCid.put("/ecircumflex", 0352);
+        this.labelToCid.put("/edieresis", 0353);
+        this.labelToCid.put("/egrave", 0350);
+        this.labelToCid.put("/eight", 0070);
+        this.labelToCid.put("/equal", 0075);
+        this.labelToCid.put("/eth", 0360);
+        this.labelToCid.put("/exclam", 0041);
+        this.labelToCid.put("/exclamdown", 0241);
+        this.labelToCid.put("/f", 0146);
+        this.labelToCid.put("/five", 0065);
+        this.labelToCid.put("/four", 0064);
+        this.labelToCid.put("/g", 0147);
+        this.labelToCid.put("/germandbls", 0337);
+        this.labelToCid.put("/grave", 0221);
+        this.labelToCid.put("/greater", 0076);
+        this.labelToCid.put("/guillemotleft", 0253);
+        this.labelToCid.put("/guillemotright", 0273);
+        this.labelToCid.put("/h", 0150);
+        this.labelToCid.put("/hungarumlaut", 0235);
+        this.labelToCid.put("/hyphen", 0255);
+        this.labelToCid.put("/i", 0151);
+        this.labelToCid.put("/iacute", 0355);
+        this.labelToCid.put("/icircumflex", 0356);
+        this.labelToCid.put("/idieresis", 0357);
+        this.labelToCid.put("/igrave", 0354);
+        this.labelToCid.put("/j", 0152);
+        this.labelToCid.put("/k", 0153);
+        this.labelToCid.put("/l", 0154);
+        this.labelToCid.put("/less", 0074);
+        this.labelToCid.put("/logicalnot", 0254);
+        this.labelToCid.put("/m", 0155);
+        this.labelToCid.put("/macron", 0257);
+        this.labelToCid.put("/minus", 0055);
+        this.labelToCid.put("/mu", 0265);
+        this.labelToCid.put("/multiply", 0327);
+        this.labelToCid.put("/n", 0156);
+        this.labelToCid.put("/nine", 0071);
+        this.labelToCid.put("/ntilde", 0361);
+        this.labelToCid.put("/numbersign", 0043);
+        this.labelToCid.put("/o", 0157);
+        this.labelToCid.put("/oacute", 0363);
+        this.labelToCid.put("/ocircumflex", 0364);
+        this.labelToCid.put("/odieresis", 0366);
+        this.labelToCid.put("/ogonek", 0236);
+        this.labelToCid.put("/ograve", 0362);
+        this.labelToCid.put("/one", 0061);
+        this.labelToCid.put("/onehalf", 0275);
+        this.labelToCid.put("/onequarter", 0274);
+        this.labelToCid.put("/onesuperior", 0271);
+        this.labelToCid.put("/ordfeminine", 0252);
+        this.labelToCid.put("/ordmasculine", 0272);
+        this.labelToCid.put("/oslash", 0370);
+        this.labelToCid.put("/otilde", 0365);
+        this.labelToCid.put("/p", 0160);
+        this.labelToCid.put("/paragraph", 0266);
+        this.labelToCid.put("/parenleft", 0050);
+        this.labelToCid.put("/parenright", 0051);
+        this.labelToCid.put("/percent", 0045);
+        this.labelToCid.put("/period", 0056);
+        this.labelToCid.put("/periodcentered", 0267);
+        this.labelToCid.put("/plus", 0053);
+        this.labelToCid.put("/plusminus", 0261);
+        this.labelToCid.put("/q", 0161);
+        this.labelToCid.put("/question", 0077);
+        this.labelToCid.put("/questiondown", 0277);
+        this.labelToCid.put("/quotedbl", 0042);
+        this.labelToCid.put("/quoteleft", 0140);
+        this.labelToCid.put("/quoteright", 0047);
+        this.labelToCid.put("/r", 0162);
+        this.labelToCid.put("/registered", 0256);
+        this.labelToCid.put("/ring", 0232);
+        this.labelToCid.put("/s", 0163);
+        this.labelToCid.put("/section", 0247);
+        this.labelToCid.put("/semicolon", 0073);
+        this.labelToCid.put("/seven", 0067);
+        this.labelToCid.put("/six", 0066);
+        this.labelToCid.put("/slash", 0057);
+        this.labelToCid.put("/space", 0040);
+        this.labelToCid.put("/sterling", 0243);
+        this.labelToCid.put("/t", 0164);
+        this.labelToCid.put("/thorn", 0376);
+        this.labelToCid.put("/three", 0063);
+        this.labelToCid.put("/threequarters", 0276);
+        this.labelToCid.put("/threesuperior", 0263);
+        this.labelToCid.put("/tilde", 0224);
+        this.labelToCid.put("/two", 0062);
+        this.labelToCid.put("/twosuperior", 0262);
+        this.labelToCid.put("/u", 0165);
+        this.labelToCid.put("/uacute", 0372);
+        this.labelToCid.put("/ucircumflex", 0373);
+        this.labelToCid.put("/udieresis", 0374);
+        this.labelToCid.put("/ugrave", 0371);
+        this.labelToCid.put("/underscore", 0137);
+        this.labelToCid.put("/v", 0166);
+        this.labelToCid.put("/w", 0167);
+        this.labelToCid.put("/x", 0170);
+        this.labelToCid.put("/y", 0171);
+        this.labelToCid.put("/yacute", 0375);
+        this.labelToCid.put("/ydieresis", 0377);
+        this.labelToCid.put("/yen", 0245);
+        this.labelToCid.put("/z", 0172);
+        this.labelToCid.put("/zero", 0060);
+        transafertLTOCinCTIL();
+    }
+
+    public int getWidthOfCID(int cid) throws GlyphException
+    {
+        String label = getLabelAsName(cid);
+
+        GlyphDescription glyph = this.labelToMetric.get(label);
+        if (glyph != null)
+        {
+            return glyph.getGlyphWidth();
+        }
+
+        throw new GlyphException(PreflightConstants.ERROR_FONTS_GLYPH_MISSING, cid, "Missing glyph for the CID " + cid);
+    }
+
+    private String getLabelAsName(int cid)
+    {
+        String label = null;
+
+        try
+        {
+            label = this.encoding.getName(cid);
+        }
+        catch (IOException e)
+        {
+            label = this.cidToLabel.get(cid);
+            if (label == null)
+            {
+                label = Type1Parser.NOTDEF;
+            }
+        }
+
+        return label.charAt(0) == Type1Parser.NAME_START ? label : Type1Parser.NAME_START + label;
+    }
+}

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1Parser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1Parser.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1Parser.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1Parser.java Wed Mar  6 16:46:35 2013
@@ -44,548 +44,680 @@ import org.apache.pdfbox.encoding.PdfDoc
 import org.apache.pdfbox.encoding.StandardEncoding;
 import org.apache.pdfbox.encoding.WinAnsiEncoding;
 
-public final class Type1Parser {
+public final class Type1Parser
+{
 
-	public static final Logger LOGGER = Logger.getLogger(Type1Parser.class);
-	
-	protected static final char NAME_START = '/';
-	protected static final String NOTDEF = NAME_START + ".notdef";
-	protected static final int DEFAULT_LEN_IV = 4;
-	
-	private static final String PS_STANDARD_ENCODING = "StandardEncoding";
-	private static final String PS_ISOLATIN_ENCODING = "ISOLatin1Encoding";
-
-	private static final String TOKEN_ENCODING = "US-ASCII";
-
-	/**
-	 * The PostScript font stream.
-	 */
-	private PeekInputStream fontProgram = null;
-	/**
-	 * The length in bytes of the clear-text portion of the Type1 font program.
-	 */
-	private int clearTextSize = 0;
-	/**
-	 * The length in bytes of the eexec encrypted portion of the type1 font
-	 * program.
-	 */
-	private int eexecSize = 0;
-
-	/**
-	 * This counter is used to know how many byte have been read.
-	 * It is used to read the clear part of the font. this computer is
-	 * updated during the parsing of the encoding part too but it is not 
-	 * used.
-	 */
-	private int numberOfReadBytes = 0;
-	
-	/**
-	 * Object which contains information coming from the parsing.
-	 */
-	private Type1 type1Font = null;
-	
-	private Type1Parser(InputStream type1, int length1, int length2, Encoding enc) throws IOException {
-		super();
-		this.fontProgram = new PeekInputStream(type1);
-		this.clearTextSize = length1;
-		this.eexecSize = length2;
-		// ---- Instantiate the Encoding Map
-		if (enc != null) {
-			this.type1Font = new Type1(enc);
-		} else {
-			this.type1Font = new Type1(new StandardEncoding());
-		}
-		this.type1Font.addCidWithLabel(-1, NOTDEF);
-	}
-
-	/**
-	 * 
-	 * @param fontProgram the stream of the font program extracted from the PDF file.
-	 * @param clearTextLength the length in bytes of the clear part of the font program.
-	 * @param eexecLength the length in bytes of the encoded part.
-	 * @return
-	 * @throws IOException
-	 */
-	public static Type1Parser createParser(
-			InputStream fontProgram, 
-			int clearTextLength, 
-			int eexecLength) throws IOException {
-
-		Encoding encoding = getEncodingObject("");
-		return createParserWithEncodingObject(fontProgram, clearTextLength, eexecLength, encoding);		
-	}
-
-	/**
-	 * 
-	 * @param fontProgram the stream of the font program extracted from the PDF file.
-	 * @param clearTextLength the length in bytes of the clear part of the font program.
-	 * @param eexecLength the length in bytes of the encoded part.
-	 * @param encodingName The name of encoding which is used by this font program.
-	 * @return
-	 * @throws IOException
-	 */
-	public static Type1Parser createParserWithEncodingName(
-			InputStream fontProgram, 
-			int clearTextLength, 
-			int eexecLength, 
-			String encodingName) throws IOException {
-
-		Encoding encoding = getEncodingObject(encodingName);
-		return createParserWithEncodingObject(fontProgram, clearTextLength, eexecLength, encoding);
-	}
-
-	private static Encoding getEncodingObject(String encodingName) {
-		Encoding encoding = new StandardEncoding();
-		if (FONT_DICTIONARY_VALUE_ENCODING_MAC.equals(encodingName)) {
-			encoding = new MacRomanEncoding();
-		} else if (FONT_DICTIONARY_VALUE_ENCODING_MAC_EXP.equals(encodingName)) {
-			encoding = new MacRomanEncoding();
-		} else if (FONT_DICTIONARY_VALUE_ENCODING_WIN.equals(encodingName)) {
-			encoding = new WinAnsiEncoding();
-		} else if (FONT_DICTIONARY_VALUE_ENCODING_PDFDOC.equals(encodingName)) {
-			encoding = new PdfDocEncoding();
-		}
-		return encoding;
-	}
-
-	/**
-	 * 
-	 * @param fontProgram the stream of the font program extracted from the PDF file.
-	 * @param clearTextLength the length in bytes of the clear part of the font program.
-	 * @param eexecLength the length in bytes of the encoded part.
-	 * @param encodingName The encoding object which is used by this font program.
-	 * @return
-	 * @throws IOException
-	 */
-	public static Type1Parser createParserWithEncodingObject(
-			InputStream fontProgram, 
-			int clearTextLength, 
-			int eexecLength, 
-			Encoding encoding)  throws IOException {
-
-		return new Type1Parser(fontProgram, clearTextLength, eexecLength, encoding);
-	}
-
-	public Type1 parse() throws IOException {
-		parseClearPartOfFontProgram(this.fontProgram);
-		decodeAndParseEExecPart(this.fontProgram);
-		return this.type1Font;
-	}
-
-	private void parseClearPartOfFontProgram(PeekInputStream stream) throws IOException {
-		skipComments(stream);
-		parseFontInformationUntilEncodingPart(stream);
-	}
-
-	private void decodeAndParseEExecPart(PeekInputStream stream) throws IOException {
-		byte[] eexecPart = readEexec(stream);
-		byte[] decodedEExecPart = decodeEexec(eexecPart);
-		PeekInputStream eexecStream = new PeekInputStream(new ByteArrayInputStream(decodedEExecPart));
-		parseEExecPart(eexecStream);
-	}
-
-	private void skipComments(PeekInputStream stream) throws IOException {
-		int nextChar = stream.peek();
-		while (nextChar == '%') {
-			if (nextChar == -1) {
-				throw new IOException("Unexpected End Of File during a comment parsing");
-			}
-			readLine(stream);
-			nextChar = stream.peek();
-		}
-	}
-
-	private void parseFontInformationUntilEncodingPart(PeekInputStream stream) throws IOException {
-		byte[] token = readToken(stream);
-		while (!isEExecKeyWord(token)) {
-			// add here specific operation to memorize useful information
-			if (isEncodingKeyWord(token)) {
-				parseEncodingDefinition(stream);
-			}
-			token = readToken(stream);
-		}
-
-		while (!isStartOfEExecReached()) {
-			readNextCharacter(stream);
-		}
-	}
-
-	private void parseEncodingDefinition(PeekInputStream stream) throws IOException {
-		byte[] token = readToken(stream);
-		String readableToken = new String(token, TOKEN_ENCODING);
-		if (PS_ISOLATIN_ENCODING.equals(readableToken)) {
-			this.type1Font.initEncodingWithISOLatin1Encoding();
-		} else if (PS_STANDARD_ENCODING.equals(readableToken)) {
-			this.type1Font.initEncodingWithStandardEncoding();
-		} else {
-			try {
-				Integer.parseInt(readableToken);
-				throwExceptionIfUnexpectedToken("array", readToken(stream));
-				readEndSetEncodingValues(stream);
-			} catch (NumberFormatException e) {
-				throw new IOException("Invalid encoding : Expected int value before \"array\" " 
-						+ "key word if the Encoding isn't Standard or ISOLatin");
-			}
-		}
-	}
-
-	private void parseEExecPart(PeekInputStream stream) throws IOException {
-		int lenIV = DEFAULT_LEN_IV;
-		byte[] previousToken = new byte[0];
-		while(!isEndOfStream(stream)) {
-			byte[] token = readToken(stream);
-			if (isLenIVKeyWord(token)) {
-				// lenIV belong to Private Dictionary. 
-				// If you create a method to parse PrivateDict, please update this function
-				byte[] l = readToken(stream);
-				lenIV = Integer.parseInt(new String(l, TOKEN_ENCODING));
-			} else if (isBeginOfBinaryPart(token)) {
-				try {
-					int lengthOfBinaryPart = Integer.parseInt(new String(previousToken, TOKEN_ENCODING));
-					skipSingleBlankSeparator(stream);
-					stream.read(new byte[lengthOfBinaryPart], 0, lengthOfBinaryPart);
-					token = readToken(stream); // read the end of binary part
-				} catch (NumberFormatException e) {
-					throw new IOException("Binary part found but previous token wasn't an integer");
-				}
-			} else if (isCharStringKeyWord(token)) {
-				parseCharStringArray(stream, lenIV);
-			}
-			previousToken = token;
-		}
-	}
-
-	private void parseCharStringArray(PeekInputStream stream, int lenIV) throws IOException {
-		int numberOfElements = readNumberOfCharStrings(stream);
-		goToBeginOfCharStringElements(stream);
-		
-		while (numberOfElements > 0) {
-			byte[] labelToken = readToken(stream);
-			String label = new String(labelToken, TOKEN_ENCODING);
- 
-			if (label.equals("end")){
-				// TODO thrown exception ? add an error/warning in the PreflightContext ??	
-				LOGGER.warn("[Type 1] Invalid number of elements in the CharString");
-				break;
-			}
-			
-			byte[] sizeOfCharStringToken = readToken(stream);
-			int sizeOfCharString = Integer.parseInt(new String(sizeOfCharStringToken,TOKEN_ENCODING));
-
-			readToken(stream); // skip "RD" or "-|" token
-			skipSingleBlankSeparator(stream); // "RD" or "-|" are followed by a space
-
-			byte[] descBinary = new byte[sizeOfCharString];
-			stream.read(descBinary, 0, sizeOfCharString);
-			byte[] description = Type1FontUtil.charstringDecrypt(descBinary, lenIV);
-			Type1CharStringParser t1p = new Type1CharStringParser();
-			// TODO provide the local subroutine indexes
-			List<Object> operations = t1p.parse(description, new IndexData(0));
-			type1Font.addGlyphDescription(label, new GlyphDescription(operations));
-
-			readToken(stream); // skip "ND" or "|-" token
-			--numberOfElements;
-		}
-	}
-
-	private void goToBeginOfCharStringElements(PeekInputStream stream) throws IOException {
-		byte[] token = new byte[0];
-		do {
-			token = readToken(stream);
-		} while(isNotBeginKeyWord(token));
-	}
-	
-	private boolean isNotBeginKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return !"begin".equals(word);		
-	}
-
-	private boolean isBeginOfBinaryPart(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return ("RD".equals(word) || "-|".equals(word));
-	}
-
-	private boolean isLenIVKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "/lenIV".equals(word);
-	}
-
-	private boolean isCharStringKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "/CharStrings".equals(word);
-	}
-
-	private int readNumberOfCharStrings(PeekInputStream stream) throws IOException {
-		byte[] token = readToken(stream);
-		String word = new String(token, TOKEN_ENCODING);
-		try {
-			return Integer.parseInt(word);
-		} catch (NumberFormatException e) {
-			throw new IOException("Number of CharStrings elements is expected.");
-		}
-	}
-	
-	private void throwExceptionIfUnexpectedToken(String expectedValue, byte[] token) throws IOException {
-		String valueToCheck = new String(token, TOKEN_ENCODING);
-		if (!expectedValue.equals(valueToCheck)) {
-			throw new IOException(expectedValue + " was expected but we received " + valueToCheck);
-		}
-	}
-
-	private void readEndSetEncodingValues(PeekInputStream stream) throws IOException {
-		byte[] token = readToken(stream);
-		boolean lastTokenWasReadOnly = false;
-		while ( !(lastTokenWasReadOnly && isDefKeyWord(token)) ) {
-			if (isDupKeyWord(token)) {
-				byte[] cidToken = readToken(stream);
-				byte[] labelToken = readToken(stream);
-				String cid = new String(cidToken, TOKEN_ENCODING);
-				String label = new String(labelToken, TOKEN_ENCODING);
-				try {	
-					this.type1Font.addCidWithLabel(Integer.parseInt(cid), label);
-				} catch (NumberFormatException e) {
-					throw new IOException("Invalid encoding : Expected CID value before \"" + label + "\" label");
-				}
-			} else {
-				lastTokenWasReadOnly = isReadOnlyKeyWord(token);
-			}
-			token = readToken(stream);
-		}
-	}
-
-	private byte[] readEexec(PeekInputStream stream) throws IOException {
-		int BUFFER_SIZE = 1024;
-		byte[] buffer = new byte[BUFFER_SIZE];
-		ByteArrayOutputStream eexecPart = new ByteArrayOutputStream();
-		int lr = 0;
-		int total = 0;
-		do {
-			lr = stream.read(buffer, 0, BUFFER_SIZE);
-			if (lr == BUFFER_SIZE && (total + BUFFER_SIZE < eexecSize)) {
-				eexecPart.write(buffer, 0, BUFFER_SIZE);
-				total += BUFFER_SIZE;
-			} else if (lr > 0 && (total + lr < eexecSize)) {
-				eexecPart.write(buffer, 0, lr);
-				total += lr;
-			} else if (lr > 0 && (total + lr >= eexecSize)) {
-				eexecPart.write(buffer, 0, eexecSize - total);
-				total += (eexecSize - total);
-			}
-		} while (eexecSize > total && lr > 0);
-		IOUtils.closeQuietly(eexecPart);
-		return eexecPart.toByteArray();
-	}
-
-	private byte[] decodeEexec(byte[] eexec) {
-		return Type1FontUtil.eexecDecrypt(eexec);
-	}
-
-	private byte[] readLine(PeekInputStream stream) throws IOException {
-		ArrayList<Byte> bytes = new ArrayList<Byte>();
-		int currentCharacter = 0;
-
-		do {
-			currentCharacter = readNextCharacter(stream);
-			bytes.add((byte)(currentCharacter & 0xFF));
-		} while ( !('\n' == currentCharacter || '\r' == currentCharacter)) ;
-
-		if ('\r' == currentCharacter && '\n' == stream.peek()) {
-			currentCharacter = readNextCharacter(stream);
-			bytes.add((byte)(currentCharacter & 0xFF));
-		}
-
-		byte[] result = new byte[bytes.size()];
-		for (int i = 0 ; i < bytes.size(); ++i) {
-			result[i] = bytes.get(i);
-		}
-		return result;
-	}
-
-	private byte[] readToken(PeekInputStream stream) throws IOException {
-		byte[] token = new byte[0];
-		skipBlankSeparators(stream);
-
-		int nextByte = stream.peek();
-		if (nextByte < 0) {
-			throw new IOException("Unexpected End Of File");
-		} 
-
-		if (nextByte == '(') {
-			token = readStringLiteral(stream);
-		} else if (nextByte == '[') {
-			token = readArray(stream);
-		} else if (nextByte == '{') {
-			token = readProcedure(stream);
-		} else {
-			token = readNameOrArgument(stream); 
-		}
-
-		return token;
-	}
-	
-	private byte[] readStringLiteral(PeekInputStream stream) throws IOException {
-		int opened = 0;
-		List<Integer> buffer = new ArrayList<Integer>();
-		
-		int currentByte = 0;
-		do {
-			currentByte = readNextCharacter(stream);
-			if (currentByte < 0) {
-				throw new IOException("Unexpected End Of File");
-			}
-
-			if (currentByte == '(') {
-				opened++;
-			} else if (currentByte == ')') {
-				opened--;
-			}
-
-			buffer.add(currentByte);
-		} while (opened != 0);
-
-		return convertListOfIntToByteArray(buffer);
-	}
-
-	private byte[] readArray(PeekInputStream stream) throws IOException {
-		int opened = 0;
-		List<Integer> buffer = new ArrayList<Integer>();
-		
-		int currentByte = 0;
-		do {
-			currentByte = readNextCharacter(stream);
-			if (currentByte < 0) {
-				throw new IOException("Unexpected End Of File");
-			}
-
-			if (currentByte == '[') {
-				opened++;
-			} else if (currentByte == ']') {
-				opened--;
-			}
-
-			buffer.add(currentByte);
-		} while (opened != 0);
-
-		return convertListOfIntToByteArray(buffer);
-	}
-
-	private byte[] readProcedure(PeekInputStream stream) throws IOException {
-		int opened = 0;
-		List<Integer> buffer = new ArrayList<Integer>();
-		
-		int currentByte = 0;
-		do {
-			currentByte = readNextCharacter(stream);
-			if (currentByte < 0) {
-				throw new IOException("Unexpected End Of File");
-			}
-
-			if (currentByte == '{') {
-				opened++;
-			} else if (currentByte == '}') {
-				opened--;
-			}
-
-			buffer.add(currentByte);
-		} while (opened != 0);
-
-		return convertListOfIntToByteArray(buffer);
-	}
-	
-	private byte[] readNameOrArgument(PeekInputStream stream) throws IOException {
-		List<Integer> buffer = new ArrayList<Integer>();
-		int nextByte = 0;
-		do {
-			int currentByte = readNextCharacter(stream);
-			if (currentByte < 0) {
-				throw new IOException("Unexpected End Of File");
-			}
-			buffer.add(currentByte);
-			nextByte = stream.peek();
-		} while (isNotBlankSperator(nextByte) && isNotBeginOfName(nextByte) && isNotSeparator(nextByte));
-
-		return convertListOfIntToByteArray(buffer);
-	}
-	
-	private boolean isNotBeginOfName(int character) {
-		return ('/' != character);
-	}
-	
-	private boolean isNotSeparator(int character) {
-		return !('{' == character || '}' == character || '[' == character || ']' == character);
-	}
-	
-	private byte[] convertListOfIntToByteArray(List<Integer> input) {
-		byte[] res = new byte[input.size()];
-		for (int i = 0; i < res.length; ++i) {
-			res[i] = input.get(i).byteValue();
-		}
-		return res;
-	}
-
-	private int readNextCharacter(PeekInputStream stream) throws IOException {
-		int currentByte = stream.read();
-		this.numberOfReadBytes++;
-		return currentByte;
-	}
-
-	private void skipBlankSeparators(PeekInputStream stream) throws IOException {
-		int nextByte = stream.peek();
-		while (isBlankSperator(nextByte)) {
-			readNextCharacter(stream);
-			nextByte = stream.peek();
-		}
-	}
-
-	private void skipSingleBlankSeparator(PeekInputStream stream) throws IOException {
-		int nextByte = stream.peek();
-		if(isBlankSperator(nextByte)) {
-			readNextCharacter(stream);
-		}
-	}
-	private boolean isBlankSperator(int character) {
-		return (character == ' ' || character == '\n' || character == '\r');
-	}
-
-	private boolean isNotBlankSperator(int character) {
-		return !isBlankSperator(character);
-	}
-	
-	private boolean isEExecKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "eexec".equals(word);
-	}
-
-	private boolean isDefKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "def".equals(word);
-	}
-	
-	private boolean isReadOnlyKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "readonly".equals(word);
-	}
-	
-	private boolean isEncodingKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "/Encoding".equals(word);
-	}
-
-	private boolean isDupKeyWord(byte[] token) throws IOException {
-		String word = new String(token, TOKEN_ENCODING);
-		return "dup".equals(word);
-	}
-
-	private boolean isStartOfEExecReached() {
-		return (this.numberOfReadBytes == this.clearTextSize);
-	}
-	
-	private boolean isEndOfStream(PeekInputStream stream) {
-		try {
-			skipBlankSeparators(stream);
-			return false;
-		} catch (IOException e) {
-			return true;
-		}
-	}
-}
\ No newline at end of file
+    public static final Logger LOGGER = Logger.getLogger(Type1Parser.class);
+
+    protected static final char NAME_START = '/';
+    protected static final String NOTDEF = NAME_START + ".notdef";
+    protected static final int DEFAULT_LEN_IV = 4;
+
+    private static final String PS_STANDARD_ENCODING = "StandardEncoding";
+    private static final String PS_ISOLATIN_ENCODING = "ISOLatin1Encoding";
+
+    private static final String TOKEN_ENCODING = "US-ASCII";
+
+    /**
+     * The PostScript font stream.
+     */
+    private PeekInputStream fontProgram = null;
+    /**
+     * The length in bytes of the clear-text portion of the Type1 font program.
+     */
+    private int clearTextSize = 0;
+    /**
+     * The length in bytes of the eexec encrypted portion of the type1 font program.
+     */
+    private int eexecSize = 0;
+
+    /**
+     * This counter is used to know how many byte have been read. It is used to read the clear part of the font. this
+     * computer is updated during the parsing of the encoding part too but it is not used.
+     */
+    private int numberOfReadBytes = 0;
+
+    /**
+     * Object which contains information coming from the parsing.
+     */
+    private Type1 type1Font = null;
+
+    private Type1Parser(InputStream type1, int length1, int length2, Encoding enc) throws IOException
+    {
+        super();
+        this.fontProgram = new PeekInputStream(type1);
+        this.clearTextSize = length1;
+        this.eexecSize = length2;
+        // ---- Instantiate the Encoding Map
+        if (enc != null)
+        {
+            this.type1Font = new Type1(enc);
+        }
+        else
+        {
+            this.type1Font = new Type1(new StandardEncoding());
+        }
+        this.type1Font.addCidWithLabel(-1, NOTDEF);
+    }
+
+    /**
+     * 
+     * @param fontProgram
+     *            the stream of the font program extracted from the PDF file.
+     * @param clearTextLength
+     *            the length in bytes of the clear part of the font program.
+     * @param eexecLength
+     *            the length in bytes of the encoded part.
+     * @return
+     * @throws IOException
+     */
+    public static Type1Parser createParser(InputStream fontProgram, int clearTextLength, int eexecLength)
+            throws IOException
+    {
+
+        Encoding encoding = getEncodingObject("");
+        return createParserWithEncodingObject(fontProgram, clearTextLength, eexecLength, encoding);
+    }
+
+    /**
+     * 
+     * @param fontProgram
+     *            the stream of the font program extracted from the PDF file.
+     * @param clearTextLength
+     *            the length in bytes of the clear part of the font program.
+     * @param eexecLength
+     *            the length in bytes of the encoded part.
+     * @param encodingName
+     *            The name of encoding which is used by this font program.
+     * @return
+     * @throws IOException
+     */
+    public static Type1Parser createParserWithEncodingName(InputStream fontProgram, int clearTextLength,
+            int eexecLength, String encodingName) throws IOException
+    {
+
+        Encoding encoding = getEncodingObject(encodingName);
+        return createParserWithEncodingObject(fontProgram, clearTextLength, eexecLength, encoding);
+    }
+
+    private static Encoding getEncodingObject(String encodingName)
+    {
+        Encoding encoding = new StandardEncoding();
+        if (FONT_DICTIONARY_VALUE_ENCODING_MAC.equals(encodingName))
+        {
+            encoding = new MacRomanEncoding();
+        }
+        else if (FONT_DICTIONARY_VALUE_ENCODING_MAC_EXP.equals(encodingName))
+        {
+            encoding = new MacRomanEncoding();
+        }
+        else if (FONT_DICTIONARY_VALUE_ENCODING_WIN.equals(encodingName))
+        {
+            encoding = new WinAnsiEncoding();
+        }
+        else if (FONT_DICTIONARY_VALUE_ENCODING_PDFDOC.equals(encodingName))
+        {
+            encoding = new PdfDocEncoding();
+        }
+        return encoding;
+    }
+
+    /**
+     * 
+     * @param fontProgram
+     *            the stream of the font program extracted from the PDF file.
+     * @param clearTextLength
+     *            the length in bytes of the clear part of the font program.
+     * @param eexecLength
+     *            the length in bytes of the encoded part.
+     * @param encodingName
+     *            The encoding object which is used by this font program.
+     * @return
+     * @throws IOException
+     */
+    public static Type1Parser createParserWithEncodingObject(InputStream fontProgram, int clearTextLength,
+            int eexecLength, Encoding encoding) throws IOException
+    {
+
+        return new Type1Parser(fontProgram, clearTextLength, eexecLength, encoding);
+    }
+
+    public Type1 parse() throws IOException
+    {
+        parseClearPartOfFontProgram(this.fontProgram);
+        decodeAndParseEExecPart(this.fontProgram);
+        return this.type1Font;
+    }
+
+    private void parseClearPartOfFontProgram(PeekInputStream stream) throws IOException
+    {
+        skipComments(stream);
+        parseFontInformationUntilEncodingPart(stream);
+    }
+
+    private void decodeAndParseEExecPart(PeekInputStream stream) throws IOException
+    {
+        byte[] eexecPart = readEexec(stream);
+        byte[] decodedEExecPart = decodeEexec(eexecPart);
+        PeekInputStream eexecStream = new PeekInputStream(new ByteArrayInputStream(decodedEExecPart));
+        parseEExecPart(eexecStream);
+    }
+
+    private void skipComments(PeekInputStream stream) throws IOException
+    {
+        int nextChar = stream.peek();
+        while (nextChar == '%')
+        {
+            if (nextChar == -1)
+            {
+                throw new IOException("Unexpected End Of File during a comment parsing");
+            }
+            readLine(stream);
+            nextChar = stream.peek();
+        }
+    }
+
+    private void parseFontInformationUntilEncodingPart(PeekInputStream stream) throws IOException
+    {
+        byte[] token = readToken(stream);
+        while (!isEExecKeyWord(token))
+        {
+            // add here specific operation to memorize useful information
+            if (isEncodingKeyWord(token))
+            {
+                parseEncodingDefinition(stream);
+            }
+            token = readToken(stream);
+        }
+
+        while (!isStartOfEExecReached())
+        {
+            readNextCharacter(stream);
+        }
+    }
+
+    private void parseEncodingDefinition(PeekInputStream stream) throws IOException
+    {
+        byte[] token = readToken(stream);
+        String readableToken = new String(token, TOKEN_ENCODING);
+        if (PS_ISOLATIN_ENCODING.equals(readableToken))
+        {
+            this.type1Font.initEncodingWithISOLatin1Encoding();
+        }
+        else if (PS_STANDARD_ENCODING.equals(readableToken))
+        {
+            this.type1Font.initEncodingWithStandardEncoding();
+        }
+        else
+        {
+            try
+            {
+                Integer.parseInt(readableToken);
+                throwExceptionIfUnexpectedToken("array", readToken(stream));
+                readEndSetEncodingValues(stream);
+            }
+            catch (NumberFormatException e)
+            {
+                throw new IOException("Invalid encoding : Expected int value before \"array\" "
+                        + "key word if the Encoding isn't Standard or ISOLatin");
+            }
+        }
+    }
+
+    private void parseEExecPart(PeekInputStream stream) throws IOException
+    {
+        int lenIV = DEFAULT_LEN_IV;
+        byte[] previousToken = new byte[0];
+        while (!isEndOfStream(stream))
+        {
+            byte[] token = readToken(stream);
+            if (isLenIVKeyWord(token))
+            {
+                // lenIV belong to Private Dictionary.
+                // If you create a method to parse PrivateDict, please update this function
+                byte[] l = readToken(stream);
+                lenIV = Integer.parseInt(new String(l, TOKEN_ENCODING));
+            }
+            else if (isBeginOfBinaryPart(token))
+            {
+                try
+                {
+                    int lengthOfBinaryPart = Integer.parseInt(new String(previousToken, TOKEN_ENCODING));
+                    skipSingleBlankSeparator(stream);
+                    stream.read(new byte[lengthOfBinaryPart], 0, lengthOfBinaryPart);
+                    token = readToken(stream); // read the end of binary part
+                }
+                catch (NumberFormatException e)
+                {
+                    throw new IOException("Binary part found but previous token wasn't an integer");
+                }
+            }
+            else if (isCharStringKeyWord(token))
+            {
+                parseCharStringArray(stream, lenIV);
+            }
+            previousToken = token;
+        }
+    }
+
+    private void parseCharStringArray(PeekInputStream stream, int lenIV) throws IOException
+    {
+        int numberOfElements = readNumberOfCharStrings(stream);
+        goToBeginOfCharStringElements(stream);
+
+        while (numberOfElements > 0)
+        {
+            byte[] labelToken = readToken(stream);
+            String label = new String(labelToken, TOKEN_ENCODING);
+
+            if (label.equals("end"))
+            {
+                // TODO thrown exception ? add an error/warning in the PreflightContext ??
+                LOGGER.warn("[Type 1] Invalid number of elements in the CharString");
+                break;
+            }
+
+            byte[] sizeOfCharStringToken = readToken(stream);
+            int sizeOfCharString = Integer.parseInt(new String(sizeOfCharStringToken, TOKEN_ENCODING));
+
+            readToken(stream); // skip "RD" or "-|" token
+            skipSingleBlankSeparator(stream); // "RD" or "-|" are followed by a space
+
+            byte[] descBinary = new byte[sizeOfCharString];
+            stream.read(descBinary, 0, sizeOfCharString);
+            byte[] description = Type1FontUtil.charstringDecrypt(descBinary, lenIV);
+            Type1CharStringParser t1p = new Type1CharStringParser();
+            // TODO provide the local subroutine indexes
+            List<Object> operations = t1p.parse(description, new IndexData(0));
+            type1Font.addGlyphDescription(label, new GlyphDescription(operations));
+
+            readToken(stream); // skip "ND" or "|-" token
+            --numberOfElements;
+        }
+    }
+
+    private void goToBeginOfCharStringElements(PeekInputStream stream) throws IOException
+    {
+        byte[] token = new byte[0];
+        do
+        {
+            token = readToken(stream);
+        } while (isNotBeginKeyWord(token));
+    }
+
+    private boolean isNotBeginKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return !"begin".equals(word);
+    }
+
+    private boolean isBeginOfBinaryPart(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return ("RD".equals(word) || "-|".equals(word));
+    }
+
+    private boolean isLenIVKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "/lenIV".equals(word);
+    }
+
+    private boolean isCharStringKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "/CharStrings".equals(word);
+    }
+
+    private int readNumberOfCharStrings(PeekInputStream stream) throws IOException
+    {
+        byte[] token = readToken(stream);
+        String word = new String(token, TOKEN_ENCODING);
+        try
+        {
+            return Integer.parseInt(word);
+        }
+        catch (NumberFormatException e)
+        {
+            throw new IOException("Number of CharStrings elements is expected.");
+        }
+    }
+
+    private void throwExceptionIfUnexpectedToken(String expectedValue, byte[] token) throws IOException
+    {
+        String valueToCheck = new String(token, TOKEN_ENCODING);
+        if (!expectedValue.equals(valueToCheck))
+        {
+            throw new IOException(expectedValue + " was expected but we received " + valueToCheck);
+        }
+    }
+
+    private void readEndSetEncodingValues(PeekInputStream stream) throws IOException
+    {
+        byte[] token = readToken(stream);
+        boolean lastTokenWasReadOnly = false;
+        while (!(lastTokenWasReadOnly && isDefKeyWord(token)))
+        {
+            if (isDupKeyWord(token))
+            {
+                byte[] cidToken = readToken(stream);
+                byte[] labelToken = readToken(stream);
+                String cid = new String(cidToken, TOKEN_ENCODING);
+                String label = new String(labelToken, TOKEN_ENCODING);
+                try
+                {
+                    this.type1Font.addCidWithLabel(Integer.parseInt(cid), label);
+                }
+                catch (NumberFormatException e)
+                {
+                    throw new IOException("Invalid encoding : Expected CID value before \"" + label + "\" label");
+                }
+            }
+            else
+            {
+                lastTokenWasReadOnly = isReadOnlyKeyWord(token);
+            }
+            token = readToken(stream);
+        }
+    }
+
+    private byte[] readEexec(PeekInputStream stream) throws IOException
+    {
+        int BUFFER_SIZE = 1024;
+        byte[] buffer = new byte[BUFFER_SIZE];
+        ByteArrayOutputStream eexecPart = new ByteArrayOutputStream();
+        int lr = 0;
+        int total = 0;
+        do
+        {
+            lr = stream.read(buffer, 0, BUFFER_SIZE);
+            if (lr == BUFFER_SIZE && (total + BUFFER_SIZE < eexecSize))
+            {
+                eexecPart.write(buffer, 0, BUFFER_SIZE);
+                total += BUFFER_SIZE;
+            }
+            else if (lr > 0 && (total + lr < eexecSize))
+            {
+                eexecPart.write(buffer, 0, lr);
+                total += lr;
+            }
+            else if (lr > 0 && (total + lr >= eexecSize))
+            {
+                eexecPart.write(buffer, 0, eexecSize - total);
+                total += (eexecSize - total);
+            }
+        } while (eexecSize > total && lr > 0);
+        IOUtils.closeQuietly(eexecPart);
+        return eexecPart.toByteArray();
+    }
+
+    private byte[] decodeEexec(byte[] eexec)
+    {
+        return Type1FontUtil.eexecDecrypt(eexec);
+    }
+
+    private byte[] readLine(PeekInputStream stream) throws IOException
+    {
+        ArrayList<Byte> bytes = new ArrayList<Byte>();
+        int currentCharacter = 0;
+
+        do
+        {
+            currentCharacter = readNextCharacter(stream);
+            bytes.add((byte) (currentCharacter & 0xFF));
+        } while (!('\n' == currentCharacter || '\r' == currentCharacter));
+
+        if ('\r' == currentCharacter && '\n' == stream.peek())
+        {
+            currentCharacter = readNextCharacter(stream);
+            bytes.add((byte) (currentCharacter & 0xFF));
+        }
+
+        byte[] result = new byte[bytes.size()];
+        for (int i = 0; i < bytes.size(); ++i)
+        {
+            result[i] = bytes.get(i);
+        }
+        return result;
+    }
+
+    private byte[] readToken(PeekInputStream stream) throws IOException
+    {
+        byte[] token = new byte[0];
+        skipBlankSeparators(stream);
+
+        int nextByte = stream.peek();
+        if (nextByte < 0)
+        {
+            throw new IOException("Unexpected End Of File");
+        }
+
+        if (nextByte == '(')
+        {
+            token = readStringLiteral(stream);
+        }
+        else if (nextByte == '[')
+        {
+            token = readArray(stream);
+        }
+        else if (nextByte == '{')
+        {
+            token = readProcedure(stream);
+        }
+        else
+        {
+            token = readNameOrArgument(stream);
+        }
+
+        return token;
+    }
+
+    private byte[] readStringLiteral(PeekInputStream stream) throws IOException
+    {
+        int opened = 0;
+        List<Integer> buffer = new ArrayList<Integer>();
+
+        int currentByte = 0;
+        do
+        {
+            currentByte = readNextCharacter(stream);
+            if (currentByte < 0)
+            {
+                throw new IOException("Unexpected End Of File");
+            }
+
+            if (currentByte == '(')
+            {
+                opened++;
+            }
+            else if (currentByte == ')')
+            {
+                opened--;
+            }
+
+            buffer.add(currentByte);
+        } while (opened != 0);
+
+        return convertListOfIntToByteArray(buffer);
+    }
+
+    private byte[] readArray(PeekInputStream stream) throws IOException
+    {
+        int opened = 0;
+        List<Integer> buffer = new ArrayList<Integer>();
+
+        int currentByte = 0;
+        do
+        {
+            currentByte = readNextCharacter(stream);
+            if (currentByte < 0)
+            {
+                throw new IOException("Unexpected End Of File");
+            }
+
+            if (currentByte == '[')
+            {
+                opened++;
+            }
+            else if (currentByte == ']')
+            {
+                opened--;
+            }
+
+            buffer.add(currentByte);
+        } while (opened != 0);
+
+        return convertListOfIntToByteArray(buffer);
+    }
+
+    private byte[] readProcedure(PeekInputStream stream) throws IOException
+    {
+        int opened = 0;
+        List<Integer> buffer = new ArrayList<Integer>();
+
+        int currentByte = 0;
+        do
+        {
+            currentByte = readNextCharacter(stream);
+            if (currentByte < 0)
+            {
+                throw new IOException("Unexpected End Of File");
+            }
+
+            if (currentByte == '{')
+            {
+                opened++;
+            }
+            else if (currentByte == '}')
+            {
+                opened--;
+            }
+
+            buffer.add(currentByte);
+        } while (opened != 0);
+
+        return convertListOfIntToByteArray(buffer);
+    }
+
+    private byte[] readNameOrArgument(PeekInputStream stream) throws IOException
+    {
+        List<Integer> buffer = new ArrayList<Integer>();
+        int nextByte = 0;
+        do
+        {
+            int currentByte = readNextCharacter(stream);
+            if (currentByte < 0)
+            {
+                throw new IOException("Unexpected End Of File");
+            }
+            buffer.add(currentByte);
+            nextByte = stream.peek();
+        } while (isNotBlankSperator(nextByte) && isNotBeginOfName(nextByte) && isNotSeparator(nextByte));
+
+        return convertListOfIntToByteArray(buffer);
+    }
+
+    private boolean isNotBeginOfName(int character)
+    {
+        return ('/' != character);
+    }
+
+    private boolean isNotSeparator(int character)
+    {
+        return !('{' == character || '}' == character || '[' == character || ']' == character);
+    }
+
+    private byte[] convertListOfIntToByteArray(List<Integer> input)
+    {
+        byte[] res = new byte[input.size()];
+        for (int i = 0; i < res.length; ++i)
+        {
+            res[i] = input.get(i).byteValue();
+        }
+        return res;
+    }
+
+    private int readNextCharacter(PeekInputStream stream) throws IOException
+    {
+        int currentByte = stream.read();
+        this.numberOfReadBytes++;
+        return currentByte;
+    }
+
+    private void skipBlankSeparators(PeekInputStream stream) throws IOException
+    {
+        int nextByte = stream.peek();
+        while (isBlankSperator(nextByte))
+        {
+            readNextCharacter(stream);
+            nextByte = stream.peek();
+        }
+    }
+
+    private void skipSingleBlankSeparator(PeekInputStream stream) throws IOException
+    {
+        int nextByte = stream.peek();
+        if (isBlankSperator(nextByte))
+        {
+            readNextCharacter(stream);
+        }
+    }
+
+    private boolean isBlankSperator(int character)
+    {
+        return (character == ' ' || character == '\n' || character == '\r');
+    }
+
+    private boolean isNotBlankSperator(int character)
+    {
+        return !isBlankSperator(character);
+    }
+
+    private boolean isEExecKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "eexec".equals(word);
+    }
+
+    private boolean isDefKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "def".equals(word);
+    }
+
+    private boolean isReadOnlyKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "readonly".equals(word);
+    }
+
+    private boolean isEncodingKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "/Encoding".equals(word);
+    }
+
+    private boolean isDupKeyWord(byte[] token) throws IOException
+    {
+        String word = new String(token, TOKEN_ENCODING);
+        return "dup".equals(word);
+    }
+
+    private boolean isStartOfEExecReached()
+    {
+        return (this.numberOfReadBytes == this.clearTextSize);
+    }
+
+    private boolean isEndOfStream(PeekInputStream stream)
+    {
+        try
+        {
+            skipBlankSeparators(stream);
+            return false;
+        }
+        catch (IOException e)
+        {
+            return true;
+        }
+    }
+}

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelper.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelper.java Wed Mar  6 16:46:35 2013
@@ -23,13 +23,13 @@ package org.apache.pdfbox.preflight.grap
 
 import org.apache.pdfbox.preflight.exception.ValidationException;
 
-
-public interface ColorSpaceHelper {
-  /**
-   * Process the ColorSpace validation.
-   * 
-   * @param result
-   */
-  public void validate() throws ValidationException;
+public interface ColorSpaceHelper
+{
+    /**
+     * Process the ColorSpace validation.
+     * 
+     * @param result
+     */
+    public void validate() throws ValidationException;
 
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelperFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelperFactory.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelperFactory.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaceHelperFactory.java Wed Mar  6 16:46:35 2013
@@ -21,49 +21,49 @@
 
 package org.apache.pdfbox.preflight.graphic;
 
-
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
 import org.apache.pdfbox.preflight.PreflightContext;
 
 /**
- * This factory create the right Helper according to the owner of the ColorSpace
- * entry.
+ * This factory create the right Helper according to the owner of the ColorSpace entry.
  */
-public class ColorSpaceHelperFactory {
+public class ColorSpaceHelperFactory
+{
 
-  /**
-   * Return an instance of ColorSpaceHelper according to the
-   * ColorSpaceRestiction value.
-   * <UL>
-   * <li>ColorSpaceRestiction.NO_PATTERN : returns NoPatternColorSpaceHelper
-   * <li>ColorSpaceRestiction.ONLY_DEVICE : returns DeviceColorSpaceHelper
-   * <li>default : returns StandardColorSpaceHelper
-   * </UL>
-   * 
-   * @param context
-   *          the PreflightContext to access useful data
-   * @param cs
-   *          the High level PDFBox object which represents the ColorSpace
-   * @param csr
-   *          the color space restriction
-   * @return
-   */
-  public ColorSpaceHelper getColorSpaceHelper(PreflightContext context, PDColorSpace cs, ColorSpaceRestriction csr) {
-    switch (csr) {
-    case NO_PATTERN:
-      return new NoPatternColorSpaceHelper(context, cs);
-    case ONLY_DEVICE:
-      return new DeviceColorSpaceHelper(context, cs);
-    default:
-      return new StandardColorSpaceHelper(context, cs);
+    /**
+     * Return an instance of ColorSpaceHelper according to the ColorSpaceRestiction value.
+     * <UL>
+     * <li>ColorSpaceRestiction.NO_PATTERN : returns NoPatternColorSpaceHelper
+     * <li>ColorSpaceRestiction.ONLY_DEVICE : returns DeviceColorSpaceHelper
+     * <li>default : returns StandardColorSpaceHelper
+     * </UL>
+     * 
+     * @param context
+     *            the PreflightContext to access useful data
+     * @param cs
+     *            the High level PDFBox object which represents the ColorSpace
+     * @param csr
+     *            the color space restriction
+     * @return
+     */
+    public ColorSpaceHelper getColorSpaceHelper(PreflightContext context, PDColorSpace cs, ColorSpaceRestriction csr)
+    {
+        switch (csr)
+        {
+        case NO_PATTERN:
+            return new NoPatternColorSpaceHelper(context, cs);
+        case ONLY_DEVICE:
+            return new DeviceColorSpaceHelper(context, cs);
+        default:
+            return new StandardColorSpaceHelper(context, cs);
+        }
     }
-  }
 
-  /**
-   * Enum used as argument of methods of this factory to return the right
-   * Helper.
-   */
-  public enum ColorSpaceRestriction {
-    NO_RESTRICTION, NO_PATTERN, ONLY_DEVICE;
-  }
+    /**
+     * Enum used as argument of methods of this factory to return the right Helper.
+     */
+    public enum ColorSpaceRestriction
+    {
+        NO_RESTRICTION, NO_PATTERN, ONLY_DEVICE;
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaces.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaces.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaces.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/ColorSpaces.java Wed Mar  6 16:46:35 2013
@@ -22,41 +22,42 @@
 package org.apache.pdfbox.preflight.graphic;
 
 /**
- * This enum makes ColorSpaces validation easier. Labels represent ColorSpace
- * names as defined in the "PDF Reference 1.4". Enum entries with the "_SHORT"
- * suffix are used to represent color spaces (DeviceGray, DeviceRGB, DeviceCMYK
- * and Indexed) using the InlinedImage notation.
+ * This enum makes ColorSpaces validation easier. Labels represent ColorSpace names as defined in the
+ * "PDF Reference 1.4". Enum entries with the "_SHORT" suffix are used to represent color spaces (DeviceGray, DeviceRGB,
+ * DeviceCMYK and Indexed) using the InlinedImage notation.
  */
-public enum ColorSpaces {
+public enum ColorSpaces
+{
 
-  Lab("Lab"), CalRGB("CalRGB"), CalGray("CalGray"), DeviceN("DeviceN"), Indexed(
-      "Indexed"), Indexed_SHORT("I"), Pattern("Pattern"), ICCBased("ICCBased"), DeviceRGB(
-      "DeviceRGB"), DeviceRGB_SHORT("RGB"), DeviceGray("DeviceGray"), DeviceGray_SHORT(
-      "G"), DeviceCMYK("DeviceCMYK"), DeviceCMYK_SHORT("CMYK"), Separation(
-      "Separation");
-
-  /**
-   * Name of the ColorSpace
-   */
-  public String label;
-
-  private ColorSpaces(String _label) {
-    label = _label;
-  }
-
-  /**
-   * @return the label
-   */
-  public String getLabel() {
-    return label;
-  }
-
-  /**
-   * @param label
-   *          the label to set
-   */
-  public void setLabel(String label) {
-    this.label = label;
-  }
+    Lab("Lab"), CalRGB("CalRGB"), CalGray("CalGray"), DeviceN("DeviceN"), Indexed("Indexed"), Indexed_SHORT("I"), Pattern(
+            "Pattern"), ICCBased("ICCBased"), DeviceRGB("DeviceRGB"), DeviceRGB_SHORT("RGB"), DeviceGray("DeviceGray"), DeviceGray_SHORT(
+            "G"), DeviceCMYK("DeviceCMYK"), DeviceCMYK_SHORT("CMYK"), Separation("Separation");
+
+    /**
+     * Name of the ColorSpace
+     */
+    public String label;
+
+    private ColorSpaces(String _label)
+    {
+        label = _label;
+    }
+
+    /**
+     * @return the label
+     */
+    public String getLabel()
+    {
+        return label;
+    }
+
+    /**
+     * @param label
+     *            the label to set
+     */
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
 
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/DeviceColorSpaceHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/DeviceColorSpaceHelper.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/DeviceColorSpaceHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/graphic/DeviceColorSpaceHelper.java Wed Mar  6 16:46:35 2013
@@ -32,54 +32,66 @@ import org.apache.pdfbox.preflight.Prefl
 import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
 
 /**
- * This class defines restrictions on Color Spaces. It checks the consistency of
- * the Color space with the DestOutputIntent, if the color space isn't a Device
- * Color space or a Indexed color space using Device the validation will fail.
+ * This class defines restrictions on Color Spaces. It checks the consistency of the Color space with the
+ * DestOutputIntent, if the color space isn't a Device Color space or a Indexed color space using Device the validation
+ * will fail.
  */
-public class DeviceColorSpaceHelper extends StandardColorSpaceHelper {
+public class DeviceColorSpaceHelper extends StandardColorSpaceHelper
+{
 
-	public DeviceColorSpaceHelper(PreflightContext _context, PDColorSpace _cs) {
-		super(_context, _cs);
-	}
+    public DeviceColorSpaceHelper(PreflightContext _context, PDColorSpace _cs)
+    {
+        super(_context, _cs);
+    }
 
-	/**
-	 * This method updates the given list with a ValidationError
-	 * (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN) and returns false.
-	 */
-	protected void processPatternColorSpace(PDColorSpace pdcs) {
-		context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN, "Pattern ColorSpace is forbidden"));
-	}
+    /**
+     * This method updates the given list with a ValidationError (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN)
+     * and returns false.
+     */
+    protected void processPatternColorSpace(PDColorSpace pdcs)
+    {
+        context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN,
+                "Pattern ColorSpace is forbidden"));
+    }
 
-	/**
-	 * This method updates the given list with a ValidationError
-	 * (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN) and returns false.
-	 */
-	protected void processDeviceNColorSpace(PDColorSpace pdcs) {
-		context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN, "DeviceN ColorSpace is forbidden"));
-	}
+    /**
+     * This method updates the given list with a ValidationError (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN)
+     * and returns false.
+     */
+    protected void processDeviceNColorSpace(PDColorSpace pdcs)
+    {
+        context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN,
+                "DeviceN ColorSpace is forbidden"));
+    }
 
-	/**
-	 * Indexed color space is authorized only if the BaseColorSpace is a DeviceXXX
-	 * color space. In all other cases the given list is updated with a
-	 * ValidationError (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN) and
-	 * returns false.
-	 */
-	protected void processIndexedColorSpace(PDColorSpace pdcs) {
-		PDIndexed indexed = (PDIndexed) pdcs;
-		try {
-			PDColorSpace based = indexed.getBaseColorSpace();
-			ColorSpaces colorSpace = ColorSpaces.valueOf(based.getName());
-			switch (colorSpace) {      
-			case Indexed:
-			case Indexed_SHORT:
-			case Pattern:
-				context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN, colorSpace.getLabel() + " ColorSpace is forbidden"));
-				break;
-			default:
-				processAllColorSpace(based);
-			}
-		} catch (IOException e) {
-			context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE, "Unable to read Indexed Color Space : " + e.getMessage()));
-		}
-	}
+    /**
+     * Indexed color space is authorized only if the BaseColorSpace is a DeviceXXX color space. In all other cases the
+     * given list is updated with a ValidationError (ERROR_GRAPHIC_INVALID_PATTERN_COLOR_SPACE_FORBIDDEN) and returns
+     * false.
+     */
+    protected void processIndexedColorSpace(PDColorSpace pdcs)
+    {
+        PDIndexed indexed = (PDIndexed) pdcs;
+        try
+        {
+            PDColorSpace based = indexed.getBaseColorSpace();
+            ColorSpaces colorSpace = ColorSpaces.valueOf(based.getName());
+            switch (colorSpace)
+            {
+            case Indexed:
+            case Indexed_SHORT:
+            case Pattern:
+                context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE_FORBIDDEN, colorSpace
+                        .getLabel() + " ColorSpace is forbidden"));
+                break;
+            default:
+                processAllColorSpace(based);
+            }
+        }
+        catch (IOException e)
+        {
+            context.addValidationError(new ValidationError(ERROR_GRAPHIC_INVALID_COLOR_SPACE,
+                    "Unable to read Indexed Color Space : " + e.getMessage()));
+        }
+    }
 }