]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
"fixed" block container handling fixed (see block-container_absolute-position_fixed...
authorAdrian Cumiskey <acumiskey@apache.org>
Tue, 4 Nov 2008 15:30:38 +0000 (15:30 +0000)
committerAdrian Cumiskey <acumiskey@apache.org>
Tue, 4 Nov 2008 15:30:38 +0000 (15:30 +0000)
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

48 files changed:
src/java/org/apache/fop/AbstractData.java [deleted file]
src/java/org/apache/fop/AbstractState.java [deleted file]
src/java/org/apache/fop/StateStack.java [deleted file]
src/java/org/apache/fop/afp/AFPAbstractGraphicsObjectPainter.java [deleted file]
src/java/org/apache/fop/afp/AFPBorderPainter.java
src/java/org/apache/fop/afp/AFPGraphics2D.java
src/java/org/apache/fop/afp/AFPPaintingState.java [new file with mode: 0644]
src/java/org/apache/fop/afp/AFPRectanglePainter.java
src/java/org/apache/fop/afp/AFPResourceLevel.java
src/java/org/apache/fop/afp/AFPResourceManager.java
src/java/org/apache/fop/afp/AFPState.java [deleted file]
src/java/org/apache/fop/afp/AFPStreamer.java
src/java/org/apache/fop/afp/AFPTextHandler.java
src/java/org/apache/fop/afp/AFPUnitConverter.java
src/java/org/apache/fop/afp/AbstractAFPPainter.java
src/java/org/apache/fop/afp/Factory.java
src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java [new file with mode: 0644]
src/java/org/apache/fop/afp/ioca/ImageContent.java
src/java/org/apache/fop/afp/modca/DataStream.java
src/java/org/apache/fop/image/loader/batik/BatikGraphics2DImagePainter.java [deleted file]
src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java [new file with mode: 0644]
src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
src/java/org/apache/fop/pdf/PDFPaintingState.java [new file with mode: 0644]
src/java/org/apache/fop/pdf/PDFState.java [deleted file]
src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java
src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java
src/java/org/apache/fop/render/afp/AFPBatikGraphicsObjectPainter.java [deleted file]
src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java
src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java
src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java
src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java
src/java/org/apache/fop/render/afp/AFPInfo.java
src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java
src/java/org/apache/fop/render/afp/AFPRenderer.java
src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java
src/java/org/apache/fop/render/afp/AFPSVGHandler.java
src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java [new file with mode: 0644]
src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java
src/java/org/apache/fop/render/pdf/PDFSVGHandler.java
src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
src/java/org/apache/fop/svg/PDFGraphics2D.java
src/java/org/apache/fop/util/AbstractPaintingState.java [new file with mode: 0644]

diff --git a/src/java/org/apache/fop/AbstractData.java b/src/java/org/apache/fop/AbstractData.java
deleted file mode 100644 (file)
index b689165..0000000
+++ /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/AbstractState.java b/src/java/org/apache/fop/AbstractState.java
deleted file mode 100644 (file)
index 74719e8..0000000
+++ /dev/null
@@ -1,377 +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;
-
-import java.awt.Color;
-import java.awt.geom.AffineTransform;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
-
-/**
- * A base class which holds information about the current rendering state.
- */
-public abstract class AbstractState implements Cloneable, Serializable {
-
-    private static final long serialVersionUID = 5998356138437094188L;
-
-    /** current state data */
-    private AbstractData data = null;
-
-    /** the state stack */
-    private StateStack stateStack = new StateStack();
-
-    /**
-     * Instantiates a new state data object
-     *
-     * @return a new state data object
-     */
-    protected abstract AbstractData instantiateData();
-
-    /**
-     * Instantiates a new state object
-     *
-     * @return a new state object
-     */
-    protected abstract AbstractState instantiateState();
-
-    /**
-     * Returns the currently valid state
-     *
-     * @return the currently valid state
-     */
-    public AbstractData getData() {
-        if (data == null) {
-            data = instantiateData();
-        }
-        return data;
-    }
-
-    /**
-     * Set the current color.
-     * Check if the new color is a change and then set the current color.
-     *
-     * @param col the color to set
-     * @return true if the color has changed
-     */
-    public boolean setColor(Color col) {
-        if (!col.equals(getData().color)) {
-            getData().color = col;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Get the color.
-     *
-     * @return the color
-     */
-    public Color getColor() {
-        if (getData().color == null) {
-            getData().color = Color.black;
-        }
-        return getData().color;
-    }
-
-    /**
-     * Get the background color.
-     *
-     * @return the background color
-     */
-    public Color getBackColor() {
-        if (getData().backColor == null) {
-            getData().backColor = Color.white;
-        }
-        return getData().backColor;
-    }
-
-    /**
-     * Set the current background color.
-     * Check if the new background color is a change and then set the current background color.
-     *
-     * @param col the background color to set
-     * @return true if the color has changed
-     */
-    public boolean setBackColor(Color col) {
-        if (!col.equals(getData().backColor)) {
-            getData().backColor = col;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Set the current font name
-     *
-     * @param internalFontName the internal font name
-     * @return true if the font name has changed
-     */
-    public boolean setFontName(String internalFontName) {
-        if (!internalFontName.equals(getData().fontName)) {
-            getData().fontName = internalFontName;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Gets the current font name
-     *
-     * @return the current font name
-     */
-    public String getFontName() {
-        return getData().fontName;
-    }
-
-    /**
-     * Gets the current font size
-     *
-     * @return the current font size
-     */
-    public int getFontSize() {
-        return getData().fontSize;
-    }
-
-    /**
-     * Set the current font size.
-     * Check if the font size is a change and then set the current font size.
-     *
-     * @param size the font size to set
-     * @return true if the font size has changed
-     */
-    public boolean setFontSize(int size) {
-        if (size != getData().fontSize) {
-            getData().fontSize = size;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Set the current line width.
-     *
-     * @param width the line width in points
-     * @return true if the line width has changed
-     */
-    public boolean setLineWidth(float width) {
-        if (getData().lineWidth != width) {
-            getData().lineWidth = width;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the current line width
-     *
-     * @return the current line width
-     */
-    public float getLineWidth() {
-        return getData().lineWidth;
-    }
-
-    /**
-     * Sets the dash array (line type) for the current basic stroke
-     *
-     * @param dash the line dash array
-     * @return true if the dash array has changed
-     */
-    public boolean setDashArray(float[] dash) {
-        if (!Arrays.equals(dash, getData().dashArray)) {
-            getData().dashArray = dash;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Get the current transform.
-     * This gets the combination of all transforms in the
-     * current state.
-     *
-     * @return the calculate combined transform for the current state
-     */
-    public AffineTransform getTransform() {
-       AffineTransform at = new AffineTransform();
-       for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
-           AbstractData data = (AbstractData)iter.next();
-           AffineTransform stackTrans = data.getTransform();
-           at.concatenate(stackTrans);
-       }
-       AffineTransform currentTrans = getData().getTransform();
-       at.concatenate(currentTrans);
-       return at;
-    }
-
-    /**
-     * Check the current transform.
-     * The transform for the current state is the combination of all
-     * transforms in the current state. The parameter is compared
-     * against this current transform.
-     *
-     * @param tf the transform the check against
-     * @return true if the new transform is different then the current transform
-     */
-    public boolean checkTransform(AffineTransform tf) {
-        return !tf.equals(getData().getTransform());
-    }
-
-    /**
-     * Get a copy of the base transform for the page. Used to translate
-     * IPP/BPP values into X,Y positions when positioning is "fixed".
-     *
-     * @return the base transform, or null if the state stack is empty
-     */
-    public AffineTransform getBaseTransform() {
-       if (stateStack.isEmpty()) {
-           return null;
-       } else {
-           AbstractData baseData = (AbstractData)stateStack.get(0);
-           return (AffineTransform) baseData.getTransform().clone();
-       }
-    }
-
-    /**
-     * Concatenates the given AffineTransform to the current one.
-     *
-     * @param at the transform to concatenate to the current level transform
-     */
-    public void concatenate(AffineTransform at) {
-        getData().concatenate(at);
-    }
-
-    /**
-     * Resets the current AffineTransform to the Base AffineTransform.
-     */
-    public void resetTransform() {
-        getData().setTransform(getBaseTransform());
-    }
-
-    /**
-     * Clears the current AffineTransform to the Identity AffineTransform
-     */
-    public void clearTransform() {
-        getData().clearTransform();
-    }
-
-
-    /**
-     * Push the current state onto the stack.
-     * This call should be used when the Q operator is used
-     * so that the state is known when popped.
-     */
-    public void push() {
-        AbstractData copy = (AbstractData)getData().clone();
-        stateStack.push(copy);
-    }
-
-    /**
-     * Pop the 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.
-     *
-     * @return the restored state, null if the stack is empty
-     */
-    public AbstractData pop() {
-        if (!stateStack.isEmpty()) {
-            setData((AbstractData)stateStack.pop());
-            return this.data;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Pushes all state data in the given list to the stack
-     *
-     * @param dataList a state data list
-     */
-    public void pushAll(List/*<AbstractData>*/ dataList) {
-        Iterator it = dataList.iterator();
-        while (it.hasNext()) {
-            // save current data on stack
-            push();
-            setData((AbstractData)it.next());
-        }
-    }
-
-    /**
-     * Pops all state data from the stack
-     *
-     * @return a list of state data popped from the stack
-     */
-    public List/*<AbstractData>*/ popAll() {
-        List/*<AbstractData>*/ dataList = new java.util.ArrayList/*<AbstractData>*/();
-        AbstractData data;
-        while (true) {
-            data = getData();
-            if (pop() == null) {
-                break;
-            }
-            // insert because of stack-popping
-            dataList.add(0, data);
-        }
-        return dataList;
-    }
-
-    /**
-     * Sets the current state data
-     *
-     * @param currentData state data
-     */
-    protected void setData(AbstractData data) {
-        this.data = data;
-    }
-
-    /**
-     * Clears the state stack
-     */
-    public void clear() {
-        stateStack.clear();
-        setData(null);
-    }
-
-    /**
-     * Return the state stack
-     *
-     * @return the state stack
-     */
-    protected Stack/*<AbstractData>*/ getStateStack() {
-        return this.stateStack;
-    }
-
-    /** {@inheritDoc} */
-    public Object clone() {
-        AbstractState state = instantiateState();
-        state.stateStack = new StateStack(this.stateStack);
-        state.data = (AbstractData)this.data.clone();
-        return state;
-    }
-
-    /** {@inheritDoc} */
-    public String toString() {
-        return ", stateStack=" + stateStack
-        + ", currentData=" + data;
-    }
-}
diff --git a/src/java/org/apache/fop/StateStack.java b/src/java/org/apache/fop/StateStack.java
deleted file mode 100644 (file)
index 0c73b48..0000000
+++ /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 (file)
index 8c5e840..0000000
+++ /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
index 96f9ae78faa9345d37bb65f788d8acfefe112176..86960b7ffebd5e972bab294a88dd9d69a646ddd3 100644 (file)
@@ -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);
     }
 
index 21114bb8833c640677537d26fff48a7a3bcfd0a1..d412e2b94779125051ab58bd0b5e09d35ad16eda 100644 (file)
@@ -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/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
new file mode 100644 (file)
index 0000000..60e4812
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * 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.util.AbstractPaintingState;
+
+/**
+ * This keeps information about the current painting state when writing to an AFP datastream.
+ */
+public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState  implements Cloneable {
+
+    private static final long serialVersionUID = 8206711712452344473L;
+
+    private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
+
+    /** the portrait rotation */
+    private int portraitRotation = 0;
+
+    /** the landscape rotation */
+    private int landscapeRotation = 270;
+
+    /** color image support */
+    private boolean colorImages = false;
+
+    /** images are supported in this AFP environment */
+    private boolean nativeImages = false;
+
+    /** default value for image depth */
+    private int bitsPerPixel = 8;
+
+    /** the output resolution */
+    private int resolution = 240; // 240 dpi
+
+    /** the current page */
+    private AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();
+
+//    /** reference orientation */
+//    private int orientation = 0;
+
+    /** a unit converter */
+    private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
+
+    /**
+     * Sets the rotation to be used for portrait pages, valid values are 0
+     * (default), 90, 180, 270.
+     *
+     * @param rotation
+     *            The rotation in degrees.
+     */
+    public void setPortraitRotation(int rotation) {
+        if (rotation == 0 || rotation == 90 || rotation == 180
+                || rotation == 270) {
+            portraitRotation = rotation;
+        } else {
+            throw new IllegalArgumentException(
+                    "The portrait rotation must be one"
+                            + " of the values 0, 90, 180, 270");
+
+        }
+    }
+
+    /**
+     * Returns the rotation to be used for portrait pages
+     *
+     * @return the rotation to be used for portrait pages
+     */
+    protected int getPortraitRotation() {
+        return this.portraitRotation;
+    }
+
+    /**
+     * Sets the rotation to be used for landscape pages, valid values are 0, 90,
+     * 180, 270 (default).
+     *
+     * @param rotation
+     *            The rotation in degrees.
+     */
+    public void setLandscapeRotation(int rotation) {
+        if (rotation == 0 || rotation == 90 || rotation == 180
+                || rotation == 270) {
+            landscapeRotation = rotation;
+        } else {
+            throw new IllegalArgumentException(
+                    "The landscape rotation must be one"
+                            + " of the values 0, 90, 180, 270");
+        }
+    }
+
+    /**
+     * Returns the landscape rotation
+     *
+     * @return the landscape rotation
+     */
+    protected int getLandscapeRotation() {
+        return this.landscapeRotation;
+    }
+
+    /**
+     * Sets the number of bits used per pixel
+     *
+     * @param bitsPerPixel
+     *            number of bits per pixel
+     */
+    public void setBitsPerPixel(int bitsPerPixel) {
+        switch (bitsPerPixel) {
+        case 1:
+        case 4:
+        case 8:
+            this.bitsPerPixel = bitsPerPixel;
+            break;
+        default:
+            log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
+            this.bitsPerPixel = 8;
+            break;
+        }
+    }
+
+    /**
+     * Returns the number of bits per pixel
+     *
+     * @return the number of bits per pixel
+     */
+    public int getBitsPerPixel() {
+        return this.bitsPerPixel;
+    }
+
+    /**
+     * Sets whether images are color or not
+     *
+     * @param colorImages
+     *            color image output
+     */
+    public void setColorImages(boolean colorImages) {
+        this.colorImages = colorImages;
+    }
+
+    /**
+     * Returns true if color images are to be used
+     *
+     * @return true if color images are to be used
+     */
+    public boolean isColorImages() {
+        return this.colorImages;
+    }
+
+    /**
+     * Sets whether images are natively supported or not in the AFP environment
+     *
+     * @param nativeImages true if images are natively supported in this AFP environment
+     */
+    public void setNativeImages(boolean nativeImages) {
+        this.nativeImages = nativeImages;
+    }
+
+    /**
+     * Returns true if images are supported natively in this AFP environment
+     *
+     * @return true if images are supported natively in this AFP environment
+     */
+    public boolean isNativeImages() {
+        return this.nativeImages;
+    }
+
+    /**
+     * Sets the output/device resolution
+     *
+     * @param resolution
+     *            the output resolution (dpi)
+     */
+    public void setResolution(int resolution) {
+        if (log.isDebugEnabled()) {
+            log.debug("renderer-resolution set to: " + resolution + "dpi");
+        }
+        this.resolution = resolution;
+    }
+
+    /**
+     * Returns the output/device resolution.
+     *
+     * @return the resolution in dpi
+     */
+    public int getResolution() {
+        return this.resolution;
+    }
+
+    /** {@inheritDoc} */
+    protected AbstractData instantiateData() {
+        return new AFPData();
+    }
+
+    /** {@inheritDoc} */
+    protected AbstractPaintingState instantiate() {
+        return new AFPPaintingState();
+    }
+
+    /**
+     * Returns the painting state of the current page
+     *
+     * @return the painting state of the current page
+     */
+    protected AFPPagePaintingState getPagePaintingState() {
+        return this.pagePaintingState;
+    }
+
+    /**
+     * Sets if the current painted shape is to be filled
+     *
+     * @param fill true if the current painted shape is to be filled
+     * @return true if the fill value has changed
+     */
+    protected boolean setFill(boolean fill) {
+        if (fill != ((AFPData)getData()).filled) {
+            ((AFPData)getData()).filled = fill;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets the current page fonts
+     *
+     * @return the current page fonts
+     */
+    public AFPPageFonts getPageFonts() {
+        return pagePaintingState.getFonts();
+    }
+
+    /**
+     * Increments and returns the page font count
+     *
+     * @return the page font count
+     */
+    public int incrementPageFontCount() {
+        return pagePaintingState.incrementFontCount();
+    }
+
+    /**
+     * Sets the page width
+     *
+     * @param pageWidth the page width
+     */
+    public void setPageWidth(int pageWidth) {
+        pagePaintingState.setWidth(pageWidth);
+    }
+
+    /**
+     * Returns the page width
+     *
+     * @return the page width
+     */
+    public int getPageWidth() {
+        return pagePaintingState.getWidth();
+    }
+
+    /**
+     * Sets the page height
+     *
+     * @param pageHeight the page height
+     */
+    public void setPageHeight(int pageHeight) {
+        pagePaintingState.setHeight(pageHeight);
+    }
+
+    /**
+     * Returns the page height
+     *
+     * @return the page height
+     */
+    public int getPageHeight() {
+        return pagePaintingState.getHeight();
+    }
+
+    /**
+     * Returns the page rotation
+     *
+     * @return the page rotation
+     */
+    public int getPageRotation() {
+        return pagePaintingState.getOrientation();
+    }
+
+    /**
+     * Sets the uri of the current image
+     *
+     * @param uri the uri of the current image
+     */
+    public void setImageUri(String uri) {
+        ((AFPData)getData()).imageUri = uri;
+    }
+
+    /**
+     * Gets the uri of the current image
+     *
+     * @return the uri of the current image
+     */
+    public String getImageUri() {
+        return ((AFPData)getData()).imageUri;
+    }
+
+    /**
+     * Returns the currently derived rotation
+     *
+     * @return the currently derived rotation
+     */
+    public int getRotation() {
+        return getData().getDerivedRotation();
+    }
+
+    /**
+     * Returns the unit converter
+     *
+     * @return the unit converter
+     */
+    public AFPUnitConverter getUnitConverter() {
+        return this.unitConv;
+    }
+
+    /** {@inheritDoc} */
+    public Object clone() {
+        AFPPaintingState state = (AFPPaintingState)super.clone();
+        state.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
+        state.portraitRotation = this.portraitRotation;
+        state.landscapeRotation = this.landscapeRotation;
+        state.bitsPerPixel = this.bitsPerPixel;
+        state.colorImages = this.colorImages;
+        state.resolution = this.resolution;
+        return state;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
+        + ", landscapeRotation=" + landscapeRotation
+        + ", colorImages=" + colorImages
+        + ", bitsPerPixel=" + bitsPerPixel
+        + ", resolution=" + resolution
+        + ", pageState=" + pagePaintingState
+        + super.toString()
+        + "}";
+    }
+
+    /**
+     * Page level state data
+     */
+    private class AFPPagePaintingState implements Cloneable {
+        /** page width */
+        private int width = 0;
+
+        /** page height */
+        private int height = 0;
+
+        /** page fonts */
+        private AFPPageFonts fonts = new AFPPageFonts();
+
+        /** page font count */
+        private int fontCount = 0;
+
+        /** page orientation */
+        private int orientation = 0;
+
+        /**
+         * Returns the page width
+         *
+         * @return the page width
+         */
+        protected int getWidth() {
+            return width;
+        }
+
+        /**
+         * Sets the page width
+         *
+         * @param width the page width
+         */
+        protected void setWidth(int width) {
+            this.width = width;
+        }
+
+        /**
+         * Returns the page height
+         *
+         * @return the page height
+         */
+        protected int getHeight() {
+            return height;
+        }
+
+        /**
+         * Sets the page height
+         *
+         * @param height the page height
+         */
+        protected void setHeight(int height) {
+            this.height = height;
+        }
+
+        /**
+         * Returns the page fonts
+         *
+         * @return the page fonts
+         */
+        protected AFPPageFonts getFonts() {
+            return fonts;
+        }
+
+        /**
+         * Sets the current page fonts
+         *
+         * @param fonts the current page fonts
+         */
+        protected void setFonts(AFPPageFonts fonts) {
+            this.fonts = fonts;
+        }
+
+        /**
+         * Increments and returns the current page font count
+         *
+         * @return increment and return the current page font count
+         */
+        protected int incrementFontCount() {
+            return ++fontCount;
+        }
+
+        /**
+         * Returns the current page orientation
+         *
+         * @return the current page orientation
+         */
+        protected int getOrientation() {
+            return orientation;
+        }
+
+        /**
+         * Sets the current page orientation
+         *
+         * @param orientation the current page orientation
+         */
+        protected void setOrientation(int orientation) {
+            this.orientation = orientation;
+        }
+
+        /** {@inheritDoc} */
+        public Object clone() {
+            AFPPagePaintingState state = new AFPPagePaintingState();
+            state.width = this.width;
+            state.height = this.height;
+            state.orientation = this.orientation;
+            state.fonts = new AFPPageFonts(this.fonts);
+            state.fontCount = this.fontCount;
+            return state;
+        }
+
+        /** {@inheritDoc} */
+        public String toString() {
+            return "AFPPagePaintingState{width=" + width
+            + ", height=" + height
+            + ", orientation=" + orientation
+            + ", fonts=" + fonts
+            + ", fontCount=" + fontCount
+            + "}";
+        }
+    }
+
+    /**
+     * Block level state data
+     */
+    private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
+        private static final long serialVersionUID = -1789481244175275686L;
+
+        /** The current fill status */
+        private boolean filled = false;
+
+        private String imageUri = null;
+
+        /** {@inheritDoc} */
+        public Object clone() {
+            AFPData obj = (AFPData)super.clone();
+            obj.filled = this.filled;
+            obj.imageUri = this.imageUri;
+            return obj;
+        }
+
+        /** {@inheritDoc} */
+        public String toString() {
+            return "AFPData{" + super.toString()
+            + ", filled=" + filled
+            + ", imageUri=" + imageUri
+            + "}";
+        }
+
+        /** {@inheritDoc} */
+        protected AbstractData instantiate() {
+            return new AFPData();
+        }
+    }
+
+}
\ No newline at end of file
index 56c60b44026dc00a3873c86b407f2b548ac5b969..81915a19017b7806c728405267f334a761c0990c 100644 (file)
@@ -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);
     }
 
index 85cdefb4b7ca3fb866d0f7dffc0911a1170412f3..5e8d54aaeaecc36d81062ecc8d10eb0c151ced2d 100644 (file)
@@ -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;
index 111238be8455c093276101ccb0f9bf42f57a1041..c912b8b173177628b19ed1a6c4ea71d1832c3266 100644 (file)
@@ -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/AFPState.java b/src/java/org/apache/fop/afp/AFPState.java
deleted file mode 100644 (file)
index 7e63ea0..0000000
+++ /dev/null
@@ -1,517 +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.AbstractData;
-import org.apache.fop.AbstractState;
-
-/**
- * This keeps information about the current state when writing to an AFP datastream.
- */
-public class AFPState extends org.apache.fop.AbstractState implements Cloneable {
-
-    private static final long serialVersionUID = 8206711712452344473L;
-
-    private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
-
-    /** the portrait rotation */
-    private int portraitRotation = 0;
-
-    /** the landscape rotation */
-    private int landscapeRotation = 270;
-
-    /** color image support */
-    private boolean colorImages = false;
-
-    /** images are supported in this AFP environment */
-    private boolean nativeImages = false;
-
-    /** default value for image depth */
-    private int bitsPerPixel = 8;
-
-    /** the output resolution */
-    private int resolution = 240; // 240 dpi
-
-    /** the current page */
-    private AFPPageState pageState = new AFPPageState();
-
-//    /** reference orientation */
-//    private int orientation = 0;
-
-    /** a unit converter */
-    private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
-
-    /**
-     * Sets the rotation to be used for portrait pages, valid values are 0
-     * (default), 90, 180, 270.
-     *
-     * @param rotation
-     *            The rotation in degrees.
-     */
-    public void setPortraitRotation(int rotation) {
-        if (rotation == 0 || rotation == 90 || rotation == 180
-                || rotation == 270) {
-            portraitRotation = rotation;
-        } else {
-            throw new IllegalArgumentException(
-                    "The portrait rotation must be one"
-                            + " of the values 0, 90, 180, 270");
-
-        }
-    }
-
-    /**
-     * Returns the rotation to be used for portrait pages
-     *
-     * @return the rotation to be used for portrait pages
-     */
-    protected int getPortraitRotation() {
-        return this.portraitRotation;
-    }
-
-    /**
-     * Sets the rotation to be used for landscape pages, valid values are 0, 90,
-     * 180, 270 (default).
-     *
-     * @param rotation
-     *            The rotation in degrees.
-     */
-    public void setLandscapeRotation(int rotation) {
-        if (rotation == 0 || rotation == 90 || rotation == 180
-                || rotation == 270) {
-            landscapeRotation = rotation;
-        } else {
-            throw new IllegalArgumentException(
-                    "The landscape rotation must be one"
-                            + " of the values 0, 90, 180, 270");
-        }
-    }
-
-    /**
-     * Returns the landscape rotation
-     *
-     * @return the landscape rotation
-     */
-    protected int getLandscapeRotation() {
-        return this.landscapeRotation;
-    }
-
-    /**
-     * Sets the number of bits used per pixel
-     *
-     * @param bitsPerPixel
-     *            number of bits per pixel
-     */
-    public void setBitsPerPixel(int bitsPerPixel) {
-        switch (bitsPerPixel) {
-        case 1:
-        case 4:
-        case 8:
-            this.bitsPerPixel = bitsPerPixel;
-            break;
-        default:
-            log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
-            this.bitsPerPixel = 8;
-            break;
-        }
-    }
-
-    /**
-     * Returns the number of bits per pixel
-     *
-     * @return the number of bits per pixel
-     */
-    public int getBitsPerPixel() {
-        return this.bitsPerPixel;
-    }
-
-    /**
-     * Sets whether images are color or not
-     *
-     * @param colorImages
-     *            color image output
-     */
-    public void setColorImages(boolean colorImages) {
-        this.colorImages = colorImages;
-    }
-
-    /**
-     * Returns true if color images are to be used
-     *
-     * @return true if color images are to be used
-     */
-    public boolean isColorImages() {
-        return this.colorImages;
-    }
-
-    /**
-     * Sets whether images are natively supported or not in the AFP environment
-     *
-     * @param nativeImages true if images are natively supported in this AFP environment
-     */
-    public void setNativeImages(boolean nativeImages) {
-        this.nativeImages = nativeImages;
-    }
-
-    /**
-     * Returns true if images are supported natively in this AFP environment
-     *
-     * @return true if images are supported natively in this AFP environment
-     */
-    public boolean isNativeImages() {
-        return this.nativeImages;
-    }
-
-    /**
-     * Sets the output/device resolution
-     *
-     * @param resolution
-     *            the output resolution (dpi)
-     */
-    public void setResolution(int resolution) {
-        if (log.isDebugEnabled()) {
-            log.debug("renderer-resolution set to: " + resolution + "dpi");
-        }
-        this.resolution = resolution;
-    }
-
-    /**
-     * Returns the output/device resolution.
-     *
-     * @return the resolution in dpi
-     */
-    public int getResolution() {
-        return this.resolution;
-    }
-
-    /** {@inheritDoc} */
-    protected AbstractData instantiateData() {
-        return new AFPData();
-    }
-
-    /** {@inheritDoc} */
-    protected AbstractState instantiateState() {
-        return new AFPState();
-    }
-
-    /**
-     * Returns the state of the current page
-     *
-     * @return the state of the current page
-     */
-    protected AFPPageState getPageState() {
-        return this.pageState;
-    }
-
-    /**
-     * Sets if the current painted shape is to be filled
-     *
-     * @param fill true if the current painted shape is to be filled
-     * @return true if the fill value has changed
-     */
-    protected boolean setFill(boolean fill) {
-        if (fill != ((AFPData)getData()).filled) {
-            ((AFPData)getData()).filled = fill;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Gets the current page fonts
-     *
-     * @return the current page fonts
-     */
-    public AFPPageFonts getPageFonts() {
-        return pageState.getFonts();
-    }
-
-    /**
-     * Increments and returns the page font count
-     *
-     * @return the page font count
-     */
-    public int incrementPageFontCount() {
-        return pageState.incrementFontCount();
-    }
-
-    /**
-     * Sets the page width
-     *
-     * @param pageWidth the page width
-     */
-    public void setPageWidth(int pageWidth) {
-        pageState.setWidth(pageWidth);
-    }
-
-    /**
-     * Returns the page width
-     *
-     * @return the page width
-     */
-    public int getPageWidth() {
-        return pageState.getWidth();
-    }
-
-    /**
-     * Sets the page height
-     *
-     * @param pageHeight the page height
-     */
-    public void setPageHeight(int pageHeight) {
-        pageState.setHeight(pageHeight);
-    }
-
-    /**
-     * Returns the page height
-     *
-     * @return the page height
-     */
-    public int getPageHeight() {
-        return pageState.getHeight();
-    }
-
-    /**
-     * Returns the page rotation
-     *
-     * @return the page rotation
-     */
-    public int getPageRotation() {
-        return pageState.getOrientation();
-    }
-
-    /**
-     * Sets the uri of the current image
-     *
-     * @param uri the uri of the current image
-     */
-    public void setImageUri(String uri) {
-        ((AFPData)getData()).imageUri = uri;
-    }
-
-    /**
-     * Gets the uri of the current image
-     *
-     * @return the uri of the current image
-     */
-    public String getImageUri() {
-        return ((AFPData)getData()).imageUri;
-    }
-
-    /**
-     * Returns the currently derived rotation
-     *
-     * @return the currently derived rotation
-     */
-    public int getRotation() {
-        return getData().getDerivedRotation();
-    }
-
-    /**
-     * Returns the unit converter
-     *
-     * @return the unit converter
-     */
-    public AFPUnitConverter getUnitConverter() {
-        return this.unitConv;
-    }
-
-    /** {@inheritDoc} */
-    public Object clone() {
-        AFPState state = (AFPState)super.clone();
-        state.pageState = (AFPPageState)this.pageState.clone();
-        state.portraitRotation = this.portraitRotation;
-        state.landscapeRotation = this.landscapeRotation;
-        state.bitsPerPixel = this.bitsPerPixel;
-        state.colorImages = this.colorImages;
-        state.resolution = this.resolution;
-        return state;
-    }
-
-    /** {@inheritDoc} */
-    public String toString() {
-        return "AFPState{" + "portraitRotation=" + portraitRotation
-        + ", landscapeRotation=" + landscapeRotation
-        + ", colorImages=" + colorImages
-        + ", bitsPerPixel=" + bitsPerPixel
-        + ", resolution=" + resolution
-        + ", pageState=" + pageState
-        + super.toString()
-        + "}";
-    }
-
-    /**
-     * Page level state data
-     */
-    private class AFPPageState implements Cloneable {
-        /** page width */
-        private int width = 0;
-
-        /** page height */
-        private int height = 0;
-
-        /** page fonts */
-        private AFPPageFonts fonts = new AFPPageFonts();
-
-        /** page font count */
-        private int fontCount = 0;
-
-        /** page orientation */
-        private int orientation = 0;
-
-        /**
-         * Returns the page width
-         *
-         * @return the page width
-         */
-        protected int getWidth() {
-            return width;
-        }
-
-        /**
-         * Sets the page width
-         *
-         * @param width the page width
-         */
-        protected void setWidth(int width) {
-            this.width = width;
-        }
-
-        /**
-         * Returns the page height
-         *
-         * @return the page height
-         */
-        protected int getHeight() {
-            return height;
-        }
-
-        /**
-         * Sets the page height
-         *
-         * @param height the page height
-         */
-        protected void setHeight(int height) {
-            this.height = height;
-        }
-
-        /**
-         * Returns the page fonts
-         *
-         * @return the page fonts
-         */
-        protected AFPPageFonts getFonts() {
-            return fonts;
-        }
-
-        /**
-         * Sets the current page fonts
-         *
-         * @param fonts the current page fonts
-         */
-        protected void setFonts(AFPPageFonts fonts) {
-            this.fonts = fonts;
-        }
-
-        /**
-         * Increments and returns the current page font count
-         *
-         * @return increment and return the current page font count
-         */
-        protected int incrementFontCount() {
-            return ++fontCount;
-        }
-
-        /**
-         * Returns the current page orientation
-         *
-         * @return the current page orientation
-         */
-        protected int getOrientation() {
-            return orientation;
-        }
-
-        /**
-         * Sets the current page orientation
-         *
-         * @param orientation the current page orientation
-         */
-        protected void setOrientation(int orientation) {
-            this.orientation = orientation;
-        }
-
-        /** {@inheritDoc} */
-        public Object clone() {
-            AFPPageState state = new AFPPageState();
-            state.width = this.width;
-            state.height = this.height;
-            state.orientation = this.orientation;
-            state.fonts = new AFPPageFonts(this.fonts);
-            state.fontCount = this.fontCount;
-            return state;
-        }
-
-        /** {@inheritDoc} */
-        public String toString() {
-            return "AFPPageState{width=" + width
-            + ", height=" + height
-            + ", orientation=" + orientation
-            + ", fonts=" + fonts
-            + ", fontCount=" + fontCount
-            + "}";
-        }
-    }
-
-    /**
-     * Block level state data
-     */
-    private class AFPData extends org.apache.fop.AbstractData {
-        private static final long serialVersionUID = -1789481244175275686L;
-
-        /** The current fill status */
-        private boolean filled = false;
-
-        private String imageUri = null;
-
-        /** {@inheritDoc} */
-        public Object clone() {
-            AFPData obj = (AFPData)super.clone();
-            obj.filled = this.filled;
-            obj.imageUri = this.imageUri;
-            return obj;
-        }
-
-        /** {@inheritDoc} */
-        public String toString() {
-            return "AFPData{" + super.toString()
-            + ", filled=" + filled
-            + ", imageUri=" + imageUri
-            + "}";
-        }
-
-        /** {@inheritDoc} */
-        protected AbstractData instantiate() {
-            return new AFPData();
-        }
-    }
-
-}
\ No newline at end of file
index 42dcf44120fd03fe1082996b5cc9ca1d46abca50..1d9367ef654f2c1cf40bb39e64da8a350a87bddb 100644 (file)
@@ -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");
index 3dee6ca2e6d3a538ebe9f3558390ac95d8ed1e2f..3f5ff7b3386e9b43ff76dca382b1bd7dbc1e5b16 100644 (file)
@@ -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);
         }
index 69282fc181be163a4300816f6c8da18a6636585a..c5f37d25f7a02687226897e3a03fbfaa39e4afc1 100644 (file)
@@ -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;
     }
 
index ba6d49fc67bda1a91f521f57defee4f320ac4e41..72c6c56e19a0205aa68c47617895998ae62e3834 100644 (file)
@@ -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;
     }
index 840d7b4e85720dc762486008ff0cb9a30842efcd..ef74263305aee2d4fc1910fd8ded7a513e04634c 100644 (file)
@@ -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 (file)
index 0000000..1a2883e
--- /dev/null
@@ -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
index 27147d511a9bc9e346ec5e572ac190e60e09d472..fc8ce0944ef9e7722ea15acd32314d1bb0d01088 100644 (file)
@@ -25,6 +25,7 @@ import java.io.OutputStream;
 import org.apache.fop.afp.modca.AbstractStructuredAFPObject;
 
 /**
+ * An IOCA Image Content
  */
 public class ImageContent extends AbstractStructuredAFPObject {
 
index c1c5e12a736775eeb0f136ac633366b308f86fff..00d2b6f163b5915b2df64d1e658404abce4bd556 100644 (file)
@@ -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 (file)
index 9830330..0000000
+++ /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 (file)
index 0000000..87907ed
--- /dev/null
@@ -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
index 40dc600be6aa5ce8b66525cec2697525b69740ca..81c12a628d4bcea8e8e96f86adf9b5e67069513b 100644 (file)
@@ -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/PDFPaintingState.java b/src/java/org/apache/fop/pdf/PDFPaintingState.java
new file mode 100644 (file)
index 0000000..7dd876c
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * 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.pdf;
+
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.util.Iterator;
+
+import org.apache.fop.util.AbstractPaintingState;
+
+/**
+ * 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.
+ *
+ * When setting the state for pdf there are three possible ways of
+ * handling the situation.
+ * The values can be set to override previous or default values.
+ * A new state can be added and then the values set.
+ * The current state can be popped and values will return to a
+ * previous state then the necessary values can be overridden.
+ * The current transform behaves differently to other values as the
+ * matrix is combined with the current resolved value.
+ * It is impossible to optimise the result without analysing the all
+ * the possible combinations after completing.
+ */
+public class PDFPaintingState extends org.apache.fop.util.AbstractPaintingState {
+
+    private static final long serialVersionUID = 5384726143906371279L;
+
+    /**
+     * PDF State for storing graphics state.
+     */
+    public PDFPaintingState() {
+    }
+
+    /**
+     * Set the current paint.
+     * This checks if the paint will change and then sets the current paint.
+     *
+     * @param p the new paint
+     * @return true if the new paint changes the current paint
+     */
+    public boolean setPaint(Paint p) {
+        Paint paint = ((PDFData)getData()).paint;
+        if (paint == null) {
+            if (p != null) {
+                ((PDFData)getData()).paint = p;
+                return true;
+            }
+        } else if (!paint.equals(p)) {
+            ((PDFData)getData()).paint = p;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if the clip will change the current state.
+     * A clip is assumed to be used in a situation where it will add
+     * to any clip in the current or parent states.
+     * A clip cannot be cleared, this can only be achieved by going to
+     * a parent level with the correct clip.
+     * If the clip is different then it may start a new state so that
+     * it can return to the previous clip.
+     *
+     * @param cl the clip shape to check
+     * @return true if the clip will change the current clip.
+     */
+    public boolean checkClip(Shape cl) {
+        Shape clip = ((PDFData)getData()).clip;
+        if (clip == null) {
+            if (cl != null) {
+                return true;
+            }
+        } else if (!new Area(clip).equals(new Area(cl))) {
+            return true;
+        }
+        //TODO check for clips that are larger than the current
+        return false;
+    }
+
+    /**
+     * Set the current clip.
+     * This either sets a new clip or sets the clip to the intersect of
+     * the old clip and the new clip.
+     *
+     * @param cl the new clip in the current state
+     */
+    public void setClip(Shape cl) {
+        Shape clip = ((PDFData)getData()).clip;
+        if (clip != null) {
+            Area newClip = new Area(clip);
+            newClip.intersect(new Area(cl));
+            ((PDFData)getData()).clip = new GeneralPath(newClip);
+        } else {
+            ((PDFData)getData()).clip = cl;
+        }
+    }
+
+    /**
+     * Get the current stack level.
+     *
+     * @return the current stack level
+     */
+    public int getStackLevel() {
+        return getStateStack().size();
+    }
+
+    /**
+     * Get the graphics state.
+     * This gets the combination of all graphic states for
+     * the current context.
+     * This is the graphic state set with the gs operator not
+     * the other graphic state changes.
+     *
+     * @return the calculated ExtGState in the current context
+     */
+    public PDFGState getGState() {
+        PDFGState defaultState = PDFGState.DEFAULT;
+
+        PDFGState state;
+        PDFGState newState = new PDFGState();
+        newState.addValues(defaultState);
+        for (Iterator it = getStateStack().iterator(); it.hasNext();) {
+            PDFData data = (PDFData)it.next();
+            state = data.gstate;
+            if (state != null) {
+                newState.addValues(state);
+            }
+        }
+        if (((PDFData)getData()).gstate != null) {
+            newState.addValues(((PDFData)getData()).gstate);
+        }
+        return newState;
+    }
+
+    /** {@inheritDoc} */
+    protected AbstractData instantiateData() {
+        return new PDFData();
+    }
+
+    /** {@inheritDoc} */
+    protected AbstractPaintingState instantiate() {
+        return new PDFPaintingState();
+    }
+
+    /**
+     * Push the current state onto the stack.
+     * This call should be used when the q operator is used
+     * so that the state is known when popped.
+     */
+    public void push() {
+        AbstractData data = getData();
+        AbstractData copy = (AbstractData)data.clone();
+        data.clearTransform();
+        getStateStack().add(copy);
+    }
+
+    private class PDFData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
+
+        private static final long serialVersionUID = 3527950647293177764L;
+
+        private Paint paint = null;
+        private Paint backPaint = null;
+        private int lineCap = 0;
+        private int lineJoin = 0;
+        private float miterLimit = 0;
+        private boolean text = false;
+        private int dashOffset = 0;
+        private Shape clip = null;
+        private PDFGState gstate = null;
+
+        /** {@inheritDoc} */
+        public Object clone() {
+            PDFData obj = (PDFData)super.clone();
+            obj.paint = this.paint;
+            obj.backPaint = this.paint;
+            obj.lineCap = this.lineCap;
+            obj.lineJoin = this.lineJoin;
+            obj.miterLimit = this.miterLimit;
+            obj.text = this.text;
+            obj.dashOffset = this.dashOffset;
+            obj.clip = this.clip;
+            obj.gstate = this.gstate;
+            return obj;
+        }
+
+        /** {@inheritDoc} */
+        public String toString() {
+            return super.toString()
+                + ", paint=" + paint
+                + ", backPaint=" + backPaint
+                + ", lineCap=" + lineCap
+                + ", miterLimit=" + miterLimit
+                + ", text=" + text
+                + ", dashOffset=" + dashOffset
+                + ", clip=" + clip
+                + ", gstate=" + gstate;
+        }
+
+        /** {@inheritDoc} */
+        protected AbstractData instantiate() {
+            return new PDFData();
+        }
+    }
+
+}
+
diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFState.java
deleted file mode 100644 (file)
index 3804c18..0000000
+++ /dev/null
@@ -1,230 +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.pdf;
-
-import java.awt.Paint;
-import java.awt.Shape;
-import java.awt.geom.Area;
-import java.awt.geom.GeneralPath;
-import java.util.Iterator;
-
-import org.apache.fop.AbstractData;
-import org.apache.fop.AbstractState;
-
-/**
- * This keeps information about the current 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.
- *
- * When setting the state for pdf there are three possible ways of
- * handling the situation.
- * The values can be set to override previous or default values.
- * A new state can be added and then the values set.
- * The current state can be popped and values will return to a
- * previous state then the necessary values can be overridden.
- * The current transform behaves differently to other values as the
- * matrix is combined with the current resolved value.
- * It is impossible to optimise the result without analysing the all
- * the possible combinations after completing.
- */
-public class PDFState extends org.apache.fop.AbstractState {
-
-    private static final long serialVersionUID = 5384726143906371279L;
-
-    /**
-     * PDF State for storing graphics state.
-     */
-    public PDFState() {
-    }
-
-    /**
-     * Set the current paint.
-     * This checks if the paint will change and then sets the current paint.
-     *
-     * @param p the new paint
-     * @return true if the new paint changes the current paint
-     */
-    public boolean setPaint(Paint p) {
-        Paint paint = ((PDFData)getData()).paint;
-        if (paint == null) {
-            if (p != null) {
-                ((PDFData)getData()).paint = p;
-                return true;
-            }
-        } else if (!paint.equals(p)) {
-            ((PDFData)getData()).paint = p;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Check if the clip will change the current state.
-     * A clip is assumed to be used in a situation where it will add
-     * to any clip in the current or parent states.
-     * A clip cannot be cleared, this can only be achieved by going to
-     * a parent level with the correct clip.
-     * If the clip is different then it may start a new state so that
-     * it can return to the previous clip.
-     *
-     * @param cl the clip shape to check
-     * @return true if the clip will change the current clip.
-     */
-    public boolean checkClip(Shape cl) {
-        Shape clip = ((PDFData)getData()).clip;
-        if (clip == null) {
-            if (cl != null) {
-                return true;
-            }
-        } else if (!new Area(clip).equals(new Area(cl))) {
-            return true;
-        }
-        //TODO check for clips that are larger than the current
-        return false;
-    }
-
-    /**
-     * Set the current clip.
-     * This either sets a new clip or sets the clip to the intersect of
-     * the old clip and the new clip.
-     *
-     * @param cl the new clip in the current state
-     */
-    public void setClip(Shape cl) {
-        Shape clip = ((PDFData)getData()).clip;
-        if (clip != null) {
-            Area newClip = new Area(clip);
-            newClip.intersect(new Area(cl));
-            ((PDFData)getData()).clip = new GeneralPath(newClip);
-        } else {
-            ((PDFData)getData()).clip = cl;
-        }
-    }
-
-    /**
-     * Get the current stack level.
-     *
-     * @return the current stack level
-     */
-    public int getStackLevel() {
-        return getStateStack().size();
-    }
-
-    /**
-     * Get the graphics state.
-     * This gets the combination of all graphic states for
-     * the current context.
-     * This is the graphic state set with the gs operator not
-     * the other graphic state changes.
-     *
-     * @return the calculated ExtGState in the current context
-     */
-    public PDFGState getGState() {
-        PDFGState defaultState = PDFGState.DEFAULT;
-
-        PDFGState state;
-        PDFGState newState = new PDFGState();
-        newState.addValues(defaultState);
-        for (Iterator it = getStateStack().iterator(); it.hasNext();) {
-            PDFData data = (PDFData)it.next();
-            state = data.gstate;
-            if (state != null) {
-                newState.addValues(state);
-            }
-        }
-        if (((PDFData)getData()).gstate != null) {
-            newState.addValues(((PDFData)getData()).gstate);
-        }
-        return newState;
-    }
-
-    /** {@inheritDoc} */
-    protected AbstractData instantiateData() {
-        return new PDFData();
-    }
-
-    /** {@inheritDoc} */
-    protected AbstractState instantiateState() {
-        return new PDFState();
-    }
-
-    /**
-     * Push the current state onto the stack.
-     * This call should be used when the q operator is used
-     * so that the state is known when popped.
-     */
-    public void push() {
-        AbstractData data = getData();
-        AbstractData copy = (AbstractData)data.clone();
-        data.clearTransform();
-        getStateStack().add(copy);
-    }
-
-    private class PDFData extends org.apache.fop.AbstractData {
-
-        private static final long serialVersionUID = 3527950647293177764L;
-
-        private Paint paint = null;
-        private Paint backPaint = null;
-        private int lineCap = 0;
-        private int lineJoin = 0;
-        private float miterLimit = 0;
-        private boolean text = false;
-        private int dashOffset = 0;
-        private Shape clip = null;
-        private PDFGState gstate = null;
-
-        /** {@inheritDoc} */
-        public Object clone() {
-            PDFData obj = (PDFData)super.clone();
-            obj.paint = this.paint;
-            obj.backPaint = this.paint;
-            obj.lineCap = this.lineCap;
-            obj.lineJoin = this.lineJoin;
-            obj.miterLimit = this.miterLimit;
-            obj.text = this.text;
-            obj.dashOffset = this.dashOffset;
-            obj.clip = this.clip;
-            obj.gstate = this.gstate;
-            return obj;
-        }
-
-        /** {@inheritDoc} */
-        public String toString() {
-            return super.toString()
-                + ", paint=" + paint
-                + ", backPaint=" + backPaint
-                + ", lineCap=" + lineCap
-                + ", miterLimit=" + miterLimit
-                + ", text=" + text
-                + ", dashOffset=" + dashOffset
-                + ", clip=" + clip
-                + ", gstate=" + gstate;
-        }
-
-        /** {@inheritDoc} */
-        protected AbstractData instantiate() {
-            return new PDFData();
-        }
-    }
-
-}
-
index 0d6bf9be974741c081827562becd3721e1b09ae8..18cc81400aa145201ce44adefb812e130450ab29 100644 (file)
@@ -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);
     }
 
     /**
index e37d02b2bb3664b047b340986f7710d63ccaec82..5861fb04266e30c56a8106b428fa76dbcd8fbcb4 100644 (file)
@@ -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,
index 0c32204e2ecb1148c557f9d9a333c48de5bb140c..3b00804fcf987f5912c3d6c266dd95c92bb37b69 100644 (file)
@@ -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/AFPBatikGraphicsObjectPainter.java b/src/java/org/apache/fop/render/afp/AFPBatikGraphicsObjectPainter.java
deleted file mode 100644 (file)
index 0aa77d6..0000000
+++ /dev/null
@@ -1,72 +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.render.afp;
-
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.fop.afp.AFPAbstractGraphicsObjectPainter;
-import org.apache.fop.afp.AFPGraphics2D;
-
-/**
- * Paints SVG as a GOCA Graphics Object using Batik
- */
-public class AFPBatikGraphicsObjectPainter extends AFPAbstractGraphicsObjectPainter {
-
-    /** the batik root node of the svg document */
-    private GraphicsNode root;
-
-    /**
-     * Main constructor
-     *
-     * @param graphics an AFP graphics 2D implementation
-     */
-    public AFPBatikGraphicsObjectPainter(AFPGraphics2D graphics) {
-        super(graphics);
-    }
-
-    /**
-     * Sets the graphics node
-     *
-     * @param rootNode the graphics root node
-     */
-    public void setGraphicsNode(GraphicsNode rootNode) {
-        this.root = rootNode;
-    }
-
-    /** {@inheritDoc} */
-    public void paint(Graphics2D g2d, Rectangle2D area) {
-        log.debug("Painting SVG using GOCA");
-
-        // tell batik to paint the graphics object
-        root.paint(g2d);
-
-        // dispose of the graphics 2d implementation
-        g2d.dispose();
-    }
-
-    /** {@inheritDoc} */
-    public Dimension getImageSize() {
-        return null;
-    }
-
-}
index dcf07426284f8217e437f3d9e854b98bb3daedd3..ba2392835d1b53a19be4aa44ec74357ef52f6e7a 100644 (file)
@@ -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;
     }
 
index 4211fe3604661162c41a58a61b79f06af31e1d83..aac17b701faad85dfe3e0de2bfcb921efcc19449 100644 (file)
@@ -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();
     }
index 453e16429078a71f5c79eb3df5474b91702c5064..4f92826cf5b4764a95f65fb8d80615a24eef367b 100644 (file)
@@ -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);
         }
 
index da9a37b7668b196d8e08c54e06cb0bbac1715072..88c0b5c261c0970a46bcea927666e7a0f7b27594 100644 (file)
 
 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;
     }
 
 }
index 19504f6c9fe463ddb4ae33a394054ab28cff9d6a..376bee7b95b10ae038aa4312db4885cea96be2e6 100644 (file)
@@ -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);
     }
 
index 9c59e8b8395b4ee9b24a0c9d56aa360d779bbaf2..59d6af9a8641ee37d6584b0c48575bb38412dfcb 100644 (file)
@@ -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);
     }
 
index 5fd59c2aa2f0357f1b856e39f2c99c0d5e1f0921..1059014aba02e5d1bceda090ae94fe319e0dadd5 100644 (file)
@@ -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;
     }
 
