diff options
37 files changed, 1673 insertions, 551 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; diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java index e739221b0..ad0804af5 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java @@ -21,8 +21,12 @@ package org.apache.fop.layoutengine; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; @@ -41,10 +45,16 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import org.apache.fop.DebugHelper; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; @@ -53,6 +63,8 @@ import org.apache.fop.apps.FormattingResults; import org.apache.fop.area.AreaTreeModel; import org.apache.fop.area.AreaTreeParser; import org.apache.fop.area.RenderPagesModel; +import org.apache.fop.events.Event; +import org.apache.fop.events.EventListener; import org.apache.fop.events.model.EventSeverity; import org.apache.fop.fonts.FontInfo; import org.apache.fop.intermediate.IFTester; @@ -131,6 +143,8 @@ public class LayoutEngineTestCase { Fop fop; FopFactory effFactory; + EventsChecker eventsChecker = new EventsChecker( + new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); try { Document testDoc = testAssistant.loadTestCase(testFile); effFactory = testAssistant.getFopFactory(testDoc); @@ -146,8 +160,7 @@ public class LayoutEngineTestCase { //Setup FOP for area tree rendering FOUserAgent ua = effFactory.newFOUserAgent(); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); + ua.getEventBroadcaster().addEventListener(eventsChecker); XMLRenderer atrenderer = new XMLRenderer(ua); atrenderer.setContentHandler(athandler); @@ -167,7 +180,60 @@ public class LayoutEngineTestCase { } FormattingResults results = fop.getResults(); LayoutResult result = new LayoutResult(doc, elCollector, results); - checkAll(effFactory, testFile, result); + checkAll(effFactory, testFile, result, eventsChecker); + } + + private static class EventsChecker implements EventListener { + + private final List<Event> events = new ArrayList<Event>(); + + private final EventListener defaultListener; + + /** + * @param fallbackListener the listener to which this class will pass through + * events that are not being checked + */ + public EventsChecker(EventListener fallbackListener) { + this.defaultListener = fallbackListener; + } + + public void processEvent(Event event) { + events.add(event); + } + + public void checkEvent(String expectedKey, Map<String, String> expectedParams) { + boolean eventFound = false; + for (Iterator<Event> iter = events.iterator(); !eventFound && iter.hasNext();) { + Event event = iter.next(); + if (event.getEventKey().equals(expectedKey)) { + eventFound = true; + iter.remove(); + checkParameters(event, expectedParams); + } + } + if (!eventFound) { + fail("Event did not occur but was expected to: " + expectedKey + expectedParams); + } + } + + private void checkParameters(Event event, Map<String, String> expectedParams) { + Map<String, Object> actualParams = event.getParams(); + for (Map.Entry<String, String> expectedParam : expectedParams.entrySet()) { + assertTrue("Event \"" + event.getEventKey() + + "\" is missing parameter \"" + expectedParam.getKey() + '"', + actualParams.containsKey(expectedParam.getKey())); + assertEquals("Event \"" + event.getEventKey() + + "\" has wrong value for parameter \"" + expectedParam.getKey() + "\";", + actualParams.get(expectedParam.getKey()).toString(), + expectedParam.getValue()); + } + } + + public void emitUncheckedEvents() { + for (Event event : events) { + defaultListener.processEvent(event); + } + } } /** @@ -177,8 +243,8 @@ public class LayoutEngineTestCase { * @param result The layout results * @throws TransformerException if a problem occurs in XSLT/JAXP */ - protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result) - throws TransformerException { + protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result, + EventsChecker eventsChecker) throws TransformerException { Element testRoot = testAssistant.getTestRoot(testFile); NodeList nodes; @@ -196,6 +262,13 @@ public class LayoutEngineTestCase { Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree()); ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument); } + + nodes = testRoot.getElementsByTagName("event-checks"); + if (nodes.getLength() > 0) { + Element eventChecks = (Element) nodes.item(0); + doEventChecks(eventChecks, eventsChecker); + } + eventsChecker.emitUncheckedEvents(); } private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML) @@ -254,4 +327,28 @@ public class LayoutEngineTestCase { } } + private void doEventChecks(Element eventChecks, EventsChecker eventsChecker) { + NodeList events = eventChecks.getElementsByTagName("event"); + for (int i = 0; i < events.getLength(); i++) { + Element event = (Element) events.item(i); + NamedNodeMap attributes = event.getAttributes(); + Map<String, String> params = new HashMap<String, String>(); + String key = null; + for (int j = 0; j < attributes.getLength(); j++) { + Node attribute = attributes.item(j); + String name = attribute.getNodeName(); + String value = attribute.getNodeValue(); + if ("key".equals(name)) { + key = value; + } else { + params.put(name, value); + } + } + if (key == null) { + throw new RuntimeException("An event element must have a \"key\" attribute"); + } + eventsChecker.checkEvent(key, params); + } + } + } diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 5208fa91d..b96ee1b77 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -91,16 +91,15 @@ NullPointerException.</description> </testcase> <testcase> - <name>inline-container is not implemented, yet.</name> - <file>inline-container_block_nested.xml</file> - <description>inline-container is not implemented, yet. Content of an - inline-container will get swallowed. The test case contains no checks.</description> + <name>Keeps on inline-container are not implemented, yet.</name> + <file>inline-container_keeps.xml</file> + <description>The keep-with-previous and keep-with-next properties have not been implemented on + inline-container yet. They will be treated as if they had the value "auto".</description> </testcase> <testcase> - <name>inline-container is not implemented, yet.</name> + <name>Borders and padding inline-container are not implemented, yet.</name> <file>inline-container_border_padding.xml</file> - <description>inline-container is not implemented, yet. Content of an - inline-container will get swallowed.</description> + <description>Borders and paddings on an inline-container will be ignored.</description> </testcase> <testcase> <name>inline letter-spacing</name> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml new file mode 100644 index 000000000..3e696a696 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the alignment-adjust property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="text-before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="text-before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="after-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="after-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="text-after-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="text-after-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="middle":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="middle"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="ideographic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="ideographic"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="alphabetic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="alphabetic"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="hanging":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="hanging"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="mathematical":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="mathematical"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="30pt":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="30pt"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-adjust="10%":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="-10%" dominant-baseline="text-before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- before-edge --> + <eval expected="37416" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- text-before-edge --> + <eval expected="37416" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- after-edge --> + <eval expected="31284" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="20184" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- text-after-edge --> + <eval expected="31284" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="20184" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- middle --> + <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- ideographic --> + <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="11544" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- alphabetic --> + <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8664" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- hanging --> + <eval expected="31656" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="2856" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- mathematical --> + <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- 30pt --> + <eval expected="49764" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="38664" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- 10% --> + <eval expected="38856" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="10056" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml new file mode 100644 index 000000000..53b9be0a9 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the alignment-baseline property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-baseline="before-edge":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-baseline="before-edge"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">alignment-baseline="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-baseline="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- before-edge --> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8850" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_alignment.xml b/test/layoutengine/standard-testcases/inline-container_alignment.xml new file mode 100644 index 000000000..153d9a9c4 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the inline-container is properly aligned with the parent area. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="320pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>By default the alignment is with the baseline of the first descendant + line-area.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block font-size="20pt">Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block space-before="20pt" space-before.conditionality="retain"> + <fo:block-container space-before="10pt" space-before.conditionality="retain" + border="4pt solid" padding="2pt" start-indent="6pt" end-indent="6pt"> + <fo:block font-size="20pt" start-indent="0" end-indent="0">Inside the + inline-container.</fo:block> + </fo:block-container> + </fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container has no line-area descendant. The after edge of its + allocation rectangle should be aligned with the baseline.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block border="6pt solid" padding="2pt" start-indent="8pt" end-indent="8pt"/> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>The first line-area descendant is in fo:list-item-body.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:list-block provisional-distance-between-starts="10pt" + provisional-label-separation="5pt"> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block/> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block> + <fo:block font-size="8pt">List item</fo:block> + </fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container contains a block that contains an inline that contains a + block.</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"> + <fo:block><fo:inline><fo:block>inline</fo:block></fo:inline></fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <!-- Page sequence 1 --> + <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <!-- + The font used is Helvetica, ascender 718, descender −207. + Default font size is 12pt => baseline offset = 718 * 12 = 8616mpt + Default line height is 1.2 * font-size + => space-before = (line-height − (ascender − descender) * font-size) / 2 + = (1.2 * 12000 − (718 + 207) * 12) / 2 + = 1650 + At font size 20, the distance between the before-edge of the inline-container’s child block + area and the first line area’s baseline is space-before + baseline-offset = 2750 + 14360 = 17110 + So the word "Before:" must be offset by 17110 − 8616 = 8494 + --> + <eval expected="Before: " xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]"/> + <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + + <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <eval expected=" After the" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]"/> + <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@baseline"/> + + <!-- Page sequence 2 --> + <eval expected="34494" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@baseline"/> + <eval expected="104000" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 3 --> + <!-- bpd = max(text ascent, ascent of inline-container) + text descent + = 16000 + 207 * 12 --> + <eval expected="18484" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="7384" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="16000" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 4 --> + <eval expected="11372" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="9600" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="1772" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- Page sequence 5 --> + <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="1650" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_basic.xml b/test/layoutengine/standard-testcases/inline-container_basic.xml new file mode 100644 index 000000000..b2dfcc6e5 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_basic.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Test for a basic implementation of fo:inline-container. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="320pt" page-width="420pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="80pt" height="50pt"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <!-- The inline-container’s area is there, at the right place --> + <eval expected="viewport" xpath="local-name(//flow/block/lineArea/*[position()=2])"/> + <!-- It has the right properties --> + <eval expected="true" xpath="//viewport/@is-viewport-area"/> + <eval expected="80000" xpath="//viewport/@ipd"/> + <eval expected="50000" xpath="//viewport/@bpd"/> + <eval expected="1" xpath="count(//viewport/*)"/> + <eval expected="container" xpath="local-name(//viewport/*)"/> + <!-- Its content is there too --> + <eval expected="1" xpath="count(//container/block)"/> + <eval expected="80000" xpath="//container/block/@ipd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_block_nested.xml b/test/layoutengine/standard-testcases/inline-container_block_nested.xml deleted file mode 100644 index cf4ebf486..000000000 --- a/test/layoutengine/standard-testcases/inline-container_block_nested.xml +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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$ --> -<testcase> - <info> - <p> - This test checks nested blocks with inline-containers and indents. - </p> - </info> - <fo> - <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg"> - <fo:layout-master-set> - <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - <fo:page-sequence master-reference="normal" white-space-collapse="true"> - <fo:flow flow-name="xsl-region-body"> - <fo:block margin-left="12pt">outer block - <fo:inline-container start-indent="18pt"> - <fo:block margin-left="13pt">inner block</fo:block> - </fo:inline-container> - </fo:block> - </fo:flow> - </fo:page-sequence> - </fo:root> - </fo> - <checks> - <!-- First block, no gap --> - <!--eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-start"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-end"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-before"/> - <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-after"/> - <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bap"/> - <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipd"/> - <eval expected="360000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipda"/> - <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpd"/> - <eval expected="34400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpda"/--> - <!-- Nested block of first block --> - <!--eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-start"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-end"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-before"/> - <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-after"/> - <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bap"/> - <eval expected="340000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipd"/> - <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipda"/> - <eval expected="14400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpd"/> - <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpda"/--> - </checks> -</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_bpd.xml b/test/layoutengine/standard-testcases/inline-container_bpd.xml new file mode 100644 index 000000000..8f808c030 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_bpd.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that block-progression-dimension on fo:inline-container is properly handled. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="60pt"> + <fo:block>This text inside inline-container should fit on four lines.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="70pt" height="35pt" overflow="hidden"> + <fo:block>This text overflows the inline-container in the + block-progression-direction.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="80pt"> + <fo:block space-after="10pt">Block 1</fo:block> + <fo:block space-before="20pt" space-after="10pt" + space-after.conditionality="retain">Block 2</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="40000" xpath="//pageSequence[1]//viewport/@bpd"/> + + <eval expected="35000" xpath="//pageSequence[2]//viewport/@bpd"/> + <true xpath="//pageSequence[2]//viewport/@clip"/> + + <eval expected="50000" xpath="//pageSequence[3]//viewport/@bpd"/> + </checks> + + <event-checks> + <event key="viewportBPDOverflow" elementName="fo:inline-container" amount="15000" clip="true"/> + </event-checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml new file mode 100644 index 000000000..402eb806d --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that the dominant-baseline property on inline-container behaves properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="170pt" page-width="220pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">dominant-baseline="alphabetic":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="baseline"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block space-after="10pt">dominant-baseline="central":</fo:block> + <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt" + alignment-adjust="baseline" dominant-baseline="central"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After the inline-container.</fo:block> + </fo:flow> + </fo:page-sequence> + + </fo:root> + </fo> + + <checks> + + <!-- alphabetic --> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="8664" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + <!-- central --> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/> + <eval expected="5784" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/> + <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/> + <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/> + <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml new file mode 100644 index 000000000..c19544809 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + When inline-progression-dimension has been left to auto on fo:inline-container, fall back to + the IPD of the nearest ancestor reference-area. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container height="20pt"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container space-before="10pt" start-indent="100pt" width="100pt"> + <fo:block start-indent="0"> + Before: <fo:inline-container> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After. + </fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="3" xpath="count(//pageSequence[1]//flow/block/lineArea)"/> + <eval expected="300000" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@ipd"/> + <eval expected="3" xpath="count(//pageSequence[2]//flow/block/block/block/lineArea)"/> + <eval expected="100000" xpath="//pageSequence[2]//flow/block/block/block/lineArea[2]/viewport/@ipd"/> + </checks> + + <event-checks> + <event key="inlineContainerAutoIPDNotSupported" fallback="300.0"/> + <event key="inlineContainerAutoIPDNotSupported" fallback="100.0"/> + </event-checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml new file mode 100644 index 000000000..aa681d134 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Checks that percentage values for the dimensions of an fo:inline-container are resolved + properly. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Before: <fo:inline-container width="50%" height="50%"> + <fo:block>Text inside inline-container.</fo:block> + </fo:inline-container> After.</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container space-before="10pt" start-indent="50pt" width="200pt"> + <fo:block start-indent="0"> + Before: <fo:inline-container width="30%" height="30%"> + <fo:block>Inside the inline-container.</fo:block> + </fo:inline-container> After. + </fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="150000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@ipd"/> + <eval expected="10000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@bpd"/> + <eval expected="60000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@ipd"/> + <eval expected="20000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@bpd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/inline-container_keeps.xml b/test/layoutengine/standard-testcases/inline-container_keeps.xml new file mode 100644 index 000000000..e946f13f3 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_keeps.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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$ --> +<testcase> + <info> + <p> + Test for keeps on fo:inline-container. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This inline-container must be kept with the word before: <fo:inline-container + id="inline-container" width="100pt" keep-with-previous.within-line="always" + background-color="#F0F0F0"> + <fo:block>Inline-container</fo:block> + </fo:inline-container></fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + + <checks> + <eval expected="before: " xpath="//pageSequence[1]//flow/block/lineArea[2]/text[1]"/> + <eval expected="inline-container" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@prod-id"/> + </checks> +</testcase> diff --git a/test/layoutengine/testcase2checks.xsl b/test/layoutengine/testcase2checks.xsl index ae3a8fe72..25dfcc810 100644 --- a/test/layoutengine/testcase2checks.xsl +++ b/test/layoutengine/testcase2checks.xsl @@ -25,6 +25,7 @@ <checks> <xsl:apply-templates select="checks"/> <xsl:apply-templates select="if-checks"/> + <xsl:apply-templates select="event-checks"/> </checks> </xsl:template> @@ -40,7 +41,13 @@ <xsl:copy-of select="*"/> </if-checks> </xsl:template> - + +<xsl:template match="event-checks"> + <event-checks> + <xsl:copy-of select="*"/> + </event-checks> +</xsl:template> + <xsl:template match="text()" /> </xsl:stylesheet> |