public void formFeed() throws IOException {
out.write(12); //=OC ("FF", Form feed)
}
+
+ /**
+ * Sets the unit of measure.
+ * @param value the resolution value (units per inch)
+ * @throws IOException In case of an I/O error
+ */
+ public void setUnitOfMeasure(int value) throws IOException {
+ writeCommand("&u" + value + "D");
+ }
+
+ /**
+ * Sets the raster graphics resolution
+ * @param value the resolution value (units per inch)
+ * @throws IOException In case of an I/O error
+ */
+ public void setRasterGraphicsResolution(int value) throws IOException {
+ writeCommand("*t" + value + "R");
+ }
+ /**
+ * Selects the page size.
+ * @param selector the integer representing the page size
+ * @throws IOException In case of an I/O error
+ */
+ public void selectPageSize(int selector) throws IOException {
+ writeCommand("&l" + selector + "A");
+ }
+
/**
* Clears the horizontal margins.
* @throws IOException In case of an I/O error
writeCommand("&l" + numberOfLines + "E");
}
+ /**
+ * The Text Length command can be used to define the bottom border. See the PCL specification
+ * for details.
+ * @param numberOfLines the number of lines
+ * @throws IOException In case of an I/O error
+ */
+ public void setTextLength(int numberOfLines) throws IOException {
+ writeCommand("&l" + numberOfLines + "F");
+ }
+
+ /**
+ * Sets the Vertical Motion Index (VMI).
+ * @param value the VMI value
+ * @throws IOException In case of an I/O error
+ */
+ public void setVMI(double value) throws IOException {
+ writeCommand("&l" + formatDouble4(value) + "C");
+ }
+
/**
* Sets the cursor to a new absolute coordinate.
* @param x the X coordinate (in millipoints)
}
}
+ /**
+ * Changes the current print direction while maintaining the current cursor position.
+ * @param rotate the rotation angle (counterclockwise), one of 0, 90, 180 and 270.
+ * @throws IOException In case of an I/O error
+ */
+ public void changePrintDirection(int rotate) throws IOException {
+ writeCommand("&a" + rotate + "P");
+ }
+
/**
* Enters the HP GL/2 mode.
* @param restorePreviousHPGL2Cursor true if the previous HP GL/2 pen position should be
}
/**
- * Generate a filled rectangle
+ * Generate a filled rectangle at the current cursor position.
*
- * @param x the x position of left edge in millipoints
- * @param y the y position of top edge in millipoints
* @param w the width in millipoints
* @param h the height in millipoints
* @param col the fill color
* @throws IOException In case of an I/O error
*/
- protected void fillRect(int x, int y, int w, int h, Color col) throws IOException {
+ protected void fillRect(int w, int h, Color col) throws IOException {
if ((w == 0) || (h == 0)) {
return;
}
//y += h;
}
- int xpos = (x / 100);
- if (xpos < 0) {
- //A negative x coordinate can lead to a displaced rectangle (xpos must be >= 0)
- w += x;
- xpos = 0;
- }
- writeCommand("*v1O");
- writeCommand("&a" + formatDouble4(xpos) + "h"
- + formatDouble4(y / 100) + "V");
+ setPatternTransparencyMode(false);
writeCommand("*c" + formatDouble4(w / 100) + "h"
+ formatDouble4(h / 100) + "V");
int lineshade = convertToPCLShade(col);
writeCommand("*c" + lineshade + "G");
writeCommand("*c2P");
// Reset pattern transparency mode.
- writeCommand("*v0O");
+ setPatternTransparencyMode(true);
}
/**
if (!isValidPCLResolution(resolution)) {
throw new IllegalArgumentException("Invalid PCL resolution: " + resolution);
}
- writeCommand("*t" + resolution + "R");
+ setRasterGraphicsResolution(resolution);
writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
Raster raster = img.getData();
boolean monochrome = isMonochromeImage(img);
package org.apache.fop.render.pcl;
+import java.awt.Dimension;
+import java.awt.Rectangle;
import java.util.Iterator;
import java.util.List;
public class PCLPageDefinition {
private static List pageDefinitions;
+ private static PCLPageDefinition defaultPageDefinition;
private String name;
- private long width; //in mpt
- private long height; //in mpt
- private int logicalPageXOffset; //in mpt
+ private int selector;
+ private Dimension physicalPageSize;
+ private Rectangle logicalPageRect;
private boolean landscape;
static {
createPageDefinitions();
}
- public PCLPageDefinition(String name, long width, long height, int logicalPageXOffset) {
- this(name, width, height, logicalPageXOffset, false);
- }
-
- public PCLPageDefinition(String name, long width, long height, int logicalPageXOffset,
- boolean landscape) {
+ /**
+ * Main constructor
+ * @param name the name of the page definition
+ * @param selector the selector used by the <ESC>&l#A command (page size)
+ * @param physicalPageSize the physical page size
+ * @param logicalPageRect the rectangle defining the logical page
+ * @param landscape true if it is a landscape format
+ */
+ public PCLPageDefinition(String name, int selector, Dimension physicalPageSize,
+ Rectangle logicalPageRect, boolean landscape) {
this.name = name;
- this.width = width;
- this.height = height;
- this.logicalPageXOffset = logicalPageXOffset;
+ this.selector = selector;
+ this.physicalPageSize = physicalPageSize;
+ this.logicalPageRect = logicalPageRect;
this.landscape = landscape;
}
+ /** @return the name of the page definition */
public String getName() {
return this.name;
}
+ /** @return the selector used by the <ESC>&l#A command (page size) */
+ public int getSelector() {
+ return this.selector;
+ }
+
+ /** @return true if it is a landscape format */
public boolean isLandscapeFormat() {
return this.landscape;
}
+
+ /** @return the physical page size */
+ public Dimension getPhysicalPageSize() {
+ return this.physicalPageSize;
+ }
- public int getLogicalPageXOffset() {
- return this.logicalPageXOffset;
+ /** @return the rectangle defining the logical page */
+ public Rectangle getLogicalPageRect() {
+ return this.logicalPageRect;
}
- public boolean matches(long width, long height, int errorMargin) {
- return (Math.abs(this.width - width) < errorMargin)
- && (Math.abs(this.height - height) < errorMargin);
+ private boolean matches(long width, long height, int errorMargin) {
+ return (Math.abs(this.physicalPageSize.width - width) < errorMargin)
+ && (Math.abs(this.physicalPageSize.height - height) < errorMargin);
}
/** @see java.lang.Object#toString() */
return getName();
}
+ /**
+ * Tries to determine a matching page definition.
+ * @param width the physical page width (in mpt)
+ * @param height the physical page height (in mpt)
+ * @param errorMargin the error margin for detecting the right page definition
+ * @return the page definition or null if no match was found
+ */
public static PCLPageDefinition getPageDefinition(long width, long height, int errorMargin) {
Iterator iter = pageDefinitions.iterator();
while (iter.hasNext()) {
return null;
}
+ /** @return the default page definition (letter) */
+ public static PCLPageDefinition getDefaultPageDefinition() {
+ return defaultPageDefinition;
+ }
+
/**
* Converts an offset values for logical pages to millipoints. The values are given as pixels
* in a 300dpi environment.
* @param offset the offset as given in the PCL 5 specification (under "Printable Area")
* @return the converted value in millipoints
*/
- private static int convertLogicalPageXOffset(int offset) {
+ private static int convert300dpiDotsToMpt(int offset) {
return (int)Math.round(((double)offset) * 72000 / 300);
}
+ private static Dimension createPhysicalPageSizeInch(float width, float height) {
+ return new Dimension(
+ (int)Math.round(UnitConv.in2mpt(width)),
+ (int)Math.round(UnitConv.in2mpt(height)));
+ }
+
+ private static Dimension createPhysicalPageSizeMm(float width, float height) {
+ return new Dimension(
+ (int)Math.round(UnitConv.mm2mpt(width)),
+ (int)Math.round(UnitConv.mm2mpt(height)));
+ }
+
+ private static Rectangle createLogicalPageRect(int x, int y, int width, int height) {
+ return new Rectangle(convert300dpiDotsToMpt(x), convert300dpiDotsToMpt(y),
+ convert300dpiDotsToMpt(width), convert300dpiDotsToMpt(height));
+ }
+
private static void createPageDefinitions() {
pageDefinitions = new java.util.ArrayList();
- pageDefinitions.add(new PCLPageDefinition("Letter",
- Math.round(UnitConv.in2mpt(8.5)), Math.round(UnitConv.in2mpt(11)),
- convertLogicalPageXOffset(75)));
- pageDefinitions.add(new PCLPageDefinition("Legal",
- Math.round(UnitConv.in2mpt(8.5)), Math.round(UnitConv.in2mpt(14)),
- convertLogicalPageXOffset(75)));
- pageDefinitions.add(new PCLPageDefinition("Executive",
- Math.round(UnitConv.in2mpt(7.25)), Math.round(UnitConv.in2mpt(10.5)),
- convertLogicalPageXOffset(75)));
- pageDefinitions.add(new PCLPageDefinition("Ledger",
- Math.round(UnitConv.in2mpt(11)), Math.round(UnitConv.in2mpt(17)),
- convertLogicalPageXOffset(75)));
- pageDefinitions.add(new PCLPageDefinition("A4",
- Math.round(UnitConv.mm2mpt(210)), Math.round(UnitConv.mm2mpt(297)),
- convertLogicalPageXOffset(71)));
- pageDefinitions.add(new PCLPageDefinition("A3",
- Math.round(UnitConv.mm2mpt(297)), Math.round(UnitConv.mm2mpt(420)),
- convertLogicalPageXOffset(71)));
+ pageDefinitions.add(new PCLPageDefinition("Letter", 2,
+ createPhysicalPageSizeInch(8.5f, 11),
+ createLogicalPageRect(75, 0, 2400, 3300), false));
+ defaultPageDefinition = new PCLPageDefinition("Legal", 3,
+ createPhysicalPageSizeInch(8.5f, 14),
+ createLogicalPageRect(75, 0, 2400, 4200), false);
+ pageDefinitions.add(defaultPageDefinition);
+ pageDefinitions.add(new PCLPageDefinition("Executive", 1,
+ createPhysicalPageSizeInch(7.25f, 10.5f),
+ createLogicalPageRect(75, 0, 2025, 3150), false));
+ pageDefinitions.add(new PCLPageDefinition("Ledger", 6,
+ createPhysicalPageSizeInch(11, 17),
+ createLogicalPageRect(75, 0, 3150, 5100), false));
+ pageDefinitions.add(new PCLPageDefinition("A4", 26,
+ createPhysicalPageSizeMm(210, 297),
+ createLogicalPageRect(71, 0, 2338, 3507), false));
+ pageDefinitions.add(new PCLPageDefinition("A3", 27,
+ createPhysicalPageSizeMm(297, 420),
+ createLogicalPageRect(71, 0, 3365, 4960), false));
//TODO Add envelope definitions
- pageDefinitions.add(new PCLPageDefinition("LetterL",
- Math.round(UnitConv.in2mpt(11)), Math.round(UnitConv.in2mpt(8.5)),
- convertLogicalPageXOffset(60)));
- pageDefinitions.add(new PCLPageDefinition("LegalL",
- Math.round(UnitConv.in2mpt(14)), Math.round(UnitConv.in2mpt(8.5)),
- convertLogicalPageXOffset(60)));
- pageDefinitions.add(new PCLPageDefinition("ExecutiveL",
- Math.round(UnitConv.in2mpt(10.5)), Math.round(UnitConv.in2mpt(7.25)),
- convertLogicalPageXOffset(60)));
- pageDefinitions.add(new PCLPageDefinition("LedgerL",
- Math.round(UnitConv.in2mpt(17)), Math.round(UnitConv.in2mpt(11)),
- convertLogicalPageXOffset(60)));
- pageDefinitions.add(new PCLPageDefinition("A4L",
- Math.round(UnitConv.mm2mpt(297)), Math.round(UnitConv.mm2mpt(210)),
- convertLogicalPageXOffset(59), true));
- pageDefinitions.add(new PCLPageDefinition("A3L",
- Math.round(UnitConv.mm2mpt(420)), Math.round(UnitConv.mm2mpt(297)),
- convertLogicalPageXOffset(59)));
+ pageDefinitions.add(new PCLPageDefinition("LetterL", 2,
+ createPhysicalPageSizeInch(11, 8.5f),
+ createLogicalPageRect(60, 0, 3180, 2550), true));
+ pageDefinitions.add(new PCLPageDefinition("LegalL", 3,
+ createPhysicalPageSizeInch(14, 8.5f),
+ createLogicalPageRect(60, 0, 4080, 2550), true));
+ pageDefinitions.add(new PCLPageDefinition("ExecutiveL", 1,
+ createPhysicalPageSizeInch(10.5f, 7.25f),
+ createLogicalPageRect(60, 0, 3030, 2175), true));
+ pageDefinitions.add(new PCLPageDefinition("LedgerL", 6,
+ createPhysicalPageSizeInch(17, 11),
+ createLogicalPageRect(60, 0, 4980, 3300), true));
+ pageDefinitions.add(new PCLPageDefinition("A4L", 26,
+ createPhysicalPageSizeMm(297, 210),
+ createLogicalPageRect(59, 0, 3389, 2480), true));
+ pageDefinitions.add(new PCLPageDefinition("A3L", 27,
+ createPhysicalPageSizeMm(420, 297),
+ createLogicalPageRect(59, 0, 4842, 3507), true));
}
-
}
// FOP
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.area.Area;
import org.apache.fop.render.java2d.Java2DRenderer;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.util.QName;
+import org.apache.fop.util.UnitConv;
/**
* Renderer for the PCL 5 printer language. It also uses HP GL/2 for certain graphic elements.
*/
public class PCLRenderer extends PrintRenderer {
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PCLRenderer.class);
+
/** The MIME type for PCL */
public static final String MIME_TYPE = MimeConstants.MIME_PCL_ALT;
private Stack graphicContextStack = new Stack();
private GraphicContext graphicContext = new GraphicContext();
+ private PCLPageDefinition currentPageDefinition;
+ private int currentPrintDirection = 0;
private GeneralPath currentPath = null;
private java.awt.Color currentFillColor = null;
}
private void selectPageFormat(long pagewidth, long pageheight) throws IOException {
-
- PCLPageDefinition pageDef = PCLPageDefinition.getPageDefinition(
+ this.currentPageDefinition = PCLPageDefinition.getPageDefinition(
pagewidth, pageheight, 1000);
- if (pageDef != null) {
- // Adjust for the offset into the logical page
- graphicContext.translate(-pageDef.getLogicalPageXOffset(), 0);
- if (pageDef.isLandscapeFormat()) {
- gen.writeCommand("&l1O"); //Orientation
- } else {
- gen.writeCommand("&l0O"); //Orientation
- }
+ if (this.currentPageDefinition == null) {
+ this.currentPageDefinition = PCLPageDefinition.getDefaultPageDefinition();
+ log.warn("Paper type could not be determined. Falling back to: "
+ + this.currentPageDefinition.getName());
+ }
+ log.debug("page size: " + currentPageDefinition.getPhysicalPageSize());
+ log.debug("logical page: " + currentPageDefinition.getLogicalPageRect());
+ gen.selectPageSize(this.currentPageDefinition.getSelector());
+
+ if (this.currentPageDefinition.isLandscapeFormat()) {
+ gen.writeCommand("&l1O"); //Orientation
} else {
- // Adjust for the offset into the logical page
- // X Offset to allow for PCL implicit 1/4" left margin (= 180 decipoints)
- graphicContext.translate(-18000, 18000);
gen.writeCommand("&l0O"); //Orientation
}
gen.clearHorizontalMargins();
gen.setTopMargin(0);
+ gen.setVMI(0);
+ gen.setUnitOfMeasure(600);
+ gen.setRasterGraphicsResolution(600);
}
/** Saves the current graphics state on the stack. */
//PCL cannot clip (only HP GL/2 can)
}
+ private Point2D transformedPoint(float x, float y) {
+ return transformedPoint(Math.round(x), Math.round(y));
+ }
+
+ private Point2D transformedPoint(int x, int y) {
+ AffineTransform at = graphicContext.getTransform();
+ if (log.isTraceEnabled()) {
+ log.trace("Current transform: " + at);
+ }
+ Point2D.Float orgPoint = new Point2D.Float(x, y);
+ Point2D.Float transPoint = new Point2D.Float();
+ at.transform(orgPoint, transPoint);
+ //At this point we have the absolute position in FOP's coordinate system
+
+ //Now get PCL coordinates taking the current print direction and the logical page
+ //into account.
+ Dimension pageSize = currentPageDefinition.getPhysicalPageSize();
+ Rectangle logRect = currentPageDefinition.getLogicalPageRect();
+ switch (currentPrintDirection) {
+ case 0:
+ transPoint.x -= logRect.x;
+ transPoint.y -= logRect.y;
+ break;
+ case 90:
+ float ty = transPoint.x;
+ transPoint.x = pageSize.height - transPoint.y;
+ transPoint.y = ty;
+ transPoint.x -= logRect.y;
+ transPoint.y -= logRect.x;
+ break;
+ case 180:
+ transPoint.x = pageSize.width - transPoint.x;
+ transPoint.y = pageSize.height - transPoint.y;
+ transPoint.x -= pageSize.width - logRect.x - logRect.width;
+ transPoint.y -= pageSize.height - logRect.y - logRect.height;
+ //The next line is odd and is probably necessary due to the default value of the
+ //Text Length command: "1/2 inch less than maximum text length"
+ //I wonder why this isn't necessary for the 90° rotation. *shrug*
+ transPoint.y -= UnitConv.in2mpt(0.5);
+ break;
+ case 270:
+ float tx = transPoint.y;
+ transPoint.y = pageSize.width - transPoint.x;
+ transPoint.x = tx;
+ transPoint.x -= pageSize.height - logRect.y - logRect.height;
+ transPoint.y -= pageSize.width - logRect.x - logRect.width;
+ break;
+ default:
+ throw new IllegalStateException("Illegal print direction: " + currentPrintDirection);
+ }
+ return transPoint;
+ }
+
+ private void changePrintDirection() {
+ AffineTransform at = graphicContext.getTransform();
+ int newDir;
+ try {
+ if (at.getScaleX() == 0 && at.getScaleY() == 0
+ && at.getShearX() == 1 && at.getShearY() == -1) {
+ newDir = 90;
+ } else if (at.getScaleX() == -1 && at.getScaleY() == -1
+ && at.getShearX() == 0 && at.getShearY() == 0) {
+ newDir = 180;
+ } else if (at.getScaleX() == 0 && at.getScaleY() == 0
+ && at.getShearX() == -1 && at.getShearY() == 1) {
+ newDir = 270;
+ } else {
+ newDir = 0;
+ }
+ if (newDir != this.currentPrintDirection) {
+ this.currentPrintDirection = newDir;
+ gen.changePrintDirection(this.currentPrintDirection);
+ }
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
+ }
+ }
+
/**
* @see org.apache.fop.render.AbstractRenderer#startVParea(CTM, Rectangle2D)
*/
protected void startVParea(CTM ctm, Rectangle2D clippingRect) {
saveGraphicsState();
AffineTransform at = new AffineTransform(ctm.toArray());
- log.debug("startVPArea: " + at);
graphicContext.transform(at);
+ changePrintDirection();
+ if (log.isDebugEnabled()) {
+ log.debug("startVPArea: " + at + " --> " + graphicContext.getTransform());
+ }
}
/**
*/
protected void endVParea() {
restoreGraphicsState();
+ changePrintDirection();
+ if (log.isDebugEnabled()) {
+ log.debug("endVPArea() --> " + graphicContext.getTransform());
+ }
}
/**
}
saveGraphicsState();
- updatePrintDirection();
graphicContext.translate(rx, bl);
setCursorPos(0, 0);
if (currentPath == null) {
throw new IllegalStateException("No current path available!");
}
- //TODO Find a good way to do clipping
+ //TODO Find a good way to do clipping. PCL itself cannot clip.
currentPath = null;
}
*/
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,
+ setCursorPos(x * 1000, y * 1000);
+ gen.fillRect((int)width * 1000, (int)height * 1000,
this.currentFillColor);
} catch (IOException ioe) {
handleIOTrouble(ioe);
this.currentFillColor = color;
}
- private void updatePrintDirection() throws IOException {
- AffineTransform at = graphicContext.getTransform();
- if (log.isDebugEnabled()) {
- log.debug(at.getScaleX() + " " + at.getScaleY() + " "
- + at.getShearX() + " " + at.getShearY() );
- }
- if (at.getScaleX() == 0 && at.getScaleY() == 0
- && at.getShearX() == 1 && at.getShearY() == -1) {
- gen.writeCommand("&a90P");
- } else if (at.getScaleX() == -1 && at.getScaleY() == -1
- && at.getShearX() == 0 && at.getShearY() == 0) {
- gen.writeCommand("&a180P");
- } else if (at.getScaleX() == 0 && at.getScaleY() == 0
- && at.getShearX() == -1 && at.getShearY() == 1) {
- gen.writeCommand("&a270P");
- } else {
- gen.writeCommand("&a0P");
- }
- }
-
- private Point2D transformedPoint(float x, float y) {
- return transformedPoint(Math.round(x), Math.round(y));
- }
-
- private Point2D transformedPoint(int x, int y) {
- AffineTransform at = graphicContext.getTransform();
- if (log.isDebugEnabled()) {
- log.debug("Current transform: " + at);
- }
- Point2D orgPoint = new Point2D.Float(x, y);
- Point2D transPoint = new Point2D.Float();
- at.transform(orgPoint, transPoint);
- return transPoint;
- }
-
/**
* @see org.apache.fop.render.AbstractRenderer#renderWord(org.apache.fop.area.inline.WordArea)
*/
*/
protected void drawBackAndBorders(Area area, float startx, float starty,
float width, float height) {
- 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) {
- updateFillColor(back.getColor());
- 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);
- }
+ BorderProps bpsBefore = (BorderProps) area.getTrait(Trait.BORDER_BEFORE);
+ BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER);
+ BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START);
+ BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END);
+
+ // draw background
+ Trait.Background back;
+ back = (Trait.Background) area.getTrait(Trait.BACKGROUND);
+ if (back != null) {
+
+ // Calculate padding rectangle
+ float sx = startx;
+ float sy = starty;
+ float paddRectWidth = width;
+ float paddRectHeight = height;
+
+ if (bpsStart != null) {
+ sx += bpsStart.width / 1000f;
+ paddRectWidth -= bpsStart.width / 1000f;
+ }
+ if (bpsBefore != null) {
+ sy += bpsBefore.width / 1000f;
+ paddRectHeight -= bpsBefore.width / 1000f;
+ }
+ if (bpsEnd != null) {
+ paddRectWidth -= bpsEnd.width / 1000f;
+ }
+ if (bpsAfter != null) {
+ paddRectHeight -= bpsAfter.width / 1000f;
+ }
+
+ if (back.getColor() != null) {
+ updateFillColor(back.getColor());
+ fillRect(sx, sy, paddRectWidth, paddRectHeight);
+ }
+
+ // background image
+ if (back.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);
}
+
+ Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height);
+ drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
}
/**