index 17aff9fc0fcb63dbcbb4a070b924c530a83ade0b..2e6eca6aefe478894dbc2935149aab813423c1a7 100644 (file)
@@ -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);
     }
 
index 03945dfeec03b412bf1a69323ad322d302466a6f..87c098a8958d433d590945fdc104039e9510d14a 100644 (file)
@@ -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;
     }
 
     /**
index 72be2648314a688376b52215363fc49beed8ea7d..3302b7f3ce30e3d0e028183955369baf278f8df0 100644 (file)
@@ -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";
 }
index de2786215095df578024f88ca536931d365a5740..3bdab289cf899c22496a8bae6846bb5135f1e6e6 100644 (file)
@@ -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/GraphicsObjectPainterAFP.java b/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java
new file mode 100644 (file)
index 0000000..7eb2c10
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.gvt.GraphicsNode;
+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 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;
+
+    /**
+     * Main constructor
+     *
+     * @param graphics an AFP graphics 2D implementation
+     */
+    public GraphicsObjectPainterAFP(AFPGraphics2D graphics) {
+        final boolean textAsShapes = false;
+        this.graphics2D = new AFPGraphics2D(textAsShapes);
+    }
+
+    /**
+     * Sets the graphics node
+     *
+     * @param rootNode the graphics root node
+     */
+    public void setGraphicsNode(GraphicsNode rootNode) {
+        this.root = rootNode;
+    }
+
+    /** {@inheritDoc} */
+    public void paint(Graphics2D g2d, Rectangle2D area) {
+        log.debug("Painting SVG using GOCA");
+
+        // tell batik to paint the graphics object
+        root.paint(g2d);
+
+        // dispose of the graphics 2d implementation
+        g2d.dispose();
+    }
+
+    /** {@inheritDoc} */
+    public Dimension getImageSize() {
+        return null;
+    }
+
+    /**
+     * Sets the GOCA Graphics Object
+     *
+     * @param graphicsObject the GOCA Graphics Object
+     */
+    public void setGraphicsObject(GraphicsObject graphicsObject) {
+        this.graphics2D.setGraphicsObject(graphicsObject);
+    }
+
+}
index 6ed45ca98285a2f944cfba1449d6f6f19ea329be..ba5c860594a24d5b6e085496b57f36d577d36217 100644 (file)
@@ -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;
index 2aa11227abc8c3ba882a5fb3515e92883e1e5f4c..01d863e6a3bd9fb96ca351abe53a9a1e1f6f5fde 100644 (file)
@@ -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) {
index 9f60d3c862d50788ef701e7cfd131565912324d8..0eba2fe91e93cfc45bfa35168f6d78d665d13eb9 100644 (file)
@@ -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);
     }
