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 [8/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/descriptor/FontDescriptorHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java Wed Mar  6 16:46:35 2013
@@ -61,150 +61,199 @@ import org.apache.xmpbox.xml.DomXmpParse
 import org.apache.xmpbox.xml.XmpParsingException;
 import org.apache.xmpbox.xml.XmpParsingException.ErrorType;
 
-public abstract class FontDescriptorHelper <T extends FontContainer> {
+public abstract class FontDescriptorHelper<T extends FontContainer>
+{
 
-	protected T fContainer;
+    protected T fContainer;
 
-	protected PreflightContext context;
-	protected PDFont font;
+    protected PreflightContext context;
+    protected PDFont font;
 
-	protected PDFontDescriptorDictionary fontDescriptor;
-
-	public FontDescriptorHelper(PreflightContext context, PDFont font, T fontContainer) {
-		super();
-		this.fContainer = fontContainer;
-		this.context = context;
-		this.font = font;
-	}
-
-	public void validate() {
-		PDFontDescriptor fd = this.font.getFontDescriptor();
-		// Only a PDFontDescriptorDictionary provides a way to embedded the font program.
-		if(fd != null && fd instanceof PDFontDescriptorDictionary) {
-			fontDescriptor = (PDFontDescriptorDictionary)fd;
-
-			if (checkMandatoryFields(fontDescriptor.getCOSDictionary())) {
-				if (hasOnlyOneFontFile(fontDescriptor)) {
-					PDStream fontFile = extractFontFile(fontDescriptor);
-					if (fontFile != null) {
-						processFontFile(fontDescriptor, fontFile);
-						checkFontFileMetaData(fontDescriptor, fontFile);
-					}
-				} else {
-					if (fontFileNotEmbedded(fontDescriptor)) {
-						this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "FontFile entry is missing from FontDescriptor for " + fontDescriptor.getFontName()));
-						this.fContainer.notEmbedded();
-					} else {
-						this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID,	"They are more than one FontFile for " + fontDescriptor.getFontName()));
-					}
-				}
-			}
-		} else {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_DESCRIPTOR_INVALID, "FontDescriptor is null or is a AFM Descriptor"));
-			this.fContainer.notEmbedded();
-		}
-	}
-
-	protected boolean checkMandatoryFields(COSDictionary fDescriptor) {
-		boolean areFieldsPresent = fDescriptor.containsKey(FONT_DICTIONARY_KEY_FONTNAME);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_FLAGS);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_ITALICANGLE);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_CAPHEIGHT);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_FONTBBOX);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_ASCENT);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_DESCENT);
-		areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_STEMV);
-		areFieldsPresent &= fDescriptor.containsKey(COSName.FONT_NAME);
-		if (!areFieldsPresent) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_DESCRIPTOR_INVALID, "Some mandatory fields are missing from the FontDescriptor"));
-		}
-		return areFieldsPresent;
-	}
-
-	public abstract PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor);
-
-	/**
-	 * Return true if the FontDescriptor has only one FontFile entry.
-	 * @param fontDescriptor
-	 * @return
-	 */
-	protected boolean hasOnlyOneFontFile(PDFontDescriptorDictionary fontDescriptor) {
-		PDStream ff1 = fontDescriptor.getFontFile();
-		PDStream ff2 = fontDescriptor.getFontFile2();
-		PDStream ff3 = fontDescriptor.getFontFile3();
-		return (ff1 != null ^ ff2 != null ^ ff3 != null);
-	}
-
-	protected boolean fontFileNotEmbedded(PDFontDescriptorDictionary fontDescriptor) {
-		PDStream ff1 = fontDescriptor.getFontFile();
-		PDStream ff2 = fontDescriptor.getFontFile2();
-		PDStream ff3 = fontDescriptor.getFontFile3();
-		return (ff1 == null && ff2 == null && ff3 == null);
-	}
-
-	protected abstract void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile);
-
-	/**
-	 * Type0, Type1 and TrueType FontValidator call this method to check the FontFile meta data.
-	 * 
-	 * @param fontDescriptor The FontDescriptor which contains the FontFile stream
-	 * @param fontFile The font file stream to check
-	 */
-	protected void checkFontFileMetaData(PDFontDescriptor fontDescriptor, PDStream fontFile)  {
-		PDMetadata metadata = null;
-		try {
-			metadata = fontFile.getMetadata();
-
-			if (metadata != null) {
-				// Filters are forbidden in a XMP stream
-				if (metadata.getFilters() != null && !metadata.getFilters().isEmpty()) {
-					this.fContainer.push(new ValidationError(ERROR_SYNTAX_STREAM_INVALID_FILTER,	"Filter specified in font file metadata dictionnary"));
-					return;
-				}
-
-				byte[] mdAsBytes = getMetaDataStreamAsBytes(metadata);
-
-				try {
-
-					DomXmpParser xmpBuilder = new DomXmpParser();
-					XMPMetadata xmpMeta = xmpBuilder.parse(mdAsBytes);
-
-					FontMetaDataValidation fontMDval = new FontMetaDataValidation();
-					List<ValidationError> ve = new ArrayList<ValidationError>();
-					fontMDval.analyseFontName(xmpMeta, fontDescriptor, ve);
-					fontMDval.analyseRights(xmpMeta, fontDescriptor, ve);
-					this.fContainer.push(ve);
-
-				} catch (XmpParsingException e) {
-					if (e.getErrorType()==ErrorType.NoValueType) {
-						this.fContainer.push(new ValidationError(ERROR_METADATA_UNKNOWN_VALUETYPE, e.getMessage()));
-					} else if (e.getErrorType()==ErrorType.XpacketBadEnd) {
-						this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_XPACKET, "Unable to parse font metadata due to : "  + e.getMessage()));
-					} else {
-						this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT, e.getMessage()));
-					}
-				}
-			}
-		} catch (IllegalStateException e) {
-			this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_UNKOWN,	"The Metadata entry doesn't reference a stream object"));
-		}
-	}
-
-	protected final byte[] getMetaDataStreamAsBytes(PDMetadata metadata) {
-		byte[] result = null;
-		ByteArrayOutputStream bos = null;
-		InputStream metaDataContent = null;
-		try {
-			bos = new ByteArrayOutputStream();
-			metaDataContent = metadata.createInputStream();
-			IOUtils.copyLarge(metaDataContent, bos);
-			result = bos.toByteArray();
-		} catch (IOException e) {
-			this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_STREAM, "Unable to read font metadata due to : " + e.getMessage()));
-		} finally {
-			IOUtils.closeQuietly(metaDataContent);
-			IOUtils.closeQuietly(bos);
-		}
-		return result;
-	}
+    protected PDFontDescriptorDictionary fontDescriptor;
+
+    public FontDescriptorHelper(PreflightContext context, PDFont font, T fontContainer)
+    {
+        super();
+        this.fContainer = fontContainer;
+        this.context = context;
+        this.font = font;
+    }
+
+    public void validate()
+    {
+        PDFontDescriptor fd = this.font.getFontDescriptor();
+        // Only a PDFontDescriptorDictionary provides a way to embedded the font program.
+        if (fd != null && fd instanceof PDFontDescriptorDictionary)
+        {
+            fontDescriptor = (PDFontDescriptorDictionary) fd;
+
+            if (checkMandatoryFields(fontDescriptor.getCOSDictionary()))
+            {
+                if (hasOnlyOneFontFile(fontDescriptor))
+                {
+                    PDStream fontFile = extractFontFile(fontDescriptor);
+                    if (fontFile != null)
+                    {
+                        processFontFile(fontDescriptor, fontFile);
+                        checkFontFileMetaData(fontDescriptor, fontFile);
+                    }
+                }
+                else
+                {
+                    if (fontFileNotEmbedded(fontDescriptor))
+                    {
+                        this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID,
+                                "FontFile entry is missing from FontDescriptor for " + fontDescriptor.getFontName()));
+                        this.fContainer.notEmbedded();
+                    }
+                    else
+                    {
+                        this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID,
+                                "They are more than one FontFile for " + fontDescriptor.getFontName()));
+                    }
+                }
+            }
+        }
+        else
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_DESCRIPTOR_INVALID,
+                    "FontDescriptor is null or is a AFM Descriptor"));
+            this.fContainer.notEmbedded();
+        }
+    }
+
+    protected boolean checkMandatoryFields(COSDictionary fDescriptor)
+    {
+        boolean areFieldsPresent = fDescriptor.containsKey(FONT_DICTIONARY_KEY_FONTNAME);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_FLAGS);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_ITALICANGLE);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_CAPHEIGHT);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_FONTBBOX);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_ASCENT);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_DESCENT);
+        areFieldsPresent &= fDescriptor.containsKey(FONT_DICTIONARY_KEY_STEMV);
+        areFieldsPresent &= fDescriptor.containsKey(COSName.FONT_NAME);
+        if (!areFieldsPresent)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_DESCRIPTOR_INVALID,
+                    "Some mandatory fields are missing from the FontDescriptor"));
+        }
+        return areFieldsPresent;
+    }
+
+    public abstract PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor);
+
+    /**
+     * Return true if the FontDescriptor has only one FontFile entry.
+     * 
+     * @param fontDescriptor
+     * @return
+     */
+    protected boolean hasOnlyOneFontFile(PDFontDescriptorDictionary fontDescriptor)
+    {
+        PDStream ff1 = fontDescriptor.getFontFile();
+        PDStream ff2 = fontDescriptor.getFontFile2();
+        PDStream ff3 = fontDescriptor.getFontFile3();
+        return (ff1 != null ^ ff2 != null ^ ff3 != null);
+    }
+
+    protected boolean fontFileNotEmbedded(PDFontDescriptorDictionary fontDescriptor)
+    {
+        PDStream ff1 = fontDescriptor.getFontFile();
+        PDStream ff2 = fontDescriptor.getFontFile2();
+        PDStream ff3 = fontDescriptor.getFontFile3();
+        return (ff1 == null && ff2 == null && ff3 == null);
+    }
+
+    protected abstract void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile);
+
+    /**
+     * Type0, Type1 and TrueType FontValidator call this method to check the FontFile meta data.
+     * 
+     * @param fontDescriptor
+     *            The FontDescriptor which contains the FontFile stream
+     * @param fontFile
+     *            The font file stream to check
+     */
+    protected void checkFontFileMetaData(PDFontDescriptor fontDescriptor, PDStream fontFile)
+    {
+        PDMetadata metadata = null;
+        try
+        {
+            metadata = fontFile.getMetadata();
+
+            if (metadata != null)
+            {
+                // Filters are forbidden in a XMP stream
+                if (metadata.getFilters() != null && !metadata.getFilters().isEmpty())
+                {
+                    this.fContainer.push(new ValidationError(ERROR_SYNTAX_STREAM_INVALID_FILTER,
+                            "Filter specified in font file metadata dictionnary"));
+                    return;
+                }
+
+                byte[] mdAsBytes = getMetaDataStreamAsBytes(metadata);
+
+                try
+                {
+
+                    DomXmpParser xmpBuilder = new DomXmpParser();
+                    XMPMetadata xmpMeta = xmpBuilder.parse(mdAsBytes);
+
+                    FontMetaDataValidation fontMDval = new FontMetaDataValidation();
+                    List<ValidationError> ve = new ArrayList<ValidationError>();
+                    fontMDval.analyseFontName(xmpMeta, fontDescriptor, ve);
+                    fontMDval.analyseRights(xmpMeta, fontDescriptor, ve);
+                    this.fContainer.push(ve);
+
+                }
+                catch (XmpParsingException e)
+                {
+                    if (e.getErrorType() == ErrorType.NoValueType)
+                    {
+                        this.fContainer.push(new ValidationError(ERROR_METADATA_UNKNOWN_VALUETYPE, e.getMessage()));
+                    }
+                    else if (e.getErrorType() == ErrorType.XpacketBadEnd)
+                    {
+                        this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_XPACKET,
+                                "Unable to parse font metadata due to : " + e.getMessage()));
+                    }
+                    else
+                    {
+                        this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT, e.getMessage()));
+                    }
+                }
+            }
+        }
+        catch (IllegalStateException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_UNKOWN,
+                    "The Metadata entry doesn't reference a stream object"));
+        }
+    }
+
+    protected final byte[] getMetaDataStreamAsBytes(PDMetadata metadata)
+    {
+        byte[] result = null;
+        ByteArrayOutputStream bos = null;
+        InputStream metaDataContent = null;
+        try
+        {
+            bos = new ByteArrayOutputStream();
+            metaDataContent = metadata.createInputStream();
+            IOUtils.copyLarge(metaDataContent, bos);
+            result = bos.toByteArray();
+        }
+        catch (IOException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_METADATA_FORMAT_STREAM,
+                    "Unable to read font metadata due to : " + e.getMessage()));
+        }
+        finally
+        {
+            IOUtils.closeQuietly(metaDataContent);
+            IOUtils.closeQuietly(bos);
+        }
+        return result;
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java Wed Mar  6 16:46:35 2013
@@ -40,52 +40,68 @@ import org.apache.pdfbox.preflight.Prefl
 import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
 import org.apache.pdfbox.preflight.font.container.TrueTypeContainer;
 
