Author: jeremias
Date: Thu Oct 30 01:49:44 2008
New Revision: 709119
URL: http://svn.apache.org/viewvc?rev=709119&view=rev
Log:
Re-Implemented "quality" rendering mode (painting borders and rules using
bitmaps).
Added a new rendering mode "bitmap" (in addition to "speed" and "bitmap") that
uses Java2DPainter for the whole page and paints a single bitmap (much like
most PCL drivers operate). Quality: "speed" < "quality" < "bitmap",
Performance: "speed" > "quality" > "bitmap" (at high page complexity "bitmap"
might actually be better), File Size: "speed" < "quality" < "bitmap"
Increased bitmap encoding performance by up to 100% (by optimizing the Java
code and by supporting the "zeroed row" PCL command)
Added:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
(with props)
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
Thu Oct 30 01:49:44 2008
@@ -21,6 +21,7 @@
import java.awt.Color;
import java.awt.Dimension;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.FileNotFoundException;
@@ -47,6 +48,8 @@
import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.RenderingContext;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.RuleStyle;
/**
* Abstract base class for IFPainter implementations.
@@ -195,8 +198,8 @@
+ effImage.getInfo() + " (" +
effImage.getClass().getName() + ")");
}
- if (log.isDebugEnabled()) {
- log.debug("Using ImageHandler: " + handler.getClass().getName());
+ if (log.isTraceEnabled()) {
+ log.trace("Using ImageHandler: " + handler.getClass().getName());
}
//TODO foreign attributes
@@ -262,6 +265,67 @@
}
/** [EMAIL PROTECTED] */
+ public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps
after,
+ BorderProps start, BorderProps end) throws IFException {
+ if (before != null) {
+ Rectangle b = new Rectangle(
+ rect.x, rect.y,
+ rect.width, before.width);
+ fillRect(b, before.color);
+ }
+ if (end != null) {
+ Rectangle b = new Rectangle(
+ rect.x + rect.width - end.width, rect.y,
+ end.width, rect.height);
+ fillRect(b, end.color);
+ }
+ if (after != null) {
+ Rectangle b = new Rectangle(
+ rect.x, rect.y + rect.height - after.width,
+ rect.width, after.width);
+ fillRect(b, after.color);
+ }
+ if (start != null) {
+ Rectangle b = new Rectangle(
+ rect.x, rect.y,
+ start.width, rect.height);
+ fillRect(b, start.color);
+ }
+ }
+
+ /** [EMAIL PROTECTED] */
+ public void drawLine(Point start, Point end, int width, Color color,
RuleStyle style)
+ throws IFException {
+ Rectangle rect = getLineBoundingBox(start, end, width);
+ fillRect(rect, color);
+ }
+
+ /**
+ * Calculates the bounding box for a line. Currently, only horizontal and
vertical lines
+ * are needed and supported.
+ * @param start the starting point of the line (coordinates in mpt)
+ * @param end the ending point of the line (coordinates in mpt)
+ * @param width the line width (in mpt)
+ * @return the bounding box (coordinates in mpt)
+ */
+ protected Rectangle getLineBoundingBox(Point start, Point end, int width) {
+ if (start.y == end.y) {
+ int topy = start.y - width / 2;
+ return new Rectangle(
+ start.x, topy,
+ end.x - start.x, width);
+ } else if (start.x == end.y) {
+ int leftx = start.x - width / 2;
+ return new Rectangle(
+ leftx, start.x,
+ width, end.y - start.y);
+ } else {
+ throw new IllegalArgumentException(
+ "Only horizontal or vertical lines are supported at the
moment.");
+ }
+ }
+
+ /** [EMAIL PROTECTED] */
public void setFont(String family, String style, Integer weight, String
variant, Integer size,
Color color) throws IFException {
if (family != null) {
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
Thu Oct 30 01:49:44 2008
@@ -32,9 +32,13 @@
public class DefaultMonochromeBitmapConverter implements
MonochromeBitmapConverter {
+ private boolean quality = false;
+
/** [EMAIL PROTECTED] */
public void setHint(String name, String value) {
- //ignore, not supported
+ if ("quality".equalsIgnoreCase(name)) {
+ quality = "true".equalsIgnoreCase(value);
+ }
}
/** [EMAIL PROTECTED] */
@@ -42,8 +46,16 @@
BufferedImage buf = new BufferedImage(img.getWidth(), img.getHeight(),
BufferedImage.TYPE_BYTE_BINARY);
RenderingHints hints = new RenderingHints(null);
- //This hint doesn't seem to make a difference :-(
- hints.put(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
+ //These hints don't seem to make a difference :-( Not seeing any
dithering on Sun Java.
+ hints.put(RenderingHints.KEY_DITHERING,
+ RenderingHints.VALUE_DITHER_ENABLE);
+ if (quality) {
+ hints.put(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+ hints.put(RenderingHints.KEY_COLOR_RENDERING,
+ RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+ }
+
ColorConvertOp op = new ColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY), hints);
op.filter(img, buf);
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
Thu Oct 30 01:49:44 2008
@@ -19,18 +19,27 @@
package org.apache.fop.render.pcl;
+import java.awt.Color;
import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+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.util.UnitConv;
+
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactoryConfigurator;
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;
+import org.apache.fop.render.java2d.Java2DPainter;
/**
* [EMAIL PROTECTED] IFDocumentHandler} implementation that produces PCL 5.
@@ -54,6 +63,10 @@
/** contains the pageHeight of the last printed page */
private long pageHeight = 0;
+ /** the current page image (only set when all-bitmap painting is
activated) */
+ private BufferedImage currentImage;
+
+
/**
* Default constructor.
*/
@@ -190,12 +203,74 @@
/** [EMAIL PROTECTED] */
public IFPainter startPageContent() throws IFException {
- return new PCLPainter(this, this.currentPageDefinition);
+ if (pclUtil.getRenderingMode() == PCLRenderingMode.BITMAP) {
+ return createAllBitmapPainter();
+ } else {
+ return new PCLPainter(this, this.currentPageDefinition);
+ }
+ }
+
+ private IFPainter createAllBitmapPainter() {
+ double scale = gen.getMaximumBitmapResolution()
+ / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+ Rectangle printArea = this.currentPageDefinition.getLogicalPageRect();
+ int bitmapWidth = (int)Math.ceil(
+ UnitConv.mpt2px(printArea.width,
gen.getMaximumBitmapResolution()));
+ int bitmapHeight = (int)Math.ceil(
+ UnitConv.mpt2px(printArea.height,
gen.getMaximumBitmapResolution()));
+ this.currentImage = createBufferedImage(bitmapWidth, bitmapHeight);
+ Graphics2D graphics2D = this.currentImage.createGraphics();
+
+ if (!PCLGenerator.isJAIAvailable()) {
+ RenderingHints hints = new RenderingHints(null);
+ //These hints don't seem to make a difference :-( Not seeing any
dithering on Sun Java.
+ hints.put(RenderingHints.KEY_DITHERING,
+ RenderingHints.VALUE_DITHER_ENABLE);
+ graphics2D.addRenderingHints(hints);
+ }
+
+ //Ensure white page background
+ graphics2D.setBackground(Color.WHITE);
+ graphics2D.clearRect(0, 0, bitmapWidth, bitmapHeight);
+
+ graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_PURE);
+ graphics2D.scale(scale / 1000f, scale / 1000f);
+ graphics2D.translate(-printArea.x, -printArea.y);
+
+ return new Java2DPainter(graphics2D, getUserAgent(), getFontInfo());
+ }
+
+ private BufferedImage createBufferedImage(int bitmapWidth, int
bitmapHeight) {
+ int bitmapType;
+ if (PCLGenerator.isJAIAvailable()) {
+ //TYPE_BYTE_GRAY was used to work around the lack of dithering
when using
+ //TYPE_BYTE_BINARY. Adding RenderingHints didn't help.
+ bitmapType = BufferedImage.TYPE_BYTE_GRAY;
+ //bitmapType = BufferedImage.TYPE_INT_RGB; //Use to enable Batik
gradients
+ } else {
+ bitmapType = BufferedImage.TYPE_BYTE_BINARY;
+ }
+ return new BufferedImage(
+ bitmapWidth, bitmapHeight, bitmapType);
}
/** [EMAIL PROTECTED] */
public void endPageContent() throws IFException {
- //nop
+ if (this.currentImage != null) {
+ try {
+ //ImageWriterUtil.saveAsPNG(this.currentImage, new
java.io.File("D:/page.png"));
+ Rectangle printArea =
this.currentPageDefinition.getLogicalPageRect();
+ gen.setCursorPos(0, 0);
+ gen.paintBitmap(this.currentImage, printArea.getSize(), true);
+ } catch (IOException ioe) {
+ throw new IFException("I/O error while encoding page image",
ioe);
+ } finally {
+ this.currentImage = null;
+ }
+ }
}
/** [EMAIL PROTECTED] */
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
Thu Oct 30 01:49:44 2008
@@ -30,8 +30,10 @@
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.LookupOp;
+import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
@@ -604,6 +606,26 @@
return (img.getColorModel().getNumColorComponents() == 1);
}
+ private static int jaiAvailable = -1; //no synchronization necessary, not
critical
+
+ /**
+ * Indicates whether JAI is available. JAI has shown to be reliable when
dithering a
+ * grayscale or color image to monochrome bitmaps (1-bit).
+ * @return true if JAI is available
+ */
+ public static boolean isJAIAvailable() {
+ if (jaiAvailable < 0) {
+ try {
+ String clName =
"org.apache.fop.render.pcl.JAIMonochromeBitmapConverter";
+ Class.forName(clName);
+ jaiAvailable = 1;
+ } catch (ClassNotFoundException cnfe) {
+ jaiAvailable = 0;
+ }
+ }
+ return (jaiAvailable > 0);
+ }
+
private MonochromeBitmapConverter createMonochromeBitmapConverter() {
MonochromeBitmapConverter converter = null;
try {
@@ -839,6 +861,16 @@
g2d.clearRect(0, 0, effDim.width, effDim.height);
}
+ private int toGray(int rgb) {
+ // see http://www.jguru.com/faq/view.jsp?EID=221919
+ double greyVal = 0.072169d * (rgb & 0xff);
+ rgb >>= 8;
+ greyVal += 0.715160d * (rgb & 0xff);
+ rgb >>= 8;
+ greyVal += 0.212671d * (rgb & 0xff);
+ return (int)greyVal;
+ }
+
/**
* Paint a bitmap at the current cursor position. The bitmap must be a
monochrome
* (1-bit) bitmap image.
@@ -850,79 +882,159 @@
if (!isValidPCLResolution(resolution)) {
throw new IllegalArgumentException("Invalid PCL resolution: " +
resolution);
}
- setRasterGraphicsResolution(resolution);
- writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
- Raster raster = img.getData();
boolean monochrome = isMonochromeImage(img);
if (!monochrome) {
throw new IllegalArgumentException("img must be a monochrome
image");
}
- int x = 0;
- int y = 0;
- int imgw = img.getWidth();
- int imgh = img.getHeight();
- int bytewidth = (imgw / 8);
- if ((imgw % 8) != 0) {
- bytewidth++;
- }
- byte ib;
- byte[] rle = new byte[bytewidth * 2]; //compressed (RLE)
- byte[] uncompressed = new byte[bytewidth]; //uncompressed
- int lastcount = -1;
- byte lastbyte = 0;
- int rlewidth = 0;
+ setRasterGraphicsResolution(resolution);
+ writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
+ Raster raster = img.getData();
+ Encoder encoder = new Encoder(img);
// Transfer graphics data
- for (y = 0; y < imgh; y++) {
- ib = 0;
- for (x = 0; x < imgw; x++) {
- int sample = raster.getSample(x, y, 0);
- //Set image bit for black
- if ((sample == 0)) {
- ib |= (1 << (7 - (x % 8)));
- }
-
- //RLE encoding
- if ((x % 8) == 7 || ((x + 1) == imgw)) {
- if (rlewidth < bytewidth) {
- if (lastcount >= 0) {
- if (ib == lastbyte) {
- lastcount++;
- } else {
- rle[rlewidth++] = (byte)(lastcount & 0xFF);
- rle[rlewidth++] = lastbyte;
- lastbyte = ib;
- lastcount = 0;
- }
+ int imgw = img.getWidth();
+ IndexColorModel cm = (IndexColorModel)img.getColorModel();
+ if (cm.getTransferType() == DataBuffer.TYPE_BYTE) {
+ DataBufferByte dataBuffer = (DataBufferByte)raster.getDataBuffer();
+ MultiPixelPackedSampleModel packedSampleModel = new
MultiPixelPackedSampleModel(
+ DataBuffer.TYPE_BYTE, img.getWidth(), img.getHeight(), 1);
+ if (img.getSampleModel().equals(packedSampleModel)
+ && dataBuffer.getNumBanks() == 1) {
+ //Optimized packed encoding
+ byte[] buf = dataBuffer.getData();
+ int scanlineStride = packedSampleModel.getScanlineStride();
+ int idx = 0;
+ int c0 = toGray(cm.getRGB(0));
+ int c1 = toGray(cm.getRGB(1));
+ boolean zeroIsWhite = c0 > c1;
+ for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+ for (int x = 0, maxx = scanlineStride; x < maxx; x++) {
+ if (zeroIsWhite) {
+ encoder.add8Bits(buf[idx]);
} else {
- lastbyte = ib;
- lastcount = 0;
- }
- if (lastcount == 255 || ((x + 1) == imgw)) {
- rle[rlewidth++] = (byte)(lastcount & 0xFF);
- rle[rlewidth++] = lastbyte;
- lastbyte = 0;
- lastcount = -1;
+ encoder.add8Bits((byte)~buf[idx]);
}
+ idx++;
}
- uncompressed[x / 8] = ib;
- ib = 0;
+ encoder.endLine();
+ }
+ } else {
+ //Optimized non-packed encoding
+ for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+ byte[] line = (byte[])raster.getDataElements(0, y, imgw,
1, null);
+ for (int x = 0, maxx = imgw; x < maxx; x++) {
+ encoder.addBit(line[x] == 0);
+ }
+ encoder.endLine();
+ }
+ }
+ } else {
+ //Safe but slow fallback
+ for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+ for (int x = 0, maxx = imgw; x < maxx; x++) {
+ int sample = raster.getSample(x, y, 0);
+ encoder.addBit(sample == 0);
}
+ encoder.endLine();
}
+ }
+
+ // End raster graphics
+ writeCommand("*rB");
+ }
+
+ private class Encoder {
+
+ private int imgw;
+ private int bytewidth;
+ private byte[] rle; //compressed (RLE)
+ private byte[] uncompressed; //uncompressed
+ private int lastcount = -1;
+ private byte lastbyte = 0;
+ private int rlewidth = 0;
+ private byte ib = 0; //current image bits
+ private int x = 0;
+ private boolean zeroRow = true;
+
+ public Encoder(RenderedImage img) {
+ imgw = img.getWidth();
+ bytewidth = (imgw / 8);
+ if ((imgw % 8) != 0) {
+ bytewidth++;
+ }
+ rle = new byte[bytewidth * 2];
+ uncompressed = new byte[bytewidth];
+ }
+
+ public void addBit(boolean bit) {
+ //Set image bit for black
+ if (bit) {
+ ib |= 1;
+ }
+
+ //RLE encoding
+ if ((x % 8) == 7 || ((x + 1) == imgw)) {
+ finishedByte();
+ } else {
+ ib <<= 1;
+ }
+ x++;
+ }
+
+ public void add8Bits(byte b) {
+ ib = b;
+ finishedByte();
+ x += 8;
+ }
+
+ private void finishedByte() {
if (rlewidth < bytewidth) {
+ if (lastcount >= 0) {
+ if (ib == lastbyte) {
+ lastcount++;
+ } else {
+ rle[rlewidth++] = (byte)(lastcount & 0xFF);
+ rle[rlewidth++] = lastbyte;
+ lastbyte = ib;
+ lastcount = 0;
+ }
+ } else {
+ lastbyte = ib;
+ lastcount = 0;
+ }
+ if (lastcount == 255 || ((x + 1) == imgw)) {
+ rle[rlewidth++] = (byte)(lastcount & 0xFF);
+ rle[rlewidth++] = lastbyte;
+ lastbyte = 0;
+ lastcount = -1;
+ }
+ }
+ uncompressed[x / 8] = ib;
+ if (ib != 0) {
+ zeroRow = false;
+ }
+ ib = 0;
+ }
+
+ public void endLine() throws IOException {
+ if (zeroRow) {
+ writeCommand("*b1Y");
+ } else if (rlewidth < bytewidth) {
writeCommand("*b1m" + rlewidth + "W");
- this.out.write(rle, 0, rlewidth);
+ out.write(rle, 0, rlewidth);
} else {
writeCommand("*b0m" + bytewidth + "W");
- this.out.write(uncompressed);
+ out.write(uncompressed);
}
lastcount = -1;
rlewidth = 0;
+ ib = 0;
+ x = 0;
+ zeroRow = true;
}
- // End raster graphics
- writeCommand("*rB");
+
}
}
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
Thu Oct 30 01:49:44 2008
@@ -114,6 +114,22 @@
return null;
}
+ /**
+ * Returns a page definition based on a page format.
+ * @param name the name of the page format (ex. "A4" or "Letter")
+ * @return the page definition or null if no match was found
+ */
+ public static PCLPageDefinition getPageDefinition(String name) {
+ Iterator iter = pageDefinitions.iterator();
+ while (iter.hasNext()) {
+ PCLPageDefinition def = (PCLPageDefinition)iter.next();
+ if (def.getName().equalsIgnoreCase(name)) {
+ return def;
+ }
+ }
+ return null;
+ }
+
/** @return the default page definition (letter) */
public static PCLPageDefinition getDefaultPageDefinition() {
return defaultPageDefinition;
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
Thu Oct 30 01:49:44 2008
@@ -66,7 +66,7 @@
/** logging instance */
private static Log log = LogFactory.getLog(PCLPainter.class);
- private final boolean DEBUG = false;
+ private static final boolean DEBUG = false;
private PCLDocumentHandler parent;
@@ -173,10 +173,7 @@
/** [EMAIL PROTECTED] */
public void clipRect(Rectangle rect) throws IFException {
//PCL cannot clip (only HP GL/2 can)
- /*
- generator.endTextObject();
- generator.clipRect(rect);
- */
+ //If you need clipping support, switch to RenderingMode.BITMAP.
}
/** [EMAIL PROTECTED] */
@@ -203,23 +200,97 @@
}
/** [EMAIL PROTECTED] */
- public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps
after,
- BorderProps start, BorderProps end) throws IFException {
+ public void drawBorderRect(final Rectangle rect,
+ final BorderProps before, final BorderProps after,
+ final BorderProps start, final BorderProps end) throws IFException
{
+ if (getPCLUtil().getRenderingMode() == PCLRenderingMode.SPEED) {
+ super.drawBorderRect(rect, before, after, start, end);
+ return;
+ }
if (before != null || after != null || start != null || end != null) {
- /*
- generator.endTextObject();
- this.borderPainter.drawBorders(rect, before, after, start, end);
- */
+ final Rectangle boundingBox = rect;
+ final Dimension dim = boundingBox.getSize();
+
+ Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+ public void paint(Graphics2D g2d, Rectangle2D area) {
+ g2d.translate(-rect.x, -rect.y);
+
+ Java2DPainter painter = new Java2DPainter(g2d,
+ getUserAgent(), parent.getFontInfo(), state);
+ try {
+ painter.drawBorderRect(rect, before, after, start,
end);
+ } catch (IFException e) {
+ //This should never happen with the Java2DPainter
+ throw new RuntimeException("Unexpected error while
painting borders", e);
+ }
+ }
+
+ public Dimension getImageSize() {
+ return dim.getSize();
+ }
+
+ };
+ paintMarksAsBitmap(painter, boundingBox);
}
}
/** [EMAIL PROTECTED] */
- public void drawLine(Point start, Point end, int width, Color color,
RuleStyle style)
+ public void drawLine(final Point start, final Point end,
+ final int width, final Color color, final RuleStyle style)
+ throws IFException {
+ if (getPCLUtil().getRenderingMode() == PCLRenderingMode.SPEED) {
+ super.drawLine(start, end, width, color, style);
+ return;
+ }
+ final Rectangle boundingBox = getLineBoundingBox(start, end, width);
+ final Dimension dim = boundingBox.getSize();
+
+ Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+ public void paint(Graphics2D g2d, Rectangle2D area) {
+ g2d.translate(-boundingBox.x, -boundingBox.y);
+
+ Java2DPainter painter = new Java2DPainter(g2d,
+ getUserAgent(), parent.getFontInfo(), state);
+ try {
+ painter.drawLine(start, end, width, color, style);
+ } catch (IFException e) {
+ //This should never happen with the Java2DPainter
+ throw new RuntimeException("Unexpected error while
painting a line", e);
+ }
+ }
+
+ public Dimension getImageSize() {
+ return dim.getSize();
+ }
+
+ };
+ paintMarksAsBitmap(painter, boundingBox);
+ }
+
+ private void paintMarksAsBitmap(Graphics2DImagePainter painter, Rectangle
boundingBox)
throws IFException {
- /*
- generator.endTextObject();
- this.borderPainter.drawLine(start, end, width, color, style);
- */
+ ImageInfo info = new ImageInfo(null, null);
+ ImageSize size = new ImageSize();
+ size.setSizeInMillipoints(boundingBox.width, boundingBox.height);
+ info.setSize(size);
+ ImageGraphics2D img = new ImageGraphics2D(info, painter);
+
+ Map hints = new java.util.HashMap();
+ hints.put(ImageProcessingHints.BITMAP_TYPE_INTENT,
+ ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY);
+ PCLRenderingContext context =
(PCLRenderingContext)createRenderingContext();
+ context.setSourceTransparencyEnabled(true);
+ try {
+ drawImage(img, boundingBox, context, true, hints);
+ } catch (IOException ioe) {
+ throw new IFException(
+ "I/O error while painting marks using a bitmap", ioe);
+ } catch (ImageException ie) {
+ throw new IFException(
+ "Error while painting marks using a bitmap", ie);
+ }
}
/** [EMAIL PROTECTED] */
@@ -246,8 +317,6 @@
}
} catch (IOException ioe) {
throw new IFException("I/O error in drawText()", ioe);
- } catch (ImageException ime) {
- throw new IFException("Image processing error in drawText()", ime);
}
}
@@ -304,7 +373,7 @@
private static final double SAFETY_MARGIN_FACTOR = 0.05;
- private Rectangle getTextBoundingRect(int x, int y, int[] dx, int[] dy,
String text,
+ private Rectangle getTextBoundingBox(int x, int y, int[] dx, int[] dy,
String text,
Font font, FontMetricsMapper metrics) {
int maxAscent = metrics.getMaxAscent(font.getFontSize()) / 1000;
int descent = metrics.getDescender(font.getFontSize()) / 1000; //is
negative
@@ -339,11 +408,9 @@
}
private void drawTextAsBitmap(final int x, final int y, final int[] dx,
final int[] dy,
- final String text, FontTriplet triplet) throws IOException,
ImageException {
+ final String text, FontTriplet triplet) throws IFException {
//Use Java2D to paint different fonts via bitmap
final Font font = parent.getFontInfo().getFontInstance(triplet,
state.getFontSize());
- //final Font font = getFontFromArea(text);
- //final int baseline = text.getBaselineOffset();
//for cursive fonts, so the text isn't clipped
final FontMetricsMapper mapper =
(FontMetricsMapper)parent.getFontInfo().getMetricsFor(
@@ -354,14 +421,9 @@
int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
final int baselineOffset = maxAscent + safetyMargin;
- final Rectangle boundingRect = getTextBoundingRect(x, y, dx, dy, text,
font, mapper);
-
- Map atts = new java.util.HashMap();
- atts.put(CONV_MODE, "bitmap");
- atts.put(SRC_TRANSPARENCY, "true");
- //rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts);
+ final Rectangle boundingBox = getTextBoundingBox(x, y, dx, dy, text,
font, mapper);
+ final Dimension dim = boundingBox.getSize();
- final Dimension dim = boundingRect.getSize();
Graphics2DImagePainter painter = new Graphics2DImagePainter() {
public void paint(Graphics2D g2d, Rectangle2D area) {
@@ -394,19 +456,7 @@
}
};
- ImageInfo info = new ImageInfo(null, null);
- ImageSize size = new ImageSize();
- size.setSizeInMillipoints(boundingRect.width, boundingRect.height);
- info.setSize(size);
- ImageGraphics2D img = new ImageGraphics2D(info, painter);
-
- Rectangle rect = boundingRect;
- Map hints = new java.util.HashMap();
- hints.put(ImageProcessingHints.BITMAP_TYPE_INTENT,
- ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY);
- PCLRenderingContext context =
(PCLRenderingContext)createRenderingContext();
- context.setSourceTransparencyEnabled(true);
- drawImage(img, rect, context, true, hints);
+ paintMarksAsBitmap(painter, boundingBox);
}
/** Saves the current graphics state on the stack. */
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
Thu Oct 30 01:49:44 2008
@@ -164,7 +164,8 @@
* @param qualityBeforeSpeed true if quality is more important than speed
*/
public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
- pclUtil.setQualityBeforeSpeed(qualityBeforeSpeed);
+ pclUtil.setRenderingMode(qualityBeforeSpeed
+ ? PCLRenderingMode.QUALITY : PCLRenderingMode.SPEED);
}
/**
@@ -1187,10 +1188,10 @@
if (bpsBefore == null && bpsAfter == null && bpsStart == null &&
bpsEnd == null) {
return; //no borders to paint
}
- if (pclUtil.isQualityBeforeSpeed()) {
- drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart,
bpsEnd);
- } else {
+ if (PCLRenderingMode.SPEED == pclUtil.getRenderingMode()) {
drawFastBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+ } else {
+ drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart,
bpsEnd);
}
}
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
Thu Oct 30 01:49:44 2008
@@ -75,13 +75,11 @@
private void configure(Configuration cfg, PCLRenderingUtil pclUtil) throws
FOPException {
String rendering = cfg.getChild("rendering").getValue(null);
- if ("quality".equalsIgnoreCase(rendering)) {
- pclUtil.setQualityBeforeSpeed(true);
- } else if ("speed".equalsIgnoreCase(rendering)) {
- pclUtil.setQualityBeforeSpeed(false);
- } else if (rendering != null) {
+ try {
+ pclUtil.setRenderingMode(PCLRenderingMode.valueOf(rendering));
+ } catch (IllegalArgumentException e) {
throw new FOPException(
- "Valid values for 'rendering' are 'quality' and 'speed'.
Value found: "
+ "Valid values for 'rendering' are 'quality', 'speed' and
'bitmap'. Value found: "
+ rendering);
}
Added:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java?rev=709119&view=auto
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
(added)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
Thu Oct 30 01:49:44 2008
@@ -0,0 +1,82 @@
+/*
+ * 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.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * Enumeration class for PCL rendering modes.
+ */
+public final class PCLRenderingMode implements Serializable {
+
+ private static final long serialVersionUID = 6359884255324755026L;
+
+ /** "Quality" rendering (mixed native and bitmap for improved quality) */
+ public static final PCLRenderingMode QUALITY = new
PCLRenderingMode("quality");
+ /** "Speed" rendering (maximum speed with native rendering, reduced visual
quality) */
+ public static final PCLRenderingMode SPEED = new PCLRenderingMode("speed");
+ /**
+ * "Bitmap" rendering (pages are painted entirely as bitmaps, maximum
quality,
+ * reduced performance)
+ */
+ public static final PCLRenderingMode BITMAP = new
PCLRenderingMode("bitmap");
+
+ private String name;
+
+ /**
+ * Constructor to add a new named item.
+ * @param name Name of the item.
+ */
+ private PCLRenderingMode(String name) {
+ this.name = name;
+ }
+
+ /** @return the name of the enum */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Returns the enumeration/singleton object based on its name.
+ * @param name the name of the enumeration value
+ * @return the enumeration object
+ */
+ public static PCLRenderingMode valueOf(String name) {
+ if (QUALITY.getName().equalsIgnoreCase(name)) {
+ return QUALITY;
+ } else if (SPEED.getName().equalsIgnoreCase(name)) {
+ return SPEED;
+ } else if (BITMAP.getName().equalsIgnoreCase(name)) {
+ return BITMAP;
+ } else {
+ throw new IllegalArgumentException("Illegal value for enumeration:
" + name);
+ }
+ }
+
+ private Object readResolve() throws ObjectStreamException {
+ return valueOf(getName());
+ }
+
+ /** [EMAIL PROTECTED] */
+ public String toString() {
+ return "PCLRenderingMode:" + name;
+ }
+}
Propchange:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified:
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
---
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
(original)
+++
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
Thu Oct 30 01:49:44 2008
@@ -42,10 +42,10 @@
private FOUserAgent userAgent;
/**
- * Controls whether appearance is more important than speed. False can
cause some FO feature
+ * Controls whether appearance is more important than speed. "SPEED" can
cause some FO feature
* to be ignored (like the advanced borders).
*/
- private boolean qualityBeforeSpeed = false;
+ private PCLRenderingMode renderingMode = PCLRenderingMode.SPEED;
/**
* Controls whether all text should be painted as text. This is a fallback
setting in case
@@ -84,18 +84,18 @@
/**
* Configures the renderer to trade speed for quality if desired. One
example here is the way
* that borders are rendered.
- * @param qualityBeforeSpeed true if quality is more important than speed
+ * @param mode one of the [EMAIL PROTECTED] PCLRenderingMode}.* constants
*/
- public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
- this.qualityBeforeSpeed = qualityBeforeSpeed;
+ public void setRenderingMode(PCLRenderingMode mode) {
+ this.renderingMode = mode;
}
/**
- * Indicates whether quality is more important than speed.
- * @return true if quality is favored over speed
+ * Returns the selected rendering mode.
+ * @return the rendering mode
*/
- public boolean isQualityBeforeSpeed() {
- return this.qualityBeforeSpeed;
+ public PCLRenderingMode getRenderingMode() {
+ return this.renderingMode;
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]