You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2012/07/14 21:53:50 UTC
svn commit: r1361579 [1/3] - in /pdfbox/trunk:
pdfbox/src/main/java/org/apache/pdfbox/cos/
preflight/src/main/java/org/apache/padaf/preflight/contentstream/
preflight/src/main/java/org/apache/pdfbox/preflight/
preflight/src/main/java/org/apache/pdfbox/...
Author: leleueri
Date: Sat Jul 14 19:53:48 2012
New Revision: 1361579
URL: http://svn.apache.org/viewvc?rev=1361579&view=rev
Log:
[https://issues.apache.org/jira/browse/PDFBOX-1312] Font validation refactoring
Added:
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/CIDType0Container.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/CIDType2Container.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/FontContainer.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/TrueTypeContainer.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/Type0Container.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/Type1Container.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/container/Type3Container.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java (with props)
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/CIDToGIDMap.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDToGIDMap.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/FontMetaDataValidation.java
- copied, changed from r1359830, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontMetaDataValidation.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDescription.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/type1/GlyphDescription.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphDetail.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/GlyphDetail.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/GlyphException.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/GlyphException.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PDFAType3StreamParser.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/PDFAType3StreamParser.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/PeekInputStream.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/type1/PeekInputStream.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/type1/Type1.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/util/Type1Parser.java
- copied, changed from r1355309, pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/type1/Type1Parser.java
Removed:
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/AbstractFontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/AbstractFontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CFFType0FontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CFFType2FontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDToGIDMap.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CompositeFontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CompositeFontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontMetaDataValidation.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/GlyphDetail.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/GlyphException.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/PDFAType3StreamParser.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1MetricHelper.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type3FontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/UndefFontContainer.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/type1/
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightConstants.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightContext.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/content/ContentStreamWrapper.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/SimpleFontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type3FontValidator.java
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/FontValidationProcess.java
pdfbox/trunk/preflight/src/test/java/org/apache/pdfbox/preflight/TestInvalidDirectory.java
pdfbox/trunk/preflight/src/test/java/org/apache/pdfbox/preflight/TestValidDirectory.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java Sat Jul 14 19:53:48 2012
@@ -779,6 +779,7 @@ public final class COSName extends COSBa
*/
public static final COSName LENGTH1 = new COSName( "Length1" );
+ public static final COSName LENGTH2 = new COSName( "Length2" );
/**
* A common COSName value.
*/
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java Sat Jul 14 19:53:48 2012
@@ -344,7 +344,7 @@ public class ContentStreamWrapper extend
} catch (IOException e) {
throwContentStreamException("Encoding can't interpret the character code", ERROR_FONTS_ENCODING_ERROR);
}
-
+
try {
fontContainer.checkCID(cid);
} catch (GlyphException e) {
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightConstants.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightConstants.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightConstants.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightConstants.java Sat Jul 14 19:53:48 2012
@@ -85,7 +85,6 @@ public interface PreflightConstants {
String DICTIONARY_KEY_XOBJECT = "XObject";
String DICTIONARY_KEY_PATTERN = "Pattern";
- String DICTIONARY_KEY_FONT = "Font";
String DICTIONARY_KEY_PATTERN_TYPE = "PatternType";
int DICTIONARY_PATTERN_TILING = 1;
@@ -147,18 +146,12 @@ public interface PreflightConstants {
String FONT_DICTIONARY_KEY_DESCENT = "Descent";
String FONT_DICTIONARY_KEY_CAPHEIGHT = "CapHeight";
String FONT_DICTIONARY_KEY_STEMV = "StemV";
- String FONT_DICTIONARY_KEY_LENGTH1 = "Length1";
String FONT_DICTIONARY_KEY_LENGTH2 = "Length2";
String FONT_DICTIONARY_KEY_LENGTH3 = "Length3";
String FONT_DICTIONARY_KEY_METADATA = "Metadata";
String FONT_DICTIONARY_KEY_BASEENCODING = "BaseEncoding";
- String FONT_DICTIONARY_KEY_DIFFERENCES = "Differences";
String FONT_DICTIONARY_KEY_DESCENDANT_FONTS = "DescendantFonts";
- String FONT_DICTIONARY_KEY_CID_SYSINFO = "CIDSystemInfo";
String FONT_DICTIONARY_KEY_CID_GIDMAP = "CIDToGIDMap";
- String FONT_DICTIONARY_KEY_SYSINFO_REGISTRY = "Registry";
- String FONT_DICTIONARY_KEY_SYSINFO_ORDERING = "Ordering";
- String FONT_DICTIONARY_KEY_SYSINFO_SUPPLEMENT = "Supplement";
String FONT_DICTIONARY_KEY_CMAP_NAME = "CMapName";
String FONT_DICTIONARY_KEY_CMAP_WMODE = "WMode";
String FONT_DICTIONARY_KEY_CMAP_USECMAP = "UseCMap";
@@ -834,6 +827,14 @@ public interface PreflightConstants {
*/
String ERROR_METADATA_FORMAT_UNKOWN = "7.1.3";
/**
+ * Invalid metadata, unable to process the font due to IOException
+ */
+ String ERROR_METADATA_FORMAT_STREAM = "7.1.4";
+ /**
+ * Invalid metadata, unable to process the font due to Invalid XPacket exception
+ */
+ String ERROR_METADATA_FORMAT_XPACKET = "7.1.5";
+ /**
* Metadata mismatch between PDF Dictionnary and xmp
*/
String ERROR_METADATA_MISMATCH = "7.2";
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightContext.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightContext.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/PreflightContext.java Sat Jul 14 19:53:48 2012
@@ -30,7 +30,7 @@ import javax.activation.DataSource;
import org.apache.padaf.xmpbox.XMPMetadata;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
-import org.apache.pdfbox.preflight.font.AbstractFontContainer;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
import org.apache.pdfbox.preflight.graphic.ICCProfileWrapper;
import org.apache.pdfbox.preflight.javacc.extractor.ExtractorTokenManager;
import org.apache.pdfbox.preflight.utils.COSUtils;
@@ -39,8 +39,8 @@ public class PreflightContext {
/**
* Contains the list of font name embedded in the PDF document.
*/
- protected Map<COSBase, AbstractFontContainer> embeddedFonts = new HashMap<COSBase, AbstractFontContainer>();
-
+ protected Map<COSBase, FontContainer> fontContainers = new HashMap<COSBase, FontContainer>();
+
/**
* The PDFbox object representation of the PDF source.
*/
@@ -148,23 +148,21 @@ public class PreflightContext {
* @param fKey
* @param fc
*/
- public void addFont(COSBase cBase, AbstractFontContainer fc) {
- this.embeddedFonts.put(cBase, fc);
+ public void addFontContainer(COSBase cBase, FontContainer fc) {
+ this.fontContainers.put(cBase, fc);
}
-
-
/**
* Return the FontContainer identified by the COSBase. If the given object
- * is missing from the emmbeddedFont map, the null value is returned.
+ * is missing from the {@link #fontContainers} map, the null value is returned.
*
* @param fKey
* @return
*/
- public AbstractFontContainer getFont(COSBase cBase) {
- return this.embeddedFonts.get(cBase);
+ public FontContainer getFontContainer(COSBase cBase) {
+ return this.fontContainers.get(cBase);
}
-
+
/**
* @return the iccProfileWrapper
*/
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/content/ContentStreamWrapper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/content/ContentStreamWrapper.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/content/ContentStreamWrapper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/content/ContentStreamWrapper.java Sat Jul 14 19:53:48 2012
@@ -22,7 +22,6 @@
package org.apache.pdfbox.preflight.content;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_ENCODING_ERROR;
-import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_FONT_FILEX_INVALID;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_UNKNOWN_FONT_REF;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_SYNTAX_CONTENT_STREAM_UNSUPPORTED_OP;
@@ -47,9 +46,8 @@ import org.apache.pdfbox.pdmodel.text.PD
import org.apache.pdfbox.preflight.PreflightContext;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
import org.apache.pdfbox.preflight.exception.ValidationException;
-import org.apache.pdfbox.preflight.font.AbstractFontContainer;
-import org.apache.pdfbox.preflight.font.AbstractFontContainer.State;
-import org.apache.pdfbox.preflight.font.GlyphException;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
+import org.apache.pdfbox.preflight.font.util.GlyphException;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
@@ -280,42 +278,36 @@ public class ContentStreamWrapper extend
* @throws IOException
*/
public void validText(byte[] string) throws IOException {
- // --- TextSize accessible through the TextState
+ // TextSize accessible through the TextState
PDTextState textState = getGraphicsState().getTextState();
final int renderingMode = textState.getRenderingMode();
final PDFont font = textState.getFont();
if (font == null) {
- // ---- Unable to decode the Text without Font
+ // Unable to decode the Text without Font
throwContentStreamException("Text operator can't be process without Font", ERROR_FONTS_UNKNOWN_FONT_REF);
}
- AbstractFontContainer fontContainer = context.getFont(font.getCOSObject());
-
- if (fontContainer != null && fontContainer.isValid() == State.INVALID) {
- context.addValidationErrors(fontContainer.getErrors());
- return;
- }
-
- if (renderingMode == 3 && (fontContainer == null || !fontContainer.isFontProgramEmbedded())) {
+ FontContainer fontContainer = context.getFontContainer(font.getCOSObject());
+ if (renderingMode == 3 && (fontContainer == null || !fontContainer.isEmbeddedFont())) {
// font not embedded and rendering mode is 3. Valid case and nothing to check
return ;
- }
-
- if (fontContainer == null) {
- // ---- Font Must be embedded if the RenderingMode isn't 3
+ } else if (fontContainer == null) {
+ // Font Must be embedded if the RenderingMode isn't 3
throwContentStreamException(font.getBaseFont() + " is unknown wasn't found by the FontHelperValdiator", ERROR_FONTS_UNKNOWN_FONT_REF);
+ } else if (!fontContainer.isValid() && ! fontContainer.errorsAleadyMerged()) {
+ context.addValidationErrors(fontContainer.getAllErrors());
+ fontContainer.setErrorsAleadyMerged(true);
}
- if (!fontContainer.isFontProgramEmbedded()) {
- throwContentStreamException(font.getBaseFont() + " isn't embedded and the rendering mode isn't 3", ERROR_FONTS_FONT_FILEX_INVALID);
- }
int codeLength = 1;
for (int i = 0; i < string.length; i += codeLength) {
+ // explore the string to detect character code (length can be 1 or 2 bytes)
int cid = -1;
codeLength = 1;
try {
+ // according to the encoding, extract the character identifier
cid = font.encodeToCID(string, i, codeLength);
if (cid == -1 && i + 1 < string.length) {
// maybe a multibyte encoding
@@ -327,7 +319,7 @@ public class ContentStreamWrapper extend
}
try {
- fontContainer.checkCID(cid);
+ fontContainer.checkGlyphWith(cid);
} catch (GlyphException e) {
if (renderingMode != 3) {
throwContentStreamException(e.getMessage(), e.getErrorCode());
Added: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java?rev=1361579&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java Sat Jul 14 19:53:48 2012
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+package org.apache.pdfbox.preflight.font;
+
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.preflight.PreflightContext;
+import org.apache.pdfbox.preflight.font.container.CIDType0Container;
+import org.apache.pdfbox.preflight.font.descriptor.CIDType0DescriptorHelper;
+
+public class CIDType0FontValidator extends DescendantFontValidator<CIDType0Container> {
+
+ public CIDType0FontValidator(PreflightContext context, PDFont font) {
+ super(context, font, new CIDType0Container(font));
+ }
+
+ @Override
+ protected void checkCIDToGIDMap(COSBase ctog) {
+ checkCIDToGIDMap(ctog, false);
+ }
+
+ @Override
+ protected void createFontDescriptorHelper() {
+ this.descriptorHelper = new CIDType0DescriptorHelper(context, font, fontContainer);
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType0FontValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java?rev=1361579&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java Sat Jul 14 19:53:48 2012
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+package org.apache.pdfbox.preflight.font;
+
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.preflight.PreflightContext;
+import org.apache.pdfbox.preflight.font.container.CIDType2Container;
+import org.apache.pdfbox.preflight.font.descriptor.CIDType2DescriptorHelper;
+import org.apache.pdfbox.preflight.font.util.CIDToGIDMap;
+
+public class CIDType2FontValidator extends DescendantFontValidator<CIDType2Container> {
+
+ public CIDType2FontValidator(PreflightContext context, PDFont font) {
+ super(context, font, new CIDType2Container(font));
+ }
+
+ @Override
+ protected void checkCIDToGIDMap(COSBase ctog) {
+ CIDToGIDMap cidToGid = checkCIDToGIDMap(ctog, true);
+ this.fontContainer.setCidToGid(cidToGid);
+ }
+
+ @Override
+ protected void createFontDescriptorHelper() {
+ this.descriptorHelper = new CIDType2DescriptorHelper(context, font, fontContainer);
+ }
+
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/CIDType2FontValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java?rev=1361579&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java Sat Jul 14 19:53:48 2012
@@ -0,0 +1,139 @@
+/*****************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+package org.apache.pdfbox.preflight.font;
+
+import static org.apache.pdfbox.preflight.PreflightConstants.*;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_DICTIONARY_INVALID;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSDocument;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.preflight.PreflightContext;
+import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
+import org.apache.pdfbox.preflight.font.util.CIDToGIDMap;
+import org.apache.pdfbox.preflight.utils.COSUtils;
+
+public abstract class DescendantFontValidator <T extends FontContainer> extends SimpleFontValidator<T> {
+
+ protected COSDocument cosDocument = null;
+
+ public DescendantFontValidator(PreflightContext context, PDFont font, T fContainer) {
+ super(context, font, fContainer);
+ cosDocument = context.getDocument().getDocument();
+ }
+
+ @Override
+ protected void checkMandatoryField() {
+ COSDictionary fontDictionary = (COSDictionary)font.getCOSObject();
+
+ boolean arePresent =fontDictionary.containsKey(COSName.TYPE);
+ arePresent &= fontDictionary.containsKey(COSName.SUBTYPE);
+ arePresent &= fontDictionary.containsKey(COSName.BASE_FONT);
+ arePresent &= fontDictionary.containsKey(COSName.CIDSYSTEMINFO);
+ arePresent &= fontDictionary.containsKey(COSName.FONT_DESC);
+
+ if (!arePresent) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Required keys are missing"));
+ }
+
+ checkCIDSystemInfo(fontDictionary.getItem(COSName.CIDSYSTEMINFO));
+ checkCIDToGIDMap(fontDictionary.getItem(COSName.CID_TO_GID_MAP));
+ }
+
+ /**
+ * Check the content of the CIDSystemInfo dictionary. A CIDSystemInfo dictionary must contain :
+ * <UL>
+ * <li>a Name - Registry
+ * <li>a Name - Ordering
+ * <li>a Integer - Supplement
+ * </UL>
+ *
+ * @param sysinfo
+ * @return
+ */
+ protected void checkCIDSystemInfo(COSBase sysinfo) {
+ COSDictionary cidSysInfo = COSUtils.getAsDictionary(sysinfo, cosDocument);
+ if (cidSysInfo != null) {
+ COSBase reg = cidSysInfo.getItem(COSName.REGISTRY);
+ COSBase ord = cidSysInfo.getItem(COSName.ORDERING);
+ COSBase sup = cidSysInfo.getItem(COSName.SUPPLEMENT);
+
+ if (!(COSUtils.isString(reg, cosDocument) && COSUtils.isString(ord, cosDocument) && COSUtils.isInteger(sup, cosDocument))) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_SYSINFO));
+ }
+
+ } else {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_SYSINFO));
+ }
+ }
+
+ /**
+ * This method checks the CIDtoGIDMap entry of the Font dictionary.
+ * call the {@linkplain #checkCIDToGIDMap(COSBase, boolean)} with right parameters
+ * according to the instance of DescendantFontValidator
+ *
+ * @param ctog
+ */
+ protected abstract void checkCIDToGIDMap(COSBase ctog);
+
+ /**
+ * This method checks the CIDtoGIDMap entry of the Font dictionary. This
+ * element must be a Stream or a Name. If it is a name, it must be "Identity"
+ * otherwise, the PDF file isn't a PDF/A-1b.
+ *
+ * If the validation fails the list of errors in the FontContainer is updated.
+ *
+ * If the CIDtoGIDMap is a Stream, it is parsed as a CMap and the result is returned.
+ * @param ctog
+ * @param mandatory true for CIDType2 , false for CIDType0
+ * @return
+ */
+ protected CIDToGIDMap checkCIDToGIDMap(COSBase ctog,boolean mandatory) {
+ CIDToGIDMap cidToGidMap = null;
+
+ if (COSUtils.isString(ctog, cosDocument)) {
+ // ---- valid only if the string is Identity
+ String ctogStr = COSUtils.getAsString(ctog, cosDocument);
+ if (!FONT_DICTIONARY_VALUE_CMAP_IDENTITY.equals(ctogStr)) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CIDTOGID,"The CIDToGID entry is invalid"));
+ }
+ } else if (COSUtils.isStream(ctog, cosDocument)) {
+ try {
+ COSStream ctogMap = COSUtils.getAsStream(ctog, cosDocument);
+ cidToGidMap = new CIDToGIDMap();
+ cidToGidMap.parseStream(ctogMap);
+ } catch (IOException e) {
+ // map can be invalid, return a Validation Error
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CIDTOGID));
+ }
+ } else if (mandatory) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CIDTOGID));
+ }
+ return cidToGidMap;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/DescendantFontValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontValidator.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontValidator.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/FontValidator.java Sat Jul 14 19:53:48 2012
@@ -21,33 +21,49 @@
package org.apache.pdfbox.preflight.font;
-import org.apache.pdfbox.preflight.font.AbstractFontContainer.State;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.preflight.PreflightContext;
import org.apache.pdfbox.preflight.exception.ValidationException;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
+import org.apache.pdfbox.preflight.font.descriptor.FontDescriptorHelper;
-
-public interface FontValidator {
-
- /**
- * Call this method to validate the font wrapped by this interface
- * implementation. Return true if the validation succeed, false otherwise. If
- * the validation failed, the error is updated in the FontContainer with the
- * right error code.
- *
- * @return
- */
- public abstract void validate() throws ValidationException;
-
- /**
- * Return the State of the Font Validation. Three values are possible :
- * <UL>
- * <li>VALID : there are no errors
- * <li>MAYBE : Metrics aren't consistent of the FontProgram isn't embedded,
- * but it can be valid.
- * <li>INVALID : the validation fails
- * </UL>
- *
- * @return
- */
- public State getState();
-
+public abstract class FontValidator <T extends FontContainer> {
+
+ protected T fontContainer;
+ protected PreflightContext context;
+ protected PDFont font;
+ protected FontDescriptorHelper<T> descriptorHelper;
+
+ private static final String subSetPattern = "^[A-Z]{6}\\+.*";
+
+ public FontValidator(PreflightContext context, PDFont font, T fContainer) {
+ super();
+ this.context = context;
+ this.font = font;
+ this.fontContainer = fContainer;
+ this.context.addFontContainer(font.getCOSObject(), fContainer);
+ }
+
+ public static boolean isSubSet(String fontName) {
+ return fontName.matches(subSetPattern);
+ }
+
+ public static String getSubSetPatternDelimiter() {
+ return "\\+";
+ }
+
+ public abstract void validate() throws ValidationException;
+
+ protected void checkEncoding() {
+ // nothing to check for PDF/A-1b
+ }
+
+ protected void checkToUnicode() {
+ // nothing to check for PDF/A-1b
+ }
+
+ public T getFontContainer() {
+ return fontContainer;
+ }
+
}
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/SimpleFontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/SimpleFontValidator.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/SimpleFontValidator.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/SimpleFontValidator.java Sat Jul 14 19:53:48 2012
@@ -21,206 +21,58 @@
package org.apache.pdfbox.preflight.font;
-
-import java.util.List;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_DICTIONARY_INVALID;
import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.font.PDFont;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptorAFM;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary;
-import org.apache.pdfbox.preflight.PreflightConstants;
import org.apache.pdfbox.preflight.PreflightContext;
-import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
import org.apache.pdfbox.preflight.exception.ValidationException;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
-public abstract class SimpleFontValidator extends AbstractFontValidator {
- protected String basefont;
- protected int firstChar;
- protected int lastChar;
- protected List<Float> widths;
- /**
- * The PdfBox font descriptor dictionary wrapper.
- */
- protected PDFontDescriptor pFontDesc = null;
-
- public SimpleFontValidator(PreflightContext context, PDFont font)
- throws ValidationException {
- super(context, font);
- this.pFontDesc = font.getFontDescriptor();
- }
-
- /**
- * Extract element from the COSObject to avoid useless access to this object.
- */
- private void extractElementsToCheck() {
- // here is required elements
- this.basefont = pFont.getBaseFont();
- this.firstChar = pFont.getFirstChar();
- this.lastChar = pFont.getLastChar();
- this.widths = pFont.getWidths();
- }
-
- /**
- * Check if All required fields of a Font Dictionary are present. If there are
- * some missing fields, this method returns false and the FontContainer is
- * updated.
- *
- * @return
- */
- protected boolean checkMandatoryFields() {
- String type = pFont.getBaseFont();
- String subtype = pFont.getSubType();
-
- if (this.pFontDesc == null) {
- this.fontContainer
- .addError(new ValidationError(ERROR_FONTS_FONT_FILEX_INVALID,
- "The FontDescriptor is missing, so the Font Program isn't embedded."));
- this.fontContainer.setFontProgramEmbedded(false);
- return false;
- }
-
- if ((type == null || "".equals(type))
- || (subtype == null || "".equals(subtype))) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID,
- "Type and/or Subtype keys are missing"));
- return false;
- } else {
- extractElementsToCheck();
- // ---- according to the subtype, the validation process isn't the same.
- return checkSpecificMandatoryFields();
- }
- }
-
- /**
- * This method checks the presence of some fields according to the Font type
- *
- * @return
- */
- protected abstract boolean checkSpecificMandatoryFields();
-
- /**
- * Check if the widths array contains integer and if its length is valid. If
- * the validation fails, the FontContainer is updated.
- *
- * @param cDoc
- */
- protected boolean checkWidthsArray(COSDocument cDoc) {
- if (widths == null) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID, "The Widths array is unreachable"));
- return false;
- }
-
- int expectedLength = (lastChar - firstChar) + 1;
- if (widths.size() != expectedLength) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID,
- "The length of Witdhs array is invalid. Expected : \""
- + expectedLength + "\" Current : \"" + widths.size() + "\""));
- return false;
- }
- return true;
- }
-
- protected boolean checkEncoding(COSDocument cDoc) {
- return true;
- }
-
- protected boolean checkToUnicode(COSDocument cDoc) {
- // Check the toUnicode -- Useless for PDF/A 1-b
- return true;
+public abstract class SimpleFontValidator <T extends FontContainer> extends FontValidator<T> {
+
+ public SimpleFontValidator(PreflightContext context, PDFont font, T fContainer) {
+ super(context, font, fContainer);
}
/**
- * This method checks the font descriptor dictionary and embedded font files.
- * If the FontDescriptor validation fails, the FontContainer is updated.
- *
- * @return
- */
- protected abstract boolean checkFontDescriptor() throws ValidationException;
+ * Call this method to validate the font wrapped by this object.
+ * If the validation failed, the error is updated in the FontContainer
+ * with the right error code.
+ *
+ * Errors that are saved in the container will be added on the PreflightContext if the font is used later.
+ *
+ * @return
+ */
+ public void validate() throws ValidationException {
+ checkMandatoryField();
- /**
- * Check if all required fields are present in the PDF file to describe the
- * Font Descriptor. If validation fails, FontConatiner is updated and false is
- * returned.
- */
- protected boolean checkFontDescriptorMandatoryFields() throws ValidationException {
- boolean fname = false, flags = false, itangle = false, cheight = false;
- boolean fbbox = false, asc = false, desc = false, stemv = false;
-
- if(pFontDesc instanceof PDFontDescriptorDictionary) {
- COSDictionary fDescriptor = ((PDFontDescriptorDictionary) pFontDesc).getCOSDictionary();
- for (Object key : fDescriptor.keySet()) {
- if (!(key instanceof COSName)) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
- "Invalid key in The font descriptor"));
- return false;
- }
-
- String cosName = ((COSName) key).getName();
- if (cosName.equals(FONT_DICTIONARY_KEY_FONTNAME)) {
- fname = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_FLAGS)) {
- flags = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_ITALICANGLE)) {
- itangle = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_CAPHEIGHT)) {
- cheight = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_FONTBBOX)) {
- fbbox = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_ASCENT)) {
- asc = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_DESCENT)) {
- desc = true;
- }
- if (cosName.equals(FONT_DICTIONARY_KEY_STEMV)) {
- stemv = true;
- }
- }
-
- if (!(fname && flags && itangle && cheight && fbbox && asc && desc && stemv)) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DESCRIPTOR_INVALID, "Some mandatory fields are missing"));
- return false;
- }
- } else if(pFontDesc instanceof PDFontDescriptorAFM) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DESCRIPTOR_INVALID, "Font Descriptor is missing"));
- return false;
- } else {
- throw new ValidationException("Invalid FontDescription object, expected PDFontDescriptorDictionary");
+ createFontDescriptorHelper();
+ processFontDescriptorValidation();
+
+ checkEncoding();
+ checkToUnicode();
+ }
+
+ protected void checkMandatoryField() {
+ COSDictionary fontDictionary = (COSDictionary)font.getCOSObject();
+ boolean areFieldsPResent = fontDictionary.containsKey(COSName.TYPE);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.SUBTYPE);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.BASE_FONT);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.FIRST_CHAR);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.LAST_CHAR);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.WIDTHS);
+
+ if (!areFieldsPResent) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Some required fields are missing from the Font dictionary."));
}
- return true;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * net.awl.edoc.pdfa.validation.font.FontValidator#validate(java.util.List)
- */
- public void validate() throws ValidationException {
- COSDocument cDoc = context.getDocument().getDocument();
- if (!checkMandatoryFields()) {
- return ;
- }
-
- boolean result = true;
- result = result && checkWidthsArray(cDoc);
- result = result && checkFontDescriptor();
- result = result && checkEncoding(cDoc);
- result = result && checkToUnicode(cDoc);
+ protected abstract void createFontDescriptorHelper();
+
+ protected void processFontDescriptorValidation() {
+ this.descriptorHelper.validate();
}
}
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontValidator.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontValidator.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/TrueTypeFontValidator.java Sat Jul 14 19:53:48 2012
@@ -21,245 +21,52 @@
package org.apache.pdfbox.preflight.font;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.fontbox.ttf.CMAPEncodingEntry;
-import org.apache.fontbox.ttf.CMAPTable;
-import org.apache.fontbox.ttf.TTFParser;
-import org.apache.fontbox.ttf.TrueTypeFont;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_ENCODING;
+
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.MacRomanEncoding;
import org.apache.pdfbox.encoding.WinAnsiEncoding;
-import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary;
-import org.apache.pdfbox.preflight.PreflightConstants;
+import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.preflight.PreflightContext;
-import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
-import org.apache.pdfbox.preflight.exception.ValidationException;
-
-public class TrueTypeFontValidator extends SimpleFontValidator {
-
-
- public TrueTypeFontValidator(PreflightContext context, PDFont font)
- throws ValidationException {
- super(context, font);
- }
-
- /**
- * Check if mandatory fields are present. Return false if a field is missing,
- * true otherwise. If validation fails, the FontContainer is updated.
- */
- protected boolean checkSpecificMandatoryFields() {
- // ---- name is required only in a PDF-1.0.
- // ---- Currently our grammar matches only with PDF-1.[1-4]
- // ---- BaseFont is required and is usually the FontName
- if (basefont == null || "".equals(basefont)) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID, "BaseFont is missing"));
- // continue to process this font dictionary is useless
- return false;
- }
-
- boolean allPresent = (firstChar >= 0 && lastChar >= 0 && widths != null);
- if (!allPresent) {
- this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Required keys are missing"));
- return false;
- } // else ok
-
+import org.apache.pdfbox.preflight.font.container.TrueTypeContainer;
+import org.apache.pdfbox.preflight.font.descriptor.TrueTypeDescriptorHelper;
- return true;
- }
+public class TrueTypeFontValidator extends SimpleFontValidator<TrueTypeContainer> {
- /*
- * (non-Javadoc)
- *
- * @see
- * net.awl.edoc.pdfa.validation.font.SimpleFontValidator#checkFontDescriptor()
- */
- @Override
- protected boolean checkFontDescriptor() throws ValidationException {
- boolean res = checkFontDescriptorMandatoryFields();
- res = res && checkFontName();
- res = res && checkFontFileElement();
- return res;
+ public TrueTypeFontValidator(PreflightContext context, PDFont font) {
+ super(context, font, new TrueTypeContainer(font));
}
-
- /**
- * If the FontName is missing from the FontDescriptor dictionary, this method
- * returns false and the FontContainer is updated.
- *
- * @return
- */
- protected boolean checkFontName() {
- String fontName = this.pFontDesc.getFontName();
- if (fontName == null) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_DESCRIPTOR_INVALID,
- "The FontName in font descriptor is null"));
- return false;
- }
- return true;
- }
-
- /**
- * This methods validates the Font Stream. If the font is damaged or missing
- * the FontContainer is updated and false is returned. Moreover, this method
- * checks the Encoding property of the FontDescriptor dictionary.
- *
- * @return
- */
- protected boolean checkFontFileElement() throws ValidationException {
- if (pFontDesc instanceof PDFontDescriptorDictionary) {
- PDStream ff1 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile();
- PDStream ff2 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile2();
- PDStream ff3 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile3();
- boolean onlyOne = (ff1 != null && ff2 == null && ff3 == null)
- || (ff1 == null && ff2 != null && ff3 == null)
- || (ff1 == null && ff2 == null && ff3 != null);
-
- if (ff2 == null || !onlyOne) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_FONT_FILEX_INVALID,
- "The FontFile2 is invalid"));
- return false;
- }
-
- // ---- Stream validation should be done by the StreamValidateHelper.
- // ---- Process font specific check
- COSStream stream = ff2.getStream();
- if (stream == null) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_FONT_FILEX_INVALID,
- "The FontFile is missing"));
- this.fontContainer.setFontProgramEmbedded(false);
- return false;
- }
-
- boolean hasLength1 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_LENGTH1)) > 0;
- if (!hasLength1) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_FONT_FILEX_INVALID,
- "The FontFile is invalid"));
- return false;
- }
-
- // ---- check the encoding part.
- if (pFontDesc.isNonSymbolic()) {
- // ---- only MacRomanEncoding or WinAnsiEncoding are allowed for a non
- // symbolic font
- Encoding encodingValue = this.pFont.getFontEncoding();
- if (encodingValue == null
- || !(encodingValue instanceof MacRomanEncoding || encodingValue instanceof WinAnsiEncoding)) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_ENCODING,
- "The Encoding is invalid for the NonSymbolic TTF"));
- return false;
+
+ protected void createFontDescriptorHelper() {
+ this.descriptorHelper = new TrueTypeDescriptorHelper(context, font, fontContainer);
+ }
+
+ protected void checkEncoding() {
+ PDFontDescriptor fd = this.font.getFontDescriptor();
+ if(fd != null) {
+ /*
+ * only MacRomanEncoding or WinAnsiEncoding are allowed for a non symbolic font.
+ */
+ if (fd.isNonSymbolic()) {
+ Encoding encodingValue = this.font.getFontEncoding();
+ if (encodingValue == null || !(encodingValue instanceof MacRomanEncoding || encodingValue instanceof WinAnsiEncoding)) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_ENCODING, "The Encoding is invalid for the NonSymbolic TTF"));
}
- } else if (pFontDesc.isSymbolic()) {
- // ---- For symbolic font, no encoding entry is allowed and only one
- // encoding entry is expected into the FontFile CMap
- if (((COSDictionary) this.pFont.getCOSObject()).getItem(COSName
- .getPDFName(FONT_DICTIONARY_KEY_ENCODING)) != null) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_ENCODING,
- "The Encoding should be missing for the Symbolic TTF"));
- return false;
- } // else check the content of the Font CMap (see below)
-
- } else {
- // ----- should never happen
- return true;
- }
+ }
/*
- * ---- 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)
+ * For symbolic font, no encoding entry is allowed and only one
+ * encoding entry is expected into the FontFile CMap (Check latter when
+ * the FontFile stream will be checked)
*/
- ByteArrayInputStream bis = null;
- try {
- bis = new ByteArrayInputStream(ff2.getByteArray());
- TrueTypeFont ttf = new TTFParser(true).parseTTF(bis);
- if (pFontDesc.isSymbolic() && ttf.getCMAP().getCmaps().length != 1) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_ENCODING,
- "The Encoding should be missing for the Symbolic TTF"));
- return false;
- }
-
- ((TrueTypeFontContainer)this.fontContainer).setFontObjectAndInitializeInnerFields(ttf);
- ((TrueTypeFontContainer)this.fontContainer).setCMap(getCMapOfFontProgram(ttf));
-
- return checkFontFileMetaData(pFontDesc, ff2);
- } catch (IOException e) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- PreflightConstants.ERROR_FONTS_TRUETYPE_DAMAGED,
- "The FontFile can't be read"));
- return false;
- } finally {
- if (bis != null) {
- IOUtils.closeQuietly(bis);
- }
- }
- } else {
- throw new ValidationException("Invalid FontDescription object, expected PDFontDescriptorDictionary");
- }
- }
-
- /**
- * Return the CMap encoding entry to use. This CMap belong to the TrueType
- * Font Program.
- *
- * Here the selection rules :
- * <UL>
- * <li>For a Symbolic TrueType, the Font Program has only one CMap (Checked in
- * the checkFontFileElement method)
- * <li>For a Non-Symbolic TrueType, only two CMap can be used (WinAnsi
- * (plateformId : 3 / encodingId : 1) or MacRoman (plateformId : 1 /
- * encodingId : 0) ). This CMap returns the CMap which corresponds to the
- * Encoding value of the FontDescriptor dictionary.
- * </UL>
- *
- * @param ttf
- * The FontBox object which manages a TrueType Font program.
- * @return
- * @throws ValidationException
- * if the FontProgram doesn't have the expected CMap
- */
- protected CMAPEncodingEntry[] getCMapOfFontProgram(TrueTypeFont ttf)
- throws ValidationException {
- CMAPTable cmap = ttf.getCMAP();
- if (this.pFontDesc.isSymbolic()) {
- return cmap.getCmaps();
- } else {
- List<CMAPEncodingEntry> res = new ArrayList<CMAPEncodingEntry>();
- boolean firstIs31 = false;
- for (CMAPEncodingEntry cmapEntry : cmap.getCmaps()) {
- // ---- Returns the WinAnsiEncoding CMap
- if ((cmapEntry.getPlatformId() == 3) && (cmapEntry.getPlatformEncodingId() == 1)) {
- res.add(0,cmapEntry);
- firstIs31 = true;
- } else if ((cmapEntry.getPlatformId() == 1)&& (cmapEntry.getPlatformEncodingId() == 0)) {
- if (firstIs31) {
- res.add(1, cmapEntry);
- } else {
- res.add(0, cmapEntry);
- }
- } else {
- res.add(cmapEntry);
- }
- }
- return res.toArray(new CMAPEncodingEntry[res.size()]);
+ if (fd.isSymbolic() &&
+ ((COSDictionary)this.font.getCOSObject()).getItem(COSName.ENCODING) != null) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_ENCODING, "The Encoding should be missing for the Symbolic TTF"));
+ }
}
}
}
Added: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java?rev=1361579&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java Sat Jul 14 19:53:48 2012
@@ -0,0 +1,295 @@
+/*****************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+package org.apache.pdfbox.preflight.font;
+
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_CIDKEYED_CMAP_INVALID_OR_MISSING;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_CIDKEYED_INVALID;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_CIDKEYED_SYSINFO;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_CID_CMAP_DAMAGED;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_DICTIONARY_INVALID;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_DEFAULT_CMAP_WMODE;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_KEY_CMAP_NAME;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_KEY_CMAP_USECMAP;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_KEY_CMAP_WMODE;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_CMAP_IDENTITY_H;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_CMAP_IDENTITY_V;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_TYPE0;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_TYPE2;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_TYPE_CMAP;
+
+import java.io.IOException;
+
+import org.apache.fontbox.cmap.CMap;
+import org.apache.fontbox.cmap.CMapParser;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSDocument;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType0Font;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType2Font;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.preflight.PreflightContext;
+import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.preflight.exception.ValidationException;
+import org.apache.pdfbox.preflight.font.container.FontContainer;
+import org.apache.pdfbox.preflight.font.container.Type0Container;
+import org.apache.pdfbox.preflight.utils.COSUtils;
+
+public class Type0FontValidator extends FontValidator<Type0Container> {
+
+ protected COSDocument cosDocument = null;
+
+ public Type0FontValidator(PreflightContext context, PDFont font) {
+ super(context, font, new Type0Container(font));
+ cosDocument = this.context.getDocument().getDocument();
+ }
+
+ @Override
+ public void validate() throws ValidationException {
+ checkMandatoryFields();
+
+ processDescendantFont();
+
+ checkEncoding();
+ checkToUnicode();
+ }
+
+ /**
+ * This methods extracts from the Font dictionary all mandatory fields. If a
+ * mandatory field is missing, the list of ValidationError in the
+ * FontContainer is updated.
+ */
+ protected void checkMandatoryFields() {
+ COSDictionary fontDictionary = (COSDictionary)font.getCOSObject();
+ boolean areFieldsPResent = fontDictionary.containsKey(COSName.TYPE);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.SUBTYPE);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.BASE_FONT);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.DESCENDANT_FONTS);
+ areFieldsPResent &= fontDictionary.containsKey(COSName.ENCODING);
+
+ if (!areFieldsPResent) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Some keys are missing from composite font dictionary"));
+ }
+ }
+
+ /**
+ * Extract the single CIDFont from the Descendant array.
+ * Create a FontValidator for this CODFont and launch its validation.
+ */
+ protected void processDescendantFont() throws ValidationException {
+ COSDictionary fontDictionary = (COSDictionary)font.getCOSObject();
+ // a CIDFont is contained in the DescendantFonts array
+ COSArray array = COSUtils.getAsArray(fontDictionary.getItem(COSName.DESCENDANT_FONTS), cosDocument);
+ if (array == null || array.size() != 1) {
+ /*
+ * in PDF 1.4, this array must contain only one element,
+ * because of a PDF/A should be a PDF 1.4, this method
+ * returns an error if the array has more than one element.
+ */
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "CIDFont is missing from the DescendantFonts array or the size of array is greater than 1"));
+ return;
+ }
+
+ COSDictionary cidFont = COSUtils.getAsDictionary(array.get(0), cosDocument);
+ if (cidFont == null) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "The DescendantFonts array should have one element with is a dictionary."));
+ return;
+ }
+
+ FontValidator<? extends FontContainer> cidFontValidator = createDescendantValidator(cidFont);
+ if (cidFontValidator != null) {
+ this.fontContainer.setDelegateFontContainer(cidFontValidator.getFontContainer());
+ cidFontValidator.validate();
+ }
+ }
+
+ protected FontValidator<? extends FontContainer> createDescendantValidator(COSDictionary cidFont) {
+ String subtype = cidFont.getNameAsString(COSName.SUBTYPE);
+ FontValidator<? extends FontContainer> cidFontValidator = null;
+ if (FONT_DICTIONARY_VALUE_TYPE0.equals(subtype)) {
+ cidFontValidator = createCIDType0FontValidator(cidFont);
+ } else if (FONT_DICTIONARY_VALUE_TYPE2.equals(subtype)) {
+ cidFontValidator = createCIDType2FontValidator(cidFont);
+ } else {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Type and/or Subtype keys are missing"));
+ }
+ return cidFontValidator;
+ }
+
+ /**
+ * Create the validation object for CIDType0 Font
+ * @return
+ */
+ protected FontValidator<? extends FontContainer> createCIDType0FontValidator(COSDictionary fDict) {
+ return new CIDType0FontValidator(context, new PDCIDFontType0Font(fDict));
+ }
+
+ /**
+ * Create the validation object for CIDType2 Font
+ * @return
+ */
+ protected FontValidator<? extends FontContainer> createCIDType2FontValidator(COSDictionary fDict) {
+ return new CIDType2FontValidator(context, new PDCIDFontType2Font(fDict));
+ }
+
+ /**
+ * Check the CMap entry.
+ *
+ * The CMap entry must be a dictionary in a PDF/A. This entry can be a String
+ * only if the String value is Identity-H or Identity-V
+ *
+ * @param encoding
+ */
+ protected void checkEncoding() {
+ COSBase encoding = ((COSDictionary)font.getCOSObject()).getItem(COSName.ENCODING);
+ checkCMapEncoding(encoding);
+ }
+
+ protected void checkCMapEncoding(COSBase encoding) {
+ if (COSUtils.isString(encoding, cosDocument)) {
+ // if encoding is a string, only 2 values are allowed
+ String str = COSUtils.getAsString(encoding, cosDocument);
+ if (!(FONT_DICTIONARY_VALUE_CMAP_IDENTITY_V.equals(str) || FONT_DICTIONARY_VALUE_CMAP_IDENTITY_H.equals(str))) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "The CMap is a string but it isn't an Identity-H/V"));
+ return;
+ }
+ } else if (COSUtils.isStream(encoding, cosDocument)) {
+ /*
+ * If the CMap is a stream, some fields are mandatory
+ * and the CIDSytemInfo must be compared with the CIDSystemInfo
+ * entry of the CIDFont.
+ */
+ processCMapAsStream(COSUtils.getAsStream(encoding, cosDocument));
+ } else {
+ // CMap type is invalid
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CMAP_INVALID_OR_MISSING, "The CMap type is invalid"));
+ }
+ }
+
+ /**
+ * Standard information of a stream element will be checked by the StreamValidationProcess.
+ *
+ * This method checks mandatory fields of the CMap stream. This method checks
+ * too if the CMap stream is damaged using the CMapParser of the fontbox api.
+ *
+ * @param aCMap
+ * @return
+ */
+ private void processCMapAsStream(COSStream aCMap) {
+
+ COSBase sysinfo = aCMap.getItem(COSName.CIDSYSTEMINFO);
+ checkCIDSystemInfo(sysinfo);
+
+ try {
+ // extract information from the CMap stream
+ CMap fontboxCMap = new CMapParser().parse(null, aCMap.getUnfilteredStream());
+ int wmValue = fontboxCMap.getWMode();
+ String cmnValue = fontboxCMap.getName();
+
+ /*
+ * According to the getInt javadoc, -1 is returned if there are no result.
+ * In the PDF Reference v1.7 p449, we can read that Default value is 0.
+ */
+ int wmode = aCMap.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_CMAP_WMODE), FONT_DICTIONARY_DEFAULT_CMAP_WMODE);
+ String type = aCMap.getNameAsString(COSName.TYPE);
+ String cmapName = aCMap.getNameAsString(COSName.getPDFName(FONT_DICTIONARY_KEY_CMAP_NAME));
+
+ if (cmapName == null || "".equals(cmapName) || wmode > 1) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CMAP_INVALID_OR_MISSING, "Some elements in the CMap dictionary are missing or invalid"));
+ } else if (!(wmValue == wmode && cmnValue.equals(cmapName))) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CMAP_INVALID_OR_MISSING, "CMapName or WMode is inconsistent"));
+ } else if (!FONT_DICTIONARY_VALUE_TYPE_CMAP.equals(type)) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_CMAP_INVALID_OR_MISSING, "The CMap type is invalid"));
+ }
+ } catch (IOException e) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CID_CMAP_DAMAGED, "The CMap type is damaged"));
+ }
+
+ COSDictionary cmapUsed = (COSDictionary)aCMap.getDictionaryObject(COSName.getPDFName(FONT_DICTIONARY_KEY_CMAP_USECMAP));
+ if (cmapUsed != null) {
+ checkCMapEncoding(cmapUsed);
+ }
+ compareCIDSystemInfo(aCMap);
+ }
+
+ /**
+ * Check the content of the CIDSystemInfo dictionary. A CIDSystemInfo dictionary must contain :
+ * <UL>
+ * <li>a Name - Registry
+ * <li>a Name - Ordering
+ * <li>a Integer - Supplement
+ * </UL>
+ *
+ * @param sysinfo
+ * @return
+ */
+ protected boolean checkCIDSystemInfo(COSBase sysinfo) {
+ boolean result = true;
+ COSDictionary cidSysInfo = COSUtils.getAsDictionary(sysinfo, cosDocument);
+
+ if (cidSysInfo != null) {
+ COSBase reg = cidSysInfo.getItem(COSName.REGISTRY);
+ COSBase ord = cidSysInfo.getItem(COSName.ORDERING);
+ COSBase sup = cidSysInfo.getItem(COSName.SUPPLEMENT);
+
+ if (!(COSUtils.isString(reg, cosDocument) && COSUtils.isString(ord, cosDocument) && COSUtils.isInteger(sup, cosDocument))) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_SYSINFO));
+ result = false;
+ }
+
+ } else {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_SYSINFO));
+ result = false;
+ }
+ return result;
+ }
+
+ /**
+ * The CIDSystemInfo must have the same Registry and Ordering for CMap and
+ * CIDFont. This control is useless if CMap is Identity-H or Identity-V so
+ * this method is called by the checkCMap method.
+ *
+ * @param cmap
+ * @return
+ */
+ private void compareCIDSystemInfo(COSDictionary cmap) {
+ COSDictionary fontDictionary = (COSDictionary)font.getCOSObject();
+ COSArray array = COSUtils.getAsArray(fontDictionary.getItem(COSName.DESCENDANT_FONTS), cosDocument);
+
+ if (array != null && array.size() > 0) {
+ COSDictionary cidFont = COSUtils.getAsDictionary(array.get(0), cosDocument);
+ COSDictionary cmsi = COSUtils.getAsDictionary(cmap.getItem(COSName.CIDSYSTEMINFO), cosDocument);
+ COSDictionary cfsi = COSUtils.getAsDictionary(cidFont.getItem(COSName.CIDSYSTEMINFO), cosDocument);
+
+ String regCM = COSUtils.getAsString(cmsi.getItem(COSName.REGISTRY), cosDocument);
+ String ordCM = COSUtils.getAsString(cmsi.getItem(COSName.ORDERING), cosDocument);
+ String regCF = COSUtils.getAsString(cfsi.getItem(COSName.REGISTRY), cosDocument);
+ String ordCF = COSUtils.getAsString(cfsi.getItem(COSName.ORDERING), cosDocument);
+
+ if (!regCF.equals(regCM) || !ordCF.equals(ordCM)) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_CIDKEYED_SYSINFO, "The CIDSystemInfo is inconsistent"));
+ }
+ }
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type0FontValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontValidator.java?rev=1361579&r1=1361578&r2=1361579&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontValidator.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/Type1FontValidator.java Sat Jul 14 19:53:48 2012
@@ -21,269 +21,52 @@
package org.apache.pdfbox.preflight.font;
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.List;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_ENCODING;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_ENCODING_MAC;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_ENCODING_MAC_EXP;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_ENCODING_PDFDOC;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_ENCODING_STD;
+import static org.apache.pdfbox.preflight.PreflightConstants.FONT_DICTIONARY_VALUE_ENCODING_WIN;
-import org.apache.commons.io.IOUtils;
-import org.apache.fontbox.cff.CFFFont;
-import org.apache.fontbox.cff.CFFParser;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary;
import org.apache.pdfbox.preflight.PreflightContext;
-import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
-import org.apache.pdfbox.preflight.exception.ValidationException;
-import org.apache.pdfbox.preflight.font.type1.Type1;
-import org.apache.pdfbox.preflight.font.type1.Type1Parser;
+import org.apache.pdfbox.preflight.font.container.Type1Container;
+import org.apache.pdfbox.preflight.font.descriptor.Type1DescriptorHelper;
import org.apache.pdfbox.preflight.utils.COSUtils;
-public class Type1FontValidator extends SimpleFontValidator {
-
- public Type1FontValidator(PreflightContext context, PDFont font)
- throws ValidationException {
- super(context, font);
- }
-
- /*
- * (non-Javadoc)
- *
- * @seenet.awl.edoc.pdfa.validation.font.SimpleFontValidator#
- * checkSpecificMandatoryFields()
- */
- protected boolean checkSpecificMandatoryFields() {
- // ---- name is required only in a PDF-1.0.
- // ---- Currently our grammar matches only with PDF-1.[1-4]
- // ---- baseFont is required and is usually the FontName
- if (basefont == null || "".equals(basefont)) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID, "BaseFont is missing"));
- return false;
- }
-
- boolean allPresent = (firstChar >= 0 && lastChar >= 0 && widths != null);
- if (!allPresent) {
- this.fontContainer.addError(new ValidationError(
- ERROR_FONTS_DICTIONARY_INVALID, "Required keys are missing"));
- return false;
- }
- // else
- // ---- Event if the Font is one of the 14 standard Fonts, those keys are
- // mandatory for a PDF/A
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * net.awl.edoc.pdfa.validation.font.SimpleFontValidator#checkEncoding(org
- * .apache.pdfbox.cos.COSDocument)
- */
- protected boolean checkEncoding() {
- COSBase encoding = ((COSDictionary)pFont.getCOSObject()).getItem(COSName.ENCODING);
- if (COSUtils.isString(encoding, cosDocument)) {
- String encodingName = COSUtils.getAsString(encoding, cosDocument);
- if (!(encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_MAC)
- || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_MAC_EXP)
- || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_WIN)
- || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_PDFDOC) || encodingName
- .equals(FONT_DICTIONARY_VALUE_ENCODING_STD))) {
- this.fontContainer.addError(new ValidationError(ERROR_FONTS_ENCODING));
- return false;
- }
- } else if (COSUtils.isDictionary(encoding, cosDocument)) {
- this.pFont.getFontEncoding();
- } else if (encoding != null) {
- this.fontContainer.addError(new ValidationError(ERROR_FONTS_ENCODING));
- return false;
- }
- //else
- // ---- According to PDF Reference, the encoding entry is optional.
- // PDF/A specification only speaks of TrueType encoding
-
- return true;
+public class Type1FontValidator extends SimpleFontValidator<Type1Container> {
+
+ public Type1FontValidator(PreflightContext context, PDFont font) {
+ super(context, font, new Type1Container(font));
}
- /*
- * (non-Javadoc)
- *
- * @see
- * net.awl.edoc.pdfa.validation.font.SimpleFontValidator#checkFontDescriptor()
- */
@Override
- protected boolean checkFontDescriptor() throws ValidationException {
- boolean res = checkFontDescriptorMandatoryFields();
- res = res && checkFontName();
- res = res && checkFontFileElement();
- return res;
+ protected void createFontDescriptorHelper() {
+ this.descriptorHelper = new Type1DescriptorHelper(context, font, fontContainer);
}
- /**
- * Check if the font name is present and if fontName equals to the baseName.
- * If the validation fails, false is returned and the FontContainer is
- * updated.
- *
- * @return
- */
- boolean checkFontName() {
- String fontName = this.pFontDesc.getFontName();
- if (fontName == null) {
- this.fontContainer
- .addError(new ValidationResult.ValidationError(ERROR_FONTS_DESCRIPTOR_INVALID,
- "The FontName in font descriptor isn't the same as the BaseFont in the Font dictionary"));
- return false;
- }
-
- return true;
- }
-
- /**
- * This methods validates the Font Stream, if the font program is damaged or
- * missing the FontContainer is updated and false is returned.
- *
- * @throws ValidationException
- */
- protected boolean checkFontFileElement() throws ValidationException {
- // ---- if the this font is a Subset, the CharSet entry must be present in
- // the FontDescriptor
- if (isSubSet(pFontDesc.getFontName())) {
- String charsetStr = pFontDesc.getCharSet();
- if (charsetStr == null || "".equals(charsetStr)) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_CHARSET_MISSING_FOR_SUBSET,
- "The Charset entry is missing for the Type1 Subset"));
- return false;
- }
- }
-
- // ---- FontFile Validation
- if (pFontDesc instanceof PDFontDescriptorDictionary) {
- PDStream ff1 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile();
- PDStream ff2 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile2();
- PDStream ff3 = ((PDFontDescriptorDictionary)pFontDesc).getFontFile3();
- boolean onlyOne = (ff1 != null && ff2 == null && ff3 == null)
- || (ff1 == null && ff2 != null && ff3 == null)
- || (ff1 == null && ff2 == null && ff3 != null);
-
- if ((ff1 == null && (ff3 == null || !"Type1C".equals(((COSDictionary)ff3.getCOSObject()).getNameAsString(COSName.SUBTYPE)))) || !onlyOne) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is invalid"));
- return false;
- }
-
- if (ff1 != null) {
- COSStream stream = ff1.getStream();
- if (stream == null) {
- this.fontContainer.addError(new ValidationResult.ValidationError(ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is missing"));
- this.fontContainer.setFontProgramEmbedded(false);
- return false;
+ protected void checkEncoding() {
+ COSBase encoding = ((COSDictionary)font.getCOSObject()).getItem(COSName.ENCODING);
+ if (encoding != null) {
+ COSDocument cosDocument = context.getDocument().getDocument();
+ if (COSUtils.isString(encoding, cosDocument)) {
+ String encodingName = COSUtils.getAsString(encoding, cosDocument);
+ if (!(encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_MAC)
+ || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_MAC_EXP)
+ || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_WIN)
+ || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_PDFDOC)
+ || encodingName.equals(FONT_DICTIONARY_VALUE_ENCODING_STD))) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_ENCODING));
}
-
- boolean hasLength1 = stream.getInt(COSName.getPDFName(FONT_DICTIONARY_KEY_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.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_FONT_FILEX_INVALID, "The FontFile is invalid"));
- return false;
- }
-
- // ---- Stream validation should be done by the StreamValidateHelper.
- // ---- Process font specific check
- // ---- try to load the font using the java.awt.font object.
- // ---- if the font is invalid, an exception will be thrown
- ByteArrayInputStream bis = null;
- try {
- bis = new ByteArrayInputStream(ff1.getByteArray());
- Font.createFont(Font.TYPE1_FONT, bis);
- return checkFontMetricsDataAndFeedFontContainer(ff1) && checkFontFileMetaData(pFontDesc, ff1);
- } catch (IOException e) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_TYPE1_DAMAGED, "The FontFile can't be read"));
- return false;
- } catch (FontFormatException e) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_TYPE1_DAMAGED, "The FontFile is damaged"));
- return false;
- } finally {
- if (bis != null) {
- IOUtils.closeQuietly(bis);
- }
- }
- } else {
- return checkCIDFontWidths(ff3) && checkFontFileMetaData(pFontDesc, ff3);
- }
- } else {
- throw new ValidationException("Invalid FontDescription object, expected PDFontDescriptorDictionary");
- }
- }
-
- /**
- * Type1C is a CFF font format, extract all CFFFont object from the stream
- *
- * @param fontStream
- * @return
- * @throws ValidationException
- */
- protected boolean checkCIDFontWidths(PDStream fontStream)
- throws ValidationException {
- try {
- CFFParser cffParser = new CFFParser();
- List<CFFFont> lCFonts = cffParser.parse(fontStream.getByteArray());
-
- if (lCFonts == null || lCFonts.isEmpty()) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
- return false;
- }
-
- ((Type1FontContainer)this.fontContainer).setCFFFontObjects(lCFonts);
-
- return true;
- } catch (IOException e) {
- this.fontContainer.addError(new ValidationResult.ValidationError(
- ERROR_FONTS_CID_DAMAGED, "The FontFile can't be read"));
- return false;
- }
- }
- /**
- * This method checks the metric consistency and adds the FontContainer in the
- * DocumentHandler.
- *
- * @param fontStream
- * @return
- * @throws ValidationException
- */
- protected boolean checkFontMetricsDataAndFeedFontContainer(PDStream fontStream)
- throws ValidationException {
- try {
-
- // ---- Parse the Type1 Font program
- ByteArrayInputStream bis = new ByteArrayInputStream(fontStream
- .getByteArray());
- COSStream streamObj = fontStream.getStream();
- int length1 = streamObj.getInt(COSName
- .getPDFName(FONT_DICTIONARY_KEY_LENGTH1));
- int length2 = streamObj.getInt(COSName
- .getPDFName(FONT_DICTIONARY_KEY_LENGTH2));
-
- Type1Parser parserForMetrics = Type1Parser.createParserWithEncodingObject(bis, length1, length2, pFont.getFontEncoding());
- Type1 parsedData = parserForMetrics.parse();
-
- ((Type1FontContainer)this.fontContainer).setFontObject(parsedData);
-
- return true;
- } catch (IOException e) {
- throw new ValidationException("Unable to check Type1 metrics due to : "
- + e.getMessage(), e);
- }
+ } else if (!COSUtils.isDictionary(encoding, cosDocument)) {
+ this.fontContainer.push(new ValidationError(ERROR_FONTS_ENCODING));
+ }
+ }
}
+
}