-public class TrueTypeDescriptorHelper extends FontDescriptorHelper<TrueTypeContainer> {
+public class TrueTypeDescriptorHelper extends FontDescriptorHelper<TrueTypeContainer>
+{
 
-	public TrueTypeDescriptorHelper(PreflightContext context, PDFont font, TrueTypeContainer fontContainer) {
-		super(context, font, fontContainer);
-	}
-
-	public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) {
-		PDStream fontFile = fontDescriptor.getFontFile2();
-		COSStream stream =  (fontFile == null ? null : fontFile.getStream());
-		if (stream == null) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile2 is missing for " + fontDescriptor.getFontName()));
-			this.fContainer.notEmbedded();
-			return null;
-		}
-
-		if (stream.getInt(COSName.LENGTH1) <= 0) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile entry /Length1 is invalid for " + fontDescriptor.getFontName()));
-			return null;
-		}
-
-		return fontFile;
-	}
-	
-	protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) {
-		/*
-		 * Try to load the font using the TTFParser object. If the font is
-		 * invalid, an exception will be thrown. Because of it is a Embedded Font
-		 * Program, some tables are required and other are optional see PDF
-		 * Reference (§5.8)
-		 */
-		ByteArrayInputStream bis = null;
-		try {
-
-			bis = new ByteArrayInputStream(fontFile.getByteArray());
-			TrueTypeFont ttf = new TTFParser(true).parseTTF(bis);
-
-			if (fontDescriptor.isSymbolic() && ttf.getCMAP().getCmaps().length != 1) {
-				this.fContainer.push(new ValidationError(ERROR_FONTS_ENCODING, "The Encoding should be missing for the Symbolic TTF"));
-			} else {
-				((TrueTypeContainer)this.fContainer).setTrueTypeFont(ttf);
-				// TODO check the WIdth consistency too				
-			}
-		} catch (IOException e) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_TRUETYPE_DAMAGED, "The FontFile can't be read for " + this.font.getBaseFont()));
-		} finally {
-			IOUtils.closeQuietly(bis);
-		}
-	}
+    public TrueTypeDescriptorHelper(PreflightContext context, PDFont font, TrueTypeContainer fontContainer)
+    {
+        super(context, font, fontContainer);
+    }
+
+    public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor)
+    {
+        PDStream fontFile = fontDescriptor.getFontFile2();
+        COSStream stream = (fontFile == null ? null : fontFile.getStream());
+        if (stream == null)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile2 is missing for "
+                    + fontDescriptor.getFontName()));
+            this.fContainer.notEmbedded();
+            return null;
+        }
+
+        if (stream.getInt(COSName.LENGTH1) <= 0)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID,
+                    "The FontFile entry /Length1 is invalid for " + fontDescriptor.getFontName()));
+            return null;
+        }
+
+        return fontFile;
+    }
+
+    protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile)
+    {
+        /*
+         * Try to load the font using the TTFParser object. If the font is invalid, an exception will be thrown. Because
+         * of it is a Embedded Font Program, some tables are required and other are optional see PDF Reference (§5.8)
+         */
+        ByteArrayInputStream bis = null;
+        try
+        {
+
+            bis = new ByteArrayInputStream(fontFile.getByteArray());
+            TrueTypeFont ttf = new TTFParser(true).parseTTF(bis);
+
+            if (fontDescriptor.isSymbolic() && ttf.getCMAP().getCmaps().length != 1)
+            {
+                this.fContainer.push(new ValidationError(ERROR_FONTS_ENCODING,
+                        "The Encoding should be missing for the Symbolic TTF"));
+            }
+            else
+            {
+                ((TrueTypeContainer) this.fContainer).setTrueTypeFont(ttf);
+                // TODO check the WIdth consistency too
+            }
+        }
+        catch (IOException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_TRUETYPE_DAMAGED, "The FontFile can't be read for "
+                    + this.font.getBaseFont()));
+        }
+        finally
+        {
+            IOUtils.closeQuietly(bis);
+        }
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java Wed Mar  6 16:46:35 2013
@@ -51,116 +51,148 @@ import org.apache.pdfbox.preflight.font.
 import org.apache.pdfbox.preflight.font.util.Type1;
 import org.apache.pdfbox.preflight.font.util.Type1Parser;
 
