From 26393f0e181ca1c71c83e594fa67cc7c26b49df3 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 25 Aug 2010 15:43:55 +0000 Subject: [PATCH] Removed old Renderer implementations for AFP, PCL, PDF, PS. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@989178 13f79535-47bb-0310-9956-ffa450edef68 --- .../content/xdocs/trunk/configuration.xml | 2 + .../services/org.apache.fop.render.Renderer | 4 - .../org.apache.fop.render.afp.AFPImageHandler | 5 - .../org.apache.fop.render.pdf.PDFImageHandler | 5 - .../apache/fop/cli/CommandLineOptions.java | 6 +- src/java/org/apache/fop/pdf/PDFFactory.java | 3 + .../render/AbstractImageHandlerRegistry.java | 209 --- .../fop/render/afp/AFPImageHandler.java | 41 - .../render/afp/AFPImageHandlerGraphics2D.java | 41 - .../render/afp/AFPImageHandlerRegistry.java | 42 - .../afp/AFPImageHandlerRenderedImage.java | 20 - .../fop/render/afp/AFPImageHandlerXML.java | 77 - .../apache/fop/render/afp/AFPRenderer.java | 924 ---------- .../render/afp/AFPRendererConfigurator.java | 23 +- .../fop/render/afp/AFPRendererMaker.java | 58 - .../apache/fop/render/afp/AFPSVGHandler.java | 2 +- .../afp/AbstractAFPImageHandlerRawStream.java | 15 - .../fop/render/pcl/PCLGraphics2DAdapter.java | 123 -- .../apache/fop/render/pcl/PCLRenderer.java | 1516 ----------------- .../render/pcl/PCLRendererConfigurator.java | 16 +- .../fop/render/pcl/PCLRendererMaker.java | 57 - .../apache/fop/render/pcl/PCLSVGHandler.java | 3 +- .../fop/render/pdf/PDFGraphics2DAdapter.java | 132 -- .../fop/render/pdf/PDFImageHandler.java | 52 - .../render/pdf/PDFImageHandlerGraphics2D.java | 29 +- .../pdf/PDFImageHandlerRawCCITTFax.java | 29 +- .../render/pdf/PDFImageHandlerRawJPEG.java | 29 +- .../render/pdf/PDFImageHandlerRegistry.java | 36 - .../pdf/PDFImageHandlerRenderedImage.java | 29 +- .../fop/render/pdf/PDFImageHandlerXML.java | 72 - .../apache/fop/render/pdf/PDFRenderer.java | 1361 --------------- .../render/pdf/PDFRendererConfigurator.java | 40 +- .../fop/render/pdf/PDFRendererMaker.java | 55 - .../apache/fop/render/pdf/PDFSVGHandler.java | 159 +- .../fop/render/ps/PSGraphics2DAdapter.java | 14 +- .../org/apache/fop/render/ps/PSRenderer.java | 1290 -------------- .../fop/render/ps/PSRendererConfigurator.java | 16 +- .../apache/fop/render/ps/PSRendererMaker.java | 54 - .../apache/fop/render/ps/PSSVGHandler.java | 2 +- status.xml | 4 + .../org/apache/fop/StandardTestSuite.java | 2 - .../fop/fonts/TrueTypeAnsiTestCase.java | 107 -- test/java/org/apache/fop/fonts/fonttest.xsl | 24 - .../fop/render/RendererFactoryTest.java | 15 - .../fop/render/ps/ImageHandlingTestCase.java | 48 +- .../ps/ResourceOptimizationTestCase.java | 22 +- 46 files changed, 60 insertions(+), 6753 deletions(-) delete mode 100644 src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler delete mode 100644 src/java/META-INF/services/org.apache.fop.render.pdf.PDFImageHandler delete mode 100644 src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java delete mode 100644 src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java delete mode 100644 src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java delete mode 100644 src/java/org/apache/fop/render/afp/AFPRenderer.java delete mode 100644 src/java/org/apache/fop/render/afp/AFPRendererMaker.java delete mode 100644 src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java delete mode 100644 src/java/org/apache/fop/render/pcl/PCLRenderer.java delete mode 100644 src/java/org/apache/fop/render/pcl/PCLRendererMaker.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFImageHandler.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFRenderer.java delete mode 100644 src/java/org/apache/fop/render/pdf/PDFRendererMaker.java delete mode 100644 src/java/org/apache/fop/render/ps/PSRenderer.java delete mode 100644 src/java/org/apache/fop/render/ps/PSRendererMaker.java delete mode 100644 test/java/org/apache/fop/fonts/TrueTypeAnsiTestCase.java delete mode 100644 test/java/org/apache/fop/fonts/fonttest.xsl diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml index 0f4100bf7..aae7de7f0 100644 --- a/src/documentation/content/xdocs/trunk/configuration.xml +++ b/src/documentation/content/xdocs/trunk/configuration.xml @@ -151,6 +151,7 @@ default-page-settings element to specify the two values. "height" 11 inches, "width" 8.26 inches + use-cache boolean (true, false) diff --git a/src/java/META-INF/services/org.apache.fop.render.Renderer b/src/java/META-INF/services/org.apache.fop.render.Renderer index 0e6f12cb5..2bf59a805 100644 --- a/src/java/META-INF/services/org.apache.fop.render.Renderer +++ b/src/java/META-INF/services/org.apache.fop.render.Renderer @@ -1,10 +1,6 @@ -org.apache.fop.render.pdf.PDFRendererMaker -org.apache.fop.render.ps.PSRendererMaker org.apache.fop.render.txt.TXTRendererMaker org.apache.fop.render.bitmap.PNGRendererMaker org.apache.fop.render.bitmap.TIFFRendererMaker org.apache.fop.render.xml.XMLRendererMaker org.apache.fop.render.awt.AWTRendererMaker org.apache.fop.render.print.PrintRendererMaker -org.apache.fop.render.afp.AFPRendererMaker -org.apache.fop.render.pcl.PCLRendererMaker \ No newline at end of file diff --git a/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler b/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler deleted file mode 100644 index 3f8c8dea6..000000000 --- a/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler +++ /dev/null @@ -1,5 +0,0 @@ -org.apache.fop.render.afp.AFPImageHandlerRenderedImage -org.apache.fop.render.afp.AFPImageHandlerRawCCITTFax -org.apache.fop.render.afp.AFPImageHandlerRawStream -org.apache.fop.render.afp.AFPImageHandlerGraphics2D -org.apache.fop.render.afp.AFPImageHandlerXML diff --git a/src/java/META-INF/services/org.apache.fop.render.pdf.PDFImageHandler b/src/java/META-INF/services/org.apache.fop.render.pdf.PDFImageHandler deleted file mode 100644 index 18fc3e96a..000000000 --- a/src/java/META-INF/services/org.apache.fop.render.pdf.PDFImageHandler +++ /dev/null @@ -1,5 +0,0 @@ -org.apache.fop.render.pdf.PDFImageHandlerRawJPEG -org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax -org.apache.fop.render.pdf.PDFImageHandlerGraphics2D -org.apache.fop.render.pdf.PDFImageHandlerRenderedImage -org.apache.fop.render.pdf.PDFImageHandlerXML diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index fbd263633..6b4ec1a1d 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -51,7 +51,7 @@ import org.apache.fop.render.awt.AWTRenderer; import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.intermediate.IFSerializer; -import org.apache.fop.render.pdf.PDFRenderer; +import org.apache.fop.render.pdf.PDFConfigurationConstants; import org.apache.fop.render.print.PagesMode; import org.apache.fop.render.print.PrintRenderer; import org.apache.fop.render.xml.XMLRenderer; @@ -805,14 +805,14 @@ public class CommandLineOptions { private PDFEncryptionParams getPDFEncryptionParams() throws FOPException { PDFEncryptionParams params = (PDFEncryptionParams)renderingOptions.get( - PDFRenderer.ENCRYPTION_PARAMS); + PDFConfigurationConstants.ENCRYPTION_PARAMS); if (params == null) { if (!PDFEncryptionManager.checkAvailableAlgorithms()) { throw new FOPException("PDF encryption requested but it is not available." + " Please make sure MD5 and RC4 algorithms are available."); } params = new PDFEncryptionParams(); - renderingOptions.put(PDFRenderer.ENCRYPTION_PARAMS, params); + renderingOptions.put(PDFConfigurationConstants.ENCRYPTION_PARAMS, params); } return params; } diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index 4c00f3187..8ebd15127 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -65,6 +65,9 @@ import org.apache.fop.fonts.type1.PFBParser; */ public class PDFFactory { + /** Resolution of the User Space coordinate system (72dpi). */ + public static final int DEFAULT_PDF_RESOLUTION = 72; + private PDFDocument document; private Log log = LogFactory.getLog(PDFFactory.class); diff --git a/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java b/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java deleted file mode 100644 index 4196a1b19..000000000 --- a/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.Image; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.util.Service; - -/** - * This class holds references to various image handlers used by the renderers. It also - * supports automatic discovery of additional handlers available through - * the class path. - */ -public abstract class AbstractImageHandlerRegistry { - - /** the logger */ - private static Log log = LogFactory.getLog(AbstractImageHandlerRegistry.class); - - private static final Comparator HANDLER_COMPARATOR = new Comparator() { - public int compare(Object o1, Object o2) { - ImageHandlerBase h1 = (ImageHandlerBase)o1; - ImageHandlerBase h2 = (ImageHandlerBase)o2; - return h1.getPriority() - h2.getPriority(); - } - }; - - /** Map containing image handlers for various MIME types */ - private final Map/**/ handlers - = new java.util.HashMap/**/(); - - /** List containing the same handlers as above but ordered by priority */ - private final List/**/ handlerList - = new java.util.LinkedList/**/(); - - /** Sorted Set of registered handlers */ - private ImageFlavor[] supportedFlavors = new ImageFlavor[0]; - - private int handlerRegistrations; - private int lastSync; - - /** - * Default constructor. - */ - public AbstractImageHandlerRegistry() { - discoverHandlers(); - } - - /** - * Add an ImageHandler. The handler itself is inspected to find out what it supports. - * @param classname the fully qualified class name - */ - public void addHandler(String classname) { - try { - ImageHandlerBase handlerInstance - = (ImageHandlerBase)Class.forName(classname).newInstance(); - addHandler(handlerInstance); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Could not find " - + classname); - } catch (InstantiationException e) { - throw new IllegalArgumentException("Could not instantiate " - + classname); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Could not access " - + classname); - } catch (ClassCastException e) { - throw new IllegalArgumentException(classname - + " is not an " - + getHandlerClass().getName()); - } - } - - /** - * Add an image handler. The handler itself is inspected to find out what it supports. - * @param handler the ImageHandler instance - */ - public synchronized void addHandler(ImageHandlerBase handler) { - this.handlers.put(handler.getSupportedImageClass(), handler); - - //Sorted insert - ListIterator iter = this.handlerList.listIterator(); - while (iter.hasNext()) { - ImageHandlerBase h = (ImageHandlerBase)iter.next(); - if (getHandlerComparator().compare(handler, h) < 0) { - iter.previous(); - break; - } - } - iter.add(handler); - this.handlerRegistrations++; - } - - /** - * Returns an ImageHandler which handles an specific image type given the MIME type - * of the image. - * @param img the Image to be handled - * @return the ImageHandler responsible for handling the image or null if none is available - */ - public ImageHandlerBase getHandler(Image img) { - return getHandler(img.getClass()); - } - - /** - * Returns an ImageHandler which handles an specific image type given the MIME type - * of the image. - * @param imageClass the Image subclass for which to get a handler - * @return the ImageHandler responsible for handling the image or null if none is available - */ - public synchronized ImageHandlerBase getHandler(Class imageClass) { - ImageHandlerBase handler = null; - Class cl = imageClass; - while (cl != null) { - handler = (ImageHandlerBase)handlers.get(cl); - if (handler != null) { - break; - } - cl = cl.getSuperclass(); - } - return handler; - } - - /** - * Returns the ordered array of supported image flavors. - * @return the array of image flavors - */ - public synchronized ImageFlavor[] getSupportedFlavors() { - if (this.lastSync != this.handlerRegistrations) { - //Extract all ImageFlavors into a single array - List flavors = new java.util.ArrayList(); - Iterator iter = this.handlerList.iterator(); - while (iter.hasNext()) { - ImageFlavor[] f = ((ImageHandlerBase)iter.next()).getSupportedImageFlavors(); - for (int i = 0; i < f.length; i++) { - flavors.add(f[i]); - } - } - this.supportedFlavors = (ImageFlavor[])flavors.toArray(new ImageFlavor[flavors.size()]); - this.lastSync = this.handlerRegistrations; - } - return this.supportedFlavors; - } - - /** - * Discovers ImageHandler implementations through the classpath and dynamically - * registers them. - */ - private void discoverHandlers() { - // add mappings from available services - Class imageHandlerClass = getHandlerClass(); - Iterator providers = Service.providers(imageHandlerClass); - if (providers != null) { - while (providers.hasNext()) { - ImageHandlerBase handler = (ImageHandlerBase)providers.next(); - try { - if (log.isDebugEnabled()) { - log.debug("Dynamically adding ImageHandler: " - + handler.getClass().getName()); - } - addHandler(handler); - } catch (IllegalArgumentException e) { - log.error("Error while adding ImageHandler", e); - } - - } - } - } - - /** - * Returns the ImageHandler comparator - * - * @return the ImageHandler comparator - */ - public Comparator getHandlerComparator() { - return HANDLER_COMPARATOR; - } - - /** - * Returns the ImageHandler implementing class - * - * @return the ImageHandler implementing class - */ - public abstract Class getHandlerClass(); -} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandler.java b/src/java/org/apache/fop/render/afp/AFPImageHandler.java index 4a985db00..244263213 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandler.java @@ -19,10 +19,7 @@ package org.apache.fop.render.afp; -import java.awt.Point; import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.io.IOException; import java.util.Map; import org.apache.fop.afp.AFPDataObjectInfo; @@ -43,44 +40,6 @@ public abstract class AFPImageHandler implements ImageHandlerBase { private final AFPForeignAttributeReader foreignAttributeReader = new AFPForeignAttributeReader(); - /** - * Generates an intermediate AFPDataObjectInfo that is later used to construct - * the appropriate data object in the AFP DataStream. - * - * @param rendererImageInfo the renderer image info - * @return a data object info object - * @throws IOException thrown if an I/O exception of some sort has occurred. - */ - public AFPDataObjectInfo generateDataObjectInfo( - AFPRendererImageInfo rendererImageInfo) throws IOException { - AFPDataObjectInfo dataObjectInfo = createDataObjectInfo(); - - // set resource information - setResourceInformation(dataObjectInfo, - rendererImageInfo.getURI(), - rendererImageInfo.getForeignAttributes()); - - - Point origin = rendererImageInfo.getOrigin(); - Rectangle2D position = rendererImageInfo.getPosition(); - int srcX = Math.round(origin.x + (float)position.getX()); - int srcY = Math.round(origin.y + (float)position.getY()); - Rectangle targetRect = new Rectangle( - srcX, - srcY, - (int)Math.round(position.getWidth()), - (int)Math.round(position.getHeight())); - - AFPRendererContext rendererContext - = (AFPRendererContext)rendererImageInfo.getRendererContext(); - AFPInfo afpInfo = rendererContext.getInfo(); - AFPPaintingState paintingState = afpInfo.getPaintingState(); - - dataObjectInfo.setObjectAreaInfo(createObjectAreaInfo(paintingState, targetRect)); - - return dataObjectInfo; - } - /** * Sets resource information on the data object info. * @param dataObjectInfo the data object info instance diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java index aaaecf2ea..07b712ceb 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java @@ -49,47 +49,6 @@ public class AFPImageHandlerGraphics2D extends AFPImageHandler implements ImageH ImageFlavor.GRAPHICS2D }; - /** {@inheritDoc} */ - public AFPDataObjectInfo generateDataObjectInfo( - AFPRendererImageInfo rendererImageInfo) throws IOException { - - AFPRendererContext rendererContext - = (AFPRendererContext)rendererImageInfo.getRendererContext(); - AFPInfo afpInfo = rendererContext.getInfo(); - ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage(); - Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter(); - - if (afpInfo.paintAsBitmap()) { - int x = afpInfo.getX(); - int y = afpInfo.getY(); - int width = afpInfo.getWidth(); - int height = afpInfo.getHeight(); - AFPPaintingState paintingState = afpInfo.getPaintingState(); - AFPGraphics2DAdapter g2dAdapter = new AFPGraphics2DAdapter(paintingState); - g2dAdapter.paintImage(painter, rendererContext, x, y, width, height); - return null; - } else { - AFPGraphicsObjectInfo graphicsObjectInfo - = (AFPGraphicsObjectInfo)super.generateDataObjectInfo(rendererImageInfo); - - setDefaultResourceLevel(graphicsObjectInfo, afpInfo.getResourceManager()); - - // set mime type (unsupported by MOD:CA registry) - graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA); - - // set g2d - boolean textAsShapes = false; - AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes); - - graphicsObjectInfo.setGraphics2D(g2d); - - // set painter - graphicsObjectInfo.setPainter(painter); - - return graphicsObjectInfo; - } - } - private void setDefaultResourceLevel(AFPGraphicsObjectInfo graphicsObjectInfo, AFPResourceManager resourceManager) { AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo(); diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java deleted file mode 100644 index 59ca6cf38..000000000 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import org.apache.fop.render.AbstractImageHandlerRegistry; - -/** - * This class holds references to various image handlers used by the AFP renderer. It also - * supports automatic discovery of additional handlers available through - * the class path. - */ -public class AFPImageHandlerRegistry extends AbstractImageHandlerRegistry { - - /** - * Main constructor - */ - public AFPImageHandlerRegistry() { - } - - /** {@inheritDoc} */ - public Class getHandlerClass() { - return AFPImageHandler.class; - } - -} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java index 09b93d41a..ca0544542 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@ -66,26 +66,6 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima ImageFlavor.RENDERED_IMAGE }; - /** {@inheritDoc} */ - public AFPDataObjectInfo generateDataObjectInfo( - AFPRendererImageInfo rendererImageInfo) throws IOException { - AFPImageObjectInfo imageObjectInfo - = (AFPImageObjectInfo)super.generateDataObjectInfo(rendererImageInfo); - - AFPRendererContext rendererContext - = (AFPRendererContext)rendererImageInfo.getRendererContext(); - AFPInfo afpInfo = rendererContext.getInfo(); - - setDefaultResourceLevel(imageObjectInfo, afpInfo.getResourceManager()); - - AFPPaintingState paintingState = afpInfo.getPaintingState(); - ImageRendered imageRendered = (ImageRendered) rendererImageInfo.img; - Dimension targetSize = new Dimension(afpInfo.getWidth(), afpInfo.getHeight()); - - updateDataObjectInfo(imageObjectInfo, paintingState, imageRendered, targetSize); - return imageObjectInfo; - } - private AFPDataObjectInfo updateDataObjectInfo // CSOK: MethodLength (AFPImageObjectInfo imageObjectInfo, AFPPaintingState paintingState, ImageRendered imageRendered, Dimension targetSize) diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java deleted file mode 100644 index 7ea1a7a10..000000000 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.util.Map; - -import org.apache.fop.afp.AFPDataObjectInfo; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.RendererContextConstants; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; -import org.w3c.dom.Document; - -/** - * PDFImageHandler implementation which handles XML-based images. - */ -public class AFPImageHandlerXML extends AFPImageHandler { - - private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { - ImageFlavor.XML_DOM, - }; - - /** {@inheritDoc} */ - public AFPDataObjectInfo generateDataObjectInfo(AFPRendererImageInfo rendererImageInfo) - throws IOException { - RendererContext rendererContext = rendererImageInfo.getRendererContext(); - AFPRenderer renderer = (AFPRenderer)rendererContext.getRenderer(); - ImageXMLDOM imgXML = (ImageXMLDOM)rendererImageInfo.getImage(); - Document doc = imgXML.getDocument(); - String ns = imgXML.getRootNamespace(); - Map foreignAttributes = (Map)rendererContext.getProperty( - RendererContextConstants.FOREIGN_ATTRIBUTES); - Rectangle2D pos = rendererImageInfo.getPosition(); - renderer.renderDocument(doc, ns, pos, foreignAttributes); - return null; - } - - /** {@inheritDoc} */ - public int getPriority() { - return 400; - } - - /** {@inheritDoc} */ - public Class getSupportedImageClass() { - return ImageXMLDOM.class; - } - - /** {@inheritDoc} */ - public ImageFlavor[] getSupportedImageFlavors() { - return FLAVORS; - } - - /** {@inheritDoc} */ - protected AFPDataObjectInfo createDataObjectInfo() { - return null; - } - -} diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java deleted file mode 100644 index df6cf2c5f..000000000 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ /dev/null @@ -1,924 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import java.awt.Color; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.RenderedImage; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.image.loader.util.ImageUtil; -import org.apache.xmlgraphics.ps.ImageEncodingHelper; - -import org.apache.fop.ResourceEventProducer; -import org.apache.fop.afp.AFPBorderPainter; -import org.apache.fop.afp.AFPDataObjectInfo; -import org.apache.fop.afp.AFPDitheredRectanglePainter; -import org.apache.fop.afp.AFPEventProducer; -import org.apache.fop.afp.AFPPaintingState; -import org.apache.fop.afp.AFPRectanglePainter; -import org.apache.fop.afp.AFPResourceLevelDefaults; -import org.apache.fop.afp.AFPResourceManager; -import org.apache.fop.afp.AFPTextDataInfo; -import org.apache.fop.afp.AFPUnitConverter; -import org.apache.fop.afp.AbstractAFPPainter; -import org.apache.fop.afp.BorderPaintingInfo; -import org.apache.fop.afp.DataStream; -import org.apache.fop.afp.RectanglePaintingInfo; -import org.apache.fop.afp.fonts.AFPFont; -import org.apache.fop.afp.fonts.AFPFontAttributes; -import org.apache.fop.afp.fonts.AFPFontCollection; -import org.apache.fop.afp.fonts.AFPPageFonts; -import org.apache.fop.afp.fonts.CharacterSet; -import org.apache.fop.afp.modca.PageObject; -import org.apache.fop.afp.modca.ResourceObject; -import org.apache.fop.afp.util.DefaultFOPResourceAccessor; -import org.apache.fop.afp.util.ResourceAccessor; -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.area.CTM; -import org.apache.fop.area.OffDocumentExtensionAttachment; -import org.apache.fop.area.OffDocumentItem; -import org.apache.fop.area.PageSequence; -import org.apache.fop.area.PageViewport; -import org.apache.fop.area.Trait; -import org.apache.fop.area.inline.Image; -import org.apache.fop.area.inline.Leader; -import org.apache.fop.area.inline.TextArea; -import org.apache.fop.datatypes.URISpecification; -import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontCollection; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontManager; -import org.apache.fop.render.AbstractPathOrientedRenderer; -import org.apache.fop.render.Graphics2DAdapter; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.afp.extensions.AFPElementMapping; -import org.apache.fop.render.afp.extensions.AFPExtensionAttachment; -import org.apache.fop.render.afp.extensions.AFPIncludeFormMap; -import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap; -import org.apache.fop.render.afp.extensions.AFPPageOverlay; -import org.apache.fop.render.afp.extensions.AFPPageSetup; - -/** - * This is an implementation of a FOP Renderer that renders areas to AFP. - *

- * A renderer is primarily designed to convert a given area tree into the output - * document format. It should be able to produce pages and fill the pages with - * the text and graphical content. Usually the output is sent to an output - * stream. Some output formats may support extra information that is not - * available from the area tree or depends on the destination of the document. - * Each renderer is given an area tree to render to its output format. The area - * tree is simply a representation of the pages and the placement of text and - * graphical objects on those pages. - *

- *

- * The renderer will be given each page as it is ready and an output stream to - * write the data out. All pages are supplied in the order they appear in the - * document. In order to save memory it is possible to render the pages out of - * order. Any page that is not ready to be rendered is setup by the renderer - * first so that it can reserve a space or reference for when the page is ready - * to be rendered.The renderer is responsible for managing the output format and - * associated data and flow. - *

- *

- * Each renderer is totally responsible for its output format. Because font - * metrics (and therefore layout) are obtained in two different ways depending - * on the renderer, the renderer actually sets up the fonts being used. The font - * metrics are used during the layout process to determine the size of - * characters. - *

- *

- * The render context is used by handlers. It contains information about the - * current state of the renderer, such as the page, the position, and any other - * miscellaneous objects that are required to draw into the page. - *

- *

- * A renderer is created by implementing the Renderer interface. However, the - * AbstractRenderer does most of what is needed, including iterating through the - * tree parts, so it is this that is extended. This means that this object only - * need to implement the basic functionality such as text, images, and lines. - * AbstractRenderer's methods can easily be overridden to handle things in a - * different way or do some extra processing. - *

- *

- * The relevant AreaTree structures that will need to be rendered are Page, - * Viewport, Region, Span, Block, Line, Inline. A renderer implementation - * renders each individual page, clips and aligns child areas to a viewport, - * handle all types of inline area, text, image etc and draws various lines and - * rectangles. - *

- * - * Note: There are specific extensions that have been added to the FO. They are - * specific to their location within the FO and have to be processed accordingly - * (ie. at the start or end of the page). - * - */ -public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCustomizable { - - private static final int X = 0; - private static final int Y = 1; - - /** the resource manager */ - private AFPResourceManager resourceManager; - - /** the painting state */ - private final AFPPaintingState paintingState; - - /** unit converter */ - private final AFPUnitConverter unitConv; - - /** the line painter */ - private AFPBorderPainter borderPainter; - - /** the map of page segments */ - private final Map/**/pageSegmentMap - = new java.util.HashMap/**/(); - - /** the map of saved incomplete pages */ - private final Map pages = new java.util.HashMap/**/(); - - /** the AFP datastream */ - private DataStream dataStream; - - /** the image handler registry */ - private final AFPImageHandlerRegistry imageHandlerRegistry; - - private AbstractAFPPainter rectanglePainter; - - /** the shading mode for filled rectangles */ - private AFPShadingMode shadingMode = AFPShadingMode.COLOR; - - /** medium map referenced used on previous page **/ - private String lastMediumMap; - - /** - * Constructor for AFPRenderer. - */ - public AFPRenderer() { - super(); - this.imageHandlerRegistry = new AFPImageHandlerRegistry(); - this.resourceManager = new AFPResourceManager(); - this.paintingState = new AFPPaintingState(); - this.unitConv = paintingState.getUnitConverter(); - } - - /** {@inheritDoc} */ - public void setupFontInfo(FontInfo inFontInfo) { - this.fontInfo = inFontInfo; - FontManager fontManager = userAgent.getFactory().getFontManager(); - FontCollection[] fontCollections = new FontCollection[] { - new AFPFontCollection(userAgent.getEventBroadcaster(), getFontList()) - }; - fontManager.setup(getFontInfo(), fontCollections); - } - - /** {@inheritDoc} */ - public void setUserAgent(FOUserAgent agent) { - super.setUserAgent(agent); - } - - /** {@inheritDoc} */ - public void startRenderer(OutputStream outputStream) throws IOException { - paintingState.setColor(Color.WHITE); - - this.dataStream = resourceManager.createDataStream(paintingState, outputStream); - this.borderPainter = new AFPBorderPainter(paintingState, dataStream); - this.rectanglePainter = createRectanglePainter(); - - dataStream.startDocument(); - } - - AbstractAFPPainter createRectanglePainter() { - if (AFPShadingMode.DITHERED.equals(this.shadingMode)) { - return new AFPDitheredRectanglePainter( - this.paintingState, this.dataStream, this.resourceManager); - } else { - return new AFPRectanglePainter( - this.paintingState, this.dataStream); - } - } - - /** {@inheritDoc} */ - public void stopRenderer() throws IOException { - dataStream.endDocument(); - resourceManager.writeToStream(); - resourceManager = null; - } - - /** {@inheritDoc} */ - public void startPageSequence(PageSequence pageSequence) { - super.startPageSequence(pageSequence); - try { - dataStream.startPageGroup(); - } catch (IOException e) { - log.error(e.getMessage()); - } - if (pageSequence.hasExtensionAttachments()) { - for (Iterator iter = pageSequence.getExtensionAttachments().iterator(); - iter.hasNext();) { - ExtensionAttachment attachment = (ExtensionAttachment)iter.next(); - if (attachment instanceof AFPInvokeMediumMap) { - AFPInvokeMediumMap imm = (AFPInvokeMediumMap)attachment; - String mediumMap = imm.getName(); - if (mediumMap != null) { - dataStream.createInvokeMediumMap(mediumMap); - } - } else if (attachment instanceof AFPPageSetup) { - AFPPageSetup aps = (AFPPageSetup)attachment; - String name = aps.getName(); - String value = aps.getValue(); - dataStream.createTagLogicalElement(name, value); - } - } - } - } - - /** {@inheritDoc} */ - public boolean supportsOutOfOrder() { - return false; - } - - /** {@inheritDoc} */ - public void preparePage(PageViewport page) { - int pageRotation = paintingState.getPageRotation(); - int pageWidth = paintingState.getPageWidth(); - int pageHeight = paintingState.getPageHeight(); - int resolution = paintingState.getResolution(); - dataStream.startPage(pageWidth, pageHeight, pageRotation, - resolution, resolution); - - renderPageObjectExtensions(page); - - PageObject currentPage = dataStream.savePage(); - pages.put(page, currentPage); - } - - /** {@inheritDoc} */ - public void processOffDocumentItem(OffDocumentItem odi) { - if (odi instanceof OffDocumentExtensionAttachment) { - ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)odi).getAttachment(); - if (attachment != null) { - if (AFPExtensionAttachment.CATEGORY.equals(attachment.getCategory())) { - if (attachment instanceof AFPIncludeFormMap) { - handleIncludeFormMap((AFPIncludeFormMap)attachment); - } - } - } - } - } - - private void handleIncludeFormMap(AFPIncludeFormMap formMap) { - ResourceAccessor accessor = new DefaultFOPResourceAccessor( - getUserAgent(), null, null); - try { - this.resourceManager.createIncludedResource(formMap.getName(), - formMap.getSrc(), accessor, - ResourceObject.TYPE_FORMDEF); - } catch (IOException ioe) { - AFPEventProducer eventProducer - = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster()); - eventProducer.resourceEmbeddingError(this, formMap.getName(), ioe); - } - } - - /** {@inheritDoc} */ - public Graphics2DAdapter getGraphics2DAdapter() { - return new AFPGraphics2DAdapter(paintingState); - } - - /** {@inheritDoc} */ - public void startVParea(CTM ctm, Rectangle2D clippingRect) { - saveGraphicsState(); - if (ctm != null) { - AffineTransform at = ctm.toAffineTransform(); - concatenateTransformationMatrix(at); - } - if (clippingRect != null) { - clipRect((float)clippingRect.getX() / 1000f, - (float)clippingRect.getY() / 1000f, - (float)clippingRect.getWidth() / 1000f, - (float)clippingRect.getHeight() / 1000f); - } - } - - /** {@inheritDoc} */ - public void endVParea() { - restoreGraphicsState(); - } - - /** {@inheritDoc} */ - protected void concatenateTransformationMatrix(AffineTransform at) { - if (!at.isIdentity()) { - paintingState.concatenate(at); - } - } - - /** - * Returns the base AFP transform - * - * @return the base AFP transform - */ - private AffineTransform getBaseTransform() { - AffineTransform baseTransform = new AffineTransform(); - double scale = unitConv.mpt2units(1); - baseTransform.scale(scale, scale); - return baseTransform; - } - - /** {@inheritDoc} */ - public void renderPage(PageViewport pageViewport) throws IOException, FOPException { - paintingState.clear(); - - Rectangle2D bounds = pageViewport.getViewArea(); - - AffineTransform baseTransform = getBaseTransform(); - paintingState.concatenate(baseTransform); - - if (pages.containsKey(pageViewport)) { - dataStream.restorePage( - (PageObject)pages.remove(pageViewport)); - } else { - int pageWidth - = Math.round(unitConv.mpt2units((float)bounds.getWidth())); - paintingState.setPageWidth(pageWidth); - - int pageHeight - = Math.round(unitConv.mpt2units((float)bounds.getHeight())); - paintingState.setPageHeight(pageHeight); - - int pageRotation = paintingState.getPageRotation(); - - int resolution = paintingState.getResolution(); - - // IMM should occur before BPG - renderInvokeMediumMap(pageViewport); - - dataStream.startPage(pageWidth, pageHeight, pageRotation, - resolution, resolution); - - renderPageObjectExtensions(pageViewport); - } - - super.renderPage(pageViewport); - - AFPPageFonts pageFonts = paintingState.getPageFonts(); - if (pageFonts != null && !pageFonts.isEmpty()) { - dataStream.addFontsToCurrentPage(pageFonts); - } - - dataStream.endPage(); - } - - /** {@inheritDoc} */ - public void drawBorderLine // CSOK: ParameterNumber - (float x1, float y1, float x2, float y2, - boolean horz, boolean startOrBefore, int style, Color col) { - BorderPaintingInfo borderPaintInfo - = new BorderPaintingInfo(x1, y1, x2, y2, horz, style, col); - borderPainter.paint(borderPaintInfo); - } - - /** {@inheritDoc} */ - public void fillRect(float x, float y, float width, float height) { - RectanglePaintingInfo rectanglePaintInfo = new RectanglePaintingInfo(x, y, width, height); - try { - rectanglePainter.paint(rectanglePaintInfo); - } catch (IOException ioe) { - //TODO not ideal, but the AFPRenderer is legacy - throw new RuntimeException("I/O error while painting a filled rectangle", ioe); - } - } - - /** {@inheritDoc} */ - protected RendererContext instantiateRendererContext() { - return new AFPRendererContext(this, getMimeType()); - } - - /** {@inheritDoc} */ - protected RendererContext createRendererContext(int x, int y, int width, - int height, Map foreignAttributes) { - RendererContext context; - context = super.createRendererContext(x, y, width, height, - foreignAttributes); - context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO, - this.fontInfo); - context.setProperty(AFPRendererContextConstants.AFP_RESOURCE_MANAGER, - this.resourceManager); - context.setProperty(AFPRendererContextConstants.AFP_PAINTING_STATE, paintingState); - return context; - } - - private static final ImageFlavor[] NATIVE_FLAVORS = new ImageFlavor[] { - ImageFlavor.XML_DOM, - /*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP - ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS, - ImageFlavor.RAW_TIFF, - ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; - - private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { - ImageFlavor.XML_DOM, - ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; - - /** {@inheritDoc} */ - public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { - uri = URISpecification.getURL(uri); - paintingState.setImageUri(uri); - - Point origin = new Point(currentIPPosition, currentBPPosition); - Rectangle posInt = new Rectangle( - (int)Math.round(pos.getX()), - (int)Math.round(pos.getY()), - (int)Math.round(pos.getWidth()), - (int)Math.round(pos.getHeight()) - ); - int x = origin.x + posInt.x; - int y = origin.y + posInt.y; - - String name = (String)pageSegmentMap.get(uri); - if (name != null) { - float[] srcPts = {x, y, posInt.width, posInt.height}; - int[] coords = unitConv.mpts2units(srcPts); - int width = Math.round(unitConv.mpt2units(posInt.width)); - int height = Math.round(unitConv.mpt2units(posInt.height)); - dataStream.createIncludePageSegment(name, coords[X], coords[Y], width, height); - } else { - ImageManager manager = userAgent.getFactory().getImageManager(); - ImageInfo info = null; - try { - ImageSessionContext sessionContext = userAgent - .getImageSessionContext(); - info = manager.getImageInfo(uri, sessionContext); - - // Only now fully load/prepare the image - Map hints = ImageUtil.getDefaultHints(sessionContext); - - boolean nativeImagesSupported = paintingState.isNativeImagesSupported(); - ImageFlavor[] flavors = nativeImagesSupported ? NATIVE_FLAVORS : FLAVORS; - - // Load image - org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, flavors, hints, sessionContext); - - // Handle image - AFPImageHandler imageHandler - = (AFPImageHandler)imageHandlerRegistry.getHandler(img); - if (imageHandler != null) { - RendererContext rendererContext = createRendererContext( - x, y, posInt.width, posInt.height, foreignAttributes); - AFPRendererImageInfo rendererImageInfo = new AFPRendererImageInfo( - uri, pos, origin, info, img, rendererContext, foreignAttributes); - AFPDataObjectInfo dataObjectInfo = null; - try { - dataObjectInfo = imageHandler.generateDataObjectInfo(rendererImageInfo); - // Create image - if (dataObjectInfo != null) { - resourceManager.createObject(dataObjectInfo); - } - } catch (IOException ioe) { - ResourceEventProducer eventProducer - = ResourceEventProducer.Provider.get(userAgent.getEventBroadcaster()); - eventProducer.imageWritingError(this, ioe); - throw ioe; - } - } else { - throw new UnsupportedOperationException( - "No AFPImageHandler available for image: " - + info + " (" + img.getClass().getName() + ")"); - } - - } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider - .get(userAgent.getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() - : uri), ie, null); - } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider - .get(userAgent.getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() - : uri), fe, null); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider - .get(userAgent.getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() - : uri), ioe, null); - } - } - } - - /** - * Writes a RenderedImage to an OutputStream as raw sRGB bitmaps. - * - * @param image - * the RenderedImage - * @param out - * the OutputStream - * @throws IOException - * In case of an I/O error. - * @deprecated use ImageEncodingHelper.encodeRenderedImageAsRGB(image, out) - * directly instead - */ - public static void writeImage(RenderedImage image, OutputStream out) - throws IOException { - ImageEncodingHelper.encodeRenderedImageAsRGB(image, out); - } - - /** {@inheritDoc} */ - public void updateColor(Color col, boolean fill) { - if (fill) { - paintingState.setColor(col); - } - } - - /** {@inheritDoc} */ - public void restoreStateStackAfterBreakOut(List breakOutList) { - log.debug("Block.FIXED --> restoring context after break-out"); - paintingState.saveAll(breakOutList); - } - - /** {@inheritDoc} */ - protected List breakOutOfStateStack() { - log.debug("Block.FIXED --> break out"); - return paintingState.restoreAll(); - } - - /** {@inheritDoc} */ - public void saveGraphicsState() { - paintingState.save(); - } - - /** {@inheritDoc} */ - public void restoreGraphicsState() { - paintingState.restore(); - } - - /** {@inheritDoc} */ - public void renderImage(Image image, Rectangle2D pos) { - drawImage(image.getURL(), pos, image.getForeignAttributes()); - } - - /** {@inheritDoc} */ - public void renderText(TextArea text) { - renderInlineAreaBackAndBorders(text); - - // set font size - int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - paintingState.setFontSize(fontSize); - - // register font as necessary - String internalFontName = getInternalFontNameForArea(text); - Map/**/ fontMetricMap = fontInfo.getFonts(); - AFPFont font = (AFPFont)fontMetricMap.get(internalFontName); - AFPPageFonts pageFonts = paintingState.getPageFonts(); - AFPFontAttributes fontAttributes = pageFonts.registerFont(internalFontName, font, fontSize); - Font fnt = getFontFromArea(text); - - if (font.isEmbeddable()) { - CharacterSet charSet = font.getCharacterSet(fontSize); - try { - this.resourceManager.embedFont(font, charSet); - } catch (IOException ioe) { - AFPEventProducer eventProducer - = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster()); - eventProducer.resourceEmbeddingError(this, charSet.getName(), ioe); - } - } - - // create text data info - AFPTextDataInfo textDataInfo = new AFPTextDataInfo(); - - int fontReference = fontAttributes.getFontReference(); - textDataInfo.setFontReference(fontReference); - - int x = (currentIPPosition + text.getBorderAndPaddingWidthStart()); - int y = (currentBPPosition + text.getOffset() + text.getBaselineOffset()); - - int[] coords = unitConv.mpts2units(new float[] {x, y} ); - textDataInfo.setX(coords[X]); - textDataInfo.setY(coords[Y]); - - Color color = (Color) text.getTrait(Trait.COLOR); - textDataInfo.setColor(color); - - int textWordSpaceAdjust = text.getTextWordSpaceAdjust(); - int textLetterSpaceAdjust = text.getTextLetterSpaceAdjust(); - int textWidth = font.getWidth(' ', fontSize) / 1000; - textWidth = 0; //JM, the above is strange - int variableSpaceCharacterIncrement - = textWidth + textWordSpaceAdjust + textLetterSpaceAdjust; - - variableSpaceCharacterIncrement - = Math.round(unitConv.mpt2units(variableSpaceCharacterIncrement)); - textDataInfo.setVariableSpaceCharacterIncrement(variableSpaceCharacterIncrement); - - int interCharacterAdjustment - = Math.round(unitConv.mpt2units(textLetterSpaceAdjust)); - textDataInfo.setInterCharacterAdjustment(interCharacterAdjustment); - - CharacterSet charSet = font.getCharacterSet(fontSize); - String encoding = charSet.getEncoding(); - textDataInfo.setEncoding(encoding); - - String textString = text.getText(); - textDataInfo.setString(textString); - - try { - dataStream.createText - (textDataInfo, textLetterSpaceAdjust, textWordSpaceAdjust, fnt, charSet); - } catch (UnsupportedEncodingException e) { - AFPEventProducer eventProducer - = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster()); - eventProducer.characterSetEncodingError(this, charSet.getName(), encoding); - } - // word.getOffset() = only height of text itself - // currentBlockIPPosition: 0 for beginning of line; nonzero - // where previous line area failed to take up entire allocated space - - super.renderText(text); - - renderTextDecoration(font, fontSize, text, y, x); - } - - /** - * Render leader area. This renders a leader area which is an area with a - * rule. - * - * @param area - * the leader area to render - */ - public void renderLeader(Leader area) { - renderInlineAreaBackAndBorders(area); - - int style = area.getRuleStyle(); - float startx = (currentIPPosition + area - .getBorderAndPaddingWidthStart()) / 1000f; - float starty = (currentBPPosition + area.getOffset()) / 1000f; - float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() + area - .getIPD()) / 1000f; - float ruleThickness = area.getRuleThickness() / 1000f; - Color col = (Color) area.getTrait(Trait.COLOR); - - switch (style) { - case EN_SOLID: - case EN_DASHED: - case EN_DOUBLE: - case EN_DOTTED: - case EN_GROOVE: - case EN_RIDGE: - drawBorderLine(startx, starty, endx, starty + ruleThickness, true, - true, style, col); - break; - default: - throw new UnsupportedOperationException("rule style not supported"); - } - super.renderLeader(area); - } - - /** - * Get the MIME type of the renderer. - * - * @return The MIME type of the renderer - */ - public String getMimeType() { - return MimeConstants.MIME_AFP; - } - - /** - * checks for IMM Extension and renders if found and different - * from previous page - * - * @param pageViewport the page object - */ - private void renderInvokeMediumMap(PageViewport pageViewport) { - if (pageViewport.getExtensionAttachments() != null - && pageViewport.getExtensionAttachments().size() > 0) { - Iterator it = pageViewport.getExtensionAttachments().iterator(); - while (it.hasNext()) { - ExtensionAttachment attachment = (ExtensionAttachment) it.next(); - if (AFPExtensionAttachment.CATEGORY.equals(attachment.getCategory())) { - AFPExtensionAttachment aea = (AFPExtensionAttachment)attachment; - if (AFPElementMapping.INVOKE_MEDIUM_MAP.equals(aea.getElementName())) { - AFPInvokeMediumMap imm = (AFPInvokeMediumMap)attachment; - String mediumMap = imm.getName(); - if (mediumMap != null) { - if (!mediumMap.equals(lastMediumMap)) { - dataStream.createInvokeMediumMap(mediumMap); - lastMediumMap = mediumMap; - } - } - } - } - } - } - } - - /** - * Method to render the page extension. - *

- * - * @param pageViewport - * the page object - */ - private void renderPageObjectExtensions(PageViewport pageViewport) { - pageSegmentMap.clear(); - if (pageViewport.getExtensionAttachments() != null - && pageViewport.getExtensionAttachments().size() > 0) { - // Extract all AFPPageSetup instances from the attachment list on - // the s-p-m - Iterator it = pageViewport.getExtensionAttachments().iterator(); - while (it.hasNext()) { - ExtensionAttachment attachment = (ExtensionAttachment) it.next(); - if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) { - if (attachment instanceof AFPPageSetup) { - AFPPageSetup aps = (AFPPageSetup) attachment; - String element = aps.getElementName(); - if (AFPElementMapping.INCLUDE_PAGE_SEGMENT - .equals(element)) { - String name = aps.getName(); - String source = aps.getValue(); - pageSegmentMap.put(source, name); - } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT - .equals(element)) { - String name = aps.getName(); - String value = aps.getValue(); - dataStream.createTagLogicalElement(name, value); - } else if (AFPElementMapping.NO_OPERATION.equals(element)) { - String content = aps.getContent(); - if (content != null) { - dataStream.createNoOperation(content); - } - } - } else if (attachment instanceof AFPPageOverlay) { - AFPPageOverlay ipo = (AFPPageOverlay) attachment; - String element = ipo.getElementName(); - if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) { - String overlay = ipo.getName(); - if (overlay != null) { - dataStream.createIncludePageOverlay - (overlay, ipo.getX(), ipo.getY()); - } - } - } - } - } - } - - } - - /** - * Sets the rotation to be used for portrait pages, valid values are 0 - * (default), 90, 180, 270. - * - * @param rotation - * The rotation in degrees. - */ - public void setPortraitRotation(int rotation) { - paintingState.setPortraitRotation(rotation); - } - - /** - * Sets the rotation to be used for landscape pages, valid values are 0, 90, - * 180, 270 (default). - * - * @param rotation - * The rotation in degrees. - */ - public void setLandscapeRotation(int rotation) { - paintingState.setLandscapeRotation(rotation); - } - - // ---=== AFPCustomizable ===--- - - /** {@inheritDoc} */ - public void setBitsPerPixel(int bitsPerPixel) { - paintingState.setBitsPerPixel(bitsPerPixel); - } - - /** {@inheritDoc} */ - public void setColorImages(boolean colorImages) { - paintingState.setColorImages(colorImages); - } - - /** {@inheritDoc} */ - public void setNativeImagesSupported(boolean nativeImages) { - paintingState.setNativeImagesSupported(nativeImages); - } - - /** {@inheritDoc} */ - public void setCMYKImagesSupported(boolean value) { - paintingState.setCMYKImagesSupported(value); - } - - /** {@inheritDoc} */ - public void setDitheringQuality(float quality) { - this.paintingState.setDitheringQuality(quality); - } - - /** {@inheritDoc} */ - public void setShadingMode(AFPShadingMode shadingMode) { - this.shadingMode = shadingMode; - } - - /** {@inheritDoc} */ - public void setResolution(int resolution) { - paintingState.setResolution(resolution); - } - - /** {@inheritDoc} */ - public int getResolution() { - return paintingState.getResolution(); - } - - /** {@inheritDoc} */ - public void setDefaultResourceGroupFilePath(String filePath) { - resourceManager.setDefaultResourceGroupFilePath(filePath); - } - - /** {@inheritDoc} */ - public void setResourceLevelDefaults(AFPResourceLevelDefaults defaults) { - resourceManager.setResourceLevelDefaults(defaults); - } - - /** {@inheritDoc} */ - protected void establishTransformationMatrix(AffineTransform at) { - saveGraphicsState(); - concatenateTransformationMatrix(at); - } - - /** {@inheritDoc} */ - public void clip() { - // TODO -// log.debug("NYI clip()"); - } - - /** {@inheritDoc} */ - public void clipRect(float x, float y, float width, float height) { - // TODO -// log.debug("NYI clipRect(x=" + x + ",y=" + y -// + ",width=" + width + ", height=" + height + ")"); - } - - /** {@inheritDoc} */ - public void moveTo(float x, float y) { - // TODO -// log.debug("NYI moveTo(x=" + x + ",y=" + y + ")"); - } - - /** {@inheritDoc} */ - public void lineTo(float x, float y) { - // TODO -// log.debug("NYI lineTo(x=" + x + ",y=" + y + ")"); - } - - /** {@inheritDoc} */ - public void closePath() { - // TODO -// log.debug("NYI closePath()"); - } - - /** Indicates the beginning of a text object. */ - public void beginTextObject() { - //TODO PDF specific maybe? -// log.debug("NYI beginTextObject()"); - } - - /** Indicates the end of a text object. */ - public void endTextObject() { - //TODO PDF specific maybe? -// log.debug("NYI endTextObject()"); - } - -} diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 77d02b8c5..8d4b3370c 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -348,27 +348,12 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator private static final String IMAGES_MODE_COLOR = "color"; /** - * Configure the AFP renderer. + * Throws an UnsupportedOperationException. * - * @param renderer AFP renderer - * @throws FOPException fop exception - * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer) + * @param renderer not used */ - public void configure(Renderer renderer) throws FOPException { - Configuration cfg = super.getRendererConfig(renderer); - if (cfg != null) { - AFPRenderer afpRenderer = (AFPRenderer)renderer; - - try { - List/**/ fontList = buildFontListFromConfiguration(cfg); - afpRenderer.setFontList(fontList); - } catch (ConfigurationException e) { - LogUtil.handleException(log, e, - userAgent.getFactory().validateUserConfigStrictly()); - } - - configure(afpRenderer, cfg); - } + public void configure(Renderer renderer) { + throw new UnsupportedOperationException(); } private void configure(AFPCustomizable customizable, Configuration cfg) throws FOPException { diff --git a/src/java/org/apache/fop/render/afp/AFPRendererMaker.java b/src/java/org/apache/fop/render/afp/AFPRendererMaker.java deleted file mode 100644 index d283d992a..000000000 --- a/src/java/org/apache/fop/render/afp/AFPRendererMaker.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.render.AbstractRendererMaker; -import org.apache.fop.render.Renderer; -import org.apache.fop.render.RendererConfigurator; - -/** - * RendererMaker for the AFP Renderer. - */ -public class AFPRendererMaker extends AbstractRendererMaker { - - private static final String[] MIMES = new String[] { - MimeConstants.MIME_AFP, - MimeConstants.MIME_AFP_ALT}; - - - /**{@inheritDoc} */ - public Renderer makeRenderer(FOUserAgent userAgent) { - return new AFPRenderer(); - } - - /** {@inheritDoc} */ - public RendererConfigurator getConfigurator(FOUserAgent userAgent) { - return new AFPRendererConfigurator(userAgent); - } - - /** {@inheritDoc} */ - public boolean needsOutputStream() { - return true; - } - - /** {@inheritDoc} */ - public String[] getSupportedMimeTypes() { - return MIMES; - } - -} diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 587c57e5b..7ade64006 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -214,7 +214,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { - return (renderer instanceof AFPRenderer); + return false; } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java b/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java index 1228365f2..5374c7051 100644 --- a/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java +++ b/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java @@ -44,21 +44,6 @@ import org.apache.fop.render.RenderingContext; public abstract class AbstractAFPImageHandlerRawStream extends AFPImageHandler implements ImageHandler { - /** {@inheritDoc} */ - public AFPDataObjectInfo generateDataObjectInfo( - AFPRendererImageInfo rendererImageInfo) throws IOException { - AFPDataObjectInfo dataObjectInfo = super.generateDataObjectInfo(rendererImageInfo); - ImageRawStream rawStream = (ImageRawStream) rendererImageInfo.getImage(); - AFPRendererContext rendererContext - = (AFPRendererContext)rendererImageInfo.getRendererContext(); - AFPInfo afpInfo = rendererContext.getInfo(); - - updateDataObjectInfo(dataObjectInfo, rawStream, afpInfo.getResourceManager()); - - setAdditionalParameters(dataObjectInfo, rawStream); - return dataObjectInfo; - } - /** * Sets additional parameters on the image object info being built. By default, this * method does nothing but it can be overridden to provide additional functionality. diff --git a/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java b/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java deleted file mode 100644 index f8c9682e9..000000000 --- a/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pcl; - -import java.awt.Dimension; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; - -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.java2d.GraphicContext; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - -import org.apache.fop.render.AbstractGraphics2DAdapter; -import org.apache.fop.render.RendererContext; -import org.apache.xmlgraphics.util.UnitConv; - -/** - * Graphics2DAdapter implementation for PCL and HP GL/2. - */ -public class PCLGraphics2DAdapter extends AbstractGraphics2DAdapter { - - /** logging instance */ - private static Log log = LogFactory.getLog(PCLGraphics2DAdapter.class); - - /** - * Main constructor - */ - public PCLGraphics2DAdapter() { - } - - /** {@inheritDoc} */ - public void paintImage(Graphics2DImagePainter painter, - RendererContext context, - int x, int y, int width, int height) throws IOException { - PCLRendererContext pclContext = PCLRendererContext.wrapRendererContext(context); - PCLRenderer pcl = (PCLRenderer)context.getRenderer(); - PCLGenerator gen = pcl.gen; - - // get the 'width' and 'height' attributes of the image/document - Dimension dim = painter.getImageSize(); - float imw = (float)dim.getWidth(); - float imh = (float)dim.getHeight(); - - boolean painted = false; - boolean paintAsBitmap = pclContext.paintAsBitmap(); - if (!paintAsBitmap) { - ByteArrayOutputStream baout = new ByteArrayOutputStream(); - PCLGenerator tempGen = new PCLGenerator(baout, gen.getMaximumBitmapResolution()); - try { - GraphicContext ctx = (GraphicContext)pcl.getGraphicContext().clone(); - - AffineTransform prepareHPGL2 = new AffineTransform(); - prepareHPGL2.scale(0.001, 0.001); - ctx.setTransform(prepareHPGL2); - - PCLGraphics2D graphics = new PCLGraphics2D(tempGen); - graphics.setGraphicContext(ctx); - graphics.setClippingDisabled(pclContext.isClippingDisabled()); - Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); - painter.paint(graphics, area); - - //If we arrive here, the graphic is natively paintable, so write the graphic - pcl.saveGraphicsState(); - pcl.setCursorPos(x, y); - gen.writeCommand("*c" + gen.formatDouble4(width / 100f) + "x" - + gen.formatDouble4(height / 100f) + "Y"); - gen.writeCommand("*c0T"); - gen.enterHPGL2Mode(false); - gen.writeText("\nIN;"); - gen.writeText("SP1;"); - //One Plotter unit is 0.025mm! - double scale = imw / UnitConv.mm2pt(imw * 0.025); - gen.writeText("SC0," + gen.formatDouble4(scale) - + ",0,-" + gen.formatDouble4(scale) + ",2;"); - gen.writeText("IR0,100,0,100;"); - gen.writeText("PU;PA0,0;\n"); - baout.writeTo(gen.getOutputStream()); //Buffer is written to output stream - gen.writeText("\n"); - - gen.enterPCLMode(false); - pcl.restoreGraphicsState(); - painted = true; - } catch (UnsupportedOperationException uoe) { - log.debug( - "Cannot paint graphic natively. Falling back to bitmap painting. Reason: " - + uoe.getMessage()); - } - } - - if (!painted) { - //Fallback solution: Paint to a BufferedImage - int resolution = Math.round(context.getUserAgent().getTargetResolution()); - BufferedImage bi = paintToBufferedImage(painter, pclContext, - resolution, !pclContext.isColorCanvas(), false); - - pcl.setCursorPos(x, y); - gen.paintBitmap(bi, new Dimension(width, height), pclContext.isSourceTransparency()); - } - } - -} diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java deleted file mode 100644 index 659997e8f..000000000 --- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java +++ /dev/null @@ -1,1516 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pcl; - -//Java -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.RenderedImage; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import org.w3c.dom.Document; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.image.loader.ImageSize; -import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; -import org.apache.xmlgraphics.image.loader.impl.ImageRendered; -import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; -import org.apache.xmlgraphics.image.loader.util.ImageUtil; -import org.apache.xmlgraphics.java2d.GraphicContext; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; -import org.apache.xmlgraphics.util.UnitConv; - -import org.apache.fop.ResourceEventProducer; -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.area.Area; -import org.apache.fop.area.Block; -import org.apache.fop.area.BlockViewport; -import org.apache.fop.area.CTM; -import org.apache.fop.area.NormalFlow; -import org.apache.fop.area.PageViewport; -import org.apache.fop.area.RegionViewport; -import org.apache.fop.area.Trait; -import org.apache.fop.area.inline.AbstractTextArea; -import org.apache.fop.area.inline.ForeignObject; -import org.apache.fop.area.inline.Image; -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.area.inline.Leader; -import org.apache.fop.area.inline.SpaceArea; -import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.inline.Viewport; -import org.apache.fop.area.inline.WordArea; -import org.apache.fop.datatypes.URISpecification; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontCollection; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontMetrics; -import org.apache.fop.render.Graphics2DAdapter; -import org.apache.fop.render.ImageHandlerUtil; -import org.apache.fop.render.PrintRenderer; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.RendererContextConstants; -import org.apache.fop.render.RendererEventProducer; -import org.apache.fop.render.java2d.Base14FontCollection; -import org.apache.fop.render.java2d.ConfiguredFontCollection; -import org.apache.fop.render.java2d.FontMetricsMapper; -import org.apache.fop.render.java2d.InstalledFontCollection; -import org.apache.fop.render.java2d.Java2DFontMetrics; -import org.apache.fop.render.java2d.Java2DRenderer; -import org.apache.fop.render.pcl.extensions.PCLElementMapping; -import org.apache.fop.traits.BorderProps; - -/* Note: - * There are some commonalities with AbstractPathOrientedRenderer but it's not possible - * to derive from it due to PCL's restrictions. We may need an additional common subclass to - * avoid methods copied from AbstractPathOrientedRenderer. Or we wait until after the IF redesign. - */ - -/** - * Renderer for the PCL 5 printer language. It also uses HP GL/2 for certain graphic elements. - */ -public class PCLRenderer extends PrintRenderer implements PCLConstants { - - /** logging instance */ - private static Log log = LogFactory.getLog(PCLRenderer.class); - - /** The MIME type for PCL */ - public static final String MIME_TYPE = MimeConstants.MIME_PCL_ALT; - - /** The OutputStream to write the PCL stream to */ - protected OutputStream out; - - /** The PCL generator */ - protected PCLGenerator gen; - private boolean ioTrouble = false; - - private final Stack graphicContextStack = new Stack(); - private GraphicContext graphicContext = new GraphicContext(); - - private PCLPageDefinition currentPageDefinition; - private int currentPrintDirection = 0; - private GeneralPath currentPath = null; - private java.awt.Color currentFillColor = null; - - /** - * Utility class which enables all sorts of features that are not directly connected to the - * normal rendering process. - */ - private PCLRenderingUtil pclUtil; - - /** contains the pageWith of the last printed page */ - private long pageWidth = 0; - /** contains the pageHeight of the last printed page */ - private long pageHeight = 0; - - /** - * Create the PCL renderer - */ - public PCLRenderer() { - } - - /** {@inheritDoc} */ - public void setUserAgent(FOUserAgent agent) { - super.setUserAgent(agent); - this.pclUtil = new PCLRenderingUtil(getUserAgent()); - } - - PCLRenderingUtil getPCLUtil() { - return this.pclUtil; - } - - /** - * Configures the renderer to trade speed for quality if desired. One example here is the way - * that borders are rendered. - * @param qualityBeforeSpeed true if quality is more important than speed - */ - public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) { - pclUtil.setRenderingMode(qualityBeforeSpeed - ? PCLRenderingMode.QUALITY : PCLRenderingMode.SPEED); - } - - /** - * Controls whether PJL commands shall be generated by the PCL renderer. - * @param disable true to disable PJL commands - */ - public void setPJLDisabled(boolean disable) { - pclUtil.setPJLDisabled(disable); - } - - /** - * Indicates whether PJL generation is disabled. - * @return true if PJL generation is disabled. - */ - public boolean isPJLDisabled() { - return pclUtil.isPJLDisabled(); - } - - /** - * Controls whether all text should be generated as bitmaps or only text for which there's - * no native font. - * @param allTextAsBitmaps true if all text should be painted as bitmaps - */ - public void setAllTextAsBitmaps(boolean allTextAsBitmaps) { - pclUtil.setAllTextAsBitmaps(allTextAsBitmaps); - } - - /** - * {@inheritDoc} - */ - public void setupFontInfo(FontInfo inFontInfo) { - //Don't call super.setupFontInfo() here! - //The PCLRenderer uses the Java2D FontSetup which needs a special font setup - //create a temp Image to test font metrics on - fontInfo = inFontInfo; - Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D(); - - FontCollection[] fontCollections = new FontCollection[] { - new Base14FontCollection(graphics2D), - new InstalledFontCollection(graphics2D), - new ConfiguredFontCollection(getFontResolver(), getFontList()) - }; - userAgent.getFactory().getFontManager().setup( - getFontInfo(), fontCollections); - } - - /** - * Central exception handler for I/O exceptions. - * @param ioe IOException to handle - */ - protected void handleIOTrouble(IOException ioe) { - if (!ioTrouble) { - RendererEventProducer eventProducer = RendererEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.ioError(this, ioe); - ioTrouble = true; - } - } - - /** {@inheritDoc} */ - public Graphics2DAdapter getGraphics2DAdapter() { - return new PCLGraphics2DAdapter(); - } - - /** @return the GraphicContext used to track coordinate system transformations */ - public GraphicContext getGraphicContext() { - return this.graphicContext; - } - - /** @return the target resolution */ - protected int getResolution() { - int resolution = Math.round(userAgent.getTargetResolution()); - if (resolution <= 300) { - return 300; - } else { - return 600; - } - } - - /** {@inheritDoc} */ - public void startRenderer(OutputStream outputStream) throws IOException { - log.debug("Rendering areas to PCL..."); - this.out = outputStream; - this.gen = new PCLGenerator(out, getResolution()); - - if (!isPJLDisabled()) { - gen.universalEndOfLanguage(); - gen.writeText("@PJL COMMENT Produced by " + userAgent.getProducer() + "\n"); - if (userAgent.getTitle() != null) { - gen.writeText("@PJL JOB NAME = \"" + userAgent.getTitle() + "\"\n"); - } - gen.writeText("@PJL SET RESOLUTION = " + getResolution() + "\n"); - gen.writeText("@PJL ENTER LANGUAGE = PCL\n"); - } - gen.resetPrinter(); - gen.setUnitOfMeasure(getResolution()); - gen.setRasterGraphicsResolution(getResolution()); - } - - /** {@inheritDoc} */ - public void stopRenderer() throws IOException { - gen.separateJobs(); - gen.resetPrinter(); - if (!isPJLDisabled()) { - gen.universalEndOfLanguage(); - } - } - - /** {@inheritDoc} */ - public String getMimeType() { - return MIME_TYPE; - } - - /** {@inheritDoc} */ - public void renderPage(PageViewport page) throws IOException, FOPException { - saveGraphicsState(); - - //Paper source - String paperSource = page.getForeignAttributeValue(PCLElementMapping.PCL_PAPER_SOURCE); - if (paperSource != null) { - gen.selectPaperSource(Integer.parseInt(paperSource)); - } - - //Output bin - String outputBin = page.getForeignAttributeValue(PCLElementMapping.PCL_OUTPUT_BIN); - if (outputBin != null) { - gen.selectOutputBin(Integer.parseInt(outputBin)); - } - - // Is Page duplex? - String pageDuplex = page.getForeignAttributeValue(PCLElementMapping.PCL_DUPLEX_MODE); - if (pageDuplex != null) { - gen.selectDuplexMode(Integer.parseInt(pageDuplex)); - } - - //Page size - final long pagewidth = Math.round(page.getViewArea().getWidth()); - final long pageheight = Math.round(page.getViewArea().getHeight()); - selectPageFormat(pagewidth, pageheight); - - super.renderPage(page); - - //Eject page - gen.formFeed(); - restoreGraphicsState(); - } - - private void selectPageFormat(long pagewidth, long pageheight) throws IOException { - //Only set the page format if it changes (otherwise duplex printing won't work) - if ((pagewidth != this.pageWidth) || (pageheight != this.pageHeight)) { - this.pageWidth = pagewidth; - this.pageHeight = pageheight; - - this.currentPageDefinition = PCLPageDefinition.getPageDefinition( - pagewidth, pageheight, 1000); - - if (this.currentPageDefinition == null) { - this.currentPageDefinition = PCLPageDefinition.getDefaultPageDefinition(); - log.warn("Paper type could not be determined. Falling back to: " - + this.currentPageDefinition.getName()); - } - if (log.isDebugEnabled()) { - log.debug("page size: " + currentPageDefinition.getPhysicalPageSize()); - log.debug("logical page: " + currentPageDefinition.getLogicalPageRect()); - } - - if (this.currentPageDefinition.isLandscapeFormat()) { - gen.writeCommand("&l1O"); //Landscape Orientation - } else { - gen.writeCommand("&l0O"); //Portrait Orientation - } - gen.selectPageSize(this.currentPageDefinition.getSelector()); - - gen.clearHorizontalMargins(); - gen.setTopMargin(0); - } - } - - /** Saves the current graphics state on the stack. */ - protected void saveGraphicsState() { - graphicContextStack.push(graphicContext); - graphicContext = (GraphicContext)graphicContext.clone(); - } - - /** Restores the last graphics state from the stack. */ - protected void restoreGraphicsState() { - graphicContext = (GraphicContext)graphicContextStack.pop(); - } - - /** - * Clip an area. write a clipping operation given coordinates in the current - * transform. Coordinates are in points. - * - * @param x the x coordinate - * @param y the y coordinate - * @param width the width of the area - * @param height the height of the area - */ - protected void clipRect(float x, float y, float width, float height) { - //PCL cannot clip (only HP GL/2 can) - } - - private Point2D transformedPoint(float x, float y) { - return transformedPoint(Math.round(x), Math.round(y)); - } - - private Point2D transformedPoint(int x, int y) { - return PCLRenderingUtil.transformedPoint(x, y, graphicContext.getTransform(), - currentPageDefinition, currentPrintDirection); - } - - private void changePrintDirection() { - AffineTransform at = graphicContext.getTransform(); - int newDir; - try { - newDir = PCLRenderingUtil.determinePrintDirection(at); - if (newDir != this.currentPrintDirection) { - this.currentPrintDirection = newDir; - gen.changePrintDirection(this.currentPrintDirection); - } - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * {@inheritDoc} - */ - protected void startVParea(CTM ctm, Rectangle2D clippingRect) { - saveGraphicsState(); - AffineTransform at = new AffineTransform(ctm.toArray()); - graphicContext.transform(at); - changePrintDirection(); - if (log.isDebugEnabled()) { - log.debug("startVPArea: " + at + " --> " + graphicContext.getTransform()); - } - } - - /** - * {@inheritDoc} - */ - protected void endVParea() { - restoreGraphicsState(); - changePrintDirection(); - if (log.isDebugEnabled()) { - log.debug("endVPArea() --> " + graphicContext.getTransform()); - } - } - - /** - * Handle block traits. - * The block could be any sort of block with any positioning - * so this should render the traits such as border and background - * in its position. - * - * @param block the block to render the traits - */ - protected void handleBlockTraits(Block block) { - int borderPaddingStart = block.getBorderAndPaddingWidthStart(); - int borderPaddingBefore = block.getBorderAndPaddingWidthBefore(); - - float startx = currentIPPosition / 1000f; - float starty = currentBPPosition / 1000f; - float width = block.getIPD() / 1000f; - float height = block.getBPD() / 1000f; - - startx += block.getStartIndent() / 1000f; - startx -= block.getBorderAndPaddingWidthStart() / 1000f; - - width += borderPaddingStart / 1000f; - width += block.getBorderAndPaddingWidthEnd() / 1000f; - height += borderPaddingBefore / 1000f; - height += block.getBorderAndPaddingWidthAfter() / 1000f; - - drawBackAndBorders(block, startx, starty, width, height); - } - - /** - * {@inheritDoc} - * @asf.todo Copied from AbstractPathOrientedRenderer - */ - protected void handleRegionTraits(RegionViewport region) { - Rectangle2D viewArea = region.getViewArea(); - float startx = (float)(viewArea.getX() / 1000f); - float starty = (float)(viewArea.getY() / 1000f); - float width = (float)(viewArea.getWidth() / 1000f); - float height = (float)(viewArea.getHeight() / 1000f); - - if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) { - currentBPPosition = region.getBorderAndPaddingWidthBefore(); - currentIPPosition = region.getBorderAndPaddingWidthStart(); - } - drawBackAndBorders(region, startx, starty, width, height); - } - - /** - * {@inheritDoc} - */ - protected void renderText(final TextArea text) { - renderInlineAreaBackAndBorders(text); - - String fontname = getInternalFontNameForArea(text); - final int fontsize = text.getTraitAsInteger(Trait.FONT_SIZE); - - //Determine position - int saveIP = currentIPPosition; - final int rx = currentIPPosition + text.getBorderAndPaddingWidthStart(); - int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset(); - - try { - - final Color col = (Color)text.getTrait(Trait.COLOR); - boolean pclFont = pclUtil.isAllTextAsBitmaps() - ? false - : HardcodedFonts.setFont(gen, fontname, fontsize, text.getText()); - if (pclFont) { - //this.currentFill = col; - if (col != null) { - //useColor(ct); - gen.setTransparencyMode(true, false); - gen.selectGrayscale(col); - } - - saveGraphicsState(); - graphicContext.translate(rx, bl); - setCursorPos(0, 0); - gen.setTransparencyMode(true, true); - if (text.hasUnderline()) { - gen.writeCommand("&d0D"); - } - super.renderText(text); //Updates IPD and renders words and spaces - if (text.hasUnderline()) { - gen.writeCommand("&d@"); - } - restoreGraphicsState(); - } else { - //Use Java2D to paint different fonts via bitmap - final Font font = getFontFromArea(text); - final int baseline = text.getBaselineOffset(); - - //for cursive fonts, so the text isn't clipped - int extraWidth = font.getFontSize() / 3; - final FontMetricsMapper mapper = (FontMetricsMapper)fontInfo.getMetricsFor( - font.getFontName()); - int maxAscent = mapper.getMaxAscent(font.getFontSize()) / 1000; - final int additionalBPD = maxAscent - baseline; - - Graphics2DAdapter g2a = getGraphics2DAdapter(); - final Rectangle paintRect = new Rectangle( - rx, currentBPPosition + text.getOffset() - additionalBPD, - text.getIPD() + extraWidth, text.getBPD() + additionalBPD); - RendererContext rc = createRendererContext(paintRect.x, paintRect.y, - paintRect.width, paintRect.height, null); - Map atts = new java.util.HashMap(); - atts.put(ImageHandlerUtil.CONVERSION_MODE, ImageHandlerUtil.CONVERSION_MODE_BITMAP); - atts.put(SRC_TRANSPARENCY, "true"); - rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts); - - Graphics2DImagePainter painter = new Graphics2DImagePainter() { - - public void paint(Graphics2D g2d, Rectangle2D area) { - g2d.setFont(mapper.getFont(font.getFontSize())); - g2d.translate(0, baseline + additionalBPD); - g2d.scale(1000, 1000); - g2d.setColor(col); - Java2DRenderer.renderText(text, g2d, font); - renderTextDecoration(g2d, mapper, fontsize, text, 0, 0); - } - - public Dimension getImageSize() { - return paintRect.getSize(); - } - - }; - g2a.paintImage(painter, rc, - paintRect.x, paintRect.y, paintRect.width, paintRect.height); - currentIPPosition = saveIP + text.getAllocIPD(); - } - - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Paints the text decoration marks. - * @param g2d Graphics2D instance to paint to - * @param fm Current typeface - * @param fontsize Current font size - * @param inline inline area to paint the marks for - * @param baseline position of the baseline - * @param startx start IPD - */ - private static void renderTextDecoration(Graphics2D g2d, - FontMetrics fm, int fontsize, InlineArea inline, - int baseline, int startx) { - boolean hasTextDeco = inline.hasUnderline() - || inline.hasOverline() - || inline.hasLineThrough(); - if (hasTextDeco) { - float descender = fm.getDescender(fontsize) / 1000f; - float capHeight = fm.getCapHeight(fontsize) / 1000f; - float lineWidth = (descender / -4f) / 1000f; - float endx = (startx + inline.getIPD()) / 1000f; - if (inline.hasUnderline()) { - Color ct = (Color) inline.getTrait(Trait.UNDERLINE_COLOR); - g2d.setColor(ct); - float y = baseline - descender / 2f; - g2d.setStroke(new BasicStroke(lineWidth)); - g2d.draw(new Line2D.Float(startx / 1000f, y / 1000f, - endx, y / 1000f)); - } - if (inline.hasOverline()) { - Color ct = (Color) inline.getTrait(Trait.OVERLINE_COLOR); - g2d.setColor(ct); - float y = (float)(baseline - (1.1 * capHeight)); - g2d.setStroke(new BasicStroke(lineWidth)); - g2d.draw(new Line2D.Float(startx / 1000f, y / 1000f, - endx, y / 1000f)); - } - if (inline.hasLineThrough()) { - Color ct = (Color) inline.getTrait(Trait.LINETHROUGH_COLOR); - g2d.setColor(ct); - float y = (float)(baseline - (0.45 * capHeight)); - g2d.setStroke(new BasicStroke(lineWidth)); - g2d.draw(new Line2D.Float(startx / 1000f, y / 1000f, - endx, y / 1000f)); - } - } - } - - /** - * Sets the current cursor position. The coordinates are transformed to the absolute position - * on the logical PCL page and then passed on to the PCLGenerator. - * @param x the x coordinate (in millipoints) - * @param y the y coordinate (in millipoints) - */ - void setCursorPos(float x, float y) { - try { - Point2D transPoint = transformedPoint(x, y); - gen.setCursorPos(transPoint.getX(), transPoint.getY()); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** Clip using the current path. */ - protected void clip() { - if (currentPath == null) { - throw new IllegalStateException("No current path available!"); - } - //TODO Find a good way to do clipping. PCL itself cannot clip. - currentPath = null; - } - - /** - * Closes the current subpath by appending a straight line segment from - * the current point to the starting point of the subpath. - */ - protected void closePath() { - currentPath.closePath(); - } - - /** - * Appends a straight line segment from the current point to (x, y). The - * new current point is (x, y). - * @param x x coordinate - * @param y y coordinate - */ - protected void lineTo(float x, float y) { - if (currentPath == null) { - currentPath = new GeneralPath(); - } - currentPath.lineTo(x, y); - } - - /** - * Moves the current point to (x, y), omitting any connecting line segment. - * @param x x coordinate - * @param y y coordinate - */ - protected void moveTo(float x, float y) { - if (currentPath == null) { - currentPath = new GeneralPath(); - } - currentPath.moveTo(x, y); - } - - /** - * Fill a rectangular area. - * @param x the x coordinate (in pt) - * @param y the y coordinate (in pt) - * @param width the width of the rectangle - * @param height the height of the rectangle - */ - protected void fillRect(float x, float y, float width, float height) { - try { - setCursorPos(x * 1000, y * 1000); - gen.fillRect((int)(width * 1000), (int)(height * 1000), - this.currentFillColor); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Sets the new current fill color. - * @param color the color - */ - protected void updateFillColor(java.awt.Color color) { - this.currentFillColor = color; - } - - /** - * {@inheritDoc} - */ - protected void renderWord(WordArea word) { - //Font font = getFontFromArea(word.getParentArea()); - - String s = word.getWord(); - - try { - gen.writeText(s); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - - super.renderWord(word); - } - - /** - * {@inheritDoc} - */ - protected void renderSpace(SpaceArea space) { - AbstractTextArea textArea = (AbstractTextArea)space.getParentArea(); - String s = space.getSpace(); - char sp = s.charAt(0); - Font font = getFontFromArea(textArea); - - int tws = (space.isAdjustable() - ? textArea.getTextWordSpaceAdjust() - + 2 * textArea.getTextLetterSpaceAdjust() - : 0); - - double dx = (font.getCharWidth(sp) + tws) / 100f; - try { - gen.writeCommand("&a+" + gen.formatDouble2(dx) + "H"); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - super.renderSpace(space); - } - - /** - * Render an inline viewport. - * This renders an inline viewport by clipping if necessary. - * @param viewport the viewport to handle - * @asf.todo Copied from AbstractPathOrientedRenderer - */ - public void renderViewport(Viewport viewport) { - - float x = currentIPPosition / 1000f; - float y = (currentBPPosition + viewport.getOffset()) / 1000f; - float width = viewport.getIPD() / 1000f; - float height = viewport.getBPD() / 1000f; - // TODO: Calculate the border rect correctly. - float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f; - float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f; - float bpwidth = borderPaddingStart - + (viewport.getBorderAndPaddingWidthEnd() / 1000f); - float bpheight = borderPaddingBefore - + (viewport.getBorderAndPaddingWidthAfter() / 1000f); - - drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight); - - if (viewport.getClip()) { - saveGraphicsState(); - - clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height); - } - super.renderViewport(viewport); - - if (viewport.getClip()) { - restoreGraphicsState(); - } - } - - /** - * {@inheritDoc} - */ - protected void renderBlockViewport(BlockViewport bv, List children) { - // clip and position viewport if necessary - - // save positions - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - CTM ctm = bv.getCTM(); - int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); - int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore(); - //This is the content-rect - float width = bv.getIPD() / 1000f; - float height = bv.getBPD() / 1000f; - - - if (bv.getPositioning() == Block.ABSOLUTE - || bv.getPositioning() == Block.FIXED) { - - //For FIXED, we need to break out of the current viewports to the - //one established by the page. We save the state stack for restoration - //after the block-container has been painted. See below. - List breakOutList = null; - if (bv.getPositioning() == Block.FIXED) { - breakOutList = breakOutOfStateStack(); - } - - AffineTransform positionTransform = new AffineTransform(); - positionTransform.translate(bv.getXOffset(), bv.getYOffset()); - - //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle - positionTransform.translate(-borderPaddingStart, -borderPaddingBefore); - - saveGraphicsState(); - //Viewport position - concatenateTransformationMatrix(UnitConv.mptToPt(positionTransform)); - - //Background and borders - float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; - float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f; - drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight); - - //Shift to content rectangle after border painting - AffineTransform contentRectTransform = new AffineTransform(); - contentRectTransform.translate(borderPaddingStart, borderPaddingBefore); - concatenateTransformationMatrix(UnitConv.mptToPt(contentRectTransform)); - - //Clipping - if (bv.getClip()) { - clipRect(0f, 0f, width, height); - } - - saveGraphicsState(); - //Set up coordinate system for content rectangle - AffineTransform contentTransform = ctm.toAffineTransform(); - concatenateTransformationMatrix(UnitConv.mptToPt(contentTransform)); - - currentIPPosition = 0; - currentBPPosition = 0; - renderBlocks(bv, children); - - restoreGraphicsState(); - restoreGraphicsState(); - - if (breakOutList != null) { - restoreStateStackAfterBreakOut(breakOutList); - } - - currentIPPosition = saveIP; - currentBPPosition = saveBP; - } else { - - currentBPPosition += bv.getSpaceBefore(); - - //borders and background in the old coordinate system - handleBlockTraits(bv); - - //Advance to start of content area - currentIPPosition += bv.getStartIndent(); - - CTM tempctm = new CTM(containingIPPosition, currentBPPosition); - ctm = tempctm.multiply(ctm); - - //Now adjust for border/padding - currentBPPosition += borderPaddingBefore; - - Rectangle2D clippingRect = null; - if (bv.getClip()) { - clippingRect = new Rectangle(currentIPPosition, currentBPPosition, - bv.getIPD(), bv.getBPD()); - } - - startVParea(ctm, clippingRect); - currentIPPosition = 0; - currentBPPosition = 0; - renderBlocks(bv, children); - endVParea(); - - currentIPPosition = saveIP; - currentBPPosition = saveBP; - - currentBPPosition += (bv.getAllocBPD()); - } - //currentFontName = saveFontName; - } - - /** {@inheritDoc} */ - protected void renderReferenceArea(Block block) { - //TODO This is the same code as in AbstractPathOrientedRenderer - //So there's some optimization potential but not otherwise PCLRenderer is a little - //difficult to derive from AbstractPathOrientedRenderer. Maybe an additional layer - //between PrintRenderer and AbstractPathOrientedRenderer is necessary. - - // save position and offset - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - //Establish a new coordinate system - AffineTransform at = new AffineTransform(); - at.translate(currentIPPosition, currentBPPosition); - at.translate(block.getXOffset(), block.getYOffset()); - at.translate(0, block.getSpaceBefore()); - - if (!at.isIdentity()) { - saveGraphicsState(); - concatenateTransformationMatrix(UnitConv.mptToPt(at)); - } - - currentIPPosition = 0; - currentBPPosition = 0; - handleBlockTraits(block); - - List children = block.getChildAreas(); - if (children != null) { - renderBlocks(block, children); - } - - if (!at.isIdentity()) { - restoreGraphicsState(); - } - - // stacked and relative blocks effect stacking - currentIPPosition = saveIP; - currentBPPosition = saveBP; - } - - /** {@inheritDoc} */ - protected void renderFlow(NormalFlow flow) { - //TODO This is the same code as in AbstractPathOrientedRenderer - //So there's some optimization potential but not otherwise PCLRenderer is a little - //difficult to derive from AbstractPathOrientedRenderer. Maybe an additional layer - //between PrintRenderer and AbstractPathOrientedRenderer is necessary. - - // save position and offset - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - //Establish a new coordinate system - AffineTransform at = new AffineTransform(); - at.translate(currentIPPosition, currentBPPosition); - - if (!at.isIdentity()) { - saveGraphicsState(); - concatenateTransformationMatrix(UnitConv.mptToPt(at)); - } - - currentIPPosition = 0; - currentBPPosition = 0; - super.renderFlow(flow); - - if (!at.isIdentity()) { - restoreGraphicsState(); - } - - // stacked and relative blocks effect stacking - currentIPPosition = saveIP; - currentBPPosition = saveBP; - } - - /** - * Concatenates the current transformation matrix with the given one, therefore establishing - * a new coordinate system. - * @param at the transformation matrix to process (coordinates in points) - */ - protected void concatenateTransformationMatrix(AffineTransform at) { - if (!at.isIdentity()) { - graphicContext.transform(UnitConv.ptToMpt(at)); - changePrintDirection(); - } - } - - private List breakOutOfStateStack() { - log.debug("Block.FIXED --> break out"); - List breakOutList = new java.util.ArrayList(); - while (!this.graphicContextStack.empty()) { - breakOutList.add(0, this.graphicContext); - restoreGraphicsState(); - } - return breakOutList; - } - - private void restoreStateStackAfterBreakOut(List breakOutList) { - log.debug("Block.FIXED --> restoring context after break-out"); - for (int i = 0, c = breakOutList.size(); i < c; i++) { - saveGraphicsState(); - this.graphicContext = (GraphicContext)breakOutList.get(i); - } - } - - /** {@inheritDoc} */ - protected RendererContext createRendererContext(int x, int y, int width, int height, - Map foreignAttributes) { - RendererContext context = super.createRendererContext( - x, y, width, height, foreignAttributes); - context.setProperty(PCLRendererContextConstants.PCL_COLOR_CANVAS, - Boolean.valueOf(pclUtil.isColorCanvasEnabled())); - return context; - } - - /** {@inheritDoc} */ - public void renderImage(Image image, Rectangle2D pos) { - drawImage(image.getURL(), pos, image.getForeignAttributes()); - } - - private static final ImageFlavor[] FLAVORS = new ImageFlavor[] - {ImageFlavor.GRAPHICS2D, - ImageFlavor.BUFFERED_IMAGE, - ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM}; - /** - * Draw an image at the indicated location. - * @param uri the URI/URL of the image - * @param pos the position of the image - * @param foreignAttributes an optional Map with foreign attributes, may be null - */ - protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { - uri = URISpecification.getURL(uri); - Rectangle posInt = new Rectangle( - (int)pos.getX(), - (int)pos.getY(), - (int)pos.getWidth(), - (int)pos.getHeight()); - Point origin = new Point(currentIPPosition, currentBPPosition); - int x = origin.x + posInt.x; - int y = origin.y + posInt.y; - - ImageManager manager = getUserAgent().getFactory().getImageManager(); - ImageInfo info = null; - try { - ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); - info = manager.getImageInfo(uri, sessionContext); - - //Only now fully load/prepare the image - Map hints = ImageUtil.getDefaultHints(sessionContext); - org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, FLAVORS, hints, sessionContext); - - //...and process the image - if (img instanceof ImageGraphics2D) { - ImageGraphics2D imageG2D = (ImageGraphics2D)img; - RendererContext context = createRendererContext( - posInt.x, posInt.y, - posInt.width, posInt.height, foreignAttributes); - getGraphics2DAdapter().paintImage(imageG2D.getGraphics2DImagePainter(), - context, x, y, posInt.width, posInt.height); - } else if (img instanceof ImageRendered) { - ImageRendered imgRend = (ImageRendered)img; - RenderedImage ri = imgRend.getRenderedImage(); - setCursorPos(x, y); - gen.paintBitmap(ri, - new Dimension(posInt.width, posInt.height), - false); - } else if (img instanceof ImageXMLDOM) { - ImageXMLDOM imgXML = (ImageXMLDOM)img; - renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(), - pos, foreignAttributes); - } else { - throw new UnsupportedOperationException("Unsupported image type: " + img); - } - - } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); - } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); - } - } - - /** {@inheritDoc} */ - public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { - Document doc = fo.getDocument(); - String ns = fo.getNameSpace(); - renderDocument(doc, ns, pos, fo.getForeignAttributes()); - } - - /** - * Common method to render the background and borders for any inline area. - * The all borders and padding are drawn outside the specified area. - * @param area the inline area for which the background, border and padding is to be - * rendered - * @asf.todo Copied from AbstractPathOrientedRenderer - */ - protected void renderInlineAreaBackAndBorders(InlineArea area) { - float x = currentIPPosition / 1000f; - float y = (currentBPPosition + area.getOffset()) / 1000f; - float width = area.getIPD() / 1000f; - float height = area.getBPD() / 1000f; - float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f; - float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f; - float bpwidth = borderPaddingStart - + (area.getBorderAndPaddingWidthEnd() / 1000f); - float bpheight = borderPaddingBefore - + (area.getBorderAndPaddingWidthAfter() / 1000f); - - if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) { - drawBackAndBorders(area, x, y - borderPaddingBefore - , width + bpwidth - , height + bpheight); - } - } - - /** - * Draw the background and borders. This draws the background and border - * traits for an area given the position. - * - * @param area the area whose traits are used - * @param startx the start x position - * @param starty the start y position - * @param width the width of the area - * @param height the height of the area - */ - protected void drawBackAndBorders(Area area, float startx, float starty, - float width, float height) { - BorderProps bpsBefore = (BorderProps) area.getTrait(Trait.BORDER_BEFORE); - BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER); - BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START); - BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END); - - // draw background - Trait.Background back; - back = (Trait.Background) area.getTrait(Trait.BACKGROUND); - if (back != null) { - - // Calculate padding rectangle - float sx = startx; - float sy = starty; - float paddRectWidth = width; - float paddRectHeight = height; - - if (bpsStart != null) { - sx += bpsStart.width / 1000f; - paddRectWidth -= bpsStart.width / 1000f; - } - if (bpsBefore != null) { - sy += bpsBefore.width / 1000f; - paddRectHeight -= bpsBefore.width / 1000f; - } - if (bpsEnd != null) { - paddRectWidth -= bpsEnd.width / 1000f; - } - if (bpsAfter != null) { - paddRectHeight -= bpsAfter.width / 1000f; - } - - if (back.getColor() != null) { - updateFillColor(back.getColor()); - fillRect(sx, sy, paddRectWidth, paddRectHeight); - } - - // background image - if (back.getImageInfo() != null) { - ImageSize imageSize = back.getImageInfo().getSize(); - saveGraphicsState(); - clipRect(sx, sy, paddRectWidth, paddRectHeight); - int horzCount = (int) ((paddRectWidth * 1000 / imageSize.getWidthMpt()) + 1.0f); - int vertCount = (int) ((paddRectHeight * 1000 / imageSize.getHeightMpt()) + 1.0f); - if (back.getRepeat() == EN_NOREPEAT) { - horzCount = 1; - vertCount = 1; - } else if (back.getRepeat() == EN_REPEATX) { - vertCount = 1; - } else if (back.getRepeat() == EN_REPEATY) { - horzCount = 1; - } - // change from points to millipoints - sx *= 1000; - sy *= 1000; - if (horzCount == 1) { - sx += back.getHoriz(); - } - if (vertCount == 1) { - sy += back.getVertical(); - } - for (int x = 0; x < horzCount; x++) { - for (int y = 0; y < vertCount; y++) { - // place once - Rectangle2D pos; - // Image positions are relative to the currentIP/BP - pos = new Rectangle2D.Float( - sx - currentIPPosition - + (x * imageSize.getWidthMpt()), - sy - currentBPPosition - + (y * imageSize.getHeightMpt()), - imageSize.getWidthMpt(), - imageSize.getHeightMpt()); - drawImage(back.getURL(), pos, null); - } - } - restoreGraphicsState(); - } - } - - Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height); - drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd); - } - - /** - * Draws borders. - * @param borderRect the border rectangle - * @param bpsBefore the border specification on the before side - * @param bpsAfter the border specification on the after side - * @param bpsStart the border specification on the start side - * @param bpsEnd the border specification on the end side - */ - protected void drawBorders(Rectangle2D.Float borderRect, - final BorderProps bpsBefore, final BorderProps bpsAfter, - final BorderProps bpsStart, final BorderProps bpsEnd) { - if (bpsBefore == null && bpsAfter == null && bpsStart == null && bpsEnd == null) { - return; //no borders to paint - } - if (PCLRenderingMode.SPEED == pclUtil.getRenderingMode()) { - drawFastBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd); - } else { - drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd); - } - } - - /** - * Draws borders. Borders are drawn as shaded rectangles with no clipping. - * @param borderRect the border rectangle - * @param bpsBefore the border specification on the before side - * @param bpsAfter the border specification on the after side - * @param bpsStart the border specification on the start side - * @param bpsEnd the border specification on the end side - */ - protected void drawFastBorders(Rectangle2D.Float borderRect, - final BorderProps bpsBefore, final BorderProps bpsAfter, - final BorderProps bpsStart, final BorderProps bpsEnd) { - float startx = borderRect.x; - float starty = borderRect.y; - float width = borderRect.width; - float height = borderRect.height; - if (bpsBefore != null) { - float borderWidth = bpsBefore.width / 1000f; - updateFillColor(bpsBefore.color); - fillRect(startx, starty, width, borderWidth); - } - if (bpsAfter != null) { - float borderWidth = bpsAfter.width / 1000f; - updateFillColor(bpsAfter.color); - fillRect(startx, (starty + height - borderWidth), - width, borderWidth); - } - if (bpsStart != null) { - float borderWidth = bpsStart.width / 1000f; - updateFillColor(bpsStart.color); - fillRect(startx, starty, borderWidth, height); - } - if (bpsEnd != null) { - float borderWidth = bpsEnd.width / 1000f; - updateFillColor(bpsEnd.color); - fillRect((startx + width - borderWidth), starty, borderWidth, height); - } - } - - /** - * Draws borders. Borders are drawn in-memory and painted as a bitmap. - * @param borderRect the border rectangle - * @param bpsBefore the border specification on the before side - * @param bpsAfter the border specification on the after side - * @param bpsStart the border specification on the start side - * @param bpsEnd the border specification on the end side - */ - protected void drawQualityBorders // CSOK: MethodLength - (Rectangle2D.Float borderRect, - final BorderProps bpsBefore, final BorderProps bpsAfter, - final BorderProps bpsStart, final BorderProps bpsEnd) { - Graphics2DAdapter g2a = getGraphics2DAdapter(); - final Rectangle.Float effBorderRect = new Rectangle2D.Float( - 0, - 0, - borderRect.width, - borderRect.height); - final Rectangle paintRect = new Rectangle( - Math.round(borderRect.x * 1000f), - Math.round(borderRect.y * 1000f), - (int)Math.floor(borderRect.width * 1000f) + 1, - (int)Math.floor(borderRect.height * 1000f) + 1); - //Add one pixel wide safety margin around the paint area - int pixelWidth = (int)Math.round(UnitConv.in2mpt(1) / userAgent.getTargetResolution()); - final int xoffset = Math.round(-effBorderRect.x * 1000f) + pixelWidth; - final int yoffset = pixelWidth; - paintRect.x += xoffset; - paintRect.y += yoffset; - paintRect.width += 2 * pixelWidth; - paintRect.height += 2 * pixelWidth; - - RendererContext rc = createRendererContext(paintRect.x, paintRect.y, - paintRect.width, paintRect.height, null); - Map atts = new java.util.HashMap(); - atts.put(ImageHandlerUtil.CONVERSION_MODE, ImageHandlerUtil.CONVERSION_MODE_BITMAP); - atts.put(SRC_TRANSPARENCY, "true"); - rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts); - - Graphics2DImagePainter painter = new Graphics2DImagePainter() { - - public void paint // CSOK: MethodLength - (Graphics2D g2d, Rectangle2D area) { - g2d.translate(xoffset, yoffset); - g2d.scale(1000, 1000); - float startx = effBorderRect.x; - float starty = effBorderRect.y; - float width = effBorderRect.width; - float height = effBorderRect.height; - boolean[] b = new boolean[] { - (bpsBefore != null), (bpsEnd != null), - (bpsAfter != null), (bpsStart != null)}; - if (!b[0] && !b[1] && !b[2] && !b[3]) { - return; - } - float[] bw = new float[] { - (b[0] ? bpsBefore.width / 1000f : 0.0f), - (b[1] ? bpsEnd.width / 1000f : 0.0f), - (b[2] ? bpsAfter.width / 1000f : 0.0f), - (b[3] ? bpsStart.width / 1000f : 0.0f)}; - float[] clipw = new float[] { - BorderProps.getClippedWidth(bpsBefore) / 1000f, - BorderProps.getClippedWidth(bpsEnd) / 1000f, - BorderProps.getClippedWidth(bpsAfter) / 1000f, - BorderProps.getClippedWidth(bpsStart) / 1000f}; - starty += clipw[0]; - height -= clipw[0]; - height -= clipw[2]; - startx += clipw[3]; - width -= clipw[3]; - width -= clipw[1]; - - boolean[] slant = new boolean[] { - (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])}; - if (bpsBefore != null) { - //endTextObject(); - - float sx1 = startx; - float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1); - float ex1 = startx + width; - float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1); - float outery = starty - clipw[0]; - float clipy = outery + clipw[0]; - float innery = outery + bw[0]; - - //saveGraphicsState(); - Graphics2D g = (Graphics2D)g2d.create(); - moveTo(sx1, clipy); - float sx1a = sx1; - float ex1a = ex1; - if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { - if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) { - sx1a -= clipw[3]; - } - if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { - ex1a += clipw[1]; - } - lineTo(sx1a, outery); - lineTo(ex1a, outery); - } - lineTo(ex1, clipy); - lineTo(ex2, innery); - lineTo(sx2, innery); - closePath(); - //clip(); - g.clip(currentPath); - currentPath = null; - Rectangle2D.Float lineRect = new Rectangle2D.Float( - sx1a, outery, ex1a - sx1a, innery - outery); - Java2DRenderer.drawBorderLine(lineRect, true, true, - bpsBefore.style, bpsBefore.color, g); - //restoreGraphicsState(); - } - if (bpsEnd != null) { - //endTextObject(); - - float sy1 = starty; - float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1); - float ey1 = starty + height; - float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1); - float outerx = startx + width + clipw[1]; - float clipx = outerx - clipw[1]; - float innerx = outerx - bw[1]; - - //saveGraphicsState(); - Graphics2D g = (Graphics2D)g2d.create(); - moveTo(clipx, sy1); - float sy1a = sy1; - float ey1a = ey1; - if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { - if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { - sy1a -= clipw[0]; - } - if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { - ey1a += clipw[2]; - } - lineTo(outerx, sy1a); - lineTo(outerx, ey1a); - } - lineTo(clipx, ey1); - lineTo(innerx, ey2); - lineTo(innerx, sy2); - closePath(); - //clip(); - g.setClip(currentPath); - currentPath = null; - Rectangle2D.Float lineRect = new Rectangle2D.Float( - innerx, sy1a, outerx - innerx, ey1a - sy1a); - Java2DRenderer.drawBorderLine(lineRect, false, false, - bpsEnd.style, bpsEnd.color, g); - //restoreGraphicsState(); - } - if (bpsAfter != null) { - //endTextObject(); - - float sx1 = startx; - float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1); - float ex1 = startx + width; - float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1); - float outery = starty + height + clipw[2]; - float clipy = outery - clipw[2]; - float innery = outery - bw[2]; - - //saveGraphicsState(); - Graphics2D g = (Graphics2D)g2d.create(); - moveTo(ex1, clipy); - float sx1a = sx1; - float ex1a = ex1; - if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { - if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) { - sx1a -= clipw[3]; - } - if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { - ex1a += clipw[1]; - } - lineTo(ex1a, outery); - lineTo(sx1a, outery); - } - lineTo(sx1, clipy); - lineTo(sx2, innery); - lineTo(ex2, innery); - closePath(); - //clip(); - g.setClip(currentPath); - currentPath = null; - Rectangle2D.Float lineRect = new Rectangle2D.Float( - sx1a, innery, ex1a - sx1a, outery - innery); - Java2DRenderer.drawBorderLine(lineRect, true, false, - bpsAfter.style, bpsAfter.color, g); - //restoreGraphicsState(); - } - if (bpsStart != null) { - //endTextObject(); - - float sy1 = starty; - float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1); - float ey1 = sy1 + height; - float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1); - float outerx = startx - clipw[3]; - float clipx = outerx + clipw[3]; - float innerx = outerx + bw[3]; - - //saveGraphicsState(); - Graphics2D g = (Graphics2D)g2d.create(); - moveTo(clipx, ey1); - float sy1a = sy1; - float ey1a = ey1; - if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) { - if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { - sy1a -= clipw[0]; - } - if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { - ey1a += clipw[2]; - } - lineTo(outerx, ey1a); - lineTo(outerx, sy1a); - } - lineTo(clipx, sy1); - lineTo(innerx, sy2); - lineTo(innerx, ey2); - closePath(); - //clip(); - g.setClip(currentPath); - currentPath = null; - Rectangle2D.Float lineRect = new Rectangle2D.Float( - outerx, sy1a, innerx - outerx, ey1a - sy1a); - Java2DRenderer.drawBorderLine(lineRect, false, false, - bpsStart.style, bpsStart.color, g); - //restoreGraphicsState(); - } - } - - public Dimension getImageSize() { - return paintRect.getSize(); - } - - }; - try { - g2a.paintImage(painter, rc, - paintRect.x - xoffset, paintRect.y, paintRect.width, paintRect.height); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** {@inheritDoc} */ - public void renderLeader(Leader area) { - renderInlineAreaBackAndBorders(area); - - saveGraphicsState(); - int style = area.getRuleStyle(); - float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f; - float starty = (currentBPPosition + area.getOffset()) / 1000f; - float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() - + area.getIPD()) / 1000f; - float ruleThickness = area.getRuleThickness() / 1000f; - Color col = (Color)area.getTrait(Trait.COLOR); - - switch (style) { - case EN_SOLID: - case EN_DASHED: //TODO Improve me and following (this is just a quick-fix ATM) - case EN_DOUBLE: - case EN_DOTTED: - case EN_GROOVE: - case EN_RIDGE: - updateFillColor(col); - fillRect(startx, starty, endx - startx, ruleThickness); - break; - default: - throw new UnsupportedOperationException("rule style not supported"); - } - - restoreGraphicsState(); - super.renderLeader(area); - } - -} diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java index 802ba4176..339880b64 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java +++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java @@ -57,20 +57,12 @@ public class PCLRendererConfigurator extends PrintRendererConfigurator } /** - * Configure the PCL renderer. + * Throws an UnsupportedOperationException. * - * @param renderer PCL renderer - * @throws FOPException fop exception + * @param renderer not used */ - public void configure(Renderer renderer) throws FOPException { - Configuration cfg = super.getRendererConfig(renderer); - if (cfg != null) { - PCLRenderer pclRenderer = (PCLRenderer)renderer; - - PCLRenderingUtil pclUtil = pclRenderer.getPCLUtil(); - configure(cfg, pclUtil); - } - super.configure(renderer); + public void configure(Renderer renderer) { + throw new UnsupportedOperationException(); } private void configure(Configuration cfg, PCLRenderingUtil pclUtil) throws FOPException { diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java b/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java deleted file mode 100644 index a7651a6ac..000000000 --- a/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pcl; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.render.AbstractRendererMaker; -import org.apache.fop.render.Renderer; -import org.apache.fop.render.RendererConfigurator; - -/** - * RendererMaker for the PCL Renderer. - */ -public class PCLRendererMaker extends AbstractRendererMaker { - - private static final String[] MIMES = new String[] { - MimeConstants.MIME_PCL, - MimeConstants.MIME_PCL_ALT - }; - - /**{@inheritDoc} */ - public Renderer makeRenderer(FOUserAgent userAgent) { - return new PCLRenderer(); - } - - /** {@inheritDoc} */ - public RendererConfigurator getConfigurator(FOUserAgent userAgent) { - return new PCLRendererConfigurator(userAgent); - } - - /** {@inheritDoc} */ - public boolean needsOutputStream() { - return true; - } - - /** {@inheritDoc} */ - public String[] getSupportedMimeTypes() { - return MIMES; - } -} diff --git a/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java b/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java index fb2389758..f07a7a7e2 100644 --- a/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java +++ b/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java @@ -28,13 +28,12 @@ import org.apache.fop.render.RendererContext; * PCL XML handler for SVG. Uses Apache Batik for SVG processing. * This handler handles XML for foreign objects when rendering to HP GL/2. * It renders SVG to HP GL/2 using the PCLGraphics2D. - * @see PCLGraphics2DAdapter */ public class PCLSVGHandler extends AbstractGenericSVGHandler { /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { - return (renderer instanceof PCLRenderer); + return false; } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java deleted file mode 100644 index 102c1ab45..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; - -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - -import org.apache.fop.render.AbstractGraphics2DAdapter; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.RendererContext.RendererContextWrapper; -import org.apache.fop.svg.PDFGraphics2D; - -/** - * Graphics2DAdapter implementation for PDF. - */ -public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter { - - private PDFRenderer renderer; - - /** - * Main constructor - * @param renderer the Renderer instance to which this instance belongs - */ - public PDFGraphics2DAdapter(PDFRenderer renderer) { - this.renderer = renderer; - } - - /** {@inheritDoc} */ - public void paintImage(Graphics2DImagePainter painter, - RendererContext context, - int x, int y, int width, int height) throws IOException { - - PDFContentGenerator generator = renderer.getGenerator(); - PDFSVGHandler.PDFInfo pdfInfo = PDFSVGHandler.getPDFInfo(context); - float fwidth = width / 1000f; - float fheight = height / 1000f; - float fx = x / 1000f; - float fy = y / 1000f; - - // get the 'width' and 'height' attributes of the SVG document - Dimension dim = painter.getImageSize(); - float imw = (float)dim.getWidth() / 1000f; - float imh = (float)dim.getHeight() / 1000f; - - float sx = pdfInfo.paintAsBitmap ? 1.0f : (fwidth / (float)imw); - float sy = pdfInfo.paintAsBitmap ? 1.0f : (fheight / (float)imh); - - generator.comment("G2D start"); - generator.saveGraphicsState(); - generator.updateColor(Color.black, false, null); - generator.updateColor(Color.black, true, null); - - //TODO Clip to the image area. - - // transform so that the coordinates (0,0) is from the top left - // and positive is down and to the right. (0,0) is where the - // viewBox puts it. - generator.add(sx + " 0 0 " + sy + " " + fx + " " - + fy + " cm\n"); - - - final boolean textAsShapes = false; - if (pdfInfo.pdfContext == null) { - pdfInfo.pdfContext = pdfInfo.pdfPage; - } - PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes, - pdfInfo.fi, pdfInfo.pdfDoc, - pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(), - pdfInfo.currentFontName, - pdfInfo.currentFontSize); - graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); - - AffineTransform transform = new AffineTransform(); - transform.translate(fx, fy); - generator.getState().concatenate(transform); - graphics.setPaintingState(generator.getState()); - graphics.setOutputStream(pdfInfo.outputStream); - - if (pdfInfo.paintAsBitmap) { - //Fallback solution: Paint to a BufferedImage - int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); - RendererContextWrapper ctx = RendererContext.wrapRendererContext(context); - BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false); - - float scale = PDFRenderer.NORMAL_PDF_RESOLUTION - / context.getUserAgent().getTargetResolution(); - graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null); - } else { - Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); - painter.paint(graphics, area); - } - - generator.add(graphics.getString()); - generator.restoreGraphicsState(); - generator.comment("G2D end"); - } - - /** {@inheritDoc} */ - protected void setRenderingHintsForBufferedImage(Graphics2D g2d) { - super.setRenderingHintsForBufferedImage(g2d); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - } - -} diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java b/src/java/org/apache/fop/render/pdf/PDFImageHandler.java deleted file mode 100644 index 934d306b9..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import java.awt.Point; -import java.awt.Rectangle; -import java.io.IOException; - -import org.apache.xmlgraphics.image.loader.Image; - -import org.apache.fop.pdf.PDFXObject; -import org.apache.fop.render.ImageHandlerBase; -import org.apache.fop.render.RendererContext; - -/** - * This interface is used for handling all sorts of image type for PDF output. - */ -public interface PDFImageHandler extends ImageHandlerBase { - - /** - * Generates the PDF objects for the given {@link Image} instance. If the handler generates - * an XObject, it shall return it or otherwise return null. A generated XObject shall be - * placed in the current viewport according to the two parameters "origin" and "pos". - * @param context the PDF renderer context - * @param image the image to be handled - * @param origin the current position in the current viewport (in millipoints) - * @param pos the position and scaling of the image relative to the origin point - * (in millipoints) - * @return the generated XObject or null if no XObject was generated - * @throws IOException if an I/O error occurs - */ - PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) throws IOException; - -} diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java index c3242827a..d309a00aa 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java @@ -21,7 +21,6 @@ package org.apache.fop.render.pdf; import java.awt.Color; import java.awt.Dimension; -import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; @@ -31,9 +30,7 @@ import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; -import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.AbstractImageHandlerGraphics2D; -import org.apache.fop.render.RendererContext; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo; import org.apache.fop.svg.PDFGraphics2D; @@ -41,36 +38,12 @@ import org.apache.fop.svg.PDFGraphics2D; /** * PDFImageHandler implementation which handles Graphics2D images. */ -public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D - implements PDFImageHandler { +public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D { private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.GRAPHICS2D, }; - /** {@inheritDoc} */ - public PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) - throws IOException { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - /* - ImageGraphics2D imageG2D = (ImageGraphics2D)image; - renderer.getGraphics2DAdapter().paintImage(imageG2D.getGraphics2DImagePainter(), - context, origin.x + pos.x, origin.y + pos.y, pos.width, pos.height); - */ - PDFRenderingContext pdfContext = new PDFRenderingContext( - context.getUserAgent(), - renderer.getGenerator(), - renderer.currentPage, - renderer.getFontInfo()); - Rectangle effPos = new Rectangle(origin.x + pos.x, origin.y + pos.y, pos.width, pos.height); - if (context.getUserAgent().isAccessibilityEnabled()) { - pdfContext.setMarkedContentInfo(renderer.addCurrentImageToStructureTree()); - } - handleImage(pdfContext, image, effPos); - return null; - } - /** {@inheritDoc} */ public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException { diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java index 75b1d356e..b7d47ad58 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java @@ -19,7 +19,6 @@ package org.apache.fop.render.pdf; -import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; @@ -27,47 +26,21 @@ import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; -import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFImage; -import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.ImageHandler; -import org.apache.fop.render.RendererContext; import org.apache.fop.render.RenderingContext; /** * Image handler implementation which handles CCITT encoded images (CCITT fax group 3/4) * for PDF output. */ -public class PDFImageHandlerRawCCITTFax implements PDFImageHandler, ImageHandler { +public class PDFImageHandlerRawCCITTFax implements ImageHandler { private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.RAW_CCITTFAX, }; - /** {@inheritDoc} */ - public PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) - throws IOException { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - ImageRawCCITTFax ccitt = (ImageRawCCITTFax)image; - PDFDocument pdfDoc = (PDFDocument)context.getProperty( - PDFRendererContextConstants.PDF_DOCUMENT); - PDFResourceContext resContext = (PDFResourceContext)context.getProperty( - PDFRendererContextConstants.PDF_CONTEXT); - - PDFImage pdfimage = new ImageRawCCITTFaxAdapter(ccitt, image.getInfo().getOriginalURI()); - PDFXObject xobj = pdfDoc.addImage(resContext, pdfimage); - - float x = (float)pos.getX() / 1000f; - float y = (float)pos.getY() / 1000f; - float w = (float)pos.getWidth() / 1000f; - float h = (float)pos.getHeight() / 1000f; - renderer.placeImage(x, y, w, h, xobj); - - return xobj; - } - /** {@inheritDoc} */ public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException { diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java index 02dd98ecf..7ac181014 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java @@ -19,7 +19,6 @@ package org.apache.fop.render.pdf; -import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; @@ -27,47 +26,21 @@ import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG; -import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFImage; -import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.ImageHandler; -import org.apache.fop.render.RendererContext; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo; /** * Image handler implementation which handles raw JPEG images for PDF output. */ -public class PDFImageHandlerRawJPEG implements PDFImageHandler, ImageHandler { +public class PDFImageHandlerRawJPEG implements ImageHandler { private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.RAW_JPEG, }; - /** {@inheritDoc} */ - public PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) - throws IOException { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - ImageRawJPEG jpeg = (ImageRawJPEG)image; - PDFDocument pdfDoc = (PDFDocument)context.getProperty( - PDFRendererContextConstants.PDF_DOCUMENT); - PDFResourceContext resContext = (PDFResourceContext)context.getProperty( - PDFRendererContextConstants.PDF_CONTEXT); - - PDFImage pdfimage = new ImageRawJPEGAdapter(jpeg, image.getInfo().getOriginalURI()); - PDFXObject xobj = pdfDoc.addImage(resContext, pdfimage); - - float x = (float)pos.getX() / 1000f; - float y = (float)pos.getY() / 1000f; - float w = (float)pos.getWidth() / 1000f; - float h = (float)pos.getHeight() / 1000f; - renderer.placeImage(x, y, w, h, xobj); - - return xobj; - } - /** {@inheritDoc} */ public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException { diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java deleted file mode 100644 index 1d4c733a3..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import org.apache.fop.render.AbstractImageHandlerRegistry; - -/** - * This class holds references to various image handlers used by the PDF renderer. It also - * supports automatic discovery of additional handlers available through - * the class path. - */ -public class PDFImageHandlerRegistry extends AbstractImageHandlerRegistry { - - /** {@inheritDoc} */ - public Class getHandlerClass() { - return PDFImageHandler.class; - } - -} diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java index 3c02cb6f3..e0ff3cdd4 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java @@ -19,7 +19,6 @@ package org.apache.fop.render.pdf; -import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; @@ -27,48 +26,22 @@ import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; -import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFImage; -import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.ImageHandler; -import org.apache.fop.render.RendererContext; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo; /** * Image handler implementation which handles RenderedImage instances for PDF output. */ -public class PDFImageHandlerRenderedImage implements PDFImageHandler, ImageHandler { +public class PDFImageHandlerRenderedImage implements ImageHandler { private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; - /** {@inheritDoc} */ - public PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) - throws IOException { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - ImageRendered imageRend = (ImageRendered)image; - PDFDocument pdfDoc = (PDFDocument)context.getProperty( - PDFRendererContextConstants.PDF_DOCUMENT); - PDFResourceContext resContext = (PDFResourceContext)context.getProperty( - PDFRendererContextConstants.PDF_CONTEXT); - - PDFImage pdfimage = new ImageRenderedAdapter(imageRend, image.getInfo().getOriginalURI()); - PDFXObject xobj = pdfDoc.addImage(resContext, pdfimage); - - float x = (float)pos.getX() / 1000f; - float y = (float)pos.getY() / 1000f; - float w = (float)pos.getWidth() / 1000f; - float h = (float)pos.getHeight() / 1000f; - renderer.placeImage(x, y, w, h, xobj); - - return xobj; - } - /** {@inheritDoc} */ public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException { diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java deleted file mode 100644 index 26ba83371..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import java.awt.Point; -import java.awt.Rectangle; -import java.io.IOException; -import java.util.Map; - -import org.apache.fop.pdf.PDFXObject; -import org.apache.fop.render.RendererContext; -import org.apache.xmlgraphics.image.loader.Image; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; -import org.w3c.dom.Document; - -/** - * PDFImageHandler implementation which handles XML-based images. - */ -public class PDFImageHandlerXML implements PDFImageHandler { - - private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { - ImageFlavor.XML_DOM, - }; - - /** {@inheritDoc} */ - public PDFXObject generateImage(RendererContext context, Image image, - Point origin, Rectangle pos) - throws IOException { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - ImageXMLDOM imgXML = (ImageXMLDOM)image; - Document doc = imgXML.getDocument(); - String ns = imgXML.getRootNamespace(); - Map foreignAttributes = (Map)context.getProperty( - PDFRendererContextConstants.FOREIGN_ATTRIBUTES); - renderer.renderDocument(doc, ns, pos, foreignAttributes); - return null; - } - - /** {@inheritDoc} */ - public int getPriority() { - return 400; - } - - /** {@inheritDoc} */ - public Class getSupportedImageClass() { - return ImageXMLDOM.class; - } - - /** {@inheritDoc} */ - public ImageFlavor[] getSupportedImageFlavors() { - return FLAVORS; - } - -} diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java deleted file mode 100644 index 1aa5ac74e..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -// Java -import java.awt.Color; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.image.loader.util.ImageUtil; - -import org.apache.fop.ResourceEventProducer; -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.area.Area; -import org.apache.fop.area.Block; -import org.apache.fop.area.BookmarkData; -import org.apache.fop.area.CTM; -import org.apache.fop.area.DestinationData; -import org.apache.fop.area.LineArea; -import org.apache.fop.area.OffDocumentExtensionAttachment; -import org.apache.fop.area.OffDocumentItem; -import org.apache.fop.area.PageSequence; -import org.apache.fop.area.PageViewport; -import org.apache.fop.area.Trait; -import org.apache.fop.area.inline.AbstractTextArea; -import org.apache.fop.area.inline.Image; -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.area.inline.InlineParent; -import org.apache.fop.area.inline.Leader; -import org.apache.fop.area.inline.SpaceArea; -import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.inline.Viewport; -import org.apache.fop.area.inline.WordArea; -import org.apache.fop.datatypes.URISpecification; -import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.apache.fop.fo.extensions.xmp.XMPMetadata; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.LazyFont; -import org.apache.fop.fonts.SingleByteFont; -import org.apache.fop.fonts.Typeface; -import org.apache.fop.pdf.PDFAMode; -import org.apache.fop.pdf.PDFAction; -import org.apache.fop.pdf.PDFAnnotList; -import org.apache.fop.pdf.PDFDocument; -import org.apache.fop.pdf.PDFEncryptionParams; -import org.apache.fop.pdf.PDFFactory; -import org.apache.fop.pdf.PDFGoTo; -import org.apache.fop.pdf.PDFInfo; -import org.apache.fop.pdf.PDFLink; -import org.apache.fop.pdf.PDFNumber; -import org.apache.fop.pdf.PDFOutline; -import org.apache.fop.pdf.PDFPage; -import org.apache.fop.pdf.PDFPaintingState; -import org.apache.fop.pdf.PDFResourceContext; -import org.apache.fop.pdf.PDFResources; -import org.apache.fop.pdf.PDFTextUtil; -import org.apache.fop.pdf.PDFXMode; -import org.apache.fop.pdf.PDFXObject; -import org.apache.fop.render.AbstractPathOrientedRenderer; -import org.apache.fop.render.Graphics2DAdapter; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo; -import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment; -import org.apache.fop.traits.RuleStyle; -import org.apache.fop.util.AbstractPaintingState; -import org.apache.fop.util.CharUtilities; -import org.apache.fop.util.XMLUtil; -import org.apache.fop.util.AbstractPaintingState.AbstractData; - -/** - * Renderer that renders areas to PDF. - */ -public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConfigurationConstants { - - /** The MIME type for PDF */ - public static final String MIME_TYPE = MimeConstants.MIME_PDF; - - /** Normal PDF resolution (72dpi) */ - public static final int NORMAL_PDF_RESOLUTION = 72; - - - /** Controls whether comments are written to the PDF stream. */ - protected static final boolean WRITE_COMMENTS = true; - - /** - * the PDF Document being created - */ - protected PDFDocument pdfDoc; - - /** - * Utility class which enables all sorts of features that are not directly connected to the - * normal rendering process. - */ - protected PDFRenderingUtil pdfUtil; - - /** - * Map of pages using the PageViewport as the key - * this is used for prepared pages that cannot be immediately - * rendered - */ - private Map pages; - - /** - * Maps unique PageViewport key to PDF page reference - */ - protected Map pageReferences = new java.util.HashMap(); - - /** - * Maps unique PageViewport key back to PageViewport itself - */ - //protected Map pvReferences = new java.util.HashMap(); - - /** - * Maps XSL-FO element IDs to their on-page XY-positions - * Must be used in conjunction with the page reference to fully specify the PDFGoTo details - */ - protected Map idPositions = new java.util.HashMap(); - - /** - * Maps XSL-FO element IDs to PDFGoTo objects targeting the corresponding areas - * These objects may not all be fully filled in yet - */ - protected Map idGoTos = new java.util.HashMap(); - - /** - * The PDFGoTos in idGoTos that are not complete yet - */ - protected List unfinishedGoTos = new java.util.ArrayList(); - // can't use a Set because PDFGoTo.equals returns true if the target is the same, - // even if the object number differs - - /** - * The output stream to write the document to - */ - protected OutputStream ostream; - - /** - * the /Resources object of the PDF document being created - */ - protected PDFResources pdfResources; - - /** The current content generator to produce PDF commands with */ - protected PDFContentGenerator generator; - private PDFBorderPainter borderPainter; - - /** - * the current annotation list to add annotations to - */ - protected PDFResourceContext currentContext = null; - - /** - * the current page to add annotations to - */ - protected PDFPage currentPage; - - /** - * the current page's PDF reference string (to avoid numerous function calls) - */ - protected String currentPageRef; - - /** page height */ - protected int pageHeight; - - /** Image handler registry */ - private final PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry(); - - private boolean accessEnabled; - - private PDFLogicalStructureHandler logicalStructureHandler; - - private int pageSequenceIndex; - - /** Reference in the structure tree to the image being rendered. */ - private String imageReference; - - /** - * create the PDF renderer - */ - public PDFRenderer() { - } - - /** {@inheritDoc} */ - public void setUserAgent(FOUserAgent agent) { - super.setUserAgent(agent); - this.pdfUtil = new PDFRenderingUtil(getUserAgent()); - accessEnabled = agent.isAccessibilityEnabled(); - } - - PDFRenderingUtil getPDFUtil() { - return this.pdfUtil; - } - - PDFContentGenerator getGenerator() { - return this.generator; - } - - PDFPaintingState getState() { - return getGenerator().getState(); - } - - /** {@inheritDoc} */ - public void startRenderer(OutputStream stream) throws IOException { - if (userAgent == null) { - throw new IllegalStateException("UserAgent must be set before starting the renderer"); - } - ostream = stream; - this.pdfDoc = pdfUtil.setupPDFDocument(stream); - if (accessEnabled) { - pdfDoc.getRoot().makeTagged(); - logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc, - userAgent.getEventBroadcaster()); - } - } - - /** - * Checks if there are any unfinished PDFGoTos left in the list and resolves them - * to a default position on the page. Logs a warning, as this should not happen. - */ - protected void finishOpenGoTos() { - int count = unfinishedGoTos.size(); - if (count > 0) { - // TODO : page height may not be the same for all targeted pages - Point2D.Float defaultPos = new Point2D.Float(0f, pageHeight / 1000f); // top-o-page - while (!unfinishedGoTos.isEmpty()) { - PDFGoTo gt = (PDFGoTo) unfinishedGoTos.get(0); - finishIDGoTo(gt, defaultPos); - } - PDFEventProducer eventProducer = PDFEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.nonFullyResolvedLinkTargets(this, count); - // dysfunctional if pageref is null - } - } - - /** {@inheritDoc} */ - public void stopRenderer() throws IOException { - finishOpenGoTos(); - - pdfDoc.getResources().addFonts(pdfDoc, fontInfo); - pdfDoc.outputTrailer(ostream); - - this.pdfDoc = null; - ostream = null; - - pages = null; - - pageReferences.clear(); - //pvReferences.clear(); - pdfResources = null; - this.generator = null; - currentContext = null; - currentPage = null; - - idPositions.clear(); - idGoTos.clear(); - } - - /** - * {@inheritDoc} - */ - public boolean supportsOutOfOrder() { - return !accessEnabled; - } - - /** - * {@inheritDoc} - */ - public void processOffDocumentItem(OffDocumentItem odi) { - if (odi instanceof DestinationData) { - // render Destinations - renderDestination((DestinationData) odi); - } else if (odi instanceof BookmarkData) { - // render Bookmark-Tree - renderBookmarkTree((BookmarkData) odi); - } else if (odi instanceof OffDocumentExtensionAttachment) { - ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)odi).getAttachment(); - if (XMPMetadata.CATEGORY.equals(attachment.getCategory())) { - pdfUtil.renderXMPMetadata((XMPMetadata)attachment); - } else if (PDFEmbeddedFileExtensionAttachment.CATEGORY.equals( - attachment.getCategory())) { - try { - pdfUtil.addEmbeddedFile((PDFEmbeddedFileExtensionAttachment)attachment); - } catch (IOException ioe) { - throw new RuntimeException("Error embedding file", ioe); - } - } - } - } - - private void renderDestination(DestinationData dd) { - String targetID = dd.getIDRef(); - if (targetID == null || targetID.length() == 0) { - throw new IllegalArgumentException("DestinationData must contain a ID reference"); - } - PageViewport pv = dd.getPageViewport(); - if (pv != null) { - PDFGoTo gt = getPDFGoToForID(targetID, pv.getKey()); - pdfDoc.getFactory().makeDestination( - dd.getIDRef(), gt.makeReference()); - } else { - //Warning already issued by AreaTreeHandler (debug level is sufficient) - log.debug("Unresolved destination item received: " + dd.getIDRef()); - } - } - - /** - * Renders a Bookmark-Tree object - * @param bookmarks the BookmarkData object containing all the Bookmark-Items - */ - protected void renderBookmarkTree(BookmarkData bookmarks) { - for (int i = 0; i < bookmarks.getCount(); i++) { - BookmarkData ext = bookmarks.getSubData(i); - renderBookmarkItem(ext, null); - } - } - - private void renderBookmarkItem(BookmarkData bookmarkItem, - PDFOutline parentBookmarkItem) { - PDFOutline pdfOutline = null; - - String targetID = bookmarkItem.getIDRef(); - if (targetID == null || targetID.length() == 0) { - throw new IllegalArgumentException("DestinationData must contain a ID reference"); - } - PageViewport pv = bookmarkItem.getPageViewport(); - if (pv != null) { - String pvKey = pv.getKey(); - PDFGoTo gt = getPDFGoToForID(targetID, pvKey); - // create outline object: - PDFOutline parent = parentBookmarkItem != null - ? parentBookmarkItem - : pdfDoc.getOutlineRoot(); - pdfOutline = pdfDoc.getFactory().makeOutline(parent, - bookmarkItem.getBookmarkTitle(), gt, bookmarkItem.showChildItems()); - } else { - //Warning already issued by AreaTreeHandler (debug level is sufficient) - log.debug("Bookmark with IDRef \"" + targetID + "\" has a null PageViewport."); - } - - for (int i = 0; i < bookmarkItem.getCount(); i++) { - renderBookmarkItem(bookmarkItem.getSubData(i), pdfOutline); - } - } - - /** {@inheritDoc} */ - public Graphics2DAdapter getGraphics2DAdapter() { - return new PDFGraphics2DAdapter(this); - } - - /** {@inheritDoc} */ - protected void saveGraphicsState() { - generator.saveGraphicsState(); - } - - /** {@inheritDoc} */ - protected void restoreGraphicsState() { - generator.restoreGraphicsState(); - } - - /** Indicates the beginning of a text object. */ - protected void beginTextObject() { - generator.beginTextObject(); - } - - /** Indicates the end of a text object. */ - protected void endTextObject() { - generator.endTextObject(); - } - - /** - * Start the next page sequence. - * For the PDF renderer there is no concept of page sequences - * but it uses the first available page sequence title to set - * as the title of the PDF document, and the language of the - * document. - * @param pageSequence the page sequence - */ - public void startPageSequence(PageSequence pageSequence) { - super.startPageSequence(pageSequence); - LineArea seqTitle = pageSequence.getTitle(); - if (seqTitle != null) { - String str = convertTitleToString(seqTitle); - PDFInfo info = this.pdfDoc.getInfo(); - if (info.getTitle() == null) { - info.setTitle(str); - } - } - Locale language = null; - if (pageSequence.getLanguage() != null) { - String lang = pageSequence.getLanguage(); - String country = pageSequence.getCountry(); - if (lang != null) { - language = (country == null) ? new Locale(lang) : new Locale(lang, country); - } - if (pdfDoc.getRoot().getLanguage() == null) { - //Only set if not set already (first non-null is used) - //Note: No checking is performed whether the values are valid! - pdfDoc.getRoot().setLanguage(XMLUtil.toRFC3066(language)); - } - } - pdfUtil.generateDefaultXMPMetadata(); - if (accessEnabled) { - NodeList nodes = getUserAgent().getStructureTree().getPageSequence(pageSequenceIndex++); - logicalStructureHandler.processStructureTree(nodes, language); - } - } - - /** - * The pdf page is prepared by making the page. - * The page is made in the pdf document without any contents - * and then stored to add the contents later. - * The page objects is stored using the area tree PageViewport - * as a key. - * - * @param page the page to prepare - */ - public void preparePage(PageViewport page) { - setupPage(page); - if (pages == null) { - pages = new java.util.HashMap(); - } - pages.put(page, currentPage); - } - - private void setupPage(PageViewport page) { - this.pdfResources = this.pdfDoc.getResources(); - - Rectangle2D bounds = page.getViewArea(); - double w = bounds.getWidth(); - double h = bounds.getHeight(); - this.currentPage = this.pdfDoc.getFactory().makePage( - this.pdfResources, - (int) Math.round(w / 1000), (int) Math.round(h / 1000), - page.getPageIndex()); - pageReferences.put(page.getKey(), currentPage.referencePDF()); - //pvReferences.put(page.getKey(), page); - - pdfUtil.generatePageLabel(page.getPageIndex(), page.getPageNumberString()); - } - - /** - * This method creates a PDF stream for the current page - * uses it as the contents of a new page. The page is written - * immediately to the output stream. - * {@inheritDoc} - */ - public void renderPage(PageViewport page) - throws IOException, FOPException { - if (pages != null - && (currentPage = (PDFPage) pages.get(page)) != null) { // CSOK: InnerAssignment - //Retrieve previously prepared page (out-of-line rendering) - pages.remove(page); - } else { - setupPage(page); - } - currentPageRef = currentPage.referencePDF(); - - if (accessEnabled) { - logicalStructureHandler.startPage(currentPage); - } - - Rectangle bounds = page.getViewArea(); - pageHeight = bounds.height; - - this.generator = new PDFContentGenerator(this.pdfDoc, this.ostream, this.currentPage); - this.borderPainter = new PDFBorderPainter(this.generator); - - // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's - saveGraphicsState(); - AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0, - pageHeight / 1000f); - generator.concatenate(basicPageTransform); - - super.renderPage(page); - - restoreGraphicsState(); - if (accessEnabled) { - logicalStructureHandler.endPage(); - } - - this.pdfDoc.registerObject(generator.getStream()); - currentPage.setContents(generator.getStream()); - PDFAnnotList annots = currentPage.getAnnotations(); - if (annots != null) { - this.pdfDoc.addObject(annots); - } - this.pdfDoc.addObject(currentPage); - this.borderPainter = null; - this.generator.flushPDFDoc(); - this.generator = null; - } - - /** {@inheritDoc} */ - protected void startVParea(CTM ctm, Rectangle2D clippingRect) { - saveGraphicsState(); - // Set the given CTM in the graphics state - /* - currentState.concatenate( - new AffineTransform(CTMHelper.toPDFArray(ctm))); - */ - - if (clippingRect != null) { - clipRect((float)clippingRect.getX() / 1000f, - (float)clippingRect.getY() / 1000f, - (float)clippingRect.getWidth() / 1000f, - (float)clippingRect.getHeight() / 1000f); - } - // multiply with current CTM - generator.concatenate(new AffineTransform(CTMHelper.toPDFArray(ctm))); - } - - /** {@inheritDoc} */ - protected void endVParea() { - restoreGraphicsState(); - } - - /** {@inheritDoc} */ - protected void concatenateTransformationMatrix(AffineTransform at) { - generator.concatenate(at); - } - - /** - * Formats a float value (normally coordinates) as Strings. - * @param value the value - * @return the formatted value - */ - protected static String format(float value) { - return PDFNumber.doubleOut(value); - } - - /** {@inheritDoc} */ - protected void drawBorderLine // CSOK: ParameterNumber - (float x1, float y1, float x2, float y2, - boolean horz, boolean startOrBefore, int style, Color col) { - PDFBorderPainter.drawBorderLine(generator, x1, y1, x2, y2, horz, startOrBefore, style, col); - } - - /** {@inheritDoc} */ - protected void clipRect(float x, float y, float width, float height) { - generator.add(format(x) + " " + format(y) + " " - + format(width) + " " + format(height) + " re "); - clip(); - } - - /** - * Clip an area. - */ - protected void clip() { - generator.add("W\n" + "n\n"); - } - - /** - * Moves the current point to (x, y), omitting any connecting line segment. - * @param x x coordinate - * @param y y coordinate - */ - protected void moveTo(float x, float y) { - generator.add(format(x) + " " + format(y) + " m "); - } - - /** - * Appends a straight line segment from the current point to (x, y). The - * new current point is (x, y). - * @param x x coordinate - * @param y y coordinate - */ - protected void lineTo(float x, float y) { - generator.add(format(x) + " " + format(y) + " l "); - } - - /** - * Closes the current subpath by appending a straight line segment from - * the current point to the starting point of the subpath. - */ - protected void closePath() { - generator.add("h "); - } - - /** - * {@inheritDoc} - */ - protected void fillRect(float x, float y, float width, float height) { - if (width > 0 && height > 0) { - generator.add(format(x) + " " + format(y) + " " - + format(width) + " " + format(height) + " re f\n"); - } - } - - /** - * Draw a line. - * - * @param startx the start x position - * @param starty the start y position - * @param endx the x end position - * @param endy the y end position - */ - private void drawLine(float startx, float starty, float endx, float endy) { - generator.add(format(startx) + " " + format(starty) + " m "); - generator.add(format(endx) + " " + format(endy) + " l S\n"); - } - - /** - * Breaks out of the state stack to handle fixed block-containers. - * @return the saved state stack to recreate later - */ - protected List breakOutOfStateStack() { - PDFPaintingState paintingState = getState(); - List breakOutList = new java.util.ArrayList(); - AbstractPaintingState.AbstractData data; - while (true) { - data = paintingState.getData(); - if (paintingState.restore() == null) { - break; - } - if (breakOutList.size() == 0) { - generator.comment("------ break out!"); - } - breakOutList.add(0, data); //Insert because of stack-popping - generator.restoreGraphicsState(false); - } - return breakOutList; - } - - /** - * Restores the state stack after a break out. - * @param breakOutList the state stack to restore. - */ - protected void restoreStateStackAfterBreakOut(List breakOutList) { - generator.comment("------ restoring context after break-out..."); -// currentState.pushAll(breakOutList); - AbstractData data; - Iterator i = breakOutList.iterator(); - while (i.hasNext()) { - data = (AbstractData)i.next(); - saveGraphicsState(); - AffineTransform at = data.getTransform(); - concatenateTransformationMatrix(at); - //TODO Break-out: Also restore items such as line width and color - //Left out for now because all this painting stuff is very - //inconsistent. Some values go over PDFState, some don't. - } - generator.comment("------ done."); - } - - /** - * Returns area's id if it is the first area in the document with that id - * (i.e. if the area qualifies as a link target). - * Otherwise, or if the area has no id, null is returned. - * - * NOTE: area must be on currentPageViewport, otherwise result may be wrong! - * - * @param area the area for which to return the id - * @return the area's id (null if the area has no id or - * other preceding areas have the same id) - */ - protected String getTargetableID(Area area) { - String id = (String) area.getTrait(Trait.PROD_ID); - if (id == null || id.length() == 0 - || !currentPageViewport.isFirstWithID(id) - || idPositions.containsKey(id)) { - return null; - } else { - return id; - } - } - - /** - * Set XY position in the PDFGoTo and add it to the PDF trailer. - * - * @param gt the PDFGoTo object - * @param position the X,Y position to set - */ - protected void finishIDGoTo(PDFGoTo gt, Point2D.Float position) { - gt.setPosition(position); - pdfDoc.addTrailerObject(gt); - unfinishedGoTos.remove(gt); - } - - /** - * Set page reference and XY position in the PDFGoTo and add it to the PDF trailer. - * - * @param gt the PDFGoTo object - * @param pdfPageRef the PDF reference string of the target page object - * @param position the X,Y position to set - */ - protected void finishIDGoTo(PDFGoTo gt, String pdfPageRef, Point2D.Float position) { - gt.setPageReference(pdfPageRef); - finishIDGoTo(gt, position); - } - - /** - * Get a PDFGoTo pointing to the given id. Create one if necessary. - * It is possible that the PDFGoTo is not fully resolved yet. In that case - * it must be completed (and added to the PDF trailer) later. - * - * @param targetID the target id of the PDFGoTo - * @param pvKey the unique key of the target PageViewport - * - * @return the PDFGoTo that was found or created - */ - protected PDFGoTo getPDFGoToForID(String targetID, String pvKey) { - // Already a PDFGoTo present for this target? If not, create. - PDFGoTo gt = (PDFGoTo) idGoTos.get(targetID); - if (gt == null) { - String pdfPageRef = (String) pageReferences.get(pvKey); - Point2D.Float position = (Point2D.Float) idPositions.get(targetID); - // can the GoTo already be fully filled in? - if (pdfPageRef != null && position != null) { - // getPDFGoTo shares PDFGoTo objects as much as possible. - // It also takes care of assignObjectNumber and addTrailerObject. - gt = pdfDoc.getFactory().getPDFGoTo(pdfPageRef, position); - } else { - // Not complete yet, can't use getPDFGoTo: - gt = new PDFGoTo(pdfPageRef); - pdfDoc.assignObjectNumber(gt); - // pdfDoc.addTrailerObject() will be called later, from finishIDGoTo() - unfinishedGoTos.add(gt); - } - idGoTos.put(targetID, gt); - } - return gt; - } - - /** - * Saves id's absolute position on page for later retrieval by PDFGoTos - * - * @param id the id of the area whose position must be saved - * @param pdfPageRef the PDF page reference string - * @param relativeIPP the *relative* IP position in millipoints - * @param relativeBPP the *relative* BP position in millipoints - * @param tf the transformation to apply once the relative positions have been - * converted to points - */ - protected void saveAbsolutePosition(String id, String pdfPageRef, - int relativeIPP, int relativeBPP, AffineTransform tf) { - Point2D.Float position = new Point2D.Float(relativeIPP / 1000f, relativeBPP / 1000f); - tf.transform(position, position); - idPositions.put(id, position); - // is there already a PDFGoTo waiting to be completed? - PDFGoTo gt = (PDFGoTo) idGoTos.get(id); - if (gt != null) { - finishIDGoTo(gt, pdfPageRef, position); - } -/* - // The code below auto-creates a named destination for every id in the document. - // This should probably be controlled by a user-configurable setting, as it may - // make the PDF file grow noticeably. - // *** NOT YET WELL-TESTED ! *** - if (true) { - PDFFactory factory = pdfDoc.getFactory(); - if (gt == null) { - gt = factory.getPDFGoTo(pdfPageRef, position); - idGoTos.put(id, gt); // so others can pick it up too - } - factory.makeDestination(id, gt.referencePDF(), currentPageViewport); - // Note: using currentPageViewport is only correct if the id is indeed on - // the current PageViewport. But even if incorrect, it won't interfere with - // what gets created in the PDF. - // For speedup, we should also create a lookup map id -> PDFDestination - } -*/ - } - - /** - * Saves id's absolute position on page for later retrieval by PDFGoTos, - * using the currently valid transformation and the currently valid PDF page reference - * - * @param id the id of the area whose position must be saved - * @param relativeIPP the *relative* IP position in millipoints - * @param relativeBPP the *relative* BP position in millipoints - */ - protected void saveAbsolutePosition(String id, int relativeIPP, int relativeBPP) { - saveAbsolutePosition(id, currentPageRef, - relativeIPP, relativeBPP, getState().getTransform()); - } - - /** - * If the given block area is a possible link target, its id + absolute position will - * be saved. The saved position is only correct if this function is called at the very - * start of renderBlock! - * - * @param block the block area in question - */ - protected void saveBlockPosIfTargetable(Block block) { - String id = getTargetableID(block); - if (id != null) { - // FIXME: Like elsewhere in the renderer code, absolute and relative - // directions are happily mixed here. This makes sure that the - // links point to the right location, but it is not correct. - int ipp = block.getXOffset(); - int bpp = block.getYOffset() + block.getSpaceBefore(); - int positioning = block.getPositioning(); - if (!(positioning == Block.FIXED || positioning == Block.ABSOLUTE)) { - ipp += currentIPPosition; - bpp += currentBPPosition; - } - AffineTransform tf = positioning == Block.FIXED - ? getState().getBaseTransform() - : getState().getTransform(); - saveAbsolutePosition(id, currentPageRef, ipp, bpp, tf); - } - } - - /** - * If the given inline area is a possible link target, its id + absolute position will - * be saved. The saved position is only correct if this function is called at the very - * start of renderInlineArea! - * - * @param inlineArea the inline area in question - */ - protected void saveInlinePosIfTargetable(InlineArea inlineArea) { - String id = getTargetableID(inlineArea); - if (id != null) { - int extraMarginBefore = 5000; // millipoints - int ipp = currentIPPosition; - int bpp = currentBPPosition + inlineArea.getOffset() - extraMarginBefore; - saveAbsolutePosition(id, ipp, bpp); - } - } - - /** - * {@inheritDoc} - */ - protected void renderBlock(Block block) { - saveBlockPosIfTargetable(block); - super.renderBlock(block); - } - - /** {@inheritDoc} */ - protected void renderLineArea(LineArea line) { - super.renderLineArea(line); - } - - /** - * {@inheritDoc} - */ - protected void renderInlineArea(InlineArea inlineArea) { - saveInlinePosIfTargetable(inlineArea); - super.renderInlineArea(inlineArea); - } - - /** - * Render inline parent area. - * For pdf this handles the inline parent area traits such as - * links, border, background. - * @param ip the inline parent area - */ - public void renderInlineParent(InlineParent ip) { - - boolean annotsAllowed = pdfDoc.getProfile().isAnnotationAllowed(); - - // stuff we only need if a link must be created: - Rectangle2D ipRect = null; - PDFFactory factory = null; - PDFAction action = null; - if (annotsAllowed) { - // make sure the rect is determined *before* calling super! - int ipp = currentIPPosition; - int bpp = currentBPPosition + ip.getOffset(); - ipRect = new Rectangle2D.Float(ipp / 1000f, bpp / 1000f, - ip.getIPD() / 1000f, ip.getBPD() / 1000f); - AffineTransform transform = getState().getTransform(); - ipRect = transform.createTransformedShape(ipRect).getBounds2D(); - - factory = pdfDoc.getFactory(); - } - - // render contents - super.renderInlineParent(ip); - - boolean linkTraitFound = false; - - // try INTERNAL_LINK first - Trait.InternalLink intLink = (Trait.InternalLink) ip.getTrait(Trait.INTERNAL_LINK); - if (intLink != null) { - linkTraitFound = true; - String pvKey = intLink.getPVKey(); - String idRef = intLink.getIDRef(); - boolean pvKeyOK = pvKey != null && pvKey.length() > 0; - boolean idRefOK = idRef != null && idRef.length() > 0; - if (pvKeyOK && idRefOK) { - if (annotsAllowed) { - action = getPDFGoToForID(idRef, pvKey); - } - } else { - //Warnings already issued by AreaTreeHandler - } - } - - // no INTERNAL_LINK, look for EXTERNAL_LINK - if (!linkTraitFound) { - Trait.ExternalLink extLink = (Trait.ExternalLink) ip.getTrait(Trait.EXTERNAL_LINK); - if (extLink != null) { - String extDest = extLink.getDestination(); - if (extDest != null && extDest.length() > 0) { - linkTraitFound = true; - if (annotsAllowed) { - action = factory.getExternalAction(extDest, extLink.newWindow()); - } - } - } - } - - // warn if link trait found but not allowed, else create link - if (linkTraitFound) { - if (!annotsAllowed) { - log.warn("Skipping annotation for a link due to PDF profile: " - + pdfDoc.getProfile()); - } else if (action != null) { - PDFLink pdfLink = factory.makeLink(ipRect, action); - if (accessEnabled) { - String ptr = (String) ip.getTrait(Trait.PTR); - logicalStructureHandler.addLinkContentItem(pdfLink, ptr); - } - currentPage.addAnnotation(pdfLink); - } - } - } - - /** {@inheritDoc} */ - public void renderViewport(Viewport viewport) { - imageReference = (String) viewport.getTrait(Trait.PTR); - super.renderViewport(viewport); - imageReference = null; - } - - private Typeface getTypeface(String fontName) { - Typeface tf = (Typeface) fontInfo.getFonts().get(fontName); - if (tf instanceof LazyFont) { - tf = ((LazyFont)tf).getRealFont(); - } - return tf; - } - - /** {@inheritDoc} */ - public void renderText(TextArea text) { - renderInlineAreaBackAndBorders(text); - Color ct = (Color) text.getTrait(Trait.COLOR); - updateColor(ct, true); - - if (accessEnabled) { - String ptr = (String) text.getTrait(Trait.PTR); - MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(ptr); - if (generator.getTextUtil().isInTextObject()) { - generator.separateTextElements(mci.tag, mci.mcid); - } - generator.beginTextObject(mci.tag, mci.mcid); - } else { - beginTextObject(); - } - - String fontName = getInternalFontNameForArea(text); - int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - - // This assumes that *all* CIDFonts use a /ToUnicode mapping - Typeface tf = getTypeface(fontName); - - PDFTextUtil textutil = generator.getTextUtil(); - textutil.updateTf(fontName, size / 1000f, tf.isMultiByte()); - - - // word.getOffset() = only height of text itself - // currentBlockIPPosition: 0 for beginning of line; nonzero - // where previous line area failed to take up entire allocated space - int rx = currentIPPosition + text.getBorderAndPaddingWidthStart(); - int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset(); - - textutil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, rx / 1000f, bl / 1000f)); - - super.renderText(text); - - textutil.writeTJ(); - - renderTextDecoration(tf, size, text, bl, rx); - } - - /** {@inheritDoc} */ - public void renderWord(WordArea word) { - Font font = getFontFromArea(word.getParentArea()); - String s = word.getWord(); - - escapeText(s, word.getLetterAdjustArray(), - font, (AbstractTextArea)word.getParentArea()); - - super.renderWord(word); - } - - /** {@inheritDoc} */ - public void renderSpace(SpaceArea space) { - Font font = getFontFromArea(space.getParentArea()); - String s = space.getSpace(); - - AbstractTextArea textArea = (AbstractTextArea)space.getParentArea(); - escapeText(s, null, font, textArea); - - if (space.isAdjustable()) { - int tws = -((TextArea) space.getParentArea()).getTextWordSpaceAdjust() - - 2 * textArea.getTextLetterSpaceAdjust(); - - if (tws != 0) { - float adjust = tws / (font.getFontSize() / 1000f); - generator.getTextUtil().adjustGlyphTJ(adjust); - } - } - - super.renderSpace(space); - } - - /** - * Escapes text according to PDF rules. - * @param s Text to escape - * @param letterAdjust an array of widths for letter adjustment (may be null) - * @param font to font in use - * @param parentArea the parent text area to retrieve certain traits from - */ - protected void escapeText(String s, - int[] letterAdjust, - Font font, AbstractTextArea parentArea) { - escapeText(s, 0, s.length(), letterAdjust, font, parentArea); - } - - /** - * Escapes text according to PDF rules. - * @param s Text to escape - * @param start the start position in the text - * @param end the end position in the text - * @param letterAdjust an array of widths for letter adjustment (may be null) - * @param font to font in use - * @param parentArea the parent text area to retrieve certain traits from - */ - protected void escapeText(String s, int start, int end, - int[] letterAdjust, - Font font, AbstractTextArea parentArea) { - String fontName = font.getFontName(); - float fontSize = font.getFontSize() / 1000f; - Typeface tf = getTypeface(fontName); - SingleByteFont singleByteFont = null; - if (tf instanceof SingleByteFont) { - singleByteFont = (SingleByteFont)tf; - } - PDFTextUtil textutil = generator.getTextUtil(); - - int l = s.length(); - - for (int i = start; i < end; i++) { - char orgChar = s.charAt(i); - char ch; - float glyphAdjust = 0; - if (font.hasChar(orgChar)) { - ch = font.mapChar(orgChar); - if (singleByteFont != null && singleByteFont.hasAdditionalEncodings()) { - int encoding = ch / 256; - if (encoding == 0) { - textutil.updateTf(fontName, fontSize, tf.isMultiByte()); - } else { - textutil.updateTf(fontName + "_" + Integer.toString(encoding), - fontSize, tf.isMultiByte()); - ch = (char)(ch % 256); - } - } - int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0); - glyphAdjust -= tls; - } else { - if (CharUtilities.isFixedWidthSpace(orgChar)) { - //Fixed width space are rendered as spaces so copy/paste works in a reader - ch = font.mapChar(CharUtilities.SPACE); - glyphAdjust = font.getCharWidth(ch) - font.getCharWidth(orgChar); - } else { - ch = font.mapChar(orgChar); - } - } - if (letterAdjust != null && i < l - 1) { - glyphAdjust -= letterAdjust[i + 1]; - } - - textutil.writeTJMappedChar(ch); - - float adjust = glyphAdjust / fontSize; - - if (adjust != 0) { - textutil.adjustGlyphTJ(adjust); - } - - } - } - - /** {@inheritDoc} */ - protected void updateColor(Color col, boolean fill) { - generator.updateColor(col, fill, null); - } - - /** {@inheritDoc} */ - public void renderImage(Image image, Rectangle2D pos) { - endTextObject(); - String url = image.getURL(); - putImage(url, pos, image.getForeignAttributes()); - } - - /** {@inheritDoc} */ - protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { - endTextObject(); - putImage(url, pos, foreignAttributes); - } - - /** - * Adds a PDF XObject (a bitmap or form) to the PDF that will later be referenced. - * @param uri URL of the bitmap - * @param pos Position of the bitmap - * @deprecated Use {@link #putImage(String, Rectangle2D, Map)} instead. - */ - protected void putImage(String uri, Rectangle2D pos) { - putImage(uri, pos, null); - } - - /** - * Adds a PDF XObject (a bitmap or form) to the PDF that will later be referenced. - * @param uri URL of the bitmap - * @param pos Position of the bitmap - * @param foreignAttributes foreign attributes associated with the image - */ - protected void putImage(String uri, Rectangle2D pos, Map foreignAttributes) { - Rectangle posInt = new Rectangle( - (int)pos.getX(), - (int)pos.getY(), - (int)pos.getWidth(), - (int)pos.getHeight()); - - uri = URISpecification.getURL(uri); - PDFXObject xobject = pdfDoc.getXObject(uri); - if (xobject != null) { - float w = (float) pos.getWidth() / 1000f; - float h = (float) pos.getHeight() / 1000f; - placeImage((float)pos.getX() / 1000f, - (float)pos.getY() / 1000f, w, h, xobject); - return; - } - Point origin = new Point(currentIPPosition, currentBPPosition); - int x = origin.x + posInt.x; - int y = origin.y + posInt.y; - - ImageManager manager = getUserAgent().getFactory().getImageManager(); - ImageInfo info = null; - try { - ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); - info = manager.getImageInfo(uri, sessionContext); - - Map hints = ImageUtil.getDefaultHints(sessionContext); - ImageFlavor[] supportedFlavors = imageHandlerRegistry.getSupportedFlavors(); - org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, supportedFlavors, hints, sessionContext); - - //First check for a dynamically registered handler - PDFImageHandler handler - = (PDFImageHandler)imageHandlerRegistry.getHandler(img.getClass()); - if (handler != null) { - if (log.isDebugEnabled()) { - log.debug("Using PDFImageHandler: " + handler.getClass().getName()); - } - try { - RendererContext context = createRendererContext( - x, y, posInt.width, posInt.height, foreignAttributes); - handler.generateImage(context, img, origin, posInt); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageWritingError(this, ioe); - return; - } - } else { - throw new UnsupportedOperationException( - "No PDFImageHandler available for image: " - + info + " (" + img.getClass().getName() + ")"); - } - } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); - } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); - } - - // output new data - try { - this.generator.flushPDFDoc(); - } catch (IOException ioe) { - // ioexception will be caught later - log.error(ioe.getMessage()); - } - } - - /** - * Places a previously registered image at a certain place on the page. - * @param x X coordinate - * @param y Y coordinate - * @param w width for image - * @param h height for image - * @param xobj the image XObject - */ - public void placeImage(float x, float y, float w, float h, PDFXObject xobj) { - if (accessEnabled) { - MarkedContentInfo mci = logicalStructureHandler.addImageContentItem(imageReference); - generator.saveGraphicsState(mci.tag, mci.mcid); - } else { - saveGraphicsState(); - } - generator.add(format(w) + " 0 0 " - + format(-h) + " " - + format(currentIPPosition / 1000f + x) + " " - + format(currentBPPosition / 1000f + h + y) - + " cm\n" + xobj.getName() + " Do\n"); - if (accessEnabled) { - generator.restoreGraphicsStateAccess(); - } else { - restoreGraphicsState(); - } - } - - /** {@inheritDoc} */ - protected RendererContext createRendererContext(int x, int y, int width, int height, - Map foreignAttributes) { - RendererContext context = super.createRendererContext( - x, y, width, height, foreignAttributes); - context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc); - context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream); - context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage); - context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext); - context.setProperty(PDFRendererContextConstants.PDF_STREAM, generator.getStream()); - context.setProperty(PDFRendererContextConstants.PDF_FONT_INFO, fontInfo); - context.setProperty(PDFRendererContextConstants.PDF_FONT_NAME, ""); - context.setProperty(PDFRendererContextConstants.PDF_FONT_SIZE, new Integer(0)); - return context; - } - - /** {@inheritDoc} */ - public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) { - if (accessEnabled) { - MarkedContentInfo mci = logicalStructureHandler.addImageContentItem(imageReference); - generator.beginMarkedContentSequence(mci.tag, mci.mcid); - } - super.renderDocument(doc, ns, pos, foreignAttributes); - if (accessEnabled) { - generator.endMarkedContentSequence(); - } - } - - /** - * Render leader area. - * This renders a leader area which is an area with a rule. - * @param area the leader area to render - */ - public void renderLeader(Leader area) { - renderInlineAreaBackAndBorders(area); - - int style = area.getRuleStyle(); - int ruleThickness = area.getRuleThickness(); - int startx = currentIPPosition + area.getBorderAndPaddingWidthStart(); - int starty = currentBPPosition + area.getOffset() + (ruleThickness / 2); - int endx = currentIPPosition - + area.getBorderAndPaddingWidthStart() - + area.getIPD(); - Color col = (Color)area.getTrait(Trait.COLOR); - - endTextObject(); - borderPainter.drawLine(new Point(startx, starty), new Point(endx, starty), - ruleThickness, col, RuleStyle.valueOf(style)); - super.renderLeader(area); - } - - /** {@inheritDoc} */ - public String getMimeType() { - return MIME_TYPE; - } - - /** - * Sets the PDF/A mode for the PDF renderer. - * @param mode the PDF/A mode - */ - public void setAMode(PDFAMode mode) { - this.pdfUtil.setAMode(mode); - } - - /** - * Sets the PDF/X mode for the PDF renderer. - * @param mode the PDF/X mode - */ - public void setXMode(PDFXMode mode) { - this.pdfUtil.setXMode(mode); - } - - /** - * Sets the output color profile for the PDF renderer. - * @param outputProfileURI the URI to the output color profile - */ - public void setOutputProfileURI(String outputProfileURI) { - this.pdfUtil.setOutputProfileURI(outputProfileURI); - } - - /** - * Sets the filter map to be used by the PDF renderer. - * @param filterMap the filter map - */ - public void setFilterMap(Map filterMap) { - this.pdfUtil.setFilterMap(filterMap); - } - - /** - * Sets the encryption parameters used by the PDF renderer. - * @param encryptionParams the encryption parameters - */ - public void setEncryptionParams(PDFEncryptionParams encryptionParams) { - this.pdfUtil.setEncryptionParams(encryptionParams); - } - - MarkedContentInfo addCurrentImageToStructureTree() { - return logicalStructureHandler.addImageContentItem(imageReference); - } -} - diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java index f3511298e..9ebb1d5a1 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java +++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java @@ -51,22 +51,12 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator { } /** - * Configure the PDF renderer. - * Get the configuration to be used for pdf stream filters, - * fonts etc. + * Throws an UnsupportedOperationException. * - * @param renderer pdf renderer - * @throws FOPException fop exception + * @param renderer not used */ - public void configure(Renderer renderer) throws FOPException { - Configuration cfg = super.getRendererConfig(renderer); - if (cfg != null) { - PDFRenderer pdfRenderer = (PDFRenderer)renderer; - super.configure(renderer); - - PDFRenderingUtil pdfUtil = pdfRenderer.getPDFUtil(); - configure(cfg, pdfUtil); - } + public void configure(Renderer renderer) { + throw new UnsupportedOperationException(); } private void configure(Configuration cfg, PDFRenderingUtil pdfUtil) throws FOPException { @@ -80,20 +70,20 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator { LogUtil.handleException(log, e, false); } - String s = cfg.getChild(PDFRenderer.PDF_A_MODE, true).getValue(null); + String s = cfg.getChild(PDFConfigurationConstants.PDF_A_MODE, true).getValue(null); if (s != null) { pdfUtil.setAMode(PDFAMode.valueOf(s)); } - s = cfg.getChild(PDFRenderer.PDF_X_MODE, true).getValue(null); + s = cfg.getChild(PDFConfigurationConstants.PDF_X_MODE, true).getValue(null); if (s != null) { pdfUtil.setXMode(PDFXMode.valueOf(s)); } Configuration encryptionParamsConfig - = cfg.getChild(PDFRenderer.ENCRYPTION_PARAMS, false); + = cfg.getChild(PDFConfigurationConstants.ENCRYPTION_PARAMS, false); if (encryptionParamsConfig != null) { PDFEncryptionParams encryptionParams = new PDFEncryptionParams(); Configuration ownerPasswordConfig = encryptionParamsConfig.getChild( - PDFRenderer.OWNER_PASSWORD, false); + PDFConfigurationConstants.OWNER_PASSWORD, false); if (ownerPasswordConfig != null) { String ownerPassword = ownerPasswordConfig.getValue(null); if (ownerPassword != null) { @@ -101,7 +91,7 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator { } } Configuration userPasswordConfig = encryptionParamsConfig.getChild( - PDFRenderer.USER_PASSWORD, false); + PDFConfigurationConstants.USER_PASSWORD, false); if (userPasswordConfig != null) { String userPassword = userPasswordConfig.getValue(null); if (userPassword != null) { @@ -109,33 +99,33 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator { } } Configuration noPrintConfig = encryptionParamsConfig.getChild( - PDFRenderer.NO_PRINT, false); + PDFConfigurationConstants.NO_PRINT, false); if (noPrintConfig != null) { encryptionParams.setAllowPrint(false); } Configuration noCopyContentConfig = encryptionParamsConfig.getChild( - PDFRenderer.NO_COPY_CONTENT, false); + PDFConfigurationConstants.NO_COPY_CONTENT, false); if (noCopyContentConfig != null) { encryptionParams.setAllowCopyContent(false); } Configuration noEditContentConfig = encryptionParamsConfig.getChild( - PDFRenderer.NO_EDIT_CONTENT, false); + PDFConfigurationConstants.NO_EDIT_CONTENT, false); if (noEditContentConfig != null) { encryptionParams.setAllowEditContent(false); } Configuration noAnnotationsConfig = encryptionParamsConfig.getChild( - PDFRenderer.NO_ANNOTATIONS, false); + PDFConfigurationConstants.NO_ANNOTATIONS, false); if (noAnnotationsConfig != null) { encryptionParams.setAllowEditAnnotations(false); } pdfUtil.setEncryptionParams(encryptionParams); } - s = cfg.getChild(PDFRenderer.KEY_OUTPUT_PROFILE, true).getValue(null); + s = cfg.getChild(PDFConfigurationConstants.KEY_OUTPUT_PROFILE, true).getValue(null); if (s != null) { pdfUtil.setOutputProfileURI(s); } Configuration disableColorSpaceConfig = cfg.getChild( - PDFRenderer.KEY_DISABLE_SRGB_COLORSPACE, false); + PDFConfigurationConstants.KEY_DISABLE_SRGB_COLORSPACE, false); if (disableColorSpaceConfig != null) { pdfUtil.setDisableSRGBColorSpace( disableColorSpaceConfig.getValueAsBoolean(false)); diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java b/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java deleted file mode 100644 index fb65c9d74..000000000 --- a/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.render.AbstractRendererMaker; -import org.apache.fop.render.Renderer; -import org.apache.fop.render.RendererConfigurator; - -/** - * RendererMaker for the PDF Renderer. - */ -public class PDFRendererMaker extends AbstractRendererMaker { - - private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF}; - - /** {@inheritDoc} */ - public Renderer makeRenderer(FOUserAgent userAgent) { - return new PDFRenderer(); - } - - /** {@inheritDoc} */ - public RendererConfigurator getConfigurator(FOUserAgent userAgent) { - return new PDFRendererConfigurator(userAgent); - } - - /** {@inheritDoc} */ - public boolean needsOutputStream() { - return true; - } - - /** {@inheritDoc} */ - public String[] getSupportedMimeTypes() { - return MIMES; - } - -} diff --git a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java index 6b14566eb..434daa5b0 100644 --- a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java @@ -19,26 +19,14 @@ package org.apache.fop.render.pdf; -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.io.IOException; import java.io.OutputStream; import java.util.Map; -import org.w3c.dom.Document; - import org.apache.avalon.framework.configuration.Configuration; -import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.bridge.GVTBuilder; -import org.apache.batik.dom.svg.SVGDOMImplementation; -import org.apache.batik.gvt.GraphicsNode; -import org.apache.batik.util.SVGConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.FontInfo; -import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFPage; import org.apache.fop.pdf.PDFResourceContext; @@ -47,11 +35,6 @@ import org.apache.fop.render.ImageHandlerUtil; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; -import org.apache.fop.svg.PDFAElementBridge; -import org.apache.fop.svg.PDFBridgeContext; -import org.apache.fop.svg.PDFGraphics2D; -import org.apache.fop.svg.SVGEventProducer; -import org.apache.fop.svg.SVGUserAgent; /** * PDF XML handler for SVG (uses Apache Batik). @@ -126,148 +109,8 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler public boolean paintAsBitmap; // CSOK: VisibilityModifier } - /** - * {@inheritDoc} - */ - protected void renderSVGDocument(RendererContext context, - Document doc) { - PDFRenderer renderer = (PDFRenderer)context.getRenderer(); - PDFInfo pdfInfo = getPDFInfo(context); - if (pdfInfo.paintAsBitmap) { - try { - super.renderSVGDocument(context, doc); - } catch (IOException ioe) { - SVGEventProducer eventProducer = SVGEventProducer.Provider.get( - context.getUserAgent().getEventBroadcaster()); - eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc)); - } - return; - } - int xOffset = pdfInfo.currentXPosition; - int yOffset = pdfInfo.currentYPosition; - - FOUserAgent userAgent = context.getUserAgent(); - final float deviceResolution = userAgent.getTargetResolution(); - if (log.isDebugEnabled()) { - log.debug("Generating SVG at " + deviceResolution + "dpi."); - } - - final float uaResolution = userAgent.getSourceResolution(); - SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform()); - - //Scale for higher resolution on-the-fly images from Batik - double s = uaResolution / deviceResolution; - AffineTransform resolutionScaling = new AffineTransform(); - resolutionScaling.scale(s, s); - - //Controls whether text painted by Batik is generated using text or path operations - boolean strokeText = false; - Configuration cfg = pdfInfo.cfg; - if (cfg != null) { - strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText); - } - - BridgeContext ctx = new PDFBridgeContext(ua, - (strokeText ? null : pdfInfo.fi), - userAgent.getFactory().getImageManager(), - userAgent.getImageSessionContext(), - new AffineTransform()); - - //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) - //to it. - Document clonedDoc = BatikUtil.cloneSVGDocument(doc); - - GraphicsNode root; - try { - GVTBuilder builder = new GVTBuilder(); - root = builder.build(ctx, clonedDoc); - } catch (Exception e) { - SVGEventProducer eventProducer = SVGEventProducer.Provider.get( - context.getUserAgent().getEventBroadcaster()); - eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); - return; - } - // get the 'width' and 'height' attributes of the SVG document - float w = (float)ctx.getDocumentSize().getWidth() * 1000f; - float h = (float)ctx.getDocumentSize().getHeight() * 1000f; - - float sx = pdfInfo.width / w; - float sy = pdfInfo.height / h; - - //Scaling and translation for the bounding box of the image - AffineTransform scaling = new AffineTransform( - sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f); - - //Transformation matrix that establishes the local coordinate system for the SVG graphic - //in relation to the current coordinate system - AffineTransform imageTransform = new AffineTransform(); - imageTransform.concatenate(scaling); - imageTransform.concatenate(resolutionScaling); - - /* - * Clip to the svg area. - * Note: To have the svg overlay (under) a text area then use - * an fo:block-container - */ - PDFContentGenerator generator = renderer.getGenerator(); - generator.comment("SVG setup"); - generator.saveGraphicsState(); - generator.setColor(Color.black, false); - generator.setColor(Color.black, true); - - if (!scaling.isIdentity()) { - generator.comment("viewbox"); - generator.add(CTMHelper.toPDFString(scaling, false) + " cm\n"); - } - - //SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); - - if (pdfInfo.pdfContext == null) { - pdfInfo.pdfContext = pdfInfo.pdfPage; - } - PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fi, - pdfInfo.pdfDoc, - pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(), - pdfInfo.currentFontName, pdfInfo.currentFontSize); - graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); - - if (!resolutionScaling.isIdentity()) { - generator.comment("resolution scaling for " + uaResolution - + " -> " + deviceResolution + "\n"); - generator.add( - CTMHelper.toPDFString(resolutionScaling, false) + " cm\n"); - graphics.scale(1 / s, 1 / s); - } - - generator.comment("SVG start"); - - //Save state and update coordinate system for the SVG image - generator.getState().save(); - generator.getState().concatenate(imageTransform); - - //Now that we have the complete transformation matrix for the image, we can update the - //transformation matrix for the AElementBridge. - PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge( - SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG); - aBridge.getCurrentTransform().setTransform(generator.getState().getTransform()); - - graphics.setPaintingState(generator.getState()); - graphics.setOutputStream(pdfInfo.outputStream); - try { - root.paint(graphics); - generator.add(graphics.getString()); - } catch (Exception e) { - SVGEventProducer eventProducer = SVGEventProducer.Provider.get( - context.getUserAgent().getEventBroadcaster()); - eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); - } - generator.getState().restore(); - generator.restoreGraphicsState(); - generator.comment("SVG end"); - } - /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { - return (renderer instanceof PDFRenderer); + return false; } } diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java index 3858cc716..e13591ae3 100644 --- a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java @@ -30,12 +30,12 @@ import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; import org.apache.xmlgraphics.ps.PSGenerator; +import org.apache.fop.pdf.PDFFactory; import org.apache.fop.render.AbstractGraphics2DAdapter; import org.apache.fop.render.ImageHandlerUtil; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; import org.apache.fop.render.RendererContext.RendererContextWrapper; -import org.apache.fop.render.pdf.PDFRenderer; /** * Graphics2DAdapter implementation for PostScript. @@ -46,15 +46,7 @@ public class PSGraphics2DAdapter extends AbstractGraphics2DAdapter { private boolean clip = true; /** - * Main constructor - * @param renderer the Renderer instance to which this instance belongs - */ - public PSGraphics2DAdapter(PSRenderer renderer) { - this(renderer.gen, true); - } - - /** - * Constructor for use without a PSRenderer instance. + * Creates a new instance. * @param gen the PostScript generator * @param clip true if the image should be clipped */ @@ -114,7 +106,7 @@ public class PSGraphics2DAdapter extends AbstractGraphics2DAdapter { RendererContextWrapper ctx = RendererContext.wrapRendererContext(context); BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false); - float scale = PDFRenderer.NORMAL_PDF_RESOLUTION + float scale = PDFFactory.DEFAULT_PDF_RESOLUTION / context.getUserAgent().getTargetResolution(); graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null); } else { diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java deleted file mode 100644 index 0703912ce..000000000 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ /dev/null @@ -1,1290 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -// Java -import java.awt.Color; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.RenderedImage; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.transform.Source; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.image.loader.util.ImageUtil; -import org.apache.xmlgraphics.ps.DSCConstants; -import org.apache.xmlgraphics.ps.PSDictionary; -import org.apache.xmlgraphics.ps.PSDictionaryFormatException; -import org.apache.xmlgraphics.ps.PSGenerator; -import org.apache.xmlgraphics.ps.PSPageDeviceDictionary; -import org.apache.xmlgraphics.ps.PSProcSets; -import org.apache.xmlgraphics.ps.PSResource; -import org.apache.xmlgraphics.ps.PSState; -import org.apache.xmlgraphics.ps.dsc.DSCException; -import org.apache.xmlgraphics.ps.dsc.ResourceTracker; -import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox; -import org.apache.xmlgraphics.ps.dsc.events.DSCCommentHiResBoundingBox; - -import org.apache.fop.ResourceEventProducer; -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.area.Area; -import org.apache.fop.area.BlockViewport; -import org.apache.fop.area.CTM; -import org.apache.fop.area.OffDocumentExtensionAttachment; -import org.apache.fop.area.OffDocumentItem; -import org.apache.fop.area.PageViewport; -import org.apache.fop.area.RegionViewport; -import org.apache.fop.area.Trait; -import org.apache.fop.area.inline.AbstractTextArea; -import org.apache.fop.area.inline.Image; -import org.apache.fop.area.inline.InlineParent; -import org.apache.fop.area.inline.Leader; -import org.apache.fop.area.inline.SpaceArea; -import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.inline.WordArea; -import org.apache.fop.datatypes.URISpecification; -import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.LazyFont; -import org.apache.fop.fonts.SingleByteFont; -import org.apache.fop.fonts.Typeface; -import org.apache.fop.render.AbstractPathOrientedRenderer; -import org.apache.fop.render.Graphics2DAdapter; -import org.apache.fop.render.ImageAdapter; -import org.apache.fop.render.ImageHandler; -import org.apache.fop.render.ImageHandlerRegistry; -import org.apache.fop.render.RendererContext; -import org.apache.fop.render.RendererEventProducer; -import org.apache.fop.render.ps.extensions.PSCommentAfter; -import org.apache.fop.render.ps.extensions.PSCommentBefore; -import org.apache.fop.render.ps.extensions.PSExtensionAttachment; -import org.apache.fop.render.ps.extensions.PSSetPageDevice; -import org.apache.fop.render.ps.extensions.PSSetupCode; -import org.apache.fop.traits.RuleStyle; -import org.apache.fop.util.CharUtilities; - -/** - * Renderer that renders to PostScript. - *
- * This class currently generates PostScript Level 2 code. The only exception - * is the FlateEncode filter which is a Level 3 feature. The filters in use - * are hardcoded at the moment. - *
- * This class follows the Document Structuring Conventions (DSC) version 3.0. - * If anyone modifies this renderer please make - * sure to also follow the DSC to make it simpler to programmatically modify - * the generated Postscript files (ex. extract pages etc.). - *
- * This renderer inserts FOP-specific comments into the PostScript stream which - * may help certain users to do certain types of post-processing of the output. - * These comments all start with "%FOP". - * - * @author Apache FOP Development Team - * @version $Id$ - */ -public class PSRenderer extends AbstractPathOrientedRenderer - implements ImageAdapter, PSSupportedFlavors, PSConfigurationConstants { - - /** logging instance */ - private static Log log = LogFactory.getLog(PSRenderer.class); - - /** The MIME type for PostScript */ - public static final String MIME_TYPE = "application/postscript"; - - /** The application producing the PostScript */ - private int currentPageNumber = 0; - - /** the OutputStream the PS file is written to */ - private OutputStream outputStream; - /** the temporary file in case of two-pass processing */ - private File tempFile; - - /** The PostScript generator used to output the PostScript */ - protected PSGenerator gen; - private boolean ioTrouble = false; - - private boolean inTextMode = false; - - /** Used to temporarily store PSSetupCode instance until they can be written. */ - private List setupCodeList; - - /** This is a map of PSResource instances of all fonts defined (key: font key) */ - private Map fontResources; - /** This is a map of PSResource instances of all forms (key: uri) */ - private Map formResources; - - /** encapsulation of dictionary used in setpagedevice instruction **/ - private PSPageDeviceDictionary pageDeviceDictionary; - - /** - * Utility class which enables all sorts of features that are not directly connected to the - * normal rendering process. - */ - protected PSRenderingUtil psUtil; - private PSBorderPainter borderPainter; - - /** Is used to determine the document's bounding box */ - private Rectangle2D documentBoundingBox; - - /** This is a collection holding all document header comments */ - private Collection headerComments; - - /** This is a collection holding all document footer comments */ - private Collection footerComments; - - /** {@inheritDoc} */ - public void setUserAgent(FOUserAgent agent) { - super.setUserAgent(agent); - this.psUtil = new PSRenderingUtil(getUserAgent()); - } - - PSRenderingUtil getPSUtil() { - return this.psUtil; - } - - /** - * Sets the landscape mode for this renderer. - * @param value false will normally generate a "pseudo-portrait" page, true will rotate - * a "wider-than-long" page by 90 degrees. - */ - public void setAutoRotateLandscape(boolean value) { - getPSUtil().setAutoRotateLandscape(value); - } - - /** @return true if the renderer is configured to rotate landscape pages */ - public boolean isAutoRotateLandscape() { - return getPSUtil().isAutoRotateLandscape(); - } - - /** - * Sets the PostScript language level that the renderer should produce. - * @param level the language level (currently allowed: 2 or 3) - */ - public void setLanguageLevel(int level) { - getPSUtil().setLanguageLevel(level); - } - - /** - * Return the PostScript language level that the renderer produces. - * @return the language level - */ - public int getLanguageLevel() { - return getPSUtil().getLanguageLevel(); - } - - /** - * Sets the resource optimization mode. If set to true, the renderer does two passes to - * only embed the necessary resources in the PostScript file. This is slower, but produces - * smaller files. - * @param value true to enable the resource optimization - */ - public void setOptimizeResources(boolean value) { - getPSUtil().setOptimizeResources(value); - } - - /** @return true if the renderer does two passes to optimize PostScript resources */ - public boolean isOptimizeResources() { - return getPSUtil().isOptimizeResources(); - } - - /** {@inheritDoc} */ - public Graphics2DAdapter getGraphics2DAdapter() { - return new PSGraphics2DAdapter(this); - } - - /** {@inheritDoc} */ - public ImageAdapter getImageAdapter() { - return this; - } - - /** - * Write out a command - * @param cmd PostScript command - */ - protected void writeln(String cmd) { - try { - gen.writeln(cmd); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Central exception handler for I/O exceptions. - * @param ioe IOException to handle - */ - protected void handleIOTrouble(IOException ioe) { - if (!ioTrouble) { - RendererEventProducer eventProducer = RendererEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.ioError(this, ioe); - ioTrouble = true; - } - } - - /** - * Write out a comment - * @param comment Comment to write - */ - protected void comment(String comment) { - try { - if (comment.startsWith("%")) { - gen.commentln(comment); - writeln(comment); - } else { - gen.commentln("%" + comment); - } - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Make sure the cursor is in the right place. - */ - protected void movetoCurrPosition() { - moveTo(this.currentIPPosition, this.currentBPPosition); - } - - /** {@inheritDoc} */ - protected void clip() { - writeln("clip newpath"); - } - - /** {@inheritDoc} */ - protected void clipRect(float x, float y, float width, float height) { - try { - gen.defineRect(x, y, width, height); - clip(); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** {@inheritDoc} */ - protected void moveTo(float x, float y) { - writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " M"); - } - - /** - * Moves the current point by (x, y) relative to the current position, - * omitting any connecting line segment. - * @param x x coordinate - * @param y y coordinate - */ - protected void rmoveTo(float x, float y) { - writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " RM"); - } - - /** {@inheritDoc} */ - protected void lineTo(float x, float y) { - writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " lineto"); - } - - /** {@inheritDoc} */ - protected void closePath() { - writeln("cp"); - } - - /** {@inheritDoc} */ - protected void fillRect(float x, float y, float width, float height) { - if (width != 0 && height != 0) { - try { - gen.defineRect(x, y, width, height); - gen.writeln("fill"); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - } - - /** {@inheritDoc} */ - protected void updateColor(Color col, boolean fill) { - try { - useColor(col); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** {@inheritDoc} */ - protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { - endTextObject(); - int x = currentIPPosition + (int)Math.round(pos.getX()); - int y = currentBPPosition + (int)Math.round(pos.getY()); - uri = URISpecification.getURL(uri); - if (log.isDebugEnabled()) { - log.debug("Handling image: " + uri); - } - int width = (int)pos.getWidth(); - int height = (int)pos.getHeight(); - Rectangle targetRect = new Rectangle(x, y, width, height); - - ImageManager manager = getUserAgent().getFactory().getImageManager(); - ImageInfo info = null; - try { - ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); - info = manager.getImageInfo(uri, sessionContext); - - PSRenderingContext renderingContext = new PSRenderingContext( - getUserAgent(), gen, getFontInfo()); - - if (!isOptimizeResources() - || PSImageUtils.isImageInlined(info, renderingContext)) { - if (log.isDebugEnabled()) { - log.debug("Image " + info + " is inlined"); - } - - //Determine supported flavors - ImageFlavor[] flavors; - ImageHandlerRegistry imageHandlerRegistry - = userAgent.getFactory().getImageHandlerRegistry(); - flavors = imageHandlerRegistry.getSupportedFlavors(renderingContext); - - //Only now fully load/prepare the image - Map hints = ImageUtil.getDefaultHints(sessionContext); - org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, flavors, hints, sessionContext); - - //Get handler for image - ImageHandler basicHandler = imageHandlerRegistry.getHandler(renderingContext, img); - - //...and embed as inline image - basicHandler.handleImage(renderingContext, img, targetRect); - } else { - if (log.isDebugEnabled()) { - log.debug("Image " + info + " is embedded as a form later"); - } - //Don't load image at this time, just put a form placeholder in the stream - PSResource form = getFormForImage(info.getOriginalURI()); - PSImageUtils.drawForm(form, info, targetRect, gen); - } - - } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); - } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); - } - } - - /** - * Returns a PSResource instance representing a image as a PostScript form. - * @param uri the image URI - * @return a PSResource instance - */ - protected PSResource getFormForImage(String uri) { - if (uri == null || "".equals(uri)) { - throw new IllegalArgumentException("uri must not be empty or null"); - } - if (this.formResources == null) { - this.formResources = new java.util.HashMap(); - } - PSResource form = (PSResource)this.formResources.get(uri); - if (form == null) { - form = new PSImageFormResource(this.formResources.size() + 1, uri); - this.formResources.put(uri, form); - } - return form; - } - - /** {@inheritDoc} */ - public void paintImage(RenderedImage image, RendererContext context, - int x, int y, int width, int height) throws IOException { - float fx = x / 1000f; - x += currentIPPosition / 1000f; - float fy = y / 1000f; - y += currentBPPosition / 1000f; - float fw = width / 1000f; - float fh = height / 1000f; - PSImageUtils.renderBitmapImage(image, fx, fy, fw, fh, gen); - } - - /** - * Draw a line. - * - * @param startx the start x position - * @param starty the start y position - * @param endx the x end position - * @param endy the y end position - */ - private void drawLine(float startx, float starty, float endx, float endy) { - writeln(gen.formatDouble(startx) + " " - + gen.formatDouble(starty) + " M " - + gen.formatDouble(endx) + " " - + gen.formatDouble(endy) + " lineto stroke newpath"); - } - - /** Saves the graphics state of the rendering engine. */ - public void saveGraphicsState() { - endTextObject(); - try { - //delegate - gen.saveGraphicsState(); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** Restores the last graphics state of the rendering engine. */ - public void restoreGraphicsState() { - try { - endTextObject(); - //delegate - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Concats the transformation matrix. - * @param a A part - * @param b B part - * @param c C part - * @param d D part - * @param e E part - * @param f F part - */ - protected void concatMatrix(double a, double b, - double c, double d, - double e, double f) { - try { - gen.concatMatrix(a, b, c, d, e, f); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * Concats the transformations matrix. - * @param matrix Matrix to use - */ - protected void concatMatrix(double[] matrix) { - try { - gen.concatMatrix(matrix); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** {@inheritDoc} */ - protected void concatenateTransformationMatrix(AffineTransform at) { - try { - gen.concatMatrix(at); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - private String getPostScriptNameForFontKey(String key) { - int pos = key.indexOf('_'); - String postFix = null; - if (pos > 0) { - postFix = key.substring(pos); - key = key.substring(0, pos); - } - Map fonts = fontInfo.getFonts(); - Typeface tf = (Typeface)fonts.get(key); - if (tf instanceof LazyFont) { - tf = ((LazyFont)tf).getRealFont(); - } - if (tf == null) { - throw new IllegalStateException("Font not available: " + key); - } - if (postFix == null) { - return tf.getFontName(); - } else { - return tf.getFontName() + postFix; - } - } - - /** - * Returns the PSResource for the given font key. - * @param key the font key ("F*") - * @return the matching PSResource - */ - protected PSResource getPSResourceForFontKey(String key) { - PSResource res = null; - if (this.fontResources != null) { - res = (PSResource)this.fontResources.get(key); - } else { - this.fontResources = new java.util.HashMap(); - } - if (res == null) { - res = new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key)); - this.fontResources.put(key, res); - } - return res; - } - - /** - * Changes the currently used font. - * @param key key of the font ("F*") - * @param size font size - */ - protected void useFont(String key, int size) { - try { - PSResource res = getPSResourceForFontKey(key); - gen.useFont("/" + res.getName(), size / 1000f); - gen.getResourceTracker().notifyResourceUsageOnPage(res); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - private void useColor(Color col) throws IOException { - gen.useColor(col); - } - - /** {@inheritDoc} */ - protected void drawBackAndBorders(Area area, float startx, float starty, - float width, float height) { - if (area.hasTrait(Trait.BACKGROUND) - || area.hasTrait(Trait.BORDER_BEFORE) - || area.hasTrait(Trait.BORDER_AFTER) - || area.hasTrait(Trait.BORDER_START) - || area.hasTrait(Trait.BORDER_END)) { - comment("%FOPBeginBackgroundAndBorder: " - + startx + " " + starty + " " + width + " " + height); - super.drawBackAndBorders(area, startx, starty, width, height); - comment("%FOPEndBackgroundAndBorder"); - } - } - - /** {@inheritDoc} */ - protected void drawBorderLine // CSOK: ParameterNumber - (float x1, float y1, float x2, float y2, - boolean horz, boolean startOrBefore, int style, Color col) { - try { - PSBorderPainter.drawBorderLine(gen, x1, y1, x2, y2, horz, startOrBefore, style, col); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** {@inheritDoc} */ - public void startRenderer(OutputStream outputStream) - throws IOException { - log.debug("Rendering areas to PostScript..."); - - this.outputStream = outputStream; - OutputStream out; - if (isOptimizeResources()) { - this.tempFile = File.createTempFile("fop", null); - out = new java.io.FileOutputStream(this.tempFile); - out = new java.io.BufferedOutputStream(out); - } else { - out = this.outputStream; - } - - //Setup for PostScript generation - this.gen = new PSGenerator(out) { - /** Need to subclass PSGenerator to have better URI resolution */ - public Source resolveURI(String uri) { - return userAgent.resolveURI(uri); - } - }; - this.gen.setPSLevel(getLanguageLevel()); - this.borderPainter = new PSBorderPainter(this.gen); - this.currentPageNumber = 0; - - //Initial default page device dictionary settings - this.pageDeviceDictionary = new PSPageDeviceDictionary(); - pageDeviceDictionary.setFlushOnRetrieval(!getPSUtil().isDSCComplianceEnabled()); - pageDeviceDictionary.put("/ImagingBBox", "null"); - } - - private void writeHeader() throws IOException { - //PostScript Header - writeln(DSCConstants.PS_ADOBE_30); - gen.writeDSCComment(DSCConstants.CREATOR, new String[] {userAgent.getProducer()}); - gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new java.util.Date()}); - gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new Integer(gen.getPSLevel())); - gen.writeDSCComment(DSCConstants.PAGES, new Object[] {DSCConstants.ATEND}); - gen.writeDSCComment(DSCConstants.BBOX, DSCConstants.ATEND); - gen.writeDSCComment(DSCConstants.HIRES_BBOX, DSCConstants.ATEND); - this.documentBoundingBox = new Rectangle2D.Double(); - gen.writeDSCComment(DSCConstants.DOCUMENT_SUPPLIED_RESOURCES, - new Object[] {DSCConstants.ATEND}); - if (headerComments != null) { - for (Iterator iter = headerComments.iterator(); iter.hasNext();) { - PSExtensionAttachment comment = (PSExtensionAttachment)iter.next(); - gen.writeln("%" + comment.getContent()); - } - } - gen.writeDSCComment(DSCConstants.END_COMMENTS); - - //Defaults - gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS); - gen.writeDSCComment(DSCConstants.END_DEFAULTS); - - //Prolog and Setup written right before the first page-sequence, see startPageSequence() - //Do this only once, as soon as we have all the content for the Setup section! - //Prolog - gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); - PSProcSets.writeStdProcSet(gen); - PSProcSets.writeEPSProcSet(gen); - gen.writeDSCComment(DSCConstants.END_PROLOG); - - //Setup - gen.writeDSCComment(DSCConstants.BEGIN_SETUP); - PSRenderingUtil.writeSetupCodeList(gen, setupCodeList, "SetupCode"); - if (!isOptimizeResources()) { - this.fontResources = PSFontUtils.writeFontDict(gen, fontInfo); - } else { - gen.commentln("%FOPFontSetup"); //Place-holder, will be replaced in the second pass - } - gen.writeDSCComment(DSCConstants.END_SETUP); - } - - /** {@inheritDoc} */ - public void stopRenderer() throws IOException { - //Write trailer - gen.writeDSCComment(DSCConstants.TRAILER); - if (footerComments != null) { - for (Iterator iter = footerComments.iterator(); iter.hasNext();) { - PSExtensionAttachment comment = (PSExtensionAttachment)iter.next(); - gen.commentln("%" + comment.getContent()); - } - footerComments.clear(); - } - gen.writeDSCComment(DSCConstants.PAGES, new Integer(this.currentPageNumber)); - new DSCCommentBoundingBox(this.documentBoundingBox).generate(gen); - new DSCCommentHiResBoundingBox(this.documentBoundingBox).generate(gen); - gen.getResourceTracker().writeResources(false, gen); - gen.writeDSCComment(DSCConstants.EOF); - gen.flush(); - log.debug("Rendering to PostScript complete."); - if (isOptimizeResources()) { - IOUtils.closeQuietly(gen.getOutputStream()); - rewritePostScriptFile(); - } - if (footerComments != null) { - headerComments.clear(); - } - if (pageDeviceDictionary != null) { - pageDeviceDictionary.clear(); - } - this.borderPainter = null; - this.gen = null; - } - - /** - * Used for two-pass production. This will rewrite the PostScript file from the temporary - * file while adding all needed resources. - * @throws IOException In case of an I/O error. - */ - private void rewritePostScriptFile() throws IOException { - log.debug("Processing PostScript resources..."); - long startTime = System.currentTimeMillis(); - ResourceTracker resTracker = gen.getResourceTracker(); - InputStream in = new java.io.FileInputStream(this.tempFile); - in = new java.io.BufferedInputStream(in); - try { - try { - ResourceHandler handler = new ResourceHandler(this.userAgent, this.fontInfo, - resTracker, this.formResources); - handler.process(in, this.outputStream, - this.currentPageNumber, this.documentBoundingBox); - this.outputStream.flush(); - } catch (DSCException e) { - throw new RuntimeException(e.getMessage()); - } - } finally { - IOUtils.closeQuietly(in); - if (!this.tempFile.delete()) { - this.tempFile.deleteOnExit(); - log.warn("Could not delete temporary file: " + this.tempFile); - } - } - if (log.isDebugEnabled()) { - long duration = System.currentTimeMillis() - startTime; - log.debug("Resource Processing complete in " + duration + " ms."); - } - } - - /** {@inheritDoc} */ - public void processOffDocumentItem(OffDocumentItem oDI) { - if (log.isDebugEnabled()) { - log.debug("Handling OffDocumentItem: " + oDI.getName()); - } - if (oDI instanceof OffDocumentExtensionAttachment) { - ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment(); - if (attachment != null) { - if (PSExtensionAttachment.CATEGORY.equals(attachment.getCategory())) { - if (attachment instanceof PSSetupCode) { - if (setupCodeList == null) { - setupCodeList = new java.util.ArrayList(); - } - if (!setupCodeList.contains(attachment)) { - setupCodeList.add(attachment); - } - } else if (attachment instanceof PSSetPageDevice) { - /** - * Extract all PSSetPageDevice instances from the - * attachment list on the s-p-m and add all dictionary - * entries to our internal representation of the the - * page device dictionary. - */ - PSSetPageDevice setPageDevice = (PSSetPageDevice)attachment; - String content = setPageDevice.getContent(); - if (content != null) { - try { - this.pageDeviceDictionary.putAll(PSDictionary.valueOf(content)); - } catch (PSDictionaryFormatException e) { - PSEventProducer eventProducer = PSEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.postscriptDictionaryParseError(this, content, e); - } - } - } else if (attachment instanceof PSCommentBefore) { - if (headerComments == null) { - headerComments = new java.util.ArrayList(); - } - headerComments.add(attachment); - } else if (attachment instanceof PSCommentAfter) { - if (footerComments == null) { - footerComments = new java.util.ArrayList(); - } - footerComments.add(attachment); - } - } - } - } - super.processOffDocumentItem(oDI); - } - - /** {@inheritDoc} */ - public void renderPage(PageViewport page) - throws IOException, FOPException { - log.debug("renderPage(): " + page); - - if (this.currentPageNumber == 0) { - writeHeader(); - } - - this.currentPageNumber++; - - gen.getResourceTracker().notifyStartNewPage(); - gen.getResourceTracker().notifyResourceUsageOnPage(PSProcSets.STD_PROCSET); - gen.writeDSCComment(DSCConstants.PAGE, new Object[] - {page.getPageNumberString(), - new Integer(this.currentPageNumber)}); - - double pageWidth = page.getViewArea().width / 1000f; - double pageHeight = page.getViewArea().height / 1000f; - boolean rotate = false; - List pageSizes = new java.util.ArrayList(); - if (getPSUtil().isAutoRotateLandscape() && (pageHeight < pageWidth)) { - rotate = true; - pageSizes.add(new Long(Math.round(pageHeight))); - pageSizes.add(new Long(Math.round(pageWidth))); - } else { - pageSizes.add(new Long(Math.round(pageWidth))); - pageSizes.add(new Long(Math.round(pageHeight))); - } - pageDeviceDictionary.put("/PageSize", pageSizes); - - if (page.hasExtensionAttachments()) { - for (Iterator iter = page.getExtensionAttachments().iterator(); - iter.hasNext();) { - ExtensionAttachment attachment = (ExtensionAttachment) iter.next(); - if (attachment instanceof PSSetPageDevice) { - /** - * Extract all PSSetPageDevice instances from the - * attachment list on the s-p-m and add all - * dictionary entries to our internal representation - * of the the page device dictionary. - */ - PSSetPageDevice setPageDevice = (PSSetPageDevice)attachment; - String content = setPageDevice.getContent(); - if (content != null) { - try { - pageDeviceDictionary.putAll(PSDictionary.valueOf(content)); - } catch (PSDictionaryFormatException e) { - PSEventProducer eventProducer = PSEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.postscriptDictionaryParseError(this, content, e); - } - } - } - } - } - - try { - if (setupCodeList != null) { - PSRenderingUtil.writeEnclosedExtensionAttachments(gen, setupCodeList); - setupCodeList.clear(); - } - } catch (IOException e) { - log.error(e.getMessage()); - } - final Integer zero = new Integer(0); - Rectangle2D pageBoundingBox = new Rectangle2D.Double(); - if (rotate) { - pageBoundingBox.setRect(0, 0, pageHeight, pageWidth); - gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] { - zero, zero, new Long(Math.round(pageHeight)), - new Long(Math.round(pageWidth)) }); - gen.writeDSCComment(DSCConstants.PAGE_HIRES_BBOX, new Object[] { - zero, zero, new Double(pageHeight), - new Double(pageWidth) }); - gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Landscape"); - } else { - pageBoundingBox.setRect(0, 0, pageWidth, pageHeight); - gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] { - zero, zero, new Long(Math.round(pageWidth)), - new Long(Math.round(pageHeight)) }); - gen.writeDSCComment(DSCConstants.PAGE_HIRES_BBOX, new Object[] { - zero, zero, new Double(pageWidth), - new Double(pageHeight) }); - if (getPSUtil().isAutoRotateLandscape()) { - gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, - "Portrait"); - } - } - this.documentBoundingBox.add(pageBoundingBox); - gen.writeDSCComment(DSCConstants.PAGE_RESOURCES, - new Object[] {DSCConstants.ATEND}); - - gen.commentln("%FOPSimplePageMaster: " + page.getSimplePageMasterName()); - - gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); - - if (page.hasExtensionAttachments()) { - List extensionAttachments = page.getExtensionAttachments(); - for (int i = 0; i < extensionAttachments.size(); i++) { - Object attObj = extensionAttachments.get(i); - if (attObj instanceof PSExtensionAttachment) { - PSExtensionAttachment attachment = (PSExtensionAttachment)attObj; - if (attachment instanceof PSCommentBefore) { - gen.commentln("%" + attachment.getContent()); - } else if (attachment instanceof PSSetupCode) { - gen.writeln(attachment.getContent()); - } - } - } - } - - // Write any unwritten changes to page device dictionary - if (!pageDeviceDictionary.isEmpty()) { - String content = pageDeviceDictionary.getContent(); - if (getPSUtil().isSafeSetPageDevice()) { - content += " SSPD"; - } else { - content += " setpagedevice"; - } - PSRenderingUtil.writeEnclosedExtensionAttachment(gen, new PSSetPageDevice(content)); - } - - if (rotate) { - gen.writeln(Math.round(pageHeight) + " 0 translate"); - gen.writeln("90 rotate"); - } - concatMatrix(1, 0, 0, -1, 0, pageHeight); - - gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); - - //Process page - super.renderPage(page); - - //Show page - gen.showPage(); - gen.writeDSCComment(DSCConstants.PAGE_TRAILER); - if (page.hasExtensionAttachments()) { - List extensionAttachments = page.getExtensionAttachments(); - for (int i = 0; i < extensionAttachments.size(); i++) { - Object attObj = extensionAttachments.get(i); - if (attObj instanceof PSExtensionAttachment) { - PSExtensionAttachment attachment = (PSExtensionAttachment)attObj; - if (attachment instanceof PSCommentAfter) { - gen.commentln("%" + attachment.getContent()); - } - } - } - } - gen.getResourceTracker().writeResources(true, gen); - } - - /** {@inheritDoc} */ - protected void renderRegionViewport(RegionViewport port) { - if (port != null) { - comment("%FOPBeginRegionViewport: " + port.getRegionReference().getRegionName()); - super.renderRegionViewport(port); - comment("%FOPEndRegionViewport"); - } - } - - /** Indicates the beginning of a text object. */ - protected void beginTextObject() { - if (!inTextMode) { - saveGraphicsState(); - writeln("BT"); - inTextMode = true; - } - } - - /** Indicates the end of a text object. */ - protected void endTextObject() { - if (inTextMode) { - inTextMode = false; //set before restoreGraphicsState() to avoid recursion - writeln("ET"); - restoreGraphicsState(); - } - } - - /** {@inheritDoc} */ - public void renderText(TextArea area) { - renderInlineAreaBackAndBorders(area); - String fontkey = getInternalFontNameForArea(area); - int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE); - - // This assumes that *all* CIDFonts use a /ToUnicode mapping - Typeface tf = (Typeface) fontInfo.getFonts().get(fontkey); - - //Determine position - int rx = currentIPPosition + area.getBorderAndPaddingWidthStart(); - int bl = currentBPPosition + area.getOffset() + area.getBaselineOffset(); - - Color ct = (Color)area.getTrait(Trait.COLOR); - if (ct != null) { - try { - useColor(ct); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - beginTextObject(); - writeln("1 0 0 -1 " + gen.formatDouble(rx / 1000f) - + " " + gen.formatDouble(bl / 1000f) + " Tm"); - - super.renderText(area); //Updates IPD - - renderTextDecoration(tf, fontsize, area, bl, rx); - } - - /** {@inheritDoc} */ - protected void renderWord(WordArea word) { - renderText((TextArea)word.getParentArea(), word.getWord(), word.getLetterAdjustArray()); - super.renderWord(word); - } - - /** {@inheritDoc} */ - protected void renderSpace(SpaceArea space) { - AbstractTextArea textArea = (AbstractTextArea)space.getParentArea(); - String s = space.getSpace(); - char sp = s.charAt(0); - Font font = getFontFromArea(textArea); - - int tws = (space.isAdjustable() - ? ((TextArea) space.getParentArea()).getTextWordSpaceAdjust() - + 2 * textArea.getTextLetterSpaceAdjust() - : 0); - - rmoveTo((font.getCharWidth(sp) + tws) / 1000f, 0); - super.renderSpace(space); - } - - private Typeface getTypeface(String fontName) { - Typeface tf = (Typeface)fontInfo.getFonts().get(fontName); - if (tf instanceof LazyFont) { - tf = ((LazyFont)tf).getRealFont(); - } - return tf; - } - - private void renderText(AbstractTextArea area, String text, int[] letterAdjust) { - String fontkey = getInternalFontNameForArea(area); - int fontSize = area.getTraitAsInteger(Trait.FONT_SIZE); - Font font = getFontFromArea(area); - Typeface tf = getTypeface(font.getFontName()); - SingleByteFont singleByteFont = null; - if (tf instanceof SingleByteFont) { - singleByteFont = (SingleByteFont)tf; - } - - int textLen = text.length(); - if (singleByteFont != null && singleByteFont.hasAdditionalEncodings()) { - int start = 0; - int currentEncoding = -1; - for (int i = 0; i < textLen; i++) { - char c = text.charAt(i); - char mapped = tf.mapChar(c); - int encoding = mapped / 256; - if (currentEncoding != encoding) { - if (i > 0) { - writeText(area, text, start, i - start, letterAdjust, fontSize, tf); - } - if (encoding == 0) { - useFont(fontkey, fontSize); - } else { - useFont(fontkey + "_" + Integer.toString(encoding), fontSize); - } - currentEncoding = encoding; - start = i; - } - } - writeText(area, text, start, textLen - start, letterAdjust, fontSize, tf); - } else { - useFont(fontkey, fontSize); - writeText(area, text, 0, textLen, letterAdjust, fontSize, tf); - } - } - - private void writeText(AbstractTextArea area, String text, int start, int len, - int[] letterAdjust, int fontsize, Typeface tf) { - int end = start + len; - int initialSize = text.length(); - initialSize += initialSize / 2; - StringBuffer sb = new StringBuffer(initialSize); - if (letterAdjust == null - && area.getTextLetterSpaceAdjust() == 0 - && area.getTextWordSpaceAdjust() == 0) { - sb.append("("); - for (int i = start; i < end; i++) { - final char c = text.charAt(i); - final char mapped = (char)(tf.mapChar(c) % 256); - PSGenerator.escapeChar(mapped, sb); - } - sb.append(") t"); - } else { - sb.append("("); - int[] offsets = new int[len]; - for (int i = start; i < end; i++) { - final char c = text.charAt(i); - final char mapped = tf.mapChar(c); - char codepoint = (char)(mapped % 256); - int wordSpace; - - if (CharUtilities.isAdjustableSpace(mapped)) { - wordSpace = area.getTextWordSpaceAdjust(); - } else { - wordSpace = 0; - } - int cw = tf.getWidth(mapped, fontsize) / 1000; - int ladj = (letterAdjust != null && i < end - 1 ? letterAdjust[i + 1] : 0); - int tls = (i < end - 1 ? area.getTextLetterSpaceAdjust() : 0); - offsets[i - start] = cw + ladj + tls + wordSpace; - PSGenerator.escapeChar(codepoint, sb); - } - sb.append(")" + PSGenerator.LF + "["); - for (int i = 0; i < len; i++) { - if (i > 0) { - if (i % 8 == 0) { - sb.append(PSGenerator.LF); - } else { - sb.append(" "); - } - } - sb.append(gen.formatDouble(offsets[i] / 1000f)); - } - sb.append("]" + PSGenerator.LF + "xshow"); - } - writeln(sb.toString()); - } - - /** {@inheritDoc} */ - protected List breakOutOfStateStack() { - try { - List breakOutList = new java.util.ArrayList(); - PSState state; - while (true) { - if (breakOutList.size() == 0) { - endTextObject(); - comment("------ break out!"); - } - state = gen.getCurrentState(); - if (!gen.restoreGraphicsState()) { - break; - } - breakOutList.add(0, state); //Insert because of stack-popping - } - return breakOutList; - } catch (IOException ioe) { - handleIOTrouble(ioe); - return null; - } - } - - /** {@inheritDoc} */ - protected void restoreStateStackAfterBreakOut(List breakOutList) { - try { - comment("------ restoring context after break-out..."); - PSState state; - Iterator i = breakOutList.iterator(); - while (i.hasNext()) { - state = (PSState)i.next(); - saveGraphicsState(); - state.reestablish(gen); - } - comment("------ done."); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - } - - /** - * {@inheritDoc} - */ - protected void startVParea(CTM ctm, Rectangle2D clippingRect) { - saveGraphicsState(); - if (clippingRect != null) { - clipRect((float)clippingRect.getX() / 1000f, - (float)clippingRect.getY() / 1000f, - (float)clippingRect.getWidth() / 1000f, - (float)clippingRect.getHeight() / 1000f); - } - // multiply with current CTM - final double[] matrix = ctm.toArray(); - matrix[4] /= 1000f; - matrix[5] /= 1000f; - concatMatrix(matrix); - } - - /** - * {@inheritDoc} - */ - protected void endVParea() { - restoreGraphicsState(); - } - - /** {@inheritDoc} */ - protected void renderBlockViewport(BlockViewport bv, List children) { - comment("%FOPBeginBlockViewport: " + bv.toString()); - super.renderBlockViewport(bv, children); - comment("%FOPEndBlockViewport"); - } - - /** {@inheritDoc} */ - protected void renderInlineParent(InlineParent ip) { - super.renderInlineParent(ip); - } - - /** {@inheritDoc} */ - public void renderLeader(Leader area) { - renderInlineAreaBackAndBorders(area); - - int style = area.getRuleStyle(); - int ruleThickness = area.getRuleThickness(); - int startx = currentIPPosition + area.getBorderAndPaddingWidthStart(); - int starty = currentBPPosition + area.getOffset() + (ruleThickness / 2); - int endx = currentIPPosition - + area.getBorderAndPaddingWidthStart() - + area.getIPD(); - Color col = (Color)area.getTrait(Trait.COLOR); - - endTextObject(); - try { - borderPainter.drawLine(new Point(startx, starty), new Point(endx, starty), - ruleThickness, col, RuleStyle.valueOf(style)); - } catch (IOException ioe) { - handleIOTrouble(ioe); - } - - super.renderLeader(area); - } - - /** - * {@inheritDoc} - */ - public void renderImage(Image image, Rectangle2D pos) { - drawImage(image.getURL(), pos, image.getForeignAttributes()); - } - - /** - * {@inheritDoc} - */ - protected RendererContext createRendererContext(int x, int y, int width, int height, - Map foreignAttributes) { - RendererContext context = super.createRendererContext( - x, y, width, height, foreignAttributes); - context.setProperty(PSRendererContextConstants.PS_GENERATOR, this.gen); - context.setProperty(PSRendererContextConstants.PS_FONT_INFO, fontInfo); - return context; - } - - /** {@inheritDoc} */ - public String getMimeType() { - return MIME_TYPE; - } - - /** - * Sets whether or not the safe set page device macro should be used - * (as opposed to directly invoking setpagedevice) when setting the - * postscript page device. - * - * This option is a useful option when you want to guard against the possibility - * of invalid/unsupported postscript key/values being placed in the page device. - * - * @param safeSetPageDevice setting to false and the renderer will make a - * standard "setpagedevice" call, setting to true will make a safe set page - * device macro call (default is false). - */ - public void setSafeSetPageDevice(boolean safeSetPageDevice) { - getPSUtil().setSafeSetPageDevice(safeSetPageDevice); - } - - /** - * Sets whether or not PostScript Document Structuring Conventions (dsc) compliance are - * enforced. - *

- * It can cause problems (unwanted PostScript subsystem initgraphics/erasepage calls) - * on some printers when the pagedevice is set. If this causes problems on a - * particular implementation then use this setting with a 'false' value to try and - * minimize the number of setpagedevice calls in the postscript document output. - *

- * Set this value to false if you experience unwanted blank pages in your - * postscript output. - * @param dscCompliant boolean value (default is true) - */ - public void setDSCCompliant(boolean dscCompliant) { - getPSUtil().setDSCComplianceEnabled(dscCompliant); - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java index 0f880a928..2280bf0dc 100644 --- a/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java +++ b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java @@ -45,18 +45,12 @@ public class PSRendererConfigurator extends PrintRendererConfigurator } /** - * Configure the PS renderer. - * @param renderer postscript renderer - * @throws FOPException fop exception + * Throws an UnsupportedOperationException. + * + * @param renderer not used */ - public void configure(Renderer renderer) throws FOPException { - Configuration cfg = super.getRendererConfig(renderer); - if (cfg != null) { - super.configure(renderer); - - PSRenderer psRenderer = (PSRenderer)renderer; - configure(psRenderer.getPSUtil(), cfg); - } + public void configure(Renderer renderer) { + throw new UnsupportedOperationException(); } private void configure(PSRenderingUtil psUtil, Configuration cfg) { diff --git a/src/java/org/apache/fop/render/ps/PSRendererMaker.java b/src/java/org/apache/fop/render/ps/PSRendererMaker.java deleted file mode 100644 index 8c64f2806..000000000 --- a/src/java/org/apache/fop/render/ps/PSRendererMaker.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.render.AbstractRendererMaker; -import org.apache.fop.render.Renderer; -import org.apache.fop.render.RendererConfigurator; - -/** - * RendererMaker for the PostScript Renderer. - */ -public class PSRendererMaker extends AbstractRendererMaker { - - private static final String[] MIMES = new String[] {MimeConstants.MIME_POSTSCRIPT}; - - /** {@inheritDoc} */ - public Renderer makeRenderer(FOUserAgent userAgent) { - return new PSRenderer(); - } - - /** {@inheritDoc} */ - public RendererConfigurator getConfigurator(FOUserAgent userAgent) { - return new PSRendererConfigurator(userAgent); - } - - /** {@inheritDoc} */ - public boolean needsOutputStream() { - return true; - } - - /** {@inheritDoc} */ - public String[] getSupportedMimeTypes() { - return MIMES; - } -} diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index 66b26fb33..14e2beddd 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -333,7 +333,7 @@ public class PSSVGHandler extends AbstractGenericSVGHandler /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { - return (renderer instanceof PSRenderer); + return false; } } diff --git a/status.xml b/status.xml index ae322a0d2..1f0916753 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Removed old Renderer implementations for those output formats that have a version based on + the new DocumentHandler architecture available (AFP, PCL, PDF, PS). + Reinstated support for being able to specify a font cache filepath in the fop user configuration. diff --git a/test/java/org/apache/fop/StandardTestSuite.java b/test/java/org/apache/fop/StandardTestSuite.java index 281301789..caf75b4b4 100644 --- a/test/java/org/apache/fop/StandardTestSuite.java +++ b/test/java/org/apache/fop/StandardTestSuite.java @@ -23,7 +23,6 @@ import junit.framework.Test; import junit.framework.TestSuite; import org.apache.fop.fonts.DejaVuLGCSerifTest; -import org.apache.fop.fonts.TrueTypeAnsiTestCase; import org.apache.fop.image.loader.batik.ImageLoaderTestCase; import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; import org.apache.fop.intermediate.IFMimickingTestCase; @@ -54,7 +53,6 @@ public class StandardTestSuite { suite.addTest(new TestSuite(PDFEncodingTestCase.class)); suite.addTest(new TestSuite(PDFCMapTestCase.class)); suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class)); - suite.addTest(new TestSuite(TrueTypeAnsiTestCase.class)); suite.addTest(new TestSuite(DejaVuLGCSerifTest.class)); suite.addTest(RichTextFormatTestSuite.suite()); suite.addTest(new TestSuite(ImageLoaderTestCase.class)); diff --git a/test/java/org/apache/fop/fonts/TrueTypeAnsiTestCase.java b/test/java/org/apache/fop/fonts/TrueTypeAnsiTestCase.java deleted file mode 100644 index 3f98c93f4..000000000 --- a/test/java/org/apache/fop/fonts/TrueTypeAnsiTestCase.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - */ - -/* $Id$ */ - -package org.apache.fop.fonts; - -import java.io.File; -import java.io.OutputStream; -import java.io.StringReader; -import java.net.URL; -import java.util.List; - -import javax.xml.transform.Result; -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 junit.framework.TestCase; - -import org.apache.commons.io.output.NullOutputStream; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.fonts.apps.TTFReader; -import org.apache.fop.render.pdf.PDFRenderer; - -/** - * Tests XML font metrics file generation and usage for WinAnsi mode. - */ -public class TrueTypeAnsiTestCase extends TestCase { - - /** - * Tests a TrueType font in WinAnsi mode. - * @throws Exception if an error occurs - */ - public void testTrueTypeAnsi() throws Exception { - String fontFamily = "Gladiator Bold"; - File ttfFile = new File("./test/resources/fonts/glb12.ttf"); - File workDir = new File("./build/test-results"); - if (!workDir.isDirectory()) { - assertTrue(workDir.mkdirs()); - } - File metricsFile = new File(workDir, ttfFile.getName() + ".xml"); - if (metricsFile.isFile()) { - assertTrue(metricsFile.delete()); - } - - String[] args = new String[] {"-enc", "ansi", - ttfFile.getCanonicalPath(), metricsFile.getCanonicalPath()}; - TTFReader.main(args); - assertTrue(metricsFile.isFile()); - - FopFactory fopFactory = FopFactory.newInstance(); - FOUserAgent ua = fopFactory.newFOUserAgent(); - PDFRenderer renderer = new PDFRenderer(); - renderer.setUserAgent(ua); - List fontList = new java.util.ArrayList(); - List triplets = new java.util.ArrayList(); - triplets.add(new FontTriplet(fontFamily, "normal", Font.WEIGHT_NORMAL)); - EmbedFontInfo font = new EmbedFontInfo( - metricsFile.toURI().toASCIIString(), - true, triplets, - ttfFile.toURI().toASCIIString(), null); - fontList.add(font); - renderer.addFontList(fontList); - - ua.setRendererOverride(renderer); - OutputStream out = new NullOutputStream(); - - Fop fop = fopFactory.newFop(null, ua, out); - - TransformerFactory tFactory = TransformerFactory.newInstance(); - Source src = new StreamSource(new StringReader( - "Test!")); - Result res = new SAXResult(fop.getDefaultHandler()); - Transformer transformer = tFactory.newTransformer( - getSourceForResource(this, "fonttest.xsl")); - transformer.transform(src, res); - } - - private static Source getSourceForResource(Object reference, String name) { - URL url = reference.getClass().getResource(name); - if (url == null) { - throw new NullPointerException("Resource not found: " + name); - } - return new StreamSource(url.toExternalForm()); - } - -} diff --git a/test/java/org/apache/fop/fonts/fonttest.xsl b/test/java/org/apache/fop/fonts/fonttest.xsl deleted file mode 100644 index 26c7d72a5..000000000 --- a/test/java/org/apache/fop/fonts/fonttest.xsl +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/java/org/apache/fop/render/RendererFactoryTest.java b/test/java/org/apache/fop/render/RendererFactoryTest.java index 4a40ac7c1..6b8e8f5f3 100644 --- a/test/java/org/apache/fop/render/RendererFactoryTest.java +++ b/test/java/org/apache/fop/render/RendererFactoryTest.java @@ -33,7 +33,6 @@ import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.intermediate.IFRenderer; import org.apache.fop.render.pdf.PDFDocumentHandler; -import org.apache.fop.render.pdf.PDFRenderer; import org.apache.fop.render.rtf.RTFHandler; /** @@ -73,29 +72,15 @@ public class RendererFactoryTest extends TestCase { RendererFactory factory = fopFactory.getRendererFactory(); FOUserAgent ua; Renderer renderer; - Renderer overrideRenderer; ua = fopFactory.newFOUserAgent(); renderer = factory.createRenderer(ua, MimeConstants.MIME_PDF); assertTrue(renderer instanceof IFRenderer); - factory.setRendererPreferred(true); //Test legacy setting - ua = fopFactory.newFOUserAgent(); - renderer = factory.createRenderer(ua, MimeConstants.MIME_PDF); - assertTrue(renderer instanceof PDFRenderer); - ua = fopFactory.newFOUserAgent(); renderer = factory.createRenderer(ua, MimeConstants.MIME_FOP_IF); assertTrue(renderer instanceof IFRenderer); - factory.setRendererPreferred(false); - ua = fopFactory.newFOUserAgent(); - overrideRenderer = new PDFRenderer(); - overrideRenderer.setUserAgent(ua); - ua.setRendererOverride(overrideRenderer); - renderer = factory.createRenderer(ua, null); - assertTrue(renderer == overrideRenderer); - ua = fopFactory.newFOUserAgent(); IFDocumentHandler overrideHandler; overrideHandler = new PDFDocumentHandler(); diff --git a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java index 7f0462a75..72c677a0c 100644 --- a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java +++ b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java @@ -43,52 +43,22 @@ import org.apache.fop.render.intermediate.IFContext; public class ImageHandlingTestCase extends AbstractPostScriptTestCase { /** - * Tests JPEG handling with the {@link PSRenderer}. + * Tests JPEG handling. * @throws Exception if an error occurs */ - public void testJPEGImageWithRendererLevel3() throws Exception { - innerTestJPEGImageWithRenderer(3); + public void testJPEGImageLevel3() throws Exception { + innerTestJPEGImage(3); } /** - * Tests JPEG handling with the {@link PSRenderer}. + * Tests JPEG handling. * @throws Exception if an error occurs */ - public void testJPEGImageWithRendererLevel2() throws Exception { - innerTestJPEGImageWithRenderer(2); + public void testJPEGImageLevel2() throws Exception { + innerTestJPEGImage(2); } - /** - * Tests JPEG handling with the {@link PSDocumentHandler}. - * @throws Exception if an error occurs - */ - public void testJPEGImageWithIFLevel3() throws Exception { - innerTestJPEGImageWithIF(3); - } - - /** - * Tests JPEG handling with the {@link PSDocumentHandler}. - * @throws Exception if an error occurs - */ - public void testJPEGImageWithIFLevel2() throws Exception { - innerTestJPEGImageWithIF(2); - } - - private void innerTestJPEGImageWithRenderer(int level) throws Exception { - FOUserAgent ua = fopFactory.newFOUserAgent(); - PSRenderer renderer = new PSRenderer(); - renderer.setUserAgent(ua); - PSRenderingUtil psUtil = renderer.getPSUtil(); - psUtil.setLanguageLevel(level); - psUtil.setOptimizeResources(true); - ua.setRendererOverride(renderer); - - // Prepare output file - File outputFile = renderFile(ua, "ps-jpeg-image.fo", "-rend-l" + psUtil.getLanguageLevel()); - verifyPostScriptFile(outputFile, psUtil.getLanguageLevel()); - } - - private void innerTestJPEGImageWithIF(int level) throws Exception { + private void innerTestJPEGImage(int level) throws Exception { FOUserAgent ua = fopFactory.newFOUserAgent(); PSDocumentHandler handler = new PSDocumentHandler(); handler.setContext(new IFContext(ua)); @@ -159,10 +129,6 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase { } } - private void assertMatches(String text, String regex) { - assertTrue("Text didn't match '" + regex + "'", text.matches(regex)); - } - private void assertContains(String text, String searchString) { assertTrue("Text doesn't contain '" + searchString + "'", text.indexOf(searchString) >= 0); } diff --git a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java index e5b9a4d27..862ad5205 100644 --- a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java +++ b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java @@ -54,28 +54,10 @@ import org.apache.fop.render.intermediate.IFContext; public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase { /** - * Tests resource optimization with the {@link PSRenderer}. + * Tests resource optimization. * @throws Exception if an error occurs */ - public void testResourceOptimizationWithRenderer() throws Exception { - FOUserAgent ua = fopFactory.newFOUserAgent(); - PSRenderer renderer = new PSRenderer(); - renderer.setUserAgent(ua); - // This is the important part: we're enabling resource optimization - renderer.getPSUtil().setOptimizeResources(true); - ua.setRendererOverride(renderer); - - // Prepare output file - File outputFile = renderFile(ua, "ps-resources.fo", - "-rend-l" + renderer.getPSUtil().getLanguageLevel()); - verifyPostScriptFile(outputFile); - } - - /** - * Tests resource optimization with the {@link PSDocumentHandler}. - * @throws Exception if an error occurs - */ - public void testResourceOptimizationWithIF() throws Exception { + public void testResourceOptimization() throws Exception { FOUserAgent ua = fopFactory.newFOUserAgent(); PSDocumentHandler handler = new PSDocumentHandler(); handler.setContext(new IFContext(ua)); -- 2.39.5