git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1562429 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -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) { |
@@ -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; | |||
} | |||
@@ -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(); |
@@ -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 --------- // |
@@ -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 |
@@ -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)); | |||
} | |||
@@ -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) { |
@@ -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() { |
@@ -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; | |||
} |
@@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager | |||
*/ | |||
public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) { | |||
super(node); | |||
setGeneratesBlockArea(true); | |||
setParent(pslm); | |||
} | |||
@@ -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 |
@@ -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)); | |||
} | |||
} | |||
@@ -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(); | |||
} |
@@ -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(); | |||
} | |||
@@ -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 --------- // | |||
/** |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} |
@@ -20,4 +20,5 @@ | |||
<message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message> | |||
<message key="leaderWithoutContent">fo:leader is set to "use-content" but has no content.{{locator}}</message> | |||
<message key="lineOverflows">The contents of {elementName} line {line} exceed the available area in the inline-progression direction by {overflowLength,choice,50000#{overflowLength} millipoints|50000<more than 50 points}.{{locator}}</message> | |||
<message key="inlineContainerAutoIPDNotSupported">A value of "auto" for the inline-progression-dimension property on fo:inline-container is not supported. Falling back to {fallback}pt.{{locator}}</message> | |||
</catalogue> |
@@ -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. | |||
* |
@@ -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); | |||
} | |||
} | |||
} | |||
@@ -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() { |
@@ -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; |
@@ -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(); |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |