diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2014-01-29 12:52:26 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2014-01-29 12:52:26 +0000 |
commit | cdc09052891898a46b70b3298c389e96ffff87ac (patch) | |
tree | 46908d666ce2a5c934b221627f6c53ae1c5deb8a /src | |
parent | f788f5d12b85ddecf7daa95f4eb735139080f399 (diff) | |
parent | f7befc49c57bf68450774250338d449253c2f5e3 (diff) | |
download | xmlgraphics-fop-cdc09052891898a46b70b3298c389e96ffff87ac.tar.gz xmlgraphics-fop-cdc09052891898a46b70b3298c389e96ffff87ac.zip |
Merged branch Temp_InlineContainer back into trunk
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1562429 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
24 files changed, 707 insertions, 473 deletions
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index f6de99dd0..640f04335 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -62,6 +62,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Trait.Background; import org.apache.fop.area.Trait.InternalLink; import org.apache.fop.area.inline.AbstractTextArea; +import org.apache.fop.area.inline.Container; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; @@ -195,6 +196,7 @@ public class AreaTreeParser { makers.put("space", new SpaceMaker()); makers.put("leader", new LeaderMaker()); makers.put("viewport", new InlineViewportMaker()); + makers.put("container", new ContainerMaker()); makers.put("image", new ImageMaker()); makers.put("foreignObject", new ForeignObjectMaker()); makers.put("bookmarkTree", new BookmarkTreeMaker()); @@ -863,6 +865,21 @@ public class AreaTreeParser { } } + private class ContainerMaker extends AbstractMaker { + + public void startElement(Attributes attributes) { + Container container = new Container(); + transferForeignObjects(attributes, container); + InlineViewport parent = (InlineViewport) areaStack.peek(); + parent.setContent(container); + areaStack.push(container); + } + + public void endElement() { + assertObjectOfClass(areaStack.pop(), Container.class); + } + } + private class InlineViewportMaker extends AbstractMaker { public void startElement(Attributes attributes) { diff --git a/src/java/org/apache/fop/area/inline/Container.java b/src/java/org/apache/fop/area/inline/Container.java index bc2acaa28..3d0060007 100644 --- a/src/java/org/apache/fop/area/inline/Container.java +++ b/src/java/org/apache/fop/area/inline/Container.java @@ -51,13 +51,12 @@ public class Container extends Area { public Container() { } - /** - * Add the block to this area. - * - * @param block the block area to add - */ - public void addBlock(Block block) { - blocks.add(block); + @Override + public void addChildArea(Area child) { + if (!(child instanceof Block)) { + throw new IllegalArgumentException("Container only accepts block areas"); + } + blocks.add((Block) child); } /** @@ -65,7 +64,7 @@ public class Container extends Area { * * @return the list of block areas */ - public List getBlocks() { + public List<Block> getBlocks() { return blocks; } diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index cf970c325..5c95fa34e 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -37,49 +37,38 @@ import org.apache.fop.traits.Direction; import org.apache.fop.traits.WritingMode; import org.apache.fop.traits.WritingModeTraits; -/** - * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container"> - * <code>fo:inline-container</code></a> object. - */ public class InlineContainer extends FObj { - // The value of FO traits (refined properties) that apply to fo:inline-container. - private Length alignmentAdjust; - private int alignmentBaseline; - private Length baselineShift; + private LengthRangeProperty inlineProgressionDimension; private LengthRangeProperty blockProgressionDimension; + private int overflow; private CommonBorderPaddingBackground commonBorderPaddingBackground; private CommonMarginInline commonMarginInline; - private int clip; - private int dominantBaseline; - private LengthRangeProperty inlineProgressionDimension; + private Numeric referenceOrientation; + private int displayAlign; private KeepProperty keepTogether; + private KeepProperty keepWithNext; + private KeepProperty keepWithPrevious; private SpaceProperty lineHeight; - private int overflow; - private Numeric referenceOrientation; + private Length alignmentAdjust; + private int alignmentBaseline; + private Length baselineShift; + private int dominantBaseline; private WritingModeTraits writingModeTraits; - // Unused but valid items, commented out for performance: - // private CommonRelativePosition commonRelativePosition; - // private int displayAlign; - // private Length height; - // private KeepProperty keepWithNext; - // private KeepProperty keepWithPrevious; - // private Length width; - // End of FO trait values /** used for FO validation */ - private boolean blockItemFound = false; + private boolean blockItemFound; /** - * Base constructor + * Creates a new instance. * - * @param parent {@link FONode} that is the parent of this object + * @param parent the parent of this inline-container */ public InlineContainer(FONode parent) { super(parent); } - /** {@inheritDoc} */ + @Override public void bind(PropertyList pList) throws FOPException { super.bind(pList); alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); @@ -88,28 +77,31 @@ public class InlineContainer extends FObj { blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange(); commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps(); commonMarginInline = pList.getMarginInlineProps(); - clip = pList.get(PR_CLIP).getEnum(); + displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum(); dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum(); inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); + keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); + keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); overflow = pList.get(PR_OVERFLOW).getEnum(); referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric(); writingModeTraits = new WritingModeTraits( - WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()), - pList.getExplicit(PR_WRITING_MODE) != null); + WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()), + pList.getExplicit(PR_WRITING_MODE) != null); } /** * {@inheritDoc} * <br>XSL Content Model: marker* (%block;)+ */ + @Override protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { if (localName.equals("marker")) { if (blockItemFound) { - nodesOutOfOrderError(loc, "fo:marker", "(%block;)"); + nodesOutOfOrderError(loc, "fo:marker", "(%block;)+"); } } else if (!isBlockItem(nsURI, localName)) { invalidChildError(loc, nsURI, localName); @@ -119,153 +111,129 @@ public class InlineContainer extends FObj { } } - /** {@inheritDoc} */ + @Override public void endOfNode() throws FOPException { if (!blockItemFound) { missingChildElementError("marker* (%block;)+"); } } - /** @return the "alignment-adjust" FO trait */ - public Length getAlignmentAdjust() { - return alignmentAdjust; + /** {@inheritDoc} */ + public String getLocalName() { + return "inline-container"; } - /** @return the "alignment-baseline" FO trait */ - public int getAlignmentBaseline() { - return alignmentBaseline; + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} + */ + public int getNameId() { + return FO_INLINE_CONTAINER; } - /** @return the "baseline-shift" FO trait */ - public Length getBaselineShift() { - return baselineShift; + public LengthRangeProperty getInlineProgressionDimension() { + return inlineProgressionDimension; } - /** @return the "block-progression-dimension" FO trait */ public LengthRangeProperty getBlockProgressionDimension() { return blockProgressionDimension; } - /** @return the "clip" FO trait */ - public int getClip() { - return clip; + public int getOverflow() { + return overflow; } - /**@return Returns the {@link CommonBorderPaddingBackground} */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { return this.commonBorderPaddingBackground; } - /** @return Returns the {@link CommonMarginInline} */ public CommonMarginInline getCommonMarginInline() { return this.commonMarginInline; } - /** @return the "dominant-baseline" FO trait */ - public int getDominantBaseline() { - return dominantBaseline; + public int getReferenceOrientation() { + return referenceOrientation.getValue(); + } + + public int getDisplayAlign() { + return this.displayAlign; + } + + public KeepProperty getKeepWithPrevious() { + return keepWithPrevious; } - /** @return the "keep-together" FO trait */ public KeepProperty getKeepTogether() { return keepTogether; } - /** @return the "inline-progression-dimension" FO trait */ - public LengthRangeProperty getInlineProgressionDimension() { - return inlineProgressionDimension; + public KeepProperty getKeepWithNext() { + return keepWithNext; } - /** @return the "line-height" FO trait */ public SpaceProperty getLineHeight() { return lineHeight; } - /** @return the "overflow" FO trait */ - public int getOverflow() { - return overflow; + public Length getAlignmentAdjust() { + return alignmentAdjust; } - /** @return the "reference-orientation" FO trait */ - public int getReferenceOrientation() { - return referenceOrientation.getValue(); + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + public Length getBaselineShift() { + return baselineShift; + } + + public int getDominantBaseline() { + return dominantBaseline; + } + + public WritingMode getWritingMode() { + return writingModeTraits.getWritingMode(); } /** - * Obtain inline progression direction. - * @return the inline progression direction + * Obtain writing mode explicit indicator. + * @return the writing mode explicit indicator */ + public boolean getExplicitWritingMode() { + return writingModeTraits.getExplicitWritingMode(); + } + public Direction getInlineProgressionDirection() { return writingModeTraits.getInlineProgressionDirection(); } - /** - * Obtain block progression direction. - * @return the block progression direction - */ public Direction getBlockProgressionDirection() { return writingModeTraits.getBlockProgressionDirection(); } - /** - * Obtain column progression direction. - * @return the column progression direction - */ public Direction getColumnProgressionDirection() { return writingModeTraits.getColumnProgressionDirection(); } - /** - * Obtain row progression direction. - * @return the row progression direction - */ public Direction getRowProgressionDirection() { return writingModeTraits.getRowProgressionDirection(); } - /** - * Obtain (baseline) shift direction. - * @return the (baseline) shift direction - */ public Direction getShiftDirection() { return writingModeTraits.getShiftDirection(); } - /** - * Obtain writing mode. - * @return the writing mode - */ - public WritingMode getWritingMode() { - return writingModeTraits.getWritingMode(); - } - - /** - * Obtain writing mode explicit indicator. - * @return the writing mode explicit indicator - */ - public boolean getExplicitWritingMode() { - return writingModeTraits.getExplicitWritingMode(); - } - - /** {@inheritDoc} */ - public String getLocalName() { - return "inline-container"; - } - - /** - * {@inheritDoc} - * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} - */ - public int getNameId() { - return FO_INLINE_CONTAINER; - } - @Override public boolean isDelimitedTextRangeBoundary(int boundary) { return false; } @Override + public boolean generatesReferenceAreas() { + return true; + } + + @Override protected boolean isBidiBoundary(boolean propagate) { return getExplicitWritingMode(); } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java index 5d7cc0b64..635e267c1 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java @@ -65,9 +65,6 @@ public abstract class AbstractBaseLayoutManager public AbstractBaseLayoutManager(FObj fo) { this.fobj = fo; setGeneratesReferenceArea(fo.generatesReferenceAreas()); - if (getGeneratesReferenceArea()) { - setGeneratesBlockArea(true); - } } // --------- Property Resolution related functions --------- // diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 0285a41e7..2dd18e4ee 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im && isFinished()); } + public boolean hasLineAreaDescendant() { + if (childLMs == null || childLMs.isEmpty()) { + return false; + } else { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return true; + } + } + } + return false; + } + + public int getBaselineOffset() { + if (childLMs != null) { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return childLM.getBaselineOffset(); + } + } + } + throw newNoLineAreaDescendantException(); + } + + protected IllegalStateException newNoLineAreaDescendantException() { + return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant"); + } + /** * Transfers foreign attributes from the formatting object to the area. * @param targetArea the area to set the attributes on diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java index 0ed6cb69b..d731ab62a 100644 --- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java +++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java @@ -33,11 +33,11 @@ public final class AreaAdditionUtil { /** * Creates the child areas for the given layout manager. - * @param bslm the BlockStackingLayoutManager instance for which "addAreas" is performed. + * @param parentLM the parent layout manager * @param parentIter the position iterator * @param layoutContext the layout context */ - public static void addAreas(BlockStackingLayoutManager bslm, + public static void addAreas(AbstractLayoutManager parentLM, PositionIterator parentIter, LayoutContext layoutContext) { LayoutManager childLM; LayoutContext lc = LayoutContext.offspringOf(layoutContext); @@ -46,8 +46,8 @@ public final class AreaAdditionUtil { Position firstPos = null; Position lastPos = null; - if (bslm != null) { - bslm.addId(); + if (parentLM != null) { + parentLM.addId(); } // "unwrap" the NonLeafPositions stored in parentIter @@ -86,11 +86,11 @@ public final class AreaAdditionUtil { //doesn't give us that info. } - if (bslm != null) { - bslm.registerMarkers( + if (parentLM != null) { + parentLM.registerMarkers( true, - bslm.isFirst(firstPos), - bslm.isLast(lastPos)); + parentLM.isFirst(firstPos), + parentLM.isLast(lastPos)); } PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); @@ -113,11 +113,11 @@ public final class AreaAdditionUtil { childLM.addAreas(childPosIter, lc); } - if (bslm != null) { - bslm.registerMarkers( + if (parentLM != null) { + parentLM.registerMarkers( false, - bslm.isFirst(firstPos), - bslm.isLast(lastPos)); + parentLM.isFirst(firstPos), + parentLM.isLast(lastPos)); } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index eced48939..3da6974a6 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.properties.CommonAbsolutePosition; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block-container FO. */ -public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements - ConditionalElementListener, BreakOpportunity { +public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl private MinOptMax foBlockSpaceBefore; private MinOptMax foBlockSpaceAfter; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int horizontalOverflow; private double contentRectOffsetX = 0; private double contentRectOffsetY = 0; @@ -96,6 +90,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl */ public BlockContainerLayoutManager(BlockContainer node) { super(node); + setGeneratesBlockArea(true); } /** {@inheritDoc} */ @@ -128,6 +123,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockContainerFO().getCommonBorderPaddingBackground(); + } + private void resetSpaces() { this.discardBorderBefore = false; this.discardBorderAfter = false; @@ -995,51 +995,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ public boolean handleOverflow(int milliPoints) { if (milliPoints > this.horizontalOverflow) { this.horizontalOverflow = milliPoints; diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index b29b95cb1..d3bdc7b85 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Block; import org.apache.fop.area.LineArea; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block FO. */ -public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(BlockLayoutManager.class); @@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co private int follow = 2000; //private int middleShift = 0; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Creates a new BlockLayoutManager. * @param inBlock the block FO object to create the layout manager for. @@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co .getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockFO().getCommonBorderPaddingBackground(); + } + /** {@inheritDoc} */ @Override public List getNextKnuthElements(LayoutContext context, int alignment) { @@ -458,51 +457,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ @Override public boolean isRestartable() { return true; diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index d11f062cb..250e07727 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -36,6 +36,7 @@ import org.apache.fop.fo.properties.BreakPropertySet; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.ListUtil; @@ -1246,6 +1247,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager public boolean handleOverflow(int milliPoints) { if (getParent() instanceof BlockStackingLayoutManager) { return ((BlockStackingLayoutManager) getParent()).handleOverflow(milliPoints); + } else if (getParent() instanceof InlineContainerLayoutManager) { + return ((InlineContainerLayoutManager) getParent()).handleOverflow(milliPoints); } return false; } diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index 0260046e1..4c7afa8d6 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager */ public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) { super(node); + setGeneratesBlockArea(true); setParent(pslm); } diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java index 985131bf1..8d1e4001c 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -178,6 +178,25 @@ public interface LayoutManager extends PercentBaseContext { List getChangedKnuthElements(List oldList, int alignment); /** + * Whether the FO handled by this layout manager has a descendant (including itself) + * that will generate a line-area. + * + * @return {@code true} if a descendant line-area will be generated, {@code false} otherwise + */ + boolean hasLineAreaDescendant(); + + /** + * Returns the position of the dominant-baseline of this FO's first descendant + * line-area. <p>The behavior of this method is undefined if this FO has no descendant + * line-area, and an exception may be thrown. See {@link #hasLineAreaDescendant()}</p> + * + * @return this FO's space-before plus the distance from the before-edge of its + * allocation-rectangle to the dominant-baseline of the first line-area descendant + * @see #hasLineAreaDescendant() + */ + int getBaselineOffset(); + + /** * Returns the IPD of the content area * @return the IPD of the content area */ diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java index 292251a84..0e333d219 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java @@ -73,7 +73,7 @@ import org.apache.fop.layoutmgr.inline.CharacterLayoutManager; import org.apache.fop.layoutmgr.inline.ContentLayoutManager; import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager; import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager; -import org.apache.fop.layoutmgr.inline.ICLayoutManager; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM; import org.apache.fop.layoutmgr.inline.LeaderLayoutManager; @@ -257,9 +257,9 @@ public class LayoutManagerMapping implements LayoutManagerMaker { /** a layout manager maker */ public static class InlineLayoutManagerMaker extends Maker { /** {@inheritDoc} */ - public void make(FONode node, List lms) { - lms.add(new InlineLayoutManager((InlineLevel) node)); - } + public void make(FONode node, List lms) { + lms.add(new InlineLayoutManager((InlineLevel) node)); + } } /** a layout manager maker */ @@ -274,9 +274,7 @@ public class LayoutManagerMapping implements LayoutManagerMaker { public static class InlineContainerLayoutManagerMaker extends Maker { /** {@inheritDoc} */ public void make(FONode node, List lms) { - ArrayList childList = new ArrayList(); - super.make(node, childList); - lms.add(new ICLayoutManager((InlineContainer) node, childList)); + lms.add(new InlineContainerLayoutManager((InlineContainer) node)); } } diff --git a/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java new file mode 100644 index 000000000..2ac41e96a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java @@ -0,0 +1,112 @@ +/* + * 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.layoutmgr; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.traits.MinOptMax; + +/** + * A block-stacking layout manager for an FO that supports spaces, border and padding. + */ +public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager + implements ConditionalElementListener { + + private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class); + + protected MinOptMax effSpaceBefore; + + protected MinOptMax effSpaceAfter; + + protected boolean discardBorderBefore; + protected boolean discardBorderAfter; + protected boolean discardPaddingBefore; + protected boolean discardPaddingAfter; + + public SpacedBorderedPaddedBlockLayoutManager(FObj node) { + super(node); + } + + public void notifySpace(RelSide side, MinOptMax effectiveLength) { + if (RelSide.BEFORE == side) { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceBefore + "-> " + effectiveLength); + } + this.effSpaceBefore = effectiveLength; + } else { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceAfter + "-> " + effectiveLength); + } + this.effSpaceAfter = effectiveLength; + } + } + + public void notifyBorder(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardBorderBefore = true; + } else { + this.discardBorderAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Border " + side + " -> " + effectiveLength); + } + } + + public void notifyPadding(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardPaddingBefore = true; + } else { + this.discardPaddingAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Padding " + side + " -> " + effectiveLength); + } + } + + @Override + public int getBaselineOffset() { + int baselineOffset = super.getBaselineOffset(); + if (effSpaceBefore != null) { + baselineOffset += effSpaceBefore.getOpt(); + } + if (!discardBorderBefore) { + baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false); + } + if (!discardPaddingBefore) { + baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this); + } + return baselineOffset; + } + + /** + * Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager. + */ + protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java index c1992965c..192956abc 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java +++ b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java @@ -295,7 +295,7 @@ public class AlignmentContext implements Constants { * Return the dominant baseline identifier. * @return the dominant baseline identifier */ - private int getDominantBaselineIdentifier() { + public int getDominantBaselineIdentifier() { return actualBaselineTable.getDominantBaselineIdentifier(); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index b3c768987..c067b040f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -332,6 +332,15 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager return parentLM.getPSLM(); } + + public boolean hasLineAreaDescendant() { + return true; + } + + public int getBaselineOffset() { + return childLM.getBaselineOffset(); + } + // --------- Property Resolution related functions --------- // /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java deleted file mode 100644 index 7fe90f63c..000000000 --- a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java +++ /dev/null @@ -1,54 +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.layoutmgr.inline; - -// Java -import java.util.List; - -// FOP -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.fo.flow.InlineContainer; -/** - * This creates a single inline container area after - * laying out the child block areas. All footnotes, floats - * and id areas are maintained for later retrieval. - */ -public class ICLayoutManager extends LeafNodeLayoutManager { - private List childrenLM; - - /** - * Construct inline container layout manager. - * @param node inline container FO node - * @param childLM child layout manager - */ - public ICLayoutManager(InlineContainer node, List childLM) { - super(node); - childrenLM = childLM; - } - - /** - * @param index an integer - * @return an inline area or null - */ - public InlineArea get(int index) { - return null; - } - -} diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java new file mode 100644 index 000000000..54237a914 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -0,0 +1,326 @@ +/* + * 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.layoutmgr.inline; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.Container; +import org.apache.fop.area.inline.InlineViewport; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.SimplePercentBaseContext; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.flow.InlineContainer; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.LengthRangeProperty; +import org.apache.fop.fo.properties.Property; +import org.apache.fop.layoutmgr.AbstractLayoutManager; +import org.apache.fop.layoutmgr.AreaAdditionUtil; +import org.apache.fop.layoutmgr.BlockLevelEventProducer; +import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.InlineKnuthSequence; +import org.apache.fop.layoutmgr.KnuthPossPosIter; +import org.apache.fop.layoutmgr.KnuthSequence; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.ListElement; +import org.apache.fop.layoutmgr.NonLeafPosition; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.TraitSetter; + +/** + * This creates a single inline container area after + * laying out the child block areas. All footnotes, floats + * and id areas are maintained for later retrieval. + */ +public class InlineContainerLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager { + + private CommonBorderPaddingBackground borderProps; + private int contentAreaIPD; + private int contentAreaBPD; + + private List<ListElement> childElements; + private int ipdOverflow; + private AlignmentContext alignmentContext; + private InlineViewport currentViewport; + private Container referenceArea; + + public InlineContainerLayoutManager(InlineContainer node) { + super(node); + setGeneratesReferenceArea(true); + } + + @Override + public void initialize() { + InlineContainer node = (InlineContainer) fobj; + borderProps = node.getCommonBorderPaddingBackground(); + } + + private InlineContainer getInlineContainer() { + assert fobj instanceof InlineContainer; + return (InlineContainer) fobj; + } + + @Override + public List<KnuthSequence> getNextKnuthElements(LayoutContext context, int alignment) { + determineIPD(context); + childElements = getChildKnuthElements(context, alignment); + determineBPD(); + alignmentContext = makeAlignmentContext(context); + Position position = new Position(this, 0); + KnuthSequence knuthSequence = new InlineKnuthSequence(); + knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); + List<KnuthSequence> knuthElements = new ArrayList<KnuthSequence>(1); + knuthElements.add(knuthSequence); + setFinished(true); + return knuthElements; + } + + private void determineIPD(LayoutContext layoutContext) { + LengthRangeProperty ipd = getInlineContainer().getInlineProgressionDimension(); + Property optimum = ipd.getOptimum(this); + if (optimum.isAuto()) { + contentAreaIPD = layoutContext.getRefIPD(); + InlineLevelEventProducer eventProducer = InlineLevelEventProducer.Provider.get( + fobj.getUserAgent().getEventBroadcaster()); + eventProducer.inlineContainerAutoIPDNotSupported(this, contentAreaIPD / 1000f); + } else { + contentAreaIPD = optimum.getLength().getValue(this); + } + } + + private List<ListElement> getChildKnuthElements(LayoutContext layoutContext, int alignment) { + List<ListElement> allChildElements = new LinkedList<ListElement>(); + LayoutManager childLM; + while ((childLM = getChildLM()) != null) { + LayoutContext childLC = LayoutContext.offspringOf(layoutContext); + childLC.setRefIPD(contentAreaIPD); + @SuppressWarnings("unchecked") + List<ListElement> childElements = childLM.getNextKnuthElements(childLC, alignment); + allChildElements.addAll(childElements); + } + handleIPDOverflow(); + wrapPositions(allChildElements); + SpaceResolver.resolveElementList(allChildElements); + SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1); + return allChildElements; + } + + private void determineBPD() { + LengthRangeProperty bpd = getInlineContainer().getBlockProgressionDimension(); + Property optimum = bpd.getOptimum(this); + int actualBPD = ElementListUtils.calcContentLength(childElements); + if (optimum.isAuto()) { + contentAreaBPD = actualBPD; + } else { + double bpdValue = optimum.getLength().getNumericValue(this); + if (bpdValue < 0) { + contentAreaBPD = actualBPD; + } else { + contentAreaBPD = (int) Math.round(bpdValue); + if (contentAreaBPD < actualBPD) { + BlockLevelEventProducer eventProducer = getBlockLevelEventProducer(); + eventProducer.viewportBPDOverflow(this, fobj.getName(), + actualBPD - contentAreaBPD, needClip(), canRecoverFromOverflow(), + fobj.getLocator()); + } + } + } + } + + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + InlineContainer ic = (InlineContainer) fobj; + AlignmentContext ac = new AlignmentContext(contentAreaBPD, + ic.getAlignmentAdjust(), ic.getAlignmentBaseline(), + ic.getBaselineShift(), ic.getDominantBaseline(), + context.getAlignmentContext()); + int baselineOffset = getAlignmentPoint(ac.getDominantBaselineIdentifier()); + ac.resizeLine(contentAreaBPD, baselineOffset); + return ac; + } + + private void handleIPDOverflow() { + if (ipdOverflow > 0) { + BlockLevelEventProducer eventProducer = getBlockLevelEventProducer(); + eventProducer.viewportIPDOverflow(this, fobj.getName(), + ipdOverflow, needClip(), canRecoverFromOverflow(), + fobj.getLocator()); + } + } + + private void wrapPositions(List<ListElement> elements) { + for (ListElement element : elements) { + Position position = new NonLeafPosition(this, element.getPosition()); + notifyPos(position); + element.setPosition(position); + } + } + + private BlockLevelEventProducer getBlockLevelEventProducer() { + return BlockLevelEventProducer.Provider.get(fobj.getUserAgent().getEventBroadcaster()); + } + + private boolean canRecoverFromOverflow() { + return getInlineContainer().getOverflow() != EN_ERROR_IF_OVERFLOW; + } + + private int getAlignmentPoint(int dominantBaseline) { + Length alignmentAdjust = getInlineContainer().getAlignmentAdjust(); + int baseline = alignmentAdjust.getEnum(); + if (baseline == Constants.EN_AUTO) { + return getInlineContainerBaselineOffset(getInlineContainer().getAlignmentBaseline()); + } else if (baseline == Constants.EN_BASELINE) { + return getInlineContainerBaselineOffset(dominantBaseline); + } else if (baseline != 0) { + return getInlineContainerBaselineOffset(baseline); + } else { + int baselineOffset = getInlineContainerBaselineOffset(dominantBaseline); + int lineHeight = getInlineContainer().getLineHeight().getOptimum(this).getLength().getValue(this); + int adjust = alignmentAdjust.getValue( + new SimplePercentBaseContext(null, LengthBase.ALIGNMENT_ADJUST, lineHeight)); + return baselineOffset + adjust; + } + } + + private int getInlineContainerBaselineOffset(int property) { + switch (property) { + case Constants.EN_BEFORE_EDGE: + case Constants.EN_TEXT_BEFORE_EDGE: + return 0; + case Constants.EN_AFTER_EDGE: + case Constants.EN_TEXT_AFTER_EDGE: + return contentAreaBPD; + case Constants.EN_MIDDLE: + case Constants.EN_CENTRAL: + case Constants.EN_MATHEMATICAL: + return contentAreaBPD / 2; + case Constants.EN_IDEOGRAPHIC: + return contentAreaBPD * 7 / 10; + case Constants.EN_ALPHABETIC: + return contentAreaBPD * 6 / 10; + case Constants.EN_HANGING: + return contentAreaBPD * 2 / 10; + case Constants.EN_AUTO: + case Constants.EN_BASELINE: + return hasLineAreaDescendant() ? getBaselineOffset() : contentAreaBPD; + default: + throw new AssertionError("Unknown baseline value: " + property); + } + } + + @Override + public void addAreas(PositionIterator posIter, LayoutContext context) { + Position inlineContainerPosition = null; + while (posIter.hasNext()) { + /* + * Should iterate only once, but hasNext must be called twice for its + * side-effects to apply and the iterator to switch to the next LM. + */ + assert inlineContainerPosition == null; + inlineContainerPosition = posIter.next(); + assert inlineContainerPosition.getLM() == this; + } + assert inlineContainerPosition != null; + KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); + AreaAdditionUtil.addAreas(this, childPosIter, context); + } + + @Override + public Area getParentArea(Area childArea) { + if (referenceArea == null) { + referenceArea = new Container(); + referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); + TraitSetter.setProducerID(referenceArea, fobj.getId()); + referenceArea.setIPD(contentAreaIPD); + currentViewport = new InlineViewport(referenceArea); + currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + TraitSetter.setProducerID(currentViewport, fobj.getId()); + currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); + currentViewport.setIPD(getContentAreaIPD()); + currentViewport.setBPD(getContentAreaBPD()); + TraitSetter.addBackground(currentViewport, borderProps, this); + currentViewport.setClip(needClip()); + currentViewport.setContentPosition( + new Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); + getParent().addChildArea(currentViewport); + } + return referenceArea; + } + + @Override + public int getContentAreaIPD() { + return contentAreaIPD; + } + + @Override + public int getContentAreaBPD() { + return contentAreaBPD; + } + + @Override + public void addChildArea(Area childArea) { + referenceArea.addChildArea(childArea); + } + + private boolean needClip() { + int overflow = getInlineContainer().getOverflow(); + return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW); + } + + public boolean handleOverflow(int milliPoints) { + ipdOverflow = Math.max(ipdOverflow, milliPoints); + return true; + } + + public List addALetterSpaceTo(List oldList) { + return oldList; + } + + public List addALetterSpaceTo(List oldList, int depth) { + return oldList; + } + + public String getWordChars(Position pos) { + return ""; + } + + public void hyphenate(Position pos, HyphContext hyphContext) { + } + + public boolean applyChanges(List oldList) { + return false; + } + + public boolean applyChanges(List oldList, int depth) { + return false; + } + + public List getChangedKnuthElements(List oldList, int alignment, int depth) { + return oldList; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java index 15284ae0a..332e14935 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java @@ -67,4 +67,13 @@ public interface InlineLevelEventProducer extends EventProducer { */ void lineOverflows(Object source, String elementName, int line, int overflowLength, Locator loc); + /** + * Auto IPD on inline-container is not supported. + * + * @param source the event source + * @param fallback the value in points that will be used as a fallback + * @event.severity WARN + */ + void inlineContainerAutoIPDNotSupported(Object source, float fallback); + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml index 66d352eb7..8d699f6bc 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml @@ -20,4 +20,5 @@ <message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message> <message key="leaderWithoutContent">fo:leader is set to "use-content" but has no content.{{locator}}</message> <message key="lineOverflows">The contents of {elementName} line {line} exceed the available area in the inline-progression direction by {overflowLength,choice,50000#{overflowLength} millipoints|50000<more than 50 points}.{{locator}}</message> + <message key="inlineContainerAutoIPDNotSupported">A value of "auto" for the inline-progression-dimension property on fo:inline-container is not supported. Falling back to {fallback}pt.{{locator}}</message> </catalogue> diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index b3987a075..25d8c0872 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -160,6 +160,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager private final int follow; private AlignmentContext alignmentContext; + private int baselineOffset = -1; + private List<KnuthSequence> knuthParagraphs; private LineLayoutPossibilities lineLayouts; @@ -556,7 +558,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int constantLineHeight = 12000; - /** * Create a new Line Layout Manager. * This is used by the block layout manager to create @@ -939,7 +940,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager while (listIter.hasNext()) { ListElement tempElement; tempElement = (ListElement) listIter.next(); - if (tempElement.getLayoutManager() != this) { + LayoutManager lm = tempElement.getLayoutManager(); + if (baselineOffset < 0 && lm != null && lm.hasLineAreaDescendant()) { + baselineOffset = lm.getBaselineOffset(); + } + if (lm != this) { tempElement.setPosition(notifyPos(new NonLeafPosition(this, tempElement.getPosition()))); } @@ -987,6 +992,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager } startIndex = endIndex + 1; LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i); + if (baselineOffset < 0) { + baselineOffset = lbp.spaceBefore + lbp.baseline; + } returnList.add(new KnuthBlockBox( lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter, footnoteList, lbp, false)); @@ -1424,6 +1432,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } + @Override + public boolean hasLineAreaDescendant() { + return true; + } + + @Override + public int getBaselineOffset() { + return baselineOffset; + } + /** * Add the areas with the break points. * diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 5d89b3440..062a67b38 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal; * A list block contains list items which are stacked within * the list block area.. */ -public class ListBlockLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener { +public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager { /** logging instance */ private static Log log = LogFactory.getLog(ListBlockLayoutManager.class); private Block curBlockArea; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Create a new list block layout manager. * @param node list-block to create the layout manager for @@ -70,6 +61,11 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager super(node); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListBlockFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -279,50 +275,5 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager return getListBlockFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 84dba03ee..773506632 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,12 +32,11 @@ import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; import org.apache.fop.layoutmgr.BreakOpportunityHelper; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager; @@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import org.apache.fop.util.BreakUtil; @@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil; * LayoutManager for a list-item FO. * The list item contains a list item label and a list item body. */ -public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(ListItemLayoutManager.class); @@ -78,13 +76,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements private List<ListElement> labelList = null; private List<ListElement> bodyList = null; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private Keep keepWithNextPendingOnLabel; private Keep keepWithNextPendingOnBody; @@ -145,6 +136,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements setBody(node.getBody()); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListItemFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -475,6 +471,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return returnedList; } + + @Override + public boolean hasLineAreaDescendant() { + return label.hasLineAreaDescendant() || body.hasLineAreaDescendant(); + } + + @Override + public int getBaselineOffset() { + if (label.hasLineAreaDescendant()) { + return label.getBaselineOffset(); + } else if (body.hasLineAreaDescendant()) { + return body.getBaselineOffset(); + } else { + throw newNoLineAreaDescendantException(); + } + } + /** * Add the areas for the break points. * @@ -655,51 +668,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ @Override public void reset() { super.reset(); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index af8e071d5..b2851c1b0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -117,6 +117,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager */ public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) { super(node); + setGeneratesBlockArea(true); this.primaryGridUnit = pgu; this.isDescendantOfTableHeader = node.getParent().getParent() instanceof TableHeader || node.getParent() instanceof TableHeader; diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 7f1754064..afb6547c0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers; import org.apache.fop.fo.flow.RetrieveTableMarker; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.layoutmgr.BlockLevelEventProducer; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.LayoutContext; @@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil; * The table then creates areas for the columns, bodies and rows * the render background. */ -public class TableLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener, BreakOpportunity { +public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -82,13 +81,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager private double tableUnit; private boolean autoLayout = true; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int halfBorderSeparationBPD; private int halfBorderSeparationIPD; @@ -132,6 +124,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager this.columns = new ColumnSetup(node); } + + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getTable().getCommonBorderPaddingBackground(); + } + + /** @return the table FO */ public Table getTable() { return (Table)this.fobj; @@ -522,51 +521,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ public void reset() { super.reset(); curBlockArea = null; |