You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2006/05/02 16:41:21 UTC
svn commit: r398945 [2/2] - in /xmlgraphics/fop/trunk/src:
java/org/apache/fop/render/ java/org/apache/fop/render/awt/
java/org/apache/fop/render/awt/viewer/ java/org/apache/fop/render/bitmap/
java/org/apache/fop/render/java2d/ java/org/apache/fop/rend...
Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java?rev=398945&r1=398944&r2=398945&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java Tue May 2 07:39:32 2006
@@ -20,6 +20,7 @@
import java.awt.BasicStroke;
import java.awt.Color;
+import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -28,6 +29,8 @@
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
@@ -50,6 +53,9 @@
/** The PCL generator */
protected PCLGenerator gen;
+ private boolean failOnUnsupportedFeature = true;
+ private boolean clippingDisabled = false;
+
/**
* Create a new PCLGraphics2D.
* @param gen the PCL Generator to paint with
@@ -70,7 +76,9 @@
/** @see java.awt.Graphics#create() */
public Graphics create() {
- return new PCLGraphics2D(this);
+ PCLGraphics2D copy = new PCLGraphics2D(this);
+ copy.setGraphicContext((GraphicContext)getGraphicContext().clone());
+ return copy;
}
/** @see java.awt.Graphics#dispose() */
@@ -95,6 +103,18 @@
ioe.printStackTrace();
}
+ /**
+ * Raises an UnsupportedOperationException if this instance is configured to do so and an
+ * unsupported feature has been requested. Clients can make use of this to fall back to
+ * a more compatible way of painting a PCL graphic.
+ * @param msg the error message to be displayed
+ */
+ protected void handleUnsupportedFeature(String msg) {
+ if (this.failOnUnsupportedFeature) {
+ throw new UnsupportedOperationException(msg);
+ }
+ }
+
/** @see java.awt.Graphics2D#getDeviceConfiguration() */
public GraphicsConfiguration getDeviceConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
@@ -114,18 +134,35 @@
if (da != null) {
gen.writeText("UL1,");
- for (int idx = 0, len = Math.min(20, da.length); idx < len; idx++) {
- gen.writeText(gen.formatDouble4(da[idx]));
+ int len = Math.min(20, da.length);
+ float patternLen = 0.0f;
+ for (int idx = 0; idx < len; idx++) {
+ patternLen += da[idx];
+ }
+ if (len == 1) {
+ patternLen *= 2;
+ }
+ for (int idx = 0; idx < len; idx++) {
+ float perc = da[idx] * 100 / patternLen;
+ gen.writeText(gen.formatDouble2(perc));
if (idx < da.length - 1) {
gen.writeText(",");
}
}
+ if (len == 1) {
+ gen.writeText("," + gen.formatDouble2(da[0] * 100 / patternLen ));
+
+ }
gen.writeText(";");
/* TODO Dash phase NYI
float offset = bs.getDashPhase();
gen.writeln(gen.formatDouble4(offset) + " setdash");
*/
- gen.writeText("LT1;");
+ Point2D ptLen = new Point2D.Double(patternLen, 0);
+ //interpret as absolute length
+ getTransform().deltaTransform(ptLen, ptLen);
+ double transLen = UnitConv.pt2mm(ptLen.distance(0, 0));
+ gen.writeText("LT1," + gen.formatDouble4(transLen) + ",1;");
} else {
gen.writeText("LT;");
}
@@ -166,13 +203,13 @@
float lw = bs.getLineWidth();
Point2D ptSrc = new Point2D.Double(lw, 0);
//Pen widths are set as absolute metric values (WU0;)
- Point2D ptDest = getTransform().transform(ptSrc, null);
+ Point2D ptDest = getTransform().deltaTransform(ptSrc, null);
double transDist = UnitConv.pt2mm(ptDest.distance(0, 0));
//System.out.println("--" + ptDest.distance(0, 0) + " " + transDist);
gen.writeText(";PW" + gen.formatDouble4(transDist) + ";");
} else {
- System.err.println("Unsupported Stroke: " + stroke.getClass().getName());
+ handleUnsupportedFeature("Unsupported Stroke: " + stroke.getClass().getName());
}
}
@@ -187,7 +224,31 @@
int shade = gen.convertToPCLShade(col);
gen.writeText("TR0;FT10," + shade + ";");
} else {
- System.err.println("Unsupported Paint: " + paint.getClass().getName());
+ handleUnsupportedFeature("Unsupported Paint: " + paint.getClass().getName());
+ }
+ }
+
+ private void writeClip(Shape imclip) throws IOException {
+ if (clippingDisabled) {
+ return;
+ }
+ if (imclip == null) {
+ //gen.writeText("IW;");
+ } else {
+ handleUnsupportedFeature("Clipping is not supported. Shape: " + imclip);
+ /* This is an attempt to clip using the "InputWindow" (IW) but this only allows to
+ * clip a rectangular area. Force falling back to bitmap mode for now.
+ Rectangle2D bounds = imclip.getBounds2D();
+ Point2D p1 = new Point2D.Double(bounds.getX(), bounds.getY());
+ Point2D p2 = new Point2D.Double(
+ bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight());
+ getTransform().transform(p1, p1);
+ getTransform().transform(p2, p2);
+ gen.writeText("IW" + gen.formatDouble4(p1.getX())
+ + "," + gen.formatDouble4(p2.getY())
+ + "," + gen.formatDouble4(p2.getX())
+ + "," + gen.formatDouble4(p1.getY()) + ";");
+ */
}
}
@@ -197,16 +258,17 @@
AffineTransform trans = getTransform();
Shape imclip = getClip();
- //writeClip(imclip);
- //establishColor(getColor());
+ writeClip(imclip);
- applyPaint(getPaint());
+ if (!Color.black.equals(getColor())) {
+ //TODO PCL 5 doesn't support colored pens, PCL5c has a pen color (PC) command
+ handleUnsupportedFeature("Only black is supported as stroke color: " + getColor());
+ }
applyStroke(getStroke());
- //gen.writeln("newpath");
PathIterator iter = s.getPathIterator(trans);
- processPathIterator(iter);
- gen.writeText("EP;");
+ processPathIteratorStroke(iter);
+ writeClip(null);
} catch (IOException ioe) {
handleIOException(ioe);
}
@@ -217,16 +279,13 @@
try {
AffineTransform trans = getTransform();
Shape imclip = getClip();
- //writeClip(imclip);
+ writeClip(imclip);
- //establishColor(getColor());
-
applyPaint(getPaint());
PathIterator iter = s.getPathIterator(trans);
- processPathIterator(iter);
- int fillMethod = (iter.getWindingRule() == PathIterator.WIND_EVEN_ODD ? 0 : 1);
- gen.writeText("FP" + fillMethod + ";");
+ processPathIteratorFill(iter);
+ writeClip(null);
} catch (IOException ioe) {
handleIOException(ioe);
}
@@ -237,97 +296,163 @@
* @param iter PathIterator to process
* @throws IOException In case of an I/O problem.
*/
- public void processPathIterator(PathIterator iter) throws IOException {
+ public void processPathIteratorStroke(PathIterator iter) throws IOException {
+ gen.writeText("\n");
double[] vals = new double[6];
boolean penDown = false;
- boolean hasFirst = false;
- double x = 0, firstX = 0;
- double y = 0, firstY = 0;
- boolean pendingPM0 = true;
- penUp();
+ double x = 0;
+ double y = 0;
+ StringBuffer sb = new StringBuffer(256);
+ penUp(sb);
while (!iter.isDone()) {
int type = iter.currentSegment(vals);
if (type == PathIterator.SEG_CLOSE) {
- hasFirst = false;
- /*
- if (firstX != x && firstY != y) {
- plotAbsolute(firstX, firstY);
- }*/
- //penUp();
- gen.writeText("PM1;");
+ gen.writeText("PM;");
+ gen.writeText(sb.toString());
+ gen.writeText("PM2;EP;");
+ sb.setLength(0);
iter.next();
continue;
- }
- if (type == PathIterator.SEG_MOVETO) {
+ } else if (type == PathIterator.SEG_MOVETO) {
+ gen.writeText(sb.toString());
+ sb.setLength(0);
if (penDown) {
- penUp();
+ penUp(sb);
penDown = false;
}
} else {
if (!penDown) {
- penDown();
+ penDown(sb);
penDown = true;
}
}
switch (type) {
+ case PathIterator.SEG_CLOSE:
+ break;
+ case PathIterator.SEG_MOVETO:
+ x = vals[0];
+ y = vals[1];
+ plotAbsolute(x, y, sb);
+ gen.writeText(sb.toString());
+ sb.setLength(0);
+ break;
+ case PathIterator.SEG_LINETO:
+ x = vals[0];
+ y = vals[1];
+ plotAbsolute(x, y, sb);
+ break;
case PathIterator.SEG_CUBICTO:
x = vals[4];
y = vals[5];
- bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y);
+ bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y, sb);
break;
- case PathIterator.SEG_LINETO:
+ case PathIterator.SEG_QUADTO:
+ double originX = x;
+ double originY = y;
+ x = vals[2];
+ y = vals[3];
+ quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y, sb);
+ break;
+ default:
+ break;
+ }
+ iter.next();
+ }
+ sb.append("\n");
+ gen.writeText(sb.toString());
+ }
+
+ /**
+ * Processes a path iterator generating the nexessary painting operations.
+ * @param iter PathIterator to process
+ * @throws IOException In case of an I/O problem.
+ */
+ public void processPathIteratorFill(PathIterator iter) throws IOException {
+ gen.writeText("\n");
+ double[] vals = new double[6];
+ boolean penDown = false;
+ double x = 0;
+ double y = 0;
+ boolean pendingPM0 = true;
+ StringBuffer sb = new StringBuffer(256);
+ penUp(sb);
+ while (!iter.isDone()) {
+ int type = iter.currentSegment(vals);
+ if (type == PathIterator.SEG_CLOSE) {
+ sb.append("PM1;");
+ iter.next();
+ continue;
+ } else if (type == PathIterator.SEG_MOVETO) {
+ if (penDown) {
+ penUp(sb);
+ penDown = false;
+ }
+ } else {
+ if (!penDown) {
+ penDown(sb);
+ penDown = true;
+ }
+ }
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
x = vals[0];
y = vals[1];
- plotAbsolute(x, y);
+ plotAbsolute(x, y, sb);
break;
- case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_LINETO:
x = vals[0];
y = vals[1];
- plotAbsolute(x, y);
+ plotAbsolute(x, y, sb);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ x = vals[4];
+ y = vals[5];
+ bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y, sb);
break;
case PathIterator.SEG_QUADTO:
double originX = x;
double originY = y;
x = vals[2];
y = vals[3];
- quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y);
- break;
- case PathIterator.SEG_CLOSE:
+ quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y, sb);
break;
default:
- break;
+ throw new IllegalStateException("Must not get here");
}
if (pendingPM0) {
pendingPM0 = false;
- gen.writeText("PM;");
- }
- if (!hasFirst) {
- firstX = x;
- firstY = y;
+ sb.append("PM;");
}
iter.next();
}
- gen.writeText("PM2;");
+ sb.append("PM2;");
+ fillPolygon(iter.getWindingRule(), sb);
+ sb.append("\n");
+ gen.writeText(sb.toString());
}
-
- private void plotAbsolute(double x, double y) throws IOException {
- gen.writeText("PA" + gen.formatDouble4(x) + ","
- + gen.formatDouble4(y) + ";");
- }
-
- private void bezierAbsolute(double x1, double y1, double x2, double y2, double x3, double y3)
- throws IOException {
- gen.writeText("BZ" + gen.formatDouble4(x1) + ","
- + gen.formatDouble4(y1) + ","
- + gen.formatDouble4(x2) + ","
- + gen.formatDouble4(y2) + ","
- + gen.formatDouble4(x3) + ","
- + gen.formatDouble4(y3) + ";");
+
+ private void fillPolygon(int windingRule, StringBuffer sb) {
+ int fillMethod = (windingRule == PathIterator.WIND_EVEN_ODD ? 0 : 1);
+ sb.append("FP").append(fillMethod).append(";");
+ }
+
+ private void plotAbsolute(double x, double y, StringBuffer sb) {
+ sb.append("PA").append(gen.formatDouble4(x));
+ sb.append(",").append(gen.formatDouble4(y)).append(";");
+ }
+
+ private void bezierAbsolute(double x1, double y1, double x2, double y2, double x3, double y3,
+ StringBuffer sb) {
+ sb.append("BZ").append(gen.formatDouble4(x1));
+ sb.append(",").append(gen.formatDouble4(y1));
+ sb.append(",").append(gen.formatDouble4(x2));
+ sb.append(",").append(gen.formatDouble4(y2));
+ sb.append(",").append(gen.formatDouble4(x3));
+ sb.append(",").append(gen.formatDouble4(y3)).append(";");
}
private void quadraticBezierAbsolute(double originX, double originY,
- double x1, double y1, double x2, double y2)
- throws IOException {
+ double x1, double y1, double x2, double y2, StringBuffer sb) {
//Quadratic Bezier curve can be mapped to a normal bezier curve
//See http://pfaedit.sourceforge.net/bezier.html
double nx1 = originX + (2.0 / 3.0) * (x1 - originX);
@@ -336,28 +461,31 @@
double nx2 = nx1 + (1.0 / 3.0) * (x2 - originX);
double ny2 = ny1 + (1.0 / 3.0) * (y2 - originY);
- bezierAbsolute(nx1, ny1, nx2, ny2, x2, y2);
+ bezierAbsolute(nx1, ny1, nx2, ny2, x2, y2, sb);
}
- private void penDown() throws IOException {
- gen.writeText("PD;");
+ private void penDown(StringBuffer sb) {
+ sb.append("PD;");
}
- private void penUp() throws IOException {
- gen.writeText("PU;");
+ private void penUp(StringBuffer sb) {
+ sb.append("PU;");
}
/** @see java.awt.Graphics2D#drawString(java.lang.String, float, float) */
public void drawString(String s, float x, float y) {
- // TODO Auto-generated method stub
- System.err.println("drawString NYI");
+ java.awt.Font awtFont = getFont();
+ FontRenderContext frc = getFontRenderContext();
+ GlyphVector gv = awtFont.createGlyphVector(frc, s);
+ Shape glyphOutline = gv.getOutline(x, y);
+ fill(glyphOutline);
}
/** @see java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float) */
public void drawString(AttributedCharacterIterator iterator, float x,
float y) {
// TODO Auto-generated method stub
- System.err.println("drawString NYI");
+ handleUnsupportedFeature("drawString NYI");
}
/**
@@ -365,8 +493,7 @@
* java.awt.geom.AffineTransform)
*/
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
- // TODO Auto-generated method stub
- System.err.println("drawRenderedImage NYI");
+ handleUnsupportedFeature("Bitmap images are not supported");
}
/**
@@ -374,8 +501,7 @@
* java.awt.geom.AffineTransform)
*/
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
- // TODO Auto-generated method stub
- System.err.println("drawRenderedImage NYI");
+ handleUnsupportedFeature("Bitmap images are not supported");
}
/**
@@ -384,8 +510,7 @@
*/
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer) {
- // TODO Auto-generated method stub
- System.err.println("drawImage NYI");
+ handleUnsupportedFeature("Bitmap images are not supported");
return false;
}
@@ -393,21 +518,62 @@
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int, java.awt.image.ImageObserver)
*/
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
- // TODO Auto-generated method stub
- System.err.println("drawImage NYI");
+ handleUnsupportedFeature("Bitmap images are not supported");
return false;
+ /*
+ * First attempt disabled.
+ * Reasons: Lack of transparency control, positioning and rotation issues
+ final int width = img.getWidth(observer);
+ final int height = img.getHeight(observer);
+ if (width == -1 || height == -1) {
+ return false;
+ }
+
+ Dimension size = new Dimension(width, height);
+ BufferedImage buf = buildBufferedImage(size);
+
+ java.awt.Graphics2D g = buf.createGraphics();
+ try {
+ g.setComposite(AlphaComposite.SrcOver);
+ g.setBackground(new Color(255, 255, 255));
+ g.setPaint(new Color(255, 255, 255));
+ g.fillRect(0, 0, width, height);
+ g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
+
+ if (!g.drawImage(img, 0, 0, observer)) {
+ return false;
+ }
+ } finally {
+ g.dispose();
+ }
+
+ try {
+ AffineTransform at = getTransform();
+ gen.enterPCLMode(false);
+ //Shape imclip = getClip(); Clipping is not available in PCL
+ Point2D p1 = new Point2D.Double(x, y);
+ at.transform(p1, p1);
+ pclContext.getTransform().transform(p1, p1);
+ gen.setCursorPos(p1.getX(), p1.getY());
+ gen.paintBitmap(buf, 72);
+ gen.enterHPGL2Mode(false);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
+ }
+
+ return true;*/
}
/** @see java.awt.Graphics#copyArea(int, int, int, int, int, int) */
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
// TODO Auto-generated method stub
- System.err.println("copyArea NYI");
+ handleUnsupportedFeature("copyArea NYI");
}
/** @see java.awt.Graphics#setXORMode(java.awt.Color) */
public void setXORMode(Color c1) {
// TODO Auto-generated method stub
- System.err.println("setXORMode NYI");
+ handleUnsupportedFeature("setXORMode NYI");
}
/**
@@ -422,6 +588,16 @@
fmg = bi.createGraphics();
}
+ /**
+ * Creates a buffered image.
+ * @param size dimensions of the image to be created
+ * @return the buffered image
+ */
+ protected BufferedImage buildBufferedImage(Dimension size) {
+ return new BufferedImage(size.width, size.height,
+ BufferedImage.TYPE_BYTE_GRAY);
+ }
+
/** @see java.awt.Graphics#getFontMetrics(java.awt.Font) */
public java.awt.FontMetrics getFontMetrics(java.awt.Font f) {
return fmg.getFontMetrics(f);
Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java?rev=398945&r1=398944&r2=398945&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java Tue May 2 07:39:32 2006
@@ -27,6 +27,9 @@
import java.awt.image.BufferedImage;
import java.io.IOException;
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.Graphics2DAdapter;
import org.apache.fop.render.Graphics2DImagePainter;
import org.apache.fop.render.RendererContext;
@@ -38,6 +41,9 @@
*/
public class PCLGraphics2DAdapter implements Graphics2DAdapter {
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PCLGraphics2DAdapter.class);
+
/**
* Main constructor
*/
@@ -57,80 +63,84 @@
float imw = (float)dim.getWidth();
float imh = (float)dim.getHeight();
+ boolean painted = false;
boolean paintAsBitmap = pclContext.paintAsBitmap();
- if (paintAsBitmap) {
+ if (!paintAsBitmap) {
+ ByteArrayOutputStream baout = new ByteArrayOutputStream();
+ PCLGenerator tempGen = new PCLGenerator(baout);
+ try {
+ GraphicContext ctx = (GraphicContext)pcl.getGraphicContext().clone();
+
+ AffineTransform prepareHPGL2 = new AffineTransform();
+ prepareHPGL2.scale(0.001, 0.001);
+ ctx.setTransform(prepareHPGL2);
+
+ PCLGraphics2D graphics = new PCLGraphics2D(tempGen);
+ graphics.setGraphicContext(ctx);
+ Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
+ painter.paint(graphics, area);
+
+ //If we arrive here, the graphic is natively paintable, so write the graphic
+ pcl.saveGraphicsState();
+ pcl.setCursorPos(x, y);
+ gen.writeCommand("*c" + gen.formatDouble4(width / 100f) + "x"
+ + gen.formatDouble4(height / 100f) + "Y");
+ gen.writeCommand("*c0T");
+ gen.enterHPGL2Mode(false);
+ gen.writeText("\nIN;");
+ gen.writeText("SP1;");
+ //One Plotter unit is 0.025mm!
+ double scale = imw / UnitConv.mm2pt(imw * 0.025);
+ gen.writeText("SC0," + gen.formatDouble4(scale)
+ + ",0,-" + gen.formatDouble4(scale) + ",2;");
+ gen.writeText("IR0,100,0,100;");
+ gen.writeText("PU;PA0,0;\n");
+ baout.writeTo(gen.getOutputStream()); //Buffer is written to output stream
+ gen.writeText("\n");
+
+ gen.enterPCLMode(false);
+ pcl.restoreGraphicsState();
+ painted = true;
+ } catch (UnsupportedOperationException uoe) {
+ log.debug(
+ "Cannot paint graphic natively. Falling back to bitmap painting. Reason: "
+ + uoe.getMessage());
+ }
+ }
+
+ if (!painted) {
int resolution = 300; //TODO not hard-coded, please!
int bmw = UnitConv.mpt2px(pclContext.getWidth(), resolution);
int bmh = UnitConv.mpt2px(pclContext.getHeight(), resolution);
BufferedImage bi = new BufferedImage(
bmw, bmh,
- BufferedImage.TYPE_INT_RGB);
+ BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = bi.createGraphics();
try {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_OFF);
- g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
- RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
- g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
- RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
- g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
- RenderingHints.VALUE_RENDER_QUALITY);
- g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
- RenderingHints.VALUE_COLOR_RENDER_QUALITY);
- g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
- RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
- g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
- RenderingHints.VALUE_DITHER_ENABLE);
- g2d.setBackground(Color.white);
- g2d.setColor(Color.black);
- g2d.clearRect(0, 0, bmw, bmh);
- double sx = (double)bmw / pclContext.getWidth() * 1000;
- double sy = (double)bmh / pclContext.getHeight() * 1000;
- g2d.scale(sx, sy);
-
- //Paint the SVG on the BufferedImage
- Rectangle2D area = new Rectangle2D.Double(
- 0.0, 0.0, pclContext.getWidth(), pclContext.getHeight());
- painter.paint(g2d, area);
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+ g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ g2d.setBackground(Color.white);
+ g2d.setColor(Color.black);
+ g2d.clearRect(0, 0, bmw, bmh);
+ double sx = (double)bmw / pclContext.getWidth();
+ double sy = (double)bmh / pclContext.getHeight();
+ g2d.scale(sx, sy);
+
+ //Paint the SVG on the BufferedImage
+ Rectangle2D area = new Rectangle2D.Double(
+ 0.0, 0.0, pclContext.getWidth(), pclContext.getHeight());
+ painter.paint(g2d, area);
} finally {
g2d.dispose();
}
- pcl.moveTo(x, y);
+ pcl.setCursorPos(x, y);
gen.paintBitmap(bi, resolution);
- } else {
- pcl.saveGraphicsState();
- GraphicContext ctx = (GraphicContext)pcl.getGraphicContext().clone();
-
- // Clip to the image area.
- //gen.writeln("newpath");
- //gen.defineRect(fx, fy, fwidth, fheight);
- //gen.writeln("clip");
-
- AffineTransform prepareHPGL2 = new AffineTransform();
- //prepareHPGL2.scale(1, 1);
- ctx.setTransform(prepareHPGL2);
-
- pcl.moveTo(x, y);
- gen.writeCommand("*c" + gen.formatDouble4(width / 100f) + "x"
- + gen.formatDouble4(height / 100f) + "Y");
- gen.writeCommand("*c0T");
- gen.writeCommand("%0B");
- gen.writeText("IN;");
- gen.writeText("SP1;");
- //One Plotter unit is 0.025mm!
- double scale = imw / UnitConv.mm2pt(imw * 0.025);
- gen.writeText("SC0," + gen.formatDouble4(scale)
- + ",0,-" + gen.formatDouble4(scale) + ",2;");
- gen.writeText("IR0,100,0,100;");
- gen.writeText("PU;PA0,0;");
- PCLGraphics2D graphics = new PCLGraphics2D(gen);
- graphics.setGraphicContext(ctx);
- Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
- painter.paint(graphics, area);
-
- gen.writeCommand("%0A");
- pcl.restoreGraphicsState();
}
}
Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java?rev=398945&r1=398944&r2=398945&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java Tue May 2 07:39:32 2006
@@ -18,7 +18,38 @@
package org.apache.fop.render.pcl;
+//Java
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+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.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.w3c.dom.Document;
+
+import org.apache.xmlgraphics.java2d.GraphicContext;
+
// FOP
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.area.Area;
@@ -31,44 +62,25 @@
import org.apache.fop.area.inline.AbstractTextArea;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.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.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontSetup;
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;
+import org.apache.fop.render.java2d.Java2DRenderer;
import org.apache.fop.traits.BorderProps;
-import org.apache.xmlgraphics.java2d.GraphicContext;
-import org.w3c.dom.Document;
-
-// Java
-import java.awt.Rectangle;
-import java.awt.color.ColorSpace;
-import java.awt.geom.AffineTransform;
-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.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
+import org.apache.fop.util.QName;
/**
* Renderer for the PCL 5 printer language. It also uses HP GL/2 for certain graphic elements.
@@ -87,6 +99,15 @@
private Stack graphicContextStack = new Stack();
private GraphicContext graphicContext = new GraphicContext();
+
+ private GeneralPath currentPath = null;
+ private java.awt.Color currentFillColor = null;
+
+ /**
+ * Controls whether appearance is more important than speed. False can cause some FO feature
+ * to be ignored (like the advanced borders).
+ */
+ private boolean qualityBeforeSpeed = false;
/**
* Create the PCL renderer
@@ -95,6 +116,23 @@
}
/**
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+ */
+ public void configure(Configuration cfg) throws ConfigurationException {
+ super.configure(cfg);
+ String rendering = cfg.getChild("rendering").getValue(null);
+ if ("quality".equalsIgnoreCase(rendering)) {
+ this.qualityBeforeSpeed = true;
+ } else if ("speed".equalsIgnoreCase(rendering)) {
+ this.qualityBeforeSpeed = false;
+ } else if (rendering != null) {
+ throw new ConfigurationException(
+ "Valid values for 'rendering' are 'quality' and 'speed'. Value found: "
+ + rendering);
+ }
+ }
+
+ /**
* Central exception handler for I/O exceptions.
* @param ioe IOException to handle
*/
@@ -229,6 +267,8 @@
this.gen = new PCLGenerator(out);
gen.universalEndOfLanguage();
+ gen.writeText("@PJL JOB NAME = \"" + userAgent.getTitle() + "\"\n");
+ gen.writeText("@PJL ENTER LANGUAGE = PCL\n");
gen.resetPrinter();
}
@@ -253,19 +293,6 @@
final long pageheight = Math.round(page.getViewArea().getHeight());
selectPageFormat(pagewidth, pageheight);
- if (false) { //TODO DEBUG CODE! Remove me.
- //gen.fillRect(0, 0, (int)pagewidth, (int)pageheight, java.awt.Color.yellow);
- //gen.fillRect(5000, 5000, (int)pagewidth - 10000, (int)pageheight - 10000, java.awt.Color.yellow);
- //gen.fillRect(10000, 10000, (int)pagewidth / 4 - 20000, (int)pageheight / 4 - 20000, java.awt.Color.red);
- for (int i = 0; i < 29; i++) {
- if (i % 2 == 0) {
- int w = (int)(10 * 2.835 * 1000);
- Point2D p = transformedPoint(i * w, 0);
- gen.fillRect((int)p.getX(), (int)p.getY(), w, w, java.awt.Color.yellow);
- }
- }
- }
-
super.renderPage(page);
gen.formFeed();
restoreGraphicsState();
@@ -389,7 +416,7 @@
saveGraphicsState();
updatePrintDirection();
graphicContext.translate(rx, bl);
- moveTo(0, 0);
+ setCursorPos(0, 0);
super.renderText(area); //Updates IPD
@@ -400,10 +427,83 @@
}
}
- void moveTo(int x, int y) throws IOException {
- Point2D transPoint = transformedPoint(x, y);
- gen.writeCommand("&a" + gen.formatDouble2(transPoint.getX() / 100) + "h"
- + gen.formatDouble2(transPoint.getY() / 100) + "V");
+ /**
+ * Sets the current cursor position. The coordinates are transformed to the absolute position
+ * on the logical PCL page and then passed on to the PCLGenerator.
+ * @param x the x coordinate (in millipoints)
+ * @param y the y coordinate (in millipoints)
+ */
+ void setCursorPos(float x, float y) {
+ try {
+ Point2D transPoint = transformedPoint(x, y);
+ gen.setCursorPos(transPoint.getX(), transPoint.getY());
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
+ }
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractPathOrientedRenderer#clip()
+ */
+ protected void clip() {
+ if (currentPath == null) {
+ throw new IllegalStateException("No current path available!");
+ }
+ //TODO Find a good way to do clipping
+ currentPath = null;
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractPathOrientedRenderer#closePath()
+ */
+ protected void closePath() {
+ currentPath.closePath();
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractPathOrientedRenderer#lineTo(float, float)
+ */
+ protected void lineTo(float x, float y) {
+ if (currentPath == null) {
+ currentPath = new GeneralPath();
+ }
+ currentPath.lineTo(x, y);
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractPathOrientedRenderer#moveTo(float, float)
+ */
+ protected void moveTo(float x, float y) {
+ if (currentPath == null) {
+ currentPath = new GeneralPath();
+ }
+ currentPath.moveTo(x, y);
+ }
+
+ /**
+ * Fill a rectangular area.
+ * @param x the x coordinate (in pt)
+ * @param y the y coordinate (in pt)
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ protected void fillRect(float x, float y, float width, float height) {
+ try {
+ Point2D p = transformedPoint(x * 1000, y * 1000);
+ gen.fillRect((int)p.getX(), (int)p.getY(),
+ (int)width * 1000, (int)height * 1000,
+ this.currentFillColor);
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
+ }
+ }
+
+ /**
+ * Sets the new current fill color.
+ * @param color the color
+ */
+ protected void updateFillColor(java.awt.Color color) {
+ this.currentFillColor = color;
}
private void updatePrintDirection() throws IOException {
@@ -482,37 +582,6 @@
}
/**
- * @see org.apache.fop.render.AbstractRenderer#renderViewport(org.apache.fop.area.inline.Viewport)
- */
- public void renderViewport(Viewport viewport) {
-
- float x = currentIPPosition / 1000f;
- float y = (currentBPPosition + viewport.getOffset()) / 1000f;
- float width = viewport.getIPD() / 1000f;
- float height = viewport.getBPD() / 1000f;
- // TODO: Calculate the border rect correctly.
- float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f;
- float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f;
- float bpwidth = borderPaddingStart
- + (viewport.getBorderAndPaddingWidthEnd() / 1000f);
- float bpheight = borderPaddingBefore
- + (viewport.getBorderAndPaddingWidthAfter() / 1000f);
-
- drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight);
-
- if (viewport.getClip()) {
- saveGraphicsState();
-
- clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
- }
- super.renderViewport(viewport);
-
- if (viewport.getClip()) {
- restoreGraphicsState();
- }
- }
-
- /**
* @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
*/
protected void renderBlockViewport(BlockViewport bv, List children) {
@@ -625,7 +694,17 @@
* @see org.apache.fop.render.AbstractRenderer#renderImage(Image, Rectangle2D)
*/
public void renderImage(Image image, Rectangle2D pos) {
- String url = ImageFactory.getURL(image.getURL());
+ drawImage(image.getURL(), pos, image.getForeignAttributes());
+ }
+
+ /**
+ * Draw an image at the indicated location.
+ * @param url 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) {
@@ -642,7 +721,7 @@
Document doc = ((XMLImage) fopimage).getDocument();
String ns = ((XMLImage) fopimage).getNameSpace();
- renderDocument(doc, ns, pos, image.getForeignAttributes());
+ renderDocument(doc, ns, pos, foreignAttributes);
} else if ("image/svg+xml".equals(mime)) {
if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
return;
@@ -650,7 +729,7 @@
Document doc = ((XMLImage) fopimage).getDocument();
String ns = ((XMLImage) fopimage).getNameSpace();
- renderDocument(doc, ns, pos, image.getForeignAttributes());
+ renderDocument(doc, ns, pos, foreignAttributes);
} else if (fopimage instanceof EPSImage) {
log.warn("EPS images are not supported by this renderer");
} else {
@@ -678,7 +757,7 @@
RenderedImage img = new BufferedImage(cm, raster, false, null);
try {
- moveTo(this.currentIPPosition + (int)pos.getX(),
+ setCursorPos(this.currentIPPosition + (int)pos.getX(),
this.currentBPPosition + (int)pos.getY());
int resolution = (int)Math.round(Math.max(fopimage.getHorizontalResolution(),
fopimage.getVerticalResolution()));
@@ -706,27 +785,72 @@
* @param foreignAttributes the foreign attributes containing rendering hints, or null
*/
public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) {
+ int x = currentIPPosition + (int) pos.getX();
+ int y = currentBPPosition + (int) pos.getY();
+ int width = (int)pos.getWidth();
+ int height = (int)pos.getHeight();
+ RendererContext context = createRendererContext(x, y, width, height, foreignAttributes);
+
+ renderXML(context, doc, ns);
+ }
+
+ /**
+ * Creates a RendererContext for an image.
+ * @param x the x coordinate (in millipoints)
+ * @param y the y coordinate (in millipoints)
+ * @param width the width of the image (in millipoints)
+ * @param height the height of the image (in millipoints)
+ * @param foreignAttributes a Map or foreign attributes, may be null
+ * @return the RendererContext
+ */
+ protected RendererContext createRendererContext(int x, int y, int width, int height,
+ Map foreignAttributes) {
RendererContext context;
context = new RendererContext(this, MIME_TYPE);
context.setUserAgent(userAgent);
context.setProperty(RendererContextConstants.WIDTH,
- new Integer((int) pos.getWidth()));
+ new Integer(width));
context.setProperty(RendererContextConstants.HEIGHT,
- new Integer((int) pos.getHeight()));
+ new Integer(height));
context.setProperty(RendererContextConstants.XPOS,
- new Integer(currentIPPosition + (int) pos.getX()));
+ new Integer(x));
context.setProperty(RendererContextConstants.YPOS,
- new Integer(currentBPPosition + (int) pos.getY()));
+ new Integer(y));
context.setProperty(RendererContextConstants.PAGE_VIEWPORT,
getCurrentPageViewport());
if (foreignAttributes != null) {
context.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, foreignAttributes);
}
-
- renderXML(context, doc, ns);
+ return context;
}
+ /**
+ * Common method to render the background and borders for any inline area.
+ * The all borders and padding are drawn outside the specified area.
+ * @param area the inline area for which the background, border and padding is to be
+ * rendered
+ * @todo Copied from AbstractPathOrientedRenderer
+ */
+ protected void renderInlineAreaBackAndBorders(InlineArea area) {
+ float x = currentIPPosition / 1000f;
+ float y = (currentBPPosition + area.getOffset()) / 1000f;
+ float width = area.getIPD() / 1000f;
+ float height = area.getBPD() / 1000f;
+ float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f;
+ float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f;
+ float bpwidth = borderPaddingStart
+ + (area.getBorderAndPaddingWidthEnd() / 1000f);
+ float bpheight = borderPaddingBefore
+ + (area.getBorderAndPaddingWidthAfter() / 1000f);
+
+ if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) {
+ drawBackAndBorders(area, x, y - borderPaddingBefore
+ , width + bpwidth
+ , height + bpheight);
+ }
+ }
+
/**
* Draw the background and borders. This draws the background and border
* traits for an area given the position.
@@ -742,127 +866,401 @@
try {
updatePrintDirection();
BorderProps bpsBefore = (BorderProps) area.getTrait(Trait.BORDER_BEFORE);
- BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER);
- BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START);
- BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END);
-
- // draw background
- Trait.Background back;
- back = (Trait.Background) area.getTrait(Trait.BACKGROUND);
- if (back != null) {
-
- // Calculate padding rectangle
- float sx = startx;
- float sy = starty;
- float paddRectWidth = width;
- float paddRectHeight = height;
-
- if (bpsStart != null) {
- sx += bpsStart.width / 1000f;
- paddRectWidth -= bpsStart.width / 1000f;
- }
- if (bpsBefore != null) {
- sy += bpsBefore.width / 1000f;
- paddRectHeight -= bpsBefore.width / 1000f;
- }
- if (bpsEnd != null) {
- paddRectWidth -= bpsEnd.width / 1000f;
- }
- if (bpsAfter != null) {
- paddRectHeight -= bpsAfter.width / 1000f;
- }
-
- if (back.getColor() != null) {
- Point2D p = transformedPoint(sx * 1000, sy * 1000);
- gen.fillRect((int)p.getX(), (int)p.getY(),
- (int)paddRectWidth * 1000, (int)paddRectHeight * 1000,
- back.getColor().getAWTColor());
- }
-
- // 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;
- pos = new Rectangle2D.Float(sx
- + (x * fopimage.getIntrinsicWidth()), sy
- + (y * fopimage.getIntrinsicHeight()),
- fopimage.getIntrinsicWidth(), fopimage
- .getIntrinsicHeight());
- //putImage(back.getURL(), pos); // TODO test
+ BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER);
+ BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START);
+ BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END);
+
+ // draw background
+ Trait.Background back;
+ back = (Trait.Background) area.getTrait(Trait.BACKGROUND);
+ if (back != null) {
+
+ // Calculate padding rectangle
+ float sx = startx;
+ float sy = starty;
+ float paddRectWidth = width;
+ float paddRectHeight = height;
+
+ if (bpsStart != null) {
+ sx += bpsStart.width / 1000f;
+ paddRectWidth -= bpsStart.width / 1000f;
+ }
+ if (bpsBefore != null) {
+ sy += bpsBefore.width / 1000f;
+ paddRectHeight -= bpsBefore.width / 1000f;
+ }
+ if (bpsEnd != null) {
+ paddRectWidth -= bpsEnd.width / 1000f;
+ }
+ if (bpsAfter != null) {
+ paddRectHeight -= bpsAfter.width / 1000f;
+ }
+
+ if (back.getColor() != null) {
+ updateFillColor(back.getColor().getAWTColor());
+ fillRect(sx, sy, paddRectWidth, paddRectHeight);
+ }
+
+ // 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);
+ }
+ }
+ restoreGraphicsState();
+ } else {
+ log.warn(
+ "Can't find background image: " + back.getURL());
}
- restoreGraphicsState();
- } else {
- log.warn(
- "Can't find background image: " + back.getURL());
}
}
+
+ Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height);
+ drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
}
-/*
- // draw border
- // BORDER_BEFORE
+ }
+
+ /**
+ * Draws borders.
+ * @param borderRect the border rectangle
+ * @param bpsBefore the border specification on the before side
+ * @param bpsAfter the border specification on the after side
+ * @param bpsStart the border specification on the start side
+ * @param bpsEnd the border specification on the end side
+ */
+ protected void drawBorders(Rectangle2D.Float borderRect,
+ final BorderProps bpsBefore, final BorderProps bpsAfter,
+ final BorderProps bpsStart, final BorderProps bpsEnd) {
+ if (bpsBefore == null && bpsAfter == null && bpsStart == null && bpsEnd == null) {
+ return; //no borders to paint
+ }
+ if (qualityBeforeSpeed) {
+ drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+ } else {
+ drawFastBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+ }
+ }
+
+ /**
+ * Draws borders. Borders are drawn as shaded rectangles with no clipping.
+ * @param borderRect the border rectangle
+ * @param bpsBefore the border specification on the before side
+ * @param bpsAfter the border specification on the after side
+ * @param bpsStart the border specification on the start side
+ * @param bpsEnd the border specification on the end side
+ */
+ protected void drawFastBorders(Rectangle2D.Float borderRect,
+ final BorderProps bpsBefore, final BorderProps bpsAfter,
+ final BorderProps bpsStart, final BorderProps bpsEnd) {
+ float startx = borderRect.x;
+ float starty = borderRect.y;
+ float width = borderRect.width;
+ float height = borderRect.height;
if (bpsBefore != null) {
int borderWidth = (int) Math.round((bpsBefore.width / 1000f));
- state.updateColor(bpsBefore.color);
- state.getGraph().fillRect((int) startx, (int) starty, (int) width,
+ updateFillColor(bpsBefore.color.getAWTColor());
+ fillRect((int) startx, (int) starty, (int) width,
borderWidth);
}
- // BORDER_AFTER
if (bpsAfter != null) {
int borderWidth = (int) Math.round((bpsAfter.width / 1000f));
- float sy = starty + height;
- state.updateColor(bpsAfter.color);
- state.getGraph().fillRect((int) startx,
+ updateFillColor(bpsAfter.color.getAWTColor());
+ fillRect((int) startx,
(int) (starty + height - borderWidth), (int) width,
borderWidth);
}
- // BORDER_START
if (bpsStart != null) {
int borderWidth = (int) Math.round((bpsStart.width / 1000f));
- state.updateColor(bpsStart.color);
- state.getGraph().fillRect((int) startx, (int) starty, borderWidth,
+ updateFillColor(bpsStart.color.getAWTColor());
+ fillRect((int) startx, (int) starty, borderWidth,
(int) height);
}
- // BORDER_END
if (bpsEnd != null) {
int borderWidth = (int) Math.round((bpsEnd.width / 1000f));
- float sx = startx + width;
- state.updateColor(bpsEnd.color);
- state.getGraph().fillRect((int) (startx + width - borderWidth),
+ updateFillColor(bpsEnd.color.getAWTColor());
+ fillRect((int) (startx + width - borderWidth),
(int) starty, borderWidth, (int) height);
}
- */
+ }
+
+ /**
+ * Draws borders. Borders are drawn in-memory and painted as a bitmap.
+ * @param borderRect the border rectangle
+ * @param bpsBefore the border specification on the before side
+ * @param bpsAfter the border specification on the after side
+ * @param bpsStart the border specification on the start side
+ * @param bpsEnd the border specification on the end side
+ */
+ protected void drawQualityBorders(Rectangle2D.Float borderRect,
+ final BorderProps bpsBefore, final BorderProps bpsAfter,
+ final BorderProps bpsStart, final BorderProps bpsEnd) {
+ Graphics2DAdapter g2a = getGraphics2DAdapter();
+ final Rectangle.Float effBorderRect = new Rectangle2D.Float(
+ borderRect.x - (currentIPPosition / 1000f),
+ borderRect.y - (currentBPPosition / 1000f),
+ borderRect.width, borderRect.height);
+ final Rectangle paintRect = new Rectangle(
+ (int)Math.round(borderRect.x * 1000),
+ (int)Math.round(borderRect.y * 1000),
+ (int)Math.floor(borderRect.width * 1000) + 1,
+ (int)Math.floor(borderRect.height * 1000) + 1);
+ int xoffset = (bpsStart != null ? bpsStart.width : 0);
+ paintRect.x += xoffset;
+ paintRect.width += xoffset;
+ paintRect.width += (bpsEnd != null ? bpsEnd.width : 0);
+
+ RendererContext rc = createRendererContext(paintRect.x, paintRect.y,
+ paintRect.width, paintRect.height, null);
+ if (false) {
+ Map atts = new java.util.HashMap();
+ atts.put(new QName(ExtensionElementMapping.URI, null, "conversion-mode"), "bitmap");
+ rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts);
+ }
+
+ Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+ public void paint(Graphics2D g2d, Rectangle2D area) {
+ g2d.translate((bpsStart != null ? bpsStart.width : 0), 0);
+ g2d.scale(1000, 1000);
+ float startx = effBorderRect.x;
+ float starty = effBorderRect.y;
+ float width = effBorderRect.width;
+ float height = effBorderRect.height;
+ boolean[] b = new boolean[] {
+ (bpsBefore != null), (bpsEnd != null),
+ (bpsAfter != null), (bpsStart != null)};
+ if (!b[0] && !b[1] && !b[2] && !b[3]) {
+ return;
+ }
+ float[] bw = new float[] {
+ (b[0] ? bpsBefore.width / 1000f : 0.0f),
+ (b[1] ? bpsEnd.width / 1000f : 0.0f),
+ (b[2] ? bpsAfter.width / 1000f : 0.0f),
+ (b[3] ? bpsStart.width / 1000f : 0.0f)};
+ float[] clipw = new float[] {
+ BorderProps.getClippedWidth(bpsBefore) / 1000f,
+ BorderProps.getClippedWidth(bpsEnd) / 1000f,
+ BorderProps.getClippedWidth(bpsAfter) / 1000f,
+ BorderProps.getClippedWidth(bpsStart) / 1000f};
+ starty += clipw[0];
+ height -= clipw[0];
+ height -= clipw[2];
+ startx += clipw[3];
+ width -= clipw[3];
+ width -= clipw[1];
+
+ boolean[] slant = new boolean[] {
+ (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
+ if (bpsBefore != null) {
+ //endTextObject();
+
+ float sx1 = startx;
+ float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
+ float ex1 = startx + width;
+ float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
+ float outery = starty - clipw[0];
+ float clipy = outery + clipw[0];
+ float innery = outery + bw[0];
+
+ //saveGraphicsState();
+ Graphics2D g = (Graphics2D)g2d.create();
+ moveTo(sx1, clipy);
+ float sx1a = sx1;
+ float ex1a = ex1;
+ if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+ if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+ sx1a -= clipw[3];
+ }
+ if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+ ex1a += clipw[1];
+ }
+ lineTo(sx1a, outery);
+ lineTo(ex1a, outery);
+ }
+ lineTo(ex1, clipy);
+ lineTo(ex2, innery);
+ lineTo(sx2, innery);
+ closePath();
+ //clip();
+ g.clip(currentPath);
+ currentPath = null;
+ Rectangle2D.Float lineRect = new Rectangle2D.Float(
+ sx1a, outery, ex1a - sx1a, innery - outery);
+ Java2DRenderer.drawBorderLine(lineRect, true, true,
+ bpsBefore.style, toColor(bpsBefore.color), g);
+ //restoreGraphicsState();
+ }
+ if (bpsEnd != null) {
+ //endTextObject();
+
+ float sy1 = starty;
+ float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
+ float ey1 = starty + height;
+ float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
+ float outerx = startx + width + clipw[1];
+ float clipx = outerx - clipw[1];
+ float innerx = outerx - bw[1];
+
+ //saveGraphicsState();
+ Graphics2D g = (Graphics2D)g2d.create();
+ moveTo(clipx, sy1);
+ float sy1a = sy1;
+ float ey1a = ey1;
+ if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+ if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+ sy1a -= clipw[0];
+ }
+ if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+ ey1a += clipw[2];
+ }
+ lineTo(outerx, sy1a);
+ lineTo(outerx, ey1a);
+ }
+ lineTo(clipx, ey1);
+ lineTo(innerx, ey2);
+ lineTo(innerx, sy2);
+ closePath();
+ //clip();
+ g.setClip(currentPath);
+ currentPath = null;
+ Rectangle2D.Float lineRect = new Rectangle2D.Float(
+ innerx, sy1a, outerx - innerx, ey1a - sy1a);
+ Java2DRenderer.drawBorderLine(lineRect, false, false,
+ bpsEnd.style, toColor(bpsEnd.color), g);
+ //restoreGraphicsState();
+ }
+ if (bpsAfter != null) {
+ //endTextObject();
+
+ float sx1 = startx;
+ float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
+ float ex1 = startx + width;
+ float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
+ float outery = starty + height + clipw[2];
+ float clipy = outery - clipw[2];
+ float innery = outery - bw[2];
+
+ //saveGraphicsState();
+ Graphics2D g = (Graphics2D)g2d.create();
+ moveTo(ex1, clipy);
+ float sx1a = sx1;
+ float ex1a = ex1;
+ if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+ if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+ sx1a -= clipw[3];
+ }
+ if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+ ex1a += clipw[1];
+ }
+ lineTo(ex1a, outery);
+ lineTo(sx1a, outery);
+ }
+ lineTo(sx1, clipy);
+ lineTo(sx2, innery);
+ lineTo(ex2, innery);
+ closePath();
+ //clip();
+ g.setClip(currentPath);
+ currentPath = null;
+ Rectangle2D.Float lineRect = new Rectangle2D.Float(
+ sx1a, innery, ex1a - sx1a, outery - innery);
+ Java2DRenderer.drawBorderLine(lineRect, true, false,
+ bpsAfter.style, toColor(bpsAfter.color), g);
+ //restoreGraphicsState();
+ }
+ if (bpsStart != null) {
+ //endTextObject();
+
+ float sy1 = starty;
+ float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
+ float ey1 = sy1 + height;
+ float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
+ float outerx = startx - clipw[3];
+ float clipx = outerx + clipw[3];
+ float innerx = outerx + bw[3];
+
+ //saveGraphicsState();
+ Graphics2D g = (Graphics2D)g2d.create();
+ moveTo(clipx, ey1);
+ float sy1a = sy1;
+ float ey1a = ey1;
+ if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+ if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+ sy1a -= clipw[0];
+ }
+ if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+ ey1a += clipw[2];
+ }
+ lineTo(outerx, ey1a);
+ lineTo(outerx, sy1a);
+ }
+ lineTo(clipx, sy1);
+ lineTo(innerx, sy2);
+ lineTo(innerx, ey2);
+ closePath();
+ //clip();
+ g.setClip(currentPath);
+ currentPath = null;
+ Rectangle2D.Float lineRect = new Rectangle2D.Float(
+ outerx, sy1a, innerx - outerx, ey1a - sy1a);
+ Java2DRenderer.drawBorderLine(lineRect, false, false,
+ bpsStart.style, toColor(bpsStart.color), g);
+ //restoreGraphicsState();
+ }
+ }
+
+ public Dimension getImageSize() {
+ return paintRect.getSize();
+ }
+
+ };
+ try {
+ g2a.paintImage(painter, rc,
+ paintRect.x - xoffset, paintRect.y, paintRect.width, paintRect.height);
} catch (IOException ioe) {
handleIOTrouble(ioe);
}
}
-
+
+
}
Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java?rev=398945&r1=398944&r2=398945&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java Tue May 2 07:39:32 2006
@@ -86,33 +86,35 @@
int x = pclContext.getCurrentXPosition();
int y = pclContext.getCurrentYPosition();
+ SVGUserAgent ua = new SVGUserAgent(
+ context.getUserAgent().getSourcePixelUnitToMillimeter(),
+ new AffineTransform());
+ GVTBuilder builder = new GVTBuilder();
+ final BridgeContext ctx = new BridgeContext(ua);
+
+ final GraphicsNode root;
+ try {
+ root = builder.build(ctx, doc);
+
+ } catch (Exception e) {
+ log.error("SVG graphic could not be built: "
+ + e.getMessage(), e);
+ return;
+ }
+
Graphics2DImagePainter painter = new Graphics2DImagePainter() {
public void paint(Graphics2D g2d, Rectangle2D area) {
- SVGUserAgent ua = new SVGUserAgent(
- context.getUserAgent().getSourcePixelUnitToMillimeter(),
- new AffineTransform());
- GVTBuilder builder = new GVTBuilder();
- BridgeContext ctx = new BridgeContext(ua);
-
- GraphicsNode root;
- try {
- root = builder.build(ctx, doc);
-
- // If no viewbox is defined in the svg file, a viewbox of 100x100 is
- // assumed, as defined in SVGUserAgent.getViewportSize()
- float iw = (float) ctx.getDocumentSize().getWidth() * 1000f;
- float ih = (float) ctx.getDocumentSize().getHeight() * 1000f;
- float w = (float) area.getWidth();
- float h = (float) area.getHeight();
- g2d.scale(w / iw, h / ih);
+
+ // If no viewbox is defined in the svg file, a viewbox of 100x100 is
+ // assumed, as defined in SVGUserAgent.getViewportSize()
+ float iw = (float) ctx.getDocumentSize().getWidth();
+ float ih = (float) ctx.getDocumentSize().getHeight();
+ float w = (float) area.getWidth();
+ float h = (float) area.getHeight();
+ g2d.scale(w / iw, h / ih);
- root.paint(g2d);
- } catch (Exception e) {
- log.error("SVG graphic could not be built: "
- + e.getMessage(), e);
- return;
- }
+ root.paint(g2d);
}
public Dimension getImageSize() {
Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java?rev=398945&r1=398944&r2=398945&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java Tue May 2 07:39:32 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.inline.ForeignObject;
+import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.svg.SVGUtilities;
@@ -430,6 +431,10 @@
* @see org.apache.fop.render.AbstractRenderer#endVParea()
*/
protected void endVParea() {
+ // TODO Auto-generated method stub
+ }
+
+ protected void renderInlineAreaBackAndBorders(InlineArea area) {
// TODO Auto-generated method stub
}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org