org.apache.fop.render.pdf.PDFImageHandlerRawJPEG\r
org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax\r
org.apache.fop.render.pdf.PDFImageHandlerSVG\r
+org.apache.fop.render.java2d.Java2DImageHandlerRenderedImage\r
+org.apache.fop.render.java2d.Java2DImageHandlerGraphics2D\r
--- /dev/null
+org.apache.fop.render.pdf.PDFDocumentHandlerMaker\r
+org.apache.fop.render.pcl.PCLDocumentHandlerMaker\r
+org.apache.fop.render.bitmap.TIFFDocumentHandlerMaker
\ No newline at end of file
+++ /dev/null
-org.apache.fop.render.pdf.PDFPainterMaker\r
-org.apache.fop.render.pcl.PCLPainterMaker
\ No newline at end of file
import org.apache.fop.fonts.FontManager;
import org.apache.fop.hyphenation.HyphenationTreeResolver;
import org.apache.fop.layoutmgr.LayoutManagerMaker;
+import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.util.ColorSpaceCache;
/** Registry for XML handlers */
private XMLHandlerRegistry xmlHandlers;
+ /** Registry for image handlers */
+ private ImageHandlerRegistry imageHandlers;
+
/** The registry for ElementMapping instances */
private ElementMappingRegistry elementMappingRegistry;
this.imageManager = new ImageManager(this);
this.rendererFactory = new RendererFactory();
this.xmlHandlers = new XMLHandlerRegistry();
+ this.imageHandlers = new ImageHandlerRegistry();
this.ignoredNamespaces = new java.util.HashSet();
}
return this.xmlHandlers;
}
+ /** @return the image handler registry */
+ public ImageHandlerRegistry getImageHandlerRegistry() {
+ return this.imageHandlers;
+ }
+
/** @return the element mapping registry */
public ElementMappingRegistry getElementMappingRegistry() {
return this.elementMappingRegistry;
private Set warnedXMLHandlers;
/** {@inheritDoc} */
- public abstract void setupFontInfo(FontInfo fontInfo);
+ public abstract void setupFontInfo(FontInfo fontInfo) throws FOPException;
/** {@inheritDoc} */
public void setUserAgent(FOUserAgent agent) {
import org.w3c.dom.Document;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.area.Area;
import org.apache.fop.area.Trait;
import org.apache.fop.fonts.CustomFontCollection;
return this.embedFontInfoList;
}
- /**
- * Set up the font info
- *
- * @param inFontInfo font info to set up
- */
- public void setupFontInfo(FontInfo inFontInfo) {
+ /** {@inheritDoc} */
+ public void setupFontInfo(FontInfo inFontInfo) throws FOPException {
this.fontInfo = inFontInfo;
FontManager fontManager = userAgent.getFactory().getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
* Set up the given FontInfo.
*
* @param fontInfo The font information
+ * @throws FOPException if an error occurs while setting up the font info object
*/
- void setupFontInfo(FontInfo fontInfo);
+ void setupFontInfo(FontInfo fontInfo) throws FOPException;
/**
* Reports if out of order rendering is supported. <p>
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.fo.FOEventHandler;
-import org.apache.fop.render.intermediate.AbstractIFPainterMaker;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
+import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFRenderer;
/**
private Map rendererMakerMapping = new java.util.HashMap();
private Map eventHandlerMakerMapping = new java.util.HashMap();
- private Map painterMakerMapping = new java.util.HashMap();
+ private Map documentHandlerMakerMapping = new java.util.HashMap();
/**
* Main constructor.
public RendererFactory() {
discoverRenderers();
discoverFOEventHandlers();
- discoverPainters();
+ discoverDocumentHandlers();
}
/**
}
/**
- * Add a new painter maker. If another maker has already been registered for a
+ * Add a new document handler maker. If another maker has already been registered for a
* particular MIME type, this call overwrites the existing one.
- * @param maker the painter maker
+ * @param maker the intermediate format document handler maker
*/
- public void addPainterMaker(AbstractIFPainterMaker maker) {
+ public void addDocumentHandlerMaker(AbstractIFDocumentHandlerMaker maker) {
String[] mimes = maker.getSupportedMimeTypes();
for (int i = 0; i < mimes.length; i++) {
//This overrides any renderer previously set for a MIME type
- if (painterMakerMapping.get(mimes[i]) != null) {
- log.trace("Overriding painter for " + mimes[i]
+ if (documentHandlerMakerMapping.get(mimes[i]) != null) {
+ log.trace("Overriding document handler for " + mimes[i]
+ " with " + maker.getClass().getName());
}
- painterMakerMapping.put(mimes[i], maker);
+ documentHandlerMakerMapping.put(mimes[i], maker);
}
}
}
/**
- * Add a new painter maker. If another maker has already been registered for a
+ * Add a new document handler maker. If another maker has already been registered for a
* particular MIME type, this call overwrites the existing one.
- * @param className the fully qualified class name of the painter maker
+ * @param className the fully qualified class name of the document handler maker
*/
- public void addPainterMaker(String className) {
+ public void addDocumentHandlerMaker(String className) {
try {
- AbstractIFPainterMaker makerInstance
- = (AbstractIFPainterMaker)Class.forName(className).newInstance();
- addPainterMaker(makerInstance);
+ AbstractIFDocumentHandlerMaker makerInstance
+ = (AbstractIFDocumentHandlerMaker)Class.forName(className).newInstance();
+ addDocumentHandlerMaker(makerInstance);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Could not find "
+ className);
} catch (ClassCastException e) {
throw new IllegalArgumentException(className
+ " is not an "
- + AbstractIFPainterMaker.class.getName());
+ + AbstractIFDocumentHandlerMaker.class.getName());
}
}
* @param mime the requested output format
* @return the requested RendererMaker or null if none is available
*/
- public AbstractIFPainterMaker getPainterMaker(String mime) {
- AbstractIFPainterMaker maker
- = (AbstractIFPainterMaker)painterMakerMapping.get(mime);
+ public AbstractIFDocumentHandlerMaker getDocumentHandlerMaker(String mime) {
+ AbstractIFDocumentHandlerMaker maker
+ = (AbstractIFDocumentHandlerMaker)documentHandlerMakerMapping.get(mime);
return maker;
}
}
return rend;
} else {
- AbstractIFPainterMaker painterMaker = getPainterMaker(outputFormat);
- if (painterMaker != null) {
+ AbstractIFDocumentHandlerMaker documentHandlerMaker
+ = getDocumentHandlerMaker(outputFormat);
+ if (documentHandlerMaker != null) {
IFRenderer rend = new IFRenderer();
rend.setUserAgent(userAgent);
- IFPainter painter = createPainter(userAgent, outputFormat);
- rend.setPainter(painter);
+ IFDocumentHandler documentHandler = createDocumentHandler(
+ userAgent, outputFormat);
+ rend.setDocumentHandler(documentHandler);
return rend;
} else {
throw new UnsupportedOperationException(
return maker.makeFOEventHandler(userAgent, out);
} else {
AbstractRendererMaker rendMaker = getRendererMaker(outputFormat);
- AbstractIFPainterMaker painterMaker = null;
+ AbstractIFDocumentHandlerMaker documentHandlerMaker = null;
boolean outputStreamMissing = (userAgent.getRendererOverride() == null);
if (rendMaker == null) {
- painterMaker = getPainterMaker(outputFormat);
- if (painterMaker != null) {
- outputStreamMissing &= (out == null) && (painterMaker.needsOutputStream());
+ documentHandlerMaker = getDocumentHandlerMaker(outputFormat);
+ if (documentHandlerMaker != null) {
+ outputStreamMissing &= (out == null)
+ && (documentHandlerMaker.needsOutputStream());
}
} else {
outputStreamMissing &= (out == null) && (rendMaker.needsOutputStream());
}
if (userAgent.getRendererOverride() != null
|| rendMaker != null
- || painterMaker != null) {
+ || documentHandlerMaker != null) {
if (outputStreamMissing) {
throw new FOPException(
"OutputStream has not been set");
}
/**
- * Creates a {@code IFPainter} object based on render-type desired
+ * Creates a {@code IFDocumentHandler} object based on the desired output format.
* @param userAgent the user agent for access to configuration
* @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
- * @return the new {@code IFPainter} instance
- * @throws FOPException if the painter cannot be properly constructed
+ * @return the new {@code IFDocumentHandler} instance
+ * @throws FOPException if the document handler cannot be properly constructed
*/
- public IFPainter createPainter(FOUserAgent userAgent, String outputFormat)
+ public IFDocumentHandler createDocumentHandler(FOUserAgent userAgent, String outputFormat)
throws FOPException {
/*
- if (userAgent.getIFPainterOverride() != null) {
- return userAgent.getIFPainterOverride();
+ if (userAgent.getIFDocumentHandlerOverride() != null) {
+ return userAgent.getIFDocumentHandlerOverride();
} else {
*/
- AbstractIFPainterMaker maker = getPainterMaker(outputFormat);
+ AbstractIFDocumentHandlerMaker maker = getDocumentHandlerMaker(outputFormat);
if (maker == null) {
throw new UnsupportedOperationException(
- "No renderer for the requested format available: " + outputFormat);
+ "No IF document handler for the requested format available: " + outputFormat);
}
- IFPainter painter = maker.makePainter(userAgent);
- painter.setUserAgent(userAgent);
- IFPainterConfigurator configurator = maker.getConfigurator(userAgent);
- if (configurator != null) {
- configurator.configure(painter);
- configurator.setupFontInfo(painter);
- }
- return painter;
+ IFDocumentHandler documentHandler = maker.makeIFDocumentHandler(userAgent);
+ return documentHandler;
//}
}
while (iter.hasNext()) {
lst.add(((String)iter.next()));
}
- iter = this.painterMakerMapping.keySet().iterator();
+ iter = this.documentHandlerMakerMapping.keySet().iterator();
while (iter.hasNext()) {
lst.add(((String)iter.next()));
}
}
/**
- * Discovers {@code IFPainter} implementations through the classpath and dynamically
+ * Discovers {@code IFDocumentHandler} implementations through the classpath and dynamically
* registers them.
*/
- private void discoverPainters() {
+ private void discoverDocumentHandlers() {
// add mappings from available services
- Iterator providers
- = Service.providers(IFPainter.class);
+ Iterator providers = Service.providers(IFDocumentHandler.class);
if (providers != null) {
while (providers.hasNext()) {
- AbstractIFPainterMaker maker = (AbstractIFPainterMaker)providers.next();
+ AbstractIFDocumentHandlerMaker maker = (AbstractIFDocumentHandlerMaker)providers.next();
try {
if (log.isDebugEnabled()) {
- log.debug("Dynamically adding maker for IFPainter: "
+ log.debug("Dynamically adding maker for IFDocumentHandler: "
+ maker.getClass().getName());
}
- addPainterMaker(maker);
+ addDocumentHandlerMaker(maker);
} catch (IllegalArgumentException e) {
- log.error("Error while adding maker for IFPainter", e);
+ log.error("Error while adding maker for IFDocumentHandler", e);
}
}
--- /dev/null
+/*
+ * 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.bitmap;
+
+import java.awt.image.BufferedImage;
+
+import org.apache.xmlgraphics.image.writer.ImageWriterParams;
+
+import org.apache.fop.render.java2d.Java2DRenderingSettings;
+
+/**
+ * This class holds settings used when rendering to bitmaps.
+ */
+public class BitmapRenderingSettings extends Java2DRenderingSettings implements TIFFConstants {
+
+ /** ImageWriter parameters */
+ private ImageWriterParams writerParams;
+
+ /** Image Type as parameter for the BufferedImage constructor (see BufferedImage.TYPE_*) */
+ private int bufferedImageType = BufferedImage.TYPE_INT_ARGB;
+
+ /** true if anti-aliasing is set */
+ private boolean antialiasing = true;
+
+ /** true if qualityRendering is set */
+ private boolean qualityRendering = true;
+
+ /**
+ * Default constructor. Initializes the settings to their default values.
+ */
+ public BitmapRenderingSettings() {
+ writerParams = new ImageWriterParams();
+ writerParams.setCompressionMethod(COMPRESSION_PACKBITS);
+ }
+
+ /**
+ * Returns the image writer parameters used for encoding the bitmap images.
+ * @return the image writer parameters
+ */
+ public ImageWriterParams getWriterParams() {
+ return this.writerParams;
+ }
+
+ /**
+ * Returns the BufferedImage type.
+ * @return one of BufferedImage.TYPE_*
+ */
+ public int getBufferedImageType() {
+ return this.bufferedImageType;
+ }
+
+ /**
+ * Sets the type of the BufferedImage to use when preparing a new instance.
+ * @param bufferedImageType a BufferImage.TYPE_* value
+ */
+ public void setBufferedImageType(int bufferedImageType) {
+ this.bufferedImageType = bufferedImageType;
+ }
+
+ /**
+ * Enables or disables anti-aliasing.
+ * @param value true to enable anti-aliasing
+ */
+ public void setAntiAliasing(boolean value) {
+ this.antialiasing = value;
+ }
+
+ /**
+ * Indicates whether anti-aliasing is enabled.
+ * @return true if anti-aliasing is enabled
+ */
+ public boolean isAntiAliasingEnabled() {
+ return this.antialiasing;
+ }
+
+ /**
+ * Controls whether to optimize rendering for speed or for quality.
+ * @param quality true to optimize for quality, false to optimize for speed
+ */
+ public void setQualityRendering(boolean quality) {
+ this.qualityRendering = quality;
+ }
+
+ /**
+ * Indicates whether quality rendering is enabled.
+ * @return true indicates optimization for quality, false indicates optimization for speed
+ */
+ public boolean isQualityRenderingEnabled() {
+ return this.qualityRendering;
+ }
+
+}
--- /dev/null
+/*
+ * 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.bitmap;
+
+import org.apache.fop.apps.MimeConstants;
+
+/**
+ * Constants for TIFF output.
+ */
+public interface TIFFConstants {
+
+ /** The MIME type for tiff-Rendering */
+ String MIME_TYPE = MimeConstants.MIME_TIFF;
+
+ /** No compression */
+ String COMPRESSION_NONE = "NONE";
+ /** JPEG compression */
+ String COMPRESSION_JPEG = "JPEG";
+ /** Packbits (RLE) compression */
+ String COMPRESSION_PACKBITS = "PackBits";
+ /** Deflate compression */
+ String COMPRESSION_DEFLATE = "Deflate";
+ /** LZW compression */
+ String COMPRESSION_LZW = "LZW";
+ /** ZLib compression */
+ String COMPRESSION_ZLIB = "ZLib";
+ /** CCITT Group 4 (T.6) compression */
+ String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
+ /** CCITT Group 3 (T.4) compression */
+ String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
+
+}
--- /dev/null
+/*
+ * 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.bitmap;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.image.writer.ImageWriter;
+import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
+import org.apache.xmlgraphics.image.writer.MultiImageWriter;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactoryConfigurator;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.java2d.Java2DPainter;
+import org.apache.fop.render.java2d.Java2DUtil;
+
+/**
+ * {@code IFDocumentHandler} implementation that produces PCL 5.
+ */
+public class TIFFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
+ implements TIFFConstants {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(TIFFDocumentHandler.class);
+
+ private ImageWriter imageWriter;
+ private MultiImageWriter multiImageWriter;
+
+ private int pageCount;
+ private Dimension currentPageDimensions;
+ private BufferedImage currentImage;
+
+ private BitmapRenderingSettings bitmapSettings = new BitmapRenderingSettings();
+
+ private double scaleFactor = 1.0;
+
+ /**
+ * Default constructor.
+ */
+ public TIFFDocumentHandler() {
+ }
+
+ /** {@inheritDoc} */
+ public boolean supportsPagesOutOfOrder() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_TIFF;
+ }
+
+ /** {@inheritDoc} */
+ public void setUserAgent(FOUserAgent ua) {
+ super.setUserAgent(ua);
+
+ //Set target resolution
+ int dpi = Math.round(ua.getTargetResolution());
+ getSettings().getWriterParams().setResolution(dpi);
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ return new TIFFRendererConfigurator(getUserAgent());
+ }
+
+ /**
+ * Returns the settings for bitmap rendering.
+ * @return the settings object
+ */
+ public BitmapRenderingSettings getSettings() {
+ return this.bitmapSettings;
+ }
+
+ /** {@inheritDoc} */
+ public void setDefaultFontInfo(FontInfo fontInfo) {
+ FontInfo fi = Java2DUtil.buildDefaultJava2DBasedFontInfo(fontInfo, getUserAgent());
+ setFontInfo(fi);
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+ /** {@inheritDoc} */
+ public void startDocument() throws IFException {
+ try {
+ if (getUserAgent() == null) {
+ throw new IllegalStateException(
+ "User agent must be set before starting PDF generation");
+ }
+ if (this.outputStream == null) {
+ throw new IllegalStateException("OutputStream hasn't been set through setResult()");
+ }
+
+ // Creates writer
+ this.imageWriter = ImageWriterRegistry.getInstance().getWriterFor(getMimeType());
+ if (this.imageWriter == null) {
+ BitmapRendererEventProducer eventProducer
+ = BitmapRendererEventProducer.Provider.get(
+ getUserAgent().getEventBroadcaster());
+ eventProducer.noImageWriterFound(this, getMimeType());
+ }
+ if (this.imageWriter.supportsMultiImageWriter()) {
+ this.multiImageWriter = this.imageWriter.createMultiImageWriter(outputStream);
+ }
+ this.pageCount = 0;
+ } catch (IOException e) {
+ throw new IFException("I/O error in startDocument()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ try {
+ if (this.multiImageWriter != null) {
+ this.multiImageWriter.close();
+ }
+ this.multiImageWriter = null;
+ this.imageWriter = null;
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in endDocument()", ioe);
+ }
+ super.endDocument();
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(String id) throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPageSequence() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPage(int index, String name, Dimension size) throws IFException {
+ this.pageCount++;
+ this.currentPageDimensions = new Dimension(size);
+ }
+
+ /** {@inheritDoc} */
+ public IFPainter startPageContent() throws IFException {
+ double scale = scaleFactor
+ * (25.4f / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+ / getUserAgent().getTargetPixelUnitToMillimeter();
+ int bitmapWidth = (int) ((this.currentPageDimensions.width * scale / 1000f) + 0.5f);
+ int bitmapHeight = (int) ((this.currentPageDimensions.height * scale / 1000f) + 0.5f);
+ this.currentImage = createBufferedImage(bitmapWidth, bitmapHeight);
+ Graphics2D graphics2D = this.currentImage.createGraphics();
+ // draw page background
+ if (!getSettings().hasTransparentPageBackground()) {
+ graphics2D.setBackground(getSettings().getPageBackgroundColor());
+ graphics2D.setPaint(getSettings().getPageBackgroundColor());
+ graphics2D.fillRect(0, 0, bitmapWidth, bitmapHeight);
+ }
+
+ graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ if (getSettings().isAntiAliasingEnabled()
+ && this.currentImage.getColorModel().getPixelSize() > 1) {
+ graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ } else {
+ graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+ graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+ }
+ if (getSettings().isQualityRenderingEnabled()) {
+ graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+ } else {
+ graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_SPEED);
+ }
+ graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_PURE);
+ graphics2D.scale(scale / 1000f, scale / 1000f);
+
+ return new Java2DPainter(graphics2D, getUserAgent(), getFontInfo());
+ }
+
+ /**
+ * Creates a new BufferedImage.
+ * @param bitmapWidth the desired width in pixels
+ * @param bitmapHeight the desired height in pixels
+ * @return the new BufferedImage instance
+ */
+ protected BufferedImage createBufferedImage(int bitmapWidth, int bitmapHeight) {
+ return new BufferedImage(bitmapWidth, bitmapHeight, getSettings().getBufferedImageType());
+ }
+
+ /** {@inheritDoc} */
+ public void endPageContent() throws IFException {
+ try {
+ if (this.multiImageWriter == null) {
+ switch (this.pageCount) {
+ case 1:
+ this.imageWriter.writeImage(
+ this.currentImage, this.outputStream,
+ getSettings().getWriterParams());
+ break;
+ case 2:
+ BitmapRendererEventProducer eventProducer
+ = BitmapRendererEventProducer.Provider.get(
+ getUserAgent().getEventBroadcaster());
+ eventProducer.stoppingAfterFirstPageNoFilename(this);
+ break;
+ default:
+ //ignore
+ }
+ } else {
+ this.multiImageWriter.writeImage(this.currentImage,
+ getSettings().getWriterParams());
+ }
+ this.currentImage = null;
+ } catch (IOException ioe) {
+ throw new IFException("I/O error while encoding BufferedImage", ioe);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endPage() throws IFException {
+ this.currentPageDimensions = null;
+ }
+
+ /** {@inheritDoc} */
+ public void handleExtensionObject(Object extension) throws IFException {
+ if (false) {
+ //TODO Handle extensions
+ } else {
+ log.debug("Don't know how to handle extension object. Ignoring: "
+ + extension + " (" + extension.getClass().getName() + ")");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.bitmap;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Document handler factory for TIFF output.
+ */
+public class TIFFDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
+
+ //TODO Revert to normal MIME after stabilization!
+ private static final String[] MIMES = new String[] {MimeConstants.MIME_TIFF + ";mode=painter"};
+
+ /** {@inheritDoc} */
+ public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
+ TIFFDocumentHandler handler = new TIFFDocumentHandler();
+ handler.setUserAgent(ua);
+ return handler;
+ }
+
+ /** {@inheritDoc} */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new TIFFRendererConfigurator(userAgent);
+ }
+
+}
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.java2d.Java2DRenderer;
/**
* <code>org.apache.fop.render.java2D.Java2DRenderer</code> and just encode
* rendering results into TIFF format using Batik's image codec
*/
-public class TIFFRenderer extends Java2DRenderer {
-
- /** The MIME type for tiff-Rendering */
- public static final String MIME_TYPE = MimeConstants.MIME_TIFF;
-
- //private static final String COMPRESSION_NONE = "NONE";
- //private static final String COMPRESSION_JPEG = "JPEG";
- public static final String COMPRESSION_PACKBITS = "PackBits";
- //private static final String COMPRESSION_DEFLATE = "Deflate";
- //private static final String COMPRESSION_LZW = "LZW";
- //private static final String COMPRESSION_ZLIB = "ZLib";
- public static final String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
- public static final String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
+public class TIFFRenderer extends Java2DRenderer implements TIFFConstants {
/** ImageWriter parameters */
private ImageWriterParams writerParams;
package org.apache.fop.render.bitmap;
+import java.awt.Color;
+import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
+import java.util.List;
import org.apache.avalon.framework.configuration.Configuration;
+
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontEventAdapter;
+import org.apache.fop.fonts.FontEventListener;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.render.DefaultFontResolver;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.java2d.Base14FontCollection;
+import org.apache.fop.render.java2d.ConfiguredFontCollection;
+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.java2d.Java2DRendererConfigurator;
+import org.apache.fop.util.ColorUtil;
/**
* TIFF Renderer configurator
*/
-public class TIFFRendererConfigurator extends PrintRendererConfigurator {
+public class TIFFRendererConfigurator extends Java2DRendererConfigurator
+ implements IFDocumentHandlerConfigurator {
/**
* Default constructor
if (cfg != null) {
TIFFRenderer tiffRenderer = (TIFFRenderer)renderer;
//set compression
- String name = cfg.getChild("compression").getValue(TIFFRenderer.COMPRESSION_PACKBITS);
+ String name = cfg.getChild("compression").getValue(TIFFConstants.COMPRESSION_PACKBITS);
//Some compression formats need a special image format:
- if (name.equalsIgnoreCase(TIFFRenderer.COMPRESSION_CCITT_T6)) {
- tiffRenderer.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
- } else if (name.equalsIgnoreCase(TIFFRenderer.COMPRESSION_CCITT_T4)) {
- tiffRenderer.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
- } else {
- tiffRenderer.setBufferedImageType(BufferedImage.TYPE_INT_ARGB);
- }
+ tiffRenderer.setBufferedImageType(getBufferedImageTypeFor(name));
if (!"NONE".equalsIgnoreCase(name)) {
tiffRenderer.getWriterParams().setCompressionMethod(name);
}
}
super.configure(renderer);
}
+
+ private int getBufferedImageTypeFor(String compressionName) {
+ if (compressionName.equalsIgnoreCase(TIFFConstants.COMPRESSION_CCITT_T6)) {
+ return BufferedImage.TYPE_BYTE_BINARY;
+ } else if (compressionName.equalsIgnoreCase(TIFFConstants.COMPRESSION_CCITT_T4)) {
+ return BufferedImage.TYPE_BYTE_BINARY;
+ } else {
+ return BufferedImage.TYPE_INT_ARGB;
+ }
+ }
+
+ // ---=== IFDocumentHandler configuration ===---
+
+ /** {@inheritDoc} */
+ public void configure(IFDocumentHandler documentHandler) throws FOPException {
+ Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
+ if (cfg != null) {
+ TIFFDocumentHandler tiffHandler = (TIFFDocumentHandler)documentHandler;
+ BitmapRenderingSettings settings = tiffHandler.getSettings();
+ //set compression
+ String name = cfg.getChild("compression").getValue(TIFFConstants.COMPRESSION_PACKBITS);
+ //Some compression formats need a special image format:
+ settings.setBufferedImageType(getBufferedImageTypeFor(name));
+ if (!"NONE".equalsIgnoreCase(name)) {
+ settings.getWriterParams().setCompressionMethod(name);
+ }
+ if (log.isInfoEnabled()) {
+ log.info("TIFF compression set to " + name);
+ }
+
+ boolean transparent = cfg.getChild(
+ Java2DRenderer.JAVA2D_TRANSPARENT_PAGE_BACKGROUND).getValueAsBoolean(
+ settings.hasTransparentPageBackground());
+ if (transparent) {
+ settings.setPageBackgroundColor(null);
+ } else {
+ String background = cfg.getChild("background-color").getValue(null);
+ if (background != null) {
+ settings.setPageBackgroundColor(
+ ColorUtil.parseColorString(this.userAgent, background));
+ } else {
+ settings.setPageBackgroundColor(Color.WHITE);
+ }
+ }
+
+ boolean antiAliasing = cfg.getChild("anti-aliasing").getValueAsBoolean(
+ settings.isAntiAliasingEnabled());
+ settings.setAntiAliasing(antiAliasing);
+
+ String optimization = cfg.getChild("rendering").getValue(null);
+ if ("quality".equalsIgnoreCase(optimization)) {
+ settings.setQualityRendering(true);
+ } else if ("speed".equalsIgnoreCase(optimization)) {
+ settings.setQualityRendering(false);
+ }
+
+ String color = cfg.getChild("color-mode").getValue(null);
+ if (color != null) {
+ if ("rgba".equalsIgnoreCase(color)) {
+ settings.setBufferedImageType(BufferedImage.TYPE_INT_ARGB);
+ } else if ("rgb".equalsIgnoreCase(color)) {
+ settings.setBufferedImageType(BufferedImage.TYPE_INT_RGB);
+ } else if ("gray".equalsIgnoreCase(color)) {
+ settings.setBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
+ } else if ("binary".equalsIgnoreCase(color)) {
+ settings.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
+ } else {
+ throw new FOPException("Invalid value for color-mode: " + color);
+ }
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
+ throws FOPException {
+ FontManager fontManager = userAgent.getFactory().getFontManager();
+
+ Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+
+ List fontCollections = new java.util.ArrayList();
+ fontCollections.add(new Base14FontCollection(graphics2D));
+ fontCollections.add(new InstalledFontCollection(graphics2D));
+
+ Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
+ if (cfg != null) {
+ FontResolver fontResolver = new DefaultFontResolver(userAgent);
+ FontEventListener listener = new FontEventAdapter(
+ userAgent.getEventBroadcaster());
+ List fontList = buildFontList(cfg, fontResolver, listener);
+ fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList));
+ }
+
+ fontManager.setup(fontInfo,
+ (FontCollection[])fontCollections.toArray(
+ new FontCollection[fontCollections.size()]));
+ documentHandler.setFontInfo(fontInfo);
+ }
+
+
}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontEventAdapter;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.base14.Base14FontCollection;
+
+/**
+ * Abstract base class for binary-writing {@code IFDocumentHandler} implementations.
+ */
+public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFDocumentHandler {
+
+ /** The output stream to write the document to */
+ protected OutputStream outputStream;
+
+ private boolean ownOutputStream;
+
+ /** Font configuration */
+ protected FontInfo fontInfo;
+
+ /** {@inheritDoc} */
+ public void setResult(Result result) throws IFException {
+ if (result instanceof StreamResult) {
+ StreamResult streamResult = (StreamResult)result;
+ OutputStream out = streamResult.getOutputStream();
+ if (out == null) {
+ if (streamResult.getWriter() != null) {
+ throw new IllegalArgumentException(
+ "FOP cannot use a Writer. Please supply an OutputStream!");
+ }
+ try {
+ URL url = new URL(streamResult.getSystemId());
+ File f = FileUtils.toFile(url);
+ if (f != null) {
+ out = new java.io.FileOutputStream(f);
+ } else {
+ out = url.openConnection().getOutputStream();
+ }
+ } catch (IOException ioe) {
+ throw new IFException("I/O error while opening output stream" , ioe);
+ }
+ out = new java.io.BufferedOutputStream(out);
+ this.ownOutputStream = true;
+ }
+ if (out == null) {
+ throw new IllegalArgumentException("Need a StreamResult with an OutputStream");
+ }
+ this.outputStream = out;
+ } else {
+ throw new UnsupportedOperationException(
+ "Unsupported Result subclass: " + result.getClass().getName());
+ }
+ }
+
+ /** {@inheritDoc} */
+ public FontInfo getFontInfo() {
+ return this.fontInfo;
+ }
+
+ /** {@inheritDoc} */
+ public void setFontInfo(FontInfo fontInfo) {
+ this.fontInfo = fontInfo;
+ }
+
+ /** {@inheritDoc} */
+ public void setDefaultFontInfo(FontInfo fontInfo) {
+ FontManager fontManager = getUserAgent().getFactory().getFontManager();
+ FontCollection[] fontCollections = new FontCollection[] {
+ new Base14FontCollection(fontManager.isBase14KerningEnabled())
+ };
+
+ FontInfo fi = (fontInfo != null ? fontInfo : new FontInfo());
+ fi.setEventListener(new FontEventAdapter(getUserAgent().getEventBroadcaster()));
+ fontManager.setup(fi, fontCollections);
+ setFontInfo(fi);
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ if (this.ownOutputStream) {
+ IOUtils.closeQuietly(this.outputStream);
+ this.outputStream = null;
+ }
+ }
+
+}
+++ /dev/null
-/*
- * 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.intermediate;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.URL;
-
-import javax.xml.transform.Result;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-
-import org.apache.fop.fonts.FontCollection;
-import org.apache.fop.fonts.FontEventAdapter;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.base14.Base14FontCollection;
-
-/**
- * Abstract base class for binary-writing IFPainter implementations.
- */
-public abstract class AbstractBinaryWritingIFPainter extends AbstractIFPainter {
-
- /** The output stream to write the document to */
- protected OutputStream outputStream;
-
- private boolean ownOutputStream;
-
- /** Font configuration */
- protected FontInfo fontInfo;
-
- /** {@inheritDoc} */
- public void setResult(Result result) throws IFException {
- if (result instanceof StreamResult) {
- StreamResult streamResult = (StreamResult)result;
- OutputStream out = streamResult.getOutputStream();
- if (out == null) {
- if (streamResult.getWriter() != null) {
- throw new IllegalArgumentException(
- "FOP cannot use a Writer. Please supply an OutputStream!");
- }
- try {
- URL url = new URL(streamResult.getSystemId());
- File f = FileUtils.toFile(url);
- if (f != null) {
- out = new java.io.FileOutputStream(f);
- } else {
- out = url.openConnection().getOutputStream();
- }
- } catch (IOException ioe) {
- throw new IFException("I/O error while opening output stream" , ioe);
- }
- out = new java.io.BufferedOutputStream(out);
- this.ownOutputStream = true;
- }
- if (out == null) {
- throw new IllegalArgumentException("Need a StreamResult with an OutputStream");
- }
- this.outputStream = out;
- } else {
- throw new UnsupportedOperationException(
- "Unsupported Result subclass: " + result.getClass().getName());
- }
- }
-
- /**
- * Returns the {@code FontInfo} object.
- * @return the font info
- */
- public FontInfo getFontInfo() {
- return this.fontInfo;
- }
-
- /** {@inheritDoc} */
- public void setFontInfo(FontInfo fontInfo) {
- this.fontInfo = fontInfo;
- }
-
- /** {@inheritDoc} */
- public void setDefaultFontInfo() {
- FontManager fontManager = getUserAgent().getFactory().getFontManager();
- FontCollection[] fontCollections = new FontCollection[] {
- new Base14FontCollection(fontManager.isBase14KerningEnabled())
- };
-
- FontInfo fi = new FontInfo();
- fi.setEventListener(new FontEventAdapter(getUserAgent().getEventBroadcaster()));
- fontManager.setup(fi, fontCollections);
- setFontInfo(fi);
- }
-
- /** {@inheritDoc} */
- public void endDocument() throws IFException {
- if (this.ownOutputStream) {
- IOUtils.closeQuietly(this.outputStream);
- this.outputStream = null;
- }
- }
-
-}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Abstract base class for {@code IFDocumentHandler} implementations.
+ */
+public abstract class AbstractIFDocumentHandler implements IFDocumentHandler {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(AbstractIFDocumentHandler.class);
+
+ private FOUserAgent userAgent;
+
+ /**
+ * Default constructor.
+ */
+ public AbstractIFDocumentHandler() {
+ }
+
+ /** {@inheritDoc} */
+ public void setUserAgent(FOUserAgent ua) {
+ if (this.userAgent != null) {
+ throw new IllegalStateException("The user agent was already set");
+ }
+ this.userAgent = ua;
+ }
+
+ /**
+ * Returns the user agent.
+ * @return the user agent
+ */
+ public FOUserAgent getUserAgent() {
+ return this.userAgent;
+ }
+
+ /** {@inheritDoc} */
+ public void startDocumentHeader() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startDocumentTrailer() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentTrailer() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPageHeader() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPageHeader() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPageTrailer() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPageTrailer() throws IFException {
+ //nop
+ }
+
+}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Base class for factory classes which instantiate {@code IFDocumentHandler}s and provide
+ * information about them.
+ */
+public abstract class AbstractIFDocumentHandlerMaker {
+
+ /**
+ * Instantiates a new {@code IFDocumentHandler}.
+ * @param userAgent the user agent
+ * @return the newly instantiated document handler
+ */
+ public abstract IFDocumentHandler makeIFDocumentHandler(FOUserAgent userAgent);
+
+ /**
+ * @return Indicates whether this document handler requires an OutputStream to work with.
+ */
+ public abstract boolean needsOutputStream();
+
+ /**
+ * @return an array of MIME types the document handler supports.
+ */
+ public abstract String[] getSupportedMimeTypes();
+
+ /**
+ * Returns a configurator object that can be used to
+ * configure the document handler.
+ * @param userAgent the user agent
+ * @return a configurator object that can be used to configure the document handler
+ */
+ public abstract IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent);
+
+ /**
+ * Indicates whether a specific MIME type is supported by this document handler.
+ * @param mimeType the MIME type (ex. "application/pdf")
+ * @return true if the MIME type is supported
+ */
+ public boolean isMimeTypeSupported(String mimeType) {
+ String[] mimes = getSupportedMimeTypes();
+ for (int i = 0; i < mimes.length; i++) {
+ if (mimes[i].equals(mimeType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
import org.apache.fop.events.ResourceEventProducer;
import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.ImageHandlerRegistry;
/** non-URI that can be used in feedback messages that an image is an instream-object */
protected static final String INSTREAM_OBJECT_URI = "(instream-object)";
- private FOUserAgent userAgent;
-
- /** Image handler registry */
- protected ImageHandlerRegistry imageHandlerRegistry = new ImageHandlerRegistry();
- //TODO Move reference to FOPFactory to the user has a chance to add his own implementations
- //and so the lookup process isn't redone for each painter instance.
/**
* Default constructor.
public AbstractIFPainter() {
}
- /** {@inheritDoc} */
- public void setUserAgent(FOUserAgent ua) {
- if (this.userAgent != null) {
- throw new IllegalStateException("The user agent was already set");
- }
- this.userAgent = ua;
- }
-
/**
* Returns the user agent.
* @return the user agent
*/
- protected FOUserAgent getUserAgent() {
- return this.userAgent;
- }
-
- /** {@inheritDoc} */
- public void startDocumentHeader() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void endDocumentHeader() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void startDocumentTrailer() throws IFException {
- //nop
- }
+ protected abstract FOUserAgent getUserAgent();
- /** {@inheritDoc} */
- public void endDocumentTrailer() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void startPageHeader() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void endPageHeader() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void startPageTrailer() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void endPageTrailer() throws IFException {
- //nop
+ /**
+ * Returns the FOP factory.
+ * @return the FOP factory.
+ */
+ protected FopFactory getFopFactory() {
+ return getUserAgent().getFactory();
}
private AffineTransform combine(AffineTransform[] transforms) {
*/
protected void drawImageUsingImageHandler(ImageInfo info, Rectangle rect)
throws ImageException, IOException {
- ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageManager manager = getFopFactory().getImageManager();
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
+ ImageHandlerRegistry imageHandlerRegistry = getFopFactory().getImageHandlerRegistry();
//Load and convert the image to a supported format
RenderingContext context = createRenderingContext();
* @param rect the rectangle in which to paint the image
*/
protected void drawImageUsingURI(String uri, Rectangle rect) {
- ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageManager manager = getFopFactory().getImageManager();
ImageInfo info = null;
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
* @param rect the rectangle in which to paint the image
*/
protected void drawImageUsingDocument(Document doc, Rectangle rect) {
- ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageManager manager = getFopFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.preloadImage(null, new DOMSource(doc));
+++ /dev/null
-/*
- * 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.intermediate;
-
-import org.apache.fop.apps.FOUserAgent;
-
-/**
- * Base class for factory classes which instantiate {@code IFPainter}s and provide information
- * about them.
- */
-public abstract class AbstractIFPainterMaker {
-
- /**
- * Instantiates a new {@code IFPainter}.
- * @param userAgent the user agent
- * @return the newly instantiated painter
- */
- public abstract IFPainter makePainter(FOUserAgent userAgent);
-
- /**
- * @return Indicates whether this painter requires an OutputStream to work with.
- */
- public abstract boolean needsOutputStream();
-
- /**
- * @return an array of MIME types the painter supports.
- */
- public abstract String[] getSupportedMimeTypes();
-
- /**
- * Returns a configurator object that can be used to
- * configure the painter.
- * @param userAgent the user agent
- * @return a configurator object that can be used to configure the painter
- */
- public abstract IFPainterConfigurator getConfigurator(FOUserAgent userAgent);
-
- /**
- * Indicates whether a specific MIME type is supported by this painter.
- * @param mimeType the MIME type (ex. "application/pdf")
- * @return true if the MIME type is supported
- */
- public boolean isMimeTypeSupported(String mimeType) {
- String[] mimes = getSupportedMimeTypes();
- for (int i = 0; i < mimes.length; i++) {
- if (mimes[i].equals(mimeType)) {
- return true;
- }
- }
- return false;
- }
-}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.xml.sax.ContentHandler;
+
+import org.apache.fop.util.GenerationHelperContentHandler;
+
+/**
+ * Abstract base class for XML-writing {@code IFDocumentHandler} implementations.
+ */
+public abstract class AbstractXMLWritingIFDocumentHandler extends AbstractIFDocumentHandler {
+
+ /**
+ * Default SAXTransformerFactory that can be used by subclasses.
+ */
+ protected SAXTransformerFactory tFactory
+ = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+
+ /** Main SAX ContentHandler to receive the generated SAX events. */
+ protected GenerationHelperContentHandler handler;
+
+ /** {@inheritDoc} */
+ public void setResult(Result result) throws IFException {
+ if (result instanceof SAXResult) {
+ SAXResult saxResult = (SAXResult)result;
+ this.handler = new GenerationHelperContentHandler(
+ saxResult.getHandler(), getMainNamespace());
+ } else {
+ this.handler = new GenerationHelperContentHandler(
+ createContentHandler(result), getMainNamespace());
+ }
+ }
+
+ /**
+ * Returns the main namespace used for generated XML content.
+ * @return the main namespace
+ */
+ protected abstract String getMainNamespace();
+
+ /**
+ * Creates a ContentHandler for the given JAXP Result instance.
+ * @param result the JAXP Result instance
+ * @return the requested SAX ContentHandler
+ * @throws IFException if an error occurs setting up the output
+ */
+ protected ContentHandler createContentHandler(Result result) throws IFException {
+ try {
+ TransformerHandler tHandler = tFactory.newTransformerHandler();
+ Transformer transformer = tHandler.getTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ tHandler.setResult(result);
+ return tHandler;
+ } catch (TransformerConfigurationException tce) {
+ throw new IFException(
+ "Error while setting up the serializer for XML output", tce);
+ }
+ }
+
+}
+++ /dev/null
-/*
- * 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.intermediate;
-
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import org.apache.xmlgraphics.util.QName;
-
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.util.DecimalFormatCache;
-import org.apache.fop.util.XMLUtil;
-
-/**
- * Abstract base class for XML-writing IFPainter implementations.
- */
-public abstract class AbstractXMLWritingIFPainter extends AbstractIFPainter {
-
- private static final Attributes EMPTY_ATTS = new AttributesImpl();
-
- /**
- * Default SAXTransformerFactory that can be used by subclasses.
- */
- protected SAXTransformerFactory tFactory
- = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
-
- /** Main SAX ContentHandler to receive the generated SAX events. */
- protected ContentHandler handler;
-
- /** {@inheritDoc} */
- public void setResult(Result result) throws IFException {
- if (result instanceof SAXResult) {
- SAXResult saxResult = (SAXResult)result;
- this.handler = saxResult.getHandler();
- } else {
- this.handler = createContentHandler(result);
- }
- }
-
- /** {@inheritDoc} */
- public void setFontInfo(FontInfo fontInfo) {
- //nop, not used
- }
-
- /** {@inheritDoc} */
- public void setDefaultFontInfo() {
- //nop, not used
- }
-
- /**
- * Returns the main namespace used for generated XML content.
- * @return the main namespace
- */
- protected abstract String getMainNamespace();
-
- /**
- * Creates a ContentHandler for the given JAXP Result instance.
- * @param result the JAXP Result instance
- * @return the requested SAX ContentHandler
- * @throws IFException if an error occurs setting up the output
- */
- protected ContentHandler createContentHandler(Result result) throws IFException {
- try {
- TransformerHandler tHandler = tFactory.newTransformerHandler();
- Transformer transformer = tHandler.getTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- tHandler.setResult(result);
- return tHandler;
- } catch (TransformerConfigurationException tce) {
- throw new IFException(
- "Error while setting up the serializer for SVG output", tce);
- }
- }
-
- /* ---=== helper methods ===--- */
-
- private static String format(double value) {
- if (value == -0.0) {
- //Don't allow negative zero because of testing
- //See http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3
- value = 0.0;
- }
- return DecimalFormatCache.getDecimalFormat(6).format(value);
- }
-
- /**
- * Converts an {@code AffineTransform} instance to an SVG style transform method.
- * @param transform the transformation matrix
- * @param sb the StringBuffer to write the transform method to
- * @return the StringBuffer passed to this method
- */
- public static StringBuffer toString(AffineTransform transform, StringBuffer sb) {
- if (transform.isIdentity()) {
- return sb;
- }
- double[] matrix = new double[6];
- transform.getMatrix(matrix);
- if (matrix[0] == 1 && matrix[3] == 1 && matrix[1] == 0 && matrix[2] == 0) {
- sb.append("translate(");
- sb.append(format(matrix[4]));
- if (matrix[5] != 0) {
- sb.append(',').append(format(matrix[5]));
- }
- } else {
- sb.append("matrix(");
- for (int i = 0; i < 6; i++) {
- if (i > 0) {
- sb.append(',');
- }
- sb.append(format(matrix[i]));
- }
- }
- sb.append(')');
- return sb;
- }
-
- /**
- * Converts an {@code AffineTransform} array to an SVG style transform method sequence.
- * @param transforms the transformation matrix array
- * @param sb the StringBuffer to write the transform method sequence to
- * @return the StringBuffer passed to this method
- */
- public static StringBuffer toString(AffineTransform[] transforms, StringBuffer sb) {
- for (int i = 0, c = transforms.length; i < c; i++) {
- if (i > 0) {
- sb.append(' ');
- }
- toString(transforms[i], sb);
- }
- return sb;
- }
-
- /**
- * Converts an {@code AffineTransform} array to an SVG style transform method sequence.
- * @param transforms the transformation matrix array
- * @return the formatted array
- */
- public static String toString(AffineTransform[] transforms) {
- return toString(transforms, new StringBuffer()).toString();
- }
-
- /**
- * Converts an {@code AffineTransform} instance to an SVG style transform method.
- * @param transform the transformation matrix
- * @return the formatted array
- */
- public static String toString(AffineTransform transform) {
- return toString(transform, new StringBuffer()).toString();
- }
-
- /**
- * Convenience method to generate a startElement SAX event.
- * @param localName the local name of the element
- * @param atts the attributes
- * @throws SAXException if a SAX exception occurs
- */
- protected void startElement(String localName, Attributes atts) throws SAXException {
- handler.startElement(getMainNamespace(), localName, localName, atts);
- }
-
- /**
- * Convenience method to generate a startElement SAX event.
- * @param localName the local name of the element
- * @throws SAXException if a SAX exception occurs
- */
- protected void startElement(String localName) throws SAXException {
- handler.startElement(getMainNamespace(), localName, localName, EMPTY_ATTS);
- }
-
- /**
- * Convenience method to generate a endElement SAX event.
- * @param localName the local name of the element
- * @throws SAXException if a SAX exception occurs
- */
- protected void endElement(String localName) throws SAXException {
- handler.endElement(getMainNamespace(), localName, localName);
- }
-
- /**
- * Convenience method to generate an empty element.
- * @param localName the local name of the element
- * @param atts the attributes
- * @throws SAXException if a SAX exception occurs
- */
- protected void element(String localName, Attributes atts) throws SAXException {
- handler.startElement(getMainNamespace(), localName, localName, atts);
- handler.endElement(getMainNamespace(), localName, localName);
- }
-
- /**
- * Adds an attribute to a given {@code AttributesImpl} instance.
- * @param atts the attributes collection
- * @param attribute the attribute to add
- * @param value the attribute's CDATA value
- */
- protected void addAttribute(AttributesImpl atts, QName attribute, String value) {
- atts.addAttribute(attribute.getNamespaceURI(),
- attribute.getLocalName(), attribute.getQName(), XMLUtil.CDATA, value);
- }
-
- /**
- * Adds an attribute to a given {@code AttributesImpl} instance. The attribute will be
- * added in the default namespace.
- * @param atts the attributes collection
- * @param localName the local name of the attribute
- * @param value the attribute's CDATA value
- */
- protected void addAttribute(AttributesImpl atts, String localName, String value) {
- atts.addAttribute("", localName, localName, XMLUtil.CDATA, value);
- }
-
- /**
- * Converts an array of integer coordinates into a space-separated string.
- * @param coordinates the coordinates
- * @return the space-separated array of coordinates
- */
- protected String toString(int[] coordinates) {
- if (coordinates == null) {
- return "";
- }
- StringBuffer sb = new StringBuffer();
- for (int i = 0, c = coordinates.length; i < c; i++) {
- if (i > 0) {
- sb.append(' ');
- }
- sb.append(Integer.toString(coordinates[i]));
- }
- return sb.toString();
- }
-
- /**
- * Converts a rectangle into a space-separated string.
- * @param rect the rectangle
- * @return the space-separated array of coordinates
- */
- protected String toString(Rectangle rect) {
- if (rect == null) {
- return "";
- }
- StringBuffer sb = new StringBuffer();
- sb.append(rect.x).append(' ').append(rect.y).append(' ');
- sb.append(rect.width).append(' ').append(rect.height);
- return sb.toString();
- }
-
-}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import java.awt.Dimension;
+
+import javax.xml.transform.Result;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontInfo;
+
+/**
+ * Interface used to paint whole documents layouted by Apache FOP.
+ * <p>
+ * Call sequence:
+ * <p>
+ * <pre>
+ * startDocument()
+ * startDocumentHeader()
+ * [handleExtension()]*
+ * endDocumentHeader()
+ * [
+ * startPageSequence()
+ * [
+ * startPage()
+ * startPageHeader()
+ * [handleExtension()]*
+ * endPageHeader()
+ * startPageContent()
+ * (#box)+
+ * endPageContent()
+ * startPageTrailer()
+ * (addTarget())*
+ * endPageTrailer()
+ * endPage()
+ * ]*
+ * endPageSequence()
+ * ]*
+ * startDocumentTrailer()
+ * [handleExtension()]*
+ * endDocumentTrailer()
+ * endDocument()
+ *
+ * #box:
+ * startBox() (#pageContent)+ endBox() |
+ * startViewport() (#pageContext)+ endViewport()
+ *
+ * #pageContent:
+ * (
+ * setFont() |
+ * drawText() |
+ * drawRect() |
+ * drawImage() |
+ * TODO etc. etc. |
+ * handleExtensionObject()
+ * )
+ * </pre>
+ */
+public interface IFDocumentHandler {
+
+ /**
+ * Set the user agent.
+ * @param userAgent The user agent
+ */
+ void setUserAgent(FOUserAgent userAgent);
+
+ /**
+ * Sets the JAXP Result object to receive the generated content.
+ * @param result the JAXP Result object to receive the generated content
+ * @throws IFException if an error occurs setting up the output
+ */
+ void setResult(Result result) throws IFException;
+
+ /**
+ * Sets the font set to work with.
+ * @param fontInfo the font info object
+ */
+ void setFontInfo(FontInfo fontInfo);
+
+ /**
+ * Returns the font set to work with.
+ * @return the font info object
+ */
+ FontInfo getFontInfo();
+
+ /**
+ * Sets the default font set (with no custom configuration).
+ * @param fontInfo the font info object to populate
+ */
+ void setDefaultFontInfo(FontInfo fontInfo);
+
+ /**
+ * Returns the configurator for this document handler, if any.
+ * @return the configurator or null if there's no configurator
+ */
+ IFDocumentHandlerConfigurator getConfigurator();
+
+ /**
+ * Indicates whether the painter supports to handle the pages in mixed order rather than
+ * ascending order.
+ * @return true if out-of-order handling is supported
+ */
+ boolean supportsPagesOutOfOrder();
+
+ /**
+ * Returns the MIME type of the output format that is generated by this implementation.
+ * @return the MIME type
+ */
+ String getMimeType();
+
+ /**
+ * Indicates the start of a document. This method may only be called once before any other
+ * event method.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startDocument() throws IFException;
+
+ /**
+ * Indicates the end of a document. This method may only be called once after the whole
+ * document has been handled. Implementations can release resources (close streams). It is
+ * an error to call any event method after this method.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endDocument() throws IFException;
+
+ /**
+ * Indicates the start of the document header. This method is called right after the
+ * {@code #startDocument()} method. Extensions sent to this painter between
+ * {@code #startDocumentHeader()} and {@code #endDocumentHeader()} apply to the document as
+ * a whole (like document metadata).
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startDocumentHeader() throws IFException;
+
+ /**
+ * Indicates the end of the document header. This method is called before the first
+ * page sequence.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endDocumentHeader() throws IFException;
+
+ /**
+ * Indicates the start of the document trailer. This method is called after the last
+ * page sequence. Extensions sent to the painter between
+ * {@code #startDocumentTrailer()} and {@code #endDocumentTrailer()} apply to the document as
+ * a whole and is used for document-level content that is only known after all pages have
+ * been rendered (like named destinations or the bookmark tree).
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startDocumentTrailer() throws IFException;
+
+ /**
+ * Indicates the end of the document trailer. This method is called right before the
+ * {@code #endDocument()} method.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endDocumentTrailer() throws IFException;
+
+ /**
+ * Indicates the start of a new page sequence.
+ * @param id the page sequence's identifier (or null if none is available)
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startPageSequence(String id) throws IFException;
+ /**
+ * Indicates the end of a page sequence.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endPageSequence() throws IFException;
+
+ /**
+ * Indicates the start of a new page.
+ * @param index the index of the page (0-based)
+ * @param name the page name (usually the formatted page number)
+ * @param size the size of the page (equivalent to the MediaBox in PDF)
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startPage(int index, String name, Dimension size) throws IFException;
+
+ /**
+ * Indicates the end of a page
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endPage() throws IFException;
+
+ /**
+ * Indicates the start of the page header.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startPageHeader() throws IFException;
+
+ /**
+ * Indicates the end of the page header.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endPageHeader() throws IFException;
+
+ /**
+ * Indicates the start of the page content. The method returns an {@code IFPainter} interface
+ * which is used to paint the page contents.
+ * @throws IFException if an error occurs while handling this event
+ * @return the IFPainter for the page content
+ */
+ IFPainter startPageContent() throws IFException;
+
+ /**
+ * Indicates the end of the page content. Calls to the {@code IFPainter} returned by the
+ * respective {@code #startPageContent()} method are illegal.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endPageContent() throws IFException;
+
+ /**
+ * Indicates the start of the page trailer. The page trailer is used for writing down page
+ * elements which are only know after handling the page itself (like PDF targets).
+ * @throws IFException if an error occurs while handling this event
+ */
+ void startPageTrailer() throws IFException;
+
+ /**
+ * Indicates the end of the page trailer.
+ * @throws IFException if an error occurs while handling this event
+ */
+ void endPageTrailer() throws IFException;
+
+ /**
+ * Handles an extension object. This can be a DOM document or any arbitrary
+ * object. If an implementation doesn't know how to handle a particular extension it is simply
+ * ignored.
+ * @param extension the extension object
+ * @throws IFException if an error occurs while handling this event
+ */
+ void handleExtensionObject(Object extension) throws IFException;
+
+ //TODO Prototype the following:
+ //ContentHandler handleExtension() throws Exception
+}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fonts.FontInfo;
+
+/**
+ * This interface is implemented by classes that configure an {@code IFDocumentHandler} instance.
+ */
+public interface IFDocumentHandlerConfigurator {
+
+ /**
+ * Configures a intermediate format document handler.
+ * @param documentHandler the document handler instance
+ * @throws FOPException if an error occurs while configuring the object
+ */
+ void configure(IFDocumentHandler documentHandler) throws FOPException;
+
+ /**
+ * Sets up the {@code FontInfo} object for the IFDocumentHandler.
+ * @param documentHandler the document handler instance
+ * @param fontInfo the font info object to set up
+ * @throws FOPException if an error occurs while configuring the object
+ */
+ void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo) throws FOPException;
+
+}
/** {@inheritDoc} */
public String toString() {
StringBuffer sb = new StringBuffer("group: ");
- AbstractXMLWritingIFPainter.toString(getTransforms(), sb);
+ IFUtil.toString(getTransforms(), sb);
return sb.toString();
}
/** {@inheritDoc} */
public String toString() {
StringBuffer sb = new StringBuffer("viewport: ");
- AbstractXMLWritingIFPainter.toString(getTransforms(), sb);
+ IFUtil.toString(getTransforms(), sb);
sb.append(", ").append(getSize());
if (getClipRect() != null) {
sb.append(", ").append(getClipRect());
import java.awt.geom.AffineTransform;
import java.util.Map;
-import javax.xml.transform.Result;
-
import org.w3c.dom.Document;
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fonts.FontInfo;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
*/
public interface IFPainter {
- /**
- * Set the user agent.
- * @param userAgent The user agent
- */
- void setUserAgent(FOUserAgent userAgent);
-
- /**
- * Sets the JAXP Result object to receive the generated content.
- * @param result the JAXP Result object to receive the generated content
- * @throws IFException if an error occurs setting up the output
- */
- void setResult(Result result) throws IFException;
-
- /**
- * Sets the font set to work with.
- * @param fontInfo the font info object
- */
- void setFontInfo(FontInfo fontInfo);
-
- /**
- * Sets the default font set (with no custom configuration).
- */
- void setDefaultFontInfo();
-
- /**
- * Indicates whether the painter supports to handle the pages in mixed order rather than
- * ascending order.
- * @return true if out-of-order handling is supported
- */
- boolean supportsPagesOutOfOrder();
-
- /**
- * Returns the MIME type of the output format that is generated by this implementation.
- * @return the MIME type
- */
- String getMimeType();
-
- /**
- * Indicates the start of a document. This method may only be called once before any other
- * event method.
- * @throws IFException if an error occurs while handling this event
- */
- void startDocument() throws IFException;
-
- /**
- * Indicates the end of a document. This method may only be called once after the whole
- * document has been handled. Implementations can release resources (close streams). It is
- * an error to call any event method after this method.
- * @throws IFException if an error occurs while handling this event
- */
- void endDocument() throws IFException;
-
- /**
- * Indicates the start of the document header. This method is called right after the
- * {@code #startDocument()} method. Extensions sent to this painter between
- * {@code #startDocumentHeader()} and {@code #endDocumentHeader()} apply to the document as
- * a whole (like document metadata).
- * @throws IFException if an error occurs while handling this event
- */
- void startDocumentHeader() throws IFException;
-
- /**
- * Indicates the end of the document header. This method is called before the first
- * page sequence.
- * @throws IFException if an error occurs while handling this event
- */
- void endDocumentHeader() throws IFException;
-
- /**
- * Indicates the start of the document trailer. This method is called after the last
- * page sequence. Extensions sent to the painter between
- * {@code #startDocumentTrailer()} and {@code #endDocumentTrailer()} apply to the document as
- * a whole and is used for document-level content that is only known after all pages have
- * been rendered (like named destinations or the bookmark tree).
- * @throws IFException if an error occurs while handling this event
- */
- void startDocumentTrailer() throws IFException;
-
- /**
- * Indicates the end of the document trailer. This method is called right before the
- * {@code #endDocument()} method.
- * @throws IFException if an error occurs while handling this event
- */
- void endDocumentTrailer() throws IFException;
-
- /**
- * Indicates the start of a new page sequence.
- * @param id the page sequence's identifier (or null if none is available)
- * @throws IFException if an error occurs while handling this event
- */
- void startPageSequence(String id) throws IFException;
- /**
- * Indicates the end of a page sequence.
- * @throws IFException if an error occurs while handling this event
- */
- void endPageSequence() throws IFException;
-
- /**
- * Indicates the start of a new page.
- * @param index the index of the page (0-based)
- * @param name the page name (usually the formatted page number)
- * @param size the size of the page (equivalent to the MediaBox in PDF)
- * @throws IFException if an error occurs while handling this event
- */
- void startPage(int index, String name, Dimension size) throws IFException;
-
- /**
- * Indicates the end of a page
- * @throws IFException if an error occurs while handling this event
- */
- void endPage() throws IFException;
-
- /**
- * Indicates the start of the page header.
- * @throws IFException if an error occurs while handling this event
- */
- void startPageHeader() throws IFException;
-
- /**
- * Indicates the end of the page header.
- * @throws IFException if an error occurs while handling this event
- */
- void endPageHeader() throws IFException;
-
- /**
- * Indicates the start of the page content.
- * @throws IFException if an error occurs while handling this event
- */
- void startPageContent() throws IFException;
-
- /**
- * Indicates the end of the page content.
- * @throws IFException if an error occurs while handling this event
- */
- void endPageContent() throws IFException;
-
- /**
- * Indicates the start of the page trailer. The page trailer is used for writing down page
- * elements which are only know after handling the page itself (like PDF targets).
- * @throws IFException if an error occurs while handling this event
- */
- void startPageTrailer() throws IFException;
-
- /**
- * Indicates the end of the page trailer.
- * @throws IFException if an error occurs while handling this event
- */
- void endPageTrailer() throws IFException;
-
void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect) throws IFException;
void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) throws IFException;
//For transform, Batik's org.apache.batik.parser.TransformListHandler/Parser can be used
//etc. etc.
- /**
- * Handles an extension object. This can be a DOM document or any arbitrary
- * object. If an implementation doesn't know how to handle a particular extension it is simply
- * ignored.
- * @param extension the extension object
- * @throws IFException if an error occurs while handling this event
- */
- void handleExtensionObject(Object extension) throws IFException;
-
- //TODO Prototype the following:
- //ContentHandler handleExtension() throws Exception
}
+++ /dev/null
-/*
- * 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.intermediate;
-
-import org.apache.fop.apps.FOPException;
-
-/**
- * This interface is implemented by classes that configure an {@code IFPainter} instance.
- */
-public interface IFPainterConfigurator {
-
- /**
- * Configures a painter.
- * @param painter the painter instance
- * @throws FOPException if an error occurs while configuring the object
- */
- void configure(IFPainter painter) throws FOPException;
-
- /**
- * Sets up the {@code FontInfo} object for the IFPainter.
- * @param painter the painter instance
- * @throws FOPException if an error occurs while configuring the object
- */
- void setupFontInfo(IFPainter painter) throws FOPException;
-}
/**
* Parses an intermediate file and paints it.
* @param src the Source instance pointing to the intermediate file
- * @param painter the intermediate format painter used to process the IF events
+ * @param documentHandler the intermediate format document handler used to process the IF events
* @param userAgent the user agent
* @throws TransformerException if an error occurs while parsing the area tree XML
*/
- public void parse(Source src, IFPainter painter, FOUserAgent userAgent)
+ public void parse(Source src, IFDocumentHandler documentHandler, FOUserAgent userAgent)
throws TransformerException {
Transformer transformer = tFactory.newTransformer();
transformer.setErrorListener(new DefaultErrorListener(log));
- SAXResult res = new SAXResult(getContentHandler(painter, userAgent));
+ SAXResult res = new SAXResult(getContentHandler(documentHandler, userAgent));
transformer.transform(src, res);
}
/**
* Creates a new ContentHandler instance that you can send the area tree XML to. The parsed
* pages are added to the AreaTreeModel instance you pass in as a parameter.
- * @param painter the intermediate format painter used to process the IF events
+ * @param documentHandler the intermediate format document handler used to process the IF events
* @param userAgent the user agent
* @return the ContentHandler instance to receive the SAX stream from the area tree XML
*/
- public ContentHandler getContentHandler(IFPainter painter, FOUserAgent userAgent) {
+ public ContentHandler getContentHandler(IFDocumentHandler documentHandler,
+ FOUserAgent userAgent) {
ElementMappingRegistry elementMappingRegistry
= userAgent.getFactory().getElementMappingRegistry();
- return new Handler(painter, userAgent, elementMappingRegistry);
+ return new Handler(documentHandler, userAgent, elementMappingRegistry);
}
private static class Handler extends DefaultHandler {
private Map elementHandlers = new java.util.HashMap();
+ private IFDocumentHandler documentHandler;
private IFPainter painter;
private FOUserAgent userAgent;
private ElementMappingRegistry elementMappingRegistry;
private boolean inForeignObject;
private Document foreignObject;
- public Handler(IFPainter painter, FOUserAgent userAgent,
+ public Handler(IFDocumentHandler documentHandler, FOUserAgent userAgent,
ElementMappingRegistry elementMappingRegistry) {
- this.painter = painter;
+ this.documentHandler = documentHandler;
this.userAgent = userAgent;
this.elementMappingRegistry = elementMappingRegistry;
elementHandlers.put(EL_DOCUMENT, new DocumentHandler());
private class DocumentHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startDocument();
+ documentHandler.startDocument();
}
public void endElement() throws IFException {
- painter.endDocument();
+ documentHandler.endDocument();
}
}
private class DocumentHeaderHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startDocumentHeader();
+ documentHandler.startDocumentHeader();
}
public void endElement() throws IFException {
- painter.endDocumentHeader();
+ documentHandler.endDocumentHeader();
}
}
private class DocumentTrailerHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startDocumentTrailer();
+ documentHandler.startDocumentTrailer();
}
public void endElement() throws IFException {
- painter.endDocumentTrailer();
+ documentHandler.endDocumentTrailer();
}
}
public void startElement(Attributes attributes) throws IFException {
String id = attributes.getValue("id");
- painter.startPageSequence(id);
+ documentHandler.startPageSequence(id);
}
public void endElement() throws IFException {
- painter.endPageSequence();
+ documentHandler.endPageSequence();
}
}
String name = attributes.getValue("name");
int width = Integer.parseInt(attributes.getValue("width"));
int height = Integer.parseInt(attributes.getValue("height"));
- painter.startPage(index, name, new Dimension(width, height));
+ documentHandler.startPage(index, name, new Dimension(width, height));
}
public void endElement() throws IFException {
- painter.endPage();
+ documentHandler.endPage();
}
}
private class PageHeaderHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startPageHeader();
+ documentHandler.startPageHeader();
}
public void endElement() throws IFException {
- painter.endPageHeader();
+ documentHandler.endPageHeader();
}
}
private class PageContentHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startPageContent();
+ painter = documentHandler.startPageContent();
}
public void endElement() throws IFException {
- painter.endPageContent();
+ painter = null;
+ documentHandler.endPageContent();
}
}
private class PageTrailerHandler extends AbstractElementHandler {
public void startElement(Attributes attributes) throws IFException {
- painter.startPageTrailer();
+ documentHandler.startPageTrailer();
}
public void endElement() throws IFException {
- painter.endPageTrailer();
+ documentHandler.endPageTrailer();
}
}
// ====================================================================
-
- private void assertObjectOfClass(Object obj, Class clazz) {
- if (!clazz.isInstance(obj)) {
- throw new IllegalStateException("Object is not an instance of "
- + clazz.getName() + " but of " + obj.getClass().getName());
- }
- }
-
/**
* Handles objects created by "sub-parsers" that implement the ObjectSource interface.
* An example of object handled here are ExtensionAttachments.
*/
protected void handleExternallyGeneratedObject(Object obj) throws SAXException {
try {
- painter.handleExtensionObject(obj);
+ documentHandler.handleExtensionObject(obj);
} catch (IFException ife) {
handleIFException(ife);
}
/** XML MIME type */
public static final String IF_MIME_TYPE = MimeConstants.MIME_FOP_IF;
+ private IFDocumentHandler documentHandler;
private IFPainter painter;
/** If not null, the XMLRenderer will mimic another renderer by using its font setup. */
}
/**
- * Sets the {@code IFPainter} to be used by the {@code IFRenderer}.
- * @param painter the {@code IFPainter}
+ * Sets the {@code IFDocumentHandler} to be used by the {@code IFRenderer}.
+ * @param documentHandler the {@code IFDocumentHandler}
*/
- public void setPainter(IFPainter painter) {
- this.painter = painter;
- }
-
- /**
- * Call this method to make the XMLRenderer mimic a different renderer by using its font
- * setup. This is useful when working with the intermediate format parser.
- * @param renderer the renderer to mimic
- */
- public void mimicRenderer(Renderer renderer) {
- this.mimic = renderer;
+ public void setDocumentHandler(IFDocumentHandler documentHandler) {
+ this.documentHandler = documentHandler;
}
/** {@inheritDoc} */
- public void setupFontInfo(FontInfo inFontInfo) {
- if (mimic != null) {
- mimic.setupFontInfo(inFontInfo);
- this.fontInfo = inFontInfo;
+ public void setupFontInfo(FontInfo inFontInfo) throws FOPException {
+ if (this.documentHandler == null) {
+ this.documentHandler = createDefaultDocumentHandler();
+ }
+ IFDocumentHandlerConfigurator configurator = this.documentHandler.getConfigurator();
+ if (configurator != null) {
+ configurator.setupFontInfo(documentHandler, inFontInfo);
} else {
- super.setupFontInfo(inFontInfo);
+ this.documentHandler.setDefaultFontInfo(inFontInfo);
}
+ this.fontInfo = inFontInfo;
}
private void handleIFException(IFException ife) {
}
/**
- * Creates a default {@code IFPainter} when none has been set.
- * @return the default IFPainter
+ * Creates a default {@code IFDocumentHandler} when none has been set.
+ * @return the default IFDocumentHandler
*/
- protected IFPainter createDefaultPainter() {
- return new IFSerializer();
+ protected IFDocumentHandler createDefaultDocumentHandler() {
+ IFSerializer serializer = new IFSerializer();
+ serializer.setUserAgent(getUserAgent());
+ return serializer;
}
/** {@inheritDoc} */
result.setSystemId(
getUserAgent().getOutputFile().toURI().toURL().toExternalForm());
}
- if (this.painter == null) {
- this.painter = new IFSerializer();
- this.painter.setUserAgent(getUserAgent());
+ if (this.documentHandler == null) {
+ this.documentHandler = createDefaultDocumentHandler();
}
- this.painter.setFontInfo(fontInfo);
- this.painter.setResult(result);
+ this.documentHandler.setResult(result);
}
super.startRenderer(null);
if (log.isDebugEnabled()) {
- log.debug("Rendering areas via painter ("
- + this.painter.getClass().getName() + ")...");
+ log.debug("Rendering areas via IF document handler ("
+ + this.documentHandler.getClass().getName() + ")...");
}
- painter.startDocument();
- painter.startDocumentHeader();
+ documentHandler.startDocument();
+ documentHandler.startDocumentHeader();
} catch (IFException e) {
handleIFExceptionWithIOException(e);
}
public void stopRenderer() throws IOException {
try {
if (this.inPageSequence) {
- painter.endPageSequence();
+ documentHandler.endPageSequence();
this.inPageSequence = false;
}
- painter.startDocumentTrailer();
+ documentHandler.startDocumentTrailer();
finishOpenGoTos();
if (this.bookmarkTree != null) {
- painter.handleExtensionObject(this.bookmarkTree);
+ documentHandler.handleExtensionObject(this.bookmarkTree);
}
- painter.endDocumentTrailer();
- painter.endDocument();
+ documentHandler.endDocumentTrailer();
+ documentHandler.endDocument();
} catch (IFException e) {
handleIFExceptionWithIOException(e);
}
GoToXYAction action = getGoToActionForID(targetID, pv.getPageIndex());
NamedDestination namedDestination = new NamedDestination(targetID, action);
try {
- painter.handleExtensionObject(namedDestination);
+ documentHandler.handleExtensionObject(namedDestination);
} catch (IFException ife) {
handleIFException(ife);
}
public void startPageSequence(PageSequence pageSequence) {
try {
if (this.inPageSequence) {
- painter.endPageSequence();
+ documentHandler.endPageSequence();
} else {
if (this.documentMetadata == null) {
this.documentMetadata = createDefaultDocumentMetadata();
}
- painter.handleExtensionObject(this.documentMetadata);
- painter.endDocumentHeader();
+ documentHandler.handleExtensionObject(this.documentMetadata);
+ documentHandler.endDocumentHeader();
this.inPageSequence = true;
}
- painter.startPageSequence(null);
+ documentHandler.startPageSequence(null);
} catch (IFException e) {
handleIFException(e);
}
Dimension dim = new Dimension(
(int)Math.ceil(viewArea.getWidth()),
(int)Math.ceil(viewArea.getHeight()));
- painter.startPage(page.getPageIndex(), page.getPageNumberString(), dim);
- painter.startPageHeader();
+ documentHandler.startPage(page.getPageIndex(), page.getPageNumberString(), dim);
+ documentHandler.startPageHeader();
//TODO Handle page header
- painter.endPageHeader();
- painter.startPageContent();
+ documentHandler.endPageHeader();
+ this.painter = documentHandler.startPageContent();
super.renderPage(page);
- painter.endPageContent();
- painter.startPageTrailer();
+ this.painter = null;
+ documentHandler.endPageContent();
+ documentHandler.startPageTrailer();
//TODO Handle page trailer
- painter.endPageTrailer();
- painter.endPage();
+ documentHandler.endPageTrailer();
+ documentHandler.endPage();
} catch (IFException e) {
handleIFException(e);
}
import org.apache.xmlgraphics.util.QName;
import org.apache.xmlgraphics.util.XMLizable;
+import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
/**
* IFPainter implementation that serializes the intermediate format to XML.
*/
-public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConstants {
+public class IFSerializer extends AbstractXMLWritingIFDocumentHandler implements IFConstants, IFPainter {
+
+ private IFDocumentHandler mimicHandler;
/**
* Default constructor.
return MIME_TYPE;
}
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ if (this.mimicHandler != null) {
+ return getMimickedDocumentHandler().getConfigurator();
+ } else {
+ return new IFSerializerConfiguration(getUserAgent());
+ }
+ }
+
+ public void mimicDocumentHandler(IFDocumentHandler targetHandler) {
+ this.mimicHandler = targetHandler;
+ }
+
+ public IFDocumentHandler getMimickedDocumentHandler() {
+ return this.mimicHandler;
+ }
+
+ /** {@inheritDoc} */
+ public FontInfo getFontInfo() {
+ if (this.mimicHandler != null) {
+ return this.mimicHandler.getFontInfo();
+ } else {
+ return null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void setFontInfo(FontInfo fontInfo) {
+ //nop, not used
+ }
+
+ /** {@inheritDoc} */
+ public void setDefaultFontInfo(FontInfo fontInfo) {
+ //nop, not used
+ }
+
/** {@inheritDoc} */
public void startDocument() throws IFException {
try {
handler.startDocument();
handler.startPrefixMapping("", NAMESPACE);
handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE);
- startElement(EL_DOCUMENT);
+ handler.startElement(EL_DOCUMENT);
} catch (SAXException e) {
throw new IFException("SAX error in startDocument()", e);
}
/** {@inheritDoc} */
public void startDocumentHeader() throws IFException {
try {
- startElement(EL_HEADER);
+ handler.startElement(EL_HEADER);
} catch (SAXException e) {
throw new IFException("SAX error in startDocumentHeader()", e);
}
/** {@inheritDoc} */
public void endDocumentHeader() throws IFException {
try {
- endElement(EL_HEADER);
+ handler.endElement(EL_HEADER);
} catch (SAXException e) {
throw new IFException("SAX error in startDocumentHeader()", e);
}
/** {@inheritDoc} */
public void startDocumentTrailer() throws IFException {
try {
- startElement(EL_TRAILER);
+ handler.startElement(EL_TRAILER);
} catch (SAXException e) {
throw new IFException("SAX error in startDocumentTrailer()", e);
}
/** {@inheritDoc} */
public void endDocumentTrailer() throws IFException {
try {
- endElement(EL_TRAILER);
+ handler.endElement(EL_TRAILER);
} catch (SAXException e) {
- throw new IFException("SAX error in startDocumentTrailer()", e);
+ throw new IFException("SAX error in endDocumentTrailer()", e);
}
}
/** {@inheritDoc} */
public void endDocument() throws IFException {
try {
- endElement(EL_DOCUMENT);
+ handler.endElement(EL_DOCUMENT);
handler.endDocument();
} catch (SAXException e) {
throw new IFException("SAX error in endDocument()", e);
if (id != null) {
atts.addAttribute(XML_NAMESPACE, "id", "xml:id", XMLUtil.CDATA, id);
}
- startElement(EL_PAGE_SEQUENCE, atts);
+ handler.startElement(EL_PAGE_SEQUENCE, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startPageSequence()", e);
}
/** {@inheritDoc} */
public void endPageSequence() throws IFException {
try {
- endElement(EL_PAGE_SEQUENCE);
+ handler.endElement(EL_PAGE_SEQUENCE);
} catch (SAXException e) {
throw new IFException("SAX error in endPageSequence()", e);
}
addAttribute(atts, "name", name);
addAttribute(atts, "width", Integer.toString(size.width));
addAttribute(atts, "height", Integer.toString(size.height));
- startElement(EL_PAGE, atts);
+ handler.startElement(EL_PAGE, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startPage()", e);
}
/** {@inheritDoc} */
public void startPageHeader() throws IFException {
try {
- startElement(EL_PAGE_HEADER);
+ handler.startElement(EL_PAGE_HEADER);
} catch (SAXException e) {
throw new IFException("SAX error in startPageHeader()", e);
}
/** {@inheritDoc} */
public void endPageHeader() throws IFException {
try {
- endElement(EL_PAGE_HEADER);
+ handler.endElement(EL_PAGE_HEADER);
} catch (SAXException e) {
throw new IFException("SAX error in endPageHeader()", e);
}
}
/** {@inheritDoc} */
- public void startPageContent() throws IFException {
+ public IFPainter startPageContent() throws IFException {
try {
- startElement(EL_PAGE_CONTENT);
+ handler.startElement(EL_PAGE_CONTENT);
+ return this;
} catch (SAXException e) {
throw new IFException("SAX error in startPageContent()", e);
}
/** {@inheritDoc} */
public void endPageContent() throws IFException {
try {
- endElement(EL_PAGE_CONTENT);
+ handler.endElement(EL_PAGE_CONTENT);
} catch (SAXException e) {
throw new IFException("SAX error in endPageContent()", e);
}
/** {@inheritDoc} */
public void startPageTrailer() throws IFException {
try {
- startElement(EL_PAGE_TRAILER);
+ handler.startElement(EL_PAGE_TRAILER);
} catch (SAXException e) {
throw new IFException("SAX error in startPageTrailer()", e);
}
/** {@inheritDoc} */
public void endPageTrailer() throws IFException {
try {
- endElement(EL_PAGE_TRAILER);
+ handler.endElement(EL_PAGE_TRAILER);
} catch (SAXException e) {
throw new IFException("SAX error in endPageTrailer()", e);
}
/** {@inheritDoc} */
public void endPage() throws IFException {
try {
- endElement(EL_PAGE);
+ handler.endElement(EL_PAGE);
} catch (SAXException e) {
throw new IFException("SAX error in endPage()", e);
}
}
+ //---=== IFPainter ===---
+
/** {@inheritDoc} */
public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
throws IFException {
- startViewport(toString(transform), size, clipRect);
+ startViewport(IFUtil.toString(transform), size, clipRect);
}
/** {@inheritDoc} */
public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect)
throws IFException {
- startViewport(toString(transforms), size, clipRect);
+ startViewport(IFUtil.toString(transforms), size, clipRect);
}
private void startViewport(String transform, Dimension size, Rectangle clipRect)
addAttribute(atts, "width", Integer.toString(size.width));
addAttribute(atts, "height", Integer.toString(size.height));
if (clipRect != null) {
- addAttribute(atts, "clip-rect", toString(clipRect));
+ addAttribute(atts, "clip-rect", IFUtil.toString(clipRect));
}
- startElement(EL_VIEWPORT, atts);
+ handler.startElement(EL_VIEWPORT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startViewport()", e);
}
/** {@inheritDoc} */
public void endViewport() throws IFException {
try {
- endElement(EL_VIEWPORT);
+ handler.endElement(EL_VIEWPORT);
} catch (SAXException e) {
throw new IFException("SAX error in endViewport()", e);
}
/** {@inheritDoc} */
public void startGroup(AffineTransform[] transforms) throws IFException {
- startGroup(toString(transforms));
+ startGroup(IFUtil.toString(transforms));
}
/** {@inheritDoc} */
public void startGroup(AffineTransform transform) throws IFException {
- startGroup(toString(transform));
+ startGroup(IFUtil.toString(transform));
}
private void startGroup(String transform) throws IFException {
if (transform != null && transform.length() > 0) {
addAttribute(atts, "transform", transform);
}
- startElement(EL_GROUP, atts);
+ handler.startElement(EL_GROUP, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startGroup()", e);
}
/** {@inheritDoc} */
public void endGroup() throws IFException {
try {
- endElement(EL_GROUP);
+ handler.endElement(EL_GROUP);
} catch (SAXException e) {
throw new IFException("SAX error in endGroup()", e);
}
addAttribute(atts, (QName)entry.getKey(), entry.getValue().toString());
}
}
- element(EL_IMAGE, atts);
+ handler.element(EL_IMAGE, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startGroup()", e);
}
addAttribute(atts, (QName)entry.getKey(), entry.getValue().toString());
}
}
- startElement(EL_IMAGE, atts);
+ handler.startElement(EL_IMAGE, atts);
new DOM2SAX(handler).writeDocument(doc, true);
- endElement(EL_IMAGE);
+ handler.endElement(EL_IMAGE);
} catch (SAXException e) {
throw new IFException("SAX error in startGroup()", e);
}
addAttribute(atts, "y", Integer.toString(rect.y));
addAttribute(atts, "width", Integer.toString(rect.width));
addAttribute(atts, "height", Integer.toString(rect.height));
- element(EL_CLIP_RECT, atts);
+ handler.element(EL_CLIP_RECT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in clipRect()", e);
}
addAttribute(atts, "width", Integer.toString(rect.width));
addAttribute(atts, "height", Integer.toString(rect.height));
addAttribute(atts, "fill", toString(fill));
- element(EL_RECT, atts);
+ handler.element(EL_RECT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in fillRect()", e);
}
if (end != null) {
addAttribute(atts, "end", end.toString());
}
- element(EL_BORDER_RECT, atts);
+ handler.element(EL_BORDER_RECT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in drawBorderRect()", e);
}
addAttribute(atts, "stroke-width", Integer.toString(width));
addAttribute(atts, "color", Integer.toString(width));
addAttribute(atts, "style", style.getName());
- element(EL_LINE, atts);
+ handler.element(EL_LINE, atts);
} catch (SAXException e) {
throw new IFException("SAX error in drawLine()", e);
}
addAttribute(atts, "x", Integer.toString(x));
addAttribute(atts, "y", Integer.toString(y));
if (dx != null) {
- addAttribute(atts, "dx", toString(dx));
+ addAttribute(atts, "dx", IFUtil.toString(dx));
}
if (dy != null) {
- addAttribute(atts, "dy", toString(dy));
+ addAttribute(atts, "dy", IFUtil.toString(dy));
}
- startElement(EL_TEXT, atts);
+ handler.startElement(EL_TEXT, atts);
char[] chars = text.toCharArray();
handler.characters(chars, 0, chars.length);
- endElement(EL_TEXT);
+ handler.endElement(EL_TEXT);
} catch (SAXException e) {
throw new IFException("SAX error in setFont()", e);
}
if (color != null) {
addAttribute(atts, "color", toString(color));
}
- element(EL_FONT, atts);
+ handler.element(EL_FONT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in setFont()", e);
}
throw new IllegalStateException("Should never be called!");
}
+ private void addAttribute(AttributesImpl atts,
+ org.apache.xmlgraphics.util.QName attribute, String value) {
+ XMLUtil.addAttribute(atts, attribute, value);
+ }
+
+ private void addAttribute(AttributesImpl atts, String localName, String value) {
+ XMLUtil.addAttribute(atts, localName, value);
+ }
+
}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.CustomFontCollection;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontEventAdapter;
+import org.apache.fop.fonts.FontEventListener;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.render.DefaultFontResolver;
+import org.apache.fop.render.PrintRendererConfigurator;
+
+/**
+ * Configurator for the IFSerializer.
+ */
+public class IFSerializerConfiguration extends PrintRendererConfigurator
+ implements IFDocumentHandlerConfigurator {
+
+ /**
+ * Default constructor
+ * @param userAgent user agent
+ */
+ public IFSerializerConfiguration(FOUserAgent userAgent) {
+ super(userAgent);
+ }
+
+ /** {@inheritDoc} */
+ public void configure(IFDocumentHandler documentHandler) throws FOPException {
+ //nothing to do here
+ }
+
+ /** {@inheritDoc} */
+ public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
+ throws FOPException {
+ FontManager fontManager = userAgent.getFactory().getFontManager();
+ List fontCollections = new java.util.ArrayList();
+ fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));
+
+ Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
+ if (cfg != null) {
+ FontResolver fontResolver = new DefaultFontResolver(userAgent);
+ FontEventListener listener = new FontEventAdapter(
+ userAgent.getEventBroadcaster());
+ List fontList = buildFontList(cfg, fontResolver, listener);
+ fontCollections.add(new CustomFontCollection(fontResolver, fontList));
+ }
+
+ fontManager.setup(fontInfo,
+ (FontCollection[])fontCollections.toArray(
+ new FontCollection[fontCollections.size()]));
+ documentHandler.setFontInfo(fontInfo);
+ }
+
+}
--- /dev/null
+/*
+ * 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.intermediate;
+
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+
+import org.apache.fop.util.DecimalFormatCache;
+
+/**
+ * Utility functions for the intermediate format.
+ */
+public class IFUtil {
+
+ private static String format(double value) {
+ if (value == -0.0) {
+ //Don't allow negative zero because of testing
+ //See http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3
+ value = 0.0;
+ }
+ return DecimalFormatCache.getDecimalFormat(6).format(value);
+ }
+
+ /**
+ * Converts an {@code AffineTransform} instance to an SVG style transform method.
+ * @param transform the transformation matrix
+ * @param sb the StringBuffer to write the transform method to
+ * @return the StringBuffer passed to this method
+ */
+ public static StringBuffer toString(AffineTransform transform, StringBuffer sb) {
+ if (transform.isIdentity()) {
+ return sb;
+ }
+ double[] matrix = new double[6];
+ transform.getMatrix(matrix);
+ if (matrix[0] == 1 && matrix[3] == 1 && matrix[1] == 0 && matrix[2] == 0) {
+ sb.append("translate(");
+ sb.append(format(matrix[4]));
+ if (matrix[5] != 0) {
+ sb.append(',').append(format(matrix[5]));
+ }
+ } else {
+ sb.append("matrix(");
+ for (int i = 0; i < 6; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(format(matrix[i]));
+ }
+ }
+ sb.append(')');
+ return sb;
+ }
+
+ /**
+ * Converts an {@code AffineTransform} array to an SVG style transform method sequence.
+ * @param transforms the transformation matrix array
+ * @param sb the StringBuffer to write the transform method sequence to
+ * @return the StringBuffer passed to this method
+ */
+ public static StringBuffer toString(AffineTransform[] transforms, StringBuffer sb) {
+ for (int i = 0, c = transforms.length; i < c; i++) {
+ if (i > 0) {
+ sb.append(' ');
+ }
+ toString(transforms[i], sb);
+ }
+ return sb;
+ }
+
+ /**
+ * Converts an {@code AffineTransform} array to an SVG style transform method sequence.
+ * @param transforms the transformation matrix array
+ * @return the formatted array
+ */
+ public static String toString(AffineTransform[] transforms) {
+ return toString(transforms, new StringBuffer()).toString();
+ }
+
+ /**
+ * Converts an {@code AffineTransform} instance to an SVG style transform method.
+ * @param transform the transformation matrix
+ * @return the formatted array
+ */
+ public static String toString(AffineTransform transform) {
+ return toString(transform, new StringBuffer()).toString();
+ }
+
+ /**
+ * Converts an array of integer coordinates into a space-separated string.
+ * @param coordinates the coordinates
+ * @return the space-separated array of coordinates
+ */
+ public static String toString(int[] coordinates) {
+ if (coordinates == null) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, c = coordinates.length; i < c; i++) {
+ if (i > 0) {
+ sb.append(' ');
+ }
+ sb.append(Integer.toString(coordinates[i]));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Converts a rectangle into a space-separated string.
+ * @param rect the rectangle
+ * @return the space-separated array of coordinates
+ */
+ public static String toString(Rectangle rect) {
+ if (rect == null) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.append(rect.x).append(' ').append(rect.y).append(' ');
+ sb.append(rect.width).append(' ').append(rect.height);
+ return sb.toString();
+ }
+
+}
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.render.intermediate.BorderPainter;
+import org.apache.fop.traits.RuleStyle;
+import org.apache.fop.util.ColorUtil;
+
+/**
+ * Java2D-specific implementation of the {@code BorderPainter}.
+ */
+public class Java2DBorderPainter extends BorderPainter {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(Java2DBorderPainter.class);
+
+ private Java2DPainter painter;
+
+ private GeneralPath currentPath = null;
+
+ public Java2DBorderPainter(Java2DPainter painter) {
+ this.painter = painter;
+ }
+
+ private Java2DGraphicsState getG2DState() {
+ return this.painter.g2dState;
+ }
+
+ private Graphics2D getG2D() {
+ return getG2DState().getGraph();
+ }
+
+ /** {@inheritDoc} */
+ protected void drawBorderLine(int x1, int y1, int x2, int y2, boolean horz,
+ boolean startOrBefore, int style, Color color) {
+ float w = x2 - x1;
+ float h = y2 - y1;
+ if ((w < 0) || (h < 0)) {
+ log.error("Negative extent received. Border won't be painted.");
+ return;
+ }
+ switch (style) {
+ case Constants.EN_DASHED:
+ getG2D().setColor(color);
+ if (horz) {
+ float unit = Math.abs(2 * h);
+ int rep = (int)(w / unit);
+ if (rep % 2 == 0) {
+ rep++;
+ }
+ unit = w / rep;
+ float ym = y1 + (h / 2);
+ BasicStroke s = new BasicStroke(h, BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER, 10.0f, new float[] {unit}, 0);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(x1, ym, x2, ym));
+ } else {
+ float unit = Math.abs(2 * w);
+ int rep = (int)(h / unit);
+ if (rep % 2 == 0) {
+ rep++;
+ }
+ unit = h / rep;
+ float xm = x1 + (w / 2);
+ BasicStroke s = new BasicStroke(w, BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER, 10.0f, new float[] {unit}, 0);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(xm, y1, xm, y2));
+ }
+ break;
+ case Constants.EN_DOTTED:
+ getG2D().setColor(color);
+ if (horz) {
+ float unit = Math.abs(2 * h);
+ int rep = (int)(w / unit);
+ if (rep % 2 == 0) {
+ rep++;
+ }
+ unit = w / rep;
+ float ym = y1 + (h / 2);
+ BasicStroke s = new BasicStroke(h, BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_MITER, 10.0f, new float[] {0, unit}, 0);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(x1, ym, x2, ym));
+ } else {
+ float unit = Math.abs(2 * w);
+ int rep = (int)(h / unit);
+ if (rep % 2 == 0) {
+ rep++;
+ }
+ unit = h / rep;
+ float xm = x1 + (w / 2);
+ BasicStroke s = new BasicStroke(w, BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_MITER, 10.0f, new float[] {0, unit}, 0);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(xm, y1, xm, y2));
+ }
+ break;
+ case Constants.EN_DOUBLE:
+ getG2D().setColor(color);
+ if (horz) {
+ float h3 = h / 3;
+ float ym1 = y1 + (h3 / 2);
+ float ym2 = ym1 + h3 + h3;
+ BasicStroke s = new BasicStroke(h3);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(x1, ym1, x2, ym1));
+ getG2D().draw(new Line2D.Float(x1, ym2, x2, ym2));
+ } else {
+ float w3 = w / 3;
+ float xm1 = x1 + (w3 / 2);
+ float xm2 = xm1 + w3 + w3;
+ BasicStroke s = new BasicStroke(w3);
+ getG2D().setStroke(s);
+ getG2D().draw(new Line2D.Float(xm1, y1, xm1, y2));
+ getG2D().draw(new Line2D.Float(xm2, y1, xm2, y2));
+ }
+ break;
+ case Constants.EN_GROOVE:
+ case Constants.EN_RIDGE:
+ float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f);
+ if (horz) {
+ Color uppercol = ColorUtil.lightenColor(color, -colFactor);
+ Color lowercol = ColorUtil.lightenColor(color, colFactor);
+ float h3 = h / 3;
+ float ym1 = y1 + (h3 / 2);
+ getG2D().setStroke(new BasicStroke(h3));
+ getG2D().setColor(uppercol);
+ getG2D().draw(new Line2D.Float(x1, ym1, x2, ym1));
+ getG2D().setColor(color);
+ getG2D().draw(new Line2D.Float(x1, ym1 + h3, x2, ym1 + h3));
+ getG2D().setColor(lowercol);
+ getG2D().draw(new Line2D.Float(x1, ym1 + h3 + h3, x2, ym1 + h3 + h3));
+ } else {
+ Color leftcol = ColorUtil.lightenColor(color, -colFactor);
+ Color rightcol = ColorUtil.lightenColor(color, colFactor);
+ float w3 = w / 3;
+ float xm1 = x1 + (w3 / 2);
+ getG2D().setStroke(new BasicStroke(w3));
+ getG2D().setColor(leftcol);
+ getG2D().draw(new Line2D.Float(xm1, y1, xm1, y2));
+ getG2D().setColor(color);
+ getG2D().draw(new Line2D.Float(xm1 + w3, y1, xm1 + w3, y2));
+ getG2D().setColor(rightcol);
+ getG2D().draw(new Line2D.Float(xm1 + w3 + w3, y1, xm1 + w3 + w3, y2));
+ }
+ break;
+ case Constants.EN_INSET:
+ case Constants.EN_OUTSET:
+ colFactor = (style == Constants.EN_OUTSET ? 0.4f : -0.4f);
+ if (horz) {
+ color = ColorUtil.lightenColor(color, (startOrBefore ? 1 : -1) * colFactor);
+ getG2D().setStroke(new BasicStroke(h));
+ float ym1 = y1 + (h / 2);
+ getG2D().setColor(color);
+ getG2D().draw(new Line2D.Float(x1, ym1, x2, ym1));
+ } else {
+ color = ColorUtil.lightenColor(color, (startOrBefore ? 1 : -1) * colFactor);
+ float xm1 = x1 + (w / 2);
+ getG2D().setStroke(new BasicStroke(w));
+ getG2D().setColor(color);
+ getG2D().draw(new Line2D.Float(xm1, y1, xm1, y2));
+ }
+ break;
+ case Constants.EN_HIDDEN:
+ break;
+ default:
+ getG2D().setColor(color);
+ if (horz) {
+ float ym = y1 + (h / 2);
+ getG2D().setStroke(new BasicStroke(h));
+ getG2D().draw(new Line2D.Float(x1, ym, x2, ym));
+ } else {
+ float xm = x1 + (w / 2);
+ getG2D().setStroke(new BasicStroke(w));
+ getG2D().draw(new Line2D.Float(xm, y1, xm, y2));
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) {
+ if (start.y != end.y) {
+ //TODO Support arbitrary lines if necessary
+ throw new UnsupportedOperationException(
+ "Can only deal with horizontal lines right now");
+ }
+
+ saveGraphicsState();
+ int half = width / 2;
+ int starty = start.y - half;
+ Rectangle boundingRect = new Rectangle(start.x, start.y - half, end.x - start.x, width);
+ getG2DState().updateClip(boundingRect);
+
+ switch (style.getEnumValue()) {
+ case Constants.EN_SOLID:
+ case Constants.EN_DASHED:
+ case Constants.EN_DOUBLE:
+ drawBorderLine(start.x, start.y - half, end.x, end.y + half,
+ true, true, style.getEnumValue(), color);
+ break;
+ case Constants.EN_DOTTED:
+ int shift = half; //This shifts the dots to the right by half a dot's width
+ drawBorderLine(start.x + shift, start.y - half, end.x + shift, end.y + half,
+ true, true, style.getEnumValue(), color);
+ break;
+ case Constants.EN_GROOVE:
+ case Constants.EN_RIDGE:
+ getG2DState().updateColor(ColorUtil.lightenColor(color, 0.6f));
+ moveTo(start.x, starty);
+ lineTo(end.x, starty);
+ lineTo(end.x, starty + 2 * half);
+ lineTo(start.x, starty + 2 * half);
+ closePath();
+ getG2D().fill(currentPath);
+ currentPath = null;
+ getG2DState().updateColor(color);
+ if (style.getEnumValue() == Constants.EN_GROOVE) {
+ moveTo(start.x, starty);
+ lineTo(end.x, starty);
+ lineTo(end.x, starty + half);
+ lineTo(start.x + half, starty + half);
+ lineTo(start.x, starty + 2 * half);
+ } else {
+ moveTo(end.x, starty);
+ lineTo(end.x, starty + 2 * half);
+ lineTo(start.x, starty + 2 * half);
+ lineTo(start.x, starty + half);
+ lineTo(end.x - half, starty + half);
+ }
+ closePath();
+ getG2D().fill(currentPath);
+ currentPath = null;
+
+ case Constants.EN_NONE:
+ // No rule is drawn
+ break;
+ default:
+ } // end switch
+ restoreGraphicsState();
+ }
+
+ /** {@inheritDoc} */
+ protected void clip() {
+ if (currentPath == null) {
+ throw new IllegalStateException("No current path available!");
+ }
+ getG2DState().updateClip(currentPath);
+ currentPath = null;
+ }
+
+ /** {@inheritDoc} */
+ protected void closePath() {
+ currentPath.closePath();
+ }
+
+ /** {@inheritDoc} */
+ protected void lineTo(int x, int y) {
+ if (currentPath == null) {
+ currentPath = new GeneralPath();
+ }
+ currentPath.lineTo(x, y);
+ }
+
+ /** {@inheritDoc} */
+ protected void moveTo(int x, int y) {
+ if (currentPath == null) {
+ currentPath = new GeneralPath();
+ }
+ currentPath.moveTo(x, y);
+ }
+
+ /** {@inheritDoc} */
+ protected void saveGraphicsState() {
+ this.painter.saveGraphicsState();
+ }
+
+ /** {@inheritDoc} */
+ protected void restoreGraphicsState() {
+ this.painter.restoreGraphicsState();
+ this.currentPath = null;
+ }
+
+}
// Java
import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
import java.util.Map;
/**
*/
private Graphics2D graphics;
+ /**
+ * Creates a Graphics2D object for the sole purpose of getting font metrics.
+ * @return a Graphics2D object
+ */
+ public static Graphics2D createFontMetricsGraphics2D() {
+ BufferedImage fontImage = new BufferedImage(100, 100,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics2D = fontImage.createGraphics();
+ //The next line is important to get accurate font metrics!
+ graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ return graphics2D;
+ }
+
/**
* Constructs a new Font-metrics.
* @param graphics a temp graphics object - this is needed so
getGraph().setPaint(p);
return true;
}
- } else if (p.equals(getGraph().getPaint())) {
+ } else if (!p.equals(getGraph().getPaint())) {
getGraph().setPaint(p);
return true;
}
* according to the rule last-specified-first-applied.
* @see java.awt.Graphics2D#transform(AffineTransform)
*
- * @param tf the transform to concatonate to the current level transform
+ * @param tf the transform to concatenate to the current level transform
*/
public void transform(AffineTransform tf) {
- getGraph().transform(tf);
+ if (!tf.isIdentity()) {
+ getGraph().transform(tf);
+ }
}
/**
/** {@inheritDoc} */
public String toString() {
- String s = "AWTGraphicsState " + currentGraphics.toString()
+ String s = "Java2DGraphicsState " + currentGraphics.toString()
+ ", Stroke (width: " + currentStrokeWidth + " style: "
+ currentStrokeStyle + "), " + getTransform();
return s;
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+
+import org.apache.fop.render.ImageHandler;
+import org.apache.fop.render.RenderingContext;
+
+/**
+ * Image handler implementation that paints {@code Graphics2D} image on another {@code Graphics2D}
+ * target.
+ */
+public class Java2DImageHandlerGraphics2D implements ImageHandler {
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 200;
+ }
+
+ /** {@inheritDoc} */
+ public Class getSupportedImageClass() {
+ return ImageGraphics2D.class;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return new ImageFlavor[] {
+ ImageFlavor.GRAPHICS2D
+ };
+ }
+
+ /** {@inheritDoc} */
+ public void handleImage(RenderingContext context, Image image, Rectangle pos)
+ throws IOException {
+ Java2DRenderingContext java2dContext = (Java2DRenderingContext)context;
+ ImageInfo info = image.getInfo();
+ ImageGraphics2D imageG2D = (ImageGraphics2D)image;
+
+ Dimension dim = info.getSize().getDimensionMpt();
+
+ Graphics2D g2d = (Graphics2D)java2dContext.getGraphics2D().create();
+ g2d.translate(pos.x, pos.y);
+ double sx = pos.width / dim.getWidth();
+ double sy = pos.height / dim.getHeight();
+ g2d.scale(sx, sy);
+
+ Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, dim.getWidth(), dim.getHeight());
+ imageG2D.getGraphics2DImagePainter().paint(g2d, area);
+ g2d.dispose();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCompatible(RenderingContext targetContext, Image image) {
+ return (image == null || image instanceof ImageGraphics2D)
+ && targetContext instanceof Java2DRenderingContext;
+ }
+
+}
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+
+import org.apache.fop.render.ImageHandler;
+import org.apache.fop.render.RenderingContext;
+
+/**
+ * Image handler implementation that paints {@code RenderedImage} instances on a {@code Graphics2D}
+ * object.
+ */
+public class Java2DImageHandlerRenderedImage implements ImageHandler {
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 300;
+ }
+
+ /** {@inheritDoc} */
+ public Class getSupportedImageClass() {
+ return ImageRawStream.class;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return new ImageFlavor[] {
+ ImageFlavor.BUFFERED_IMAGE,
+ ImageFlavor.RENDERED_IMAGE,
+ };
+ }
+
+ /** {@inheritDoc} */
+ public void handleImage(RenderingContext context, Image image, Rectangle pos)
+ throws IOException {
+ Java2DRenderingContext java2dContext = (Java2DRenderingContext)context;
+ ImageInfo info = image.getInfo();
+ ImageRendered imageRend = (ImageRendered)image;
+ Graphics2D g2d = java2dContext.getGraphics2D();
+
+ AffineTransform at = new AffineTransform();
+ at.translate(pos.x, pos.y);
+ //scaling based on layout instructions
+ double sx = pos.getWidth() / (double)info.getSize().getWidthMpt();
+ double sy = pos.getHeight() / (double)info.getSize().getHeightMpt();
+
+ //scaling because of image resolution
+ //float sourceResolution = java2dContext.getUserAgent().getSourceResolution();
+ //source resolution seems to be a bad idea, not sure why
+ float sourceResolution = 72;
+ sourceResolution *= 1000; //we're working in the millipoint area
+ sx *= sourceResolution / info.getSize().getDpiHorizontal();
+ sy *= sourceResolution / info.getSize().getDpiVertical();
+ at.scale(sx, sy);
+ RenderedImage rend = imageRend.getRenderedImage();
+ if (imageRend.getTransparentColor() != null && !rend.getColorModel().hasAlpha()) {
+ int transCol = imageRend.getTransparentColor().getRGB();
+ BufferedImage bufImage = makeTransparentImage(rend);
+ WritableRaster alphaRaster = bufImage.getAlphaRaster();
+ //TODO Masked images: Does anyone know a more efficient method to do this?
+ final int[] transparent = new int[] {0x00};
+ for (int y = 0, maxy = bufImage.getHeight(); y < maxy; y++) {
+ for (int x = 0, maxx = bufImage.getWidth(); x < maxx; x++) {
+ int col = bufImage.getRGB(x, y);
+ if (col == transCol) {
+ //Mask out all pixels that match the transparent color
+ alphaRaster.setPixel(x, y, transparent);
+ }
+ }
+ }
+ g2d.drawRenderedImage(bufImage, at);
+ } else {
+ g2d.drawRenderedImage(rend, at);
+ }
+ }
+
+ private BufferedImage makeTransparentImage(RenderedImage src) {
+ BufferedImage bufImage = new BufferedImage(src.getWidth(), src.getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2d = bufImage.createGraphics();
+ g2d.drawRenderedImage(src, new AffineTransform());
+ g2d.dispose();
+ return bufImage;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCompatible(RenderingContext targetContext, Image image) {
+ return (image == null || image instanceof ImageRendered)
+ && targetContext instanceof Java2DRenderingContext;
+ }
+
+}
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+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.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.intermediate.AbstractIFPainter;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.RuleStyle;
+
+/**
+ * {@code IFPainter} implementation that paints on a Graphics2D instance.
+ */
+public class Java2DPainter extends AbstractIFPainter {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(Java2DPainter.class);
+
+ /** the FO user agent */
+ protected FOUserAgent userAgent;
+
+ /** The font information */
+ protected FontInfo fontInfo;
+
+ /** Holds the intermediate format state */
+ protected IFState state;
+
+ private Java2DBorderPainter borderPainter;
+
+ /** The current state, holds a Graphics2D and its context */
+ protected Java2DGraphicsState g2dState;
+ private Stack g2dStateStack = new Stack();
+
+ /**
+ * Main constructor.
+ * @param g2d the target Graphics2D instance
+ * @param userAgent the user agent
+ * @param fontInfo the font information
+ */
+ public Java2DPainter(Graphics2D g2d, FOUserAgent userAgent, FontInfo fontInfo) {
+ super();
+ this.userAgent = userAgent;
+ this.state = IFState.create();
+ this.fontInfo = fontInfo;
+ this.g2dState = new Java2DGraphicsState(g2d, fontInfo, g2d.getTransform());
+ this.borderPainter = new Java2DBorderPainter(this);
+ }
+
+ /** {@inheritDoc} */
+ public FOUserAgent getUserAgent() {
+ return this.userAgent;
+ }
+
+ /**
+ * Returns the associated {@code FontInfo} object.
+ * @return the font info
+ */
+ protected FontInfo getFontInfo() {
+ return this.fontInfo;
+ }
+
+ /**
+ * Returns the Java2D graphics state.
+ * @return the graphics state
+ */
+ protected Java2DGraphicsState getState() {
+ return this.g2dState;
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+
+ /** {@inheritDoc} */
+ public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
+ throws IFException {
+ saveGraphicsState();
+ try {
+ concatenateTransformationMatrix(transform);
+ //TODO CLIP!
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in startViewport()", ioe);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endViewport() throws IFException {
+ restoreGraphicsState();
+ }
+
+ /** {@inheritDoc} */
+ public void startGroup(AffineTransform transform) throws IFException {
+ saveGraphicsState();
+ try {
+ concatenateTransformationMatrix(transform);
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in startGroup()", ioe);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endGroup() throws IFException {
+ restoreGraphicsState();
+ }
+
+ /** {@inheritDoc} */
+ public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException {
+ drawImageUsingURI(uri, rect);
+ }
+
+ /** {@inheritDoc} */
+ protected RenderingContext createRenderingContext() {
+ Java2DRenderingContext java2dContext = new Java2DRenderingContext(
+ getUserAgent(), g2dState.getGraph(), getFontInfo());
+ return java2dContext;
+ }
+
+ /** {@inheritDoc} */
+ public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException {
+ drawImageUsingDocument(doc, rect);
+ }
+
+ /** {@inheritDoc} */
+ public void clipRect(Rectangle rect) throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void fillRect(Rectangle rect, Paint fill) throws IFException {
+ if (fill == null) {
+ return;
+ }
+ if (rect.width != 0 && rect.height != 0) {
+ g2dState.updatePaint(fill);
+ g2dState.getGraph().fill(rect);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
+ BorderProps start, BorderProps end) throws IFException {
+ if (before != null || after != null || start != null || end != null) {
+ this.borderPainter.drawBorders(rect, before, after, start, end);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
+ throws IFException {
+ this.borderPainter.drawLine(start, end, width, color, style);
+ }
+
+ /** {@inheritDoc} */
+ public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
+ //Note: dy is currently ignored
+ g2dState.updateColor(state.getTextColor());
+ FontTriplet triplet = new FontTriplet(
+ state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
+ //TODO Ignored: state.getFontVariant()
+ //TODO Opportunity for font caching if font state is more heavily used
+ Font font = getFontInfo().getFontInstance(triplet, state.getFontSize());
+ //String fontName = font.getFontName();
+ //float fontSize = state.getFontSize() / 1000f;
+ g2dState.updateFont(font.getFontName(), state.getFontSize() * 1000);
+
+ Graphics2D g2d = this.g2dState.getGraph();
+ GlyphVector gv = g2d.getFont().createGlyphVector(g2d.getFontRenderContext(), text);
+ Point2D cursor = new Point2D.Float(0, 0);
+
+ int l = text.length();
+ int dxl = (dx != null ? dx.length : 0);
+
+ if (dx != null && dxl > 0 && dx[0] != 0) {
+ cursor.setLocation(cursor.getX() - (dx[0] / 10f), cursor.getY());
+ gv.setGlyphPosition(0, cursor);
+ }
+ for (int i = 0; i < l; i++) {
+ char orgChar = text.charAt(i);
+ float glyphAdjust = 0;
+ int cw = font.getCharWidth(orgChar);
+
+ if (dx != null && i < dxl - 1) {
+ glyphAdjust += dx[i + 1];
+ }
+
+ cursor.setLocation(cursor.getX() + cw - glyphAdjust, cursor.getY());
+ gv.setGlyphPosition(i + 1, cursor);
+ }
+ g2d.drawGlyphVector(gv, x, y);
+ }
+
+ /** {@inheritDoc} */
+ public void setFont(String family, String style, Integer weight, String variant, Integer size,
+ Color color) throws IFException {
+ if (family != null) {
+ state.setFontFamily(family);
+ }
+ if (style != null) {
+ state.setFontStyle(style);
+ }
+ if (weight != null) {
+ state.setFontWeight(weight.intValue());
+ }
+ if (variant != null) {
+ state.setFontVariant(variant);
+ }
+ if (size != null) {
+ state.setFontSize(size.intValue());
+ }
+ if (color != null) {
+ state.setTextColor(color);
+ }
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+ /** Saves the current graphics state on the stack. */
+ protected void saveGraphicsState() {
+ g2dStateStack.push(g2dState);
+ g2dState = new Java2DGraphicsState(g2dState);
+ }
+
+ /** Restores the last graphics state from the stack. */
+ protected void restoreGraphicsState() {
+ g2dState.dispose();
+ g2dState = (Java2DGraphicsState)g2dStateStack.pop();
+ }
+
+ private void concatenateTransformationMatrix(AffineTransform transform) throws IOException {
+ g2dState.transform(transform);
+ }
+
+}
/** The 0-based current page number */
private int currentPageNumber = 0;
- /** true if antialiasing is set */
+ /** true if anti-aliasing is set */
protected boolean antialiasing = true;
/** true if qualityRendering is set */
//Don't call super.setupFontInfo() here! Java2D needs a special font setup
// create a temp Image to test font metrics on
this.fontInfo = inFontInfo;
- BufferedImage fontImage = new BufferedImage(100, 100,
- BufferedImage.TYPE_INT_RGB);
- Graphics2D graphics2D = fontImage.createGraphics();
- //The next line is important to get accurate font metrics!
- graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
- RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
FontCollection[] fontCollections = new FontCollection[] {
new Base14FontCollection(graphics2D),
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Graphics2D;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.AbstractRenderingContext;
+
+/**
+ * Rendering context for PDF production.
+ */
+public class Java2DRenderingContext extends AbstractRenderingContext {
+
+ private FontInfo fontInfo;
+ private Graphics2D g2d;
+
+ /**
+ * Main constructor.
+ * @param userAgent the user agent
+ * @param g2d the target Graphics2D instance
+ * @param fontInfo the font list
+ */
+ public Java2DRenderingContext(FOUserAgent userAgent, Graphics2D g2d, FontInfo fontInfo) {
+ super(userAgent);
+ this.g2d = g2d;
+ this.fontInfo = fontInfo;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return null; //not applicable
+ }
+
+ /**
+ * Returns the target Graphics2D object.
+ * @return the Graphics2D object
+ */
+ public Graphics2D getGraphics2D() {
+ return this.g2d;
+ }
+
+}
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Color;
+
+/**
+ * This class holds settings used when rendering with Java2D.
+ */
+public class Java2DRenderingSettings {
+
+ /** false: paints a non-transparent white background, true: for a transparent background */
+ private Color pageBackgroundColor = Color.WHITE;
+
+ /**
+ * Returns the page background color.
+ * @return the page background color or null if the page background is transparent
+ */
+ public Color getPageBackgroundColor() {
+ return this.pageBackgroundColor;
+ }
+
+ /**
+ * Sets the page background color.
+ * @param color the page background color or null if the page background shall be transparent
+ */
+ public void setPageBackgroundColor(Color color) {
+ this.pageBackgroundColor = color;
+ }
+
+ /**
+ * Indicates whether the pages have a transparent background or if it's painted in a
+ * particular color.
+ * @return true if the pages have a transparent background
+ */
+ public boolean hasTransparentPageBackground() {
+ return this.pageBackgroundColor == null;
+ }
+
+
+}
--- /dev/null
+/*
+ * 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.java2d;
+
+import java.awt.Graphics2D;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontEventAdapter;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+
+/**
+ * Rendering-related utilities for Java2D.
+ */
+public class Java2DUtil {
+
+ /**
+ * Builds a default {@code FontInfo} object for use with output formats using the Java2D
+ * font setup.
+ * @param fontInfo the font info object to populate
+ * @param userAgent the user agent
+ * @return the populated font information object
+ */
+ public static FontInfo buildDefaultJava2DBasedFontInfo(
+ FontInfo fontInfo, FOUserAgent userAgent) {
+ Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+
+ FontManager fontManager = userAgent.getFactory().getFontManager();
+ FontCollection[] fontCollections = new FontCollection[] {
+ new org.apache.fop.render.java2d.Base14FontCollection(graphics2D),
+ new InstalledFontCollection(graphics2D)
+ };
+
+ FontInfo fi = (fontInfo != null ? fontInfo : new FontInfo());
+ fi.setEventListener(new FontEventAdapter(userAgent.getEventBroadcaster()));
+ fontManager.setup(fi, fontCollections);
+ return fi;
+ }
+
+
+}
--- /dev/null
+/*
+ * 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.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+
+/**
+ * {@code IFDocumentHandler} implementation that produces PCL 5.
+ */
+public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
+ implements PCLConstants {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PCLDocumentHandler.class);
+
+ /** Utility class for handling all sorts of peripheral tasks around PCL generation. */
+ protected PCLRenderingUtil pclUtil;
+
+ /** The PCL generator */
+ private PCLGenerator gen;
+
+ private PCLPageDefinition currentPageDefinition;
+
+ /** contains the pageWith of the last printed page */
+ private long pageWidth = 0;
+ /** contains the pageHeight of the last printed page */
+ private long pageHeight = 0;
+
+ /**
+ * Default constructor.
+ */
+ public PCLDocumentHandler() {
+ }
+
+ /** {@inheritDoc} */
+ public boolean supportsPagesOutOfOrder() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_PCL;
+ }
+
+ /** {@inheritDoc} */
+ public void setUserAgent(FOUserAgent ua) {
+ super.setUserAgent(ua);
+ this.pclUtil = new PCLRenderingUtil(ua);
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ return null; //No configurator, yet.
+ }
+
+ PCLRenderingUtil getPCLUtil() {
+ return this.pclUtil;
+ }
+
+ PCLGenerator getPCLGenerator() {
+ return this.gen;
+ }
+
+ /** @return the target resolution */
+ protected int getResolution() {
+ int resolution = (int)Math.round(getUserAgent().getTargetResolution());
+ if (resolution <= 300) {
+ return 300;
+ } else {
+ return 600;
+ }
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+ /** {@inheritDoc} */
+ public void startDocument() throws IFException {
+ try {
+ if (getUserAgent() == null) {
+ throw new IllegalStateException(
+ "User agent must be set before starting PDF generation");
+ }
+ if (this.outputStream == null) {
+ throw new IllegalStateException("OutputStream hasn't been set through setResult()");
+ }
+ log.debug("Rendering areas to PCL...");
+ this.gen = new PCLGenerator(this.outputStream, getResolution());
+
+ if (!pclUtil.isPJLDisabled()) {
+ gen.universalEndOfLanguage();
+ gen.writeText("@PJL COMMENT Produced by " + getUserAgent().getProducer() + "\n");
+ if (getUserAgent().getTitle() != null) {
+ gen.writeText("@PJL JOB NAME = \"" + getUserAgent().getTitle() + "\"\n");
+ }
+ gen.writeText("@PJL SET RESOLUTION = " + getResolution() + "\n");
+ gen.writeText("@PJL ENTER LANGUAGE = PCL\n");
+ }
+ gen.resetPrinter();
+ gen.setUnitOfMeasure(getResolution());
+ gen.setRasterGraphicsResolution(getResolution());
+ } catch (IOException e) {
+ throw new IFException("I/O error in startDocument()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ try {
+ gen.separateJobs();
+ gen.resetPrinter();
+ if (!pclUtil.isPJLDisabled()) {
+ gen.universalEndOfLanguage();
+ }
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in endDocument()", ioe);
+ }
+ super.endDocument();
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(String id) throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPageSequence() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPage(int index, String name, Dimension size) throws IFException {
+
+ try {
+ //TODO Add support for paper-source and duplex-mode
+ /*
+ //Paper source
+ String paperSource = page.getForeignAttributeValue(
+ new QName(PCLElementMapping.NAMESPACE, null, "paper-source"));
+ if (paperSource != null) {
+ gen.selectPaperSource(Integer.parseInt(paperSource));
+ }
+
+ // Is Page duplex?
+ String pageDuplex = page.getForeignAttributeValue(
+ new QName(PCLElementMapping.NAMESPACE, null, "duplex-mode"));
+ if (pageDuplex != null) {
+ gen.selectDuplexMode(Integer.parseInt(pageDuplex));
+ }*/
+
+ //Page size
+ final long pagewidth = size.width;
+ final long pageheight = size.height;
+ selectPageFormat(pagewidth, pageheight);
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in startPage()", ioe);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public IFPainter startPageContent() throws IFException {
+ return new PCLPainter(this, this.currentPageDefinition);
+ }
+
+ /** {@inheritDoc} */
+ public void endPageContent() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPage() throws IFException {
+ try {
+ //Eject page
+ gen.formFeed();
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in endPage()", ioe);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void handleExtensionObject(Object extension) throws IFException {
+ if (false) {
+ //TODO Handle extensions
+ } else {
+ log.debug("Don't know how to handle extension object. Ignoring: "
+ + extension + " (" + extension.getClass().getName() + ")");
+ }
+ }
+
+ 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);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Document handler factory for PCL output.
+ */
+public class PCLDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
+
+ //TODO Revert to normal MIME after stabilization!
+ private static final String[] MIMES = new String[] {MimeConstants.MIME_PCL + ";mode=painter"};
+
+ /** {@inheritDoc} */
+ public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
+ PCLDocumentHandler handler = new PCLDocumentHandler();
+ handler.setUserAgent(ua);
+ return handler;
+ }
+
+ /** {@inheritDoc} */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
+ return null;
+ }
+
+}
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RenderingContext;
-import org.apache.fop.render.intermediate.AbstractBinaryWritingIFPainter;
+import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.util.UnitConv;
/**
- * IFPainter implementation that produces PCL.
+ * {@code IFPainter} implementation that produces PCL 5.
*/
-public class PCLPainter extends AbstractBinaryWritingIFPainter implements PCLConstants {
+public class PCLPainter extends AbstractIFPainter implements PCLConstants {
/** logging instance */
private static Log log = LogFactory.getLog(PCLPainter.class);
+ private PCLDocumentHandler parent;
+
/** Holds the intermediate format state */
protected IFState state;
- /** Utility class for handling all sorts of peripheral tasks around PCL generation. */
- protected PCLRenderingUtil pclUtil;
-
/** The PCL generator */
private PCLGenerator gen;
private Stack graphicContextStack = new Stack();
private GraphicContext graphicContext = new GraphicContext();
- /** contains the pageWith of the last printed page */
- private long pageWidth = 0;
- /** contains the pageHeight of the last printed page */
- private long pageHeight = 0;
-
/**
- * Default constructor.
+ * Main constructor.
+ * @param parent the parent document handler
*/
- public PCLPainter() {
- }
-
- /** {@inheritDoc} */
- public boolean supportsPagesOutOfOrder() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String getMimeType() {
- return MimeConstants.MIME_PCL;
+ public PCLPainter(PCLDocumentHandler parent, PCLPageDefinition pageDefinition) {
+ this.parent = parent;
+ this.gen = parent.getPCLGenerator();
+ this.state = IFState.create();
+ this.currentPageDefinition = pageDefinition;
}
/** {@inheritDoc} */
- public void setUserAgent(FOUserAgent ua) {
- super.setUserAgent(ua);
- this.pclUtil = new PCLRenderingUtil(ua);
+ public FOUserAgent getUserAgent() {
+ return this.parent.getUserAgent();
}
PCLRenderingUtil getPCLUtil() {
- return this.pclUtil;
+ return this.parent.getPCLUtil();
}
/** @return the target resolution */
//----------------------------------------------------------------------------------------------
- /** {@inheritDoc} */
- public void startDocument() throws IFException {
- try {
- if (getUserAgent() == null) {
- throw new IllegalStateException(
- "User agent must be set before starting PDF generation");
- }
- if (this.outputStream == null) {
- throw new IllegalStateException("OutputStream hasn't been set through setResult()");
- }
- log.debug("Rendering areas to PCL...");
- this.gen = new PCLGenerator(this.outputStream, getResolution());
-
- if (!pclUtil.isPJLDisabled()) {
- gen.universalEndOfLanguage();
- gen.writeText("@PJL COMMENT Produced by " + getUserAgent().getProducer() + "\n");
- if (getUserAgent().getTitle() != null) {
- gen.writeText("@PJL JOB NAME = \"" + getUserAgent().getTitle() + "\"\n");
- }
- gen.writeText("@PJL SET RESOLUTION = " + getResolution() + "\n");
- gen.writeText("@PJL ENTER LANGUAGE = PCL\n");
- }
- gen.resetPrinter();
- gen.setUnitOfMeasure(getResolution());
- gen.setRasterGraphicsResolution(getResolution());
- } catch (IOException e) {
- throw new IFException("I/O error in startDocument()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endDocumentHeader() throws IFException {
- }
-
- /** {@inheritDoc} */
- public void endDocument() throws IFException {
- try {
- gen.separateJobs();
- gen.resetPrinter();
- if (!pclUtil.isPJLDisabled()) {
- gen.universalEndOfLanguage();
- }
- } catch (IOException ioe) {
- throw new IFException("I/O error in endDocument()", ioe);
- }
- super.endDocument();
- }
-
- /** {@inheritDoc} */
- public void startPageSequence(String id) throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void endPageSequence() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void startPage(int index, String name, Dimension size) throws IFException {
- saveGraphicsState();
-
- try {
- //TODO Add support for paper-source and duplex-mode
- /*
- //Paper source
- String paperSource = page.getForeignAttributeValue(
- new QName(PCLElementMapping.NAMESPACE, null, "paper-source"));
- if (paperSource != null) {
- gen.selectPaperSource(Integer.parseInt(paperSource));
- }
-
- // Is Page duplex?
- String pageDuplex = page.getForeignAttributeValue(
- new QName(PCLElementMapping.NAMESPACE, null, "duplex-mode"));
- if (pageDuplex != null) {
- gen.selectDuplexMode(Integer.parseInt(pageDuplex));
- }*/
-
- //Page size
- final long pagewidth = size.width;
- final long pageheight = size.height;
- selectPageFormat(pagewidth, pageheight);
- } catch (IOException ioe) {
- throw new IFException("I/O error in startPage()", ioe);
- }
- }
-
- /** {@inheritDoc} */
- public void startPageContent() throws IFException {
- this.state = IFState.create();
- }
-
- /** {@inheritDoc} */
- public void endPageContent() throws IFException {
- assert this.state.pop() == null;
- //nop
- }
-
- /** {@inheritDoc} */
- public void endPage() throws IFException {
- try {
- //Eject page
- gen.formFeed();
- restoreGraphicsState();
- } catch (IOException ioe) {
- throw new IFException("I/O error in endPage()", ioe);
- }
- }
-
/** {@inheritDoc} */
public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
throws IFException {
state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
//TODO Ignored: state.getFontVariant()
//TODO Opportunity for font caching if font state is more heavily used
- String fontKey = fontInfo.getInternalFontKey(triplet);
- boolean pclFont = pclUtil.isAllTextAsBitmaps()
+ String fontKey = parent.getFontInfo().getInternalFontKey(triplet);
+ boolean pclFont = getPCLUtil().isAllTextAsBitmaps()
? false
: setFont(fontKey, state.getFontSize(), text);
if (true || pclFont) {
setCursorPos(x, y);
float fontSize = state.getFontSize() / 1000f;
- Font font = fontInfo.getFontInstance(triplet, state.getFontSize());
+ Font font = parent.getFontInfo().getFontInstance(triplet, state.getFontSize());
int l = text.length();
int dxl = (dx != null ? dx.length : 0);
}
}
- /** {@inheritDoc} */
- public void handleExtensionObject(Object extension) throws IFException {
- if (false) {
- //TODO Handle extensions
- } else {
- log.debug("Ignored extension object: "
- + extension + " (" + extension.getClass().getName() + ")");
- }
- }
-
//----------------------------------------------------------------------------------------------
/** Saves the current graphics state on the stack. */
gen.setCursorPos(transPoint.getX(), transPoint.getY());
}
- 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);
- }
- }
-
/**
* Sets the current font (NOTE: Hard-coded font mappings ATM!)
* @param name the font name (internal F* names for now)
+++ /dev/null
-/*
- * 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.intermediate.AbstractIFPainterMaker;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
-
-/**
- * Painter factory for PCL output.
- */
-public class PCLPainterMaker extends AbstractIFPainterMaker {
-
- //TODO Revert to normal MIME after stabilization!
- private static final String[] MIMES = new String[] {MimeConstants.MIME_PCL + ";mode=painter"};
-
- /** {@inheritDoc} */
- public IFPainter makePainter(FOUserAgent ua) {
- return new PCLPainter();
- }
-
- /** {@inheritDoc} */
- public boolean needsOutputStream() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String[] getSupportedMimeTypes() {
- return MIMES;
- }
-
- public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) {
- return null; //new PDFRendererConfigurator(userAgent);
- }
-
-}
--- /dev/null
+/*
+ * 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.Dimension;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.xmp.Metadata;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fo.extensions.xmp.XMPMetadata;
+import org.apache.fop.pdf.PDFAction;
+import org.apache.fop.pdf.PDFAnnotList;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFOutline;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFReference;
+import org.apache.fop.pdf.PDFResourceContext;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.intermediate.extensions.AbstractAction;
+import org.apache.fop.render.intermediate.extensions.Bookmark;
+import org.apache.fop.render.intermediate.extensions.BookmarkTree;
+import org.apache.fop.render.intermediate.extensions.GoToXYAction;
+import org.apache.fop.render.intermediate.extensions.NamedDestination;
+
+/**
+ * {@code IFDocumentHandler} implementation that produces PDF.
+ */
+public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PDFDocumentHandler.class);
+
+ /** 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;
+
+ /** the /Resources object of the PDF document being created */
+ protected PDFResources pdfResources;
+
+ /** The current content generator */
+ protected PDFContentGenerator generator;
+
+ /** the current annotation list to add annotations to */
+ protected PDFResourceContext currentContext;
+
+ /** 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;
+
+ /** Used for bookmarks/outlines. */
+ protected Map pageReferences = new java.util.HashMap();
+
+ /**
+ * Default constructor.
+ */
+ public PDFDocumentHandler() {
+ }
+
+ /** {@inheritDoc} */
+ public boolean supportsPagesOutOfOrder() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_PDF;
+ }
+
+ /** {@inheritDoc} */
+ public void setUserAgent(FOUserAgent ua) {
+ super.setUserAgent(ua);
+ this.pdfUtil = new PDFRenderingUtil(ua);
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ return new PDFRendererConfigurator(getUserAgent());
+ }
+
+ PDFRenderingUtil getPDFUtil() {
+ return this.pdfUtil;
+ }
+
+ /** {@inheritDoc} */
+ public void startDocument() throws IFException {
+ try {
+ if (getUserAgent() == null) {
+ throw new IllegalStateException(
+ "User agent must be set before starting PDF generation");
+ }
+ if (this.outputStream == null) {
+ throw new IllegalStateException("OutputStream hasn't been set through setResult()");
+ }
+ this.pdfDoc = pdfUtil.setupPDFDocument(this.outputStream);
+ } catch (IOException e) {
+ throw new IFException("I/O error in startDocument()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ pdfUtil.generateDefaultXMPMetadata();
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ try {
+ pdfDoc.getResources().addFonts(pdfDoc, fontInfo);
+ pdfDoc.outputTrailer(this.outputStream);
+
+ this.pdfDoc = null;
+
+ pdfResources = null;
+ this.generator = null;
+ currentContext = null;
+ currentPage = null;
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in endDocument()", ioe);
+ }
+ super.endDocument();
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(String id) throws IFException {
+ //TODO page sequence title, country and language
+ }
+
+ /** {@inheritDoc} */
+ public void endPageSequence() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPage(int index, String name, Dimension size) throws IFException {
+ this.pdfResources = this.pdfDoc.getResources();
+
+ this.currentPage = this.pdfDoc.getFactory().makePage(
+ this.pdfResources,
+ (int)Math.round(size.getWidth() / 1000),
+ (int)Math.round(size.getHeight() / 1000),
+ index);
+ //pageReferences.put(new Integer(index)/*page.getKey()*/, currentPage.referencePDF());
+ //pvReferences.put(page.getKey(), page);
+
+ pdfUtil.generatePageLabel(index, name);
+
+ currentPageRef = currentPage.referencePDF();
+ this.pageReferences.put(new Integer(index), new PageReference(currentPage, size));
+
+ this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream, this.currentPage);
+ // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFPainter's
+ AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
+ size.height / 1000f);
+ generator.concatenate(basicPageTransform);
+
+ }
+
+ /** {@inheritDoc} */
+ public IFPainter startPageContent() throws IFException {
+ return new PDFPainter(this);
+ }
+
+ /** {@inheritDoc} */
+ public void endPageContent() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPage() throws IFException {
+ try {
+ 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.generator.flushPDFDoc();
+ this.generator = null;
+ } catch (IOException ioe) {
+ throw new IFException("I/O error in endPage()", ioe);
+ }
+ }
+
+ private void renderBookmarkTree(BookmarkTree tree) {
+ Iterator iter = tree.getBookmarks().iterator();
+ while (iter.hasNext()) {
+ Bookmark b = (Bookmark)iter.next();
+ renderBookmark(b, null);
+ }
+ }
+
+ private void renderBookmark(Bookmark bookmark, PDFOutline parent) {
+ if (parent == null) {
+ parent = pdfDoc.getOutlineRoot();
+ }
+ PDFAction action = getAction(bookmark.getAction());
+ PDFOutline pdfOutline = pdfDoc.getFactory().makeOutline(parent,
+ bookmark.getTitle(), action, bookmark.isShown());
+ Iterator iter = bookmark.getChildBookmarks().iterator();
+ while (iter.hasNext()) {
+ Bookmark b = (Bookmark)iter.next();
+ renderBookmark(b, pdfOutline);
+ }
+ }
+
+ private void renderNamedDestination(NamedDestination destination) {
+ PDFAction action = getAction(destination.getAction());
+ pdfDoc.getFactory().makeDestination(
+ destination.getName(), action.makeReference());
+ }
+
+ private PDFAction getAction(AbstractAction action) {
+ if (action instanceof GoToXYAction) {
+ GoToXYAction a = (GoToXYAction)action;
+ PageReference pageRef = (PageReference)this.pageReferences.get(
+ new Integer(a.getPageIndex()));
+ //Convert target location from millipoints to points and adjust for different
+ //page origin
+ Point2D p2d = new Point2D.Double(
+ a.getTargetLocation().x / 1000.0,
+ (pageRef.pageDimension.height - a.getTargetLocation().y) / 1000.0);
+ return pdfDoc.getFactory().getPDFGoTo(pageRef.pageRef.toString(), p2d);
+ } else {
+ throw new UnsupportedOperationException("Unsupported action type: "
+ + action + " (" + action.getClass().getName() + ")");
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void handleExtensionObject(Object extension) throws IFException {
+ if (extension instanceof XMPMetadata) {
+ pdfUtil.renderXMPMetadata((XMPMetadata)extension);
+ } else if (extension instanceof Metadata) {
+ XMPMetadata wrapper = new XMPMetadata(((Metadata)extension));
+ pdfUtil.renderXMPMetadata(wrapper);
+ } else if (extension instanceof BookmarkTree) {
+ renderBookmarkTree((BookmarkTree)extension);
+ } else if (extension instanceof NamedDestination) {
+ renderNamedDestination((NamedDestination)extension);
+ } else {
+ log.debug("Don't know how to handle extension object. Ignoring: "
+ + extension + " (" + extension.getClass().getName() + ")");
+ }
+ }
+
+ private static final class PageReference {
+
+ private PDFReference pageRef;
+ private Dimension pageDimension;
+
+ private PageReference(PDFPage page, Dimension dim) {
+ this.pageRef = page.makeReference();
+ this.pageDimension = new Dimension(dim);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Intermediate format document handler factory for PDF output.
+ */
+public class PDFDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
+
+ //TODO Revert to normal MIME after stabilization!
+ private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF + ";mode=painter"};
+
+ /** {@inheritDoc} */
+ public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
+ PDFDocumentHandler handler = new PDFDocumentHandler();
+ handler.setUserAgent(ua);
+ return handler;
+ }
+
+ /** {@inheritDoc} */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PDFRendererConfigurator(userAgent);
+ }
+
+}
public boolean isCompatible(RenderingContext targetContext, Image image) {
return (image == null
|| (image instanceof ImageXMLDOM
- && image.getFlavor().isCompatible(BatikImageFlavors.SVG_DOM))
- && targetContext instanceof PDFRenderingContext);
+ && image.getFlavor().isCompatible(BatikImageFlavors.SVG_DOM)))
+ && targetContext instanceof PDFRenderingContext;
}
}
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.io.IOException;
-import java.util.Iterator;
import java.util.Map;
import org.w3c.dom.Document;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.xmlgraphics.xmp.Metadata;
-
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.fo.extensions.xmp.XMPMetadata;
import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
-import org.apache.fop.pdf.PDFAction;
-import org.apache.fop.pdf.PDFAnnotList;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFNumber;
-import org.apache.fop.pdf.PDFOutline;
-import org.apache.fop.pdf.PDFPage;
-import org.apache.fop.pdf.PDFReference;
-import org.apache.fop.pdf.PDFResourceContext;
-import org.apache.fop.pdf.PDFResources;
import org.apache.fop.pdf.PDFTextUtil;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RenderingContext;
-import org.apache.fop.render.intermediate.AbstractBinaryWritingIFPainter;
+import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
-import org.apache.fop.render.intermediate.extensions.AbstractAction;
-import org.apache.fop.render.intermediate.extensions.Bookmark;
-import org.apache.fop.render.intermediate.extensions.BookmarkTree;
-import org.apache.fop.render.intermediate.extensions.GoToXYAction;
-import org.apache.fop.render.intermediate.extensions.NamedDestination;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
/**
* IFPainter implementation that produces PDF.
*/
-public class PDFPainter extends AbstractBinaryWritingIFPainter {
+public class PDFPainter extends AbstractIFPainter {
/** logging instance */
private static Log log = LogFactory.getLog(PDFPainter.class);
+ private PDFDocumentHandler documentHandler;
+
/** Holds the intermediate format state */
protected IFState state;
- /** 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;
-
- /** the /Resources object of the PDF document being created */
- protected PDFResources pdfResources;
-
/** The current content generator */
protected PDFContentGenerator generator;
private PDFBorderPainter borderPainter;
- /** the current annotation list to add annotations to */
- protected PDFResourceContext currentContext;
-
- /** 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;
-
- /** Used for bookmarks/outlines. */
- private Map pageReferences = new java.util.HashMap();
-
/**
* Default constructor.
+ * @param documentHandler the parent document handler
*/
- public PDFPainter() {
- }
-
- /** {@inheritDoc} */
- public boolean supportsPagesOutOfOrder() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String getMimeType() {
- return MimeConstants.MIME_PDF;
+ public PDFPainter(PDFDocumentHandler documentHandler) {
+ super();
+ this.documentHandler = documentHandler;
+ this.generator = documentHandler.generator;
+ this.borderPainter = new PDFBorderPainter(this.generator);
+ this.state = IFState.create();
}
/** {@inheritDoc} */
- public void setUserAgent(FOUserAgent ua) {
- super.setUserAgent(ua);
- this.pdfUtil = new PDFRenderingUtil(ua);
+ protected FOUserAgent getUserAgent() {
+ return this.documentHandler.getUserAgent();
}
PDFRenderingUtil getPDFUtil() {
- return this.pdfUtil;
- }
-
- /** {@inheritDoc} */
- public void startDocument() throws IFException {
- try {
- if (getUserAgent() == null) {
- throw new IllegalStateException(
- "User agent must be set before starting PDF generation");
- }
- if (this.outputStream == null) {
- throw new IllegalStateException("OutputStream hasn't been set through setResult()");
- }
- this.pdfDoc = pdfUtil.setupPDFDocument(this.outputStream);
- } catch (IOException e) {
- throw new IFException("I/O error in startDocument()", e);
- }
+ return this.documentHandler.pdfUtil;
}
- /** {@inheritDoc} */
- public void endDocumentHeader() throws IFException {
- pdfUtil.generateDefaultXMPMetadata();
+ PDFDocument getPDFDoc() {
+ return this.documentHandler.pdfDoc;
}
- /** {@inheritDoc} */
- public void endDocument() throws IFException {
- try {
- pdfDoc.getResources().addFonts(pdfDoc, fontInfo);
- pdfDoc.outputTrailer(this.outputStream);
-
- this.pdfDoc = null;
-
- pdfResources = null;
- this.generator = null;
- currentContext = null;
- currentPage = null;
- } catch (IOException ioe) {
- throw new IFException("I/O error in endDocument()", ioe);
- }
- super.endDocument();
- }
-
- /** {@inheritDoc} */
- public void startPageSequence(String id) throws IFException {
- //TODO page sequence title, country and language
- }
-
- /** {@inheritDoc} */
- public void endPageSequence() throws IFException {
- //nop
- }
-
- /** {@inheritDoc} */
- public void startPage(int index, String name, Dimension size) throws IFException {
- this.pdfResources = this.pdfDoc.getResources();
-
- this.currentPage = this.pdfDoc.getFactory().makePage(
- this.pdfResources,
- (int)Math.round(size.getWidth() / 1000),
- (int)Math.round(size.getHeight() / 1000),
- index);
- //pageReferences.put(new Integer(index)/*page.getKey()*/, currentPage.referencePDF());
- //pvReferences.put(page.getKey(), page);
-
- pdfUtil.generatePageLabel(index, name);
-
- currentPageRef = currentPage.referencePDF();
- this.pageReferences.put(new Integer(index), new PageReference(currentPage, size));
-
- this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream, this.currentPage);
- // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFPainter's
- AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
- size.height / 1000f);
- generator.concatenate(basicPageTransform);
-
- this.borderPainter = new PDFBorderPainter(this.generator);
- }
-
- /** {@inheritDoc} */
- public void startPageContent() throws IFException {
- this.state = IFState.create();
- }
-
- /** {@inheritDoc} */
- public void endPageContent() throws IFException {
- assert this.state.pop() == null;
- }
-
- /** {@inheritDoc} */
- public void endPage() throws IFException {
- try {
- 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.generator.flushPDFDoc();
- this.generator = null;
- } catch (IOException ioe) {
- throw new IFException("I/O error in endPage()", ioe);
- }
+ FontInfo getFontInfo() {
+ return this.documentHandler.getFontInfo();
}
/** {@inheritDoc} */
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException {
- PDFXObject xobject = pdfDoc.getXObject(uri);
+ PDFXObject xobject = getPDFDoc().getXObject(uri);
if (xobject != null) {
placeImage(rect, xobject);
return;
/** {@inheritDoc} */
protected RenderingContext createRenderingContext() {
PDFRenderingContext pdfContext = new PDFRenderingContext(
- getUserAgent(), generator, currentPage, getFontInfo());
+ getUserAgent(), generator, this.documentHandler.currentPage, getFontInfo());
return pdfContext;
}
if (fontName == null) {
throw new NullPointerException("fontName must not be null");
}
- Typeface tf = (Typeface) fontInfo.getFonts().get(fontName);
+ Typeface tf = (Typeface)getFontInfo().getFonts().get(fontName);
if (tf instanceof LazyFont) {
tf = ((LazyFont)tf).getRealFont();
}
state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
//TODO Ignored: state.getFontVariant()
//TODO Opportunity for font caching if font state is more heavily used
- String fontKey = fontInfo.getInternalFontKey(triplet);
+ String fontKey = getFontInfo().getInternalFontKey(triplet);
int sizeMillipoints = state.getFontSize();
float fontSize = sizeMillipoints / 1000f;
if (tf instanceof SingleByteFont) {
singleByteFont = (SingleByteFont)tf;
}
- Font font = fontInfo.getFontInstance(triplet, sizeMillipoints);
+ Font font = getFontInfo().getFontInstance(triplet, sizeMillipoints);
String fontName = font.getFontName();
PDFTextUtil textutil = generator.getTextUtil();
}
}
- private void renderBookmarkTree(BookmarkTree tree) {
- Iterator iter = tree.getBookmarks().iterator();
- while (iter.hasNext()) {
- Bookmark b = (Bookmark)iter.next();
- renderBookmark(b, null);
- }
- }
-
- private void renderBookmark(Bookmark bookmark, PDFOutline parent) {
- if (parent == null) {
- parent = pdfDoc.getOutlineRoot();
- }
- PDFAction action = getAction(bookmark.getAction());
- PDFOutline pdfOutline = pdfDoc.getFactory().makeOutline(parent,
- bookmark.getTitle(), action, bookmark.isShown());
- Iterator iter = bookmark.getChildBookmarks().iterator();
- while (iter.hasNext()) {
- Bookmark b = (Bookmark)iter.next();
- renderBookmark(b, pdfOutline);
- }
- }
-
- private void renderNamedDestination(NamedDestination destination) {
- PDFAction action = getAction(destination.getAction());
- pdfDoc.getFactory().makeDestination(
- destination.getName(), action.makeReference());
- }
-
- private PDFAction getAction(AbstractAction action) {
- if (action instanceof GoToXYAction) {
- GoToXYAction a = (GoToXYAction)action;
- PageReference pageRef = (PageReference)this.pageReferences.get(
- new Integer(a.getPageIndex()));
- //Convert target location from millipoints to points and adjust for different
- //page origin
- Point2D p2d = new Point2D.Double(
- a.getTargetLocation().x / 1000.0,
- (pageRef.pageDimension.height - a.getTargetLocation().y) / 1000.0);
- return pdfDoc.getFactory().getPDFGoTo(pageRef.pageRef.toString(), p2d);
- } else {
- throw new UnsupportedOperationException("Unsupported action type: "
- + action + " (" + action.getClass().getName() + ")");
- }
- }
-
- /** {@inheritDoc} */
- public void handleExtensionObject(Object extension) throws IFException {
- if (extension instanceof XMPMetadata) {
- pdfUtil.renderXMPMetadata((XMPMetadata)extension);
- } else if (extension instanceof Metadata) {
- XMPMetadata wrapper = new XMPMetadata(((Metadata)extension));
- pdfUtil.renderXMPMetadata(wrapper);
- } else if (extension instanceof BookmarkTree) {
- renderBookmarkTree((BookmarkTree)extension);
- } else if (extension instanceof NamedDestination) {
- renderNamedDestination((NamedDestination)extension);
- } else {
- log.warn("Don't know how to handle extension object: "
- + extension + " (" + extension.getClass().getName());
- }
- }
-
- private static final class PageReference {
-
- private PDFReference pageRef;
- private Dimension pageDimension;
-
- private PageReference(PDFPage page, Dimension dim) {
- this.pageRef = page.makeReference();
- this.pageDimension = new Dimension(dim);
- }
- }
-
}
+++ /dev/null
-/*
- * 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.intermediate.AbstractIFPainterMaker;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
-
-/**
- * Painter factory for PDF output.
- */
-public class PDFPainterMaker extends AbstractIFPainterMaker {
-
- //TODO Revert to normal MIME after stabilization!
- private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF + ";mode=painter"};
-
- /** {@inheritDoc} */
- public IFPainter makePainter(FOUserAgent ua) {
- return new PDFPainter();
- }
-
- /** {@inheritDoc} */
- public boolean needsOutputStream() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String[] getSupportedMimeTypes() {
- return MIMES;
- }
-
- public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) {
- return new PDFRendererConfigurator(userAgent);
- }
-
-}
import org.apache.fop.render.DefaultFontResolver;
import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.Renderer;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.util.LogUtil;
/**
- * PDF renderer configurator
+ * PDF renderer configurator.
*/
public class PDFRendererConfigurator extends PrintRendererConfigurator
- implements IFPainterConfigurator {
+ implements IFDocumentHandlerConfigurator {
/**
* Default constructor
return filterMap;
}
- // ---=== IFPainter configuration ===---
+ // ---=== IFDocumentHandler configuration ===---
/** {@inheritDoc} */
- public void configure(IFPainter painter) throws FOPException {
- Configuration cfg = super.getRendererConfig(painter.getMimeType());
+ public void configure(IFDocumentHandler documentHandler) throws FOPException {
+ Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
if (cfg != null) {
- PDFPainter pdfPainter = (PDFPainter)painter;
- PDFRenderingUtil pdfUtil = pdfPainter.getPDFUtil();
+ PDFDocumentHandler pdfDocumentHandler = (PDFDocumentHandler)documentHandler;
+ PDFRenderingUtil pdfUtil = pdfDocumentHandler.getPDFUtil();
configure(cfg, pdfUtil);
}
}
/** {@inheritDoc} */
- public void setupFontInfo(IFPainter painter) throws FOPException {
+ public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
+ throws FOPException {
FontManager fontManager = userAgent.getFactory().getFontManager();
List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));
- FontEventListener listener = new FontEventAdapter(userAgent.getEventBroadcaster());
- Configuration cfg = super.getRendererConfig(painter.getMimeType());
+ Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
if (cfg != null) {
FontResolver fontResolver = new DefaultFontResolver(userAgent);
+ FontEventListener listener = new FontEventAdapter(
+ userAgent.getEventBroadcaster());
List fontList = buildFontList(cfg, fontResolver, listener);
fontCollections.add(new CustomFontCollection(fontResolver, fontList));
}
- FontInfo fontInfo = new FontInfo();
- fontInfo.setEventListener(listener);
fontManager.setup(fontInfo,
(FontCollection[])fontCollections.toArray(
new FontCollection[fontCollections.size()]));
- painter.setFontInfo(fontInfo);
+ documentHandler.setFontInfo(fontInfo);
}
}
import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.render.PrintRenderer;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.XMLHandler;
}
/** {@inheritDoc} */
- public void setupFontInfo(FontInfo inFontInfo) {
+ public void setupFontInfo(FontInfo inFontInfo) throws FOPException {
if (mimic != null) {
mimic.setupFontInfo(inFontInfo);
} else {
//nop
}
+ /**
+ * Convenience constructor. If the given handler also implements any of the EntityResolver,
+ * DTDHandler, LexicalHandler or ErrorHandler interfaces, these are set automatically.
+ * @param handler the content handler to delegate to
+ */
+ public DelegatingContentHandler(ContentHandler handler) {
+ setDelegateContentHandler(handler);
+ if (handler instanceof EntityResolver) {
+ setDelegateEntityResolver((EntityResolver)handler);
+ }
+ if (handler instanceof DTDHandler) {
+ setDelegateDTDHandler((DTDHandler)handler);
+ }
+ if (handler instanceof LexicalHandler) {
+ setDelegateLexicalHandler((LexicalHandler)handler);
+ }
+ if (handler instanceof ErrorHandler) {
+ setDelegateErrorHandler((ErrorHandler)handler);
+ }
+ }
+
/**
* @return the delegate that all ContentHandler events are forwarded to
*/
--- /dev/null
+/*
+ * 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.util;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class is a delegating SAX ContentHandler which has the purpose to provide a few handy
+ * methods that make life easier when generating SAX events.
+ */
+public class GenerationHelperContentHandler extends DelegatingContentHandler {
+
+ private static final Attributes EMPTY_ATTS = new AttributesImpl();
+
+ private String mainNamespace;
+
+ /**
+ * Main constructor. If the given handler also implements any of the EntityResolver,
+ * DTDHandler, LexicalHandler or ErrorHandler interfaces, these are set automatically.
+ * @param handler the SAX content handler to delegate all calls to
+ * @param mainNamespace the main namespace used for generated XML content when abbreviated
+ * ContentHandler calls are used.
+ */
+ public GenerationHelperContentHandler(ContentHandler handler, String mainNamespace) {
+ super(handler);
+ this.mainNamespace = mainNamespace;
+ }
+
+ /**
+ * Returns the main namespace used for generated XML content.
+ * @return the main namespace
+ */
+ public String getMainNamespace() {
+ return this.mainNamespace;
+ }
+
+ /**
+ * Sets the main namespace used for generated XML content when abbreviated ContentHandler
+ * calls are used.
+ * @param namespaceURI the new main namespace URI
+ */
+ public void setMainNamespace(String namespaceURI) {
+ this.mainNamespace = namespaceURI;
+ }
+
+ /**
+ * Convenience method to generate a startElement SAX event.
+ * @param localName the local name of the element
+ * @param atts the attributes
+ * @throws SAXException if a SAX exception occurs
+ */
+ public void startElement(String localName, Attributes atts) throws SAXException {
+ getDelegateContentHandler().startElement(getMainNamespace(), localName, localName, atts);
+ }
+
+ /**
+ * Convenience method to generate a startElement SAX event.
+ * @param localName the local name of the element
+ * @throws SAXException if a SAX exception occurs
+ */
+ public void startElement(String localName) throws SAXException {
+ getDelegateContentHandler().startElement(getMainNamespace(), localName, localName,
+ EMPTY_ATTS);
+ }
+
+ /**
+ * Convenience method to generate a endElement SAX event.
+ * @param localName the local name of the element
+ * @throws SAXException if a SAX exception occurs
+ */
+ public void endElement(String localName) throws SAXException {
+ getDelegateContentHandler().endElement(getMainNamespace(), localName, localName);
+ }
+
+ /**
+ * Convenience method to generate an empty element.
+ * @param localName the local name of the element
+ * @param atts the attributes
+ * @throws SAXException if a SAX exception occurs
+ */
+ public void element(String localName, Attributes atts) throws SAXException {
+ getDelegateContentHandler().startElement(getMainNamespace(), localName, localName, atts);
+ getDelegateContentHandler().endElement(getMainNamespace(), localName, localName);
+ }
+
+}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
/**
* A collection of utility method for XML handling.
}
}
+ /**
+ * Adds an attribute to a given {@code AttributesImpl} instance.
+ * @param atts the attributes collection
+ * @param attribute the attribute to add
+ * @param value the attribute's CDATA value
+ */
+ public static void addAttribute(AttributesImpl atts,
+ org.apache.xmlgraphics.util.QName attribute, String value) {
+ atts.addAttribute(attribute.getNamespaceURI(),
+ attribute.getLocalName(), attribute.getQName(), XMLUtil.CDATA, value);
+ }
+
+ /**
+ * Adds an attribute to a given {@code AttributesImpl} instance. The attribute will be
+ * added in the default namespace.
+ * @param atts the attributes collection
+ * @param localName the local name of the attribute
+ * @param value the attribute's CDATA value
+ */
+ public static void addAttribute(AttributesImpl atts, String localName, String value) {
+ atts.addAttribute("", localName, localName, XMLUtil.CDATA, value);
+ }
+
}
--- /dev/null
+org.apache.fop.render.svg.SVGDocumentHandlerMaker\r
+org.apache.fop.render.svg.SVGPrintDocumentHandlerMaker
\ No newline at end of file
+++ /dev/null
-org.apache.fop.render.svg.SVGPainterMaker\r
-org.apache.fop.render.svg.SVGPrintPainterMaker
\ No newline at end of file
--- /dev/null
+/*
+ * 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.svg;
+
+import org.xml.sax.SAXException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.xmp.Metadata;
+
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.intermediate.AbstractXMLWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.render.java2d.Java2DUtil;
+
+/**
+ * Abstract base class for SVG Painter implementations.
+ */
+public abstract class AbstractSVGDocumentHandler extends AbstractXMLWritingIFDocumentHandler
+ implements SVGConstants {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(AbstractSVGDocumentHandler.class);
+
+ /** Font configuration */
+ protected FontInfo fontInfo;
+
+ /** Holds the intermediate format state */
+ protected IFState state;
+
+ private static final int MODE_NORMAL = 0;
+ private static final int MODE_TEXT = 1;
+
+ private int mode = MODE_NORMAL;
+
+ /** {@inheritDoc} */
+ protected String getMainNamespace() {
+ return NAMESPACE;
+ }
+
+ /** {@inheritDoc} */
+ public FontInfo getFontInfo() {
+ return this.fontInfo;
+ }
+
+ /** {@inheritDoc} */
+ public void setFontInfo(FontInfo fontInfo) {
+ this.fontInfo = fontInfo;
+ }
+
+ /** {@inheritDoc} */
+ public void setDefaultFontInfo(FontInfo fontInfo) {
+ FontInfo fi = Java2DUtil.buildDefaultJava2DBasedFontInfo(fontInfo, getUserAgent());
+ setFontInfo(fi);
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ return null; //No configurator, yet.
+ }
+
+ /** {@inheritDoc} */
+ public void startDocumentHeader() throws IFException {
+ try {
+ handler.startElement("defs");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startDocumentHeader()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ try {
+ handler.endElement("defs");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startDocumentHeader()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void handleExtensionObject(Object extension) throws IFException {
+ if (extension instanceof Metadata) {
+ Metadata meta = (Metadata)extension;
+ try {
+ handler.startElement("metadata");
+ meta.toSAX(this.handler);
+ handler.endElement("metadata");
+ } catch (SAXException e) {
+ throw new IFException("SAX error while handling extension object", e);
+ }
+ } else {
+ log.debug("Don't know how to handle extension object. Ignoring: "
+ + extension + " (" + extension.getClass().getName() + ")");
+ }
+ }
+}
+++ /dev/null
-/*
- * 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.svg;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Paint;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-
-import org.w3c.dom.Document;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-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.ImageInfo;
-import org.apache.xmlgraphics.image.loader.ImageManager;
-import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-import org.apache.xmlgraphics.util.MimeConstants;
-import org.apache.xmlgraphics.util.QName;
-import org.apache.xmlgraphics.xmp.Metadata;
-
-import org.apache.fop.events.ResourceEventProducer;
-import org.apache.fop.fo.extensions.ExtensionElementMapping;
-import org.apache.fop.render.RenderingContext;
-import org.apache.fop.render.intermediate.AbstractXMLWritingIFPainter;
-import org.apache.fop.render.intermediate.IFConstants;
-import org.apache.fop.render.intermediate.IFException;
-import org.apache.fop.render.intermediate.IFState;
-import org.apache.fop.traits.BorderProps;
-import org.apache.fop.traits.RuleStyle;
-import org.apache.fop.util.ColorUtil;
-
-/**
- * Abstract base class for SVG Painter implementations.
- */
-public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter
- implements SVGConstants {
-
- /** logging instance */
- private static Log log = LogFactory.getLog(AbstractSVGPainter.class);
-
- /** Holds the intermediate format state */
- protected IFState state;
-
- private static final int MODE_NORMAL = 0;
- private static final int MODE_TEXT = 1;
-
- private int mode = MODE_NORMAL;
-
- /** {@inheritDoc} */
- protected String getMainNamespace() {
- return NAMESPACE;
- }
-
- /** {@inheritDoc} */
- public void startDocumentHeader() throws IFException {
- try {
- startElement("defs");
- } catch (SAXException e) {
- throw new IFException("SAX error in startDocumentHeader()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endDocumentHeader() throws IFException {
- try {
- endElement("defs");
- } catch (SAXException e) {
- throw new IFException("SAX error in startDocumentHeader()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void startPageContent() throws IFException {
- this.state = IFState.create();
- }
-
- /** {@inheritDoc} */
- public void endPageContent() throws IFException {
- assert this.state.pop() == null;
- }
-
- /** {@inheritDoc} */
- public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
- throws IFException {
- startViewport(toString(transform), size, clipRect);
- }
-
- /** {@inheritDoc} */
- public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect)
- throws IFException {
- startViewport(toString(transforms), size, clipRect);
- }
-
- private void startViewport(String transform, Dimension size, Rectangle clipRect)
- throws IFException {
- try {
- establish(MODE_NORMAL);
- AttributesImpl atts = new AttributesImpl();
- if (transform != null && transform.length() > 0) {
- atts.addAttribute("", "transform", "transform", CDATA, transform);
- }
- startElement("g", atts);
-
- atts.clear();
- atts.addAttribute("", "width", "width", CDATA, Integer.toString(size.width));
- atts.addAttribute("", "height", "height", CDATA, Integer.toString(size.height));
- if (clipRect != null) {
- int[] v = new int[] {
- clipRect.y,
- -clipRect.x + size.width - clipRect.width,
- -clipRect.y + size.height - clipRect.height,
- clipRect.x};
- int sum = 0;
- for (int i = 0; i < 4; i++) {
- sum += Math.abs(v[i]);
- }
- if (sum != 0) {
- StringBuffer sb = new StringBuffer("rect(");
- sb.append(v[0]).append(',');
- sb.append(v[1]).append(',');
- sb.append(v[2]).append(',');
- sb.append(v[3]).append(')');
- atts.addAttribute("", "clip", "clip", CDATA, sb.toString());
- }
- atts.addAttribute("", "overflow", "overflow", CDATA, "hidden");
- } else {
- atts.addAttribute("", "overflow", "overflow", CDATA, "visible");
- }
- startElement("svg", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in startBox()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endViewport() throws IFException {
- try {
- establish(MODE_NORMAL);
- endElement("svg");
- endElement("g");
- } catch (SAXException e) {
- throw new IFException("SAX error in endBox()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void startGroup(AffineTransform[] transforms) throws IFException {
- startGroup(toString(transforms));
- }
-
- /** {@inheritDoc} */
- public void startGroup(AffineTransform transform) throws IFException {
- startGroup(toString(transform));
- }
-
- private void startGroup(String transform) throws IFException {
- try {
- AttributesImpl atts = new AttributesImpl();
- if (transform != null && transform.length() > 0) {
- atts.addAttribute("", "transform", "transform", CDATA, transform);
- }
- startElement("g", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in startGroup()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endGroup() throws IFException {
- try {
- establish(MODE_NORMAL);
- endElement("g");
- } catch (SAXException e) {
- throw new IFException("SAX error in endGroup()", e);
- }
- }
-
- private static final QName CONVERSION_MODE
- = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
-
- /** {@inheritDoc} */
- public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException {
- try {
- establish(MODE_NORMAL);
-
- ImageManager manager = getUserAgent().getFactory().getImageManager();
- ImageInfo info = null;
- try {
- ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
- info = manager.getImageInfo(uri, sessionContext);
-
- String mime = info.getMimeType();
- String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE);
- if ("reference".equals(conversionMode)
- && (MimeConstants.MIME_GIF.equals(mime)
- || MimeConstants.MIME_JPEG.equals(mime)
- || MimeConstants.MIME_PNG.equals(mime)
- || MimeConstants.MIME_SVG.equals(mime))) {
- //Just reference the image
- //TODO Some additional URI rewriting might be necessary
- AttributesImpl atts = new AttributesImpl();
- addAttribute(atts, IFConstants.XLINK_HREF, uri);
- atts.addAttribute("", "x", "x", CDATA, Integer.toString(rect.x));
- atts.addAttribute("", "y", "y", CDATA, Integer.toString(rect.y));
- atts.addAttribute("", "width", "width", CDATA, Integer.toString(rect.width));
- atts.addAttribute("", "height", "height", CDATA, Integer.toString(rect.height));
- element("image", atts);
- } else {
- drawImageUsingImageHandler(info, rect);
- }
- } 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);
- }
- } catch (SAXException e) {
- throw new IFException("SAX error in drawImage()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException {
- try {
- establish(MODE_NORMAL);
-
- drawImageUsingDocument(doc, rect);
- } catch (SAXException e) {
- throw new IFException("SAX error in drawImage()", e);
- }
- }
-
- /** {@inheritDoc} */
- protected RenderingContext createRenderingContext() {
- SVGRenderingContext svgContext = new SVGRenderingContext(
- getUserAgent(), handler);
- return svgContext;
- }
-
- private static String toString(Paint paint) {
- //TODO Paint serialization: Fine-tune and extend!
- if (paint instanceof Color) {
- return ColorUtil.colorToString((Color)paint);
- } else {
- throw new UnsupportedOperationException("Paint not supported: " + paint);
- }
- }
-
- /** {@inheritDoc} */
- public void clipRect(Rectangle rect) throws IFException {
- //TODO Implement me!!!
- }
-
- /** {@inheritDoc} */
- public void fillRect(Rectangle rect, Paint fill) throws IFException {
- if (fill == null) {
- return;
- }
- try {
- establish(MODE_NORMAL);
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "x", "x", CDATA, Integer.toString(rect.x));
- atts.addAttribute("", "y", "y", CDATA, Integer.toString(rect.y));
- atts.addAttribute("", "width", "width", CDATA, Integer.toString(rect.width));
- atts.addAttribute("", "height", "height", CDATA, Integer.toString(rect.height));
- if (fill != null) {
- atts.addAttribute("", "fill", "fill", CDATA, toString(fill));
- }
- /* disabled
- if (stroke != null) {
- atts.addAttribute("", "stroke", "stroke", CDATA, toString(stroke));
- }*/
- element("rect", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in fillRect()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
- BorderProps start, BorderProps end) throws IFException {
- // TODO Auto-generated method stub
- }
-
- /** {@inheritDoc} */
- public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
- throws IFException {
- try {
- establish(MODE_NORMAL);
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "x1", "x1", CDATA, Integer.toString(start.x));
- atts.addAttribute("", "y1", "y1", CDATA, Integer.toString(start.y));
- atts.addAttribute("", "x2", "x2", CDATA, Integer.toString(end.x));
- atts.addAttribute("", "y2", "y2", CDATA, Integer.toString(end.y));
- atts.addAttribute("", "stroke-width", "stroke-width", CDATA, toString(color));
- atts.addAttribute("", "fill", "fill", CDATA, toString(color));
- //TODO Handle style parameter
- element("line", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in drawLine()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
- try {
- establish(MODE_TEXT);
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "x", "x", CDATA, Integer.toString(x));
- atts.addAttribute("", "y", "y", CDATA, Integer.toString(y));
- if (dx != null) {
- atts.addAttribute("", "dx", "dx", CDATA, toString(dx));
- }
- if (dy != null) {
- atts.addAttribute("", "dy", "dy", CDATA, toString(dy));
- }
- startElement("text", atts);
- char[] chars = text.toCharArray();
- handler.characters(chars, 0, chars.length);
- endElement("text");
- } catch (SAXException e) {
- throw new IFException("SAX error in setFont()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void setFont(String family, String style, Integer weight, String variant, Integer size,
- Color color) throws IFException {
- if (family != null) {
- state.setFontFamily(family);
- }
- if (style != null) {
- state.setFontStyle(style);
- }
- if (weight != null) {
- state.setFontWeight(weight.intValue());
- }
- if (variant != null) {
- state.setFontVariant(variant);
- }
- if (size != null) {
- state.setFontSize(size.intValue());
- }
- if (color != null) {
- state.setTextColor(color);
- }
- }
-
- private void leaveTextMode() throws SAXException {
- assert this.mode == MODE_TEXT;
- endElement("g");
- this.mode = MODE_NORMAL;
- }
-
- private void establish(int newMode) throws SAXException {
- switch (newMode) {
- case MODE_TEXT:
- enterTextMode();
- break;
- default:
- if (this.mode == MODE_TEXT) {
- leaveTextMode();
- }
- }
- }
-
- private void enterTextMode() throws SAXException {
- if (state.isFontChanged() && this.mode == MODE_TEXT) {
- leaveTextMode();
- }
- if (this.mode != MODE_TEXT) {
- startTextGroup();
- this.mode = MODE_TEXT;
- }
- }
-
- private void startTextGroup() throws SAXException {
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "font-family", "font-family",
- CDATA, state.getFontFamily());
- atts.addAttribute("", "font-style", "font-style",
- CDATA, state.getFontStyle());
- atts.addAttribute("", "font-weight", "font-weight",
- CDATA, Integer.toString(state.getFontWeight()));
- atts.addAttribute("", "font-variant", "font-variant",
- CDATA, state.getFontVariant());
- atts.addAttribute("", "font-size", "font-size",
- CDATA, Integer.toString(state.getFontSize()));
- atts.addAttribute("", "fill", "fill",
- CDATA, toString(state.getTextColor()));
- startElement("g", atts);
- state.resetFontChanged();
- }
-
- /** {@inheritDoc} */
- public void handleExtensionObject(Object extension) throws IFException {
- if (extension instanceof Metadata) {
- Metadata meta = (Metadata)extension;
- try {
- establish(MODE_NORMAL);
- startElement("metadata");
- meta.toSAX(this.handler);
- endElement("metadata");
- } catch (SAXException e) {
- throw new IFException("SAX error while handling extension object", e);
- }
- } else {
- throw new UnsupportedOperationException(
- "Don't know how to handle extension object: " + extension);
- }
- }
-}
--- /dev/null
+/*
+ * 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.svg;
+
+import java.awt.Dimension;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.render.bitmap.MultiFileRenderingUtil;
+import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.util.GenerationHelperContentHandler;
+import org.apache.fop.util.XMLUtil;
+
+/**
+ * {@code IFDocumentHandler} implementation that writes SVG 1.1.
+ */
+public class SVGDocumentHandler extends AbstractSVGDocumentHandler {
+
+ /** Helper class for generating multiple files */
+ private MultiFileRenderingUtil multiFileUtil;
+
+ private StreamResult firstStream;
+ private StreamResult currentStream;
+
+ private Document reusedParts;
+
+ /**
+ * Default constructor.
+ */
+ public SVGDocumentHandler() {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public boolean supportsPagesOutOfOrder() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MIME_TYPE;
+ }
+
+ /** {@inheritDoc} */
+ public void setResult(Result result) throws IFException {
+ if (result instanceof StreamResult) {
+ multiFileUtil = new MultiFileRenderingUtil(FILE_EXTENSION_SVG,
+ getUserAgent().getOutputFile());
+ this.firstStream = (StreamResult)result;
+ } else {
+ throw new UnsupportedOperationException("Result is not supported: " + result);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startDocument() throws IFException {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+ builderFactory.setNamespaceAware(true);
+ builderFactory.setValidating(false);
+ try {
+ DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ this.reusedParts = builder.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new IFException("Error while setting up a DOM for SVG generation", e);
+ }
+
+ try {
+ TransformerHandler toDOMHandler = tFactory.newTransformerHandler();
+ toDOMHandler.setResult(new DOMResult(this.reusedParts));
+ this.handler = decorate(toDOMHandler);
+ this.handler.startDocument();
+ } catch (SAXException se) {
+ throw new IFException("SAX error in startDocument()", se);
+ } catch (TransformerConfigurationException e) {
+ throw new IFException(
+ "Error while setting up a TransformerHandler for SVG generation", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endDocumentHeader() throws IFException {
+ super.endDocumentHeader();
+ try {
+ //Stop recording parts reused for each page
+ this.handler.endDocument();
+ this.handler = null;
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endDocumentHeader()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(String id) throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void endPageSequence() throws IFException {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void startPage(int index, String name, Dimension size) throws IFException {
+ OutputStream out;
+ try {
+ if (index == 0) {
+ out = null;
+ } else {
+ out = this.multiFileUtil.createOutputStream(index);
+ if (out == null) {
+ //TODO Convert to event
+ throw new IFException(
+ "No filename information available. Stopping after first page.", null);
+ }
+ }
+ } catch (IOException ioe) {
+ throw new IFException("I/O exception while setting up output file", ioe);
+ }
+ if (out == null) {
+ this.handler = decorate(createContentHandler(this.firstStream));
+ } else {
+ this.currentStream = new StreamResult(out);
+ this.handler = decorate(createContentHandler(this.currentStream));
+ }
+ if (false) {
+ final ContentHandler originalHandler = this.handler;
+ this.handler = decorate((ContentHandler)Proxy.newProxyInstance(
+ ContentHandler.class.getClassLoader(),
+ new Class[] {ContentHandler.class},
+ new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ String methodName = method.getName();
+ System.out.println(methodName + ":");
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ System.out.println(" " + args[i]);
+ }
+ }
+ return method.invoke(originalHandler, args);
+ }
+ }));
+ }
+ try {
+ handler.startDocument();
+ handler.startPrefixMapping("", NAMESPACE);
+ handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE);
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, "version", "1.1"); //SVG 1.1
+ /*
+ XMLUtil.addAttribute(atts, "index", Integer.toString(index));
+ XMLUtil.addAttribute(atts, "name", name);
+ */
+ XMLUtil.addAttribute(atts, "width", Float.toString(size.width / 1000f) + "pt");
+ XMLUtil.addAttribute(atts, "height", Float.toString(size.height / 1000f) + "pt");
+ XMLUtil.addAttribute(atts, "viewBox",
+ "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height));
+ handler.startElement("svg", atts);
+
+ try {
+ Transformer transformer = tFactory.newTransformer();
+ Source src = new DOMSource(this.reusedParts.getDocumentElement());
+ Result res = new SAXResult(new DelegatingFragmentContentHandler(this.handler));
+ transformer.transform(src, res);
+ } catch (TransformerConfigurationException tce) {
+ throw new IFException("Error setting up a Transformer", tce);
+ } catch (TransformerException te) {
+ if (te.getCause() instanceof SAXException) {
+ throw (SAXException)te.getCause();
+ } else {
+ throw new IFException("Error while serializing reused parts", te);
+ }
+ }
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startPage()", e);
+ }
+ }
+
+ private GenerationHelperContentHandler decorate(ContentHandler contentHandler) {
+ return new GenerationHelperContentHandler(contentHandler, getMainNamespace());
+ }
+
+ private void closeCurrentStream() {
+ if (this.currentStream != null) {
+ IOUtils.closeQuietly(currentStream.getOutputStream());
+ currentStream.setOutputStream(null);
+ IOUtils.closeQuietly(currentStream.getWriter());
+ currentStream.setWriter(null);
+ this.currentStream = null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public IFPainter startPageContent() throws IFException {
+ try {
+ handler.startElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startPageContent()", e);
+ }
+ return new SVGPainter(this, handler);
+ }
+
+ /** {@inheritDoc} */
+ public void endPageContent() throws IFException {
+ try {
+ handler.endElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endPageContent()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endPage() throws IFException {
+ try {
+ handler.endElement("svg");
+ this.handler.endDocument();
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endPage()", e);
+ }
+ closeCurrentStream();
+ }
+
+}
--- /dev/null
+/*
+ * 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.svg;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Document handler factory for SVG output.
+ */
+public class SVGDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
+
+ private static final String[] MIMES = new String[] {SVGConstants.MIME_TYPE};
+
+ /** {@inheritDoc} */
+ public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
+ SVGDocumentHandler handler = new SVGDocumentHandler();
+ handler.setUserAgent(ua);
+ return handler;
+ }
+
+ /** {@inheritDoc} */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
+ return null;
+ }
+
+}
package org.apache.fop.render.svg;
+import java.awt.Color;
import java.awt.Dimension;
+import java.awt.Paint;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
+import java.util.Map;
import org.w3c.dom.Document;
-import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
-import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.bitmap.MultiFileRenderingUtil;
-import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler;
+import org.apache.xmlgraphics.image.loader.ImageException;
+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.util.QName;
+import org.apache.xmlgraphics.xmp.Metadata;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.events.ResourceEventProducer;
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.intermediate.AbstractIFPainter;
+import org.apache.fop.render.intermediate.IFConstants;
import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.render.intermediate.IFUtil;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.RuleStyle;
+import org.apache.fop.util.ColorUtil;
+import org.apache.fop.util.GenerationHelperContentHandler;
+import org.apache.fop.util.XMLUtil;
/**
* IFPainter implementation that writes SVG.
*/
-public class SVGPainter extends AbstractSVGPainter {
+public class SVGPainter extends AbstractIFPainter implements SVGConstants {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(SVGPainter.class);
+
+ /** Holds the intermediate format state */
+ protected IFState state;
- /** Helper class for generating multiple files */
- private MultiFileRenderingUtil multiFileUtil;
+ private AbstractSVGDocumentHandler parent;
- private StreamResult firstStream;
- private StreamResult currentStream;
+ /** The SAX content handler that receives the generated XML events. */
+ protected GenerationHelperContentHandler handler;
- private Document reusedParts;
+ private static final int MODE_NORMAL = 0;
+ private static final int MODE_TEXT = 1;
+
+ private int mode = MODE_NORMAL;
/**
- * Default constructor.
+ * Main constructor.
+ * @param parent the parent document handler
+ * @param contentHandler the target SAX content handler
*/
- public SVGPainter() {
- //nop
+ public SVGPainter(AbstractSVGDocumentHandler parent,
+ GenerationHelperContentHandler contentHandler) {
+ super();
+ this.parent = parent;
+ this.handler = contentHandler;
+ this.state = IFState.create();
}
/** {@inheritDoc} */
- public boolean supportsPagesOutOfOrder() {
- return true;
+ protected FOUserAgent getUserAgent() {
+ return parent.getUserAgent();
}
/** {@inheritDoc} */
- public String getMimeType() {
- return MIME_TYPE;
+ public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
+ throws IFException {
+ startViewport(IFUtil.toString(transform), size, clipRect);
}
/** {@inheritDoc} */
- public void setResult(Result result) throws IFException {
- if (result instanceof StreamResult) {
- multiFileUtil = new MultiFileRenderingUtil(FILE_EXTENSION_SVG,
- getUserAgent().getOutputFile());
- this.firstStream = (StreamResult)result;
- } else {
- throw new UnsupportedOperationException("Result is not supported: " + result);
- }
+ public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect)
+ throws IFException {
+ startViewport(IFUtil.toString(transforms), size, clipRect);
}
- /** {@inheritDoc} */
- public void startDocument() throws IFException {
- DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
- builderFactory.setNamespaceAware(true);
- builderFactory.setValidating(false);
+ private void startViewport(String transform, Dimension size, Rectangle clipRect)
+ throws IFException {
try {
- DocumentBuilder builder = builderFactory.newDocumentBuilder();
- this.reusedParts = builder.newDocument();
- } catch (ParserConfigurationException e) {
- throw new IFException("Error while setting up a DOM for SVG generation", e);
+ establish(MODE_NORMAL);
+ AttributesImpl atts = new AttributesImpl();
+ if (transform != null && transform.length() > 0) {
+ XMLUtil.addAttribute(atts, "transform", transform);
+ }
+ handler.startElement("g", atts);
+
+ atts.clear();
+ XMLUtil.addAttribute(atts, "width", Integer.toString(size.width));
+ XMLUtil.addAttribute(atts, "height", Integer.toString(size.height));
+ if (clipRect != null) {
+ int[] v = new int[] {
+ clipRect.y,
+ -clipRect.x + size.width - clipRect.width,
+ -clipRect.y + size.height - clipRect.height,
+ clipRect.x};
+ int sum = 0;
+ for (int i = 0; i < 4; i++) {
+ sum += Math.abs(v[i]);
+ }
+ if (sum != 0) {
+ StringBuffer sb = new StringBuffer("rect(");
+ sb.append(v[0]).append(',');
+ sb.append(v[1]).append(',');
+ sb.append(v[2]).append(',');
+ sb.append(v[3]).append(')');
+ XMLUtil.addAttribute(atts, "clip", sb.toString());
+ }
+ XMLUtil.addAttribute(atts, "overflow", "hidden");
+ } else {
+ XMLUtil.addAttribute(atts, "overflow", "visible");
+ }
+ handler.startElement("svg", atts);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startBox()", e);
}
+ }
+ /** {@inheritDoc} */
+ public void endViewport() throws IFException {
try {
- TransformerHandler toDOMHandler = tFactory.newTransformerHandler();
- toDOMHandler.setResult(new DOMResult(this.reusedParts));
- this.handler = toDOMHandler;
- this.handler.startDocument();
- } catch (SAXException se) {
- throw new IFException("SAX error in startDocument()", se);
- } catch (TransformerConfigurationException e) {
- throw new IFException(
- "Error while setting up a TransformerHandler for SVG generation", e);
+ establish(MODE_NORMAL);
+ handler.endElement("svg");
+ handler.endElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endBox()", e);
}
}
/** {@inheritDoc} */
- public void endDocument() throws IFException {
- //nop
+ public void startGroup(AffineTransform[] transforms) throws IFException {
+ startGroup(IFUtil.toString(transforms));
}
/** {@inheritDoc} */
- public void endDocumentHeader() throws IFException {
- super.endDocumentHeader();
+ public void startGroup(AffineTransform transform) throws IFException {
+ startGroup(IFUtil.toString(transform));
+ }
+
+ private void startGroup(String transform) throws IFException {
try {
- //Stop recording parts reused for each page
- this.handler.endDocument();
- this.handler = null;
+ AttributesImpl atts = new AttributesImpl();
+ if (transform != null && transform.length() > 0) {
+ XMLUtil.addAttribute(atts, "transform", transform);
+ }
+ handler.startElement("g", atts);
} catch (SAXException e) {
- throw new IFException("SAX error in endDocumentHeader()", e);
+ throw new IFException("SAX error in startGroup()", e);
}
}
/** {@inheritDoc} */
- public void startPageSequence(String id) throws IFException {
- //nop
+ public void endGroup() throws IFException {
+ try {
+ establish(MODE_NORMAL);
+ handler.endElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endGroup()", e);
+ }
}
- /** {@inheritDoc} */
- public void endPageSequence() throws IFException {
- //nop
- }
+ private static final QName CONVERSION_MODE
+ = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
/** {@inheritDoc} */
- public void startPage(int index, String name, Dimension size) throws IFException {
- OutputStream out;
+ public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException {
try {
- if (index == 0) {
- out = null;
- } else {
- out = this.multiFileUtil.createOutputStream(index);
- if (out == null) {
- //TODO Convert to event
- throw new IFException(
- "No filename information available. Stopping after first page.", null);
+ establish(MODE_NORMAL);
+
+ ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageInfo info = null;
+ try {
+ ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
+ info = manager.getImageInfo(uri, sessionContext);
+
+ String mime = info.getMimeType();
+ String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE);
+ if ("reference".equals(conversionMode)
+ && (MimeConstants.MIME_GIF.equals(mime)
+ || MimeConstants.MIME_JPEG.equals(mime)
+ || MimeConstants.MIME_PNG.equals(mime)
+ || MimeConstants.MIME_SVG.equals(mime))) {
+ //Just reference the image
+ //TODO Some additional URI rewriting might be necessary
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, IFConstants.XLINK_HREF, uri);
+ XMLUtil.addAttribute(atts, "x", Integer.toString(rect.x));
+ XMLUtil.addAttribute(atts, "y", Integer.toString(rect.y));
+ XMLUtil.addAttribute(atts, "width", Integer.toString(rect.width));
+ XMLUtil.addAttribute(atts, "height", Integer.toString(rect.height));
+ handler.element("image", atts);
+ } else {
+ drawImageUsingImageHandler(info, rect);
}
+ } 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);
}
- } catch (IOException ioe) {
- throw new IFException("I/O exception while setting up output file", ioe);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in drawImage()", e);
}
- if (out == null) {
- this.handler = createContentHandler(this.firstStream);
+ }
+
+ /** {@inheritDoc} */
+ public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException {
+ try {
+ establish(MODE_NORMAL);
+
+ drawImageUsingDocument(doc, rect);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in drawImage()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected RenderingContext createRenderingContext() {
+ SVGRenderingContext svgContext = new SVGRenderingContext(
+ getUserAgent(), handler);
+ return svgContext;
+ }
+
+ private static String toString(Paint paint) {
+ //TODO Paint serialization: Fine-tune and extend!
+ if (paint instanceof Color) {
+ return ColorUtil.colorToString((Color)paint);
} else {
- this.currentStream = new StreamResult(out);
- this.handler = createContentHandler(this.currentStream);
+ throw new UnsupportedOperationException("Paint not supported: " + paint);
}
- if (false) {
- final ContentHandler originalHandler = this.handler;
- this.handler = (ContentHandler)Proxy.newProxyInstance(
- ContentHandler.class.getClassLoader(),
- new Class[] {ContentHandler.class},
- new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- String methodName = method.getName();
- System.out.println(methodName + ":");
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- System.out.println(" " + args[i]);
- }
- }
- return method.invoke(originalHandler, args);
- }
- });
+ }
+
+ /** {@inheritDoc} */
+ public void clipRect(Rectangle rect) throws IFException {
+ //TODO Implement me!!!
+ }
+
+ /** {@inheritDoc} */
+ public void fillRect(Rectangle rect, Paint fill) throws IFException {
+ if (fill == null) {
+ return;
}
try {
- handler.startDocument();
- handler.startPrefixMapping("", NAMESPACE);
- handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE);
+ establish(MODE_NORMAL);
AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "version", "version", CDATA, "1.1"); //SVG 1.1
- /*
- atts.addAttribute("", "index", "index", CDATA, Integer.toString(index));
- atts.addAttribute("", "name", "name", CDATA, name);
- */
- atts.addAttribute("", "width", "width", CDATA,
- Float.toString(size.width / 1000f) + "pt");
- atts.addAttribute("", "height", "height", CDATA,
- Float.toString(size.height / 1000f) + "pt");
- atts.addAttribute("", "viewBox", "viewBox", CDATA,
- "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height));
- startElement("svg", atts);
-
- try {
- Transformer transformer = tFactory.newTransformer();
- Source src = new DOMSource(this.reusedParts.getDocumentElement());
- Result res = new SAXResult(new DelegatingFragmentContentHandler(this.handler));
- transformer.transform(src, res);
- } catch (TransformerConfigurationException tce) {
- throw new IFException("Error setting up a Transformer", tce);
- } catch (TransformerException te) {
- if (te.getCause() instanceof SAXException) {
- throw (SAXException)te.getCause();
- } else {
- throw new IFException("Error while serializing reused parts", te);
- }
+ XMLUtil.addAttribute(atts, "x", Integer.toString(rect.x));
+ XMLUtil.addAttribute(atts, "y", Integer.toString(rect.y));
+ XMLUtil.addAttribute(atts, "width", Integer.toString(rect.width));
+ XMLUtil.addAttribute(atts, "height", Integer.toString(rect.height));
+ if (fill != null) {
+ XMLUtil.addAttribute(atts, "fill", toString(fill));
}
+ /* disabled
+ if (stroke != null) {
+ XMLUtil.addAttribute(atts, "stroke", toString(stroke));
+ }*/
+ handler.element("rect", atts);
} catch (SAXException e) {
- throw new IFException("SAX error in startPage()", e);
+ throw new IFException("SAX error in fillRect()", e);
}
}
- private void closeCurrentStream() {
- if (this.currentStream != null) {
- IOUtils.closeQuietly(currentStream.getOutputStream());
- currentStream.setOutputStream(null);
- IOUtils.closeQuietly(currentStream.getWriter());
- currentStream.setWriter(null);
- this.currentStream = null;
- }
+ /** {@inheritDoc} */
+ public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
+ BorderProps start, BorderProps end) throws IFException {
+ // TODO Auto-generated method stub
}
/** {@inheritDoc} */
- public void startPageContent() throws IFException {
- super.startPageContent();
+ public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
+ throws IFException {
try {
- startElement("g");
+ establish(MODE_NORMAL);
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, "x1", Integer.toString(start.x));
+ XMLUtil.addAttribute(atts, "y1", Integer.toString(start.y));
+ XMLUtil.addAttribute(atts, "x2", Integer.toString(end.x));
+ XMLUtil.addAttribute(atts, "y2", Integer.toString(end.y));
+ XMLUtil.addAttribute(atts, "stroke-width", toString(color));
+ XMLUtil.addAttribute(atts, "fill", toString(color));
+ //TODO Handle style parameter
+ handler.element("line", atts);
} catch (SAXException e) {
- throw new IFException("SAX error in startPageContent()", e);
+ throw new IFException("SAX error in drawLine()", e);
}
}
/** {@inheritDoc} */
- public void endPageContent() throws IFException {
+ public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
try {
- endElement("g");
+ establish(MODE_TEXT);
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, "x", Integer.toString(x));
+ XMLUtil.addAttribute(atts, "y", Integer.toString(y));
+ if (dx != null) {
+ XMLUtil.addAttribute(atts, "dx", IFUtil.toString(dx));
+ }
+ if (dy != null) {
+ XMLUtil.addAttribute(atts, "dy", IFUtil.toString(dy));
+ }
+ handler.startElement("text", atts);
+ char[] chars = text.toCharArray();
+ handler.characters(chars, 0, chars.length);
+ handler.endElement("text");
} catch (SAXException e) {
- throw new IFException("SAX error in endPageContent()", e);
+ throw new IFException("SAX error in setFont()", e);
}
- super.endPageContent();
}
/** {@inheritDoc} */
- public void endPage() throws IFException {
- try {
- endElement("svg");
- this.handler.endDocument();
- } catch (SAXException e) {
- throw new IFException("SAX error in endPage()", e);
+ public void setFont(String family, String style, Integer weight, String variant, Integer size,
+ Color color) throws IFException {
+ if (family != null) {
+ state.setFontFamily(family);
+ }
+ if (style != null) {
+ state.setFontStyle(style);
+ }
+ if (weight != null) {
+ state.setFontWeight(weight.intValue());
+ }
+ if (variant != null) {
+ state.setFontVariant(variant);
+ }
+ if (size != null) {
+ state.setFontSize(size.intValue());
+ }
+ if (color != null) {
+ state.setTextColor(color);
+ }
+ }
+
+ private void leaveTextMode() throws SAXException {
+ assert this.mode == MODE_TEXT;
+ handler.endElement("g");
+ this.mode = MODE_NORMAL;
+ }
+
+ private void establish(int newMode) throws SAXException {
+ switch (newMode) {
+ case MODE_TEXT:
+ enterTextMode();
+ break;
+ default:
+ if (this.mode == MODE_TEXT) {
+ leaveTextMode();
+ }
+ }
+ }
+
+ private void enterTextMode() throws SAXException {
+ if (state.isFontChanged() && this.mode == MODE_TEXT) {
+ leaveTextMode();
+ }
+ if (this.mode != MODE_TEXT) {
+ startTextGroup();
+ this.mode = MODE_TEXT;
+ }
+ }
+
+ private void startTextGroup() throws SAXException {
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, "font-family", state.getFontFamily());
+ XMLUtil.addAttribute(atts, "font-style", state.getFontStyle());
+ XMLUtil.addAttribute(atts, "font-weight", Integer.toString(state.getFontWeight()));
+ XMLUtil.addAttribute(atts, "font-variant", state.getFontVariant());
+ XMLUtil.addAttribute(atts, "font-size", Integer.toString(state.getFontSize()));
+ XMLUtil.addAttribute(atts, "fill", toString(state.getTextColor()));
+ handler.startElement("g", atts);
+ state.resetFontChanged();
+ }
+
+ /** {@inheritDoc} */
+ public void handleExtensionObject(Object extension) throws IFException {
+ if (extension instanceof Metadata) {
+ Metadata meta = (Metadata)extension;
+ try {
+ establish(MODE_NORMAL);
+ handler.startElement("metadata");
+ meta.toSAX(this.handler);
+ handler.endElement("metadata");
+ } catch (SAXException e) {
+ throw new IFException("SAX error while handling extension object", e);
+ }
+ } else {
+ throw new UnsupportedOperationException(
+ "Don't know how to handle extension object: " + extension);
}
- closeCurrentStream();
}
}
+++ /dev/null
-/*
- * 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.svg;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.render.intermediate.AbstractIFPainterMaker;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
-
-/**
- * Painter factory for SVG output.
- */
-public class SVGPainterMaker extends AbstractIFPainterMaker {
-
- private static final String[] MIMES = new String[] {SVGConstants.MIME_TYPE};
-
- /** {@inheritDoc} */
- public IFPainter makePainter(FOUserAgent ua) {
- return new SVGPainter();
- }
-
- /** {@inheritDoc} */
- public boolean needsOutputStream() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String[] getSupportedMimeTypes() {
- return MIMES;
- }
-
- /** {@inheritDoc} */
- public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) {
- // TODO Auto-generated method stub
- return null;
- }
-
-}
--- /dev/null
+/*
+ * 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.svg;
+
+import java.awt.Dimension;
+
+import javax.xml.transform.Result;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import org.apache.fop.render.intermediate.IFConstants;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.util.XMLUtil;
+
+/**
+ * {@code IFDocumentHandler} implementation that writes SVG Print.
+ */
+public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler {
+
+ /**
+ * Default constructor.
+ */
+ public SVGPrintDocumentHandler() {
+ //nop
+ }
+
+ /**
+ * Creates a new SVGPrintPainter that sends the XML content it generates to the given
+ * SAX ContentHandler.
+ * @param result the JAXP Result object to receive the generated content
+ * @throws IFException if an error occurs setting up the output
+ */
+ public SVGPrintDocumentHandler(Result result) throws IFException {
+ setResult(result);
+ }
+
+ /** {@inheritDoc} */
+ public boolean supportsPagesOutOfOrder() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MIME_SVG_PRINT;
+ }
+
+ /** {@inheritDoc} */
+ public void startDocument() throws IFException {
+ try {
+ handler.startDocument();
+ handler.startPrefixMapping("", NAMESPACE);
+ handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE);
+ handler.startPrefixMapping("if", IFConstants.NAMESPACE);
+ AttributesImpl atts = new AttributesImpl();
+ XMLUtil.addAttribute(atts, "version", "1.2"); //SVG Print is SVG 1.2
+ handler.startElement("svg", atts);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startDocument()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ try {
+ handler.endElement("svg");
+ handler.endDocument();
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endDocument()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(String id) throws IFException {
+ try {
+ AttributesImpl atts = new AttributesImpl();
+ if (id != null) {
+ atts.addAttribute(XML_NAMESPACE, "id", "xml:id", CDATA, id);
+ }
+ handler.startElement("pageSet", atts);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startPageSequence()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endPageSequence() throws IFException {
+ try {
+ handler.endElement("pageSet");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endPageSequence()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startPage(int index, String name, Dimension size) throws IFException {
+ try {
+ AttributesImpl atts = new AttributesImpl();
+ /*
+ XMLUtil.addAttribute(atts, "index", Integer.toString(index));
+ XMLUtil.addAttribute(atts, "name", name);
+ */
+ //NOTE: SVG Print doesn't support individual page sizes for each page
+ atts.addAttribute(IFConstants.NAMESPACE, "width", "if:width",
+ CDATA, Integer.toString(size.width));
+ atts.addAttribute(IFConstants.NAMESPACE, "height", "if:height",
+ CDATA, Integer.toString(size.height));
+ atts.addAttribute(IFConstants.NAMESPACE, "viewBox", "if:viewBox", CDATA,
+ "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height));
+ handler.startElement("page", atts);
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startPage()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startPageHeader() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void endPageHeader() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public IFPainter startPageContent() throws IFException {
+ try {
+ handler.startElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in startPageContent()", e);
+ }
+ return new SVGPainter(this, handler);
+ }
+
+ /** {@inheritDoc} */
+ public void endPageContent() throws IFException {
+ try {
+ handler.endElement("g");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endPageContent()", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startPageTrailer() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void endPageTrailer() throws IFException {
+ }
+
+ /** {@inheritDoc} */
+ public void endPage() throws IFException {
+ try {
+ handler.endElement("page");
+ } catch (SAXException e) {
+ throw new IFException("SAX error in endPage()", e);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.svg;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Document handler factory for SVG Print output.
+ */
+public class SVGPrintDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
+
+ private static final String[] MIMES = new String[] {SVGConstants.MIME_SVG_PRINT};
+
+ /** {@inheritDoc} */
+ public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
+ SVGPrintDocumentHandler handler = new SVGPrintDocumentHandler();
+ handler.setUserAgent(ua);
+ return handler;
+ }
+
+ /** {@inheritDoc} */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+ /** {@inheritDoc} */
+ public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
+ return null;
+ }
+
+}
+++ /dev/null
-/*
- * 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.svg;
-
-import java.awt.Dimension;
-
-import javax.xml.transform.Result;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import org.apache.fop.render.intermediate.IFConstants;
-import org.apache.fop.render.intermediate.IFException;
-
-/**
- * IFPainter implementation that writes SVG Print.
- */
-public class SVGPrintPainter extends AbstractSVGPainter {
-
- /**
- * Default constructor.
- */
- public SVGPrintPainter() {
- //nop
- }
-
- /**
- * Creates a new SVGPrintPainter that sends the XML content it generates to the given
- * SAX ContentHandler.
- * @param result the JAXP Result object to receive the generated content
- * @throws IFException if an error occurs setting up the output
- */
- public SVGPrintPainter(Result result) throws IFException {
- setResult(result);
- }
-
- /** {@inheritDoc} */
- public boolean supportsPagesOutOfOrder() {
- return false;
- }
-
- /** {@inheritDoc} */
- public String getMimeType() {
- return MIME_SVG_PRINT;
- }
-
- /** {@inheritDoc} */
- public void startDocument() throws IFException {
- try {
- handler.startDocument();
- handler.startPrefixMapping("", NAMESPACE);
- handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE);
- handler.startPrefixMapping("if", IFConstants.NAMESPACE);
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "version", "version", CDATA, "1.2"); //SVG Print is SVG 1.2
- startElement("svg", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in startDocument()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endDocument() throws IFException {
- try {
- endElement("svg");
- handler.endDocument();
- } catch (SAXException e) {
- throw new IFException("SAX error in endDocument()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void startPageSequence(String id) throws IFException {
- try {
- AttributesImpl atts = new AttributesImpl();
- if (id != null) {
- atts.addAttribute(XML_NAMESPACE, "id", "xml:id", CDATA, id);
- }
- startElement("pageSet", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in startPageSequence()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endPageSequence() throws IFException {
- try {
- endElement("pageSet");
- } catch (SAXException e) {
- throw new IFException("SAX error in endPageSequence()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void startPage(int index, String name, Dimension size) throws IFException {
- try {
- AttributesImpl atts = new AttributesImpl();
- /*
- atts.addAttribute("", "index", "index", CDATA, Integer.toString(index));
- atts.addAttribute("", "name", "name", CDATA, name);
- */
- //NOTE: SVG Print doesn't support individual page sizes for each page
- atts.addAttribute(IFConstants.NAMESPACE, "width", "if:width",
- CDATA, Integer.toString(size.width));
- atts.addAttribute(IFConstants.NAMESPACE, "height", "if:height",
- CDATA, Integer.toString(size.height));
- atts.addAttribute(IFConstants.NAMESPACE, "viewBox", "if:viewBox", CDATA,
- "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height));
- startElement("page", atts);
- } catch (SAXException e) {
- throw new IFException("SAX error in startPage()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void startPageHeader() throws IFException {
- }
-
- /** {@inheritDoc} */
- public void endPageHeader() throws IFException {
- }
-
- /** {@inheritDoc} */
- public void startPageContent() throws IFException {
- super.startPageContent();
- try {
- startElement("g");
- } catch (SAXException e) {
- throw new IFException("SAX error in startPageContent()", e);
- }
- }
-
- /** {@inheritDoc} */
- public void endPageContent() throws IFException {
- try {
- endElement("g");
- } catch (SAXException e) {
- throw new IFException("SAX error in endPageContent()", e);
- }
- super.endPageContent();
- }
-
- /** {@inheritDoc} */
- public void startPageTrailer() throws IFException {
- }
-
- /** {@inheritDoc} */
- public void endPageTrailer() throws IFException {
- }
-
- /** {@inheritDoc} */
- public void endPage() throws IFException {
- try {
- endElement("page");
- } catch (SAXException e) {
- throw new IFException("SAX error in endPage()", e);
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.svg;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.render.intermediate.AbstractIFPainterMaker;
-import org.apache.fop.render.intermediate.IFPainter;
-import org.apache.fop.render.intermediate.IFPainterConfigurator;
-
-/**
- * Painter factory for SVG Print output.
- */
-public class SVGPrintPainterMaker extends AbstractIFPainterMaker {
-
- private static final String[] MIMES = new String[] {SVGConstants.MIME_SVG_PRINT};
-
- /** {@inheritDoc} */
- public IFPainter makePainter(FOUserAgent ua) {
- return new SVGPrintPainter();
- }
-
- /** {@inheritDoc} */
- public boolean needsOutputStream() {
- return true;
- }
-
- /** {@inheritDoc} */
- public String[] getSupportedMimeTypes() {
- return MIMES;
- }
-
- /** {@inheritDoc} */
- public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) {
- // TODO Auto-generated method stub
- return null;
- }
-
-}
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.render.Renderer;
-import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFParser;
import org.apache.fop.render.intermediate.IFRenderer;
import org.apache.fop.render.intermediate.IFSerializer;
FOUserAgent userAgent = createUserAgent();
//Create an instance of the target renderer so the XMLRenderer can use its font setup
- Renderer targetRenderer = userAgent.getRendererFactory().createRenderer(
+ IFDocumentHandler targetHandler = userAgent.getRendererFactory().createDocumentHandler(
userAgent, getTargetMIME());
- //Setup renderer
- IFRenderer renderer = new IFRenderer();
- renderer.setUserAgent(userAgent);
- renderer.mimicRenderer(targetRenderer);
-
//Setup painter
IFSerializer serializer = new IFSerializer();
serializer.setUserAgent(userAgent);
+ serializer.mimicDocumentHandler(targetHandler);
serializer.setResult(domResult);
- renderer.setPainter(serializer);
+ //Setup renderer
+ IFRenderer renderer = new IFRenderer();
+ renderer.setUserAgent(userAgent);
+
+ renderer.setDocumentHandler(serializer);
userAgent.setRendererOverride(renderer);
Fop fop = fopFactory.newFop(userAgent);
FOUserAgent userAgent = createUserAgent();
- IFPainter painter = userAgent.getRendererFactory().createPainter(
+ IFDocumentHandler documentHandler = userAgent.getRendererFactory().createDocumentHandler(
userAgent, getTargetMIME());
- painter.setResult(new StreamResult(out));
- painter.setDefaultFontInfo();
- parser.parse(src, painter, userAgent);
+ documentHandler.setResult(new StreamResult(out));
+ documentHandler.setDefaultFontInfo(new FontInfo());
+ parser.parse(src, documentHandler, userAgent);
}
/** {@inheritDoc} */
IFSerializer serializer = new IFSerializer();
DOMResult result = new DOMResult();
serializer.setResult(result);
- ifRenderer.setPainter(serializer);
+ ifRenderer.setDocumentHandler(serializer);
ua.setRendererOverride(ifRenderer);
FontInfo fontInfo = new FontInfo();