diff options
author | Jeremias Maerki <jeremias@apache.org> | 2008-07-28 13:03:40 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2008-07-28 13:03:40 +0000 |
commit | 17214623febc22024f3cc24491b4ea7669697641 (patch) | |
tree | b843978361d95f3f14068dad668a541ed78d36f9 /src/java/org/apache/fop | |
parent | 909b93a2b94ac18245103d7f5e6231b0595f6fcd (diff) | |
download | xmlgraphics-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')
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 |