aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/render/pcl
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/render/pcl')
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java9
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRenderer.java255
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererContext.java17
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererContextConstants.java32
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLSVGHandler.java8
5 files changed, 194 insertions, 127 deletions
diff --git a/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java b/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java
index 80c010afc..06a4d37a0 100644
--- a/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java
+++ b/src/java/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java
@@ -28,11 +28,13 @@ import java.io.IOException;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+
import org.apache.fop.render.AbstractGraphics2DAdapter;
-import org.apache.fop.render.Graphics2DImagePainter;
import org.apache.fop.render.RendererContext;
import org.apache.fop.util.UnitConv;
-import org.apache.xmlgraphics.java2d.GraphicContext;
/**
* Graphics2DAdapter implementation for PCL and HP GL/2.
@@ -110,7 +112,8 @@ public class PCLGraphics2DAdapter extends AbstractGraphics2DAdapter {
if (!painted) {
//Fallback solution: Paint to a BufferedImage
int resolution = (int)Math.round(context.getUserAgent().getTargetResolution());
- BufferedImage bi = paintToBufferedImage(painter, pclContext, resolution, true, false);
+ BufferedImage bi = paintToBufferedImage(painter, pclContext,
+ resolution, !pclContext.isColorCanvas(), false);
pcl.setCursorPos(x, y);
gen.paintBitmap(bi, new Dimension(width, height), pclContext.isSourceTransparency());
diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
index 732ce0f8f..b48c28089 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
@@ -24,24 +24,17 @@ import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
-import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.Raster;
import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
@@ -52,7 +45,19 @@ import org.w3c.dom.Document;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.MimeConstants;
@@ -70,16 +75,12 @@ import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.Viewport;
import org.apache.fop.area.inline.WordArea;
+import org.apache.fop.datatypes.URISpecification;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontMetrics;
-import org.apache.fop.image.EPSImage;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.ImageFactory;
-import org.apache.fop.image.XMLImage;
import org.apache.fop.render.Graphics2DAdapter;
-import org.apache.fop.render.Graphics2DImagePainter;
import org.apache.fop.render.PrintRenderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContextConstants;
@@ -135,6 +136,13 @@ public class PCLRenderer extends PrintRenderer {
private boolean allTextAsBitmaps = false;
/**
+ * Controls whether an RGB canvas is used when converting Java2D graphics to bitmaps.
+ * This can be used to work around problems with Apache Batik, for example, but setting
+ * this to true will increase memory consumption.
+ */
+ private boolean useColorCanvas = false;
+
+ /**
* Controls whether the generation of PJL commands gets disabled.
*/
private boolean disabledPJL = false;
@@ -991,87 +999,88 @@ public class PCLRenderer extends PrintRenderer {
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
+ protected RendererContext createRendererContext(int x, int y, int width, int height,
+ Map foreignAttributes) {
+ RendererContext context = super.createRendererContext(
+ x, y, width, height, foreignAttributes);
+ context.setProperty(PCLRendererContextConstants.PCL_COLOR_CANVAS,
+ Boolean.valueOf(this.useColorCanvas));
+ return context;
+ }
+
+ /** {@inheritDoc} */
public void renderImage(Image image, Rectangle2D pos) {
drawImage(image.getURL(), pos, image.getForeignAttributes());
}
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[]
+ {ImageFlavor.GRAPHICS2D,
+ ImageFlavor.BUFFERED_IMAGE,
+ ImageFlavor.RENDERED_IMAGE,
+ ImageFlavor.XML_DOM};
/**
* Draw an image at the indicated location.
- * @param url the URI/URL of the image
+ * @param uri the URI/URL of the image
* @param pos the position of the image
* @param foreignAttributes an optional Map with foreign attributes, may be null
*/
- protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) {
- url = ImageFactory.getURL(url);
- ImageFactory fact = userAgent.getFactory().getImageFactory();
- FopImage fopimage = fact.getImage(url, userAgent);
- if (fopimage == null) {
- return;
- }
- if (!fopimage.load(FopImage.DIMENSIONS)) {
- return;
- }
- String mime = fopimage.getMimeType();
- if ("text/xml".equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- Document doc = ((XMLImage) fopimage).getDocument();
- String ns = ((XMLImage) fopimage).getNameSpace();
-
- renderDocument(doc, ns, pos, foreignAttributes);
- } else if ("image/svg+xml".equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- Document doc = ((XMLImage) fopimage).getDocument();
- String ns = ((XMLImage) fopimage).getNameSpace();
-
- renderDocument(doc, ns, pos, foreignAttributes);
- } else if (fopimage instanceof EPSImage) {
- log.warn("EPS images are not supported by this renderer");
- } else {
- if (!fopimage.load(FopImage.BITMAP)) {
- log.error("Bitmap image could not be processed: " + fopimage);
- return;
- }
- byte[] imgmap = fopimage.getBitmaps();
+ protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
+ uri = URISpecification.getURL(uri);
+ Rectangle posInt = new Rectangle(
+ (int)pos.getX(),
+ (int)pos.getY(),
+ (int)pos.getWidth(),
+ (int)pos.getHeight());
+ Point origin = new Point(currentIPPosition, currentBPPosition);
+ int x = origin.x + posInt.x;
+ int y = origin.y + posInt.y;
+
+ ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageInfo info = null;
+ try {
+ ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
+ info = manager.getImageInfo(uri, sessionContext);
- ColorModel cm = new ComponentColorModel(
- ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
- new int[] {8, 8, 8},
- false, false,
- ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
- int imgw = fopimage.getWidth();
- int imgh = fopimage.getHeight();
- SampleModel sampleModel = new PixelInterleavedSampleModel(
- DataBuffer.TYPE_BYTE, imgw, imgh, 3, imgw * 3, new int[] {0, 1, 2});
- DataBuffer dbuf = new DataBufferByte(imgmap, imgw * imgh * 3);
-
- WritableRaster raster = Raster.createWritableRaster(sampleModel,
- dbuf, null);
-
- // Combine the color model and raster into a buffered image
- RenderedImage img = new BufferedImage(cm, raster, false, null);
-
- try {
- setCursorPos(this.currentIPPosition + (int)pos.getX(),
- this.currentBPPosition + (int)pos.getY());
- gen.paintBitmap(img,
- new Dimension((int)pos.getWidth(), (int)pos.getHeight()),
+ //Only now fully load/prepare the image
+ Map hints = ImageUtil.getDefaultHints(sessionContext);
+ org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
+ info, FLAVORS, hints, sessionContext);
+
+ //...and process the image
+ if (img instanceof ImageGraphics2D) {
+ ImageGraphics2D imageG2D = (ImageGraphics2D)img;
+ RendererContext context = createRendererContext(
+ posInt.x, posInt.y,
+ posInt.width, posInt.height, foreignAttributes);
+ getGraphics2DAdapter().paintImage(imageG2D.getGraphics2DImagePainter(),
+ context, x, y, posInt.width, posInt.height);
+ } else if (img instanceof ImageRendered) {
+ ImageRendered imgRend = (ImageRendered)img;
+ RenderedImage ri = imgRend.getRenderedImage();
+ setCursorPos(x, y);
+ gen.paintBitmap(ri,
+ new Dimension(posInt.width, posInt.height),
false);
- } catch (IOException ioe) {
- handleIOTrouble(ioe);
+ } else if (img instanceof ImageXMLDOM) {
+ ImageXMLDOM imgXML = (ImageXMLDOM)img;
+ renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(),
+ pos, foreignAttributes);
+ } else {
+ throw new UnsupportedOperationException("Unsupported image type: " + img);
}
+
+ } catch (ImageException ie) {
+ log.error("Error while processing image: "
+ + (info != null ? info.toString() : uri), ie);
+ } catch (FileNotFoundException fe) {
+ log.error(fe.getMessage());
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
Document doc = fo.getDocument();
String ns = fo.getNameSpace();
@@ -1153,52 +1162,45 @@ public class PCLRenderer extends PrintRenderer {
}
// background image
- if (back.getFopImage() != null) {
- FopImage fopimage = back.getFopImage();
- if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) {
- saveGraphicsState();
- clipRect(sx, sy, paddRectWidth, paddRectHeight);
- int horzCount = (int) ((paddRectWidth * 1000 / fopimage
- .getIntrinsicWidth()) + 1.0f);
- int vertCount = (int) ((paddRectHeight * 1000 / fopimage
- .getIntrinsicHeight()) + 1.0f);
- if (back.getRepeat() == EN_NOREPEAT) {
- horzCount = 1;
- vertCount = 1;
- } else if (back.getRepeat() == EN_REPEATX) {
- vertCount = 1;
- } else if (back.getRepeat() == EN_REPEATY) {
- horzCount = 1;
- }
- // change from points to millipoints
- sx *= 1000;
- sy *= 1000;
- if (horzCount == 1) {
- sx += back.getHoriz();
- }
- if (vertCount == 1) {
- sy += back.getVertical();
- }
- for (int x = 0; x < horzCount; x++) {
- for (int y = 0; y < vertCount; y++) {
- // place once
- Rectangle2D pos;
- // Image positions are relative to the currentIP/BP
- pos = new Rectangle2D.Float(
- sx - currentIPPosition
- + (x * fopimage.getIntrinsicWidth()),
- sy - currentBPPosition
- + (y * fopimage.getIntrinsicHeight()),
- fopimage.getIntrinsicWidth(),
- fopimage.getIntrinsicHeight());
- drawImage(back.getURL(), pos, null);
- }
+ if (back.getImageInfo() != null) {
+ ImageSize imageSize = back.getImageInfo().getSize();
+ saveGraphicsState();
+ clipRect(sx, sy, paddRectWidth, paddRectHeight);
+ int horzCount = (int) ((paddRectWidth * 1000 / imageSize.getWidthMpt()) + 1.0f);
+ int vertCount = (int) ((paddRectHeight * 1000 / imageSize.getHeightMpt()) + 1.0f);
+ if (back.getRepeat() == EN_NOREPEAT) {
+ horzCount = 1;
+ vertCount = 1;
+ } else if (back.getRepeat() == EN_REPEATX) {
+ vertCount = 1;
+ } else if (back.getRepeat() == EN_REPEATY) {
+ horzCount = 1;
+ }
+ // change from points to millipoints
+ sx *= 1000;
+ sy *= 1000;
+ if (horzCount == 1) {
+ sx += back.getHoriz();
+ }
+ if (vertCount == 1) {
+ sy += back.getVertical();
+ }
+ for (int x = 0; x < horzCount; x++) {
+ for (int y = 0; y < vertCount; y++) {
+ // place once
+ Rectangle2D pos;
+ // Image positions are relative to the currentIP/BP
+ pos = new Rectangle2D.Float(
+ sx - currentIPPosition
+ + (x * imageSize.getWidthMpt()),
+ sy - currentBPPosition
+ + (y * imageSize.getHeightMpt()),
+ imageSize.getWidthMpt(),
+ imageSize.getHeightMpt());
+ drawImage(back.getURL(), pos, null);
}
- restoreGraphicsState();
- } else {
- log.warn(
- "Can't find background image: " + back.getURL());
}
+ restoreGraphicsState();
}
}
@@ -1508,6 +1510,11 @@ public class PCLRenderer extends PrintRenderer {
}
}
+ /**
+ * Controls whether all text should be generated as bitmaps or only text for which there's
+ * no native font.
+ * @param allTextAsBitmaps true if all text should be painted as bitmaps
+ */
public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
this.allTextAsBitmaps = allTextAsBitmaps;
}
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererContext.java b/src/java/org/apache/fop/render/pcl/PCLRendererContext.java
index 32510137b..62d4bcaa4 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRendererContext.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererContext.java
@@ -62,11 +62,28 @@ public class PCLRendererContext extends RendererContext.RendererContextWrapper {
&& "true".equalsIgnoreCase((String)getForeignAttributes().get(qName));
}
+ /**
+ * Indicates whether the background should not be erased prior to painting.
+ * @return true if the background shouldn't be erased
+ */
public boolean isSourceTransparency() {
QName qName = new QName(ExtensionElementMapping.URI, null, "source-transparency");
return getForeignAttributes() != null
&& "true".equalsIgnoreCase((String)getForeignAttributes().get(qName));
}
+ /**
+ * Indicates whether an RGB canvas should be used rather than one with grayscales.
+ * This can be used to work around limitations of Apache Batik if you get error while
+ * processing SVG graphics. Note, however, that RGB mode will use more memory.
+ * @return true if an EGB canvas should be used
+ */
+ public boolean isColorCanvas() {
+ QName qName = new QName(ExtensionElementMapping.URI, null, "color-canvas");
+ Boolean prop = (Boolean)context.getProperty(PCLRendererContextConstants.PCL_COLOR_CANVAS);
+ return Boolean.TRUE.equals(prop)
+ || (getForeignAttributes() != null
+ && "true".equalsIgnoreCase((String)getForeignAttributes().get(qName)));
+ }
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererContextConstants.java b/src/java/org/apache/fop/render/pcl/PCLRendererContextConstants.java
new file mode 100644
index 000000000..66ce40f5e
--- /dev/null
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererContextConstants.java
@@ -0,0 +1,32 @@
+/*
+ * 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.render.RendererContextConstants;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface PCLRendererContextConstants extends RendererContextConstants {
+
+ /** The PDF document that this image is being drawn into. */
+ String PCL_COLOR_CANVAS = "color-canvas";
+
+}
diff --git a/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java b/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java
index 8c9179063..a016c692f 100644
--- a/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java
+++ b/src/java/org/apache/fop/render/pcl/PCLSVGHandler.java
@@ -22,6 +22,7 @@ package org.apache.fop.render.pcl;
// FOP
import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererContext;
/**
* PCL XML handler for SVG. Uses Apache Batik for SVG processing.
@@ -36,5 +37,12 @@ public class PCLSVGHandler extends AbstractGenericSVGHandler {
return (renderer instanceof PCLRenderer);
}
+ /** {@inheritDoc} */
+ protected void updateRendererContext(RendererContext context) {
+ //Work around a problem in Batik: Gradients cannot be done in ColorSpace.CS_GRAY
+ context.setProperty(PCLRendererContextConstants.PCL_COLOR_CANVAS,
+ Boolean.TRUE);
+ }
+
}