/** the area's block-progression-dimension */
protected int bpd;
+ protected int effectiveIPD = -1;
+
/**
* Resolved bidirectional level for area.
*/
return getBorderAndPaddingWidthStart() + getIPD() + getBorderAndPaddingWidthEnd();
}
+ public int getEffectiveAllocIPD() {
+ return getBorderAndPaddingWidthStart() + getEffectiveIPD() + getBorderAndPaddingWidthEnd();
+ }
+
/**
* Get the allocation block progression dimension of this area.
* This adds the content, borders, padding and spaces to find the
sb.append("}");
return sb.toString();
}
+
+ public int getEffectiveIPD() {
+ return 0;
+ }
+
+ public void activateEffectiveIPD() {
+ if (effectiveIPD != -1) {
+ ipd = effectiveIPD;
+ }
+ }
}
return location;
}
+ // maybe this can be done in the parent?
+ public int getEffectiveIPD() {
+ int eIPD = super.getEffectiveIPD();
+ if (eIPD != 0) {
+ effectiveIPD = eIPD;
+ }
+ return eIPD;
+ }
+
+ // maybe this can be done in the parent?
+ public void activateEffectiveIPD() {
+ super.activateEffectiveIPD();
+ if (effectiveIPD != -1) {
+ ipd = effectiveIPD;
+ }
+ }
}
public int getYOffset() {
return yOffset;
}
+
+ public int getEffectiveIPD() {
+ int maxIPD = 0;
+ if (children != null) {
+ for (Area area : children) {
+ int effectiveIPD = area.getEffectiveIPD();
+ if (effectiveIPD > maxIPD) {
+ maxIPD = effectiveIPD;
+ }
+ }
+ }
+ return maxIPD;
+ }
+
+ public void activateEffectiveIPD() {
+ if (children != null) {
+ for (Area area : children) {
+ area.activateEffectiveIPD();
+ }
+ }
+ }
}
return null;
}
}
+
+ public int getEffectiveIPD() {
+ return getIPD();
+ }
}
// been handled, modifying the line indent
}
}
+
+ public int getEffectiveIPD() {
+ int maxIPD = 0;
+ if (inlineAreas != null) {
+ for (Area area : inlineAreas) {
+ int effectiveIPD = area.getEffectiveIPD();
+ if (effectiveIPD > maxIPD) {
+ maxIPD = effectiveIPD;
+ }
+ }
+ }
+ return maxIPD;
+ }
+
}
--- /dev/null
+/*
+ * 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.area;
+
+public class SideFloat extends Block {
+
+ private static final long serialVersionUID = 2058594336594375047L;
+
+ public SideFloat() {
+ setAreaClass(Area.CLASS_SIDE_FLOAT);
+ addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
+ setPositioning(Block.ABSOLUTE);
+ }
+}
this.content = (Area) in.readObject();
}
+ public int getEffectiveIPD() {
+ return getIPD();
+ }
}
}
}
+ public int getEffectiveIPD() {
+ return getIPD();
+ }
}
import java.util.Stack;
import org.apache.fop.fo.flow.Block;
+import org.apache.fop.fo.flow.Float;
import org.apache.fop.util.CharUtilities;
/**
charIter = new RecursiveCharIterator(fo, firstTextNode);
inWhiteSpace = false;
+ if (firstTextNode.siblings != null && firstTextNode.siblings[0] != null
+ && firstTextNode.siblings[0].getNameId() == Constants.FO_FLOAT) {
+ inWhiteSpace = ((Float) firstTextNode.siblings[0]).getInWhiteSpace();
+ }
if (fo == currentBlock
|| currentBlock == null
firstWhiteSpaceInSeq = null;
}
}
+ if (nextChild instanceof Float) {
+ ((Float) nextChild).setInWhiteSpace(inWhiteSpace);
+ }
}
/**
*/
public class Float extends FObj {
// The value of properties relevant for fo:float (commented out for performance.
- // private int float_;
- // private int clear;
+ private int foFloat;
+ private int clear;
// End of property values
-
- private static boolean notImplementedWarningGiven;
+ private boolean inWhiteSpace;
/**
* Base constructor
*/
public Float(FONode parent) {
super(parent);
-
- if (!notImplementedWarningGiven) {
- getFOValidationEventProducer().unimplementedFeature(this, getName(),
- getName(), getLocator());
- notImplementedWarningGiven = true;
- }
}
/** {@inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
- // No active properties -> Nothing to do.
+ super.bind(pList);
+ foFloat = pList.get(PR_FLOAT).getEnum();
+ clear = pList.get(PR_CLEAR).getEnum();
}
/**
public int getNameId() {
return FO_FLOAT;
}
+
+ public int getFloat() {
+ return foFloat;
+ }
+
+ public void setInWhiteSpace(boolean iws) {
+ inWhiteSpace = iws;
+ }
+
+ public boolean getInWhiteSpace() {
+ return inWhiteSpace;
+ }
}
}
}
+ public static class FloatPosition extends LeafPosition {
+ double bpdAdjust; // Percentage to adjust (stretch or shrink)
+ int difference;
+
+ FloatPosition(LayoutManager lm, int breakIndex, double bpdA, int diff) {
+ super(lm, breakIndex);
+ bpdAdjust = bpdA;
+ difference = diff;
+ }
+ }
+
/**
* Helper method, mainly used to improve debug/trace output
* @param breakClassId the {@link Constants} enum value.
}
// used by doLayout and getNextBlockList*
- private List<BlockSequence> blockLists;
+ protected List<BlockSequence> blockLists;
private boolean empty = true;
+ /** blockListIndex of the current BlockSequence in blockLists */
+ protected int blockListIndex;
+
/** desired text alignment */
protected int alignment;
//*** Phases 2 and 3 ***
log.debug("PLM> blockLists.size() = " + blockLists.size());
- for (int blockListIndex = 0; blockListIndex < blockLists.size(); blockListIndex++) {
+ for (blockListIndex = 0; blockListIndex < blockLists.size(); blockListIndex++) {
blockList = blockLists.get(blockListIndex);
//debug code start
alg.setConstantLineWidth(flowBPD);
int optimalPageCount = alg.findBreakingPoints(blockList, 1, true,
BreakingAlgorithm.ALL_BREAKS);
- if (Math.abs(alg.getIPDdifference()) > 1) {
+
+ if (alg.handlingFloat()) {
+ nextSequenceStartsOn = handleFloatLayout(alg, optimalPageCount, blockList, childLC);
+ } else if (Math.abs(alg.getIPDdifference()) > 1) {
addAreas(alg, optimalPageCount, blockList, blockList);
// *** redo Phase 1 ***
log.trace("IPD changes after page " + optimalPageCount);
for (int p = startPart; p < startPart + partCount; p++) {
PageBreakPosition pbp = alg.getPageBreaks().get(p);
- //Check the last break position for forced breaks
+ // Check the last break position for forced breaks
int lastBreakClass;
if (p == 0) {
lastBreakClass = effectiveList.getStartOn();
} else {
ListElement lastBreakElement = effectiveList.getElement(endElementIndex);
if (lastBreakElement.isPenalty()) {
- KnuthPenalty pen = (KnuthPenalty)lastBreakElement;
+ KnuthPenalty pen = (KnuthPenalty) lastBreakElement;
if (pen.getPenalty() == KnuthPenalty.INFINITE) {
/**
* That means that there was a keep.within-page="always", but that
}
}
- //the end of the new part
+ // the end of the new part
endElementIndex = pbp.getLeafPos();
// ignore the first elements added by the
// PageSequenceLayoutManager
- startElementIndex += (startElementIndex == 0)
- ? effectiveList.ignoreAtStart
- : 0;
+ startElementIndex += (startElementIndex == 0) ? effectiveList.ignoreAtStart : 0;
log.debug("PLM> part: " + (p + 1)
+ ", start at pos " + startElementIndex
int displayAlign = getCurrentDisplayAlign();
- //The following is needed by SpaceResolver.performConditionalsNotification()
- //further down as there may be important Position elements in the element list trailer
+ // The following is needed by SpaceResolver.performConditionalsNotification()
+ // further down as there may be important Position elements in the element list trailer
int notificationEndElementIndex = endElementIndex;
// ignore the last elements added by the
// PageSequenceLayoutManager
- endElementIndex -= (endElementIndex == (originalList.size() - 1))
- ? effectiveList.ignoreAtEnd
- : 0;
+ endElementIndex -= (endElementIndex == (originalList.size() - 1)) ? effectiveList.ignoreAtEnd : 0;
// ignore the last element in the page if it is a KnuthGlue
// object
- if (((KnuthElement) effectiveList.get(endElementIndex))
- .isGlue()) {
+ if (((KnuthElement) effectiveList.get(endElementIndex)).isGlue()) {
endElementIndex--;
}
}
// Handle SpaceHandling(Break)Positions, see SpaceResolver!
- SpaceResolver.performConditionalsNotification(effectiveList,
- startElementIndex, notificationEndElementIndex, lastBreak);
+ SpaceResolver.performConditionalsNotification(effectiveList, startElementIndex,
+ notificationEndElementIndex, lastBreak);
// Add areas now!
- addAreas(new KnuthPossPosIter(effectiveList,
- startElementIndex, endElementIndex + 1), childLC);
+ addAreas(new KnuthPossPosIter(effectiveList, startElementIndex, endElementIndex + 1), childLC);
} else {
- //no content for this part
+ // no content for this part
handleEmptyContent();
}
lastBreak = endElementIndex;
startElementIndex = pbp.getLeafPos() + 1;
}
+ if (alg.handlingFloat()) {
+ addAreasForFloats(alg, startPart, partCount, originalList, effectiveList, childLC, lastBreak,
+ startElementIndex, endElementIndex);
+ }
}
/**
* Notifies the layout managers about the space and conditional length situation based on
return nextSequenceStartsOn;
}
+ protected int handleFloatLayout(PageBreakingAlgorithm alg, int optimalPageCount, BlockSequence blockList,
+ LayoutContext childLC) {
+ throw new IllegalStateException();
+ }
+
+ protected void addAreasForFloats(PageBreakingAlgorithm alg, int startPart, int partCount,
+ BlockSequence originalList, BlockSequence effectiveList, final LayoutContext childLC,
+ int lastBreak, int startElementIndex, int endElementIndex) {
+ throw new IllegalStateException();
+ }
}
}
((AbstractLayoutManager) lm).possiblyRegisterMarkersForTables(markers, isStarting, isFirst, isLast);
}
+
+ public boolean handlingFloat() {
+ if (parentLayoutManager != null && parentLayoutManager instanceof AbstractLayoutManager) {
+ return ((AbstractLayoutManager) parentLayoutManager).handlingFloat();
+ }
+ return false;
+ }
}
elementIndex, previousIsBox, allowedBreaks).isBox();
if (activeNodeCount == 0) {
+ if (handlingFloat()) {
+ return handleFloat();
+ }
if (getIPDdifference() != 0) {
return handleIpdChange();
}
log.trace("\tline=" + line);
}
+ if (element.isForcedBreak() && handlingFloat()) {
+ disableFloatHandling(); // so that we do not create a float edge position later
+ }
// The line would be too long.
- if (r < -1 || element.isForcedBreak()) {
+ if (r < -1 || element.isForcedBreak() || handlingFloat()) {
deactivateNode(node, line);
}
}
}
+ createForcedNodes(node, line, elementIdx, difference, r, demerits, fitnessClass, availableShrink,
+ availableStretch, newWidth, newStretch, newShrink);
+ }
+
+ protected void createForcedNodes(KnuthNode node, int line, int elementIdx, int difference, double r,
+ double demerits, int fitnessClass, int availableShrink, int availableStretch, int newWidth,
+ int newStretch, int newShrink) {
if (r <= -1) {
log.debug("Considering tooLong, demerits=" + demerits);
if (lastTooLong == null || demerits < lastTooLong.totalDemerits) {
} else {
if (lastTooShort == null || demerits <= lastTooShort.totalDemerits) {
if (considerTooShort) {
- //consider possibilities which are too short
- best.addRecord(demerits, node, r,
- availableShrink, availableStretch,
- difference, fitnessClass);
+ // consider possibilities which are too short
+ best.addRecord(demerits, node, r, availableShrink, availableStretch, difference,
+ fitnessClass);
}
lastTooShort = createNode(elementIdx, line + 1, fitnessClass,
newWidth, newStretch, newShrink,
return this.alignmentLast;
}
+ protected boolean handlingFloat() {
+ return false;
+ }
+
+ protected int handleFloat() {
+ throw new IllegalStateException();
+ }
+
+ protected void disableFloatHandling() {
+ throw new IllegalStateException();
+ }
}
--- /dev/null
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.SideFloat;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.Float;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.layoutmgr.inline.FloatLayoutManager;
+import org.apache.fop.layoutmgr.inline.KnuthInlineBox;
+
+public class FloatContentLayoutManager extends SpacedBorderedPaddedBlockLayoutManager {
+
+ private SideFloat floatContentArea;
+ private int side;
+ private int yOffset;
+
+ public FloatContentLayoutManager(Float node) {
+ super(node);
+ generatesReferenceArea = true;
+ side = node.getFloat();
+ }
+
+ public Keep getKeepTogether() {
+ return getParentKeepTogether();
+ }
+
+ public Keep getKeepWithNext() {
+ return Keep.KEEP_AUTO;
+ }
+
+ public Keep getKeepWithPrevious() {
+ return Keep.KEEP_ALWAYS;
+ }
+
+ public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
+ floatContentArea = new SideFloat();
+ AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
+ flush();
+ }
+
+ public void addChildArea(Area childArea) {
+ floatContentArea.addChildArea(childArea);
+ floatContentArea.setBPD(childArea.getAllocBPD());
+ int effectiveContentIPD = childArea.getEffectiveAllocIPD();
+ int contentIPD = childArea.getIPD();
+ int xOffset = childArea.getBorderAndPaddingWidthStart();
+ floatContentArea.setIPD(effectiveContentIPD);
+ childArea.activateEffectiveIPD();
+ if (side == Constants.EN_END || side == Constants.EN_RIGHT) {
+ floatContentArea.setXOffset(xOffset + contentIPD - effectiveContentIPD);
+ } else if (side == Constants.EN_START || side == Constants.EN_LEFT) {
+ floatContentArea.setXOffset(xOffset);
+ }
+ LayoutManager lm = parentLayoutManager;
+ while (!lm.getGeneratesReferenceArea()) {
+ lm = lm.getParent();
+ }
+ yOffset = lm.getParentArea(floatContentArea).getBPD();
+ lm.addChildArea(floatContentArea);
+ if (side == Constants.EN_END || side == Constants.EN_RIGHT) {
+ lm.getPSLM().setEndIntrusionAdjustment(effectiveContentIPD);
+ } else if (side == Constants.EN_START || side == Constants.EN_LEFT) {
+ lm.getPSLM().setStartIntrusionAdjustment(effectiveContentIPD);
+ }
+ }
+
+ public static List<FloatContentLayoutManager> checkForFloats(List<ListElement> elemenList,
+ int startIndex, int endIndex) {
+ ListIterator<ListElement> iter = elemenList.listIterator(startIndex);
+ List<FloatContentLayoutManager> floats = new ArrayList<FloatContentLayoutManager>();
+ while (iter.nextIndex() <= endIndex) {
+ ListElement element = iter.next();
+ if (element instanceof KnuthInlineBox && ((KnuthInlineBox) element).isFloatAnchor()) {
+ floats.add(((KnuthInlineBox) element).getFloatContentLM());
+ } else if (element instanceof KnuthBlockBox && ((KnuthBlockBox) element).hasFloatAnchors()) {
+ floats.addAll(((KnuthBlockBox) element).getFloatContentLMs());
+ }
+ }
+ if (floats.isEmpty()) {
+ return Collections.emptyList();
+ } else {
+ return floats;
+ }
+ }
+
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return null;
+ }
+
+ public void processAreas(LayoutContext layoutContext) {
+ if (getParent() instanceof FloatLayoutManager) {
+ FloatLayoutManager flm = (FloatLayoutManager) getParent();
+ flm.processAreas(layoutContext);
+ }
+ }
+
+ public int getFloatHeight() {
+ return floatContentArea.getAllocBPD();
+ }
+
+ public int getFloatYOffset() {
+ return yOffset;
+ }
+}
/** Array of areas currently being filled stored by area class */
private final BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX];
+ private boolean handlingFloat;
+
/**
* This is the top level layout manager.
* It is created by the PageSequence FO.
*/
@Override
public void addChildArea(Area childArea) {
+ if (childArea instanceof BlockParent && handlingFloat()) {
+ BlockParent bp = (BlockParent) childArea;
+ bp.setXOffset(getPSLM().getStartIntrusionAdjustment());
+ }
getParentArea(childArea);
addChildToArea(childArea,
this.currentAreas[childArea.getAreaClass()]);
BlockParent parentArea = null;
int aclass = childArea.getAreaClass();
- if (aclass == Area.CLASS_NORMAL) {
+ if (aclass == Area.CLASS_NORMAL || aclass == Area.CLASS_SIDE_FLOAT) {
parentArea = getCurrentPV().getCurrentFlow();
} else if (aclass == Area.CLASS_BEFORE_FLOAT) {
parentArea = getCurrentPV().getBodyRegion().getBeforeFloat();
*/
@Override
public int getContentAreaIPD() {
- return getCurrentPV().getCurrentSpan().getColumnWidth();
+ int flowIPD = getPSLM().getCurrentColumnWidth();
+ return flowIPD;
}
/**
return true;
}
+ public void handleFloatOn() {
+ handlingFloat = true;
+ }
+
+ public void handleFloatOff() {
+ handlingFloat = false;
+ }
+
+ public boolean handlingFloat() {
+ return handlingFloat;
+ }
}
*/
private int bpd;
private List<FootnoteBodyLayoutManager> footnoteList;
+ private List<FloatContentLayoutManager> floatContentLMs;
/** List of Knuth elements. This is a list of LinkedList elements. */
private List elementLists;
ipdRange = range;
bpd = bpdim;
footnoteList = new LinkedList<FootnoteBodyLayoutManager>();
+ floatContentLMs = new LinkedList<FloatContentLayoutManager>();
}
/**
ipdRange = MinOptMax.ZERO;
bpd = 0;
footnoteList = new LinkedList<FootnoteBodyLayoutManager>(list);
+ floatContentLMs = new LinkedList<FloatContentLayoutManager>();
+ }
+
+ public KnuthBlockBox(int width, List list, Position pos, boolean auxiliary,
+ List<FloatContentLayoutManager> fclms) {
+ super(width, pos, auxiliary);
+ ipdRange = MinOptMax.ZERO;
+ bpd = 0;
+ footnoteList = new LinkedList<FootnoteBodyLayoutManager>(list);
+ floatContentLMs = new LinkedList<FloatContentLayoutManager>(fclms);
}
/**
public int getBPD() {
return bpd;
}
+
+ public List<FloatContentLayoutManager> getFloatContentLMs() {
+ return floatContentLMs;
+ }
+
+ public boolean hasFloatAnchors() {
+ return (floatContentLMs.size() > 0);
+ }
}
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
+import org.apache.fop.fo.flow.Float;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.Inline;
import org.apache.fop.fo.flow.InlineContainer;
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.FloatLayoutManager;
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
registerMaker(FObjMixed.class, new Maker());
registerMaker(BidiOverride.class, new BidiOverrideLayoutManagerMaker());
registerMaker(Inline.class, new InlineLayoutManagerMaker());
- registerMaker(Footnote.class, new FootnodeLayoutManagerMaker());
+ registerMaker(Footnote.class, new FootnoteLayoutManagerMaker());
registerMaker(InlineContainer.class,
new InlineContainerLayoutManagerMaker());
registerMaker(BasicLink.class, new BasicLinkLayoutManagerMaker());
registerMaker(Title.class, new InlineLayoutManagerMaker());
registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker());
registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker());
+ registerMaker(Float.class, new FloatLayoutManagerMaker());
}
/**
}
/** a layout manager maker */
- public static class FootnodeLayoutManagerMaker extends Maker {
+ public static class FootnoteLayoutManagerMaker extends Maker {
/** {@inheritDoc} */
public void make(FONode node, List lms) {
lms.add(new FootnoteLayoutManager((Footnote) node));
}
}
+ public static class FloatLayoutManagerMaker extends Maker {
+ public void make(FONode node, List lms) {
+ lms.add(new FloatLayoutManager((Float) node));
+ }
+ }
+
}
package org.apache.fop.layoutmgr;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.RegionBody;
import org.apache.fop.fo.pagination.StaticContent;
+import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
import org.apache.fop.traits.MinOptMax;
private PageProvider pageProvider;
private Block separatorArea;
private boolean spanAllActive;
+ private boolean handlingStartOfFloat;
+ private boolean handlingEndOfFloat;
+ private int floatHeight;
+ private int floatYOffset;
/**
* The FlowLayoutManager object, which processes
/** {@inheritDoc} */
protected void updateLayoutContext(LayoutContext context) {
- int flowIPD = pslm.getCurrentPV().getCurrentSpan().getColumnWidth();
+ int flowIPD = pslm.getCurrentColumnWidth();
context.setRefIPD(flowIPD);
}
/** {@inheritDoc} */
protected int getNextBlockList(LayoutContext childLC, int nextSequenceStartsOn,
Position positionAtIPDChange, LayoutManager restartLM, List firstElements) {
- if (!firstPart) {
- // if this is the first page that will be created by
- // the current BlockSequence, it could have a break
- // condition that must be satisfied;
- // otherwise, we may simply need a new page
- handleBreakTrait(nextSequenceStartsOn);
- }
- firstPart = false;
- pageBreakHandled = true;
+ if (!handlingFloat()) {
+ if (!firstPart) {
+ // if this is the first page that will be created by
+ // the current BlockSequence, it could have a break
+ // condition that must be satisfied;
+ // otherwise, we may simply need a new page
+ handleBreakTrait(nextSequenceStartsOn);
+ }
+ firstPart = false;
+ pageBreakHandled = true;
- pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
- pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);
+ pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(), pslm.getCurrentPV()
+ .getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);
+ }
return super.getNextBlockList(childLC, nextSequenceStartsOn, positionAtIPDChange,
restartLM, firstElements);
}
// handle the footnote separator
handleFootnoteSeparator();
}
+
return contentList;
}
return true;
}
}
+
+ protected boolean handlingStartOfFloat() {
+ return handlingStartOfFloat;
+ }
+
+ protected void handleStartOfFloat(int fHeight, int fYOffset) {
+ handlingStartOfFloat = true;
+ handlingEndOfFloat = false;
+ floatHeight = fHeight;
+ floatYOffset = fYOffset;
+ childFLM.handleFloatOn();
+ }
+
+ protected int getFloatHeight() {
+ return floatHeight;
+ }
+
+ protected int getFloatYOffset() {
+ return floatYOffset;
+ }
+
+ protected boolean handlingEndOfFloat() {
+ return handlingEndOfFloat;
+ }
+
+ protected void handleEndOfFloat(int fHeight) {
+ handlingEndOfFloat = true;
+ handlingStartOfFloat = false;
+ floatHeight = fHeight;
+ childFLM.handleFloatOff();
+ }
+
+ protected boolean handlingFloat() {
+ return (handlingStartOfFloat || handlingEndOfFloat);
+ }
+
+ public int getOffsetDueToFloat() {
+ handlingEndOfFloat = false;
+ return floatHeight + floatYOffset;
+ }
+
+ protected int handleFloatLayout(PageBreakingAlgorithm alg, int optimalPageCount, BlockSequence blockList,
+ LayoutContext childLC) {
+ pageBreakHandled = true;
+ List firstElements = Collections.EMPTY_LIST;
+ KnuthNode floatNode = alg.getBestFloatEdgeNode();
+ int floatPosition = floatNode.position;
+ KnuthElement floatElem = alg.getElement(floatPosition);
+ Position positionAtBreak = floatElem.getPosition();
+ if (!(positionAtBreak instanceof SpaceResolver.SpaceHandlingBreakPosition)) {
+ throw new UnsupportedOperationException("Don't know how to restart at position" + positionAtBreak);
+ }
+ /* Retrieve the original position wrapped into this space position */
+ positionAtBreak = positionAtBreak.getPosition();
+ addAreas(alg, optimalPageCount, blockList, blockList);
+ blockLists.clear();
+ blockListIndex = -1;
+ LayoutManager restartAtLM = null;
+ if (positionAtBreak != null && positionAtBreak.getIndex() == -1) {
+ Position position;
+ Iterator iter = blockList.listIterator(floatPosition + 1);
+ do {
+ KnuthElement nextElement = (KnuthElement) iter.next();
+ position = nextElement.getPosition();
+ } while (position == null || position instanceof SpaceResolver.SpaceHandlingPosition
+ || position instanceof SpaceResolver.SpaceHandlingBreakPosition
+ && position.getPosition().getIndex() == -1);
+ LayoutManager surroundingLM = positionAtBreak.getLM();
+ while (position.getLM() != surroundingLM) {
+ position = position.getPosition();
+ }
+ restartAtLM = position.getPosition().getLM();
+ }
+ int nextSequenceStartsOn = getNextBlockList(childLC, Constants.EN_COLUMN, positionAtBreak,
+ restartAtLM, firstElements);
+ return nextSequenceStartsOn;
+ }
+
+ protected void addAreasForFloats(PageBreakingAlgorithm alg, int startPart, int partCount,
+ BlockSequence originalList, BlockSequence effectiveList, final LayoutContext childLC,
+ int lastBreak, int startElementIndex, int endElementIndex) {
+ FloatPosition pbp = alg.getFloatPosition();
+
+ // Check the last break position for forced breaks
+ int lastBreakClass;
+ if (startElementIndex == 0) {
+ lastBreakClass = effectiveList.getStartOn();
+ } else {
+ ListElement lastBreakElement = effectiveList.getElement(endElementIndex);
+ if (lastBreakElement.isPenalty()) {
+ KnuthPenalty pen = (KnuthPenalty) lastBreakElement;
+ if (pen.getPenalty() == KnuthPenalty.INFINITE) {
+ /**
+ * That means that there was a keep.within-page="always", but that
+ * it's OK to break at a column. TODO The break class is being
+ * abused to implement keep.within-column and keep.within-page.
+ * This is very misleading and must be revised.
+ */
+ lastBreakClass = Constants.EN_COLUMN;
+ } else {
+ lastBreakClass = pen.getBreakClass();
+ }
+ } else {
+ lastBreakClass = Constants.EN_COLUMN;
+ }
+ }
+
+ // the end of the new part
+ endElementIndex = pbp.getLeafPos();
+
+ // ignore the first elements added by the
+ // PageSequenceLayoutManager
+ startElementIndex += (startElementIndex == 0) ? effectiveList.ignoreAtStart : 0;
+
+ log.debug("PLM> part: " + (startPart + partCount + 1) + ", start at pos " + startElementIndex
+ + ", break at pos " + endElementIndex + ", break class = "
+ + getBreakClassName(lastBreakClass));
+
+ startPart(effectiveList, lastBreakClass);
+
+ int displayAlign = getCurrentDisplayAlign();
+
+ // The following is needed by SpaceResolver.performConditionalsNotification()
+ // further down as there may be important Position elements in the element list trailer
+ int notificationEndElementIndex = endElementIndex;
+
+ // ignore the last elements added by the
+ // PageSequenceLayoutManager
+ endElementIndex -= (endElementIndex == (originalList.size() - 1)) ? effectiveList.ignoreAtEnd : 0;
+
+ // ignore the last element in the page if it is a KnuthGlue
+ // object
+ if (((KnuthElement) effectiveList.get(endElementIndex)).isGlue()) {
+ endElementIndex--;
+ }
+
+ // ignore KnuthGlue and KnuthPenalty objects
+ // at the beginning of the line
+ startElementIndex = alg.par.getFirstBoxIndex(startElementIndex);
+
+ if (startElementIndex <= endElementIndex) {
+ if (log.isDebugEnabled()) {
+ log.debug(" addAreas from " + startElementIndex + " to " + endElementIndex);
+ }
+ // set the space adjustment ratio
+ childLC.setSpaceAdjust(pbp.bpdAdjust);
+ // add space before if display-align is center or bottom
+ // add space after if display-align is distribute and
+ // this is not the last page
+ if (pbp.difference != 0 && displayAlign == Constants.EN_CENTER) {
+ childLC.setSpaceBefore(pbp.difference / 2);
+ } else if (pbp.difference != 0 && displayAlign == Constants.EN_AFTER) {
+ childLC.setSpaceBefore(pbp.difference);
+ }
+
+ // Handle SpaceHandling(Break)Positions, see SpaceResolver!
+ SpaceResolver.performConditionalsNotification(effectiveList, startElementIndex,
+ notificationEndElementIndex, lastBreak);
+ // Add areas of lines, in the current page, before the float or during float
+ addAreas(new KnuthPossPosIter(effectiveList, startElementIndex, endElementIndex + 1), childLC);
+ // add areas for the float, if applicable
+ if (alg.handlingStartOfFloat()) {
+ for (int k = startElementIndex; k < endElementIndex + 1; k++) {
+ ListElement le = effectiveList.getElement(k);
+ if (le instanceof KnuthBlockBox) {
+ KnuthBlockBox kbb = (KnuthBlockBox) le;
+ for (FloatContentLayoutManager fclm : kbb.getFloatContentLMs()) {
+ fclm.processAreas(childLC);
+ int floatHeight = fclm.getFloatHeight();
+ int floatYOffset = fclm.getFloatYOffset();
+ PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) getTopLevelLM();
+ pslm.recordStartOfFloat(floatHeight, floatYOffset);
+ }
+ }
+ }
+ }
+ if (alg.handlingEndOfFloat()) {
+ PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) getTopLevelLM();
+ pslm.setEndIntrusionAdjustment(0);
+ pslm.setStartIntrusionAdjustment(0);
+ int effectiveFloatHeight = alg.getFloatHeight();
+ pslm.recordEndOfFloat(effectiveFloatHeight);
+ }
+ } else {
+ // no content for this part
+ handleEmptyContent();
+ }
+
+ pageBreakHandled = true;
+ }
}
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
+import org.apache.fop.layoutmgr.AbstractBreaker.FloatPosition;
import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
+import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode;
import org.apache.fop.layoutmgr.WhitespaceManagementPenalty.Variant;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.ListUtil;
private int currentKeepContext = Constants.EN_AUTO;
private KnuthNode lastBeforeKeepContextSwitch;
+ // just one float for now...
+ private boolean handlingStartOfFloat;
+ private boolean handlingEndOfFloat;
+ private int floatYOffset;
+ private int floatHeight;
+ private KnuthNode bestFloatEdgeNode;
+ private FloatPosition floatPosition;
+
/**
* Construct a page breaking algorithm.
* @param topLevelLM the top level layout manager
insertedFootnotesLength = 0;
footnoteListIndex = 0;
footnoteElementIndex = -1;
+ if (topLevelLM instanceof PageSequenceLayoutManager) {
+ PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) topLevelLM;
+ if (pslm.handlingStartOfFloat()) {
+ floatHeight = Math.min(pslm.getFloatHeight(), lineWidth - pslm.getFloatYOffset());
+ }
+ if (pslm.handlingEndOfFloat()) {
+ totalWidth += pslm.getOffsetDueToFloat();
+ }
+ }
}
/**
firstNewFootnoteIndex = footnotesList.size() - 1;
}
}
+ if (box instanceof KnuthBlockBox && ((KnuthBlockBox) box).hasFloatAnchors()) {
+ handlingStartOfFloat = true;
+ }
+ if (floatHeight != 0 && totalWidth >= floatHeight) {
+ handlingEndOfFloat = true;
+ }
}
/**
log.debug("BBA> difference=" + difference + " ratio=" + ratio
+ " position=" + bestActiveNode.position);
}
- insertPageBreakAsFirst(new PageBreakPosition(this.topLevelLM,
- bestActiveNode.position,
- firstListIndex, firstElementIndex,
- ((KnuthPageNode) bestActiveNode).footnoteListIndex,
- ((KnuthPageNode) bestActiveNode).footnoteElementIndex,
- ratio, difference));
+ if (handlingFloat() && floatPosition == null) {
+ floatPosition = new FloatPosition(this.topLevelLM, bestActiveNode.position, ratio, difference);
+ } else {
+ insertPageBreakAsFirst(new PageBreakPosition(this.topLevelLM, bestActiveNode.position,
+ firstListIndex, firstElementIndex, ((KnuthPageNode) bestActiveNode).footnoteListIndex,
+ ((KnuthPageNode) bestActiveNode).footnoteElementIndex, ratio, difference));
+ }
}
/** {@inheritDoc} */
}
return pageProvider.compareIPDs(line);
}
+
+ protected boolean handlingFloat() {
+ return (handlingStartOfFloat || handlingEndOfFloat);
+ }
+
+ protected void createForcedNodes(KnuthNode node, int line, int elementIdx, int difference, double r,
+ double demerits, int fitnessClass, int availableShrink, int availableStretch, int newWidth,
+ int newStretch, int newShrink) {
+ super.createForcedNodes(node, line, elementIdx, difference, r, demerits, fitnessClass,
+ availableShrink, availableStretch, newWidth, newStretch, newShrink);
+ if (handlingFloat()) {
+ if (bestFloatEdgeNode == null || demerits <= bestFloatEdgeNode.totalDemerits) {
+ bestFloatEdgeNode = createNode(elementIdx, line + 1, fitnessClass, newWidth, newStretch,
+ newShrink, r, availableShrink, availableStretch, difference, demerits, node);
+ }
+ }
+ }
+
+ protected int handleFloat() {
+ calculateBreakPoints(bestFloatEdgeNode, par, bestFloatEdgeNode.line);
+ activeLines = null;
+ return bestFloatEdgeNode.line - 1;
+ }
+
+ protected KnuthNode getBestFloatEdgeNode() {
+ return bestFloatEdgeNode;
+ }
+
+ protected FloatPosition getFloatPosition() {
+ return floatPosition;
+ }
+
+ protected int getFloatHeight() {
+ return floatHeight;
+ }
+
+ protected boolean handlingStartOfFloat() {
+ return handlingStartOfFloat;
+ }
+
+ protected boolean handlingEndOfFloat() {
+ return handlingEndOfFloat;
+ }
+
+ /**
+ * Deactivate the given node
+ *
+ * @param node the node
+ * @param line the line number
+ */
+ protected void deactivateNode(KnuthNode node, int line) {
+ super.deactivateNode(node, line);
+ if (handlingEndOfFloat) {
+ floatHeight = totalWidth;
+ }
+ }
+
+ protected void disableFloatHandling() {
+ handlingEndOfFloat = false;
+ handlingStartOfFloat = false;
+ }
}
/** Footnotes coming from repeated table footers, to be added after any other footnote. */
private List<List<KnuthElement>> tableFooterFootnotes;
+ private int startIntrusionAdjustment;
+ private int endIntrusionAdjustment;
+
/**
* Constructor
*
}
}
+ public void setStartIntrusionAdjustment(int sia) {
+ startIntrusionAdjustment = sia;
+ }
+
+ public void setEndIntrusionAdjustment(int eia) {
+ endIntrusionAdjustment = eia;
+ }
+
+ public int getStartIntrusionAdjustment() {
+ return startIntrusionAdjustment;
+ }
+
+ public int getEndIntrusionAdjustment() {
+ return endIntrusionAdjustment;
+ }
+
+ public void recordEndOfFloat(int fHeight) {
+ pageBreaker.handleEndOfFloat(fHeight);
+ }
+
+ public boolean handlingEndOfFloat() {
+ return pageBreaker.handlingEndOfFloat();
+ }
+
+ public int getOffsetDueToFloat() {
+ return pageBreaker.getOffsetDueToFloat();
+ }
+
+ public void recordStartOfFloat(int fHeight, int fYOffset) {
+ pageBreaker.handleStartOfFloat(fHeight, fYOffset);
+ }
+
+ public boolean handlingStartOfFloat() {
+ return pageBreaker.handlingStartOfFloat();
+ }
+
+ public int getFloatHeight() {
+ return pageBreaker.getFloatHeight();
+ }
+
+ public int getFloatYOffset() {
+ return pageBreaker.getFloatYOffset();
+ }
+
+ public int getCurrentColumnWidth() {
+ int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth();
+ flowIPD -= startIntrusionAdjustment + endIntrusionAdjustment;
+ return flowIPD;
+ }
}
--- /dev/null
+/*
+ * 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.util.LinkedList;
+import java.util.List;
+
+import org.apache.fop.fo.flow.Float;
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
+import org.apache.fop.layoutmgr.KnuthElement;
+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.Position;
+import org.apache.fop.layoutmgr.PositionIterator;
+import org.apache.fop.layoutmgr.SpaceResolver;
+
+public class FloatLayoutManager extends InlineStackingLayoutManager {
+
+ private FloatContentLayoutManager floatContentLM;
+ private KnuthInlineBox anchor;
+ private List<KnuthElement> floatContentKnuthElements;
+ private Float floatContent;
+ private boolean floatContentAreaAdded;
+
+ public FloatLayoutManager(Float node) {
+ super(node);
+ floatContent = node;
+ }
+
+ protected LayoutManager getChildLM() {
+ return null;
+ }
+
+ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
+
+ if (!floatContentAreaAdded) {
+ floatContentLM = new FloatContentLayoutManager(floatContent);
+ floatContentLM.setParent(this);
+ floatContentLM.initialize();
+ floatContentKnuthElements = floatContentLM.getNextKnuthElements(context, alignment);
+ SpaceResolver.resolveElementList(floatContentKnuthElements);
+ }
+
+ // the only knuth element is a zero width and height knuth box
+ LinkedList knuthElements = new LinkedList();
+ KnuthSequence seq = new InlineKnuthSequence();
+ anchor = new KnuthInlineBox(0, null, null, true);
+ if (!floatContentAreaAdded) {
+ anchor.setFloatContentLM(floatContentLM);
+ }
+ anchor.setPosition(notifyPos(new Position(this)));
+ seq.add(anchor);
+ knuthElements.add(seq);
+ setFinished(true);
+
+ return knuthElements;
+ }
+
+ public void addAreas(PositionIterator posIter, LayoutContext context) {
+ // "Unwrap" the NonLeafPositions stored in posIter
+ LinkedList positionList = new LinkedList();
+ Position pos = null;
+ while (posIter.hasNext()) {
+ pos = posIter.next();
+ if (pos != null && pos.getPosition() != null) {
+ positionList.add(pos.getPosition());
+ }
+ }
+ }
+
+ public void processAreas(LayoutContext context) {
+ PositionIterator contentPosIter = new KnuthPossPosIter(floatContentKnuthElements, 0,
+ floatContentKnuthElements.size());
+ floatContentLM.addAreas(contentPosIter, context);
+ floatContentAreaAdded = true;
+ anchor.setFloatContentLM(null);
+ }
+}
package org.apache.fop.layoutmgr.inline;
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.Position;
private FootnoteBodyLayoutManager footnoteBodyLM;
private AlignmentContext alignmentContext;
+ private FloatContentLayoutManager floatContentLM;
+
/**
* Create a new KnuthBox.
public boolean isAnchor() {
return (footnoteBodyLM != null);
}
+
+ public void setFloatContentLM(FloatContentLayoutManager fclm) {
+ floatContentLM = fclm;
+ }
+
+ public FloatContentLayoutManager getFloatContentLM() {
+ return floatContentLM;
+ }
+
+ public boolean isFloatAnchor() {
+ return (floatContentLM != null);
+ }
+
}
package org.apache.fop.layoutmgr.inline;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
import org.apache.fop.layoutmgr.ElementListObserver;
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
import org.apache.fop.layoutmgr.FootenoteUtil;
import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
import org.apache.fop.layoutmgr.InlineKnuthSequence;
/* "normal" vertical alignment: create a sequence whose boxes
represent effective lines, and contain LineBreakPositions */
int startIndex = 0;
+ int previousEndIndex = 0;
for (int i = 0;
i < llPoss.getChosenLineCount();
i++) {
+ int orphans = fobj.getOrphans();
+ int widows = fobj.getWidows();
+ if (handlingFloat()) {
+ orphans = 1;
+ widows = 1;
+ }
if (returnList.size() > 0
&& i > 0 //if i==0 break generated above already
- && i >= fobj.getOrphans()
- && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
+ && i >= orphans && i <= llPoss.getChosenLineCount() - widows) {
// penalty allowing a page break between lines
Keep keep = getKeepTogether();
returnList.add(new BreakElement(
// whose citations are in this line
List<FootnoteBodyLayoutManager> footnoteList = FootenoteUtil.getFootnotes(
seq, startIndex, endIndex);
+ List<FloatContentLayoutManager> floats = FloatContentLayoutManager.checkForFloats(seq,
+ startIndex, endIndex);
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));
+ if (floats.isEmpty()) {
+ returnList.add(new KnuthBlockBox(lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter,
+ footnoteList, lbp, false));
+ } else {
+ // add a line with height zero and no content and attach float to it
+ returnList.add(new KnuthBlockBox(0, Collections.emptyList(), null, false, floats));
+ // add a break element to signal that we should restart LB at this break
+ Keep keep = getKeepTogether();
+ returnList.add(new BreakElement(new LeafPosition(this, p, previousEndIndex), keep
+ .getPenalty(), keep.getContext(), context));
+ // add the original line where the float was but without the float now
+ returnList.add(new KnuthBlockBox(lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter,
+ footnoteList, lbp, false));
+ }
+ previousEndIndex = endIndex;
}
}
}
for (int p = 0; p < knuthParagraphs.size(); p++) {
LineLayoutPossibilities llPoss = lineLayoutsList[p];
//log.debug("demerits of the chosen layout: " + llPoss.getChosenDemerits());
+ int orphans = fobj.getOrphans();
+ int widows = fobj.getWidows();
+ if (handlingFloat()) {
+ orphans = 1;
+ widows = 1;
+ }
for (int i = 0; i < llPoss.getChosenLineCount(); i++) {
- if (!((BlockLevelLayoutManager) parentLayoutManager).mustKeepTogether()
- && i >= fobj.getOrphans()
- && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
+ if (!((BlockLevelLayoutManager) parentLayoutManager).mustKeepTogether() && i >= orphans
+ && i <= llPoss.getChosenLineCount() - widows) {
// null penalty allowing a page break between lines
returnList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
}
throw new RuntimeException("No available area tree check");
}
for (LayoutEngineCheck check : checks) {
- check.check(result);
+ try {
+ check.check(result);
+ } catch (RuntimeException rte) {
+ throw new RuntimeException("Layout test (" + testFile.getName() + "): " + rte.getMessage());
+ }
}
}
--- /dev/null
+<?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 floats.
+ </p>
+ </info>
+ <fo>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master margin="50pt" master-name="page" page-height="800pt" page-width="600pt">
+ <fo:region-body background-color="yellow" />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="100pt">
+ <fo:block background-color="orange">
+ This is a normal block that is confined to the block container inside a side float. The background is orange.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="end">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="90pt">
+ <fo:block background-color="pink">
+ This is a normal block that is confined to the block container inside a side float. The background is pink.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="110pt">
+ <fo:block background-color="green">
+ This is a normal block that is confined to the block container inside a side float. The background is green.
+ </fo:block>
+ </fo:block-container>
+ <fo:block>This line is not constrained by a width.</fo:block>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block background-color="red">
+ The background is red.
+ </fo:block>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+ </fo>
+ <checks>
+ <!-- first float -->
+ <eval expected="11000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="40692" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]/text/@ipd" />
+ <eval expected="orange." xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]" />
+ <eval expected="122000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="last content before the float and the float is right now. This is the first" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[4]/lineArea[1]" />
+ <eval expected="reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[6]/lineArea[1]" />
+ <!-- second float -->
+ <eval expected="399000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[8]/@left-offset" />
+ <eval expected="25344" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[8]/block[1]/block[1]/block[1]/block[1]/lineArea[8]/text/@ipd" />
+ <eval expected="pink." xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[8]/block[1]/block[1]/block[1]/block[1]/lineArea[8]" />
+ <eval expected="last content before the float and the float is right now. This is the first" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[9]/lineArea[1]" />
+ <eval expected="the foot of the village of Elstree. This noble sheet of water occupies a space of considerable" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[11]/lineArea[1]" />
+ <!-- third float -->
+ <eval expected="11000" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="34020" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]/text/@ipd" />
+ <eval expected="green." xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]" />
+ <eval expected="224752" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="last content before the float and the float is right" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[4]/lineArea[1]" />
+ <eval expected="at some distance on the right in the valley catch a view of the celebrated reservoir, the" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[6]/lineArea[1]" />
+ <!-- fourth float -->
+ <eval expected="11000" xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="122724" xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/lineArea[1]/text/@ipd" />
+ <eval expected="The background is red." xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/lineArea[1]" />
+ <eval expected="144724" xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="last content before the float and the float is right now. This is the" xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[4]/lineArea[1]" />
+ <eval expected="float... this is very complicated but the current implementation can handle the simpler cases." xpath="//pageViewport[4]/page/regionViewport[1]//flow[1]/block[5]/lineArea[1]" />
+ </checks>
+</testcase>
--- /dev/null
+<?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 floats in two column pages.
+ </p>
+ </info>
+ <fo>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master margin="50pt" master-name="page" page-height="600pt" page-width="800pt">
+ <fo:region-body background-color="yellow" column-count="2" />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="100pt">
+ <fo:block background-color="orange">
+ This is a normal block that is confined to the block container inside a side float. The background is orange.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="end">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="90pt">
+ <fo:block background-color="pink">
+ This is a normal block that is confined to the block container inside a side float. The background is pink.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="150pt">
+ <fo:block background-color="green">
+ This is a normal block that is confined to the block container inside a side float. The background is green.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ <fo:block>
+Elstree Reservoir[edit]
+The dam was built in 1795 by French prisoners of war.[34] English watercolour landscape painter John Hassell writes:
+"At the top of Stanmore Hill we enter on Bushy Heath, and at some distance on the right in the valley catch a view of the celebrated reservoir, the property of the Grand Junction Company, on Aidenham Common, at the foot of the village of Elstree. This noble sheet of water occupies a space of considerable extent on the verge of Aidenham Common, which thirty years ago was a barren waste; here the improvements in agriculture are indeed conspicuous, for at this place a poor, sandy, meagre, wretched soil has now by good husbandry been converted into rich pasturage.
+"The reservoir has all the appearance of a lake; and when the timber that surrounds it shall have arrived at maturity, it will be a most delightful spot. From this immense sheet of water, in event of drought or a deficiency of upland waters, the lower parts of the Grand Junction and the Paddington Canals can have an immediate supply. The feeder from this reservoir enters the main stream near Rickmansworth, above Batchworth Mills, and supplies the millers' below with 300 locks of water, to whose interest the Duke of Northumberland is a perpetual trustee."[35]
+In 1886, the Photographic Society of Great Britain featured an exhibition of photos of Elstree Reservoir by Edgar Clifton.[36] During World War I, then Major Keith Caldwell with No. 74 Squadron RAF, used Elstree Reservoir for target practice.[37] In 1918, one of the pilots accidentally killed a local resident when his machine gun misfired.[38]
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+ </fo>
+ <checks>
+ <!-- first float -->
+ <eval expected="11000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="40692" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]/text/@ipd" />
+ <eval expected="orange." xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[7]" />
+ <eval expected="122000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="content before the float and the float is" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[4]/lineArea[1]" />
+ <eval expected="built in 1795 by French prisoners of war.[34] English" xpath="//pageViewport[2]/page/regionViewport[1]//flow[1]/block[6]/lineArea[1]" />
+ <!-- second float -->
+ <eval expected="240000" xpath="//pageViewport[2]/page/regionViewport[1]//flow[2]/block[3]/@left-offset" />
+ <eval expected="25344" xpath="//pageViewport[2]/page/regionViewport[1]//flow[2]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[8]/text/@ipd" />
+ <eval expected="pink." xpath="//pageViewport[2]/page/regionViewport[1]//flow[2]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[8]" />
+ <eval expected="content before the float and the float is" xpath="//pageViewport[2]/page/regionViewport[1]//flow[2]/block[4]/lineArea[1]" />
+ <eval expected="war.[34] English watercolour landscape painter John Hassell" xpath="//pageViewport[2]/page/regionViewport[1]//flow[2]/block[6]/lineArea[1]" />
+ <!-- third float -->
+ <eval expected="11000" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="136068" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[4]/text/@ipd" />
+ <eval expected="The background is green." xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[3]/block[1]/block[1]/block[1]/block[1]/lineArea[4]" />
+ <eval expected="172000" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="content before the float and" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[4]/lineArea[1]" />
+ <eval expected="wrapped around the float... this is very complicated but the" xpath="//pageViewport[3]/page/regionViewport[1]//flow[1]/block[5]/lineArea[1]" />
+ </checks>
+</testcase>
--- /dev/null
+<?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 floats.
+ </p>
+ </info>
+ <fo>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master margin="50pt" master-name="page" page-height="800pt" page-width="600pt">
+ <fo:region-body background-color="yellow" />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="110pt">
+ <fo:block background-color="green">
+ This is a normal block that is confined to the block container inside a side float. The background is green.
+ </fo:block>
+ </fo:block-container>
+ <fo:block>This line is not constrained by a width. xxx xxx xxx xxx xxx</fo:block>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+ </fo>
+ <checks>
+ <!-- first float -->
+ <eval expected="11000" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[2]/@left-offset" />
+ <eval expected="green." xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[2]/block[1]/block[1]/block[1]/block[1]/lineArea[7]" />
+ <eval expected="331432" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[3]/@left-offset" />
+ <eval expected="last content before the float" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[3]/lineArea[1]" />
+ <eval expected="handle the simpler cases." xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[3]/lineArea[10]" />
+ </checks>
+</testcase>
--- /dev/null
+<?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 floats.
+ </p>
+ </info>
+ <fo>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master margin="50pt" master-name="page" page-height="800pt" page-width="600pt">
+ <fo:region-body background-color="yellow" />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C11</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C12</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C21</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C22</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C31</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C32</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C41</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C42</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C51</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C52</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="start">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="110pt">
+ <fo:block background-color="green">
+ This is a normal block that is confined to the block container inside a side float. The background is green.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C11</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C12</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C21</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C22</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>C31</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block>C32</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:block>
+ <fo:block>Content after the table. Floats cannot be handled if next to a table, unless the table starts and ends between the start and the end of the float. Tables before or after floats are not a problem.</fo:block>
+ <fo:block>
+ Put some content before the float but enough to make the float go to the third line of this block. Just enought content to place the float in the second line is not desirable. <fo:inline color="red">This is the last content before the float and the float is right now.</fo:inline>
+ <fo:float float="end">
+ <fo:block border="1pt solid red" padding="10pt" color="blue" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="110pt">
+ <fo:block background-color="orange">
+ This is a normal block that is confined to the block container inside a side float. The background is orange.
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ <fo:inline color="blue">This is the first content after the float.</fo:inline> This paragraph contains a side float and the content of the paragraph needs to be wrapped around the float... this is very complicated but the current implementation can handle the simpler cases.
+ </fo:block>
+ <fo:block>
+ <fo:list-block>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(a)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body and lets make sure the text is enought to wrap at the edge of the float
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(b)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:block>
+ <fo:block>Content after the list. Floats cannot be handled if next to a list, unless the list starts and ends between the start and the end of the float. Lists before or after a float are not a problem.</fo:block>
+ <fo:block>
+ <fo:list-block >
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(a)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(b)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(c)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>(d)</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ here is text in the list item body
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+ </fo>
+ <checks>
+ <!-- first float -->
+ <eval expected="132000" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[5]/@left-offset" />
+ <eval expected="C11" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[5]/block[1]/block[1]/block[1]/lineArea[1]" />
+ <eval expected="379000" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[9]/@left-offset" />
+ <eval expected="here is text in the list item body and lets make sure the text is" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[11]/block[1]/block[1]/block[2]/block[1]/lineArea[1]" />
+ </checks>
+</testcase>