Browse Source

Merged branch Temp_InlineContainer back into trunk


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1562429 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_0
Vincent Hennebert 10 years ago
parent
commit
cdc0905289
37 changed files with 1673 additions and 551 deletions
  1. 17
    0
      src/java/org/apache/fop/area/AreaTreeParser.java
  2. 7
    8
      src/java/org/apache/fop/area/inline/Container.java
  3. 74
    106
      src/java/org/apache/fop/fo/flow/InlineContainer.java
  4. 0
    3
      src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
  5. 28
    0
      src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
  6. 12
    12
      src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
  7. 9
    54
      src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
  8. 8
    54
      src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
  9. 3
    0
      src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
  10. 1
    0
      src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
  11. 19
    0
      src/java/org/apache/fop/layoutmgr/LayoutManager.java
  12. 5
    7
      src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
  13. 112
    0
      src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java
  14. 1
    1
      src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java
  15. 9
    0
      src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
  16. 0
    54
      src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java
  17. 326
    0
      src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java
  18. 9
    0
      src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java
  19. 1
    0
      src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml
  20. 20
    2
      src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
  21. 8
    57
      src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
  22. 26
    58
      src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
  23. 1
    0
      src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
  24. 11
    57
      src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
  25. 102
    5
      test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
  26. 6
    7
      test/layoutengine/disabled-testcases.xml
  27. 244
    0
      test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml
  28. 74
    0
      test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml
  29. 154
    0
      test/layoutengine/standard-testcases/inline-container_alignment.xml
  30. 56
    0
      test/layoutengine/standard-testcases/inline-container_basic.xml
  31. 0
    65
      test/layoutengine/standard-testcases/inline-container_block_nested.xml
  32. 72
    0
      test/layoutengine/standard-testcases/inline-container_bpd.xml
  33. 74
    0
      test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml
  34. 66
    0
      test/layoutengine/standard-testcases/inline-container_ipd-auto.xml
  35. 61
    0
      test/layoutengine/standard-testcases/inline-container_ipd-percent.xml
  36. 49
    0
      test/layoutengine/standard-testcases/inline-container_keeps.xml
  37. 8
    1
      test/layoutengine/testcase2checks.xsl

+ 17
- 0
src/java/org/apache/fop/area/AreaTreeParser.java View File

@@ -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) {

+ 7
- 8
src/java/org/apache/fop/area/inline/Container.java View File

@@ -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;
}


+ 74
- 106
src/java/org/apache/fop/fo/flow/InlineContainer.java View File

@@ -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,152 +111,128 @@ 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();

+ 0
- 3
src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java View File

@@ -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 --------- //

+ 28
- 0
src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java View File

@@ -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

+ 12
- 12
src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java View File

@@ -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));
}



+ 9
- 54
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java View File

@@ -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;
@@ -994,51 +994,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
return true;
}

/** {@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) {

+ 8
- 54
src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java View File

@@ -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) {
@@ -457,51 +456,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
return true;
}

/** {@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() {

+ 3
- 0
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java View File

@@ -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;
}

+ 1
- 0
src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java View File

@@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
*/
public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) {
super(node);
setGeneratesBlockArea(true);
setParent(pslm);
}


+ 19
- 0
src/java/org/apache/fop/layoutmgr/LayoutManager.java View File

@@ -177,6 +177,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

+ 5
- 7
src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java View File

@@ -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));
}
}


+ 112
- 0
src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java View File

@@ -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();

}

+ 1
- 1
src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java View File

@@ -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();
}


+ 9
- 0
src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java View File

@@ -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 --------- //

/**

+ 0
- 54
src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java View File

@@ -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;
}

}

+ 326
- 0
src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java View File

@@ -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;
}

}

+ 9
- 0
src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java View File

@@ -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);

}

+ 1
- 0
src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml View File

@@ -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>

+ 20
- 2
src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java View File

@@ -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.
*

+ 8
- 57
src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java View File

@@ -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);
}
}

}


+ 26
- 58
src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java View File

@@ -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.
*
@@ -654,51 +667,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements
return getListItemFO().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);
}
}

/** {@inheritDoc} */
@Override
public void reset() {

+ 1
- 0
src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java View File

@@ -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;

+ 11
- 57
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java View File

@@ -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;
@@ -521,51 +520,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();

+ 102
- 5
test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java View File

@@ -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);
}
}

}

+ 6
- 7
test/layoutengine/disabled-testcases.xml View File

@@ -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>

+ 244
- 0
test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml View File

@@ -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>

+ 74
- 0
test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml View File

@@ -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>

+ 154
- 0
test/layoutengine/standard-testcases/inline-container_alignment.xml View File

@@ -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>

+ 56
- 0
test/layoutengine/standard-testcases/inline-container_basic.xml View File

@@ -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>

+ 0
- 65
test/layoutengine/standard-testcases/inline-container_block_nested.xml View File

@@ -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>

+ 72
- 0
test/layoutengine/standard-testcases/inline-container_bpd.xml View File

@@ -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>

+ 74
- 0
test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml View File

@@ -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>

+ 66
- 0
test/layoutengine/standard-testcases/inline-container_ipd-auto.xml View File

@@ -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>

+ 61
- 0
test/layoutengine/standard-testcases/inline-container_ipd-percent.xml View File

@@ -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>

+ 49
- 0
test/layoutengine/standard-testcases/inline-container_keeps.xml View File

@@ -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>

+ 8
- 1
test/layoutengine/testcase2checks.xsl View File

@@ -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>

Loading…
Cancel
Save