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 2011/07/24 16:02:33 UTC
svn commit: r1150373 [4/12] - in /pdfbox/trunk/preflight: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/padaf/ src/main/java/org/apache/padaf/preflight/
src/main/java/org/apache/padaf/preflight/a...
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/SquareCircleAnnotationValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/SquareCircleAnnotationValidator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/SquareCircleAnnotationValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/SquareCircleAnnotationValidator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.annotation;
+
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_F;
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_RECT;
+import static org.apache.padaf.preflight.ValidationConstants.DICTIONARY_KEY_SUBTYPE;
+
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle;
+
+/**
+ * Validation class for the Square/Circle Annotation
+ */
+public class SquareCircleAnnotationValidator extends AnnotationValidator {
+ /**
+ * PDFBox object which wraps the annotation dictionary
+ */
+ protected PDAnnotationSquareCircle pdSquareCircle = null;
+
+ public SquareCircleAnnotationValidator(DocumentHandler handler,
+ COSDictionary annotDictionary) {
+ super(handler, annotDictionary);
+ this.pdSquareCircle = new PDAnnotationSquareCircle(annotDictionary);
+ this.pdAnnot = this.pdSquareCircle;
+ }
+
+ /**
+ * In addition of the AnnotationValidator.validate() method, this method
+ * executes the the checkIColors method.
+ *
+ * @see org.apache.padaf.preflight.annotation.AnnotationValidator#validate(java.util.List)
+ */
+ @Override
+ public boolean validate(List<ValidationError> errors)
+ throws ValidationException {
+ boolean isValide = super.validate(errors);
+ isValide = isValide && checkIColors(errors);
+ return isValide;
+ }
+
+ /**
+ * Return true if the IC field is present in the Annotation dictionary and if
+ * the RGB profile is used in the DestOutputProfile of the OutputIntent
+ * dictionary.
+ *
+ * @param errors
+ * list of errors with is updated if no RGB profile is found when the
+ * IC element is present
+ * @return
+ */
+ protected boolean checkIColors(List<ValidationError> errors) {
+ if (this.pdSquareCircle.getInteriorColour() != null) {
+ if (!searchRGBProfile()) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_FORBIDDEN_COLOR,"Annotation uses a Color profile which isn't the same than the profile contained by the OutputIntent"));
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.awl.edoc.pdfa.validation.annotation.AnnotationValidator#
+ * checkMandatoryFields(java.util.List)
+ */
+ protected boolean checkMandatoryFields(List<ValidationError> errors) {
+ boolean subtype = false;
+ boolean rect = false;
+ boolean f = false;
+
+ for (Object key : this.annotDictionary.keySet()) {
+ if (!(key instanceof COSName)) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+ "Invalid key in The Annotation dictionary"));
+ return false;
+ }
+
+ String cosName = ((COSName) key).getName();
+ if (cosName.equals(DICTIONARY_KEY_SUBTYPE)) {
+ subtype = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_RECT)) {
+ rect = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_F)) {
+ f = true;
+ }
+ }
+
+ /*
+ * ---- After PDF 1.4, all additional entries in this annotation are
+ * optional and they seem to be compatible with the PDF/A specification.
+ */
+ boolean result = (subtype && rect && f);
+ if (!result) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_MISSING_FIELDS));
+ }
+ return result;
+ }
+
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/SquareCircleAnnotationValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TextAnnotationValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TextAnnotationValidator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TextAnnotationValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TextAnnotationValidator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.annotation;
+
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_CONTENTS;
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_F;
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_RECT;
+import static org.apache.padaf.preflight.ValidationConstants.DICTIONARY_KEY_SUBTYPE;
+
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText;
+
+/**
+ * Validation class for Text Annotation
+ */
+public class TextAnnotationValidator extends AnnotationValidator {
+ /**
+ * PDFBox object which wraps the annotation dictionary
+ */
+ protected PDAnnotationText pdText = null;
+
+ public TextAnnotationValidator(DocumentHandler handler,
+ COSDictionary annotDictionary) {
+ super(handler, annotDictionary);
+ this.pdText = new PDAnnotationText(annotDictionary);
+ this.pdAnnot = this.pdText;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.awl.edoc.pdfa.validation.annotation.AnnotationValidator#checkFlags(
+ * java.util.List)
+ */
+ protected boolean checkFlags(List<ValidationError> errors) {
+ // ---- call common flags settings
+ boolean result = super.checkFlags(errors);
+
+ // ---- For Text Annotation, this two flags should be set to avoid potential
+ // ambiguity between the annotation dictionary and the reader behavior.
+ result = result && this.pdAnnot.isNoRotate();
+ result = result && this.pdAnnot.isNoZoom();
+ if (!result) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_NOT_RECOMMENDED_FLAG));
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.awl.edoc.pdfa.validation.annotation.AnnotationValidator#
+ * checkMandatoryFields(java.util.List)
+ */
+ protected boolean checkMandatoryFields(List<ValidationError> errors) {
+ boolean subtype = false;
+ boolean rect = false;
+ boolean f = false;
+ boolean contents = false;
+
+ for (Object key : this.annotDictionary.keySet()) {
+ if (!(key instanceof COSName)) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+ "Invalid key in The Annotation dictionary"));
+ return false;
+ }
+
+ String cosName = ((COSName) key).getName();
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_RECT)) {
+ rect = true;
+ }
+ if (cosName.equals(DICTIONARY_KEY_SUBTYPE)) {
+ subtype = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_F)) {
+ f = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_CONTENTS)) {
+ contents = true;
+ }
+ }
+
+ /*
+ * ---- Since PDF 1.5, two optional entries are possible. These new entries
+ * seem to e compatible with the PDF/A specification (used to set a State to
+ * the annotation - ex : rejected, reviewed...)
+ */
+ boolean result = (subtype && rect && f && contents);
+ if (!result) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_MISSING_FIELDS));
+ }
+ return result;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TextAnnotationValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TrapNetAnnotationValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TrapNetAnnotationValidator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TrapNetAnnotationValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TrapNetAnnotationValidator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.annotation;
+
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_F;
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_RECT;
+import static org.apache.padaf.preflight.ValidationConstants.DICTIONARY_KEY_SUBTYPE;
+
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationUnknown;
+
+/**
+ * Validation class for the TrapNet annotation
+ */
+public class TrapNetAnnotationValidator extends AnnotationValidator {
+ /**
+ * PDFBox object which wraps the annotation dictionary
+ */
+ protected PDAnnotationUnknown pdUnk = null;
+
+ public TrapNetAnnotationValidator(DocumentHandler handler,
+ COSDictionary annotDictionary) {
+ super(handler, annotDictionary);
+ this.pdUnk = new PDAnnotationUnknown(annotDictionary);
+ this.pdAnnot = this.pdUnk;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.awl.edoc.pdfa.validation.annotation.AnnotationValidator#
+ * checkMandatoryFields(java.util.List)
+ */
+ protected boolean checkMandatoryFields(List<ValidationError> errors) {
+ boolean subtype = false;
+ boolean rect = false;
+ boolean f = false;
+
+ for (Object key : this.annotDictionary.keySet()) {
+ if (!(key instanceof COSName)) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+ "Invalid key in The Annotation dictionary"));
+ return false;
+ }
+
+ String cosName = ((COSName) key).getName();
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_RECT)) {
+ rect = true;
+ }
+ if (cosName.equals(DICTIONARY_KEY_SUBTYPE)) {
+ subtype = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_F)) {
+ f = true;
+ }
+ }
+
+ boolean result = (subtype && rect && f);
+ if (!result) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_MISSING_FIELDS));
+ }
+ return result;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/TrapNetAnnotationValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/WidgetAnnotationValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/WidgetAnnotationValidator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/WidgetAnnotationValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/WidgetAnnotationValidator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.annotation;
+
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_F;
+import static org.apache.padaf.preflight.ValidationConstants.ANNOT_DICTIONARY_KEY_RECT;
+import static org.apache.padaf.preflight.ValidationConstants.DICTIONARY_KEY_SUBTYPE;
+
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+
+/**
+ * Validation class for the Widget Annotation
+ */
+public class WidgetAnnotationValidator extends AnnotationValidator {
+ /**
+ * PDFBox object which wraps the annotation dictionary
+ */
+ protected PDAnnotationWidget pdWidget = null;
+
+ public WidgetAnnotationValidator(DocumentHandler handler,
+ COSDictionary annotDictionary) {
+ super(handler, annotDictionary);
+ this.pdWidget = new PDAnnotationWidget(annotDictionary);
+ this.pdAnnot = this.pdWidget;
+ }
+
+ /**
+ * In addition of the AnnotationValidator.validate() method, this method
+ * executes the the checkAAField method.
+ *
+ * @see org.apache.padaf.preflight.annotation.AnnotationValidator#validate(java.util.List)
+ */
+ @Override
+ public boolean validate(List<ValidationError> errors)
+ throws ValidationException {
+ boolean isValide = super.validate(errors);
+ isValide = isValide && checkAAField(errors);
+ return isValide;
+ }
+
+ /**
+ * The AA field is forbidden for the Widget annotation when the PDF is a
+ * PDF/A. This method return false and update the errors list if this key is
+ * present. returns true otherwise
+ *
+ * @param errors
+ * @return
+ */
+ protected boolean checkAAField(List<ValidationError> errors) {
+ if (this.pdWidget.getActions() != null) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_FORBIDDEN_AA));
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.awl.edoc.pdfa.validation.annotation.AnnotationValidator#
+ * checkMandatoryFields(java.util.List)
+ */
+ protected boolean checkMandatoryFields(List<ValidationError> errors) {
+ boolean subtype = false;
+ boolean rect = false;
+ boolean f = false;
+
+ for (Object key : this.annotDictionary.keySet()) {
+ if (!(key instanceof COSName)) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+ "Invalid key in The Annotation dictionary"));
+ return false;
+ }
+
+ String cosName = ((COSName) key).getName();
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_RECT)) {
+ rect = true;
+ }
+ if (cosName.equals(DICTIONARY_KEY_SUBTYPE)) {
+ subtype = true;
+ }
+ if (cosName.equals(ANNOT_DICTIONARY_KEY_F)) {
+ f = true;
+ }
+ }
+
+ boolean result = (subtype && rect && f);
+ if (!result) {
+ errors.add(new ValidationResult.ValidationError(
+ ValidationConstants.ERROR_ANNOT_MISSING_FIELDS));
+ }
+ return result;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/annotation/WidgetAnnotationValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamException.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamException.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamException.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamException.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.contentstream;
+
+import java.io.IOException;
+
+/**
+ * This exception inherits from the IOException to be thrown by classes which
+ * inherit from org.apache.pdfbox.util.PDFStreamEngine.
+ *
+ * This exception contains a validationError code.
+ */
+public class ContentStreamException extends IOException {
+ private String validationError = "";
+
+ public ContentStreamException() {
+ super();
+ }
+
+ public ContentStreamException(String arg0, Throwable arg1) {
+ super(arg0);
+ }
+
+ public ContentStreamException(String arg0) {
+ super(arg0);
+ }
+
+ public ContentStreamException(Throwable arg0) {
+ super(arg0.getMessage());
+ }
+
+ /**
+ * @return the validationError
+ */
+ public String getValidationError() {
+ return validationError;
+ }
+
+ /**
+ * @param validationError
+ * the validationError to set
+ */
+ public void setValidationError(String validationError) {
+ this.validationError = validationError;
+ }
+
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,365 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.contentstream;
+
+import static org.apache.padaf.preflight.ValidationConstants.DICTIONARY_KEY_RESOURCES;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_FONTS_ENCODING_ERROR;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_FONTS_FONT_FILEX_INVALID;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_FONTS_UNKNOWN_FONT_REF;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_CONTENT_STREAM_UNSUPPORTED_OP;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.font.AbstractFontContainer;
+import org.apache.padaf.preflight.font.GlyphException;
+import org.apache.padaf.preflight.font.AbstractFontContainer.State;
+import org.apache.padaf.preflight.utils.ContentStreamEngine;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.graphics.PDGraphicsState;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.pdmodel.text.PDTextState;
+import org.apache.pdfbox.util.PDFOperator;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+public class ContentStreamWrapper extends ContentStreamEngine {
+
+ public ContentStreamWrapper(DocumentHandler handler) {
+ super(handler);
+ }
+
+ /**
+ * Process the validation of a PageContent (The page is initialized by the
+ * constructor)
+ *
+ * @return A list of validation error. This list is empty if the validation
+ * succeed.
+ * @throws ValidationException.
+ */
+ public List<ValidationError> validPageContentStream(PDPage page)
+ throws ValidationException {
+ List<ValidationError> errors = new ArrayList<ValidationError>();
+
+ try {
+ PDStream pstream = page.getContents();
+ if (pstream != null) {
+ processStream(page, page.findResources(), pstream.getStream());
+ }
+ } catch (ContentStreamException e) {
+ errors.add(new ValidationError(e.getValidationError(), e.getMessage()));
+ } catch (IOException e) {
+ throw new ValidationException("Unable to check the ContentStream : "
+ + e.getMessage(), e);
+ }
+
+ return errors;
+ }
+
+ /**
+ * Process the validation of a XObject Form
+ *
+ * @param xobj
+ * @return A list of validation error. This list is empty if the validation
+ * succeed.
+ * @throws ValidationException
+ */
+ public List<ValidationError> validXObjContentStream(PDXObjectForm xobj)
+ throws ValidationException {
+ List<ValidationError> errors = new ArrayList<ValidationError>();
+
+ try {
+ resetEnginContext();
+ processSubStream(null, xobj.getResources(), xobj.getCOSStream());
+ } catch (ContentStreamException e) {
+ errors.add(new ValidationError(e.getValidationError(), e.getMessage()));
+ } catch (IOException e) {
+ throw new ValidationException("Unable to check the ContentStream : "
+ + e.getMessage(), e);
+ }
+
+ return errors;
+ }
+
+ /**
+ * Process the validation of a Tiling Pattern
+ *
+ * @param pattern
+ * @return A list of validation error. This list is empty if the validation
+ * succeed.
+ * @throws ValidationException
+ */
+ public List<ValidationError> validPatternContentStream(COSStream pattern)
+ throws ValidationException {
+ List<ValidationError> errors = new ArrayList<ValidationError>();
+
+ try {
+ COSDictionary res = (COSDictionary) pattern
+ .getDictionaryObject(DICTIONARY_KEY_RESOURCES);
+ resetEnginContext();
+ processSubStream(null, new PDResources(res), pattern);
+ } catch (ContentStreamException e) {
+ errors.add(new ValidationError(e.getValidationError(), e.getMessage()));
+ } catch (IOException e) {
+ throw new ValidationException("Unable to check the ContentStream : "
+ + e.getMessage(), e);
+ }
+
+ return errors;
+ }
+
+ public final void resetEnginContext() {
+ this.setGraphicsState(new PDGraphicsState());
+ this.setTextMatrix(null);
+ this.setTextLineMatrix(null);
+ this.getGraphicsStack().clear();
+ // this.streamResourcesStack.clear();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.pdfbox.util.PDFStreamEngine#processOperator(org.apache.pdfbox
+ * .util.PDFOperator, java.util.List)
+ */
+ protected void processOperator(PDFOperator operator, List arguments)
+ throws IOException {
+
+ // ---- Here is a copy of the super method because the else block is
+ // different. (If the operator is unknown, throw an exception)
+ String operation = operator.getOperation();
+ OperatorProcessor processor = (OperatorProcessor) contentStreamEngineOperators.get(operation);
+ if (processor != null) {
+ processor.setContext(this);
+ processor.process(operator, arguments);
+ } else {
+ throwContentStreamException("The operator \"" + operation
+ + "\" isn't supported.", ERROR_SYNTAX_CONTENT_STREAM_UNSUPPORTED_OP);
+ }
+
+ // --- Process Specific Validation
+ // --- The Generic Processing is useless for PDFA validation
+ if ("BI".equals(operation)) {
+ validImageFilter(operator);
+ validImageColorSpace(operator);
+ }
+
+ checkShowTextOperators(operator, arguments);
+ checkColorOperators(operation);
+ validRenderingIntent(operator, arguments);
+ checkSetColorSpaceOperators(operator, arguments);
+ validNumberOfGraphicStates(operator);
+ }
+
+ /**
+ * Process Text Validation. According to the operator one of the both method
+ * will be called. (validStringDefinition(PDFOperator operator, List<?>
+ * arguments) / validStringArray(PDFOperator operator, List<?> arguments))
+ *
+ * @param operator
+ * @param arguments
+ * @throws ContentStreamException
+ * @throws IOException
+ */
+ protected void checkShowTextOperators(PDFOperator operator, List<?> arguments)
+ throws ContentStreamException, IOException {
+ String op = operator.getOperation();
+ if ("Tj".equals(op)
+ || "'".equals(op)
+ || "\"".equals(op)) {
+ validStringDefinition(operator, arguments);
+ }
+
+ if ("TJ".equals(op)) {
+ validStringArray(operator, arguments);
+ }
+ }
+
+ /**
+ * Process Text Validation for the Operands of a Tj, "'" and "\"" operator.
+ *
+ * If the validation fails for an unexpected reason, a IOException is thrown.
+ * If the validation fails due to validation error, a ContentStreamException
+ * is thrown. (Use the ValidationError attribute to know the cause)
+ *
+ * @param operator
+ * @param arguments
+ * @throws ContentStreamException
+ * @throws IOException
+ */
+ private void validStringDefinition(PDFOperator operator, List<?> arguments)
+ throws ContentStreamException, IOException {
+ // ---- For a Text operator, the arguments list should contain only one
+ // COSString object
+ if ("\"".equals(operator.getOperation())) {
+ if (arguments.size() != 3) {
+ throwContentStreamException("Invalid argument for the operator : "
+ + operator.getOperation(),
+ ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ }
+ Object arg0 = arguments.get(0);
+ Object arg1 = arguments.get(1);
+ Object arg2 = arguments.get(2);
+ if (!(arg0 instanceof COSInteger || arg0 instanceof COSFloat) ||
+ !(arg1 instanceof COSInteger || arg1 instanceof COSFloat) ) {
+ throwContentStreamException("Invalid argument for the operator : "
+ + operator.getOperation(),
+ ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ }
+
+ if (arg2 instanceof COSString) {
+ validText(((COSString) arg2).getBytes());
+ } else {
+ throwContentStreamException("Invalid argument for the operator : "
+ + operator.getOperation(),
+ ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ }
+ } else {
+ Object objStr = arguments.get(0);
+ if (objStr instanceof COSString) {
+ validText(((COSString) objStr).getBytes());
+ } else if (!(objStr instanceof COSInteger)) {
+ throwContentStreamException("Invalid argument for the operator : "
+ + operator.getOperation(),
+ ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ }
+ }
+ }
+
+ /**
+ * Process Text Validation for the Operands of a TJ operator.
+ *
+ * If the validation fails for an unexpected reason, a IOException is thrown.
+ * If the validation fails due to validation error, a ContentStreamException
+ * is thrown. (Use the ValidationError attribute to know the cause)
+ *
+ * @param operator
+ * @param arguments
+ * @throws ContentStreamException
+ * @throws IOException
+ */
+ private void validStringArray(PDFOperator operator, List<?> arguments)
+ throws ContentStreamException, IOException {
+ for (Object object : arguments) {
+ if (object instanceof COSArray) {
+ validStringArray(operator, ((COSArray) object).toList());
+ } else if (object instanceof COSString) {
+ validText(((COSString) object).getBytes());
+ } else if (!(object instanceof COSInteger || object instanceof COSFloat)) {
+ throwContentStreamException("Invalid argument for the operator : "
+ + operator.getOperation(),
+ ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ }
+ }
+ }
+
+ /**
+ * Process the validation of a Text operand contains in a ContentStream This
+ * validation checks that :
+ * <UL>
+ * <li>The font isn't missing if the Rendering Mode isn't 3
+ * <li>The font metrics are consistent
+ * <li>All character used in the text are defined in the font program.
+ * </UL>
+ *
+ * @param string
+ * @throws IOException
+ */
+ public void validText(byte[] string) throws IOException {
+ // --- 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
+ throwContentStreamException("Text operator can't be process without Font", ERROR_FONTS_UNKNOWN_FONT_REF);
+ }
+
+ // FontContainer fontContainer = documentHandler.retrieveFontContainer(font);
+ AbstractFontContainer fontContainer = documentHandler.getFont(font.getCOSObject());
+
+ if (fontContainer != null && fontContainer.isValid() == State.INVALID) {
+ return;
+ }
+
+ if (renderingMode == 3 && (fontContainer == null || !fontContainer.isFontProgramEmbedded())) {
+ // 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
+ throwContentStreamException(font.getBaseFont() + " is unknown wasn't found by the FontHelperValdiator", ERROR_FONTS_UNKNOWN_FONT_REF);
+ }
+
+ 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) {
+ // Decode the value to a Unicode character
+ codeLength = 1;
+ String c = null;
+ try {
+ c = font.encode(string, i, codeLength);
+ if (c == null && i + 1 < string.length) {
+ // maybe a multibyte encoding
+ codeLength++;
+ c = font.encode(string, i, codeLength);
+ }
+ } catch (IOException e) {
+ throwContentStreamException("Encoding can't interpret the character code", ERROR_FONTS_ENCODING_ERROR);
+ }
+
+ // ---- According to the length of the character encoding,
+ // convert the character to CID
+ int cid = 0;
+ for (int j = 0; j < codeLength; j++) {
+ cid <<= 8;
+ cid += ((string[i + j] + 256) % 256);
+ }
+
+ try {
+ fontContainer.checkCID(cid);
+ } catch (GlyphException e) {
+ throwContentStreamException(e.getMessage(), e.getErrorCode());
+ }
+ }
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/ContentStreamWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/StubOperator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/StubOperator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/StubOperator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/StubOperator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,334 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.contentstream;
+
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_ARRAY_TOO_LONG;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_LITERAL_TOO_LONG;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_NAME_TOO_LONG;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_NUMERIC_RANGE;
+import static org.apache.padaf.preflight.ValidationConstants.ERROR_SYNTAX_TOO_MANY_ENTRIES;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_ARRAY_ELEMENTS;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_DICT_ENTRIES;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_NAME_SIZE;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_NEGATIVE_FLOAT;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_POSITIVE_FLOAT;
+import static org.apache.padaf.preflight.ValidationConstants.MAX_STRING_LENGTH;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.util.PDFOperator;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+/**
+ * This implementation of OperatorProcessor allow the operator validation
+ * according PDF/A rules without compute the operator actions.
+ */
+public class StubOperator extends OperatorProcessor {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.pdfbox.util.operator.OperatorProcessor#process(org.apache.pdfbox
+ * .util.PDFOperator, java.util.List)
+ */
+ @Override
+ public void process(PDFOperator operator, List<COSBase> arguments)
+ throws IOException {
+ String op = operator.getOperation();
+ if ("S".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("B".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("f".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("F".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("f*".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("b".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("B*".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("b*".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("s".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("EMC".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("BMC".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("BDC".equals(op)) {
+ checkTagAndPropertyOperands(arguments);
+ } else if ("DP".equals(op)) {
+ checkTagAndPropertyOperands(arguments);
+ } else if ("c".equals(op)) {
+ checkNumberOperands(arguments, 6);
+ } else if ("v".equals(op)) {
+ checkNumberOperands(arguments, 4);
+ } else if ("y".equals(op)) {
+ checkNumberOperands(arguments, 4);
+ } else if ("d0".equals(op)) {
+ checkNumberOperands(arguments, 2);
+ } else if ("d1".equals(op)) {
+ checkNumberOperands(arguments, 6);
+ } else if ("g".equals(op)) {
+ checkNumberOperands(arguments, 1);
+ } else if ("G".equals(op)) {
+ checkNumberOperands(arguments, 1);
+ } else if ("gs".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("h".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("i".equals(op)) {
+ checkNumberOperands(arguments, 1);
+ } else if ("l".equals(op)) {
+ checkNumberOperands(arguments, 2);
+ } else if ("m".equals(op)) {
+ checkNumberOperands(arguments, 2);
+ } else if ("M".equals(op)) {
+ checkNumberOperands(arguments, 1);
+ } else if ("MP".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("n".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("re".equals(op)) {
+ checkNumberOperands(arguments, 4);
+ } else if ("ri".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("s".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("S".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("sh".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("'".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("Tj".equals(op)) {
+ checkStringOperands(arguments, 1);
+ } else if ("TJ".equals(op)) {
+ checkArrayOperands(arguments, 1);
+ } else if ("W".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("W*".equals(op)) {
+ checkNoOperands(arguments);
+ } else if ("\"".equals(op)) {
+ checkNumberOperands(arguments.subList(0, 2), 2);
+ checkStringOperands(arguments.subList(2, arguments.size()), 1);
+ }
+ // else
+ // ---- Some operators are processed by PDFBox Objects.
+ // ---- Other operators are authorized but it isn't used.
+
+ }
+
+ /**
+ * If the arguments list of Operator isn't empty, this method throws a
+ * ContentStreamException.
+ *
+ * @param arguments
+ * @throws ContentStreamException
+ */
+ private void checkNoOperands(List<COSBase> arguments)
+ throws ContentStreamException {
+ if (arguments != null && !arguments.isEmpty()) {
+ throw createInvalidArgumentsError();
+ }
+ }
+
+ /**
+ * If the arguments list of Operator doesn't have String parameter, this
+ * method throws a ContentStreamException.
+ *
+ * @param arguments
+ * @param length
+ * @throws ContentStreamException
+ */
+ private void checkStringOperands(List<COSBase> arguments, int length)
+ throws ContentStreamException {
+ if (arguments == null || arguments.isEmpty() || arguments.size() != length) {
+ throw createInvalidArgumentsError();
+ }
+
+ for (int i = 0; i < length; ++i) {
+ COSBase arg = arguments.get(i);
+ if (!(arg instanceof COSName) && !(arg instanceof COSString)) {
+ throw createInvalidArgumentsError();
+ }
+
+ if (arg instanceof COSName
+ && ((COSName) arg).getName().length() > MAX_NAME_SIZE) {
+ throw createLimitError(ERROR_SYNTAX_NAME_TOO_LONG, "A Name operand is too long");
+ }
+
+ if (arg instanceof COSString
+ && ((COSString) arg).getString().getBytes().length > MAX_STRING_LENGTH) {
+ throw createLimitError(ERROR_SYNTAX_LITERAL_TOO_LONG, "A String operand is too long");
+ }
+ }
+ }
+
+ /**
+ * If the arguments list of Operator doesn't have Array parameter, this method
+ * throws a ContentStreamException.
+ *
+ * @param arguments
+ * @param length
+ * @throws ContentStreamException
+ */
+ private void checkArrayOperands(List<COSBase> arguments, int length)
+ throws ContentStreamException {
+ if (arguments == null || arguments.isEmpty() || arguments.size() != length) {
+ throw createInvalidArgumentsError();
+ }
+
+ for (int i = 0; i < length; ++i) {
+ COSBase arg = arguments.get(i);
+ if (!(arg instanceof COSArray)) {
+ throw createInvalidArgumentsError();
+ }
+
+ if (((COSArray) arg).size() > MAX_ARRAY_ELEMENTS) {
+ throw createLimitError(ERROR_SYNTAX_ARRAY_TOO_LONG, "Array has " + ((COSArray) arg).size() + " elements");
+ }
+ }
+ }
+
+ /**
+ * If the arguments list of Operator doesn't have Number parameters (Int,
+ * float...), this method throws a ContentStreamException.
+ *
+ * @param arguments
+ * the arguments list to check
+ * @param length
+ * the expected size of the list
+ * @throws ContentStreamException
+ */
+ private void checkNumberOperands(List<COSBase> arguments, int length)
+ throws ContentStreamException {
+ if (arguments == null || arguments.isEmpty() || arguments.size() != length) {
+ throw createInvalidArgumentsError();
+ }
+
+ for (int i = 0; i < length; ++i) {
+ COSBase arg = arguments.get(i);
+ if (!(arg instanceof COSFloat) && !(arg instanceof COSInteger)) {
+ throw createInvalidArgumentsError();
+ }
+
+ if (arg instanceof COSInteger
+ && (((COSInteger) arg).longValue() > Integer.MAX_VALUE || ((COSInteger) arg)
+ .longValue() < Integer.MIN_VALUE)) {
+ throw createLimitError(ERROR_SYNTAX_NUMERIC_RANGE, "Invalid integer range in a Number operands");
+ }
+
+ if (arg instanceof COSFloat
+ && (((COSFloat) arg).doubleValue() > MAX_POSITIVE_FLOAT || ((COSFloat) arg)
+ .doubleValue() < MAX_NEGATIVE_FLOAT)) {
+ throw createLimitError(ERROR_SYNTAX_NUMERIC_RANGE, "Invalid float range in a Number operands");
+ }
+ }
+ }
+
+ /**
+ * The given arguments list is valid only if the first argument is a Tag (A
+ * String) and if the second argument is a String or a Dictionary
+ *
+ * @param arguments
+ * @throws ContentStreamException
+ */
+ private void checkTagAndPropertyOperands(List<COSBase> arguments)
+ throws ContentStreamException {
+ if (arguments == null || arguments.isEmpty() || arguments.size() != 2) {
+ throw createInvalidArgumentsError();
+ }
+
+ COSBase arg = arguments.get(0);
+ if (!(arg instanceof COSName) && !(arg instanceof COSString)) {
+ throw createInvalidArgumentsError();
+ }
+
+ if (arg instanceof COSName
+ && ((COSName) arg).getName().length() > MAX_NAME_SIZE) {
+ throw createLimitError(ERROR_SYNTAX_NAME_TOO_LONG,"A Name operand is too long");
+ }
+
+ if (arg instanceof COSString
+ && ((COSString) arg).getString().getBytes().length > MAX_STRING_LENGTH) {
+ throw createLimitError(ERROR_SYNTAX_LITERAL_TOO_LONG,"A String operand is too long");
+ }
+
+ COSBase arg2 = arguments.get(1);
+ if (!(arg2 instanceof COSName) && !(arg2 instanceof COSString)
+ && !(arg2 instanceof COSDictionary)) {
+ throw createInvalidArgumentsError();
+ }
+
+ if (arg2 instanceof COSName
+ && ((COSName) arg2).getName().length() > MAX_NAME_SIZE) {
+ throw createLimitError(ERROR_SYNTAX_NAME_TOO_LONG,"A Name operand is too long");
+ }
+
+ if (arg2 instanceof COSString
+ && ((COSString) arg2).getString().getBytes().length > MAX_STRING_LENGTH) {
+ throw createLimitError(ERROR_SYNTAX_LITERAL_TOO_LONG,"A String operand is too long");
+ }
+
+ if (arg2 instanceof COSDictionary
+ && ((COSDictionary) arg2).size() > MAX_DICT_ENTRIES) {
+ throw createLimitError(ERROR_SYNTAX_TOO_MANY_ENTRIES, "Dictionary has " + ((COSDictionary) arg2).size() + " entries");
+ }
+ }
+
+ /**
+ * Create a ContentStreamException with
+ * ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT.
+ *
+ * @return
+ */
+ private ContentStreamException createInvalidArgumentsError() {
+ ContentStreamException ex = new ContentStreamException();
+ ex.setValidationError(ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT);
+ return ex;
+ }
+
+ /**
+ * Create a ContentStreamException with
+ * ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT.
+ *
+ * @return
+ */
+ private ContentStreamException createLimitError(String errorCode, String details) {
+ ContentStreamException ex = new ContentStreamException(details);
+ ex.setValidationError(errorCode);
+ return ex;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/contentstream/StubOperator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontContainer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontContainer.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontContainer.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontContainer.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.font;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+
+public abstract class AbstractFontContainer {
+ /**
+ * PDFBox object which contains the Font Dictionary
+ */
+ protected PDFont font = null;
+
+ protected Map<Integer, GlyphDetail> cidKnownByFont = new HashMap<Integer, GlyphDetail>();
+
+ /**
+ * Boolean used to know if the Font Program is embedded.
+ */
+ protected boolean isFontProgramEmbedded = true;
+
+ /**
+ * Errors which occurs during the Font Validation
+ */
+ protected List<ValidationError> errors = new ArrayList<ValidationError>(0);
+
+ /**
+ * The FontContainer Constructor. The type attribute is initialized according
+ * to the given PDFont object.
+ *
+ * @param fd
+ * Font object of the PDFBox API. (Mandatory)
+ * @throws NullPointerException
+ * If the fd is null.
+ */
+ public AbstractFontContainer(PDFont fd) {
+ this.font = fd;
+ }
+
+ /**
+ * Return the PDFont object
+ *
+ * @return
+ */
+ public PDFont getFont() {
+ return font;
+ }
+
+ public void addCID(Integer cid, GlyphDetail details) {
+ this.cidKnownByFont.put(cid, details);
+ }
+
+ /**
+ * @return the isFontProgramEmbedded
+ */
+ public boolean isFontProgramEmbedded() {
+ return isFontProgramEmbedded;
+ }
+
+ /**
+ * @param isFontProgramEmbedded
+ * the isFontProgramEmbedded to set
+ */
+ public void setFontProgramEmbedded(boolean isFontProgramEmbedded) {
+ this.isFontProgramEmbedded = isFontProgramEmbedded;
+ }
+
+ /**
+ * Addition of a validation error.
+ *
+ * @param error
+ */
+ public void addError(ValidationError error) {
+ this.errors.add(error);
+ }
+
+ /**
+ * This method returns the validation state of the font.
+ *
+ * If the list of errors is empty, the validation is successful (State :
+ * VALID). If the size of the list is 1 and if the error is about EmbeddedFont,
+ * the state is "MAYBE" because the font can be valid if
+ * it isn't used (for Width error) or if the rendering mode is 3 (For not
+ * embedded font). Otherwise, the validation failed (State : INVALID)
+ *
+ * @return
+ */
+ public State isValid() {
+ if (this.errors.isEmpty()) {
+ return State.VALID;
+ }
+
+ if ((this.errors.size() == 1)
+ && !this.isFontProgramEmbedded) {
+ return State.MAYBE;
+ }
+
+ // else more than one error, the validation failed
+ return State.INVALID;
+ }
+
+ /**
+ * @return the errors
+ */
+ public List<ValidationError> getErrors() {
+ return errors;
+ }
+
+ public static enum State {
+ VALID, MAYBE, INVALID;
+ }
+
+
+ /**
+ * Check if the cid is present and consistent in the contained font.
+ * @param cid the cid
+ * @return true if cid is present and consistent, false otherwise
+ */
+ public abstract void checkCID (int cid) throws GlyphException;
+
+
+ void addKnownCidElement(GlyphDetail glyphDetail) {
+ this.cidKnownByFont.put(glyphDetail.getCID(), glyphDetail);
+ }
+
+ protected boolean isAlreadyComputedCid(int cid) throws GlyphException {
+ boolean already = false;
+ GlyphDetail gdetail = this.cidKnownByFont.get(cid);
+ if (gdetail != null) {
+ gdetail.throwExceptionIfNotValid();
+ already = true;
+ }
+ return already;
+ }
+
+ protected void checkWidthsConsistency(int cid, float widthProvidedByPdfDictionary, float widthInFontProgram) throws GlyphException {
+ if(!(Math.floor(widthInFontProgram) == widthProvidedByPdfDictionary || Math.round(widthInFontProgram) == widthProvidedByPdfDictionary)) {
+ GlyphException e = new GlyphException(ValidationConstants.ERROR_FONTS_METRICS, cid,
+ "Width of the character \"" + cid
+ + "\" in the font program \""
+ + this.font.getBaseFont()
+ + "\"is inconsistent with the width in the PDF dictionary.");
+ addKnownCidElement(new GlyphDetail(cid, e));
+ throw e;
+ }
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontContainer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontValidator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontValidator.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontValidator.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontValidator.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,228 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.font;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.commons.io.IOUtils;
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.font.AbstractFontContainer.State;
+import org.apache.padaf.xmpbox.XMPMetadata;
+import org.apache.padaf.xmpbox.parser.XMPDocumentBuilder;
+import org.apache.padaf.xmpbox.parser.XmpExpectedRdfAboutAttribute;
+import org.apache.padaf.xmpbox.parser.XmpParsingException;
+import org.apache.padaf.xmpbox.parser.XmpSchemaException;
+import org.apache.padaf.xmpbox.parser.XmpUnknownValueTypeException;
+import org.apache.padaf.xmpbox.parser.XmpXpacketEndException;
+import org.apache.padaf.xmpbox.type.BadFieldValueException;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.pdmodel.common.PDMetadata;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
+import org.apache.pdfbox.pdmodel.font.PDFontFactory;
+
+public abstract class AbstractFontValidator implements FontValidator,ValidationConstants {
+ /**
+ * DocumentHandler which contains all useful objects to validate a PDF/A ex :
+ * parser JavaCC
+ */
+ protected DocumentHandler handler = null;
+ /**
+ * The COSObject which is the starting point of the Font description in the
+ * PDF/A file. This object should be an insteance of COSDictionary
+ */
+ protected COSObject cObj = null;
+ /**
+ * The cObj casted as COSDictionary
+ */
+ protected COSDictionary fDictionary = null;
+ /**
+ * The PdfBox font dictionary wrapper.
+ */
+ protected PDFont pFont = null;
+
+ /**
+ * The Font Container contains the Font Validation state ( valid or not,
+ * why...) This Font Container is tested when the font is used as resource.
+ * According to the state of this font, the PDF File will be PDF/A conforming
+ * file or not. (Ex : if the FontContainer flags this font as not embedded,
+ * the PDF is a PDF/A only if the font is used in a Rendering Mode 3.)
+ */
+ protected AbstractFontContainer fontContainer = null;
+
+ /**
+ * Abstract Constructor
+ * @param handler the handled document
+ * @param cObj The cos object representing the font
+ * @throws ValidationException when object creation fails
+ */
+ public AbstractFontValidator(DocumentHandler handler, COSObject cObj)
+ throws ValidationException {
+ try {
+ this.handler = handler;
+ this.cObj = cObj;
+ this.fDictionary = (COSDictionary) cObj.getObject();
+ this.pFont = PDFontFactory.createFont(fDictionary);
+
+ this.fontContainer = instanciateContainer(this.pFont);
+ this.handler.addFont(this.pFont.getCOSObject(), this.fontContainer);
+ } catch (IOException e) {
+ throw new ValidationException(
+ "Unable to instantiate a FontValidator object : " + e.getMessage());
+ }
+ }
+
+ protected AbstractFontContainer instanciateContainer (PDFont fd) {
+ String subtype = fd.getSubType();
+ if (FONT_DICTIONARY_VALUE_TRUETYPE.equals(subtype)) {
+ return new TrueTypeFontContainer(fd);
+ } else if (FONT_DICTIONARY_VALUE_MMTYPE.equals(subtype)) {
+ return new Type1FontContainer(fd);
+ } else if (FONT_DICTIONARY_VALUE_TYPE1.equals(subtype)) {
+ return new Type1FontContainer(fd);
+ } else if (FONT_DICTIONARY_VALUE_TYPE3.equals(subtype)) {
+ return new Type3FontContainer(fd);
+ } else if (FONT_DICTIONARY_VALUE_COMPOSITE.equals(subtype)) {
+ return new CompositeFontContainer(fd);
+ } else {
+ return new UndefFontContainer(fd);
+ }
+ }
+
+ private static final String subSetPattern = "^[A-Z]{6}\\+.*";
+
+ public static boolean isSubSet(String fontName) {
+ return fontName.matches(subSetPattern);
+ }
+
+ public static String getSubSetPatternDelimiter() {
+ return "+";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.awl.edoc.pdfa.validation.font.FontValidator#getState()
+ */
+ public State getState() {
+ return this.fontContainer.isValid();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.awl.edoc.pdfa.validation.font.FontValidator#getValdiationErrors()
+ */
+ public List<ValidationError> getValdiationErrors() {
+ return this.fontContainer.getErrors();
+ }
+
+ /**
+ * Type0, Type1 and TrueType FontValidatir call this method to check the
+ * FontFile meta data.
+ *
+ * @param fontDesc
+ * The FontDescriptor which contains the FontFile stream
+ * @param fontFile
+ * The font file stream to check
+ * @return true if the meta data is valid, false otherwise
+ * @throws ValidationException when checking fails
+ */
+ protected boolean checkFontFileMetaData(PDFontDescriptor fontDesc,
+ PDStream fontFile) throws ValidationException {
+ PDMetadata metadata = fontFile.getMetadata();
+ if (metadata != null) {
+ // --- Filters are forbidden in a XMP stream
+ if (metadata.getFilters() != null && !metadata.getFilters().isEmpty()) {
+ fontContainer.addError(new ValidationError(
+ ValidationConstants.ERROR_SYNTAX_STREAM_INVALID_FILTER,
+ "Filter specified in font file metadata dictionnary"));
+ return false;
+ }
+
+ // --- extract the meta data content
+ byte[] mdAsBytes = null;
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ InputStream metaDataContent = metadata.createInputStream();
+ IOUtils.copyLarge(metaDataContent, bos);
+ IOUtils.closeQuietly(metaDataContent);
+ IOUtils.closeQuietly(bos);
+ mdAsBytes = bos.toByteArray();
+ } catch (IOException e) {
+ throw new ValidationException("Unable to read font metadata due to : "
+ + e.getMessage(), e);
+ }
+
+ try {
+
+ XMPDocumentBuilder xmpBuilder = new XMPDocumentBuilder();
+ XMPMetadata xmpMeta = xmpBuilder.parse(mdAsBytes);
+
+ FontMetaDataValidation fontMDval = new FontMetaDataValidation();
+ List<ValidationError> ve = new ArrayList<ValidationError>();
+ boolean isVal = fontMDval.analyseFontName(xmpMeta, fontDesc, ve);
+ isVal = isVal && fontMDval.analyseFontName(xmpMeta, fontDesc, ve);
+ for (ValidationError validationError : ve) {
+ fontContainer.addError(validationError);
+ }
+ return isVal;
+
+ } catch (XmpUnknownValueTypeException e) {
+ fontContainer.addError(new ValidationError(
+ ValidationConstants.ERROR_METADATA_UNKNOWN_VALUETYPE, e
+ .getMessage()));
+ return false;
+ } catch (XmpParsingException e) {
+ fontContainer.addError(new ValidationError(
+ ValidationConstants.ERROR_METADATA_FORMAT, e.getMessage()));
+ return false;
+ } catch (XmpSchemaException e) {
+ fontContainer.addError(new ValidationError(
+ ValidationConstants.ERROR_METADATA_FORMAT, e.getMessage()));
+ return false;
+ } catch (XmpExpectedRdfAboutAttribute e) {
+ fontContainer.addError(new ValidationError(ValidationConstants.ERROR_METADATA_RDF_ABOUT_ATTRIBUTE_MISSING,e.getMessage()));
+ return false;
+ } catch (BadFieldValueException e) {
+ fontContainer.addError(new ValidationError(ValidationConstants.ERROR_METADATA_CATEGORY_PROPERTY_INVALID,e.getMessage()));
+ return false;
+ } catch (XmpXpacketEndException e) {
+ throw new ValidationException("Unable to parse font metadata due to : "
+ + e.getMessage(), e);
+ }
+ }
+
+ // --- No MetaData, valid
+ return true;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/AbstractFontValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.font;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+
+import org.apache.fontbox.cff.CFFFont;
+import org.apache.fontbox.cff.CFFFont.Mapping;
+import org.apache.padaf.preflight.ValidationConstants;
+
+
+public class CFFType0FontContainer extends AbstractFontContainer {
+ private Map<Integer, Integer> widthsArray = new LinkedHashMap<Integer, Integer>(0);
+ /**
+ * Represent the missingWidth value of the FontDescriptor dictionary.
+ * According to the PDF Reference, if this value is missing, the default
+ * one is 0.
+ */
+ private float defaultGlyphWidth = 0;
+ /**
+ * Object which contains the CFF data extracted by the
+ * CFFParser object
+ */
+ private List<CFFFont> fontObject = null;
+
+ public CFFType0FontContainer(CompositeFontContainer container) {
+ super(container.getFont());
+ this.cidKnownByFont.putAll(container.cidKnownByFont);
+ this.isFontProgramEmbedded = container.isFontProgramEmbedded;
+ this.errors.addAll(container.errors);
+ }
+
+ @Override
+ public void checkCID(int cid) throws GlyphException {
+ if (isAlreadyComputedCid(cid)) {
+ return;
+ }
+
+ // ---- build the font container and keep it in the Handler.
+ boolean cidFound = false;
+ for (CFFFont font : this.fontObject) {
+ Collection<Mapping> cMapping = font.getMappings();
+ for (Mapping mapping : cMapping) {
+ // -- REMARK : May be this code must be changed like the Type1FontContainer to Map the SID with the character name?
+ // -- Not enough PDF with this kind of Font to test the current implementation
+ if (mapping.getSID()==cid) {
+ cidFound = true;
+ }
+ }
+ }
+
+ if (!cidFound) {
+ GlyphException ge = new GlyphException(ValidationConstants.ERROR_FONTS_GLYPH_MISSING, cid,
+ "CID " + cid + " is missing from the Composite Font format \""
+ + this.font.getBaseFont()+"\"" );
+ addKnownCidElement(new GlyphDetail(cid, ge));
+ throw ge;
+ }
+
+
+ float widthProvidedByPdfDictionary = this.defaultGlyphWidth;
+ if (this.widthsArray.containsKey(cid)) {
+ widthProvidedByPdfDictionary = this.widthsArray.get(cid);
+ }
+ float widthInFontProgram = 0;
+
+ try {
+ // ---- Search the CID in all CFFFont in the FontProgram
+ for (CFFFont cff : fontObject) {
+ widthInFontProgram = cff.getWidth(cid);
+ if (widthInFontProgram != defaultGlyphWidth) {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ GlyphException ge = new GlyphException(ValidationConstants.ERROR_FONTS_DAMAGED, cid,
+ "Unable to get width of the CID/SID : " + cid);
+ addKnownCidElement(new GlyphDetail(cid, ge));
+ throw ge;
+ }
+
+ checkWidthsConsistency(cid, widthProvidedByPdfDictionary, widthInFontProgram);
+ addKnownCidElement(new GlyphDetail(cid));
+ }
+
+ void setWidthsArray(Map<Integer, Integer> widthsArray) {
+ this.widthsArray = widthsArray;
+ }
+
+ void setDefaultGlyphWidth(float defaultGlyphWidth) {
+ this.defaultGlyphWidth = defaultGlyphWidth;
+ }
+
+ void setFontObject(List<CFFFont> fontObject) {
+ this.fontObject = fontObject;
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType2FontContainer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType2FontContainer.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType2FontContainer.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType2FontContainer.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,160 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.font;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+import org.apache.fontbox.cmap.CMap;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.padaf.preflight.ValidationConstants;
+
+
+public class CFFType2FontContainer extends AbstractFontContainer {
+ private Map<Integer, Integer> widthsArray = new LinkedHashMap<Integer, Integer>(0);
+ /**
+ * Represent the missingWidth value of the FontDescriptor dictionary.
+ * According to the PDF Reference, if this value is missing, the default
+ * one is 0.
+ */
+ private float defaultGlyphWidth = 0;
+ /**
+ * Object which contains the TrueType font data (used in the CFFType2 font)
+ * extracted by the TrueTypeParser object
+ */
+ private TrueTypeFont fontObject = null;
+ private CMap cidToGidMap = null;
+
+ private int numberOfLongHorMetrics;
+ private int unitsPerEm;
+ private int[] glyphWidths;
+
+ public CFFType2FontContainer(CompositeFontContainer container) {
+ super(container.getFont());
+ this.cidKnownByFont.putAll(container.cidKnownByFont);
+ this.isFontProgramEmbedded = container.isFontProgramEmbedded;
+ this.errors.addAll(container.errors);
+ }
+
+ @Override
+ public void checkCID(int cid) throws GlyphException {
+ if (isAlreadyComputedCid(cid)) {
+ return;
+ }
+
+ float widthProvidedByPdfDictionary = this.defaultGlyphWidth;
+ if (this.widthsArray.containsKey(cid)) {
+ Integer i = this.widthsArray.get(cid);
+ widthProvidedByPdfDictionary = i.floatValue();
+ }
+
+ int glyphIndex = getGlyphIndex(cid);
+
+ if(this.fontObject.getGlyph().getGlyphs().length <= glyphIndex) {
+ GlyphException ge = new GlyphException(ValidationConstants.ERROR_FONTS_GLYPH_MISSING, cid,
+ "CID " + cid + " is missing from font \"" + this.font.getBaseFont() + "\"");
+ addKnownCidElement(new GlyphDetail(cid, ge));
+ throw ge;
+ }
+
+ // glyph exists we can check the width
+ float glypdWidth = glyphWidths[numberOfLongHorMetrics - 1];
+ if (glyphIndex < numberOfLongHorMetrics) {
+ glypdWidth = glyphWidths[glyphIndex];
+ }
+ float widthInFontProgram = ((glypdWidth * 1000) / unitsPerEm);
+
+ checkWidthsConsistency(cid, widthProvidedByPdfDictionary, widthInFontProgram);
+ addKnownCidElement(new GlyphDetail(cid));
+ }
+
+ /**
+ * If CIDToGID map is Identity, the GID equals to the CID.
+ * Otherwise the conversion is done by the CIDToGID map
+ * @param cid
+ * @return
+ * @throws GlyphException
+ */
+ private int getGlyphIndex(int cid) throws GlyphException {
+ int glyphIndex = cid;
+
+ if (this.cidToGidMap != null) {
+ byte[] cidAsByteArray = null;
+ if (cid < 256) {
+ cidAsByteArray = new byte[1];
+ cidAsByteArray[0] = (byte) (cid & 0xFF);
+ } else {
+ cidAsByteArray = new byte[1];
+ cidAsByteArray[0] = (byte) ((cid >> 8) & 0xFF);
+ cidAsByteArray[1] = (byte) (cid & 0xFF);
+ }
+
+ String glyphIdAsString = this.cidToGidMap.lookup(cidAsByteArray, 0, cidAsByteArray.length);
+ // ---- glyphIdAsString should be a Integer
+ // TODO OD-PDFA-4 : A vérifier avec un PDF qui contient une stream pour
+ // CidToGid...
+ try {
+ glyphIndex = Integer.parseInt(glyphIdAsString);
+ } catch (NumberFormatException e) {
+ GlyphException ge = new GlyphException(ValidationConstants.ERROR_FONTS_GLYPH_MISSING, cid,
+ "CID " + cid + " isn't linked with a GlyphIndex >> " + glyphIdAsString);
+ addKnownCidElement(new GlyphDetail(cid, ge));
+ throw ge;
+ }
+ }
+ return glyphIndex;
+ }
+
+ void setPdfWidths(Map<Integer, Integer> widthsArray) {
+ this.widthsArray = widthsArray;
+ }
+
+ void setDefaultGlyphWidth(float defaultGlyphWidth) {
+ this.defaultGlyphWidth = defaultGlyphWidth;
+ }
+
+ void setFontObject(TrueTypeFont fontObject) {
+ this.fontObject = fontObject;
+ }
+
+ void setCmap(CMap cmap) {
+ this.cidToGidMap = cmap;
+ }
+
+ void setNumberOfLongHorMetrics(int numberOfLongHorMetrics) {
+ this.numberOfLongHorMetrics = numberOfLongHorMetrics;
+ }
+
+ void setUnitsPerEm(int unitsPerEm) {
+ this.unitsPerEm = unitsPerEm;
+ }
+
+ void setGlyphWidths(int[] _glyphWidths) {
+ this.glyphWidths = new int[_glyphWidths.length];
+ for( int i =0 ; i < _glyphWidths.length; ++i) {
+ this.glyphWidths[i] = _glyphWidths[i];
+ }
+ }
+
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType2FontContainer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CompositeFontContainer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CompositeFontContainer.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CompositeFontContainer.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CompositeFontContainer.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ *
+ * 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.padaf.preflight.font;
+
+import org.apache.pdfbox.pdmodel.font.PDFont;
+
+public class CompositeFontContainer extends AbstractFontContainer {
+ private AbstractFontContainer delegatedContainer = null;
+
+ public CompositeFontContainer(PDFont fd) {
+ super(fd);
+ }
+
+ @Override
+ public void checkCID(int cid) throws GlyphException {
+ this.delegatedContainer.checkCID(cid);
+ }
+
+ CFFType0FontContainer getCFFType0() {
+ if (delegatedContainer == null) {
+ delegatedContainer = new CFFType0FontContainer(this);
+ }
+ return (CFFType0FontContainer)this.delegatedContainer;
+ }
+
+ CFFType2FontContainer getCFFType2() {
+ if (delegatedContainer == null) {
+ delegatedContainer = new CFFType2FontContainer(this);
+ }
+ return (CFFType2FontContainer)this.delegatedContainer;
+ }
+}
Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CompositeFontContainer.java
------------------------------------------------------------------------------
svn:eol-style = native