aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2008-07-28 13:03:40 +0000
committerJeremias Maerki <jeremias@apache.org>2008-07-28 13:03:40 +0000
commit17214623febc22024f3cc24491b4ea7669697641 (patch)
treeb843978361d95f3f14068dad668a541ed78d36f9 /src/java/org/apache/fop
parent909b93a2b94ac18245103d7f5e6231b0595f6fcd (diff)
downloadxmlgraphics-fop-17214623febc22024f3cc24491b4ea7669697641.tar.gz
xmlgraphics-fop-17214623febc22024f3cc24491b4ea7669697641.zip
Fixed block containers now working properly.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@680339 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
-rw-r--r--src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java3
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFGraphicContext.java110
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFRenderer.java222
3 files changed, 291 insertions, 44 deletions
diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
index bf9f660be..4805d4df9 100644
--- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
@@ -469,7 +469,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
}
- private static final QName FOX_TRANSFORM
+ /** Constant for the fox:transform extension attribute */
+ protected static final QName FOX_TRANSFORM
= new QName(ExtensionElementMapping.URI, "fox:transform");
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java b/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
index ce48775b1..6183bbbad 100644
--- a/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
+++ b/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
@@ -19,11 +19,19 @@
package org.apache.fop.render.intermediate;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.util.List;
+
import org.apache.xmlgraphics.java2d.GraphicContext;
+/**
+ * Specialized graphic context class for the intermediate format renderer.
+ */
public class IFGraphicContext extends GraphicContext {
- private int groupDepth;
+ private List groupList = new java.util.ArrayList();
/**
* Default constructor.
@@ -46,15 +54,103 @@ public class IFGraphicContext extends GraphicContext {
return new IFGraphicContext(this);
}
- public void startGroup() {
- this.groupDepth++;
+ public void pushGroup(Group group) {
+ //this.groupDepth++;
+ this.groupList.add(group);
+ for (int i = 0, c = group.getTransforms().length; i < c; i++) {
+ transform(group.getTransforms()[i]);
+ }
+ }
+
+ public Group[] getGroups() {
+ return (Group[])this.groupList.toArray(new Group[getGroupStackSize()]);
}
- public void endGroup() {
- this.groupDepth--;
+ public Group[] dropGroups() {
+ Group[] groups = getGroups();
+ this.groupList.clear();
+ return groups;
+ }
+
+ public int getGroupStackSize() {
+ return this.groupList.size();
+ }
+
+ public static class Group {
+
+ private AffineTransform[] transforms;
+
+ public Group(AffineTransform[] transforms) {
+ this.transforms = transforms;
+ }
+
+ public Group(AffineTransform transform) {
+ this(new AffineTransform[] {transform});
+ }
+
+ public AffineTransform[] getTransforms() {
+ return this.transforms;
+ }
+
+ public void start(IFPainter painter) throws IFException {
+ painter.startGroup(transforms);
+ }
+
+ public void end(IFPainter painter) throws IFException {
+ painter.endGroup();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("group: ");
+ AbstractXMLWritingIFPainter.toString(getTransforms(), sb);
+ return sb.toString();
+ }
+
}
- public int getGroupDepth() {
- return this.groupDepth;
+ public static class Viewport extends Group {
+
+ private Dimension size;
+ private Rectangle clipRect;
+
+ public Viewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) {
+ super(transforms);
+ this.size = size;
+ this.clipRect = clipRect;
+ }
+
+ public Viewport(AffineTransform transform, Dimension size, Rectangle clipRect) {
+ this(new AffineTransform[] {transform}, size, clipRect);
+ }
+
+ public Dimension getSize() {
+ return this.size;
+ }
+
+ public Rectangle getClipRect() {
+ return this.clipRect;
+ }
+
+ public void start(IFPainter painter) throws IFException {
+ painter.startViewport(getTransforms(), size, clipRect);
+ }
+
+ public void end(IFPainter painter) throws IFException {
+ painter.endViewport();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("viewport: ");
+ AbstractXMLWritingIFPainter.toString(getTransforms(), sb);
+ sb.append(", ").append(getSize());
+ if (getClipRect() != null) {
+ sb.append(", ").append(getClipRect());
+ }
+ return sb.toString();
+ }
+
}
+
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
index 8935bf4e0..a8e0208f1 100644
--- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
@@ -34,6 +34,7 @@ import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
+import org.apache.batik.parser.AWTTransformProducer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -89,6 +90,7 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
private Stack graphicContextStack = new Stack();
private Stack viewportDimensionStack = new Stack();
private IFGraphicContext graphicContext = new IFGraphicContext();
+ //private Stack groupStack = new Stack();
private Metadata documentMetadata;
@@ -293,24 +295,45 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
/** {@inheritDoc} */
protected void restoreGraphicsState() {
- while (graphicContext.getGroupDepth() > 0) {
- try {
- painter.endGroup();
- } catch (IFException e) {
- handleIFException(e);
+ while (graphicContext.getGroupStackSize() > 0) {
+ IFGraphicContext.Group[] groups = graphicContext.dropGroups();
+ for (int i = groups.length - 1; i >= 0; i--) {
+ try {
+ groups[i].end(painter);
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
}
- graphicContext.endGroup();
}
graphicContext = (IFGraphicContext)graphicContextStack.pop();
}
+ private void pushGroup(IFGraphicContext.Group group) {
+ graphicContext.pushGroup(group);
+ try {
+ group.start(painter);
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
+ }
+
/** {@inheritDoc} */
protected List breakOutOfStateStack() {
log.debug("Block.FIXED --> break out");
List breakOutList = new java.util.ArrayList();
while (!this.graphicContextStack.empty()) {
+ //Handle groups
+ IFGraphicContext.Group[] groups = graphicContext.getGroups();
+ for (int j = groups.length - 1; j >= 0; j--) {
+ try {
+ groups[j].end(painter);
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
+ }
+
breakOutList.add(0, this.graphicContext);
- restoreGraphicsState();
+ graphicContext = (IFGraphicContext)graphicContextStack.pop();
}
return breakOutList;
}
@@ -319,25 +342,36 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
protected void restoreStateStackAfterBreakOut(List breakOutList) {
log.debug("Block.FIXED --> restoring context after break-out");
for (int i = 0, c = breakOutList.size(); i < c; i++) {
- saveGraphicsState();
+ graphicContextStack.push(graphicContext);
this.graphicContext = (IFGraphicContext)breakOutList.get(i);
+
+ //Handle groups
+ IFGraphicContext.Group[] groups = graphicContext.getGroups();
+ for (int j = 0, jc = groups.length; j < jc; j++) {
+ try {
+ groups[j].start(painter);
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
+ }
}
+ log.debug("restored.");
}
/** {@inheritDoc} */
protected void concatenateTransformationMatrix(AffineTransform at) {
if (!at.isIdentity()) {
+ concatenateTransformationMatrixMpt(ptToMpt(at));
+ }
+ }
+
+ private void concatenateTransformationMatrixMpt(AffineTransform at) {
+ if (!at.isIdentity()) {
if (log.isDebugEnabled()) {
log.debug("-----concatenateTransformationMatrix: " + at);
}
- AffineTransform atmpt = ptToMpt(at);
- graphicContext.transform(atmpt);
- graphicContext.startGroup();
- try {
- painter.startGroup(atmpt);
- } catch (IFException e) {
- handleIFException(e);
- }
+ IFGraphicContext.Group group = new IFGraphicContext.Group(at);
+ pushGroup(group);
}
}
@@ -361,9 +395,120 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
/** {@inheritDoc} */
protected void renderBlockViewport(BlockViewport bv, List children) {
+ //Essentially the same code as in the super class but optimized for the IF
+
+ //This is the content-rect
Dimension dim = new Dimension(bv.getIPD(), bv.getBPD());
viewportDimensionStack.push(dim);
- super.renderBlockViewport(bv, children);
+
+ // save positions
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+
+ CTM ctm = bv.getCTM();
+ int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
+ int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
+
+ if (bv.getPositioning() == Block.ABSOLUTE
+ || bv.getPositioning() == 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) {
+ breakOutList = breakOutOfStateStack();
+ }
+
+ AffineTransform positionTransform = new AffineTransform();
+ positionTransform.translate(bv.getXOffset(), bv.getYOffset());
+
+ //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
+ positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
+
+ //Free transformation for the block-container viewport
+ String transf;
+ transf = bv.getForeignAttributeValue(FOX_TRANSFORM);
+ if (transf != null) {
+ AffineTransform freeTransform = AWTTransformProducer.createAffineTransform(transf);
+ positionTransform.concatenate(freeTransform);
+ }
+
+ saveGraphicsState();
+ //Viewport position
+ concatenateTransformationMatrixMpt(positionTransform);
+
+ //Background and borders
+ float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd());
+ float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter());
+ drawBackAndBorders(bv, 0, 0,
+ (dim.width + bpwidth) / 1000f, (dim.height + bpheight) / 1000f);
+
+ //Shift to content rectangle after border painting
+ AffineTransform contentRectTransform = new AffineTransform();
+ contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+ concatenateTransformationMatrixMpt(contentRectTransform);
+
+ //Clipping
+ Rectangle clipRect = null;
+ if (bv.getClip()) {
+ clipRect = new Rectangle(0, 0, dim.width, dim.height);
+ //clipRect(0f, 0f, width, height);
+ }
+
+ //saveGraphicsState();
+ //Set up coordinate system for content rectangle
+ AffineTransform contentTransform = ctm.toAffineTransform();
+ //concatenateTransformationMatrixMpt(contentTransform);
+ startViewport(contentTransform, clipRect);
+
+ currentIPPosition = 0;
+ currentBPPosition = 0;
+ renderBlocks(bv, children);
+
+ endViewport();
+ //restoreGraphicsState();
+ restoreGraphicsState();
+
+ if (breakOutList != null) {
+ restoreStateStackAfterBreakOut(breakOutList);
+ }
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ } else {
+
+ currentBPPosition += bv.getSpaceBefore();
+
+ //borders and background in the old coordinate system
+ handleBlockTraits(bv);
+
+ //Advance to start of content area
+ currentIPPosition += bv.getStartIndent();
+
+ CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
+ ctm = tempctm.multiply(ctm);
+
+ //Now adjust for border/padding
+ currentBPPosition += borderPaddingBefore;
+
+ Rectangle2D clippingRect = null;
+ if (bv.getClip()) {
+ clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
+ bv.getIPD(), bv.getBPD());
+ }
+
+ startVParea(ctm, clippingRect);
+ currentIPPosition = 0;
+ currentBPPosition = 0;
+ renderBlocks(bv, children);
+ endVParea();
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+
+ currentBPPosition += (int)(bv.getAllocBPD());
+ }
viewportDimensionStack.pop();
}
@@ -380,40 +525,45 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
if (log.isDebugEnabled()) {
log.debug("startVParea() ctm=" + ctm + ", clippingRect=" + clippingRect);
}
- saveGraphicsState();
AffineTransform at = new AffineTransform(ctm.toArray());
- graphicContext.transform(at);
- try {
- Rectangle clipRect = null;
- if (clippingRect != null) {
- clipRect = new Rectangle(
- (int)clippingRect.getMinX() - currentIPPosition,
- (int)clippingRect.getMinY() - currentBPPosition,
- (int)clippingRect.getWidth(), (int)clippingRect.getHeight());
- }
- painter.startViewport(at, (Dimension)viewportDimensionStack.peek(), clipRect);
- } catch (IFException e) {
- handleIFException(e);
- }
+ Rectangle clipRect = null;
+ if (clippingRect != null) {
+ clipRect = new Rectangle(
+ (int)clippingRect.getMinX() - currentIPPosition,
+ (int)clippingRect.getMinY() - currentBPPosition,
+ (int)clippingRect.getWidth(), (int)clippingRect.getHeight());
+ }
+ startViewport(at, clipRect);
if (log.isDebugEnabled()) {
log.debug("startVPArea: " + at + " --> " + graphicContext.getTransform());
}
}
- /** {@inheritDoc} */
- protected void endVParea() {
- log.debug("endVParea()");
+ private void startViewport(AffineTransform at, Rectangle clipRect) {
+ saveGraphicsState();
try {
- painter.endViewport();
+ IFGraphicContext.Viewport viewport = new IFGraphicContext.Viewport(
+ at, (Dimension)viewportDimensionStack.peek(), clipRect);
+ graphicContext.pushGroup(viewport);
+ viewport.start(painter);
} catch (IFException e) {
handleIFException(e);
}
- restoreGraphicsState();
+ }
+
+ /** {@inheritDoc} */
+ protected void endVParea() {
+ log.debug("endVParea()");
+ endViewport();
if (log.isDebugEnabled()) {
log.debug("endVPArea() --> " + graphicContext.getTransform());
}
}
+ private void endViewport() {
+ restoreGraphicsState();
+ }
+
/*
protected void renderReferenceArea(Block block) {
// TODO Auto-generated method stub