diff options
24 files changed, 1319 insertions, 43 deletions
@@ -27,6 +27,27 @@ Apache FOP is part of Apache's XML Graphics project. The homepage of Apache FOP is http://xmlgraphics.apache.org/fop/. +Legal information +--------------------- + +Apache FOP is published under the Apache License version 2.0. For the license +text, please see the following files: +- LICENSE +- NOTICE + +Legal information on libraries used by Apache FOP can be found in the +"lib/README.txt" file. + +Here is a list of files included in Apache FOP but not published under Apache +License version 2.0: +- sRGB IEC61966-2.1 color profile + File: src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm + Info: src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm.LICENSE.txt +- K3 3 of 9 barcode font (TrueType) + File: examples/fo/advanced/K3.TTF + Info: example/fo/advanced/K3.README + + Where to get help? --------------------- @@ -397,6 +397,8 @@ list of possible build targets. <copy todir="${build.classes.dir}"> <fileset dir="${src.java.dir}"> <include name="META-INF/**"/> + <include name="**/*.icm"/> + <include name="**/*.LICENSE.txt"/> </fileset> </copy> <mkdir dir="${build.viewer.resources.dir}"/> @@ -670,6 +672,7 @@ list of possible build targets. </target> <target name="junit-compile" depends="package, transcoder-pkg, junit-with-xmlunit, junit-without-xmlunit" description="Runs FOP's JUnit tests" if="junit.present"> <mkdir dir="${build.dir}/test-classes"/> + <mkdir dir="${build.dir}/test-reports"/> <javac destdir="${build.dir}/test-classes" fork="${javac.fork}" debug="${javac.debug}" deprecation="${javac.deprecation}" optimize="${javac.optimize}" source="${javac.source}" @@ -687,11 +690,11 @@ list of possible build targets. <target name="junit-transcoder" depends="junit-compile" description="Runs FOP's JUnit transcoder tests" if="junit.present"> <echo message="Running basic functionality tests for fop-transcoder.jar"/> - <mkdir dir="${build.dir}/test-reports/fop-transcoder"/> <junit haltonerror="no" fork="${junit.fork}"> <sysproperty key="basedir" value="${basedir}"/> <sysproperty key="jawa.awt.headless" value="true"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-build-classpath"/> @@ -699,11 +702,7 @@ list of possible build targets. <include name="fop-transcoder.jar"/> </fileset> </classpath> - <batchtest todir="${build.dir}/test-reports/fop-transcoder"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/BasicTranscoderTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.BasicTranscoderTestSuite" todir="${build.dir}/test-reports" outfile="TEST-transcoder"/> </junit> <echo message="Running basic functionality tests for fop-transcoder-allinone.jar"/> <!-- These are the same tests as in the block above but testing the "allinone" JAR @@ -712,11 +711,11 @@ list of possible build targets. previous test block succeeded it indicates that the packaging of the allinone JAR needs to be updated. --> - <mkdir dir="${build.dir}/test-reports/fop-transcoder-allinone"/> <junit haltonerror="no" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure"> <sysproperty key="basedir" value="${basedir}"/> <sysproperty key="jawa.awt.headless" value="true"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <fileset dir="build"> @@ -728,21 +727,17 @@ list of possible build targets. <include name="batik*.jar"/> </fileset> </classpath> - <batchtest todir="${build.dir}/test-reports/fop-transcoder-allinone"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/BasicTranscoderTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.BasicTranscoderTestSuite" todir="${build.dir}/test-reports" outfile="TEST-transcoder-allinone"/> </junit> </target> <target name="junit-basic" depends="junit-compile" description="Runs FOP's JUnit basic tests" if="junit.present"> <echo message="Running basic functionality tests for fop.jar"/> - <mkdir dir="${build.dir}/test-reports/fop"/> <junit haltonerror="no" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure"> <sysproperty key="basedir" value="${basedir}"/> <sysproperty key="jawa.awt.headless" value="true"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-build-classpath"/> @@ -750,12 +745,7 @@ list of possible build targets. <include name="fop.jar"/> </fileset> </classpath> - <batchtest todir="${build.dir}/test-reports/fop"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/BasicDriverTestSuite.class"/> - <include name="org/apache/fop/UtilityCodeTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.StandardTestSuite" todir="${build.dir}/test-reports"/> </junit> </target> @@ -779,43 +769,35 @@ list of possible build targets. <target name="junit-layout-standard" depends="junit-compile" if="junit.present" description="Runs FOP's standard JUnit layout tests"> <echo message="Running standard layout engine tests"/> - <mkdir dir="${build.dir}/test-reports/fop"/> <junit haltonerror="no" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure"> <sysproperty key="basedir" value="${basedir}"/> <sysproperty key="jawa.awt.headless" value="true"/> <sysproperty key="fop.layoutengine.disabled" value="${layoutengine.disabled}"/> <sysproperty key="fop.layoutengine.testset" value="standard"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-run-classpath"/> </classpath> - <batchtest todir="${build.dir}/test-reports/fop"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/layoutengine/LayoutEngineTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.layoutengine.LayoutEngineTestSuite" todir="${build.dir}/test-reports" outfile="TEST-layoutengine-standard"/> </junit> </target> <target name="junit-layout-hyphenation" depends="hyphenation-present, junit-compile" if="hyphenation.present" description="Runs FOP's JUnit hyphenation layout tests"> <echo message="Running hyphenation layout engine tests"/> - <mkdir dir="${build.dir}/test-reports/fop"/> <junit haltonerror="no" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure"> <sysproperty key="basedir" value="${basedir}"/> <sysproperty key="jawa.awt.headless" value="true"/> <sysproperty key="fop.layoutengine.disabled" value="${layoutengine.disabled}"/> <sysproperty key="fop.layoutengine.testset" value="hyphenation"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-run-classpath"/> </classpath> - <batchtest todir="${build.dir}/test-reports/fop"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/layoutengine/LayoutEngineTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.layoutengine.LayoutEngineTestSuite" todir="${build.dir}/test-reports" outfile="TEST-layoutengine-hyphenation"/> </junit> </target> @@ -828,6 +810,7 @@ list of possible build targets. <sysproperty key="jawa.awt.headless" value="true"/> <sysproperty key="fop.layoutengine.disabled" value="${fotree.disabled}"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-build-classpath"/> @@ -835,11 +818,7 @@ list of possible build targets. <include name="fop.jar"/> </fileset> </classpath> - <batchtest todir="${build.dir}/test-reports/fop"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/fotreetest/FOTreeTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.fotreetest.FOTreeTestSuite" todir="${build.dir}/test-reports" outfile="TEST-FO-tree"/> </junit> </target> @@ -851,6 +830,7 @@ list of possible build targets. <sysproperty key="fop.layoutengine.disabled" value="${layoutengine.disabled}"/> <sysproperty key="fop.layoutengine.testset" value="standard"/> <formatter type="brief" usefile="false"/> + <formatter type="plain" usefile="true"/> <classpath> <pathelement location="${build.dir}/test-classes"/> <path refid="libs-build-classpath"/> @@ -858,11 +838,7 @@ list of possible build targets. <include name="fop.jar"/> </fileset> </classpath> - <batchtest todir="${build.dir}/test-reports/fop"> - <fileset dir="${build.dir}/test-classes"> - <include name="org/apache/fop/intermediate/IntermediateFormatTestSuite.class"/> - </fileset> - </batchtest> + <test name="org.apache.fop.intermediate.IntermediateFormatTestSuite" todir="${build.dir}/test-reports" outfile="TEST-intermediate-format"/> </junit> </target> diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java index 79b7e52e1..f97c498b6 100644 --- a/src/java/org/apache/fop/pdf/PDFDocument.java +++ b/src/java/org/apache/fop/pdf/PDFDocument.java @@ -285,7 +285,7 @@ public class PDFDocument { if (mode == PDFAMode.PDFA_1A) { throw new UnsupportedOperationException("PDF/A-1a is not implemented, yet"); } else if (mode == PDFAMode.PDFA_1B) { - log.warn("Please note: PDF/A-1b is 'WORK IN PROGRESS' and not fully supported, yet!"); + //you got the green light! } this.pdfAMode = mode; } diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index 6222cf1f0..4fddd3e35 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -150,6 +150,16 @@ public class PDFFactory { } /** + * Make a OutputIntent dictionary. + * @return the newly created OutputIntent dictionary + */ + public PDFOutputIntent makeOutputIntent() { + PDFOutputIntent outputIntent = new PDFOutputIntent(); + getDocument().registerObject(outputIntent); + return outputIntent; + } + + /** * Make a /Page object. The page is assigned an object number immediately * so references can already be made. The page must be added to the * PDFDocument later using addObject(). diff --git a/src/java/org/apache/fop/pdf/PDFOutputIntent.java b/src/java/org/apache/fop/pdf/PDFOutputIntent.java new file mode 100644 index 000000000..a18f0e351 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFOutputIntent.java @@ -0,0 +1,173 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Represents the OutputIntent dictionary. + * @since PDF 1.4 + */ +public class PDFOutputIntent extends PDFObject { + + /** Subtype for PDF/X output intents */ + public static final String GTS_PDFX = "GTS_PDFX"; + /** Subtype for PDF/A-1 output intents */ + public static final String GTS_PDFA1 = "GTS_PDFA1"; + + private String subtype; //S in the PDF spec + private String outputCondition; + private String outputConditionIdentifier; + private String registryName; + private String info; + private PDFICCStream destOutputProfile; + + + /** @return the output intent subtype. */ + public String getSubtype() { + return subtype; + } + + /** + * Sets the output intent subtype. + * @param subtype the subtype (usually "GTS_PDFX") + */ + public void setSubtype(String subtype) { + this.subtype = subtype; + } + + /** @return the OutputCondition field */ + public String getOutputCondition() { + return outputCondition; + } + + /** + * Sets the human-readable form of the output condition. + * @param outputCondition A text string concisely identifying the intended output + * device or production condition in human-readable form. + */ + public void setOutputCondition(String outputCondition) { + this.outputCondition = outputCondition; + } + + /** @return the OutputConditionIdentifier field */ + public String getOutputConditionIdentifier() { + return outputConditionIdentifier; + } + + /** + * Sets the identifier for the output condition. + * @param outputConditionIdentifier A string identifying the intended output device or + * production condition in human- or machine-readable form. + */ + public void setOutputConditionIdentifier(String outputConditionIdentifier) { + this.outputConditionIdentifier = outputConditionIdentifier; + } + + /** @return the RegistryName field */ + public String getRegistryName() { + return registryName; + } + + /** + * Sets the registry name. + * @param registryName A string (conventionally a uniform resource identifier, + * or URI) identifying the registry in which the condition designated + * by OutputConditionIdentifier is defined. + */ + public void setRegistryName(String registryName) { + this.registryName = registryName; + } + + /** @return the Info field */ + public String getInfo() { + return info; + } + + /** + * Sets the Info field. + * @param info A human-readable text string containing additional information or comments about + * the intended target device or production condition. + */ + public void setInfo(String info) { + this.info = info; + } + + /** @return the DestOutputProfile */ + public PDFICCStream getDestOutputProfile() { + return destOutputProfile; + } + + /** + * Sets the destination ICC profile. + * @param destOutputProfile An ICC profile stream defining the transformation from the PDF + * document’s source colors to output device colorants. + */ + public void setDestOutputProfile(PDFICCStream destOutputProfile) { + this.destOutputProfile = destOutputProfile; + } + + /** @see org.apache.fop.pdf.PDFObject#toPDF() */ + public byte[] toPDF() { + ByteArrayOutputStream bout = new ByteArrayOutputStream(128); + try { + bout.write(encode(getObjectID())); + bout.write(encode("<<\n")); + bout.write(encode("/Type /OutputIntent\n")); + + bout.write(encode("/S /")); + bout.write(encode(this.subtype)); + bout.write(encode("\n")); + + if (outputCondition != null) { + bout.write(encode("/OutputCondition ")); + bout.write(encodeText(this.outputCondition)); + bout.write(encode("\n")); + } + + bout.write(encode("/OutputConditionIdentifier ")); + bout.write(encodeText(this.outputConditionIdentifier)); + bout.write(encode("\n")); + + if (registryName != null) { + bout.write(encode("/RegistryName ")); + bout.write(encodeText(this.registryName)); + bout.write(encode("\n")); + } + + if (info != null) { + bout.write(encode("/Info ")); + bout.write(encodeText(this.info)); + bout.write(encode("\n")); + } + + if (destOutputProfile != null) { + bout.write(encode("/DestOutputProfile " + destOutputProfile.referencePDF() + "\n")); + } + + bout.write(encode(">>\nendobj\n")); + } catch (IOException ioe) { + log.error("Ignored I/O exception", ioe); + } + return bout.toByteArray(); + } + + +} diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java index 3d483f587..9ac4e1b0f 100644 --- a/src/java/org/apache/fop/pdf/PDFRoot.java +++ b/src/java/org/apache/fop/pdf/PDFRoot.java @@ -18,6 +18,8 @@ package org.apache.fop.pdf; +import java.util.List; + /** * class representing a Root (/Catalog) object */ @@ -56,6 +58,9 @@ public class PDFRoot extends PDFObject { /** Optional Metadata object */ private PDFMetadata metadata; + /** The array of OutputIntents */ + private List outputIntents; + private int pageMode = PAGEMODE_USENONE; /** @@ -137,6 +142,17 @@ public class PDFRoot extends PDFObject { } /** + * Adds an OutputIntent to the PDF + * @param outputIntent the OutputIntent dictionary + */ + public void addOutputIntent(PDFOutputIntent outputIntent) { + if (this.outputIntents == null) { + this.outputIntents = new java.util.ArrayList(); + } + this.outputIntents.add(outputIntent); + } + + /** * @see org.apache.fop.pdf.PDFObject#toPDFString() */ public String toPDFString() { @@ -168,6 +184,19 @@ public class PDFRoot extends PDFObject { && getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) { p.append("/Metadata " + getMetadata().referencePDF() + "\n"); } + if (this.outputIntents != null + && this.outputIntents.size() > 0 + && getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) { + p.append("/OutputIntents ["); + for (int i = 0, c = this.outputIntents.size(); i < c; i++) { + PDFOutputIntent outputIntent = (PDFOutputIntent)this.outputIntents.get(i); + if (i > 0) { + p.append(" "); + } + p.append(outputIntent.referencePDF()); + } + p.append("]\n"); + } p.append(">>\nendobj\n"); return p.toString(); } diff --git a/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm b/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm Binary files differnew file mode 100644 index 000000000..7f9d18d09 --- /dev/null +++ b/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm diff --git a/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm.LICENSE.txt b/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm.LICENSE.txt new file mode 100644 index 000000000..9b817e339 --- /dev/null +++ b/src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm.LICENSE.txt @@ -0,0 +1,14 @@ +Obtained from: http://www.srgb.com/usingsrgb.html + +The file "sRGB Color Space Profile.icm" is: +Copyright (c) 1998 Hewlett-Packard Company + +To anyone who acknowledges that the file "sRGB Color Space Profile.icm" +is provided "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTY: +permission to use, copy and distribute this file for any purpose is hereby +granted without fee, provided that the file is not changed including the HP +copyright notice tag, and that the name of Hewlett-Packard Company not be +used in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. Hewlett-Packard Company makes +no representations about the suitability of this software for any purpose. + diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java index d1beb0961..2ecdcbcec 100644 --- a/src/java/org/apache/fop/render/pdf/FopPDFImage.java +++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java @@ -17,6 +17,7 @@ /* $Id$ */ package org.apache.fop.render.pdf; +import org.apache.fop.pdf.PDFConformanceException; import org.apache.fop.pdf.PDFFilterList; import org.apache.fop.pdf.PDFImage; import org.apache.fop.pdf.PDFFilter; @@ -24,6 +25,7 @@ import org.apache.fop.pdf.PDFICCStream; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.DCTFilter; +import org.apache.fop.pdf.CCFFilter; import org.apache.fop.pdf.PDFColorSpace; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.pdf.BitmapImage; @@ -36,7 +38,6 @@ import java.io.IOException; import java.io.OutputStream; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; -import org.apache.fop.pdf.CCFFilter; /** * PDFImage implementation for the PDF renderer. @@ -129,6 +130,17 @@ public class FopPDFImage implements PDFImage { PDFXObject xobj = doc.addImage(null, fopimg); softMaskRef = xobj.referencePDF(); } + if (doc.getPDFAMode().isPDFA1LevelB()) { + if (pdfCS != null + && pdfCS.getColorSpace() != PDFColorSpace.DEVICE_RGB + && pdfCS.getColorSpace() != PDFColorSpace.DEVICE_GRAY + && prof == null) { + //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3 + //FOP is currently restricted to DeviceRGB if PDF/A-1 is active. + throw new PDFConformanceException( + "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK."); + } + } } /** diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 68e9aa022..48eef1750 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -20,8 +20,12 @@ package org.apache.fop.render.pdf; // Java import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.awt.Color; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; import java.awt.geom.Rectangle2D; import java.awt.geom.AffineTransform; import java.util.Iterator; @@ -34,6 +38,7 @@ import org.w3c.dom.Document; // Avalon import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.commons.io.IOUtils; // FOP import org.apache.fop.apps.FOPException; @@ -69,11 +74,13 @@ import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFEncryptionManager; import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.pdf.PDFFilterList; +import org.apache.fop.pdf.PDFICCStream; import org.apache.fop.pdf.PDFInfo; import org.apache.fop.pdf.PDFLink; import org.apache.fop.pdf.PDFMetadata; import org.apache.fop.pdf.PDFNumber; import org.apache.fop.pdf.PDFOutline; +import org.apache.fop.pdf.PDFOutputIntent; import org.apache.fop.pdf.PDFPage; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; @@ -352,11 +359,62 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { this.pdfDoc.setFilterMap(filterMap); this.pdfDoc.outputHeader(stream); + if (pdfAMode.isPDFA1LevelB()) { + log.debug("PDF/A is active. Conformance Level: " + pdfAMode); + addPDFA1OutputIntent(); + } + //Setup encryption if necessary PDFEncryptionManager.setupPDFEncryption(encryptionParams, this.pdfDoc); } /** + * Adds an OutputIntent to the PDF as mandated by PDF/A-1 when uncalibrated color spaces + * are used (which is true if we use DeviceRGB to represent sRGB colors). + * @throws IOException in case of an I/O problem + */ + private void addPDFA1OutputIntent() throws IOException { + PDFOutputIntent outputIntent = pdfDoc.getFactory().makeOutputIntent(); + outputIntent.setSubtype(PDFOutputIntent.GTS_PDFA1); + PDFICCStream icc = pdfDoc.getFactory().makePDFICCStream(); + ICC_Profile profile; + InputStream in = PDFDocument.class.getResourceAsStream("sRGB Color Space Profile.icm"); + if (in != null) { + try { + profile = ICC_Profile.getInstance(in); + } finally { + IOUtils.closeQuietly(in); + } + } else { + //Fallback: Use the sRGB profile from the JRE (about 140KB) + profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); + } + String desc = getICCProfileDescription(profile); + + icc.setColorSpace(profile, null); + outputIntent.setDestOutputProfile(icc); + outputIntent.setOutputConditionIdentifier(desc); + outputIntent.setInfo(outputIntent.getOutputConditionIdentifier()); + pdfDoc.getRoot().addOutputIntent(outputIntent); + } + + private String getICCProfileDescription(ICC_Profile profile) { + byte[] data = profile.getData(ICC_Profile.icSigProfileDescriptionTag); + if (data == null) { + return null; + } else { + //Info on the data format: http://www.color.org/ICC-1_1998-09.PDF + int length = (data[8] << 3 * 8) | (data[9] << 2 * 8) | (data[10] << 8) | data[11]; + length--; //Remove trailing NUL character + try { + return new String(data, 12, length, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new UnsupportedOperationException("Incompatible VM"); + } + } + } + + /** * @see org.apache.fop.render.Renderer#stopRenderer() */ public void stopRenderer() throws IOException { diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 59cb6612d..31f0567a2 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -18,6 +18,7 @@ package org.apache.fop.svg; +import org.apache.fop.pdf.PDFConformanceException; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; import org.apache.fop.pdf.PDFGState; @@ -812,6 +813,12 @@ public class PDFGraphics2D extends AbstractGraphics2D { currentStream.write(currentColour.getColorSpaceOut(fill)); } else if (c.getColorSpace().getType() == ColorSpace.TYPE_CMYK) { + if (pdfDoc.getPDFAMode().isPDFA1LevelB()) { + //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3 + //FOP is currently restricted to DeviceRGB if PDF/A-1 is active. + throw new PDFConformanceException( + "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK."); + } float[] cComps = c.getColorComponents(new float[3]); double[] cmyk = new double[3]; for (int i = 0; i < 3; i++) { diff --git a/test/java/org/apache/fop/StandardTestSuite.java b/test/java/org/apache/fop/StandardTestSuite.java new file mode 100644 index 000000000..ee3c5add8 --- /dev/null +++ b/test/java/org/apache/fop/StandardTestSuite.java @@ -0,0 +1,45 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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. + */ + +/* $Id: BasicDriverTestSuite.java 231325 2005-08-10 21:05:39Z jeremias $ */ + +package org.apache.fop; + +import org.apache.fop.render.pdf.PDFAConformanceTestCase; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for basic functionality of FOP. + */ +public class StandardTestSuite { + + /** + * Builds the test suite + * @return the test suite + */ + public static Test suite() { + TestSuite suite = new TestSuite( + "Basic functionality test suite for FOP"); + //$JUnit-BEGIN$ + suite.addTest(BasicDriverTestSuite.suite()); + suite.addTest(UtilityCodeTestSuite.suite()); + suite.addTest(new TestSuite(PDFAConformanceTestCase.class)); + //$JUnit-END$ + return suite; + } +} diff --git a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java new file mode 100644 index 000000000..365ca51db --- /dev/null +++ b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java @@ -0,0 +1,157 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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. + */ + +/* $Id$ */ + +package org.apache.fop.render.pdf; + +import java.io.File; + +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.pdf.PDFConformanceException; + +import junit.framework.TestCase; + +/** + * Tests PDF/A-1 functionality. + */ +public class PDFAConformanceTestCase extends TestCase { + + private TransformerFactory tFactory = TransformerFactory.newInstance(); + private FopFactory fopFactory = FopFactory.newInstance(); + private File foBaseDir = new File("test/xml/pdf-a"); + + /** + * Main constructor + * @param name the name of the test case + */ + public PDFAConformanceTestCase(String name) { + super(name); + try { + fopFactory.setUserConfig(new File("test/test.xconf")); + } catch (Exception e) { + throw new RuntimeException("Configuring the FopFactory failed: " + e.getMessage()); + } + } + + /** + * Convert the test file + * @param foFile the FO file + * @param ua the preconfigured user agent + * @throws Exception if the conversion fails + */ + protected void convertFO(File foFile, FOUserAgent ua) throws Exception { + ua.getRendererOptions().put("pdf-a-mode", "PDF/A-1b"); + File outFile = null; + ByteArrayOutputStream baout = new ByteArrayOutputStream(); + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, ua, baout); + Transformer transformer = tFactory.newTransformer(); + Source src = new StreamSource(foFile); + SAXResult res = new SAXResult(fop.getDefaultHandler()); + transformer.transform(src, res); + if (true) { + //Write to file for debugging + outFile = new File(foFile.getParentFile(), foFile.getName() + ".pdf"); + FileUtils.writeByteArrayToFile(outFile, baout.toByteArray()); + } + } + + /** + * Test exception when PDF/A-1 is enabled and everything is as it should. + * @throws Exception if the test fails + */ + public void testAllOk() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File foFile = new File(foBaseDir, "minimal-pdf-a.fo"); + convertFO(foFile, ua); + } + + /** + * Test exception when PDF/A-1 is enabled together with encryption. + * @throws Exception if the test fails + */ + public void testNoEncryption() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + ua.getRendererOptions().put("owner-password", "mypassword"); //To enabled encryption + File foFile = new File(foBaseDir, "minimal-pdf-a.fo"); + try { + convertFO(foFile, ua); + fail("Expected PDFConformanceException. PDF/A-1 and PDF encryption don't go together."); + } catch (PDFConformanceException e) { + //Good! + } + } + + /** + * Test exception when PDF/A-1 is enabled and a font is used which is not embedded. + * @throws Exception if the test fails + */ + public void testFontNotEmbedded() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File foFile = new File(foBaseDir, "base14-font.fo"); + try { + convertFO(foFile, ua); + fail("Expected PDFConformanceException. PDF/A-1 wants all fonts embedded."); + } catch (PDFConformanceException e) { + //Good! + } + } + + /** + * Test exception when PDF/A-1 is enabled and an EPS is used. + * @throws Exception if the test fails + */ + public void testEPSUsage() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File foFile = new File(foBaseDir, "with-eps.fo"); + try { + convertFO(foFile, ua); + fail("Expected PDFConformanceException. PDF/A-1 does not allow PostScript XObjects."); + } catch (PDFConformanceException e) { + //Good! + } + } + + /** + * Test exception when PDF/A-1 is enabled and images. + * @throws Exception if the test fails + */ + public void testImages() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File foFile = new File(foBaseDir, "with-rgb-images.fo"); + convertFO(foFile, ua); + + foFile = new File(foBaseDir, "with-cmyk-images.fo"); + try { + convertFO(foFile, ua); + fail("Expected PDFConformanceException. PDF/A-1 does not allow PostScript XObjects."); + } catch (PDFConformanceException e) { + //Good! + } + } + +} diff --git a/test/resources/fonts/glb12.README.txt b/test/resources/fonts/glb12.README.txt new file mode 100644 index 000000000..100046ad7 --- /dev/null +++ b/test/resources/fonts/glb12.README.txt @@ -0,0 +1,9 @@ +This Gladiator Bold font has been copied from Apache Batik. Origin: +http://svn.apache.org/repos/asf/xmlgraphics/batik/trunk/samples/tests/resources/ttf/glb12.ttf + +It was added to that repository in July 2003: +http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-dev/200307.mbox/%3c20030715155519.37236.qmail@icarus.apache.org%3e + +More information on that contribution can be found here: +http://svn.apache.org/repos/asf/xmlgraphics/batik/trunk/contrib/fonts/gladiator/ +http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-dev/200306.mbox/ajax/%3c3EE07AA6.5080507@sun.com%3e
\ No newline at end of file diff --git a/test/resources/fonts/glb12.ttf b/test/resources/fonts/glb12.ttf Binary files differnew file mode 100755 index 000000000..77ff2b490 --- /dev/null +++ b/test/resources/fonts/glb12.ttf diff --git a/test/resources/fonts/glb12.ttf.ansi.xml b/test/resources/fonts/glb12.ttf.ansi.xml new file mode 100644 index 000000000..18cd2650e --- /dev/null +++ b/test/resources/fonts/glb12.ttf.ansi.xml @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="UTF-8"?> +<font-metrics type="TRUETYPE"> + <font-name>Gladiator,Bold</font-name> + <embed/> + <cap-height>691</cap-height> + <x-height>429</x-height> + <ascender>765</ascender> + <descender>-234</descender> + <bbox> + <left>-157</left> + <bottom>-250</bottom> + <right>1181</right> + <top>1071</top> + </bbox> + <flags>33</flags> + <stemv>0</stemv> + <italicangle>0</italicangle> + <subtype>TRUETYPE</subtype> + <singlebyte-extras> + <encoding>WinAnsiEncoding</encoding> + <first-char>0</first-char> + <last-char>255</last-char> + <widths> + <char idx="0" wdt="432"/> + <char idx="1" wdt="432"/> + <char idx="2" wdt="432"/> + <char idx="3" wdt="432"/> + <char idx="4" wdt="432"/> + <char idx="5" wdt="432"/> + <char idx="6" wdt="432"/> + <char idx="7" wdt="432"/> + <char idx="8" wdt="432"/> + <char idx="9" wdt="432"/> + <char idx="10" wdt="432"/> + <char idx="11" wdt="432"/> + <char idx="12" wdt="432"/> + <char idx="13" wdt="432"/> + <char idx="14" wdt="432"/> + <char idx="15" wdt="432"/> + <char idx="16" wdt="432"/> + <char idx="17" wdt="432"/> + <char idx="18" wdt="432"/> + <char idx="19" wdt="432"/> + <char idx="20" wdt="432"/> + <char idx="21" wdt="432"/> + <char idx="22" wdt="432"/> + <char idx="23" wdt="432"/> + <char idx="24" wdt="432"/> + <char idx="25" wdt="432"/> + <char idx="26" wdt="432"/> + <char idx="27" wdt="432"/> + <char idx="28" wdt="432"/> + <char idx="29" wdt="432"/> + <char idx="30" wdt="432"/> + <char idx="31" wdt="432"/> + <char idx="32" wdt="332"/> + <char idx="33" wdt="376"/> + <char idx="34" wdt="525"/> + <char idx="35" wdt="980"/> + <char idx="36" wdt="625"/> + <char idx="37" wdt="754"/> + <char idx="38" wdt="886"/> + <char idx="39" wdt="311"/> + <char idx="40" wdt="398"/> + <char idx="41" wdt="398"/> + <char idx="42" wdt="601"/> + <char idx="43" wdt="652"/> + <char idx="44" wdt="311"/> + <char idx="45" wdt="331"/> + <char idx="46" wdt="311"/> + <char idx="47" wdt="500"/> + <char idx="48" wdt="541"/> + <char idx="49" wdt="541"/> + <char idx="50" wdt="541"/> + <char idx="51" wdt="541"/> + <char idx="52" wdt="541"/> + <char idx="53" wdt="541"/> + <char idx="54" wdt="541"/> + <char idx="55" wdt="541"/> + <char idx="56" wdt="541"/> + <char idx="57" wdt="541"/> + <char idx="58" wdt="311"/> + <char idx="59" wdt="311"/> + <char idx="60" wdt="500"/> + <char idx="61" wdt="805"/> + <char idx="62" wdt="500"/> + <char idx="63" wdt="569"/> + <char idx="64" wdt="805"/> + <char idx="65" wdt="729"/> + <char idx="66" wdt="708"/> + <char idx="67" wdt="725"/> + <char idx="68" wdt="748"/> + <char idx="69" wdt="683"/> + <char idx="70" wdt="665"/> + <char idx="71" wdt="769"/> + <char idx="72" wdt="808"/> + <char idx="73" wdt="347"/> + <char idx="74" wdt="347"/> + <char idx="75" wdt="769"/> + <char idx="76" wdt="644"/> + <char idx="77" wdt="1109"/> + <char idx="78" wdt="767"/> + <char idx="79" wdt="821"/> + <char idx="80" wdt="689"/> + <char idx="81" wdt="821"/> + <char idx="82" wdt="708"/> + <char idx="83" wdt="689"/> + <char idx="84" wdt="685"/> + <char idx="85" wdt="767"/> + <char idx="86" wdt="689"/> + <char idx="87" wdt="1181"/> + <char idx="88" wdt="729"/> + <char idx="89" wdt="729"/> + <char idx="90" wdt="644"/> + <char idx="91" wdt="542"/> + <char idx="92" wdt="500"/> + <char idx="93" wdt="542"/> + <char idx="94" wdt="253"/> + <char idx="95" wdt="432"/> + <char idx="96" wdt="311"/> + <char idx="97" wdt="515"/> + <char idx="98" wdt="556"/> + <char idx="99" wdt="492"/> + <char idx="100" wdt="556"/> + <char idx="101" wdt="517"/> + <char idx="102" wdt="311"/> + <char idx="103" wdt="556"/> + <char idx="104" wdt="575"/> + <char idx="105" wdt="311"/> + <char idx="106" wdt="311"/> + <char idx="107" wdt="556"/> + <char idx="108" wdt="311"/> + <char idx="109" wdt="839"/> + <char idx="110" wdt="575"/> + <char idx="111" wdt="547"/> + <char idx="112" wdt="556"/> + <char idx="113" wdt="556"/> + <char idx="114" wdt="440"/> + <char idx="115" wdt="492"/> + <char idx="116" wdt="359"/> + <char idx="117" wdt="575"/> + <char idx="118" wdt="476"/> + <char idx="119" wdt="711"/> + <char idx="120" wdt="496"/> + <char idx="121" wdt="476"/> + <char idx="122" wdt="496"/> + <char idx="123" wdt="432"/> + <char idx="124" wdt="311"/> + <char idx="125" wdt="432"/> + <char idx="126" wdt="253"/> + <char idx="127" wdt="432"/> + <char idx="128" wdt="432"/> + <char idx="129" wdt="432"/> + <char idx="130" wdt="432"/> + <char idx="131" wdt="432"/> + <char idx="132" wdt="432"/> + <char idx="133" wdt="432"/> + <char idx="134" wdt="432"/> + <char idx="135" wdt="432"/> + <char idx="136" wdt="253"/> + <char idx="137" wdt="432"/> + <char idx="138" wdt="0"/> + <char idx="139" wdt="432"/> + <char idx="140" wdt="0"/> + <char idx="141" wdt="432"/> + <char idx="142" wdt="0"/> + <char idx="143" wdt="432"/> + <char idx="144" wdt="432"/> + <char idx="145" wdt="311"/> + <char idx="146" wdt="311"/> + <char idx="147" wdt="525"/> + <char idx="148" wdt="525"/> + <char idx="149" wdt="432"/> + <char idx="150" wdt="855"/> + <char idx="151" wdt="1109"/> + <char idx="152" wdt="253"/> + <char idx="153" wdt="432"/> + <char idx="154" wdt="0"/> + <char idx="155" wdt="432"/> + <char idx="156" wdt="0"/> + <char idx="157" wdt="432"/> + <char idx="158" wdt="0"/> + <char idx="159" wdt="0"/> + <char idx="160" wdt="332"/> + <char idx="161" wdt="376"/> + <char idx="162" wdt="432"/> + <char idx="163" wdt="0"/> + <char idx="164" wdt="432"/> + <char idx="165" wdt="432"/> + <char idx="166" wdt="432"/> + <char idx="167" wdt="0"/> + <char idx="168" wdt="395"/> + <char idx="169" wdt="432"/> + <char idx="170" wdt="432"/> + <char idx="171" wdt="657"/> + <char idx="172" wdt="432"/> + <char idx="173" wdt="432"/> + <char idx="174" wdt="432"/> + <char idx="175" wdt="253"/> + <char idx="176" wdt="432"/> + <char idx="177" wdt="432"/> + <char idx="178" wdt="432"/> + <char idx="179" wdt="432"/> + <char idx="180" wdt="304"/> + <char idx="181" wdt="432"/> + <char idx="182" wdt="432"/> + <char idx="183" wdt="432"/> + <char idx="184" wdt="151"/> + <char idx="185" wdt="432"/> + <char idx="186" wdt="432"/> + <char idx="187" wdt="657"/> + <char idx="188" wdt="432"/> + <char idx="189" wdt="432"/> + <char idx="190" wdt="432"/> + <char idx="191" wdt="569"/> + <char idx="192" wdt="547"/> + <char idx="193" wdt="729"/> + <char idx="194" wdt="729"/> + <char idx="195" wdt="729"/> + <char idx="196" wdt="729"/> + <char idx="197" wdt="729"/> + <char idx="198" wdt="432"/> + <char idx="199" wdt="725"/> + <char idx="200" wdt="683"/> + <char idx="201" wdt="683"/> + <char idx="202" wdt="683"/> + <char idx="203" wdt="683"/> + <char idx="204" wdt="347"/> + <char idx="205" wdt="347"/> + <char idx="206" wdt="347"/> + <char idx="207" wdt="347"/> + <char idx="208" wdt="0"/> + <char idx="209" wdt="767"/> + <char idx="210" wdt="821"/> + <char idx="211" wdt="821"/> + <char idx="212" wdt="821"/> + <char idx="213" wdt="821"/> + <char idx="214" wdt="821"/> + <char idx="215" wdt="432"/> + <char idx="216" wdt="0"/> + <char idx="217" wdt="767"/> + <char idx="218" wdt="767"/> + <char idx="219" wdt="767"/> + <char idx="220" wdt="767"/> + <char idx="221" wdt="729"/> + <char idx="222" wdt="0"/> + <char idx="223" wdt="432"/> + <char idx="224" wdt="515"/> + <char idx="225" wdt="515"/> + <char idx="226" wdt="515"/> + <char idx="227" wdt="515"/> + <char idx="228" wdt="515"/> + <char idx="229" wdt="515"/> + <char idx="230" wdt="432"/> + <char idx="231" wdt="492"/> + <char idx="232" wdt="517"/> + <char idx="233" wdt="517"/> + <char idx="234" wdt="517"/> + <char idx="235" wdt="517"/> + <char idx="236" wdt="311"/> + <char idx="237" wdt="311"/> + <char idx="238" wdt="311"/> + <char idx="239" wdt="311"/> + <char idx="240" wdt="0"/> + <char idx="241" wdt="575"/> + <char idx="242" wdt="547"/> + <char idx="243" wdt="547"/> + <char idx="244" wdt="547"/> + <char idx="245" wdt="547"/> + <char idx="246" wdt="547"/> + <char idx="247" wdt="432"/> + <char idx="248" wdt="0"/> + <char idx="249" wdt="575"/> + <char idx="250" wdt="575"/> + <char idx="251" wdt="575"/> + <char idx="252" wdt="575"/> + <char idx="253" wdt="476"/> + <char idx="254" wdt="0"/> + <char idx="255" wdt="476"/> + </widths> + </singlebyte-extras> +</font-metrics> diff --git a/test/resources/fonts/glb12.ttf.xml b/test/resources/fonts/glb12.ttf.xml new file mode 100644 index 000000000..b4dff29c2 --- /dev/null +++ b/test/resources/fonts/glb12.ttf.xml @@ -0,0 +1,397 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2006 The Apache Software Foundation + + Licensed 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. +--> +<!-- + +Generated from glb12.ttf by Apache FOP's TTFReader + +--> +<font-metrics type="TYPE0"> + <font-name>Gladiator,Bold</font-name> + <embed/> + <cap-height>691</cap-height> + <x-height>0</x-height> + <ascender>765</ascender> + <descender>-234</descender> + <bbox> + <left>-157</left> + <bottom>-250</bottom> + <right>1181</right> + <top>1071</top> + </bbox> + <flags>33</flags> + <stemv>0</stemv> + <italicangle>0</italicangle> + <subtype>TYPE0</subtype> + <multibyte-extras> + <cid-type>CIDFontType2</cid-type> + <default-width>0</default-width> + <bfranges> + <bf gi="33" ue="33" us="32"/> + <bf gi="6" ue="34" us="34"/> + <bf gi="36" ue="38" us="35"/> + <bf gi="5" ue="39" us="39"/> + <bf gi="41" ue="91" us="40"/> + <bf gi="4" ue="92" us="92"/> + <bf gi="94" ue="93" us="93"/> + <bf gi="11" ue="94" us="94"/> + <bf gi="21" ue="96" us="96"/> + <bf gi="98" ue="122" us="97"/> + <bf gi="12" ue="124" us="124"/> + <bf gi="29" ue="126" us="126"/> + <bf gi="9" ue="161" us="161"/> + <bf gi="185" ue="163" us="163"/> + <bf gi="158" ue="167" us="167"/> + <bf gi="128" ue="168" us="168"/> + <bf gi="93" ue="171" us="171"/> + <bf gi="25" ue="175" us="175"/> + <bf gi="22" ue="180" us="180"/> + <bf gi="27" ue="184" us="184"/> + <bf gi="35" ue="187" us="187"/> + <bf gi="10" ue="191" us="191"/> + <bf gi="186" ue="197" us="192"/> + <bf gi="192" ue="214" us="199"/> + <bf gi="209" ue="222" us="216"/> + <bf gi="216" ue="229" us="224"/> + <bf gi="222" ue="246" us="231"/> + <bf gi="239" ue="255" us="248"/> + <bf gi="129" ue="258" us="258"/> + <bf gi="159" ue="259" us="259"/> + <bf gi="130" ue="260" us="260"/> + <bf gi="160" ue="261" us="261"/> + <bf gi="131" ue="262" us="262"/> + <bf gi="161" ue="263" us="263"/> + <bf gi="132" ue="268" us="268"/> + <bf gi="162" ue="269" us="269"/> + <bf gi="133" ue="270" us="270"/> + <bf gi="163" ue="271" us="271"/> + <bf gi="157" ue="273" us="273"/> + <bf gi="135" ue="280" us="280"/> + <bf gi="165" ue="281" us="281"/> + <bf gi="134" ue="282" us="282"/> + <bf gi="164" ue="283" us="283"/> + <bf gi="136" ue="286" us="286"/> + <bf gi="166" ue="287" us="287"/> + <bf gi="156" ue="304" us="304"/> + <bf gi="19" ue="305" us="305"/> + <bf gi="32" ue="307" us="307"/> + <bf gi="137" ue="313" us="313"/> + <bf gi="167" ue="314" us="314"/> + <bf gi="138" ue="317" us="317"/> + <bf gi="168" ue="318" us="318"/> + <bf gi="139" ue="321" us="321"/> + <bf gi="169" ue="322" us="322"/> + <bf gi="140" ue="323" us="323"/> + <bf gi="170" ue="324" us="324"/> + <bf gi="141" ue="327" us="327"/> + <bf gi="171" ue="328" us="328"/> + <bf gi="142" ue="336" us="336"/> + <bf gi="172" ue="337" us="337"/> + <bf gi="208" ue="338" us="338"/> + <bf gi="238" ue="339" us="339"/> + <bf gi="143" ue="340" us="340"/> + <bf gi="173" ue="341" us="341"/> + <bf gi="144" ue="344" us="344"/> + <bf gi="174" ue="345" us="345"/> + <bf gi="145" ue="346" us="346"/> + <bf gi="175" ue="347" us="347"/> + <bf gi="147" ue="350" us="350"/> + <bf gi="177" ue="351" us="351"/> + <bf gi="146" ue="352" us="352"/> + <bf gi="176" ue="353" us="353"/> + <bf gi="149" ue="354" us="354"/> + <bf gi="179" ue="355" us="355"/> + <bf gi="148" ue="356" us="356"/> + <bf gi="151" ue="366" us="366"/> + <bf gi="181" ue="367" us="367"/> + <bf gi="150" ue="368" us="368"/> + <bf gi="180" ue="369" us="369"/> + <bf gi="152" ue="377" us="376"/> + <bf gi="182" ue="378" us="378"/> + <bf gi="155" ue="379" us="379"/> + <bf gi="184" ue="380" us="380"/> + <bf gi="154" ue="381" us="381"/> + <bf gi="183" ue="382" us="382"/> + <bf gi="95" ue="710" us="710"/> + <bf gi="23" ue="711" us="711"/> + <bf gi="24" ue="728" us="728"/> + <bf gi="96" ue="729" us="729"/> + <bf gi="26" ue="730" us="730"/> + <bf gi="30" ue="731" us="731"/> + <bf gi="127" ue="732" us="732"/> + <bf gi="126" ue="733" us="733"/> + <bf gi="28" ue="823" us="823"/> + <bf gi="3" ue="915" us="915"/> + <bf gi="124" ue="8212" us="8211"/> + <bf gi="97" ue="8216" us="8216"/> + <bf gi="40" ue="8217" us="8217"/> + <bf gi="8" ue="8220" us="8220"/> + <bf gi="7" ue="8221" us="8221"/> + <bf gi="20" ue="63166" us="63166"/> + <bf gi="14" ue="64260" us="64256"/> + <bf gi="0" ue="65535" us="65535"/> + </bfranges> + <cid-widths start-index="0"> + <wx w="432"/> + <wx w="0"/> + <wx w="333"/> + <wx w="665"/> + <wx w="500"/> + <wx w="311"/> + <wx w="525"/> + <wx w="525"/> + <wx w="525"/> + <wx w="376"/> + <wx w="569"/> + <wx w="253"/> + <wx w="311"/> + <wx w="0"/> + <wx w="623"/> + <wx w="623"/> + <wx w="623"/> + <wx w="934"/> + <wx w="934"/> + <wx w="311"/> + <wx w="311"/> + <wx w="304"/> + <wx w="304"/> + <wx w="253"/> + <wx w="253"/> + <wx w="253"/> + <wx w="151"/> + <wx w="151"/> + <wx w="235"/> + <wx w="253"/> + <wx w="151"/> + <wx w="623"/> + <wx w="575"/> + <wx w="332"/> + <wx w="376"/> + <wx w="657"/> + <wx w="980"/> + <wx w="625"/> + <wx w="754"/> + <wx w="886"/> + <wx w="311"/> + <wx w="398"/> + <wx w="398"/> + <wx w="601"/> + <wx w="652"/> + <wx w="311"/> + <wx w="331"/> + <wx w="311"/> + <wx w="500"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="541"/> + <wx w="311"/> + <wx w="311"/> + <wx w="500"/> + <wx w="805"/> + <wx w="500"/> + <wx w="569"/> + <wx w="805"/> + <wx w="729"/> + <wx w="708"/> + <wx w="725"/> + <wx w="748"/> + <wx w="683"/> + <wx w="665"/> + <wx w="769"/> + <wx w="808"/> + <wx w="347"/> + <wx w="347"/> + <wx w="769"/> + <wx w="644"/> + <wx w="1109"/> + <wx w="767"/> + <wx w="821"/> + <wx w="689"/> + <wx w="821"/> + <wx w="708"/> + <wx w="689"/> + <wx w="685"/> + <wx w="767"/> + <wx w="689"/> + <wx w="1181"/> + <wx w="729"/> + <wx w="729"/> + <wx w="644"/> + <wx w="542"/> + <wx w="657"/> + <wx w="542"/> + <wx w="253"/> + <wx w="115"/> + <wx w="311"/> + <wx w="515"/> + <wx w="556"/> + <wx w="492"/> + <wx w="556"/> + <wx w="517"/> + <wx w="311"/> + <wx w="556"/> + <wx w="575"/> + <wx w="311"/> + <wx w="311"/> + <wx w="556"/> + <wx w="311"/> + <wx w="839"/> + <wx w="575"/> + <wx w="547"/> + <wx w="556"/> + <wx w="556"/> + <wx w="440"/> + <wx w="492"/> + <wx w="359"/> + <wx w="575"/> + <wx w="476"/> + <wx w="711"/> + <wx w="496"/> + <wx w="476"/> + <wx w="496"/> + <wx w="855"/> + <wx w="1109"/> + <wx w="253"/> + <wx w="253"/> + <wx w="395"/> + <wx w="729"/> + <wx w="729"/> + <wx w="725"/> + <wx w="725"/> + <wx w="748"/> + <wx w="683"/> + <wx w="683"/> + <wx w="769"/> + <wx w="644"/> + <wx w="644"/> + <wx w="644"/> + <wx w="767"/> + <wx w="767"/> + <wx w="821"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="347"/> + <wx w="0"/> + <wx w="0"/> + <wx w="515"/> + <wx w="515"/> + <wx w="492"/> + <wx w="492"/> + <wx w="556"/> + <wx w="517"/> + <wx w="517"/> + <wx w="556"/> + <wx w="311"/> + <wx w="311"/> + <wx w="311"/> + <wx w="575"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="0"/> + <wx w="547"/> + <wx w="729"/> + <wx w="729"/> + <wx w="729"/> + <wx w="729"/> + <wx w="729"/> + <wx w="725"/> + <wx w="683"/> + <wx w="683"/> + <wx w="683"/> + <wx w="683"/> + <wx w="347"/> + <wx w="347"/> + <wx w="347"/> + <wx w="347"/> + <wx w="0"/> + <wx w="767"/> + <wx w="821"/> + <wx w="821"/> + <wx w="821"/> + <wx w="821"/> + <wx w="821"/> + <wx w="0"/> + <wx w="0"/> + <wx w="767"/> + <wx w="767"/> + <wx w="767"/> + <wx w="767"/> + <wx w="729"/> + <wx w="0"/> + <wx w="515"/> + <wx w="515"/> + <wx w="515"/> + <wx w="515"/> + <wx w="515"/> + <wx w="515"/> + <wx w="492"/> + <wx w="517"/> + <wx w="517"/> + <wx w="517"/> + <wx w="517"/> + <wx w="311"/> + <wx w="311"/> + <wx w="311"/> + <wx w="311"/> + <wx w="0"/> + <wx w="575"/> + <wx w="547"/> + <wx w="547"/> + <wx w="547"/> + <wx w="547"/> + <wx w="547"/> + <wx w="0"/> + <wx w="0"/> + <wx w="575"/> + <wx w="575"/> + <wx w="575"/> + <wx w="575"/> + <wx w="476"/> + <wx w="0"/> + <wx w="476"/> + </cid-widths> + </multibyte-extras> +</font-metrics> diff --git a/test/resources/images/cmyk.jpg b/test/resources/images/cmyk.jpg Binary files differnew file mode 100644 index 000000000..cfdcca1aa --- /dev/null +++ b/test/resources/images/cmyk.jpg diff --git a/test/test.xconf b/test/test.xconf new file mode 100644 index 000000000..c0df5b0dd --- /dev/null +++ b/test/test.xconf @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<fop version="1.0"> + <renderers> + <renderer mime="application/pdf"> + <fonts> + <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> + <font-triplet name="Gladiator" style="normal" weight="normal"/> + </font> + <font metrics-url="test/resources/fonts/glb12.ttf.ansi.xml" embed-url="test/resources/fonts/glb12.ttf"> + <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> + </font> + <font metrics-url="test/resources/fonts/glb12.ttf.ansi.xml"> + <font-triplet name="Gladiator-Non-Embedded" style="normal" weight="normal"/> + </font> + </fonts> + </renderer> + </renderers> +</fop> diff --git a/test/xml/pdf-a/base14-font.fo b/test/xml/pdf-a/base14-font.fo new file mode 100644 index 000000000..a33623ec9 --- /dev/null +++ b/test/xml/pdf-a/base14-font.fo @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Helvetica"> + <fo:layout-master-set> + <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="A4"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Hello World!</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/xml/pdf-a/minimal-pdf-a.fo b/test/xml/pdf-a/minimal-pdf-a.fo new file mode 100644 index 000000000..0081be30b --- /dev/null +++ b/test/xml/pdf-a/minimal-pdf-a.fo @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> + <fo:layout-master-set> + <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="A4"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Hello World!</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/xml/pdf-a/with-cmyk-images.fo b/test/xml/pdf-a/with-cmyk-images.fo new file mode 100644 index 000000000..f3429d304 --- /dev/null +++ b/test/xml/pdf-a/with-cmyk-images.fo @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> + <fo:layout-master-set> + <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="A4"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Hello World!</fo:block> + <fo:block><fo:external-graphic src="test/resources/images/cmyk.jpg"/></fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/xml/pdf-a/with-eps.fo b/test/xml/pdf-a/with-eps.fo new file mode 100644 index 000000000..0f8913f01 --- /dev/null +++ b/test/xml/pdf-a/with-eps.fo @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> + <fo:layout-master-set> + <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="A4"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Hello World!</fo:block> + <fo:block><fo:external-graphic src="test/resources/images/barcode.eps"/></fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/xml/pdf-a/with-rgb-images.fo b/test/xml/pdf-a/with-rgb-images.fo new file mode 100644 index 000000000..952da63eb --- /dev/null +++ b/test/xml/pdf-a/with-rgb-images.fo @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> + <fo:layout-master-set> + <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="A4"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Hello World!</fo:block> + <fo:block><fo:external-graphic src="test/resources/images/bgimg300dpi.jpg"/></fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> |