diff options
author | Jeremias Maerki <jeremias@apache.org> | 2008-02-06 14:07:03 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2008-02-06 14:07:03 +0000 |
commit | 448befc115b005dc2a07391182179c686a91d25f (patch) | |
tree | b658d79ef2bbd433580a089758d5ecb945c52166 /src | |
parent | 36c62fb27612261f81eb8de02f1754a3d662cea4 (diff) | |
download | xmlgraphics-fop-448befc115b005dc2a07391182179c686a91d25f.tar.gz xmlgraphics-fop-448befc115b005dc2a07391182179c686a91d25f.zip |
Bugzilla #36391:
Fixed problem with positioning of content when reference-orientation="180" is used. CTM is now correct. It is updated after the height of the content is known. Instead of somehow inverting the element list, I've simply declared this case non-breakable, i.e. I generate one box.
Fixed a few other problems mostly occurring when rotating block-container content by 90 or 270 degrees plus a few remaining auto-height handling problems. This involved switching off some sometimes unwanted side-effects from auto-updating the BPD in some area classes.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@618992 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/java/org/apache/fop/area/Block.java | 15 | ||||
-rw-r--r-- | src/java/org/apache/fop/area/BlockViewport.java | 9 | ||||
-rw-r--r-- | src/java/org/apache/fop/area/NormalFlow.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java | 99 |
4 files changed, 87 insertions, 40 deletions
diff --git a/src/java/org/apache/fop/area/Block.java b/src/java/org/apache/fop/area/Block.java index 264a9e690..21fa7c49d 100644 --- a/src/java/org/apache/fop/area/Block.java +++ b/src/java/org/apache/fop/area/Block.java @@ -19,7 +19,6 @@ package org.apache.fop.area; -import java.util.ArrayList; // block areas hold either more block areas or line // areas can also be used as a block spacer @@ -59,6 +58,8 @@ public class Block extends BlockParent { private int stacking = TB; private int positioning = STACK; + protected transient boolean allowBPDUpdate = true; + // a block with may contain the dominant styling info in // terms of most lines or blocks with info @@ -78,7 +79,7 @@ public class Block extends BlockParent { * @param autoHeight increase the height of the block. */ public void addBlock(Block block, boolean autoHeight) { - if (autoHeight) { + if (autoHeight && allowBPDUpdate) { bpd += block.getAllocBPD(); } addChildArea(block); @@ -113,12 +114,20 @@ public class Block extends BlockParent { } /** + * Indicates whether this block is stacked, rather than absolutely positioned. + * @return true if it is stacked + */ + public boolean isStacked() { + return (getPositioning() == Block.STACK || getPositioning() == Block.RELATIVE); + } + + /** * @return the start-indent trait */ public int getStartIndent() { Integer startIndent = (Integer)getTrait(Trait.START_INDENT); return (startIndent != null ? startIndent.intValue() : 0); } - + } diff --git a/src/java/org/apache/fop/area/BlockViewport.java b/src/java/org/apache/fop/area/BlockViewport.java index af994afd4..167e7c5b3 100644 --- a/src/java/org/apache/fop/area/BlockViewport.java +++ b/src/java/org/apache/fop/area/BlockViewport.java @@ -34,6 +34,15 @@ public class BlockViewport extends Block { * Create a new block viewport area. */ public BlockViewport() { + this(false); + } + + /** + * Create a new block viewport area. + * @param allowBPDUpdate true allows the BPD to be updated when children are added + */ + public BlockViewport(boolean allowBPDUpdate) { + this.allowBPDUpdate = allowBPDUpdate; } /** diff --git a/src/java/org/apache/fop/area/NormalFlow.java b/src/java/org/apache/fop/area/NormalFlow.java index 715a61cb0..c9fc8380a 100644 --- a/src/java/org/apache/fop/area/NormalFlow.java +++ b/src/java/org/apache/fop/area/NormalFlow.java @@ -37,7 +37,9 @@ public class NormalFlow extends BlockParent { /** {@inheritDoc} */ public void addBlock(Block block) { super.addBlock(block); - bpd += block.getAllocBPD(); + if (block.isStacked()) { + bpd += block.getAllocBPD(); + } } } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index 3d9076efd..fc60b561e 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -65,7 +65,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager private int vpContentBPD; // When viewport should grow with the content. - private boolean autoHeight = true; + private boolean autoHeight = true; + private boolean inlineElementList = false; /* holds the (one-time use) fo:block space-before and -after properties. Large fo:blocks are split @@ -196,6 +197,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager return getNextKnuthElementsAbsolute(context, alignment); } + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); autoHeight = false; //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); int maxbpd = context.getStackLimit().opt; @@ -203,9 +206,13 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager if (height.getEnum() == EN_AUTO || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) { //auto height when height="auto" or "if that dimension is not specified explicitly - //(i.e., it depends on content's blockprogression-dimension)" (XSL 1.0, 7.14.1) + //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1) allocBPD = maxbpd; autoHeight = true; + if (getBlockContainerFO().getReferenceOrientation() == 0) { + //Cannot easily inline element list when ref-or="180" + inlineElementList = true; + } } else { allocBPD = height.getValue(this); //this is the content-height allocBPD += getBPIndents(); @@ -229,19 +236,14 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager contentRectOffsetY += getBlockContainerFO() .getCommonBorderPaddingBackground().getPaddingBefore(false, this); - Rectangle2D rect = new Rectangle2D.Double( - contentRectOffsetX, contentRectOffsetY, - getContentAreaIPD(), getContentAreaBPD()); - relDims = new FODimension(0, 0); - absoluteCTM = CTM.getCTMandRelDims(getBlockContainerFO().getReferenceOrientation(), - getBlockContainerFO().getWritingMode(), rect, relDims); + updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight); int availableIPD = referenceIPD - getIPIndents(); - if (rect.getWidth() > availableIPD) { + if (getContentAreaIPD() > availableIPD) { log.warn(FONode.decorateWithContextInfo( "The extent in inline-progression-direction (width) of a block-container is" + " bigger than the available space (" - + rect.getWidth() + "mpt > " + context.getRefIPD() + "mpt)", + + getContentAreaIPD() + "mpt > " + context.getRefIPD() + "mpt)", getBlockContainerFO())); } @@ -268,7 +270,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); firstVisibleMarkServed = true; - if (autoHeight) { + if (autoHeight && inlineElementList) { //Spaces, border and padding to be repeated at each break addPendingMarks(context); @@ -356,6 +358,16 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); breaker.doLayout(relDims.bpd, autoHeight); boolean contentOverflows = breaker.isOverflow(); + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.totalWidth; + if (switchedProgressionDirection) { + setContentAreaIPD(newHeight); + } else { + vpContentBPD = newHeight; + } + updateRelDims(contentRectOffsetX, contentRectOffsetY, false); + } Position bcPosition = new BlockContainerPosition(this, breaker); returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false)); @@ -385,6 +397,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager private LinkedList getNextKnuthElementsAbsolute(LayoutContext context, int alignment) { autoHeight = false; + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); Point offset = getAbsOffset(); int allocBPD, allocIPD; if (height.getEnum() == EN_AUTO @@ -432,7 +446,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } else { int maxbpd = context.getStackLimit().opt; allocBPD = maxbpd; - autoHeight = true; + if (!switchedProgressionDirection) { + autoHeight = true; + } } } else { allocBPD = height.getValue(this); //this is the content-height @@ -474,6 +490,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager */ allocIPD = 0; } + if (switchedProgressionDirection) { + autoHeight = true; + } } } else { allocIPD = width.getValue(this); //this is the content-width @@ -483,29 +502,29 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager vpContentBPD = allocBPD - getBPIndents(); setContentAreaIPD(allocIPD - getIPIndents()); - double contentRectOffsetX = 0; - double contentRectOffsetY = 0; - - Rectangle2D rect = new Rectangle2D.Double( - contentRectOffsetX, contentRectOffsetY, - getContentAreaIPD(), vpContentBPD); - relDims = new FODimension(0, 0); - absoluteCTM = CTM.getCTMandRelDims( - getBlockContainerFO().getReferenceOrientation(), - getBlockContainerFO().getWritingMode(), - rect, relDims); + updateRelDims(0, 0, autoHeight); MinOptMax range = new MinOptMax(relDims.ipd); BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight); boolean contentOverflows = breaker.isOverflow(); + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.totalWidth; + if (switchedProgressionDirection) { + setContentAreaIPD(newHeight); + } else { + vpContentBPD = newHeight; + } + updateRelDims(0, 0, false); + } LinkedList returnList = new LinkedList(); if (!breaker.isEmpty()) { Position bcPosition = new BlockContainerPosition(this, breaker); returnList.add(new KnuthBox(0, notifyPos(bcPosition), false)); //TODO Maybe check for page overflow when autoHeight=true - if (!autoHeight & (contentOverflows/*usedBPD > relDims.bpd*/)) { + if (!autoHeight & (contentOverflows)) { log.warn("Contents overflow block-container viewport: clipping"); if (getBlockContainerFO().getOverflow() == EN_ERROR_IF_OVERFLOW) { //TODO Throw layout exception @@ -516,6 +535,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager setFinished(true); return returnList; } + + private void updateRelDims(double xOffset, double yOffset, boolean skipAutoHeight) { + Rectangle2D rect = new Rectangle2D.Double( + xOffset, yOffset, + getContentAreaIPD(), + this.vpContentBPD); + relDims = new FODimension(0, 0); + absoluteCTM = CTM.getCTMandRelDims( + getBlockContainerFO().getReferenceOrientation(), + getBlockContainerFO().getWritingMode(), + rect, relDims); + } private class BlockContainerPosition extends NonLeafPosition { @@ -854,13 +885,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager */ public Area getParentArea(Area childArea) { if (referenceArea == null) { - viewportBlockArea = new BlockViewport(); + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); + boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection; + + viewportBlockArea = new BlockViewport(allowBPDUpdate); viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + viewportBlockArea.setIPD(getContentAreaIPD()); - if (autoHeight) { + if (allowBPDUpdate) { viewportBlockArea.setBPD(0); } else { - viewportBlockArea.setBPD(getContentAreaBPD()); + viewportBlockArea.setBPD(this.vpContentBPD); } transferForeignAttributes(viewportBlockArea); @@ -941,16 +977,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager getBlockContainerFO().getCommonBorderPaddingBackground(), this); - // Fake a 0 height for absolute positioned blocks. - int saveBPD = viewportBlockArea.getBPD(); - if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) { - viewportBlockArea.setBPD(0); - } super.flush(); - // Restore the right height. - if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) { - viewportBlockArea.setBPD(saveBPD); - } } /** {@inheritDoc} */ |