aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java17
-rw-r--r--src/java/org/apache/fop/area/inline/Container.java15
-rw-r--r--src/java/org/apache/fop/fo/flow/InlineContainer.java180
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java28
-rw-r--r--src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java24
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java63
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java62
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java1
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutManager.java19
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java12
-rw-r--r--src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java112
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java54
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java326
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml1
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java22
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java65
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java84
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java1
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java68
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java107
-rw-r--r--test/layoutengine/disabled-testcases.xml13
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml244
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml74
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment.xml154
-rw-r--r--test/layoutengine/standard-testcases/inline-container_basic.xml56
-rw-r--r--test/layoutengine/standard-testcases/inline-container_block_nested.xml65
-rw-r--r--test/layoutengine/standard-testcases/inline-container_bpd.xml72
-rw-r--r--test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml74
-rw-r--r--test/layoutengine/standard-testcases/inline-container_ipd-auto.xml66
-rw-r--r--test/layoutengine/standard-testcases/inline-container_ipd-percent.xml61
-rw-r--r--test/layoutengine/standard-testcases/inline-container_keeps.xml49
-rw-r--r--test/layoutengine/testcase2checks.xsl9
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&lt;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>