-public class Type1DescriptorHelper extends FontDescriptorHelper<Type1Container> {
-	private boolean isFontFile1 = true;
-
-	public Type1DescriptorHelper(PreflightContext context, PDFont font, Type1Container fontContainer) {
-		super(context, font, fontContainer);
-	}
-
-	protected boolean checkMandatoryFields(COSDictionary fDescriptor) {
-		boolean result = super.checkMandatoryFields(fDescriptor);
-		/*
-		 * if the this font is a Subset, the CharSet entry must be present in
-		 * the FontDescriptor
-		 */
-		if (isSubSet(fontDescriptor.getFontName())) {
-			String charsetStr = fontDescriptor.getCharSet();
-			if (charsetStr == null || "".equals(charsetStr)) {
-				this.fContainer.push(new ValidationError(ERROR_FONTS_CHARSET_MISSING_FOR_SUBSET, "The Charset entry is missing for the Type1 Subset"));
-				result = false;
-			}
-		}
-		return result;
-	}
-
-	@Override
-	public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) {
-		PDStream ff1 = fontDescriptor.getFontFile();
-		PDStream ff3 = fontDescriptor.getFontFile3();
-
-		if (ff1 != null) {
-			COSStream stream = ff1.getStream();
-			if (stream == null) {
-				this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is missing for " + fontDescriptor.getFontName()));
-				this.fContainer.notEmbedded();
-				return null;
-			}
-
-			boolean hasLength1 = stream.getInt(COSName.LENGTH1) > 0;
-			boolean hasLength2 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_LENGTH2)) > 0;
-			boolean hasLength3 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_LENGTH3)) >= 0;
-			if (!(hasLength1 && hasLength2 && hasLength3)) {
-				this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is invalid for " + fontDescriptor.getFontName()));
-				return null;
-			}
-
-			return ff1;
-		} else {
-			this.isFontFile1 = false;
-			this.fContainer.setFontFile1(isFontFile1);
-			return ff3;
-		}
-	}
-
-	@Override
-	protected void processFontFile(PDFontDescriptorDictionary fontDescriptor,	PDStream fontFile) {
-		if (isFontFile1) {
-			processFontFile1(fontDescriptor, fontFile);
-		} else {
-			processFontFile3(fontDescriptor, fontFile);
-		}
-	}
-
-	/**
-	 * Try to load the font using the java.awt.font object.
-	 * if the font is invalid, an exception will be pushed in the font container
-	 * @param fontDescriptor
-	 * @param fontFile
-	 */
-	protected void processFontFile1(PDFontDescriptorDictionary fontDescriptor,	PDStream fontFile) {
-		ByteArrayInputStream bis = null;
-		try {
-			bis = new ByteArrayInputStream(fontFile.getByteArray());
-			Font.createFont(Font.TYPE1_FONT, bis);
-			IOUtils.closeQuietly(bis);
-
-			// Parse the Type1 Font program in order to extract Glyph Width
-			COSStream streamObj = fontFile.getStream();
-			int length1 = streamObj.getInt(COSName.LENGTH1);
-			int length2 = streamObj.getInt(COSName.LENGTH2);
-			bis = new ByteArrayInputStream(fontFile.getByteArray());
-			Type1Parser parserForMetrics = Type1Parser.createParserWithEncodingObject(bis, length1, length2, font.getFontEncoding());
-			Type1 parsedData = parserForMetrics.parse();
-
-			this.fContainer.setType1Font(parsedData);
-
-		} catch (IOException e) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_TYPE1_DAMAGED, "The FontFile can't be read"));
-		} catch (FontFormatException e) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_TYPE1_DAMAGED, "The FontFile is damaged"));
-		} finally {
-			IOUtils.closeQuietly(bis);
-		}
-	}
-
-	/**
-	 * Type1C is a CFF font format, extract all CFFFont object from the stream
-	 * 
-	 * @param fontStream
-	 * @return
-	 * @throws ValidationException
-	 */
-	protected void processFontFile3(PDFontDescriptorDictionary fontDescriptor,	PDStream fontFile) {
-		try {
-			CFFParser cffParser = new CFFParser();
-			List<CFFFont> lCFonts = cffParser.parse(fontFile.getByteArray());
-			if (lCFonts == null || lCFonts.isEmpty()) {
-				this.fContainer.push(new ValidationError(ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
-			}
-			this.fContainer.setCFFFontObjects(lCFonts);
-		} catch (IOException e) {
-			this.fContainer.push(new ValidationError(ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
-		}
-	}
+public class Type1DescriptorHelper extends FontDescriptorHelper<Type1Container>
+{
+    private boolean isFontFile1 = true;
+
+    public Type1DescriptorHelper(PreflightContext context, PDFont font, Type1Container fontContainer)
+    {
+        super(context, font, fontContainer);
+    }
+
+    protected boolean checkMandatoryFields(COSDictionary fDescriptor)
+    {
+        boolean result = super.checkMandatoryFields(fDescriptor);
+        /*
+         * if the this font is a Subset, the CharSet entry must be present in the FontDescriptor
+         */
+        if (isSubSet(fontDescriptor.getFontName()))
+        {
+            String charsetStr = fontDescriptor.getCharSet();
+            if (charsetStr == null || "".equals(charsetStr))
+            {
+                this.fContainer.push(new ValidationError(ERROR_FONTS_CHARSET_MISSING_FOR_SUBSET,
+                        "The Charset entry is missing for the Type1 Subset"));
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor)
+    {
+        PDStream ff1 = fontDescriptor.getFontFile();
+        PDStream ff3 = fontDescriptor.getFontFile3();
+
+        if (ff1 != null)
+        {
+            COSStream stream = ff1.getStream();
+            if (stream == null)
+            {
+                this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is missing for "
+                        + fontDescriptor.getFontName()));
+                this.fContainer.notEmbedded();
+                return null;
+            }
+
+            boolean hasLength1 = stream.getInt(COSName.LENGTH1) > 0;
+            boolean hasLength2 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_LENGTH2)) > 0;
+            boolean hasLength3 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_LENGTH3)) >= 0;
+            if (!(hasLength1 && hasLength2 && hasLength3))
+            {
+                this.fContainer.push(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is invalid for "
+                        + fontDescriptor.getFontName()));
+                return null;
+            }
+
+            return ff1;
+        }
+        else
+        {
+            this.isFontFile1 = false;
+            this.fContainer.setFontFile1(isFontFile1);
+            return ff3;
+        }
+    }
+
+    @Override
+    protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile)
+    {
+        if (isFontFile1)
+        {
+            processFontFile1(fontDescriptor, fontFile);
+        }
+        else
+        {
+            processFontFile3(fontDescriptor, fontFile);
+        }
+    }
+
+    /**
+     * Try to load the font using the java.awt.font object. if the font is invalid, an exception will be pushed in the
+     * font container
+     * 
+     * @param fontDescriptor
+     * @param fontFile
+     */
+    protected void processFontFile1(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile)
+    {
+        ByteArrayInputStream bis = null;
+        try
+        {
+            bis = new ByteArrayInputStream(fontFile.getByteArray());
+            Font.createFont(Font.TYPE1_FONT, bis);
+            IOUtils.closeQuietly(bis);
+
+            // Parse the Type1 Font program in order to extract Glyph Width
+            COSStream streamObj = fontFile.getStream();
+            int length1 = streamObj.getInt(COSName.LENGTH1);
+            int length2 = streamObj.getInt(COSName.LENGTH2);
+            bis = new ByteArrayInputStream(fontFile.getByteArray());
+            Type1Parser parserForMetrics = Type1Parser.createParserWithEncodingObject(bis, length1, length2,
+                    font.getFontEncoding());
+            Type1 parsedData = parserForMetrics.parse();
+
+            this.fContainer.setType1Font(parsedData);
+
+        }
+        catch (IOException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_TYPE1_DAMAGED, "The FontFile can't be read"));
+        }
+        catch (FontFormatException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_TYPE1_DAMAGED, "The FontFile is damaged"));
+        }
+        finally
+        {
+            IOUtils.closeQuietly(bis);
+        }
+    }
+
+    /**
+     * Type1C is a CFF font format, extract all CFFFont object from the stream
+     * 
+     * @param fontStream
+     * @return
+     * @throws ValidationException
+     */
+    protected void processFontFile3(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile)
+    {
+        try
+        {
+            CFFParser cffParser = new CFFParser();
+            List<CFFFont> lCFonts = cffParser.parse(fontFile.getByteArray());
+            if (lCFonts == null || lCFonts.isEmpty())
+            {
+                this.fContainer.push(new ValidationError(ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
+            }
+            this.fContainer.setCFFFontObjects(lCFonts);
+        }
+        catch (IOException e)
+        {
+            this.fContainer.push(new ValidationError(ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
+        }
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/CIDToGIDMap.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/CIDToGIDMap.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/CIDToGIDMap.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/CIDToGIDMap.java Wed Mar  6 16:46:35 2013
@@ -28,39 +28,49 @@ import java.io.InputStream;
 import org.apache.commons.io.IOUtils;
 import org.apache.pdfbox.cos.COSStream;
 
-public class CIDToGIDMap {
+public class CIDToGIDMap
+{
 
-	public final int NOTDEF_GLYPH_INDEX = 0;
-	private byte[] map = null;
-	
-	/**
-	 * Copy the unfiltered stream content in a byte array.
-	 * @param stream
-	 * @throws IOException if the stream can't be copied
-	 */
-	public void parseStream(COSStream stream) throws IOException {
-		InputStream is = stream.getUnfilteredStream();
-		ByteArrayOutputStream os = new ByteArrayOutputStream();
-		
-		try {
-			IOUtils.copy(stream.getUnfilteredStream(), os);
-			map  = os.toByteArray();
-		} catch (IOException e) {
-			IOUtils.closeQuietly(is);
-			IOUtils.closeQuietly(os);
-		}
-	}
-	
-	/**
-	 * Return the glyph index according to the CID.
-	 * @param cid
-	 * @return
-	 */
-	public int getGID(int cid) {
-		if (map == null || (cid*2+1) >= map.length) {
-			return NOTDEF_GLYPH_INDEX;
-		}
-		int index = cid*2;
-		return ((map[index]&0xFF)<<8)^(map[index+1]&0xFF);
-	}
-}
\ No newline at end of file
+    public final int NOTDEF_GLYPH_INDEX = 0;
+    private byte[] map = null;
+
+    /**
+     * Copy the unfiltered stream content in a byte array.
+     * 
+     * @param stream
+     * @throws IOException
+     *             if the stream can't be copied
+     */
+    public void parseStream(COSStream stream) throws IOException
+    {
+        InputStream is = stream.getUnfilteredStream();
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+        try
+        {
+            IOUtils.copy(stream.getUnfilteredStream(), os);
+            map = os.toByteArray();
+        }
+        catch (IOException e)
+        {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    /**
+     * Return the glyph index according to the CID.
+     * 
+     * @param cid
+     * @return
+     */
+    public int getGID(int cid)
+    {
+        if (map == null || (cid * 2 + 1) >= map.length)
+        {
+            return NOTDEF_GLYPH_INDEX;
+        }
+        int index = cid * 2;
+        return ((map[index] & 0xFF) << 8) ^ (map[index + 1] & 0xFF);
+    }
+}

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/FontMetaDataValidation.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/FontMetaDataValidation.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/FontMetaDataValidation.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/FontMetaDataValidation.java Wed Mar  6 16:46:35 2013
@@ -41,142 +41,147 @@ import org.apache.xmpbox.type.TextType;
 /**
  * Class used to validate the MetaData entry of the Font File Stream dictionary.
  */
-public class FontMetaDataValidation {
+public class FontMetaDataValidation
+{
 
-	public List<ValidationError> validatePDFAIdentifer(XMPMetadata metadata,
-			PDFontDescriptor fontDesc) throws ValidationException {
-		List<ValidationError> ve = new ArrayList<ValidationError>();
-
-		analyseFontName(metadata, fontDesc, ve);
-		analyseRights(metadata, fontDesc, ve);
-
-		return ve;
-	}
-
-	/**
-	 * Value of the dc:title must be the same as the FontName in the font
-	 * descriptor.
-	 * 
-	 * @param metadata
-	 *          XMPMetaData of the Font File Stream
-	 * @param fontDesc
-	 *          The FontDescriptor dictionary
-	 * @param ve
-	 *          the list of validation error to update if the validation fails
-	 */
-	public boolean analyseFontName(XMPMetadata metadata,PDFontDescriptor fontDesc, List<ValidationError> ve){
-		String fontName = fontDesc.getFontName();
-		String noSubSetName = fontName;
-		if (FontValidator.isSubSet(fontName)) {
-			noSubSetName = fontName.split(FontValidator.getSubSetPatternDelimiter())[1];
-		}
-
-		DublinCoreSchema dc = metadata.getDublinCoreSchema();
-		if (dc != null) {
-			if (dc.getTitleProperty() != null) {
-				String defaultTitle = dc.getTitle("x-default");
-				if (defaultTitle != null) {
-
-					if (!defaultTitle.equals(fontName)
-							&& (noSubSetName != null && !defaultTitle.equals(noSubSetName))) {
-						StringBuilder sb = new StringBuilder(80);
-						sb
-						.append("FontName")
-						.append(
-						" present in the FontDescriptor dictionary doesn't match with XMP information dc:title of the Font File Stream.");
-						ve.add(new ValidationError(
-								PreflightConstants.ERROR_METADATA_MISMATCH, sb.toString()));
-						return false;
-					}
-
-					// --- default value is the right one
-					return true;
-				} else {
-					Iterator<AbstractField> it = dc.getTitleProperty().getContainer()
-					.getAllProperties().iterator();
-					boolean empty = true;
-					while (it.hasNext()) {
-						empty = false;
-						AbstractField tmp = it.next();
-						if (tmp != null && tmp instanceof TextType) {
-							if (((TextType) tmp).getStringValue().equals(fontName)
-									|| (noSubSetName != null && ((TextType) tmp).getStringValue()
-											.equals(noSubSetName))) {
-								// value found, return
-								return true;
-							}
-						}
-					}
-
-					// title doesn't match, it is an error.
-					StringBuilder sb = new StringBuilder(80);
-					sb.append("FontName");
-					if (empty) {
-						sb
-						.append(" present in the FontDescriptor dictionary can't be found in XMP information the Font File Stream.");
-						ve.add(new ValidationError(
-								PreflightConstants.ERROR_METADATA_PROPERTY_MISSING, sb
-								.toString()));
-					} else {
-						sb
-						.append(" present in the FontDescriptor dictionary doesn't match with XMP information dc:title of the Font File Stream.");
-						ve.add(new ValidationError(
-								PreflightConstants.ERROR_METADATA_MISMATCH, sb.toString()));
-					}
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * If XMP MetaData are present, they must have followings information :
-	 * <UL>
-	 * <li>dc:rights
-	 * <li>Marked (with the value true)
-	 * <li>Owner
-	 * <li>UsageTerms
-	 * </UL>
-	 * 
-	 * @param metadata
-	 *          XMPMetaData of the Font File Stream
-	 * @param fontDesc
-	 *          The FontDescriptor dictionary
-	 * @param ve
-	 *          the list of validation error to update if the validation fails
-	 */
-	public boolean analyseRights(XMPMetadata metadata, PDFontDescriptor fontDesc, List<ValidationError> ve)  {
-
-		DublinCoreSchema dc = metadata.getDublinCoreSchema();
-		if (dc != null) {
-			ArrayProperty copyrights = dc.getRightsProperty();
-			if (copyrights == null || copyrights.getContainer() == null
-					|| copyrights.getContainer().getAllProperties().isEmpty()) {
-				ve
-				.add(new ValidationError(
-						PreflightConstants.ERROR_METADATA_PROPERTY_MISSING,
-				"CopyRights is missing from the XMP information (dc:rights) of the Font File Stream."));
-				return false;
-			}
-		}
-
-		XMPRightsManagementSchema rights = metadata.getXMPRightsManagementSchema();
-		if (rights != null) {
-			BooleanType marked = rights.getMarkedProperty();
-			if (marked != null && !marked.getValue()) {
-				ve
-				.add(new ValidationError(
-						PreflightConstants.ERROR_METADATA_PROPERTY_MISSING,
-				"the XMP information (xmpRights:Marked) is invalid for the Font File Stream."));
-				return false;
-			}
-
-			/*
-			 * rights.getUsageTerms() & rights.getOwnerValue() should be present but it is only a 
-			 * recommendation : may be it should be useful to append a Warning if these entries are missing.  
-			 */
-		}
-		return true;
-	}
+    public List<ValidationError> validatePDFAIdentifer(XMPMetadata metadata, PDFontDescriptor fontDesc)
+            throws ValidationException
+    {
+        List<ValidationError> ve = new ArrayList<ValidationError>();
+
+        analyseFontName(metadata, fontDesc, ve);
+        analyseRights(metadata, fontDesc, ve);
+
+        return ve;
+    }
+
+    /**
+     * Value of the dc:title must be the same as the FontName in the font descriptor.
+     * 
+     * @param metadata
+     *            XMPMetaData of the Font File Stream
+     * @param fontDesc
+     *            The FontDescriptor dictionary
+     * @param ve
+     *            the list of validation error to update if the validation fails
+     */
+    public boolean analyseFontName(XMPMetadata metadata, PDFontDescriptor fontDesc, List<ValidationError> ve)
+    {
+        String fontName = fontDesc.getFontName();
+        String noSubSetName = fontName;
+        if (FontValidator.isSubSet(fontName))
+        {
+            noSubSetName = fontName.split(FontValidator.getSubSetPatternDelimiter())[1];
+        }
+
+        DublinCoreSchema dc = metadata.getDublinCoreSchema();
+        if (dc != null)
+        {
+            if (dc.getTitleProperty() != null)
+            {
+                String defaultTitle = dc.getTitle("x-default");
+                if (defaultTitle != null)
+                {
+
+                    if (!defaultTitle.equals(fontName) && (noSubSetName != null && !defaultTitle.equals(noSubSetName)))
+                    {
+                        StringBuilder sb = new StringBuilder(80);
+                        sb.append("FontName")
+                                .append(" present in the FontDescriptor dictionary doesn't match with XMP information dc:title of the Font File Stream.");
+                        ve.add(new ValidationError(PreflightConstants.ERROR_METADATA_MISMATCH, sb.toString()));
+                        return false;
+                    }
+
+                    // --- default value is the right one
+                    return true;
+                }
+                else
+                {
+                    Iterator<AbstractField> it = dc.getTitleProperty().getContainer().getAllProperties().iterator();
+                    boolean empty = true;
+                    while (it.hasNext())
+                    {
+                        empty = false;
+                        AbstractField tmp = it.next();
+                        if (tmp != null && tmp instanceof TextType)
+                        {
+                            if (((TextType) tmp).getStringValue().equals(fontName)
+                                    || (noSubSetName != null && ((TextType) tmp).getStringValue().equals(noSubSetName)))
+                            {
+                                // value found, return
+                                return true;
+                            }
+                        }
+                    }
+
+                    // title doesn't match, it is an error.
+                    StringBuilder sb = new StringBuilder(80);
+                    sb.append("FontName");
+                    if (empty)
+                    {
+                        sb.append(" present in the FontDescriptor dictionary can't be found in XMP information the Font File Stream.");
+                        ve.add(new ValidationError(PreflightConstants.ERROR_METADATA_PROPERTY_MISSING, sb.toString()));
+                    }
+                    else
+                    {
+                        sb.append(" present in the FontDescriptor dictionary doesn't match with XMP information dc:title of the Font File Stream.");
+                        ve.add(new ValidationError(PreflightConstants.ERROR_METADATA_MISMATCH, sb.toString()));
+                    }
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * If XMP MetaData are present, they must have followings information :
+     * <UL>
+     * <li>dc:rights
+     * <li>Marked (with the value true)
+     * <li>Owner
+     * <li>UsageTerms
+     * </UL>
+     * 
+     * @param metadata
+     *            XMPMetaData of the Font File Stream
+     * @param fontDesc
+     *            The FontDescriptor dictionary
+     * @param ve
+     *            the list of validation error to update if the validation fails
+     */
+    public boolean analyseRights(XMPMetadata metadata, PDFontDescriptor fontDesc, List<ValidationError> ve)
+    {
+
+        DublinCoreSchema dc = metadata.getDublinCoreSchema();
+        if (dc != null)
+        {
+            ArrayProperty copyrights = dc.getRightsProperty();
+            if (copyrights == null || copyrights.getContainer() == null
+                    || copyrights.getContainer().getAllProperties().isEmpty())
+            {
+                ve.add(new ValidationError(PreflightConstants.ERROR_METADATA_PROPERTY_MISSING,
+                        "CopyRights is missing from the XMP information (dc:rights) of the Font File Stream."));
+                return false;
+            }
+        }
+
+        XMPRightsManagementSchema rights = metadata.getXMPRightsManagementSchema();
+        if (rights != null)
+        {
+            BooleanType marked = rights.getMarkedProperty();
+            if (marked != null && !marked.getValue())
+            {
+                ve.add(new ValidationError(PreflightConstants.ERROR_METADATA_PROPERTY_MISSING,
+                        "the XMP information (xmpRights:Marked) is invalid for the Font File Stream."));
+                return false;
+            }
+
+            /*
+             * rights.getUsageTerms() & rights.getOwnerValue() should be present but it is only a recommendation : may
+             * be it should be useful to append a Warning if these entries are missing.
+             */
+        }
+        return true;
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDescription.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDescription.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDescription.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDescription.java Wed Mar  6 16:46:35 2013
@@ -25,44 +25,56 @@ import java.util.List;
 
 import org.apache.fontbox.cff.CharStringCommand;
 
-public class GlyphDescription {
-	private List<Object> operations = null;
-
-	private Integer glyphWidth = null;
-
-	GlyphDescription(List<Object> operations) {
-		this.operations = operations;
-	}
-
-	public int getGlyphWidth() {
-		if (this.glyphWidth != null) {
-			return glyphWidth;
-		}
-
-		this.glyphWidth = searchWidth();
-		return this.glyphWidth;
-	}
-
-	private int searchWidth() {
-		for (int i = 0; operations != null && i < operations.size(); ++i) {
-			Object obj = operations.get(i);
-			if (obj instanceof CharStringCommand) {
-				CharStringCommand csCmd = (CharStringCommand) obj;
-				if ("hsbw".equals(CharStringCommand.TYPE1_VOCABULARY.get(csCmd.getKey()))) {
-					// Numbers with absolute values greater than 32,000 must be followed
-					// by a div operator such that the result of the div is less than 32,000.
-					if (operations.get(i - 1) instanceof CharStringCommand) {
-						CharStringCommand div = (CharStringCommand) operations.get(i - 1);
-						if ("div".equals(CharStringCommand.TYPE1_VOCABULARY.get(div.getKey()))) {
-							return ((Integer)operations.get(i - 3) / (Integer)operations.get(i - 2));
-						}
-					} else {
-						return (Integer) operations.get(i - 1);
-					}
-				}
-			}
-		}
-		// 0 is the default value if glyph isn't found. 
-		return 0;
-	}	
-}
\ No newline at end of file
+public class GlyphDescription
+{
+    private List<Object> operations = null;
+
+    private Integer glyphWidth = null;
+
+    GlyphDescription(List<Object> operations)
+    {
+        this.operations = operations;
+    }
+
+    public int getGlyphWidth()
+    {
+        if (this.glyphWidth != null)
+        {
+            return glyphWidth;
+        }
+
+        this.glyphWidth = searchWidth();
+        return this.glyphWidth;
+    }
+
+    private int searchWidth()
+    {
+        for (int i = 0; operations != null && i < operations.size(); ++i)
+        {
+            Object obj = operations.get(i);
+            if (obj instanceof CharStringCommand)
+            {
+                CharStringCommand csCmd = (CharStringCommand) obj;
+                if ("hsbw".equals(CharStringCommand.TYPE1_VOCABULARY.get(csCmd.getKey())))
+                {
+                    // Numbers with absolute values greater than 32,000 must be followed
+                    // by a div operator such that the result of the div is less than 32,000.
+                    if (operations.get(i - 1) instanceof CharStringCommand)
+                    {
+                        CharStringCommand div = (CharStringCommand) operations.get(i - 1);
+                        if ("div".equals(CharStringCommand.TYPE1_VOCABULARY.get(div.getKey())))
+                        {
+                            return ((Integer) operations.get(i - 3) / (Integer) operations.get(i - 2));
+                        }
+                    }
+                    else
+                    {
+                        return (Integer) operations.get(i - 1);
+                    }
+                }
+            }
+        }
+        // 0 is the default value if glyph isn't found.
+        return 0;
+    }
+}

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDetail.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDetail.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDetail.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDetail.java Wed Mar  6 16:46:35 2013
@@ -21,26 +21,32 @@
 
 package org.apache.pdfbox.preflight.font.util;
 
-public class GlyphDetail {
-	private GlyphException invalidGlyphError = null;
-	private int charecterIdentifier = 0;
-	
-	public GlyphDetail(int cid) {
-		this.charecterIdentifier = cid;
-	}
-
-	public GlyphDetail(int cid, GlyphException error) {
-		this.charecterIdentifier = cid;
-		this.invalidGlyphError = error;
-	}
-
-	public void throwExceptionIfNotValid() throws GlyphException {
-		if (this.invalidGlyphError != null) {
-			throw this.invalidGlyphError;
-		}
-	}
-
-	public int getCID() {
-		return this.charecterIdentifier;
-	}
+public class GlyphDetail
+{
+    private GlyphException invalidGlyphError = null;
+    private int charecterIdentifier = 0;
+
+    public GlyphDetail(int cid)
+    {
+        this.charecterIdentifier = cid;
+    }
+
+    public GlyphDetail(int cid, GlyphException error)
+    {
+        this.charecterIdentifier = cid;
+        this.invalidGlyphError = error;
+    }
+
+    public void throwExceptionIfNotValid() throws GlyphException
+    {
+        if (this.invalidGlyphError != null)
+        {
+            throw this.invalidGlyphError;
+        }
+    }
+
+    public int getCID()
+    {
+        return this.charecterIdentifier;
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphException.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphException.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphException.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphException.java Wed Mar  6 16:46:35 2013
@@ -21,28 +21,33 @@
 
 package org.apache.pdfbox.preflight.font.util;
 
-public class GlyphException extends Exception {
-	private String errorCode;
-	private int invalidCid;
-	
-	public GlyphException(String code, int cid) {
-		super();
-		this.errorCode = code;
-		this.invalidCid = cid;
-	}
-
-	public GlyphException(String code, int cid, String message) {
-		super(message);
-		this.errorCode = code;
-		this.invalidCid = cid;
-	}
-	
-	public String getErrorCode() {
-		return errorCode;
-	}
-
-	public int getInvalidCid() {
-		return invalidCid;
-	}
+public class GlyphException extends Exception
+{
+    private String errorCode;
+    private int invalidCid;
+
+    public GlyphException(String code, int cid)
+    {
+        super();
+        this.errorCode = code;
+        this.invalidCid = cid;
+    }
+
+    public GlyphException(String code, int cid, String message)
+    {
+        super(message);
+        this.errorCode = code;
+        this.invalidCid = cid;
+    }
+
+    public String getErrorCode()
+    {
+        return errorCode;
+    }
+
+    public int getInvalidCid()
+    {
+        return invalidCid;
+    }
 
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PDFAType3StreamParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PDFAType3StreamParser.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PDFAType3StreamParser.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PDFAType3StreamParser.java Wed Mar  6 16:46:35 2013
@@ -38,131 +38,145 @@ import org.apache.pdfbox.util.ImageParam
 import org.apache.pdfbox.util.PDFOperator;
 
 /**
- * This class is used to parse a glyph of a Type3 font program. If the glyph is
- * parsed without error, the width of the glyph is accessible through the
- * getWidth method.
+ * This class is used to parse a glyph of a Type3 font program. If the glyph is parsed without error, the width of the
+ * glyph is accessible through the getWidth method.
  */
-public class PDFAType3StreamParser extends ContentStreamEngine {
-  private boolean firstOperator = true;
-  private float width = 0;
-
-  private PDInlinedImage image = null;
-  private BoundingBox box = null;
-
-  public PDFAType3StreamParser(PreflightContext context, PDPage page) {
-    super(context, page);
-  }
-
-  /**
-   * This will parse a type3 stream and create an image from it.
-   * 
-   * @param type3Stream
-   *          The stream containing the operators to draw the image.
-   * 
-   * @return The image that was created.
-   * 
-   * @throws IOException
-   *           If there is an error processing the stream.
-   */
-  public Image createImage(COSStream type3Stream) throws IOException {
-  	resetEngine();
-    processSubStream(null, null, type3Stream);
-    return image.createImage();
-  }
-
-  /**
-   * This is used to handle an operation.
-   * 
-   * @param operator
-   *          The operation to perform.
-   * @param arguments
-   *          The list of arguments.
-   * 
-   * @throws IOException
-   *           If there is an error processing the operation.
-   */
-  protected void processOperator(PDFOperator operator, List arguments)
-      throws IOException {
-    super.processOperator(operator, arguments);
-    String operation = operator.getOperation();
-
-    if (operation.equals("BI")) {
-      ImageParameters params = operator.getImageParameters();
-      image = new PDInlinedImage();
-      image.setImageParameters(params);
-      image.setImageData(operator.getImageData());
-
-      validImageFilter(operator);
-      validImageColorSpace(operator);
+public class PDFAType3StreamParser extends ContentStreamEngine
+{
+    private boolean firstOperator = true;
+    private float width = 0;
+
+    private PDInlinedImage image = null;
+    private BoundingBox box = null;
+
+    public PDFAType3StreamParser(PreflightContext context, PDPage page)
+    {
+        super(context, page);
     }
 
-    if (operation.equals("d0")) {
-      // set glyph with for a type3 font
-      // COSNumber horizontalWidth = (COSNumber)arguments.get( 0 );
-      // COSNumber verticalWidth = (COSNumber)arguments.get( 1 );
-      // width = horizontalWidth.intValue();
-      // height = verticalWidth.intValue();
-
-      checkType3FirstOperator(arguments);
-
-    } else if (operation.equals("d1")) {
-      // set glyph with and bounding box for type 3 font
-      // COSNumber horizontalWidth = (COSNumber)arguments.get( 0 );
-      // COSNumber verticalWidth = (COSNumber)arguments.get( 1 );
-      COSNumber llx = (COSNumber) arguments.get(2);
-      COSNumber lly = (COSNumber) arguments.get(3);
-      COSNumber urx = (COSNumber) arguments.get(4);
-      COSNumber ury = (COSNumber) arguments.get(5);
-
-      // width = horizontalWidth.intValue();
-      // height = verticalWidth.intValue();
-      box = new BoundingBox();
-      box.setLowerLeftX(llx.floatValue());
-      box.setLowerLeftY(lly.floatValue());
-      box.setUpperRightX(urx.floatValue());
-      box.setUpperRightY(ury.floatValue());
-
-      checkType3FirstOperator(arguments);
+    /**
+     * This will parse a type3 stream and create an image from it.
+     * 
+     * @param type3Stream
+     *            The stream containing the operators to draw the image.
+     * 
+     * @return The image that was created.
+     * 
+     * @throws IOException
+     *             If there is an error processing the stream.
+     */
+    public Image createImage(COSStream type3Stream) throws IOException
+    {
+        resetEngine();
+        processSubStream(null, null, type3Stream);
+        return image.createImage();
     }
 
-    checkColorOperators(operation);
-    validRenderingIntent(operator, arguments);
-    checkSetColorSpaceOperators(operator, arguments);
-    validNumberOfGraphicStates(operator);
-    firstOperator = false;
-  }
-
-  /**
-   * According to the PDF Reference, the first operator in a CharProc of a Type3
-   * font must be "d0" or "d1". This method process this validation. This method
-   * is called by the processOperator method.
-   * 
-   * @param arguments
-   * @throws IOException
-   */
-  private void checkType3FirstOperator(List arguments) throws IOException {
-    if (!firstOperator) {
-      throw new IOException("Type3 CharProc : First operator must be d0 or d1");
+    /**
+     * This is used to handle an operation.
+     * 
+     * @param operator
+     *            The operation to perform.
+     * @param arguments
+     *            The list of arguments.
+     * 
+     * @throws IOException
+     *             If there is an error processing the operation.
+     */
+    protected void processOperator(PDFOperator operator, List arguments) throws IOException
+    {
+        super.processOperator(operator, arguments);
+        String operation = operator.getOperation();
+
+        if (operation.equals("BI"))
+        {
+            ImageParameters params = operator.getImageParameters();
+            image = new PDInlinedImage();
+            image.setImageParameters(params);
+            image.setImageData(operator.getImageData());
+
+            validImageFilter(operator);
+            validImageColorSpace(operator);
+        }
+
+        if (operation.equals("d0"))
+        {
+            // set glyph with for a type3 font
+            // COSNumber horizontalWidth = (COSNumber)arguments.get( 0 );
+            // COSNumber verticalWidth = (COSNumber)arguments.get( 1 );
+            // width = horizontalWidth.intValue();
+            // height = verticalWidth.intValue();
+
+            checkType3FirstOperator(arguments);
+
+        }
+        else if (operation.equals("d1"))
+        {
+            // set glyph with and bounding box for type 3 font
+            // COSNumber horizontalWidth = (COSNumber)arguments.get( 0 );
+            // COSNumber verticalWidth = (COSNumber)arguments.get( 1 );
+            COSNumber llx = (COSNumber) arguments.get(2);
+            COSNumber lly = (COSNumber) arguments.get(3);
+            COSNumber urx = (COSNumber) arguments.get(4);
+            COSNumber ury = (COSNumber) arguments.get(5);
+
+            // width = horizontalWidth.intValue();
+            // height = verticalWidth.intValue();
+            box = new BoundingBox();
+            box.setLowerLeftX(llx.floatValue());
+            box.setLowerLeftY(lly.floatValue());
+            box.setUpperRightX(urx.floatValue());
+            box.setUpperRightY(ury.floatValue());
+
+            checkType3FirstOperator(arguments);
+        }
+
+        checkColorOperators(operation);
+        validRenderingIntent(operator, arguments);
+        checkSetColorSpaceOperators(operator, arguments);
+        validNumberOfGraphicStates(operator);
+        firstOperator = false;
     }
 
-    Object obj = arguments.get(0);
-    if (obj instanceof Number) {
-      width = ((Number) obj).intValue();
-    } else if (obj instanceof COSInteger) {
-      width = ((COSInteger) obj).floatValue();
-    } else if (obj instanceof COSFloat) {
-    	width = ((COSFloat)obj).floatValue();
-    } else {
-      throw new IOException(
-          "Unexpected argument type. Expected : COSInteger or Number / Received : "
-              + obj.getClass().getName());
+    /**
+     * According to the PDF Reference, the first operator in a CharProc of a Type3 font must be "d0" or "d1". This
+     * method process this validation. This method is called by the processOperator method.
+     * 
+     * @param arguments
+     * @throws IOException
+     */
+    private void checkType3FirstOperator(List arguments) throws IOException
+    {
+        if (!firstOperator)
+        {
+            throw new IOException("Type3 CharProc : First operator must be d0 or d1");
+        }
+
+        Object obj = arguments.get(0);
+        if (obj instanceof Number)
+        {
+            width = ((Number) obj).intValue();
+        }
+        else if (obj instanceof COSInteger)
+        {
+            width = ((COSInteger) obj).floatValue();
+        }
+        else if (obj instanceof COSFloat)
+        {
+            width = ((COSFloat) obj).floatValue();
+        }
+        else
+        {
+            throw new IOException("Unexpected argument type. Expected : COSInteger or Number / Received : "
+                    + obj.getClass().getName());
+        }
     }
-  }
 
-  /**
-   * @return the width of the CharProc glyph description
-   */
-  public float getWidth() {
-    return this.width;
-  }
+    /**
+     * @return the width of the CharProc glyph description
+     */
+    public float getWidth()
+    {
+        return this.width;
+    }
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PeekInputStream.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PeekInputStream.java?rev=1453416&r1=1453415&r2=1453416&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PeekInputStream.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PeekInputStream.java Wed Mar  6 16:46:35 2013
@@ -27,47 +27,58 @@ import java.io.InputStream;
 
 import org.apache.commons.io.IOUtils;
 
-public class PeekInputStream extends InputStream {
-	private byte[] content = new byte[0];
-	private int position = 0;
-	
-	public PeekInputStream(InputStream source) throws IOException {
-		ByteArrayOutputStream bos = new ByteArrayOutputStream();
-		try {
-			IOUtils.copyLarge(source, bos);
-			content = bos.toByteArray();
-		} finally {
-			IOUtils.closeQuietly(source);
-			IOUtils.closeQuietly(bos);
-		}
-	}
-
-	@Override
-	public int read() throws IOException {
-		if (position >= content.length) {
-			throw new IOException("No more content in this stream");
-		}
-
-		int currentByte = (content[position] & 0xFF);
-		++position;
-		return currentByte;
-	}
-
-	public int peek() throws IOException {
-		if (position >= content.length) {
-			throw new IOException("No more content in this stream");
-		}
-
-		return (content[position] & 0xFF);
-	}
-	
-	public byte[] peek(int numberOfBytes) throws IOException {
-		if ( numberOfBytes < 0 || (position + numberOfBytes) >= content.length) {
-			throw new IOException("No more content in this stream, can't return the next " + numberOfBytes + " bytes");
-		}
-
-		byte[] nextBytes = new byte[numberOfBytes];
-		System.arraycopy(this.content, this.position, nextBytes, 0, numberOfBytes);
-		return nextBytes; 
-	}
-}
\ No newline at end of file
+public class PeekInputStream extends InputStream
+{
+    private byte[] content = new byte[0];
+    private int position = 0;
+
+    public PeekInputStream(InputStream source) throws IOException
+    {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try
+        {
+            IOUtils.copyLarge(source, bos);
+            content = bos.toByteArray();
+        }
+        finally
+        {
+            IOUtils.closeQuietly(source);
+            IOUtils.closeQuietly(bos);
+        }
+    }
+
+    @Override
+    public int read() throws IOException
+    {
+        if (position >= content.length)
+        {
+            throw new IOException("No more content in this stream");
+        }
+
+        int currentByte = (content[position] & 0xFF);
+        ++position;
+        return currentByte;
+    }
+
+    public int peek() throws IOException
+    {
+        if (position >= content.length)
+        {
+            throw new IOException("No more content in this stream");
+        }
+
+        return (content[position] & 0xFF);
+    }
+
+    public byte[] peek(int numberOfBytes) throws IOException
+    {
+        if (numberOfBytes < 0 || (position + numberOfBytes) >= content.length)
+        {
+            throw new IOException("No more content in this stream, can't return the next " + numberOfBytes + " bytes");
+        }
+
+        byte[] nextBytes = new byte[numberOfBytes];
+        System.arraycopy(this.content, this.position, nextBytes, 0, numberOfBytes);
+        return nextBytes;
+    }
+}