diff options
author | Adrian Cumiskey <acumiskey@apache.org> | 2008-11-04 15:30:38 +0000 |
---|---|---|
committer | Adrian Cumiskey <acumiskey@apache.org> | 2008-11-04 15:30:38 +0000 |
commit | 74355f1f4b9ce01d9ad26c4c42ad025daff1263f (patch) | |
tree | 95baf61ca18cc6218ba261bbf383b08cce693fef /src/java/org/apache/fop | |
parent | c550e0349a64c0c66d6cee0f2e6f1baa97e14ad2 (diff) | |
download | xmlgraphics-fop-74355f1f4b9ce01d9ad26c4c42ad025daff1263f.tar.gz xmlgraphics-fop-74355f1f4b9ce01d9ad26c4c42ad025daff1263f.zip |
"fixed" block container handling fixed (see block-container_absolute-position_fixed.xml).
Barcode4J generating barcodes correctly for both GOCA and conversion-mode="bitmap".
AbstractGenericSVGHandler now declares use of static final String BITMAP which is used by concrete subclasses and provides overridable methods. for buildGraphicsNode() and createPainter().
*State classes are now renamed *PaintingState.
AFPImageGraphics2DFactory - painter is not overriden but is now instead prepared for y-axis inversion.
AFPGraphics2DAdapter - commented lines removed.
Inlining now only done when the graphic is a non conversion-mode="bitmap".
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@711273 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
44 files changed, 739 insertions, 740 deletions
diff --git a/src/java/org/apache/fop/AbstractData.java b/src/java/org/apache/fop/AbstractData.java deleted file mode 100644 index b689165a0..000000000 --- a/src/java/org/apache/fop/AbstractData.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.apache.fop; - -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.io.Serializable; - -/** - * A base state data holding object - */ -public abstract class AbstractData implements Cloneable, Serializable { - - private static final long serialVersionUID = 5208418041189828624L; - - /** The current color */ - protected Color color = null; - - /** The current background color */ - protected Color backColor = null; - - /** The current font name */ - protected String fontName = null; - - /** The current font size */ - protected int fontSize = 0; - - /** The current line width */ - protected float lineWidth = 0; - - /** The dash array for the current basic stroke (line type) */ - protected float[] dashArray = null; - - /** The current transform */ - protected AffineTransform transform = null; - - /** - * Returns a newly create data object - * - * @return a new data object - */ - protected abstract AbstractData instantiate(); - - /** - * Concatenate the given AffineTransform with the current thus creating - * a new viewport. Note that all concatenation operations are logged - * so they can be replayed if necessary (ex. for block-containers with - * "fixed" positioning. - * - * @param at Transformation to perform - */ - public void concatenate(AffineTransform at) { - getTransform().concatenate(at); - } - - /** - * Get the current AffineTransform. - * - * @return the current transform - */ - public AffineTransform getTransform() { - if (transform == null) { - transform = new AffineTransform(); - } - return transform; - } - - /** - * Sets the current AffineTransform. - */ - public void setTransform(AffineTransform baseTransform) { - this.transform = baseTransform; - } - - /** - * Resets the current AffineTransform. - */ - public void clearTransform() { - transform = new AffineTransform(); - } - - /** - * Returns the derived rotation from the current transform - * - * @return the derived rotation from the current transform - */ - public int getDerivedRotation() { - AffineTransform at = getTransform(); - double sx = at.getScaleX(); - double sy = at.getScaleY(); - double shx = at.getShearX(); - double shy = at.getShearY(); - int rotation = 0; - if (sx == 0 && sy == 0 && shx > 0 && shy < 0) { - rotation = 270; - } else if (sx < 0 && sy < 0 && shx == 0 && shy == 0) { - rotation = 180; - } else if (sx == 0 && sy == 0 && shx < 0 && shy > 0) { - rotation = 90; - } else { - rotation = 0; - } - return rotation; - } - - /** {@inheritDoc} */ - public Object clone() { - AbstractData data = instantiate(); - data.color = this.color; - data.backColor = this.backColor; - data.fontName = this.fontName; - data.fontSize = this.fontSize; - data.lineWidth = this.lineWidth; - data.dashArray = this.dashArray; - data.transform = new AffineTransform(this.transform); - return data; - } - - /** {@inheritDoc} */ - public String toString() { - return "color=" + color - + ", backColor=" + backColor - + ", fontName=" + fontName - + ", fontSize=" + fontSize - + ", lineWidth=" + lineWidth - + ", dashArray=" + dashArray - + ", transform=" + transform; - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/StateStack.java b/src/java/org/apache/fop/StateStack.java deleted file mode 100644 index 0c73b4829..000000000 --- a/src/java/org/apache/fop/StateStack.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.fop; - -import java.util.Collection; - -/** - * No copy constructor for java.util.Stack so extended and implemented one. - */ -class StateStack extends java.util.Stack { - - private static final long serialVersionUID = 4897178211223823041L; - - /** - * Default constructor - */ - public StateStack() { - super(); - } - - /** - * Copy constructor - * - * @param c initial contents of stack - */ - public StateStack(Collection c) { - elementCount = c.size(); - // 10% for growth - elementData = new Object[ - (int)Math.min((elementCount * 110L) / 100, Integer.MAX_VALUE)]; - c.toArray(elementData); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/afp/AFPAbstractGraphicsObjectPainter.java b/src/java/org/apache/fop/afp/AFPAbstractGraphicsObjectPainter.java deleted file mode 100644 index 8c5e84012..000000000 --- a/src/java/org/apache/fop/afp/AFPAbstractGraphicsObjectPainter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.afp; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.afp.modca.GraphicsObject; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - -/** - * A simple AFP Graphics 2D painter - */ -public abstract class AFPAbstractGraphicsObjectPainter implements Graphics2DImagePainter { - /** Static logging instance */ - protected static Log log = LogFactory.getLog(AFPAbstractGraphicsObjectPainter.class); - - private final AFPGraphics2D graphics2D; - - /** - * Default constructor - */ - public AFPAbstractGraphicsObjectPainter() { - final boolean textAsShapes = false; - this.graphics2D = new AFPGraphics2D(textAsShapes); - } - - /** - * Constructor - * - * @param graphics the afp graphics 2d implementation - */ - public AFPAbstractGraphicsObjectPainter(AFPGraphics2D graphics) { - this.graphics2D = graphics; - } - - /** - * Sets the GOCA Graphics Object - * - * @param graphicsObject the GOCA Graphics Object - */ - public void setGraphicsObject(GraphicsObject graphicsObject) { - this.graphics2D.setGraphicsObject(graphicsObject); - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/afp/AFPBorderPainter.java b/src/java/org/apache/fop/afp/AFPBorderPainter.java index 96f9ae78f..86960b7ff 100644 --- a/src/java/org/apache/fop/afp/AFPBorderPainter.java +++ b/src/java/org/apache/fop/afp/AFPBorderPainter.java @@ -33,10 +33,10 @@ public class AFPBorderPainter extends AbstractAFPPainter { /** * Main constructor * - * @param state the unit converter - * @param dataStream the afp datastream + * @param state the AFP painting state converter + * @param dataStream the AFP datastream */ - public AFPBorderPainter(AFPState state, DataStream dataStream) { + public AFPBorderPainter(AFPPaintingState state, DataStream dataStream) { super(state, dataStream); } diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java index 21114bb88..d412e2b94 100644 --- a/src/java/org/apache/fop/afp/AFPGraphics2D.java +++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java @@ -98,7 +98,7 @@ public class AFPGraphics2D extends AbstractGraphics2D { private AFPResourceInfo resourceInfo = null; /** Current AFP state */ - private AFPState state = null; + private AFPPaintingState state = null; /** The AFP FontInfo */ private FontInfo fontInfo; @@ -498,15 +498,15 @@ public class AFPGraphics2D extends AbstractGraphics2D { g2d.fillRect(0, 0, width, height); - int bufferedWidth = bufferedImage.getWidth(); - int bufferedHeight = bufferedImage.getHeight(); - Rectangle clipRect = new Rectangle(0, 0, bufferedWidth, bufferedHeight); + int imageWidth = bufferedImage.getWidth(); + int imageHeight = bufferedImage.getHeight(); + Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight); g2d.clip(clipRect); g2d.setComposite(gc.getComposite()); - boolean drawn = g2d.drawImage(img, 0, 0, bufferedWidth, bufferedHeight, observer); - g2d.dispose(); + boolean drawn = g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer); + g2d.dispose(); //drawn so dispose immediately to free system resource if (drawn) { try { @@ -575,11 +575,11 @@ public class AFPGraphics2D extends AbstractGraphics2D { } /** - * Sets the AFP state + * Sets the AFP painting state * - * @param state the AFP state + * @param state the AFP painting state */ - public void setState(AFPState state) { + public void setPaintingState(AFPPaintingState state) { this.state = state; } @@ -588,7 +588,7 @@ public class AFPGraphics2D extends AbstractGraphics2D { * * @return the AFP state */ - public AFPState getState() { + public AFPPaintingState getPaintingState() { return this.state; } diff --git a/src/java/org/apache/fop/afp/AFPState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java index 7e63ea01e..60e4812b9 100644 --- a/src/java/org/apache/fop/afp/AFPState.java +++ b/src/java/org/apache/fop/afp/AFPPaintingState.java @@ -21,13 +21,12 @@ package org.apache.fop.afp; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.AbstractData; -import org.apache.fop.AbstractState; +import org.apache.fop.util.AbstractPaintingState; /** - * This keeps information about the current state when writing to an AFP datastream. + * This keeps information about the current painting state when writing to an AFP datastream. */ -public class AFPState extends org.apache.fop.AbstractState implements Cloneable { +public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState implements Cloneable { private static final long serialVersionUID = 8206711712452344473L; @@ -52,7 +51,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable private int resolution = 240; // 240 dpi /** the current page */ - private AFPPageState pageState = new AFPPageState(); + private AFPPagePaintingState pagePaintingState = new AFPPagePaintingState(); // /** reference orientation */ // private int orientation = 0; @@ -209,17 +208,17 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable } /** {@inheritDoc} */ - protected AbstractState instantiateState() { - return new AFPState(); + protected AbstractPaintingState instantiate() { + return new AFPPaintingState(); } /** - * Returns the state of the current page + * Returns the painting state of the current page * - * @return the state of the current page + * @return the painting state of the current page */ - protected AFPPageState getPageState() { - return this.pageState; + protected AFPPagePaintingState getPagePaintingState() { + return this.pagePaintingState; } /** @@ -242,7 +241,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @return the current page fonts */ public AFPPageFonts getPageFonts() { - return pageState.getFonts(); + return pagePaintingState.getFonts(); } /** @@ -251,7 +250,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @return the page font count */ public int incrementPageFontCount() { - return pageState.incrementFontCount(); + return pagePaintingState.incrementFontCount(); } /** @@ -260,7 +259,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @param pageWidth the page width */ public void setPageWidth(int pageWidth) { - pageState.setWidth(pageWidth); + pagePaintingState.setWidth(pageWidth); } /** @@ -269,7 +268,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @return the page width */ public int getPageWidth() { - return pageState.getWidth(); + return pagePaintingState.getWidth(); } /** @@ -278,7 +277,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @param pageHeight the page height */ public void setPageHeight(int pageHeight) { - pageState.setHeight(pageHeight); + pagePaintingState.setHeight(pageHeight); } /** @@ -287,7 +286,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @return the page height */ public int getPageHeight() { - return pageState.getHeight(); + return pagePaintingState.getHeight(); } /** @@ -296,7 +295,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable * @return the page rotation */ public int getPageRotation() { - return pageState.getOrientation(); + return pagePaintingState.getOrientation(); } /** @@ -337,8 +336,8 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** {@inheritDoc} */ public Object clone() { - AFPState state = (AFPState)super.clone(); - state.pageState = (AFPPageState)this.pageState.clone(); + AFPPaintingState state = (AFPPaintingState)super.clone(); + state.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone(); state.portraitRotation = this.portraitRotation; state.landscapeRotation = this.landscapeRotation; state.bitsPerPixel = this.bitsPerPixel; @@ -349,12 +348,12 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** {@inheritDoc} */ public String toString() { - return "AFPState{" + "portraitRotation=" + portraitRotation + return "AFPPaintingState{" + "portraitRotation=" + portraitRotation + ", landscapeRotation=" + landscapeRotation + ", colorImages=" + colorImages + ", bitsPerPixel=" + bitsPerPixel + ", resolution=" + resolution - + ", pageState=" + pageState + + ", pageState=" + pagePaintingState + super.toString() + "}"; } @@ -362,7 +361,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** * Page level state data */ - private class AFPPageState implements Cloneable { + private class AFPPagePaintingState implements Cloneable { /** page width */ private int width = 0; @@ -461,7 +460,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** {@inheritDoc} */ public Object clone() { - AFPPageState state = new AFPPageState(); + AFPPagePaintingState state = new AFPPagePaintingState(); state.width = this.width; state.height = this.height; state.orientation = this.orientation; @@ -472,7 +471,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** {@inheritDoc} */ public String toString() { - return "AFPPageState{width=" + width + return "AFPPagePaintingState{width=" + width + ", height=" + height + ", orientation=" + orientation + ", fonts=" + fonts @@ -484,7 +483,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable /** * Block level state data */ - private class AFPData extends org.apache.fop.AbstractData { + private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData { private static final long serialVersionUID = -1789481244175275686L; /** The current fill status */ diff --git a/src/java/org/apache/fop/afp/AFPRectanglePainter.java b/src/java/org/apache/fop/afp/AFPRectanglePainter.java index 56c60b440..81915a190 100644 --- a/src/java/org/apache/fop/afp/AFPRectanglePainter.java +++ b/src/java/org/apache/fop/afp/AFPRectanglePainter.java @@ -28,10 +28,10 @@ public class AFPRectanglePainter extends AbstractAFPPainter { /** * Main constructor * - * @param state the afp state + * @param state the AFP painting state * @param dataStream the afp datastream */ - public AFPRectanglePainter(AFPState state, DataStream dataStream) { + public AFPRectanglePainter(AFPPaintingState state, DataStream dataStream) { super(state, dataStream); } diff --git a/src/java/org/apache/fop/afp/AFPResourceLevel.java b/src/java/org/apache/fop/afp/AFPResourceLevel.java index 85cdefb4b..5e8d54aae 100644 --- a/src/java/org/apache/fop/afp/AFPResourceLevel.java +++ b/src/java/org/apache/fop/afp/AFPResourceLevel.java @@ -55,7 +55,7 @@ public class AFPResourceLevel { /** where the resource will reside in the AFP output */ - private int level = PRINT_FILE; // default is print-file level + private int level = PRINT_FILE; // default is print-file level (images) /** the external resource group file path */ private String extFilePath = null; diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java index 111238be8..c912b8b17 100644 --- a/src/java/org/apache/fop/afp/AFPResourceManager.java +++ b/src/java/org/apache/fop/afp/AFPResourceManager.java @@ -68,10 +68,10 @@ public class AFPResourceManager { /** * Sets the outputstream * - * @param state the afp state + * @param state the AFP painting state * @param outputStream the outputstream */ - public void createDataStream(AFPState state, OutputStream outputStream) { + public void createDataStream(AFPPaintingState state, OutputStream outputStream) { this.dataStream = streamer.createDataStream(state); streamer.setOutputStream(outputStream); } diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java index 42dcf4412..1d9367ef6 100644 --- a/src/java/org/apache/fop/afp/AFPStreamer.java +++ b/src/java/org/apache/fop/afp/AFPStreamer.java @@ -83,11 +83,11 @@ public class AFPStreamer implements Streamable { /** * Creates a new DataStream - * @param state the afp state * + * @param state the AFP painting state * @return a new {@link DataStream} */ - public DataStream createDataStream(AFPState state) { + public DataStream createDataStream(AFPPaintingState state) { try { this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null); this.documentFile = new RandomAccessFile(tempFile, "rw"); diff --git a/src/java/org/apache/fop/afp/AFPTextHandler.java b/src/java/org/apache/fop/afp/AFPTextHandler.java index 3dee6ca2e..3f5ff7b33 100644 --- a/src/java/org/apache/fop/afp/AFPTextHandler.java +++ b/src/java/org/apache/fop/afp/AFPTextHandler.java @@ -71,7 +71,7 @@ public class AFPTextHandler implements TextHandler { GraphicsObject graphicsObj = g2d.getGraphicsObject(); Color col = g2d.getColor(); - AFPState state = g2d.getState(); + AFPPaintingState state = g2d.getPaintingState(); if (state.setColor(col)) { graphicsObj.setColor(col); } diff --git a/src/java/org/apache/fop/afp/AFPUnitConverter.java b/src/java/org/apache/fop/afp/AFPUnitConverter.java index 69282fc18..c5f37d25f 100644 --- a/src/java/org/apache/fop/afp/AFPUnitConverter.java +++ b/src/java/org/apache/fop/afp/AFPUnitConverter.java @@ -29,14 +29,14 @@ import java.awt.geom.AffineTransform; public class AFPUnitConverter { /** the AFP state */ - private final AFPState state; + private final AFPPaintingState state; /** * Unit converter * - * @param state the AFP state + * @param state the AFP painting state */ - public AFPUnitConverter(AFPState state) { + public AFPUnitConverter(AFPPaintingState state) { this.state = state; } diff --git a/src/java/org/apache/fop/afp/AbstractAFPPainter.java b/src/java/org/apache/fop/afp/AbstractAFPPainter.java index ba6d49fc6..72c6c56e1 100644 --- a/src/java/org/apache/fop/afp/AbstractAFPPainter.java +++ b/src/java/org/apache/fop/afp/AbstractAFPPainter.java @@ -29,7 +29,7 @@ public abstract class AbstractAFPPainter { protected static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp"); protected final DataStream dataStream; - protected final AFPState state; + protected final AFPPaintingState state; /** * Main constructor @@ -37,7 +37,7 @@ public abstract class AbstractAFPPainter { * @param state the afp state * @param dataStream the afp datastream */ - public AbstractAFPPainter(AFPState state, DataStream dataStream) { + public AbstractAFPPainter(AFPPaintingState state, DataStream dataStream) { this.state = state; this.dataStream = dataStream; } diff --git a/src/java/org/apache/fop/afp/Factory.java b/src/java/org/apache/fop/afp/Factory.java index 840d7b4e8..ef7426330 100644 --- a/src/java/org/apache/fop/afp/Factory.java +++ b/src/java/org/apache/fop/afp/Factory.java @@ -392,11 +392,11 @@ public class Factory { /** * Creates a new {@link DataStream} * - * @param state the afp state + * @param state the AFP painting state * @param outputStream an outputstream to write to * @return a new {@link DataStream} */ - public DataStream createDataStream(AFPState state, OutputStream outputStream) { + public DataStream createDataStream(AFPPaintingState state, OutputStream outputStream) { DataStream dataStream = new DataStream(this, state, outputStream); return dataStream; } diff --git a/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java b/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java new file mode 100644 index 000000000..1a2883e72 --- /dev/null +++ b/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java @@ -0,0 +1,71 @@ +/* + * 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.afp; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.gvt.GraphicsNode; +import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl; +import org.apache.xmlgraphics.java2d.Graphics2DPainterPreparator; + +/** + * Graphics2DImagePainter implementation for GOCA + */ +public class Graphics2DImagePainterGOCA extends Graphics2DImagePainterImpl { + + /** + * Main Constructor + * + * @param root the graphics node root + * @param ctx the bridge context + * @param imageSize the image size + */ + public Graphics2DImagePainterGOCA(GraphicsNode root, BridgeContext ctx, Dimension imageSize) { + super(root, ctx, imageSize); + } + + /** {@inheritDoc} */ + protected Graphics2DPainterPreparator getPreparator() { + return new Graphics2DPainterPreparator() { + + /** {@inheritdoc} */ + public void prepare(Graphics2D g2d, Rectangle2D area) { + double tx = area.getX(); + double ty = area.getHeight() - area.getY(); + if (tx != 0 || ty != 0) { + g2d.translate(tx, ty); + } + + float iw = (float) ctx.getDocumentSize().getWidth(); + float ih = (float) ctx.getDocumentSize().getHeight(); + float w = (float) area.getWidth(); + float h = (float) area.getHeight(); + float sx = w / iw; + float sy = -(h / ih); + if (sx != 1.0 || sy != 1.0) { + g2d.scale(sx, sy); + } + } + }; + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/afp/ioca/ImageContent.java b/src/java/org/apache/fop/afp/ioca/ImageContent.java index 27147d511..fc8ce0944 100644 --- a/src/java/org/apache/fop/afp/ioca/ImageContent.java +++ b/src/java/org/apache/fop/afp/ioca/ImageContent.java @@ -25,6 +25,7 @@ import java.io.OutputStream; import org.apache.fop.afp.modca.AbstractStructuredAFPObject; /** + * An IOCA Image Content */ public class ImageContent extends AbstractStructuredAFPObject { diff --git a/src/java/org/apache/fop/afp/modca/DataStream.java b/src/java/org/apache/fop/afp/modca/DataStream.java index c1c5e12a7..00d2b6f16 100644 --- a/src/java/org/apache/fop/afp/modca/DataStream.java +++ b/src/java/org/apache/fop/afp/modca/DataStream.java @@ -29,8 +29,8 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.afp.AFPLineDataInfo; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceLevel; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPTextDataInfo; import org.apache.fop.afp.Factory; import org.apache.fop.afp.fonts.AFPFont; @@ -83,17 +83,17 @@ public class DataStream { private OutputStream outputStream; - /** the afp state */ - private final AFPState state; + /** the afp painting state */ + private final AFPPaintingState state; /** * Default constructor for the AFPDocumentStream. * * @param factory the resource factory - * @param state the afp state + * @param state the AFP painting state * @param outputStream the outputstream to write to */ - public DataStream(Factory factory, AFPState state, OutputStream outputStream) { + public DataStream(Factory factory, AFPPaintingState state, OutputStream outputStream) { this.state = state; this.factory = factory; this.outputStream = outputStream; diff --git a/src/java/org/apache/fop/image/loader/batik/BatikGraphics2DImagePainter.java b/src/java/org/apache/fop/image/loader/batik/BatikGraphics2DImagePainter.java deleted file mode 100644 index 983033027..000000000 --- a/src/java/org/apache/fop/image/loader/batik/BatikGraphics2DImagePainter.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.apache.fop.image.loader.batik; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; - -import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.gvt.GraphicsNode; -import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - -/** - * A generic graphics 2D image painter implementation - */ -public class BatikGraphics2DImagePainter implements Graphics2DImagePainter { - - protected final ImageXMLDOM svg; - protected final BridgeContext ctx; - protected final GraphicsNode root; - - /** - * Constructor - * - * @param svg the svg image dom - * @param ctx the bridge context - * @param root the graphics node root - */ - public BatikGraphics2DImagePainter(ImageXMLDOM svg, BridgeContext ctx, GraphicsNode root) { - this.svg = svg; - this.ctx = ctx; - this.root = root; - } - - /** - * Initialises the graphics 2d - * - * @param g2d the graphics 2d - * @param area the rectangle drawing area - */ - protected void init(Graphics2D g2d, Rectangle2D area) { - // If no viewbox is defined in the svg file, a viewbox of 100x100 is - // assumed, as defined in SVGUserAgent.getViewportSize() - double tx = area.getX(); - double ty = area.getY(); - if (tx != 0 || ty != 0) { - g2d.translate(tx, ty); - } - - float iw = (float) ctx.getDocumentSize().getWidth(); - float ih = (float) ctx.getDocumentSize().getHeight(); - float w = (float) area.getWidth(); - float h = (float) area.getHeight(); - float sx = w / iw; - float sy = h / ih; - if (sx != 1.0 || sy != 1.0) { - g2d.scale(sx, sy); - } - } - - /** {@inheritDoc} */ - public void paint(Graphics2D g2d, Rectangle2D area) { - init(g2d, area); - root.paint(g2d); - } - - /** {@inheritDoc} */ - public Dimension getImageSize() { - return new Dimension(svg.getSize().getWidthMpt(), svg.getSize().getHeightMpt()); - } - - /** - * Returns the svg image dom - * @return the svg image dom - */ - public ImageXMLDOM getImageXMLDOM() { - return svg; - } - - /** - * Returns the bridge context - * @return the bridge context - */ - public BridgeContext getBridgeContext() { - return ctx; - } - - /** - * Returns the graphics root node - * @return the graphics root node - */ - public GraphicsNode getRoot() { - return root; - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java b/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java new file mode 100644 index 000000000..87907eddf --- /dev/null +++ b/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java @@ -0,0 +1,64 @@ +package org.apache.fop.image.loader.batik; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.gvt.GraphicsNode; +import org.apache.fop.render.AbstractGraphics2DImagePainter; +import org.apache.xmlgraphics.java2d.Graphics2DPainterPreparator; + +/** + * A generic graphics 2D image painter implementation + */ +public class Graphics2DImagePainterImpl extends AbstractGraphics2DImagePainter { + + protected final BridgeContext ctx; + protected final Dimension imageSize; + + /** + * Main constructor + * + * @param root the graphics node root + * @param ctx the bridge context + * @param imageSize the image size + */ + public Graphics2DImagePainterImpl(GraphicsNode root, BridgeContext ctx, Dimension imageSize) { + super(root); + this.imageSize = imageSize; + this.ctx = ctx; + } + + /** {@inheritDoc} */ + public Dimension getImageSize() { + return imageSize; + } + + /** {@inheritDoc} */ + protected Graphics2DPainterPreparator getPreparator() { + return new Graphics2DPainterPreparator() { + + public void prepare(Graphics2D g2d, Rectangle2D area) { + // If no viewbox is defined in the svg file, a viewbox of 100x100 is + // assumed, as defined in SVGUserAgent.getViewportSize() + double tx = area.getX(); + double ty = area.getY(); + if (tx != 0 || ty != 0) { + g2d.translate(tx, ty); + } + + float iw = (float) ctx.getDocumentSize().getWidth(); + float ih = (float) ctx.getDocumentSize().getHeight(); + float w = (float) area.getWidth(); + float h = (float) area.getHeight(); + float sx = w / iw; + float sy = h / ih; + if (sx != 1.0 || sy != 1.0) { + g2d.scale(sx, sy); + } + } + }; + } + +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java index 40dc600be..81c12a628 100644 --- a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java +++ b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java @@ -19,6 +19,7 @@ package org.apache.fop.image.loader.batik; +import java.awt.Dimension; import java.awt.geom.AffineTransform; import java.util.Map; @@ -33,6 +34,7 @@ import org.apache.fop.svg.SimpleSVGUserAgent; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; import org.apache.xmlgraphics.image.loader.impl.AbstractImageConverter; @@ -82,8 +84,14 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter { } //Create the painter - Graphics2DImagePainter painter = createPainter(svg, ctx, root); - ImageGraphics2D g2dImage = new ImageGraphics2D(src.getInfo(), painter); + int width = svg.getSize().getWidthMpt(); + int height = svg.getSize().getHeightMpt(); + Dimension imageSize = new Dimension(width, height); + Graphics2DImagePainter painter = createPainter(ctx, root, imageSize); + + //Create g2d image + ImageInfo imageInfo = src.getInfo(); + ImageGraphics2D g2dImage = new ImageGraphics2D(imageInfo, painter); return g2dImage; } @@ -109,14 +117,14 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter { /** * Creates a Graphics 2D image painter * - * @param svg the svg image dom * @param ctx the bridge context * @param root the graphics node root + * @param imageSize the image size * @return the newly created graphics 2d image painter */ protected Graphics2DImagePainter createPainter( - final ImageXMLDOM svg, final BridgeContext ctx, final GraphicsNode root) { - return new BatikGraphics2DImagePainter(svg, ctx, root); + BridgeContext ctx, GraphicsNode root, Dimension imageSize) { + return new Graphics2DImagePainterImpl(root, ctx, imageSize); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFPaintingState.java index 3804c189a..7dd876c25 100644 --- a/src/java/org/apache/fop/pdf/PDFState.java +++ b/src/java/org/apache/fop/pdf/PDFPaintingState.java @@ -25,11 +25,10 @@ import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.util.Iterator; -import org.apache.fop.AbstractData; -import org.apache.fop.AbstractState; +import org.apache.fop.util.AbstractPaintingState; /** - * This keeps information about the current state when writing to pdf. + * This keeps information about the current painting state when writing to pdf. * It allows for creating new graphics states with the q operator. * This class is only used to store the information about the state * the caller needs to handle the actual pdf operators. @@ -45,14 +44,14 @@ import org.apache.fop.AbstractState; * It is impossible to optimise the result without analysing the all * the possible combinations after completing. */ -public class PDFState extends org.apache.fop.AbstractState { +public class PDFPaintingState extends org.apache.fop.util.AbstractPaintingState { private static final long serialVersionUID = 5384726143906371279L; /** * PDF State for storing graphics state. */ - public PDFState() { + public PDFPaintingState() { } /** @@ -162,8 +161,8 @@ public class PDFState extends org.apache.fop.AbstractState { } /** {@inheritDoc} */ - protected AbstractState instantiateState() { - return new PDFState(); + protected AbstractPaintingState instantiate() { + return new PDFPaintingState(); } /** @@ -178,7 +177,7 @@ public class PDFState extends org.apache.fop.AbstractState { getStateStack().add(copy); } - private class PDFData extends org.apache.fop.AbstractData { + private class PDFData extends org.apache.fop.util.AbstractPaintingState.AbstractData { private static final long serialVersionUID = 3527950647293177764L; diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java index 0d6bf9be9..18cc81400 100644 --- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -21,9 +21,7 @@ package org.apache.fop.render; // Java import java.awt.Dimension; -import java.awt.Graphics2D; import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; import java.io.IOException; import org.apache.batik.bridge.BridgeContext; @@ -31,7 +29,9 @@ import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.dom.AbstractDocument; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl; import org.apache.fop.render.RendererContext.RendererContextWrapper; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; @@ -51,6 +51,9 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC protected static final QName CONVERSION_MODE = new QName( ExtensionElementMapping.URI, null, "conversion-mode"); + /** "bitmap" value for the "conversion-mode" extension attribute. */ + protected static final String BITMAP = "bitmap"; + /** {@inheritDoc} */ public void handleXML(RendererContext context, Document doc, String ns) throws Exception { @@ -61,65 +64,80 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC } /** - * Render the SVG document. + * Creates a graphics 2D image painter implementation * - * @param context the renderer context - * @param doc the SVG document - * @throws IOException In case of an I/O error while painting the image + * @param root the batik graphics node root + * @param ctx the batik bridge context + * @param imageSize the image size + * @return a new graphics 2D image painter implementation */ - protected void renderSVGDocument(final RendererContext context, - final Document doc) throws IOException { - updateRendererContext(context); + protected Graphics2DImagePainter createPainter( + GraphicsNode root, BridgeContext ctx, Dimension imageSize) { + return new Graphics2DImagePainterImpl(root, ctx, imageSize); + } - //Prepare - SVGUserAgent ua = new SVGUserAgent( - context.getUserAgent(), - new AffineTransform()); + /** + * Builds the GVT root + * + * @param rendererContext the renderer context + * @param ctx the batik bridge context + * @param doc the document + * @return a built GVT root tree + */ + protected GraphicsNode buildGraphicsNode( + RendererContext rendererContext, BridgeContext ctx, Document doc) { GVTBuilder builder = new GVTBuilder(); - final BridgeContext ctx = new BridgeContext(ua); - - //Build the GVT tree final GraphicsNode root; try { root = builder.build(ctx, doc); } catch (Exception e) { - SVGEventProducer eventProducer = SVGEventProducer.Provider.get( - context.getUserAgent().getEventBroadcaster()); + EventBroadcaster eventBroadcaster + = rendererContext.getUserAgent().getEventBroadcaster(); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get(eventBroadcaster); final String uri = getDocumentURI(doc); eventProducer.svgNotBuilt(this, e, uri); - return; + return null; } + return root; + } - final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(context); + /** + * Render the SVG document. + * + * @param rendererContext the renderer context + * @param doc the SVG document + * @throws IOException In case of an I/O error while painting the image + */ + protected void renderSVGDocument(final RendererContext rendererContext, + final Document doc) throws IOException { + updateRendererContext(rendererContext); - //Create the painter - Graphics2DImagePainter painter = new Graphics2DImagePainter() { + //Prepare + SVGUserAgent svgUserAgent = new SVGUserAgent( + rendererContext.getUserAgent(), new AffineTransform()); + final BridgeContext bridgeContext = new BridgeContext(svgUserAgent); - public void paint(Graphics2D g2d, Rectangle2D area) { - // 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); + //Build the GVT tree + final GraphicsNode root = buildGraphicsNode(rendererContext, bridgeContext, doc); - root.paint(g2d); - } + final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext( + rendererContext); - public Dimension getImageSize() { - return new Dimension(wrappedContext.getWidth(), wrappedContext.getHeight()); - } + //Get Image Size + final int width = wrappedContext.getWidth(); + final int height = wrappedContext.getHeight(); + Dimension imageSize = new Dimension(width, height); - }; + //Create the painter + final Graphics2DImagePainter painter = createPainter(root, bridgeContext, imageSize); //Let the painter paint the SVG on the Graphics2D instance - Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter(); - adapter.paintImage(painter, context, - wrappedContext.getCurrentXPosition(), - wrappedContext.getCurrentYPosition(), - wrappedContext.getWidth(), - wrappedContext.getHeight()); + Graphics2DAdapter g2dAdapter = rendererContext.getRenderer().getGraphics2DAdapter(); + + //Paint the image + final int x = wrappedContext.getCurrentXPosition(); + final int y = wrappedContext.getCurrentYPosition(); + g2dAdapter.paintImage(painter, rendererContext, x, y, width, height); } /** diff --git a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java index e37d02b2b..5861fb042 100644 --- a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java @@ -135,6 +135,7 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } + /** {@inheritDoc} */ public void paintImage(Graphics2DImagePainter painter, RendererContext context, diff --git a/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java b/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java index 0c32204e2..3b00804fc 100644 --- a/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java @@ -24,8 +24,8 @@ import java.io.IOException; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPForeignAttributeReader; import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPUnitConverter; @@ -37,7 +37,7 @@ public abstract class AFPAbstractImageFactory { private static final int Y = 1; /** the AFP state */ - protected final AFPState state; + protected final AFPPaintingState state; /** foreign attribute reader */ private final AFPForeignAttributeReader foreignAttributeReader @@ -46,9 +46,9 @@ public abstract class AFPAbstractImageFactory { /** * Main constructor * - * @param state the AFP state + * @param state the AFP painting state */ - public AFPAbstractImageFactory(AFPState state) { + public AFPAbstractImageFactory(AFPPaintingState state) { this.state = state; } diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java b/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java index dcf074262..ba2392835 100644 --- a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java @@ -26,8 +26,8 @@ import java.io.IOException; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPForeignAttributeReader; import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPUnitConverter; @@ -38,8 +38,8 @@ public abstract class AFPDataObjectInfoFactory { private static final int X = 0; private static final int Y = 1; - /** the AFP state */ - protected final AFPState state; + /** the AFP painting state */ + protected final AFPPaintingState state; /** foreign attribute reader */ private final AFPForeignAttributeReader foreignAttributeReader @@ -50,7 +50,7 @@ public abstract class AFPDataObjectInfoFactory { * * @param state the AFP state */ - public AFPDataObjectInfoFactory(AFPState state) { + public AFPDataObjectInfoFactory(AFPPaintingState state) { this.state = state; } diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java b/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java index 4211fe360..aac17b701 100644 --- a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java +++ b/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java @@ -22,7 +22,7 @@ package org.apache.fop.render.afp; import java.util.Iterator; import java.util.Map; -import org.apache.fop.afp.AFPState; +import org.apache.fop.afp.AFPPaintingState; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; @@ -33,16 +33,18 @@ import org.apache.xmlgraphics.image.loader.impl.ImageRendered; * AFP data object info factory provider */ public class AFPDataObjectInfoProvider { + private final Map/*<AbstractImage,AFPDataObjectInfoFactory>*/ factoryMap = new java.util.HashMap/*<AbstractImage,AFPDataObjectInfoFactory>*/(); - private final AFPState state; + + private final AFPPaintingState state; /** * Main constructor * - * @param state the AFP state + * @param state the AFP painting state */ - public AFPDataObjectInfoProvider(AFPState state) { + public AFPDataObjectInfoProvider(AFPPaintingState state) { this.state = state; init(); } diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java index 453e16429..4f92826cf 100644 --- a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java @@ -27,8 +27,9 @@ import java.io.IOException; import org.apache.fop.afp.AFPGraphics2D; import org.apache.fop.afp.AFPGraphicsObjectInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; import org.apache.fop.afp.AFPResourceManager; -import org.apache.fop.afp.AFPState; import org.apache.fop.render.AbstractGraphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContext.RendererContextWrapper; @@ -69,28 +70,32 @@ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { RendererContext context, int x, int y, int width, int height) throws IOException { - // get the 'width' and 'height' attributes of the SVG document - Dimension dim = painter.getImageSize(); + AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context); + // set resource manager + AFPResourceManager resourceManager = afpInfo.getResourceManager(); + g2d.setResourceManager(resourceManager); - AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context); - g2d.setResourceManager(afpInfo.getResourceManager()); - g2d.setResourceInfo(afpInfo.getResourceInfo()); - g2d.setState(afpInfo.getState()); - g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + // set resource information + AFPResourceInfo resourceInfo = afpInfo.getResourceInfo(); + g2d.setResourceInfo(resourceInfo); + + // set painting state + AFPPaintingState paintingState = afpInfo.getPaintingState(); + g2d.setPaintingState(paintingState); -// // scale/convert to afp units -// AFPUnitConverter unitConv = state.getUnitConverter(); -// float scale = unitConv.mpt2units(1); + // set graphic context + g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); float fwidth = width / 1000f; float fheight = height / 1000f; - float imw = (float)dim.getWidth() / 1000f; - float imh = (float)dim.getHeight() / 1000f; + + // get the 'width' and 'height' attributes of the SVG document + Dimension imageSize = painter.getImageSize(); + float imw = (float)imageSize.getWidth() / 1000f; + float imh = (float)imageSize.getHeight() / 1000f; float sx = fwidth / imw; float sy = fheight / imh; -// float fx = x / 1000f; -// float fy = y / 1000f; AffineTransform at = new AffineTransform(sx, 0, 0, sy, x, y); renderer.saveGraphicsState(); @@ -99,26 +104,21 @@ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { //Fallback solution: Paint to a BufferedImage int resolution = Math.round(context.getUserAgent().getTargetResolution()); RendererContextWrapper ctx = RendererContext.wrapRendererContext(context); - BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false); + BufferedImage bufferedImage = paintToBufferedImage(painter, ctx, resolution, false, false); - AFPState state = afpInfo.getState(); + AFPPaintingState state = afpInfo.getPaintingState(); AffineTransform trans = state.getData().getTransform(); float scale = AFPRenderer.NORMAL_AFP_RESOLUTION / context.getUserAgent().getTargetResolution(); if (scale != 1) { at.scale(scale, scale); - if (!at.isIdentity()) { - trans.concatenate(at); - } } + if (!at.isIdentity()) { + trans.concatenate(at); + } - // concatenate to transformation matrix -// state.concatenate(at); - - // draw image using current transformation matrix -// at = state.getData().getTransform(); - g2d.drawImage(bi, trans, null); + g2d.drawImage(bufferedImage, trans, null); } else { AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo(); graphicsObjectInfo.setPainter(painter); @@ -126,8 +126,6 @@ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); graphicsObjectInfo.setArea(area); - AFPResourceManager resourceManager = (AFPResourceManager)context.getProperty( - AFPRendererContextConstants.AFP_RESOURCE_MANAGER); resourceManager.createObject(graphicsObjectInfo); } diff --git a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java b/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java index da9a37b76..88c0b5c26 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java @@ -19,10 +19,8 @@ package org.apache.fop.render.afp; -import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; import java.io.IOException; import org.apache.batik.bridge.BridgeContext; @@ -30,16 +28,16 @@ import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPGraphics2D; import org.apache.fop.afp.AFPGraphicsObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; import org.apache.fop.afp.AFPResourceLevel; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPTextElementBridge; import org.apache.fop.afp.AFPTextHandler; import org.apache.fop.afp.AFPTextPainter; -import org.apache.fop.image.loader.batik.BatikGraphics2DImagePainter; import org.apache.fop.render.RendererContext; import org.apache.fop.svg.SVGUserAgent; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.xmlgraphics.util.MimeConstants; @@ -51,9 +49,9 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { /** * Main constructor * - * @param state the afp state + * @param state the AFP painting state */ - public AFPImageGraphics2DFactory(AFPState state) { + public AFPImageGraphics2DFactory(AFPPaintingState state) { super(state); } @@ -62,8 +60,6 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { return new AFPGraphicsObjectInfo(); } - private static final AFPResourceLevel inlineResourceLevel = new AFPResourceLevel(AFPResourceLevel.INLINE); - /** {@inheritDoc} */ public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException { AFPGraphicsObjectInfo graphicsObjectInfo @@ -73,7 +69,7 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { // level not explicitly set/changed so default to inline for GOCA graphic objects // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) - hard copy works just fine) if (!resourceInfo.levelChanged()) { - resourceInfo.setLevel(inlineResourceLevel); + resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); } // set mime type (unsupported by MOD:CA registry) @@ -89,7 +85,7 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(rendererContext); g2d.setResourceManager(afpInfo.getResourceManager()); g2d.setResourceInfo(afpInfo.getResourceInfo()); - g2d.setState(afpInfo.getState()); + g2d.setPaintingState(afpInfo.getPaintingState()); g2d.setFontInfo(afpInfo.getFontInfo()); // set to default graphic context @@ -100,7 +96,7 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { g2d.translate(at.getTranslateX(), at.getTranslateY()); // set afp state - g2d.setState(state); + g2d.setPaintingState(state); // controls whether text painted by Batik is generated using text or path operations SVGUserAgent svgUserAgent @@ -117,49 +113,23 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory { // set painter ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage(); - BatikGraphics2DImagePainter painter - = (BatikGraphics2DImagePainter)imageG2D.getGraphics2DImagePainter(); - painter = new AFPGraphics2DImagePainter(painter); - imageG2D.setGraphics2DImagePainter(painter); + Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter(); graphicsObjectInfo.setPainter(painter); // set object area AFPObjectAreaInfo objectAreaInfo = graphicsObjectInfo.getObjectAreaInfo(); - Rectangle area = new Rectangle(objectAreaInfo.getWidth(), objectAreaInfo.getHeight()); + int width = objectAreaInfo.getWidth(); + int height = objectAreaInfo.getHeight(); + Rectangle area = new Rectangle(width, height); graphicsObjectInfo.setArea(area); - return graphicsObjectInfo; - } - - private class AFPGraphics2DImagePainter extends BatikGraphics2DImagePainter { - /** - * Copy constructor - * - * @param painter a graphics 2D image painter - */ - public AFPGraphics2DImagePainter(BatikGraphics2DImagePainter painter) { - super(painter.getImageXMLDOM(), painter.getBridgeContext(), painter.getRoot()); - } - - /** {@inheritDoc} */ - protected void init(Graphics2D g2d, Rectangle2D area) { - double tx = area.getX(); - double ty = area.getHeight() - area.getY(); - if (tx != 0 || ty != 0) { - g2d.translate(tx, ty); - } - - float iw = (float) ctx.getDocumentSize().getWidth(); - float ih = (float) ctx.getDocumentSize().getHeight(); - float w = (float) area.getWidth(); - float h = (float) area.getHeight(); - float sx = w / iw; - float sy = -(h / ih); - if (sx != 1.0 || sy != 1.0) { - g2d.scale(sx, sy); - } - } + // invert y-axis for GOCA + final int sx = 1; + final int sy = -1; + g2d.translate(0, height); + g2d.scale(sx, sy); + return graphicsObjectInfo; } } diff --git a/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java b/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java index 19504f6c9..376bee7b9 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java @@ -24,7 +24,7 @@ import java.io.InputStream; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; -import org.apache.fop.afp.AFPState; +import org.apache.fop.afp.AFPPaintingState; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; @@ -36,9 +36,9 @@ public class AFPImageRawStreamFactory extends AFPDataObjectInfoFactory { /** * Main constructor * - * @param state the AFP state + * @param state the AFP painting state */ - public AFPImageRawStreamFactory(AFPState state) { + public AFPImageRawStreamFactory(AFPPaintingState state) { super(state); } diff --git a/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java b/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java index 9c59e8b83..59d6af9a8 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java @@ -26,7 +26,7 @@ import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPImageObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; -import org.apache.fop.afp.AFPState; +import org.apache.fop.afp.AFPPaintingState; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.ps.ImageEncodingHelper; import org.apache.xmlgraphics.util.MimeConstants; @@ -39,9 +39,9 @@ public class AFPImageRenderedFactory extends AFPDataObjectInfoFactory { /** * Main constructor * - * @param state the AFP state + * @param state the AFP painting state */ - public AFPImageRenderedFactory(AFPState state) { + public AFPImageRenderedFactory(AFPPaintingState state) { super(state); } diff --git a/src/java/org/apache/fop/render/afp/AFPInfo.java b/src/java/org/apache/fop/render/afp/AFPInfo.java index 5fd59c2aa..1059014ab 100644 --- a/src/java/org/apache/fop/render/afp/AFPInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPInfo.java @@ -20,9 +20,9 @@ package org.apache.fop.render.afp; import org.apache.avalon.framework.configuration.Configuration; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; import org.apache.fop.afp.AFPResourceManager; -import org.apache.fop.afp.AFPState; import org.apache.fop.fonts.FontInfo; /** @@ -48,7 +48,7 @@ public final class AFPInfo { private FontInfo fontInfo; /** See AFP_STATE */ - private AFPState state; + private AFPPaintingState state; /** See AFP_RESOURCE_MANAGER */ private AFPResourceManager resourceManager; @@ -127,7 +127,7 @@ public final class AFPInfo { * * @return the current AFP state */ - public AFPState getState() { + public AFPPaintingState getPaintingState() { return this.state; } @@ -146,7 +146,7 @@ public final class AFPInfo { * @return true if supports color */ public boolean isColorSupported() { - return getState().isColorImages(); + return getPaintingState().isColorImages(); } /** @@ -173,7 +173,7 @@ public final class AFPInfo { * @return the resolution */ protected int getResolution() { - return getState().getResolution(); + return getPaintingState().getResolution(); } /** @@ -181,7 +181,7 @@ public final class AFPInfo { * @return the number of bits per pixel to use */ protected int getBitsPerPixel() { - return getState().getBitsPerPixel(); + return getPaintingState().getBitsPerPixel(); } /** @@ -216,7 +216,7 @@ public final class AFPInfo { * * @param state the AFP state */ - public void setState(AFPState state) { + public void setPaintingState(AFPPaintingState state) { this.state = state; } diff --git a/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java b/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java index 17aff9fc0..2e6eca6ae 100644 --- a/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java +++ b/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java @@ -24,7 +24,7 @@ import java.io.IOException; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPImageObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; -import org.apache.fop.afp.AFPState; +import org.apache.fop.afp.AFPPaintingState; import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; /** @@ -35,9 +35,9 @@ public class AFPRawCCITTFaxFactory extends AFPDataObjectInfoFactory { /** * Main constructor * - * @param state the afp state + * @param state the AFP painting state */ - public AFPRawCCITTFaxFactory(AFPState state) { + public AFPRawCCITTFaxFactory(AFPPaintingState state) { super(state); } diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index 03945dfee..87c098a89 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -33,14 +33,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.fop.AbstractState; import org.apache.fop.afp.AFPBorderPainter; import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPPageFonts; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPRectanglePainter; import org.apache.fop.afp.AFPResourceManager; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPTextDataInfo; import org.apache.fop.afp.AFPUnitConverter; import org.apache.fop.afp.BorderPaintInfo; @@ -72,6 +71,7 @@ import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.render.afp.extensions.AFPElementMapping; import org.apache.fop.render.afp.extensions.AFPPageSetup; +import org.apache.fop.util.AbstractPaintingState; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; @@ -146,8 +146,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** resource manager */ private AFPResourceManager resourceManager; - /** drawing state */ - private final AFPState state; + /** painting state */ + private final AFPPaintingState paintingState; /** unit converter */ private final AFPUnitConverter unitConv; @@ -175,9 +175,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { public AFPRenderer() { super(); this.resourceManager = new AFPResourceManager(); - this.state = new AFPState(); - this.dataObjectInfoProvider = new AFPDataObjectInfoProvider(state); - this.unitConv = state.getUnitConverter(); + this.paintingState = new AFPPaintingState(); + this.dataObjectInfoProvider = new AFPDataObjectInfoProvider(paintingState); + this.unitConv = paintingState.getUnitConverter(); } /** {@inheritDoc} */ @@ -197,13 +197,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void startRenderer(OutputStream outputStream) throws IOException { - state.setColor(Color.WHITE); + paintingState.setColor(Color.WHITE); - resourceManager.createDataStream(state, outputStream); + resourceManager.createDataStream(paintingState, outputStream); this.dataStream = resourceManager.getDataStream(); - this.borderPainter = new AFPBorderPainter(state, dataStream); - this.rectanglePainter = new AFPRectanglePainter(state, dataStream); + this.borderPainter = new AFPBorderPainter(paintingState, dataStream); + this.rectanglePainter = new AFPRectanglePainter(paintingState, dataStream); dataStream.startDocument(); } @@ -231,10 +231,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void preparePage(PageViewport page) { - int pageRotation = state.getPageRotation(); - int pageWidth = state.getPageWidth(); - int pageHeight = state.getPageHeight(); - int resolution = state.getResolution(); + int pageRotation = paintingState.getPageRotation(); + int pageWidth = paintingState.getPageWidth(); + int pageHeight = paintingState.getPageHeight(); + int resolution = paintingState.getResolution(); dataStream.startPage(pageWidth, pageHeight, pageRotation, resolution, resolution); @@ -278,7 +278,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ protected void concatenateTransformationMatrix(AffineTransform at) { if (!at.isIdentity()) { - state.concatenate(at); + paintingState.concatenate(at); } } @@ -296,12 +296,12 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void renderPage(PageViewport pageViewport) throws IOException, FOPException { - state.clear(); + paintingState.clear(); Rectangle2D bounds = pageViewport.getViewArea(); AffineTransform baseTransform = getBaseTransform(); - state.concatenate(baseTransform); + paintingState.concatenate(baseTransform); if (pages.containsKey(pageViewport)) { dataStream.restorePage( @@ -309,15 +309,15 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } else { int pageWidth = Math.round(unitConv.mpt2units((float)bounds.getWidth())); - state.setPageWidth(pageWidth); + paintingState.setPageWidth(pageWidth); int pageHeight = Math.round(unitConv.mpt2units((float)bounds.getHeight())); - state.setPageHeight(pageHeight); + paintingState.setPageHeight(pageHeight); - int pageRotation = state.getPageRotation(); + int pageRotation = paintingState.getPageRotation(); - int resolution = state.getResolution(); + int resolution = paintingState.getResolution(); dataStream.startPage(pageWidth, pageHeight, pageRotation, resolution, resolution); @@ -327,7 +327,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { super.renderPage(pageViewport); - AFPPageFonts pageFonts = state.getPageFonts(); + AFPPageFonts pageFonts = paintingState.getPageFonts(); if (pageFonts != null && !pageFonts.isEmpty()) { dataStream.addFontsToCurrentPage(pageFonts); } @@ -389,24 +389,22 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { this.fontInfo); context.setProperty(AFPRendererContextConstants.AFP_RESOURCE_MANAGER, this.resourceManager); - context.setProperty(AFPRendererContextConstants.AFP_STATE, state); + context.setProperty(AFPRendererContextConstants.AFP_PAINTING_STATE, paintingState); return context; } private static final ImageFlavor[] NATIVE_FLAVORS = new ImageFlavor[] { /*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP - ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS, - ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM }; + ImageFlavor.XML_DOM, ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS, + ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { - ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM }; + ImageFlavor.XML_DOM, ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; /** {@inheritDoc} */ public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { uri = URISpecification.getURL(uri); - state.setImageUri(uri); + paintingState.setImageUri(uri); Rectangle posInt = new Rectangle((int) pos.getX(), (int) pos.getY(), (int) pos.getWidth(), (int) pos.getHeight()); String name = (String)pageSegmentMap.get(uri); @@ -427,7 +425,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { // Only now fully load/prepare the image Map hints = ImageUtil.getDefaultHints(sessionContext); - ImageFlavor[] flavors = state.isNativeImages() ? NATIVE_FLAVORS : FLAVORS; + ImageFlavor[] flavors = paintingState.isNativeImages() ? NATIVE_FLAVORS : FLAVORS; org.apache.xmlgraphics.image.loader.Image img = manager.getImage( info, flavors, hints, sessionContext); @@ -501,30 +499,30 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void updateColor(Color col, boolean fill) { if (fill) { - state.setColor(col); + paintingState.setColor(col); } } /** {@inheritDoc} */ public void restoreStateStackAfterBreakOut(List breakOutList) { log.debug("Block.FIXED --> restoring context after break-out"); - state.pushAll(breakOutList); + paintingState.pushAll(breakOutList); } /** {@inheritDoc} */ protected List breakOutOfStateStack() { log.debug("Block.FIXED --> break out"); - return state.popAll(); + return paintingState.popAll(); } /** {@inheritDoc} */ public void saveGraphicsState() { - state.push(); + paintingState.push(); } /** {@inheritDoc} */ public void restoreGraphicsState() { - state.pop(); + paintingState.pop(); } /** Indicates the beginning of a text object. */ @@ -549,7 +547,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { renderInlineAreaBackAndBorders(text); int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - state.setFontSize(fontSize); + paintingState.setFontSize(fontSize); String name = getInternalFontNameForArea(text); AFPFont font = (AFPFont)fontInfo.getFonts().get(name); @@ -561,10 +559,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { AFPFontAttributes fontAttributes = new AFPFontAttributes(name, font, fontSize); - AFPPageFonts pageFonts = state.getPageFonts(); + AFPPageFonts pageFonts = paintingState.getPageFonts(); if (!pageFonts.containsKey(fontAttributes.getFontKey())) { // Font not found on current page, so add the new one - fontAttributes.setFontReference(state.incrementPageFontCount()); + fontAttributes.setFontReference(paintingState.incrementPageFontCount()); pageFonts.put(fontAttributes.getFontKey(), fontAttributes); } else { // Use the previously stored font attributes @@ -727,7 +725,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * The rotation in degrees. */ public void setPortraitRotation(int rotation) { - state.setPortraitRotation(rotation); + paintingState.setPortraitRotation(rotation); } /** @@ -738,7 +736,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * The rotation in degrees. */ public void setLandscapeRotation(int rotation) { - state.setLandscapeRotation(rotation); + paintingState.setLandscapeRotation(rotation); } /** @@ -748,7 +746,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * number of bits per pixel */ public void setBitsPerPixel(int bitsPerPixel) { - state.setBitsPerPixel(bitsPerPixel); + paintingState.setBitsPerPixel(bitsPerPixel); } /** @@ -758,7 +756,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * color image output */ public void setColorImages(boolean colorImages) { - state.setColorImages(colorImages); + paintingState.setColorImages(colorImages); } /** @@ -768,7 +766,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * native image support */ public void setNativeImages(boolean nativeImages) { - state.setNativeImages(nativeImages); + paintingState.setNativeImages(nativeImages); } /** @@ -778,7 +776,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the output resolution (dpi) */ public void setResolution(int resolution) { - state.setResolution(resolution); + paintingState.setResolution(resolution); } /** @@ -787,7 +785,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * @return the resolution in dpi */ public int getResolution() { - return state.getResolution(); + return paintingState.getResolution(); } /** @@ -795,8 +793,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * * @return the current AFP state */ - public AbstractState getState() { - return this.state; + public AbstractPaintingState getState() { + return this.paintingState; } /** diff --git a/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java index 72be26483..3302b7f3c 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java @@ -38,6 +38,6 @@ public interface AFPRendererContextConstants extends RendererContextConstants { /** The afp resource manager */ String AFP_RESOURCE_MANAGER = "afpResourceManager"; - /** The afp state */ - String AFP_STATE = "afpPageState"; + /** The afp painting state */ + String AFP_PAINTING_STATE = "afpPaintingState"; } diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index de2786215..3bdab289c 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -20,6 +20,7 @@ package org.apache.fop.render.afp; // FOP +import java.awt.Dimension; import java.awt.geom.AffineTransform; import java.awt.geom.Dimension2D; import java.io.IOException; @@ -36,14 +37,16 @@ import org.apache.fop.afp.AFPForeignAttributeReader; import org.apache.fop.afp.AFPGraphics2D; import org.apache.fop.afp.AFPGraphicsObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceLevel; import org.apache.fop.afp.AFPResourceManager; -import org.apache.fop.afp.AFPState; import org.apache.fop.afp.AFPTextElementBridge; import org.apache.fop.afp.AFPTextHandler; import org.apache.fop.afp.AFPTextPainter; import org.apache.fop.afp.AFPUnitConverter; -import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.afp.Graphics2DImagePainterGOCA; +import org.apache.fop.fonts.FontInfo; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; @@ -51,7 +54,7 @@ import org.apache.fop.render.RendererContextConstants; import org.apache.fop.render.RendererContext.RendererContextWrapper; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; -import org.apache.xmlgraphics.util.QName; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.w3c.dom.Document; /** @@ -61,9 +64,7 @@ import org.w3c.dom.Document; */ public class AFPSVGHandler extends AbstractGenericSVGHandler { - /** foreign attribute reader */ - private final AFPForeignAttributeReader foreignAttributeReader - = new AFPForeignAttributeReader(); + private boolean paintAsBitmap = false; /** {@inheritDoc} */ public void handleXML(RendererContext context, @@ -88,21 +89,24 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { afpi.setHandlerConfiguration((Configuration)context.getProperty(HANDLER_CONFIGURATION)); afpi.setFontInfo((org.apache.fop.fonts.FontInfo)context.getProperty( AFPRendererContextConstants.AFP_FONT_INFO)); - afpi.setState((AFPState)context.getProperty( - AFPRendererContextConstants.AFP_STATE)); + afpi.setPaintingState((AFPPaintingState)context.getProperty( + AFPRendererContextConstants.AFP_PAINTING_STATE)); afpi.setResourceManager(((AFPResourceManager)context.getProperty( AFPRendererContextConstants.AFP_RESOURCE_MANAGER))); Map foreignAttributes = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); if (foreignAttributes != null) { + String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE); + boolean paintAsBitmap = BITMAP.equalsIgnoreCase(conversionMode); + afpi.setPaintAsBitmap(paintAsBitmap); + AFPForeignAttributeReader foreignAttributeReader = new AFPForeignAttributeReader(); AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes); - afpi.setResourceInfo(resourceInfo); - - QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); - if ("bitmap".equalsIgnoreCase((String)foreignAttributes.get(qName))) { - afpi.setPaintAsBitmap(true); + // default to inline level if painted as GOCA + if (!resourceInfo.levelChanged() && !paintAsBitmap) { + resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); } + afpi.setResourceInfo(resourceInfo); } return afpi; } @@ -122,8 +126,10 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { AFPInfo afpInfo = getAFPInfo(context); + this.paintAsBitmap = afpInfo.paintAsBitmap(); + // fallback paint as bitmap - if (afpInfo.paintAsBitmap()) { + if (paintAsBitmap) { try { super.renderSVGDocument(context, doc); } catch (IOException ioe) { @@ -135,8 +141,8 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { } String uri = ((AbstractDocument)doc).getDocumentURI(); - AFPState state = afpInfo.getState(); - state.setImageUri(uri); + AFPPaintingState paintingState = afpInfo.getPaintingState(); + paintingState.setImageUri(uri); // set the data object parameters AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); @@ -146,7 +152,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { int curry = rctx.getCurrentYPosition(); float[] srcPts = {currx, curry}; - AFPUnitConverter unitConv = state.getUnitConverter(); + AFPUnitConverter unitConv = paintingState.getUnitConverter(); int[] coords = unitConv.mpts2units(srcPts); objectAreaInfo.setX(coords[X]); objectAreaInfo.setY(coords[Y]); @@ -161,7 +167,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { int height = Math.round(unitConv.mpt2units(afpInfo.getHeight())); objectAreaInfo.setHeight(height); - int rotation = state.getRotation(); + int rotation = paintingState.getRotation(); objectAreaInfo.setRotation(rotation); AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo(); @@ -171,14 +177,22 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { final boolean textAsShapes = false; AFPGraphics2D g2d = new AFPGraphics2D(textAsShapes); - g2d.setResourceManager(afpInfo.getResourceManager()); - g2d.setResourceInfo(afpInfo.getResourceInfo()); - g2d.setState(afpInfo.getState()); + g2d.setPaintingState(paintingState); + + AFPResourceManager resourceManager = afpInfo.getResourceManager(); + g2d.setResourceManager(resourceManager); + + AFPResourceInfo resourceInfo = afpInfo.getResourceInfo(); + g2d.setResourceInfo(resourceInfo); + graphicsObjectInfo.setResourceInfo(resourceInfo); + g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); - g2d.setFontInfo(afpInfo.getFontInfo()); + + FontInfo fontInfo = afpInfo.getFontInfo(); + g2d.setFontInfo(fontInfo); // Configure GraphicsObjectPainter with the Graphics2D implementation - AFPBatikGraphicsObjectPainter painter = new AFPBatikGraphicsObjectPainter(g2d); + GraphicsObjectPainterAFP painter = new GraphicsObjectPainterAFP(g2d); (graphicsObjectInfo).setPainter(painter); // Controls whether text painted by Batik is generated using text or path operations @@ -194,12 +208,6 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { ctx.putBridge(tBridge); } - Map/*<QName, String>*/ foreignAttributes - = (Map/*<QName, String>*/)context.getProperty( - RendererContextConstants.FOREIGN_ATTRIBUTES); - AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes); - graphicsObjectInfo.setResourceInfo(resourceInfo); - // Build the SVG DOM and provide the painter with it GraphicsNode root; GVTBuilder builder = new GVTBuilder(); @@ -221,13 +229,12 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { double hx = (afpInfo.getHeight() / h); double scaleX = unitConv.pt2units((float)wx); double scaleY = unitConv.pt2units((float)hx); - double xOffset = unitConv.mpt2units(afpInfo.getX()); double yOffset = unitConv.mpt2units(afpInfo.getHeight()); // Transformation matrix that establishes the local coordinate system // for the SVG graphic in relation to the current coordinate system // (note: y axis is inverted) - AffineTransform trans = new AffineTransform(scaleX, 0, 0, -scaleY, xOffset, yOffset); + AffineTransform trans = new AffineTransform(scaleX, 0, 0, -scaleY, 0, yOffset); g2d.setTransform(trans); // Set the afp graphics 2d implementation @@ -236,8 +243,6 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { // Set the object area info graphicsObjectInfo.setObjectAreaInfo(objectAreaInfo); - AFPResourceManager resourceManager = afpInfo.getResourceManager(); - // Create the graphics object resourceManager.createObject(graphicsObjectInfo); } @@ -253,4 +258,24 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, Boolean.FALSE); } + /** {@inheritDoc} */ + protected Graphics2DImagePainter createPainter(BridgeContext ctx, GraphicsNode root, Dimension imageSize) { + Graphics2DImagePainter painter = null; + if (paintAsBitmap()) { + painter = super.createPainter(root, ctx, imageSize); + } else { + painter = new Graphics2DImagePainterGOCA(root, ctx, imageSize); + } + return painter; + } + + /** + * Returns true if the SVG is to be painted as a bitmap + * + * @return true if the SVG is to be painted as a bitmap + */ + private boolean paintAsBitmap() { + return paintAsBitmap; + } + } diff --git a/src/java/org/apache/fop/render/afp/AFPBatikGraphicsObjectPainter.java b/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java index 0aa77d61b..7eb2c1001 100644 --- a/src/java/org/apache/fop/render/afp/AFPBatikGraphicsObjectPainter.java +++ b/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java @@ -24,13 +24,20 @@ import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import org.apache.batik.gvt.GraphicsNode; -import org.apache.fop.afp.AFPAbstractGraphicsObjectPainter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.afp.modca.GraphicsObject; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * Paints SVG as a GOCA Graphics Object using Batik */ -public class AFPBatikGraphicsObjectPainter extends AFPAbstractGraphicsObjectPainter { +public class GraphicsObjectPainterAFP implements Graphics2DImagePainter { + /** Static logging instance */ + protected static Log log = LogFactory.getLog(GraphicsObjectPainterAFP.class); + + private final AFPGraphics2D graphics2D; /** the batik root node of the svg document */ private GraphicsNode root; @@ -40,8 +47,9 @@ public class AFPBatikGraphicsObjectPainter extends AFPAbstractGraphicsObjectPain * * @param graphics an AFP graphics 2D implementation */ - public AFPBatikGraphicsObjectPainter(AFPGraphics2D graphics) { - super(graphics); + public GraphicsObjectPainterAFP(AFPGraphics2D graphics) { + final boolean textAsShapes = false; + this.graphics2D = new AFPGraphics2D(textAsShapes); } /** @@ -69,4 +77,13 @@ public class AFPBatikGraphicsObjectPainter extends AFPAbstractGraphicsObjectPain return null; } + /** + * Sets the GOCA Graphics Object + * + * @param graphicsObject the GOCA Graphics Object + */ + public void setGraphicsObject(GraphicsObject graphicsObject) { + this.graphics2D.setGraphicsObject(graphicsObject); + } + } diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java index 6ed45ca98..ba5c86059 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java +++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java @@ -23,22 +23,18 @@ import java.awt.geom.AffineTransform; import java.io.IOException; import java.util.Map; -import org.w3c.dom.Document; - import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.gvt.GraphicsNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - -import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; -import org.apache.xmlgraphics.util.QName; +import org.w3c.dom.Document; /** * Java2D XML handler for SVG (uses Apache Batik). @@ -72,9 +68,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue(); pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue(); Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); - QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); if (foreign != null - && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) { + && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) { pdfi.paintAsBitmap = true; } return pdfi; diff --git a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java index 2aa11227a..01d863e6a 100644 --- a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java @@ -95,8 +95,8 @@ public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter { AffineTransform transform = new AffineTransform(); transform.translate(fx, fy); - pdfInfo.pdfState.concatenate(transform); - graphics.setPDFState(pdfInfo.pdfState); + pdfInfo.pdfPaintingState.concatenate(transform); + graphics.setPaintingState(pdfInfo.pdfPaintingState); graphics.setOutputStream(pdfInfo.outputStream); if (pdfInfo.paintAsBitmap) { diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 9f60d3c86..0eba2fe91 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -40,7 +40,6 @@ import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.IOUtils; -import org.apache.fop.AbstractData; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; @@ -95,9 +94,9 @@ import org.apache.fop.pdf.PDFOutline; import org.apache.fop.pdf.PDFOutputIntent; import org.apache.fop.pdf.PDFPage; import org.apache.fop.pdf.PDFPageLabels; +import org.apache.fop.pdf.PDFPaintingState; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; -import org.apache.fop.pdf.PDFState; import org.apache.fop.pdf.PDFStream; import org.apache.fop.pdf.PDFTextUtil; import org.apache.fop.pdf.PDFXMode; @@ -105,9 +104,11 @@ import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; +import org.apache.fop.util.AbstractPaintingState; import org.apache.fop.util.CharUtilities; import org.apache.fop.util.ColorProfileUtil; import org.apache.fop.util.ColorUtil; +import org.apache.fop.util.AbstractPaintingState.AbstractData; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; @@ -249,8 +250,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { /** Optional URI to an output profile to be used. */ protected String outputProfileURI; - /** drawing state */ - protected PDFState currentState = null; + /** Painting state */ + protected PDFPaintingState paintingState = null; /** Text generation utility holding the current font status */ protected PDFTextUtil textutil; @@ -518,7 +519,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { currentStream = null; currentContext = null; currentPage = null; - currentState = null; + paintingState = null; this.textutil = null; idPositions.clear(); @@ -639,7 +640,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ protected void saveGraphicsState() { endTextObject(); - currentState.push(); + paintingState.push(); currentStream.add("q\n"); } @@ -647,7 +648,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { endTextObject(); currentStream.add("Q\n"); if (popState) { - currentState.pop(); + paintingState.pop(); } } @@ -782,11 +783,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } }; - currentState = new PDFState(); + paintingState = new PDFPaintingState(); // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0, pageHeight / 1000f); - currentState.concatenate(basicPageTransform); + paintingState.concatenate(basicPageTransform); currentStream.add(CTMHelper.toPDFString(basicPageTransform, false) + " cm\n"); super.renderPage(page); @@ -806,7 +807,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { protected void startVParea(CTM ctm, Rectangle2D clippingRect) { saveGraphicsState(); // Set the given CTM in the graphics state - currentState.concatenate( + paintingState.concatenate( new AffineTransform(CTMHelper.toPDFArray(ctm))); if (clippingRect != null) { @@ -827,7 +828,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ protected void concatenateTransformationMatrix(AffineTransform at) { if (!at.isIdentity()) { - currentState.concatenate(at); + paintingState.concatenate(at); currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n"); } } @@ -1017,7 +1018,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { * @param width line width in points */ private void updateLineWidth(float width) { - if (currentState.setLineWidth(width)) { + if (paintingState.setLineWidth(width)) { //Only write if value has changed WRT the current line width currentStream.add(format(width) + " w\n"); } @@ -1095,10 +1096,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { protected List breakOutOfStateStack() { // return currentState.popAll(); List breakOutList = new java.util.ArrayList(); - AbstractData data; + AbstractPaintingState.AbstractData data; while (true) { - data = currentState.getData(); - if (currentState.pop() == null) { + data = paintingState.getData(); + if (paintingState.pop() == null) { break; } if (breakOutList.size() == 0) { @@ -1260,7 +1261,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { */ protected void saveAbsolutePosition(String id, int relativeIPP, int relativeBPP) { saveAbsolutePosition(id, currentPageRef, - relativeIPP, relativeBPP, currentState.getTransform()); + relativeIPP, relativeBPP, paintingState.getTransform()); } /** @@ -1284,8 +1285,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { bpp += currentBPPosition; } AffineTransform tf = positioning == Block.FIXED - ? currentState.getBaseTransform() - : currentState.getTransform(); + ? paintingState.getBaseTransform() + : paintingState.getTransform(); saveAbsolutePosition(id, currentPageRef, ipp, bpp, tf); } } @@ -1348,7 +1349,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { int bpp = currentBPPosition + ip.getOffset(); ipRect = new Rectangle2D.Float(ipp / 1000f, bpp / 1000f, ip.getIPD() / 1000f, ip.getBPD() / 1000f); - AffineTransform transform = currentState.getTransform(); + AffineTransform transform = paintingState.getTransform(); ipRect = transform.createTransformedShape(ipRect).getBounds2D(); factory = pdfDoc.getFactory(); @@ -1582,9 +1583,9 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } boolean update = false; if (fill) { - update = currentState.setBackColor(col); + update = paintingState.setBackColor(col); } else { - update = currentState.setColor(col); + update = paintingState.setColor(col); } if (update) { @@ -1725,7 +1726,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { x, y, width, height, foreignAttributes); context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc); context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream); - context.setProperty(PDFRendererContextConstants.PDF_STATE, currentState); + context.setProperty(PDFRendererContextConstants.PDF_PAINTING_STATE, paintingState); context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage); context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext == null ? currentPage : currentContext); @@ -1745,7 +1746,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { public void renderLeader(Leader area) { renderInlineAreaBackAndBorders(area); - currentState.push(); + paintingState.push(); saveGraphicsState(); int style = area.getRuleStyle(); float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f; @@ -1803,7 +1804,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } restoreGraphicsState(); - currentState.pop(); + paintingState.pop(); beginTextObject(); super.renderLeader(area); } diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java index de51aabc7..33888d442 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java +++ b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java @@ -29,8 +29,8 @@ public interface PDFRendererContextConstants extends RendererContextConstants { /** The PDF document that this image is being drawn into. */ String PDF_DOCUMENT = "pdfDoc"; - /** The current pdf state. */ - String PDF_STATE = "pdfState"; + /** The current PDF painting state. */ + String PDF_PAINTING_STATE = "pdfPaintingState"; /** The current PDF page for page renference and as a resource context. */ String PDF_PAGE = "pdfPage"; diff --git a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java index e31628160..e83579728 100644 --- a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java @@ -25,8 +25,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Map; -import org.w3c.dom.Document; - import org.apache.avalon.framework.configuration.Configuration; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; @@ -35,16 +33,12 @@ import org.apache.batik.gvt.GraphicsNode; import org.apache.batik.util.SVGConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.util.QName; - import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.FontInfo; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFPaintingState; import org.apache.fop.pdf.PDFResourceContext; -import org.apache.fop.pdf.PDFState; import org.apache.fop.pdf.PDFStream; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; @@ -55,6 +49,7 @@ import org.apache.fop.svg.PDFBridgeContext; import org.apache.fop.svg.PDFGraphics2D; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; +import org.w3c.dom.Document; /** * PDF XML handler for SVG (uses Apache Batik). @@ -78,7 +73,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler PDFInfo pdfi = new PDFInfo(); pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT); pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM); - pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE); + pdfi.pdfPaintingState = (PDFPaintingState)context.getProperty(PDF_PAINTING_STATE); pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE); pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT); pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM); @@ -91,10 +86,9 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue(); pdfi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION); Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); - - QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); + if (foreign != null - && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) { + && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) { pdfi.paintAsBitmap = true; } return pdfi; @@ -109,7 +103,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler /** see OUTPUT_STREAM */ public OutputStream outputStream; /** see PDF_STATE */ - public PDFState pdfState; + public PDFPaintingState pdfPaintingState; /** see PDF_PAGE */ public PDFPage pdfPage; /** see PDF_CONTEXT */ @@ -199,8 +193,8 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler float w = (float)ctx.getDocumentSize().getWidth() * 1000f; float h = (float)ctx.getDocumentSize().getHeight() * 1000f; - float sx = pdfInfo.width / (float)w; - float sy = pdfInfo.height / (float)h; + float sx = pdfInfo.width / w; + float sy = pdfInfo.height / h; //Scaling and translation for the bounding box of the image AffineTransform scaling = new AffineTransform( @@ -249,16 +243,16 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler pdfInfo.currentStream.add("%SVG start\n"); //Save state and update coordinate system for the SVG image - pdfInfo.pdfState.push(); - pdfInfo.pdfState.concatenate(imageTransform); + pdfInfo.pdfPaintingState.push(); + pdfInfo.pdfPaintingState.concatenate(imageTransform); //Now that we have the complete transformation matrix for the image, we can update the //transformation matrix for the AElementBridge. PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge( SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG); - aBridge.getCurrentTransform().setTransform(pdfInfo.pdfState.getTransform()); + aBridge.getCurrentTransform().setTransform(pdfInfo.pdfPaintingState.getTransform()); - graphics.setPDFState(pdfInfo.pdfState); + graphics.setPaintingState(pdfInfo.pdfPaintingState); graphics.setOutputStream(pdfInfo.outputStream); try { root.paint(graphics); @@ -268,7 +262,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler context.getUserAgent().getEventBroadcaster()); eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); } - pdfInfo.pdfState.pop(); + pdfInfo.pdfPaintingState.pop(); renderer.restoreGraphicsState(); pdfInfo.currentStream.add("%SVG end\n"); } diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java index dd13df1c4..cc6e06978 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -19,30 +19,30 @@ package org.apache.fop.svg; -import org.apache.fop.Version; -import org.apache.fop.pdf.PDFDocument; -import org.apache.fop.pdf.PDFFilterList; -import org.apache.fop.pdf.PDFPage; -import org.apache.fop.pdf.PDFStream; -import org.apache.fop.pdf.PDFState; -import org.apache.fop.pdf.PDFNumber; -import org.apache.fop.pdf.PDFResources; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.pdf.PDFAnnotList; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontSetup; - -import java.awt.Graphics; -import java.awt.Font; import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; -import java.io.OutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.StringWriter; +import org.apache.fop.Version; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontSetup; +import org.apache.fop.pdf.PDFAnnotList; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFFilterList; +import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFPaintingState; +import org.apache.fop.pdf.PDFResources; +import org.apache.fop.pdf.PDFStream; + /** * This class is a wrapper for the <tt>PDFGraphics2D</tt> that * is used to create a full document around the pdf rendering from @@ -52,7 +52,7 @@ import java.io.StringWriter; */ public class PDFDocumentGraphics2D extends PDFGraphics2D { - private PDFContext pdfContext; + private final PDFContext pdfContext; private int width; private int height; @@ -296,7 +296,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { throw new IllegalStateException("Close page first before starting another"); } //Start page - graphicsState = new PDFState(); + paintingState = new PDFPaintingState(); if (this.initialTransform == null) { //Save initial transformation matrix this.initialTransform = getTransform(); @@ -322,7 +322,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { pageRef = page.referencePDF(); AffineTransform at = new AffineTransform(1.0, 0.0, 0.0, -1.0, - 0.0, (double)height); + 0.0, height); currentStream.write("1 0 0 -1 0 " + height + " cm\n"); if (svgWidth != 0) { double scaleX = width / svgWidth; @@ -340,7 +340,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { scale(1 / s, 1 / s); } // Remember the transform we installed. - graphicsState.concatenate(at); + paintingState.concatenate(at); pdfContext.increasePageCount(); } diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index cd0a4133b..179ebb90a 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -59,15 +59,6 @@ import org.apache.batik.ext.awt.RadialGradientPaint; import org.apache.batik.ext.awt.RenderingHintsKeyExt; import org.apache.batik.gvt.GraphicsNode; import org.apache.batik.gvt.PatternPaint; - -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageSize; -import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; -import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG; -import org.apache.xmlgraphics.image.loader.impl.ImageRendered; -import org.apache.xmlgraphics.java2d.AbstractGraphics2D; -import org.apache.xmlgraphics.java2d.GraphicContext; - import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontSetup; @@ -83,16 +74,23 @@ import org.apache.fop.pdf.PDFImage; import org.apache.fop.pdf.PDFImageXObject; import org.apache.fop.pdf.PDFLink; import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFPaintingState; import org.apache.fop.pdf.PDFPattern; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; -import org.apache.fop.pdf.PDFState; import org.apache.fop.pdf.PDFText; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter; import org.apache.fop.render.pdf.ImageRawJPEGAdapter; import org.apache.fop.render.pdf.ImageRenderedAdapter; import org.apache.fop.util.ColorExt; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; +import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG; +import org.apache.xmlgraphics.image.loader.impl.ImageRendered; +import org.apache.xmlgraphics.java2d.AbstractGraphics2D; +import org.apache.xmlgraphics.java2d.GraphicContext; /** * PDF Graphics 2D. @@ -129,9 +127,9 @@ public class PDFGraphics2D extends AbstractGraphics2D { protected String pageRef; /** - * the current state of the pdf graphics + * The PDF painting state */ - protected PDFState graphicsState; + protected PDFPaintingState paintingState; /** * The PDF graphics state level that this svg is being drawn into. @@ -200,7 +198,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { currentFontSize = size; fontInfo = fi; pageRef = pref; - graphicsState = new PDFState(); + paintingState = new PDFPaintingState(); } /** @@ -226,7 +224,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { this.currentFontSize = g.currentFontSize; this.fontInfo = g.fontInfo; this.pageRef = g.pageRef; - this.graphicsState = g.graphicsState; + this.paintingState = g.paintingState; this.currentStream = g.currentStream; this.nativeCount = g.nativeCount; this.outputStream = g.outputStream; @@ -266,9 +264,9 @@ public class PDFGraphics2D extends AbstractGraphics2D { * * @param state the PDF state */ - public void setPDFState(PDFState state) { - graphicsState = state; - baseLevel = graphicsState.getStackLevel(); + public void setPaintingState(PDFPaintingState state) { + paintingState = state; + baseLevel = paintingState.getStackLevel(); } /** @@ -369,7 +367,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @return the transformation matrix that established the basic user space for this document */ protected AffineTransform getBaseTransform() { - AffineTransform at = new AffineTransform(graphicsState.getTransform()); + AffineTransform at = new AffineTransform(paintingState.getTransform()); return at; } @@ -518,10 +516,13 @@ public class PDFGraphics2D extends AbstractGraphics2D { g.setBackground(new Color(1, 1, 1, 0)); g.setPaint(new Color(1, 1, 1, 0)); g.fillRect(0, 0, width, height); - g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); + + int imageWidth = buf.getWidth(); + int imageHeight = buf.getHeight(); + g.clip(new Rectangle(0, 0, imageWidth, imageHeight)); g.setComposite(gc.getComposite()); - if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) { + if (!g.drawImage(img, 0, 0, imageWidth, imageHeight, observer)) { return false; } g.dispose(); @@ -602,13 +603,13 @@ public class PDFGraphics2D extends AbstractGraphics2D { trans.getMatrix(tranvals); Shape imclip = getClip(); - boolean newClip = graphicsState.checkClip(imclip); - boolean newTransform = graphicsState.checkTransform(trans) + boolean newClip = paintingState.checkClip(imclip); + boolean newTransform = paintingState.checkTransform(trans) && !trans.isIdentity(); if (newClip || newTransform) { currentStream.write("q\n"); - graphicsState.push(); + paintingState.push(); if (newTransform) { concatMatrix(tranvals); } @@ -625,7 +626,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { applyColor(c, true); Paint paint = getPaint(); - if (graphicsState.setPaint(paint)) { + if (paintingState.setPaint(paint)) { if (!applyPaint(paint, false)) { // Stroke the shape and use it to 'clip' // the paint contents. @@ -634,7 +635,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { if (newClip || newTransform) { currentStream.write("Q\n"); - graphicsState.pop(); + paintingState.pop(); } return; } @@ -646,7 +647,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { doDrawing(false, true, false); if (newClip || newTransform) { currentStream.write("Q\n"); - graphicsState.pop(); + paintingState.pop(); } } @@ -1380,7 +1381,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { if (!useMultiByte) { if (ch > 127) { currentStream.write("\\"); - currentStream.write(Integer.toOctalString((int)ch)); + currentStream.write(Integer.toOctalString(ch)); } else { switch (ch) { case '(': @@ -1397,8 +1398,8 @@ public class PDFGraphics2D extends AbstractGraphics2D { } if (kerningAvailable && (i + 1) < l) { - addKerning(currentStream, (new Integer((int)ch)), - (new Integer((int)fontState.mapChar(s.charAt(i + 1)))), + addKerning(currentStream, (new Integer(ch)), + (new Integer(fontState.mapChar(s.charAt(i + 1)))), kerning, startText, endText); } @@ -1426,7 +1427,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f)); } PDFGState gstate = pdfDoc.getFactory().makeGState( - vals, graphicsState.getGState()); + vals, paintingState.getGState()); resourceContext.addGState(gstate); currentStream.write("/" + gstate.getName() + " gs\n"); } @@ -1438,7 +1439,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { */ protected void updateCurrentFont(Font font) { String name = font.getFontName(); - float size = (float)font.getFontSize() / 1000f; + float size = font.getFontSize() / 1000f; //Only update if necessary if ((!name.equals(this.currentFontName)) @@ -1617,13 +1618,13 @@ public class PDFGraphics2D extends AbstractGraphics2D { trans.getMatrix(tranvals); Shape imclip = getClip(); - boolean newClip = graphicsState.checkClip(imclip); - boolean newTransform = graphicsState.checkTransform(trans) + boolean newClip = paintingState.checkClip(imclip); + boolean newTransform = paintingState.checkTransform(trans) && !trans.isIdentity(); if (newClip || newTransform) { currentStream.write("q\n"); - graphicsState.push(); + paintingState.push(); if (newTransform) { concatMatrix(tranvals); } @@ -1640,14 +1641,14 @@ public class PDFGraphics2D extends AbstractGraphics2D { applyColor(c, false); Paint paint = getPaint(); - if (graphicsState.setPaint(paint)) { + if (paintingState.setPaint(paint)) { if (!applyPaint(paint, true)) { // Use the shape to 'clip' the paint contents. applyUnknownPaint(paint, s); if (newClip || newTransform) { currentStream.write("Q\n"); - graphicsState.pop(); + paintingState.pop(); } return; } @@ -1660,7 +1661,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { iter.getWindingRule() == PathIterator.WIND_EVEN_ODD); if (newClip || newTransform) { currentStream.write("Q\n"); - graphicsState.pop(); + paintingState.pop(); } } diff --git a/src/java/org/apache/fop/AbstractState.java b/src/java/org/apache/fop/util/AbstractPaintingState.java index 74719e8f8..e712ce74f 100644 --- a/src/java/org/apache/fop/AbstractState.java +++ b/src/java/org/apache/fop/util/AbstractPaintingState.java @@ -17,12 +17,13 @@ /* $Id$ */ -package org.apache.fop; +package org.apache.fop.util; import java.awt.Color; import java.awt.geom.AffineTransform; import java.io.Serializable; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Stack; @@ -31,7 +32,7 @@ import java.util.Stack; /** * A base class which holds information about the current rendering state. */ -public abstract class AbstractState implements Cloneable, Serializable { +public abstract class AbstractPaintingState implements Cloneable, Serializable { private static final long serialVersionUID = 5998356138437094188L; @@ -39,7 +40,7 @@ public abstract class AbstractState implements Cloneable, Serializable { private AbstractData data = null; /** the state stack */ - private StateStack stateStack = new StateStack(); + private StateStack/*<AbstractData>*/ stateStack = new StateStack/*<AbstractData>*/(); /** * Instantiates a new state data object @@ -53,7 +54,7 @@ public abstract class AbstractState implements Cloneable, Serializable { * * @return a new state object */ - protected abstract AbstractState instantiateState(); + protected abstract AbstractPaintingState instantiate(); /** * Returns the currently valid state @@ -277,7 +278,7 @@ public abstract class AbstractState implements Cloneable, Serializable { /** - * Push the current state onto the stack. + * Push the current painting state onto the stack. * This call should be used when the Q operator is used * so that the state is known when popped. */ @@ -287,7 +288,7 @@ public abstract class AbstractState implements Cloneable, Serializable { } /** - * Pop the state from the stack and set current values to popped state. + * Pop the painting state from the stack and set current values to popped state. * This should be called when a Q operator is used so * the state is restored to the correct values. * @@ -303,7 +304,7 @@ public abstract class AbstractState implements Cloneable, Serializable { } /** - * Pushes all state data in the given list to the stack + * Pushes all painting state data in the given list to the stack * * @param dataList a state data list */ @@ -317,7 +318,7 @@ public abstract class AbstractState implements Cloneable, Serializable { } /** - * Pops all state data from the stack + * Pops all painting state data from the stack * * @return a list of state data popped from the stack */ @@ -363,7 +364,7 @@ public abstract class AbstractState implements Cloneable, Serializable { /** {@inheritDoc} */ public Object clone() { - AbstractState state = instantiateState(); + AbstractPaintingState state = instantiate(); state.stateStack = new StateStack(this.stateStack); state.data = (AbstractData)this.data.clone(); return state; @@ -374,4 +375,156 @@ public abstract class AbstractState implements Cloneable, Serializable { return ", stateStack=" + stateStack + ", currentData=" + data; } + + + /** + * A stack implementation which holds state objects + */ + public class StateStack extends java.util.Stack { + + private static final long serialVersionUID = 4897178211223823041L; + + /** + * Default constructor + */ + public StateStack() { + super(); + } + + /** + * Copy constructor + * + * @param c initial contents of stack + */ + public StateStack(Collection c) { + elementCount = c.size(); + // 10% for growth + elementData = new Object[ + (int)Math.min((elementCount * 110L) / 100, Integer.MAX_VALUE)]; + c.toArray(elementData); + } + } + + + /** + * A base painting state data holding object + */ + public abstract class AbstractData implements Cloneable, Serializable { + + private static final long serialVersionUID = 5208418041189828624L; + + /** The current color */ + protected Color color = null; + + /** The current background color */ + protected Color backColor = null; + + /** The current font name */ + protected String fontName = null; + + /** The current font size */ + protected int fontSize = 0; + + /** The current line width */ + protected float lineWidth = 0; + + /** The dash array for the current basic stroke (line type) */ + protected float[] dashArray = null; + + /** The current transform */ + protected AffineTransform transform = null; + + /** + * Returns a newly create data object + * + * @return a new data object + */ + protected abstract AbstractData instantiate(); + + /** + * Concatenate the given AffineTransform with the current thus creating + * a new viewport. Note that all concatenation operations are logged + * so they can be replayed if necessary (ex. for block-containers with + * "fixed" positioning. + * + * @param at Transformation to perform + */ + public void concatenate(AffineTransform at) { + getTransform().concatenate(at); + } + + /** + * Get the current AffineTransform. + * + * @return the current transform + */ + public AffineTransform getTransform() { + if (transform == null) { + transform = new AffineTransform(); + } + return transform; + } + + /** + * Sets the current AffineTransform. + */ + public void setTransform(AffineTransform baseTransform) { + this.transform = baseTransform; + } + + /** + * Resets the current AffineTransform. + */ + public void clearTransform() { + transform = new AffineTransform(); + } + + /** + * Returns the derived rotation from the current transform + * + * @return the derived rotation from the current transform + */ + public int getDerivedRotation() { + AffineTransform at = getTransform(); + double sx = at.getScaleX(); + double sy = at.getScaleY(); + double shx = at.getShearX(); + double shy = at.getShearY(); + int rotation = 0; + if (sx == 0 && sy == 0 && shx > 0 && shy < 0) { + rotation = 270; + } else if (sx < 0 && sy < 0 && shx == 0 && shy == 0) { + rotation = 180; + } else if (sx == 0 && sy == 0 && shx < 0 && shy > 0) { + rotation = 90; + } else { + rotation = 0; + } + return rotation; + } + + /** {@inheritDoc} */ + public Object clone() { + AbstractData data = instantiate(); + data.color = this.color; + data.backColor = this.backColor; + data.fontName = this.fontName; + data.fontSize = this.fontSize; + data.lineWidth = this.lineWidth; + data.dashArray = this.dashArray; + data.transform = new AffineTransform(this.transform); + return data; + } + + /** {@inheritDoc} */ + public String toString() { + return "color=" + color + + ", backColor=" + backColor + + ", fontName=" + fontName + + ", fontSize=" + fontSize + + ", lineWidth=" + lineWidth + + ", dashArray=" + dashArray + + ", transform=" + transform; + } + } } |