index de51aabc70f193d353131c529a1d97d9898b34f8..33888d44228e1e65833842f332790ac78160966d 100644 (file)
@@ -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";
index e316281600318269ede3fcd1d9093bece04e3db7..e83579728deb85aea28179fa8a79cf1b6fe3cb5d 100644 (file)
@@ -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");
     }
index dd13df1c49375202400580d31949c56fb48e273c..cc6e06978c4926e38e4a9706a698f648772f971c 100644 (file)
 
 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();
     }
index cd0a4133b8c2d330fbc1888a68a2c097162f8c11..179ebb90abe42424f0bf643d01b64fa10962f2c1 100644 (file)
@@ -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/util/AbstractPaintingState.java b/src/java/org/apache/fop/util/AbstractPaintingState.java
new file mode 100644 (file)
index 0000000..e712ce7
--- /dev/null
@@ -0,0 +1,530 @@
+/*
+ * 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.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;
+
+
+/**
+ * A base class which holds information about the current rendering state.
+ */
+public abstract class AbstractPaintingState implements Cloneable, Serializable {
+
+    private static final long serialVersionUID = 5998356138437094188L;
+
+    /** current state data */
+    private AbstractData data = null;
+
+    /** the state stack */
+    private StateStack/*<AbstractData>*/ stateStack = new StateStack/*<AbstractData>*/();
+
+    /**
+     * Instantiates a new state data object
+     *
+     * @return a new state data object
+     */
+    protected abstract AbstractData instantiateData();
+
+    /**
+     * Instantiates a new state object
+     *
+     * @return a new state object
+     */
+    protected abstract AbstractPaintingState instantiate();
+
+    /**
+     * Returns the currently valid state
+     *
+     * @return the currently valid state
+     */
+    public AbstractData getData() {
+        if (data == null) {
+            data = instantiateData();
+        }
+        return data;
+    }
+
+    /**
+     * Set the current color.
+     * Check if the new color is a change and then set the current color.
+     *
+     * @param col the color to set
+     * @return true if the color has changed
+     */
+    public boolean setColor(Color col) {
+        if (!col.equals(getData().color)) {
+            getData().color = col;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the color.
+     *
+     * @return the color
+     */
+    public Color getColor() {
+        if (getData().color == null) {
+            getData().color = Color.black;
+        }
+        return getData().color;
+    }
+
+    /**
+     * Get the background color.
+     *
+     * @return the background color
+     */
+    public Color getBackColor() {
+        if (getData().backColor == null) {
+            getData().backColor = Color.white;
+        }
+        return getData().backColor;
+    }
+
+    /**
+     * Set the current background color.
+     * Check if the new background color is a change and then set the current background color.
+     *
+     * @param col the background color to set
+     * @return true if the color has changed
+     */
+    public boolean setBackColor(Color col) {
+        if (!col.equals(getData().backColor)) {
+            getData().backColor = col;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Set the current font name
+     *
+     * @param internalFontName the internal font name
+     * @return true if the font name has changed
+     */
+    public boolean setFontName(String internalFontName) {
+        if (!internalFontName.equals(getData().fontName)) {
+            getData().fontName = internalFontName;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets the current font name
+     *
+     * @return the current font name
+     */
+    public String getFontName() {
+        return getData().fontName;
+    }
+
+    /**
+     * Gets the current font size
+     *
+     * @return the current font size
+     */
+    public int getFontSize() {
+        return getData().fontSize;
+    }
+
+    /**
+     * Set the current font size.
+     * Check if the font size is a change and then set the current font size.
+     *
+     * @param size the font size to set
+     * @return true if the font size has changed
+     */
+    public boolean setFontSize(int size) {
+        if (size != getData().fontSize) {
+            getData().fontSize = size;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Set the current line width.
+     *
+     * @param width the line width in points
+     * @return true if the line width has changed
+     */
+    public boolean setLineWidth(float width) {
+        if (getData().lineWidth != width) {
+            getData().lineWidth = width;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the current line width
+     *
+     * @return the current line width
+     */
+    public float getLineWidth() {
+        return getData().lineWidth;
+    }
+
+    /**
+     * Sets the dash array (line type) for the current basic stroke
+     *
+     * @param dash the line dash array
+     * @return true if the dash array has changed
+     */
+    public boolean setDashArray(float[] dash) {
+        if (!Arrays.equals(dash, getData().dashArray)) {
+            getData().dashArray = dash;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the current transform.
+     * This gets the combination of all transforms in the
+     * current state.
+     *
+     * @return the calculate combined transform for the current state
+     */
+    public AffineTransform getTransform() {
+       AffineTransform at = new AffineTransform();
+       for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
+           AbstractData data = (AbstractData)iter.next();
+           AffineTransform stackTrans = data.getTransform();
+           at.concatenate(stackTrans);
+       }
+       AffineTransform currentTrans = getData().getTransform();
+       at.concatenate(currentTrans);
+       return at;
+    }
+
+    /**
+     * Check the current transform.
+     * The transform for the current state is the combination of all
+     * transforms in the current state. The parameter is compared
+     * against this current transform.
+     *
+     * @param tf the transform the check against
+     * @return true if the new transform is different then the current transform
+     */
+    public boolean checkTransform(AffineTransform tf) {
+        return !tf.equals(getData().getTransform());
+    }
+
+    /**
+     * Get a copy of the base transform for the page. Used to translate
+     * IPP/BPP values into X,Y positions when positioning is "fixed".
+     *
+     * @return the base transform, or null if the state stack is empty
+     */
+    public AffineTransform getBaseTransform() {
+       if (stateStack.isEmpty()) {
+           return null;
+       } else {
+           AbstractData baseData = (AbstractData)stateStack.get(0);
+           return (AffineTransform) baseData.getTransform().clone();
+       }
+    }
+
+    /**
+     * Concatenates the given AffineTransform to the current one.
+     *
+     * @param at the transform to concatenate to the current level transform
+     */
+    public void concatenate(AffineTransform at) {
+        getData().concatenate(at);
+    }
+
+    /**
+     * Resets the current AffineTransform to the Base AffineTransform.
+     */
+    public void resetTransform() {
+        getData().setTransform(getBaseTransform());
+    }
+
+    /**
+     * Clears the current AffineTransform to the Identity AffineTransform
+     */
+    public void clearTransform() {
+        getData().clearTransform();
+    }
+
+
+    /**
+     * 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.
+     */
+    public void push() {
+        AbstractData copy = (AbstractData)getData().clone();
+        stateStack.push(copy);
+    }
+
+    /**
+     * 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.
+     *
+     * @return the restored state, null if the stack is empty
+     */
+    public AbstractData pop() {
+        if (!stateStack.isEmpty()) {
+            setData((AbstractData)stateStack.pop());
+            return this.data;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Pushes all painting state data in the given list to the stack
+     *
+     * @param dataList a state data list
+     */
+    public void pushAll(List/*<AbstractData>*/ dataList) {
+        Iterator it = dataList.iterator();
+        while (it.hasNext()) {
+            // save current data on stack
+            push();
+            setData((AbstractData)it.next());
+        }
+    }
+
+    /**
+     * Pops all painting state data from the stack
+     *
+     * @return a list of state data popped from the stack
+     */
+    public List/*<AbstractData>*/ popAll() {
+        List/*<AbstractData>*/ dataList = new java.util.ArrayList/*<AbstractData>*/();
+        AbstractData data;
+        while (true) {
+            data = getData();
+            if (pop() == null) {
+                break;
+            }
+            // insert because of stack-popping
+            dataList.add(0, data);
+        }
+        return dataList;
+    }
+
+    /**
+     * Sets the current state data
+     *
+     * @param currentData state data
+     */
+    protected void setData(AbstractData data) {
+        this.data = data;
+    }
+
+    /**
+     * Clears the state stack
+     */
+    public void clear() {
+        stateStack.clear();
+        setData(null);
+    }
+
+    /**
+     * Return the state stack
+     *
+     * @return the state stack
+     */
+    protected Stack/*<AbstractData>*/ getStateStack() {
+        return this.stateStack;
+    }
+
+    /** {@inheritDoc} */
+    public Object clone() {
+        AbstractPaintingState state = instantiate();
+        state.stateStack = new StateStack(this.stateStack);
+        state.data = (AbstractData)this.data.clone();
+        return state;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        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;
+        }
+    }
+}