]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fix for test/layoutengine/standard-testcases/block-container_absolute-position_fixed...
authorAdrian Cumiskey <acumiskey@apache.org>
Fri, 31 Oct 2008 09:58:46 +0000 (09:58 +0000)
committerAdrian Cumiskey <acumiskey@apache.org>
Fri, 31 Oct 2008 09:58:46 +0000 (09:58 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@709373 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/AbstractData.java [new file with mode: 0644]
src/java/org/apache/fop/AbstractState.java
src/java/org/apache/fop/StateStack.java [new file with mode: 0644]
src/java/org/apache/fop/afp/AFPState.java
src/java/org/apache/fop/pdf/PDFState.java
src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
src/java/org/apache/fop/render/afp/AFPRenderer.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java

diff --git a/src/java/org/apache/fop/AbstractData.java b/src/java/org/apache/fop/AbstractData.java
new file mode 100644 (file)
index 0000000..b689165
--- /dev/null
@@ -0,0 +1,128 @@
+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
index 851c50e762955f87dc056433353cc154950a770d..74719e8f8ebb20934e07c926b331c933c9c4f861 100644 (file)
@@ -23,8 +23,8 @@ 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;
 
 
@@ -33,11 +33,13 @@ import java.util.Stack;
  */
 public abstract class AbstractState implements Cloneable, Serializable {
 
+    private static final long serialVersionUID = 5998356138437094188L;
+
     /** current state data */
-    private AbstractData currentData = null;
+    private AbstractData data = null;
 
     /** the state stack */
-    private StateStack stateStack = null;
+    private StateStack stateStack = new StateStack();
 
     /**
      * Instantiates a new state data object
@@ -59,10 +61,10 @@ public abstract class AbstractState implements Cloneable, Serializable {
      * @return the currently valid state
      */
     public AbstractData getData() {
-        if (currentData == null) {
-            currentData = instantiateData();
+        if (data == null) {
+            data = instantiateData();
         }
-        return currentData;
+        return data;
     }
 
     /**
@@ -212,7 +214,7 @@ public abstract class AbstractState implements Cloneable, Serializable {
      */
     public AffineTransform getTransform() {
        AffineTransform at = new AffineTransform();
-       for (Iterator iter = getStateStack().iterator(); iter.hasNext();) {
+       for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
            AbstractData data = (AbstractData)iter.next();
            AffineTransform stackTrans = data.getTransform();
            at.concatenate(stackTrans);
@@ -242,10 +244,10 @@ public abstract class AbstractState implements Cloneable, Serializable {
      * @return the base transform, or null if the state stack is empty
      */
     public AffineTransform getBaseTransform() {
-       if (getStateStack().isEmpty()) {
+       if (stateStack.isEmpty()) {
            return null;
        } else {
-           AbstractData baseData = (AbstractData)getStateStack().get(0);
+           AbstractData baseData = (AbstractData)stateStack.get(0);
            return (AffineTransform) baseData.getTransform().clone();
        }
     }
@@ -260,12 +262,20 @@ public abstract class AbstractState implements Cloneable, Serializable {
     }
 
     /**
-     * Resets the current AffineTransform.
+     * Resets the current AffineTransform to the Base AffineTransform.
      */
     public void resetTransform() {
-        getData().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
@@ -273,7 +283,7 @@ public abstract class AbstractState implements Cloneable, Serializable {
      */
     public void push() {
         AbstractData copy = (AbstractData)getData().clone();
-        getStateStack().push(copy);
+        stateStack.push(copy);
     }
 
     /**
@@ -284,20 +294,62 @@ public abstract class AbstractState implements Cloneable, Serializable {
      * @return the restored state, null if the stack is empty
      */
     public AbstractData pop() {
-        if (!getStateStack().isEmpty()) {
-            this.currentData = (AbstractData)getStateStack().pop();
-            return this.currentData;
+        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() {
-        getStateStack().clear();
-        currentData = null;
+        stateStack.clear();
+        setData(null);
     }
 
     /**
@@ -306,160 +358,20 @@ public abstract class AbstractState implements Cloneable, Serializable {
      * @return the state stack
      */
     protected Stack/*<AbstractData>*/ getStateStack() {
-        if (stateStack == null) {
-            stateStack = new StateStack();
-        }
-        return stateStack;
+        return this.stateStack;
     }
 
     /** {@inheritDoc} */
     public Object clone() {
         AbstractState state = instantiateState();
         state.stateStack = new StateStack(this.stateStack);
-        state.currentData = (AbstractData)this.currentData.clone();
+        state.data = (AbstractData)this.data.clone();
         return state;
     }
 
     /** {@inheritDoc} */
     public String toString() {
         return ", stateStack=" + stateStack
-        + ", currentData=" + currentData;
-    }
-
-    /**
-     * A base state data holding object
-     */
-    public abstract class AbstractData implements Cloneable, Serializable {
-
-        private static final long serialVersionUID = 5208418041189828624L;
-
-        /** The current color */
-        private Color color = null;
-
-        /** The current background color */
-        private Color backColor = null;
-
-        /** The current font name */
-        private String fontName = null;
-
-        /** The current font size */
-        private int fontSize = 0;
-
-        /** The current line width */
-        private float lineWidth = 0;
-
-        /** The dash array for the current basic stroke (line type) */
-        private float[] dashArray = null;
-
-        /** The current transform */
-        private AffineTransform transform = null;
-
-        /**
-         * 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;
-        }
-
-        /**
-         * Resets the current AffineTransform.
-         */
-        public void resetTransform() {
-            transform = getBaseTransform();
-//            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 = instantiateData();
-            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 copy constructor for java.util.Stack so extended and implemented one.
-     */
-    private 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);
-        }
+        + ", currentData=" + data;
     }
 }
diff --git a/src/java/org/apache/fop/StateStack.java b/src/java/org/apache/fop/StateStack.java
new file mode 100644 (file)
index 0000000..0c73b48
--- /dev/null
@@ -0,0 +1,31 @@
+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
index 9de3a0c058800b3c9d339ee752f228fad2d0d605..7e63ea01e462797c3127618021e2293290f05b61 100644 (file)
@@ -21,6 +21,7 @@ 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;
 
 /**
@@ -483,7 +484,7 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable
     /**
      * Block level state data
      */
-    private class AFPData extends org.apache.fop.AbstractState.AbstractData {
+    private class AFPData extends org.apache.fop.AbstractData {
         private static final long serialVersionUID = -1789481244175275686L;
 
         /** The current fill status */
@@ -506,6 +507,11 @@ public class AFPState extends org.apache.fop.AbstractState implements Cloneable
             + ", imageUri=" + imageUri
             + "}";
         }
+
+        /** {@inheritDoc} */
+        protected AbstractData instantiate() {
+            return new AFPData();
+        }
     }
 
 }
\ No newline at end of file
index 138458552e0f04dc930bdd3451041e54a65f4c66..3804c189a6ebc4a1da75fafba082267a45133fc1 100644 (file)
 
 package org.apache.fop.pdf;
 
-import java.util.Iterator;
 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;
 
 /**
@@ -165,7 +166,19 @@ public class PDFState extends org.apache.fop.AbstractState {
         return new PDFState();
     }
 
-    private class PDFData extends org.apache.fop.AbstractState.AbstractData {
+    /**
+     * 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;
 
@@ -206,6 +219,11 @@ public class PDFState extends org.apache.fop.AbstractState {
                 + ", clip=" + clip
                 + ", gstate=" + gstate;
         }
+
+        /** {@inheritDoc} */
+        protected AbstractData instantiate() {
+            return new PDFData();
+        }
     }
 
 }
index 0496cf7408cdb57cc7ed86c4282439a51965ece6..e74a8f31933b5b5902d7c13c1857e9e49390eabf 100644 (file)
@@ -486,14 +486,14 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
         CTM ctm = bv.getCTM();
         int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
 
-        if (bv.getPositioning() == Block.ABSOLUTE
-                || bv.getPositioning() == Block.FIXED) {
+        int positioning = bv.getPositioning();
+        if (positioning == Block.ABSOLUTE || positioning == Block.FIXED) {
 
             //For FIXED, we need to break out of the current viewports to the
             //one established by the page. We save the state stack for restoration
             //after the block-container has been painted. See below.
             List breakOutList = null;
-            if (bv.getPositioning() == Block.FIXED) {
+            if (positioning == Block.FIXED) {
                 breakOutList = breakOutOfStateStack();
             }
 
@@ -564,8 +564,11 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
                 restoreGraphicsState();
             }
 
-            if (breakOutList != null) {
-                restoreStateStackAfterBreakOut(breakOutList);
+            //For FIXED, we need to restore break out now we are done
+            if (positioning == Block.FIXED) {
+                if (breakOutList != null) {
+                    restoreStateStackAfterBreakOut(breakOutList);
+                }
             }
 
             currentIPPosition = saveIP;
index d0737ed707de6bfd0d7b51135d838ec11affc4fe..03945dfeec03b412bf1a69323ad322d302466a6f 100644 (file)
@@ -169,7 +169,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
 
     private AFPRectanglePainter rectanglePainter;
 
-
     /**
      * Constructor for AFPRenderer.
      */
@@ -509,28 +508,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
     /** {@inheritDoc} */
     public void restoreStateStackAfterBreakOut(List breakOutList) {
         log.debug("Block.FIXED --> restoring context after break-out");
-        AbstractState.AbstractData data;
-        Iterator it = breakOutList.iterator();
-        while (it.hasNext()) {
-            data = (AbstractState.AbstractData)it.next();
-            saveGraphicsState();
-            concatenateTransformationMatrix(data.getTransform());
-        }
+        state.pushAll(breakOutList);
     }
 
     /** {@inheritDoc} */
     protected List breakOutOfStateStack() {
         log.debug("Block.FIXED --> break out");
-        List breakOutList = new java.util.ArrayList();
-        AbstractState.AbstractData data;
-        while (true) {
-            data = state.getData();
-            if (state.pop() == null) {
-                break;
-            }
-            breakOutList.add(0, data); //Insert because of stack-popping
-        }
-        return breakOutList;
+        return state.popAll();
     }
 
     /** {@inheritDoc} */
index cc1caea03868ea8df83842ba3d224c76b169c53a..9f60d3c862d50788ef701e7cfd131565912324d8 100644 (file)
@@ -40,17 +40,7 @@ import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.io.IOUtils;
-
-import org.apache.xmlgraphics.image.loader.ImageException;
-import org.apache.xmlgraphics.image.loader.ImageInfo;
-import org.apache.xmlgraphics.image.loader.ImageManager;
-import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-import org.apache.xmlgraphics.image.loader.util.ImageUtil;
-import org.apache.xmlgraphics.xmp.Metadata;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
-
-import org.apache.fop.AbstractState;
+import org.apache.fop.AbstractData;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
@@ -118,6 +108,14 @@ import org.apache.fop.render.RendererContext;
 import org.apache.fop.util.CharUtilities;
 import org.apache.fop.util.ColorProfileUtil;
 import org.apache.fop.util.ColorUtil;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
+import org.apache.xmlgraphics.xmp.Metadata;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
 
 /**
  * Renderer that renders areas to PDF.
@@ -263,7 +261,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
     protected Map filterMap;
 
     /** Image handler registry */
-    private PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry();
+    private final PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry();
 
     /**
      * create the PDF renderer
@@ -1095,8 +1093,9 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      * @return the saved state stack to recreate later
      */
     protected List breakOutOfStateStack() {
+//        return currentState.popAll();
         List breakOutList = new java.util.ArrayList();
-        AbstractState.AbstractData data;
+        AbstractData data;
         while (true) {
             data = currentState.getData();
             if (currentState.pop() == null) {
@@ -1117,10 +1116,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      */
     protected void restoreStateStackAfterBreakOut(List breakOutList) {
         comment("------ restoring context after break-out...");
-        AbstractState.AbstractData data;
+//        currentState.pushAll(breakOutList);
+        AbstractData data;
         Iterator i = breakOutList.iterator();
         while (i.hasNext()) {
-            data = (AbstractState.AbstractData)i.next();
+            data = (AbstractData)i.next();
             saveGraphicsState();
             AffineTransform at = data.getTransform();
             concatenateTransformationMatrix(at);
@@ -1609,7 +1609,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
         endTextObject();
         putImage(url, pos, foreignAttributes);
     }
-     
+
     /**
      * Adds a PDF XObject (a bitmap or form) to the PDF that will later be referenced.
      * @param uri URL of the bitmap