private boolean bFinished = false;
protected boolean bInited = false;
- /**
- * Used during addAreas(): signals that a BreakPoss is not generating areas
- * and therefore shouldn't add IDs and markers to the current page.
- * @see org.apache.fop.layoutmgr.AbstractLayoutManager#isBogus
- */
- protected boolean bBogus = false;
-
/** child LM and child LM iterator during getNextBreakPoss phase */
protected LayoutManager curChildLM = null;
protected ListIterator childLMiter = null;
return false;
}
- /** @see org.apache.fop.layoutmgr.LayoutManager#isBogus() */
- public boolean isBogus() {
- if (getParent().isBogus()) {
- return true;
- } else {
- return bBogus;
- }
- }
-
/**
* Return currently active child LayoutManager or null if
* all children have finished layout.
}
}
- public static void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
+ public static void addAreas(BlockStackingLayoutManager bslm,
+ PositionIterator parentIter, LayoutContext layoutContext) {
LayoutManager childLM = null;
LayoutContext lc = new LayoutContext(0);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
+ Position firstPos = null;
+ Position lastPos = null;
// "unwrap" the NonLeafPositions stored in parentIter
// and put them in a new list;
Position pos;
while (parentIter.hasNext()) {
pos = (Position)parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
if (pos instanceof NonLeafPosition) {
// pos was created by a child of this FlowLM
positionList.add(((NonLeafPosition) pos).getPosition());
// pos was created by this LM, so it must be ignored
}
}
+
+ if (bslm.markers != null) {
+ bslm.getCurrentPV().addMarkers(bslm.markers, true,
+ bslm.isFirst(firstPos), bslm.isLast(lastPos));
+ }
StackingIter childPosIter = new StackingIter(positionList.listIterator());
while ((childLM = childPosIter.getNextChildLM()) != null) {
lc.setStackLimit(layoutContext.getStackLimit());
childLM.addAreas(childPosIter, lc);
}
+ if (bslm.markers != null) {
+ bslm.getCurrentPV().addMarkers(bslm.markers, false,
+ bslm.isFirst(firstPos), bslm.isLast(lastPos));
+ }
+
}
}
LinkedList returnedList = null;
LinkedList contentList = new LinkedList();
LinkedList returnList = new LinkedList();
- Position returnPosition = new NonLeafPosition(this, null);
if (!bBreakBeforeServed) {
try {
- if (addKnuthElementsForBreakBefore(returnList, returnPosition)) {
+ if (addKnuthElementsForBreakBefore(returnList)) {
return returnList;
}
} finally {
}
if (!bSpaceBeforeServed) {
- addKnuthElementsForSpaceBefore(returnList, returnPosition, alignment);
+ addKnuthElementsForSpaceBefore(returnList, alignment);
bSpaceBeforeServed = true;
}
- addKnuthElementsForBorderPaddingBefore(returnList, returnPosition);
+ addKnuthElementsForBorderPaddingBefore(returnList);
if (autoHeight) {
BlockLevelLayoutManager curLM; // currently active LM
}
Position bcPosition = new BlockContainerPosition(this, breaker);
- returnList.add(new KnuthBox(vpContentBPD, bcPosition, false));
+ returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false));
//TODO Handle min/opt/max for block-progression-dimension
/* These two elements will be used to add stretchability to the above box
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
}
}
}
- addKnuthElementsForBorderPaddingAfter(returnList, returnPosition);
- addKnuthElementsForSpaceAfter(returnList, returnPosition, alignment);
- addKnuthElementsForBreakAfter(returnList, returnPosition);
+ addKnuthElementsForBorderPaddingAfter(returnList);
+ addKnuthElementsForSpaceAfter(returnList, alignment);
+ addKnuthElementsForBreakAfter(returnList);
setFinished(true);
return returnList;
LinkedList returnList = new LinkedList();
if (!breaker.isEmpty()) {
Position bcPosition = new BlockContainerPosition(this, breaker);
- returnList.add(new KnuthBox(0, bcPosition, false));
+ returnList.add(new KnuthBox(0, notifyPos(bcPosition), false));
//TODO Maybe check for page overflow when autoHeight=true
if (!autoHeight & (contentOverflows/*usedBPD > relDims.bpd*/)) {
}
protected void addAreas(PositionIterator posIter, LayoutContext context) {
- AreaAdditionUtil.addAreas(posIter, context);
+ AreaAdditionUtil.addAreas(bclm, posIter, context);
}
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
}
- getPSLM().addIDToPage(getBlockContainerFO().getId());
- //addMarkersToPV(true, bp1.isFirstArea(), bp1.isLastArea());
- getCurrentPV().addMarkers(markers, true, true, false);
-
LayoutManager childLM = null;
LayoutManager lastLM = null;
LayoutContext lc = new LayoutContext(0);
Position pos;
boolean bSpaceBefore = false;
boolean bSpaceAfter = false;
+ Position firstPos = null;
+ Position lastPos = null;
while (parentIter.hasNext()) {
pos = (Position) parentIter.next();
- /* LF *///System.out.println("pos = " + pos.getClass().getName());
+ //System.out.println("pos = " + pos.getClass().getName());
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
Position innerPosition = null;
if (pos instanceof NonLeafPosition) {
innerPosition = ((NonLeafPosition)pos).getPosition();
}
}
+ getPSLM().addIDToPage(getBlockContainerFO().getId());
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+ }
+
if (bcpos == null) {
if (bpUnit == 0) {
// the Positions in positionList were inside the elements
//int bIndents = getBlockContainerFO().getCommonBorderPaddingBackground()
// .getBPPaddingAndBorder(false);
- getCurrentPV().addMarkers(markers, false, false, true);
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+ }
flush();
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
- /* LF *///System.out.println(" BLM.addAreas>");
+ //System.out.println(" BLM.addAreas>");
getParentArea(null);
// if this will create the first block area in a page
addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
}
- getPSLM().addIDToPage(getBlockFO().getId());
- //addMarkersToPV(true, bp1.isFirstArea(), bp1.isLastArea());
- getCurrentPV().addMarkers(markers, true, true, false);
-
LayoutManager childLM = null;
LayoutManager lastLM = null;
LayoutContext lc = new LayoutContext(0);
- /* LF */// set space after in the LayoutContext for children
- /* LF */if (layoutContext.getSpaceAfter() > 0) {
- /* LF */lc.setSpaceAfter(layoutContext.getSpaceAfter());
- /* LF */}
- /* LF */PositionIterator childPosIter;
+ // set space after in the LayoutContext for children
+ if (layoutContext.getSpaceAfter() > 0) {
+ lc.setSpaceAfter(layoutContext.getSpaceAfter());
+ }
+ PositionIterator childPosIter;
// "unwrap" the NonLeafPositions stored in parentIter
// and put them in a new list;
Position pos;
boolean bSpaceBefore = false;
boolean bSpaceAfter = false;
+ Position firstPos = null;
+ Position lastPos = null;
while (parentIter.hasNext()) {
pos = (Position) parentIter.next();
//log.trace("pos = " + pos.getClass().getName() + "; " + pos);
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
Position innerPosition = pos;
if (pos instanceof NonLeafPosition) {
//Not all elements are wrapped
}
}
+ getPSLM().addIDToPage(getBlockFO().getId());
+ /* TODO remove when markers are really ok
+ log.debug("Checking on " + this);
+ log.debug("Checking first=" + firstPos);
+ log.debug("Checking last=" + lastPos);
+ log.debug("->" + isFirst(firstPos) + "/" + isLast(lastPos));
+ */
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+ }
+
if (bpUnit == 0) {
// the Positions in positionList were inside the elements
// created by the LineLM
// set last area flag
lc.setFlags(LayoutContext.LAST_AREA,
(layoutContext.isLastArea() && childLM == lastLM));
- /*LF*/lc.setStackLimit(layoutContext.getStackLimit());
+ lc.setStackLimit(layoutContext.getStackLimit());
// Add the line areas to Area
childLM.addAreas(childPosIter, lc);
}
- int bIndents = getBlockFO().getCommonBorderPaddingBackground().getBPPaddingAndBorder(false);
+ //int bIndents = getBlockFO().getCommonBorderPaddingBackground().getBPPaddingAndBorder(false);
- getCurrentPV().addMarkers(markers, false, false, true);
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+ }
flush();
*/
public interface BlockLevelLayoutManager extends LayoutManager {
- static final int NO_ADJUSTMENT = -1;
- static final int SPACE_BEFORE_ADJUSTMENT = 0;
- static final int SPACE_AFTER_ADJUSTMENT = 1;
- static final int LINE_NUMBER_ADJUSTMENT = 2;
- static final int LINE_HEIGHT_ADJUSTMENT = 3;
+ /** Adjustment class: no adjustment */
+ int NO_ADJUSTMENT = -1;
+ /** Adjustment class: adjustment for space-before */
+ int SPACE_BEFORE_ADJUSTMENT = 0;
+ /** Adjustment class: adjustment for space-after */
+ int SPACE_AFTER_ADJUSTMENT = 1;
+ /** Adjustment class: adjustment for number of lines */
+ int LINE_NUMBER_ADJUSTMENT = 2;
+ /** Adjustment class: adjustment for line height */
+ int LINE_HEIGHT_ADJUSTMENT = 3;
int negotiateBPDAdjustment(int adj, KnuthElement lastElement);
protected boolean bSpaceBeforeServed = false;
/** Reference IPD available */
protected int referenceIPD = 0;
+
+ private int lastGeneratedPosition = -1;
+ private int smallestPosNumberChecked = Integer.MAX_VALUE;
+ private Position auxiliaryPosition;
+
public BlockStackingLayoutManager(FObj node) {
super(node);
fobj = node;
}
}
+ /**
+ * Adds a Position to the Position participating in the first|last determination by assigning
+ * it a unique position index.
+ * @param pos the Position
+ * @return the same Position but with a position index
+ */
+ protected Position notifyPos(Position pos) {
+ if (pos.getIndex() >= 0) {
+ throw new IllegalStateException("Position already got its index");
+ }
+ lastGeneratedPosition++;
+ pos.setIndex(lastGeneratedPosition);
+ return pos;
+ }
+
+ /**
+ * Indicates whether the given Position is the first area-generating Position of this LM.
+ * @param pos the Position (must be one with a position index)
+ * @return True if it is the first Position
+ */
+ public boolean isFirst(Position pos) {
+ //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos);
+ if (pos.getIndex() < 0) {
+ throw new IllegalArgumentException("Only Positions with an index can be checked");
+ }
+ if (pos.getIndex() == this.smallestPosNumberChecked) {
+ return true;
+ } else if (pos.getIndex() < this.smallestPosNumberChecked) {
+ this.smallestPosNumberChecked = pos.getIndex();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Indicates whether the given Position is the last area-generating Position of this LM.
+ * @param pos the Position (must be one with a position index)
+ * @return True if it is the last Position
+ */
+ public boolean isLast(Position pos) {
+ //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos);
+ if (pos.getIndex() < 0) {
+ throw new IllegalArgumentException("Only Positions with an index can be checked");
+ }
+ return (pos.getIndex() == this.lastGeneratedPosition
+ && isFinished());
+ }
+
+ /** @return a cached auxiliary Position instance used for things like spaces. */
+ protected Position getAuxiliaryPosition() {
+ if (this.auxiliaryPosition == null) {
+ this.auxiliaryPosition = new NonLeafPosition(this, null);
+ }
+ return this.auxiliaryPosition;
+ }
+
/**
* @param len length in millipoints to span with bp units
* @return the minimum integer n such that n * bpUnit >= len
LinkedList returnedList = null;
LinkedList contentList = new LinkedList();
LinkedList returnList = new LinkedList();
- Position returnPosition = new NonLeafPosition(this, null);
if (!bBreakBeforeServed) {
try {
- if (addKnuthElementsForBreakBefore(returnList, returnPosition)) {
+ if (addKnuthElementsForBreakBefore(returnList)) {
return returnList;
}
} finally {
}
if (!bSpaceBeforeServed) {
- addKnuthElementsForSpaceBefore(returnList, returnPosition, alignment);
+ addKnuthElementsForSpaceBefore(returnList, alignment);
bSpaceBeforeServed = true;
}
- addKnuthElementsForBorderPaddingBefore(returnList, returnPosition);
+ addKnuthElementsForBorderPaddingBefore(returnList);
while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
LayoutContext childLC = new LayoutContext(0);
wrapPositionElements(contentList, returnList);
} else {
//Empty fo:block, zero-length box makes sure the IDs are registered.
- returnList.add(new KnuthBox(0, new Position(this), true));
+ returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
}
- addKnuthElementsForBorderPaddingAfter(returnList, returnPosition);
- addKnuthElementsForSpaceAfter(returnList, returnPosition, alignment);
- addKnuthElementsForBreakAfter(returnList, returnPosition);
+ addKnuthElementsForBorderPaddingAfter(returnList);
+ addKnuthElementsForSpaceAfter(returnList, alignment);
+ addKnuthElementsForBreakAfter(returnList);
if (mustKeepWithNext()) {
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
* @param returnList return list to add the additional elements to
* @param returnPosition applicable return position
*/
- protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList,
- Position returnPosition) {
+ protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList/*,
+ Position returnPosition*/) {
//Border and Padding (before)
CommonBorderPaddingBackground borderAndPadding = null;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
int bpBefore = borderAndPadding.getBorderBeforeWidth(false)
+ borderAndPadding.getPaddingBefore(false);
if (bpBefore > 0) {
- returnList.add(new KnuthBox(bpBefore, returnPosition, true));
+ returnList.add(new KnuthBox(bpBefore, getAuxiliaryPosition(), true));
}
}
}
* @param returnList return list to add the additional elements to
* @param returnPosition applicable return position
*/
- protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList,
- Position returnPosition) {
+ protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList/*,
+ Position returnPosition*/) {
//Border and Padding (after)
CommonBorderPaddingBackground borderAndPadding = null;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
int bpAfter = borderAndPadding.getBorderAfterWidth(false)
+ borderAndPadding.getPaddingAfter(false);
if (bpAfter > 0) {
- returnList.add(new KnuthBox(bpAfter, returnPosition, true));
+ returnList.add(new KnuthBox(bpAfter, getAuxiliaryPosition(), true));
}
}
}
* @param returnPosition applicable return position
* @return true if an element has been added due to a break-before.
*/
- protected boolean addKnuthElementsForBreakBefore(LinkedList returnList,
- Position returnPosition) {
+ protected boolean addKnuthElementsForBreakBefore(LinkedList returnList/*,
+ Position returnPosition*/) {
int breakBefore = -1;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
breakBefore = ((org.apache.fop.fo.flow.Block) fobj).getBreakBefore();
|| breakBefore == EN_ODD_PAGE) {
// return a penalty element, representing a forced page break
returnList.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false,
- breakBefore, returnPosition, false));
+ breakBefore, getAuxiliaryPosition(), false));
return true;
} else {
return false;
* @param returnPosition applicable return position
* @return true if an element has been added due to a break-after.
*/
- protected boolean addKnuthElementsForBreakAfter(LinkedList returnList,
- Position returnPosition) {
+ protected boolean addKnuthElementsForBreakAfter(LinkedList returnList/*,
+ Position returnPosition*/) {
int breakAfter = -1;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
breakAfter = ((org.apache.fop.fo.flow.Block) fobj).getBreakAfter();
|| breakAfter == EN_ODD_PAGE) {
// add a penalty element, representing a forced page break
returnList.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false,
- breakAfter, returnPosition, false));
+ breakAfter, getAuxiliaryPosition(), false));
return true;
} else {
return false;
* @param returnPosition applicable return position
* @param alignment vertical alignment
*/
- protected void addKnuthElementsForSpaceBefore(LinkedList returnList,
- Position returnPosition, int alignment) {
+ protected void addKnuthElementsForSpaceBefore(LinkedList returnList/*,
+ Position returnPosition*/, int alignment) {
SpaceProperty spaceBefore = null;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
spaceBefore = ((org.apache.fop.fo.flow.Block)fobj)
&& spaceBefore.getMaximum().getLength().getValue() == 0)) {
if (spaceBefore != null && !spaceBefore.getSpace().isDiscard()) {
// add elements to prevent the glue to be discarded
- returnList.add(new KnuthBox(0, returnPosition, false));
+ returnList.add(new KnuthBox(0, getAuxiliaryPosition(), false));
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
- false, returnPosition, false));
+ false, getAuxiliaryPosition(), false));
}
if (bpUnit > 0) {
returnList.add(new KnuthGlue(0, 0, 0,
BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT,
- returnPosition, true));
+ getAuxiliaryPosition(), true));
} else /*if (alignment == EN_JUSTIFY)*/ {
returnList.add(new KnuthGlue(
spaceBefore.getOptimum().getLength().getValue(),
spaceBefore.getOptimum().getLength().getValue()
- spaceBefore.getMinimum().getLength().getValue(),
BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT,
- returnPosition, true));
+ getAuxiliaryPosition(), true));
} /*else {
returnList.add(new KnuthGlue(
spaceBefore.getOptimum().getLength().getValue(),
* @param returnPosition applicable return position
* @param alignment vertical alignment
*/
- protected void addKnuthElementsForSpaceAfter(LinkedList returnList, Position returnPosition,
+ protected void addKnuthElementsForSpaceAfter(LinkedList returnList/*, Position returnPosition*/,
int alignment) {
SpaceProperty spaceAfter = null;
if (fobj instanceof org.apache.fop.fo.flow.Block) {
&& spaceAfter.getMaximum().getLength().getValue() == 0)) {
if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
- false, returnPosition, false));
+ false, getAuxiliaryPosition(), false));
}
if (bpUnit > 0) {
returnList.add(new KnuthGlue(0, 0, 0,
BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT,
- returnPosition, true));
+ getAuxiliaryPosition(), true));
} else /*if (alignment == EN_JUSTIFY)*/ {
returnList.add(new KnuthGlue(
spaceAfter.getOptimum().getLength().getValue(),
- spaceAfter.getOptimum().getLength().getValue(),
spaceAfter.getOptimum().getLength().getValue()
- spaceAfter.getMinimum().getLength().getValue(),
- BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, returnPosition,
+ BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, getAuxiliaryPosition(),
(!spaceAfter.getSpace().isDiscard()) ? false : true));
} /*else {
returnList.add(new KnuthGlue(
(!spaceAfter.getSpace().isDiscard()) ? false : true));
}*/
if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
- returnList.add(new KnuthBox(0, returnPosition, true));
+ returnList.add(new KnuthBox(0, getAuxiliaryPosition(), true));
}
}
}
* @param targetList target list receiving the wrapped position elements
*/
protected void wrapPositionElements(List sourceList, List targetList) {
+ wrapPositionElements(sourceList, targetList, false);
+ }
+
+ /**
+ * "wrap" the Position inside each element moving the elements from
+ * SourceList to targetList
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ * @param force if true, every Position is wrapper regardless of its LM of origin
+ */
+ protected void wrapPositionElements(List sourceList, List targetList, boolean force) {
+
ListIterator listIter = sourceList.listIterator();
while (listIter.hasNext()) {
KnuthElement tempElement;
tempElement = (KnuthElement) listIter.next();
- if (tempElement.getLayoutManager() != this) {
- tempElement.setPosition(new NonLeafPosition(this,
- tempElement.getPosition()));
+ if (force || tempElement.getLayoutManager() != this) {
+ tempElement.setPosition(notifyPos(new NonLeafPosition(this,
+ tempElement.getPosition())));
}
targetList.add(tempElement);
}
fobj = node;
}
- /**
- * "wrap" the Position inside each element moving the elements from
- * SourceList to targetList
- * @param sourceList source list
- * @param targetList target list receiving the wrapped position elements
- */
- protected void wrapPositionElements(List sourceList, List targetList) {
- ListIterator listIter = sourceList.listIterator();
- while (listIter.hasNext()) {
- KnuthElement tempElement;
- tempElement = (KnuthElement) listIter.next();
- //if (tempElement.getLayoutManager() != this) {
- tempElement.setPosition(new NonLeafPosition(this,
- tempElement.getPosition()));
- //}
- targetList.add(tempElement);
- }
- }
-
/** @see org.apache.fop.layoutmgr.LayoutManager */
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
// set layout dimensions
* @see org.apache.fop.layoutmgr.LayoutManager#addAreas(PositionIterator, LayoutContext)
*/
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
- AreaAdditionUtil.addAreas(parentIter, layoutContext);
+ AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
flush();
}
/**
* Get the active PageSequenceLayoutManager instance for this
* layout process.
+ * @return the PageSequenceLayoutManager
*/
PageSequenceLayoutManager getPSLM();
*/
boolean generatesInlineAreas();
- /**
- * This method is used during the stage where addAreas() converts BreakPoss
- * instances to areas. It is used to skip adding IDs and markers to a page
- * when the current BreakPoss/area was only generated to signal a break
- * situation. This avoids adding IDs and markers to the wrong pages.
- * @todo This is a hack. This should be handled differently in the long term.
- * @return true if the current BreakPoss/area was only generated to signal
- * break situations.
- */
- boolean isBogus();
-
/**
* Return true if the next area which would be generated by this
* LayoutManager could start a new line (or flow for block-level FO).
/**
* Reset to the position.
*
- * @param position
+ * @param position the Position to reset to
*/
void resetPosition(Position position);
return iLeafPos;
}
+ public boolean generatesAreas() {
+ return getLM() != null;
+ }
+
/** @see java.lang.Object#toString()*/
public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
- sb.append(" {pos=").append(getLeafPos());
- sb.append(", lm=").append(getLM()).append("}");
+ StringBuffer sb = new StringBuffer();
+ sb.append("LeafPos:").append(getIndex()).append("(");
+ sb.append("pos=").append(getLeafPos());
+ sb.append(", lm=").append(getShortLMName()).append(")");
return sb.toString();
}
}
return subPos;
}
+ public boolean generatesAreas() {
+ return (subPos != null ? subPos.generatesAreas() : false);
+ }
+
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append("NonLeafPos(");
+ sb.append("NonLeafPos:").append(getIndex()).append("(");
+ sb.append(getShortLMName());
+ sb.append(", ");
if (getPosition() != null) {
sb.append(getPosition().toString());
} else {
public class Position {
private LayoutManager layoutManager;
+ private int index = -1;
public Position(LayoutManager lm) {
layoutManager = lm;
return null;
}
+ public boolean generatesAreas() {
+ return false;
+ }
+
+ public void setIndex(int value) {
+ this.index = value;
+ }
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public String getShortLMName() {
+ if (getLM() != null) {
+ String lm = getLM().toString();
+ int idx = lm.lastIndexOf('.');
+ if (idx >= 0 && lm.indexOf('@') > 0) {
+ return(lm.substring(idx + 1));
+ } else {
+ return lm;
+ }
+ } else {
+ return "null";
+ }
+ }
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append("Position");
- if (getLM() != null) {
- sb.append(" {");
- sb.append(getLM());
- sb.append("}");
- }
+ sb.append("Position:").append(getIndex()).append("(");
+ sb.append(getShortLMName());
+ sb.append(")");
return sb.toString();
}
}
* @see org.apache.fop.layoutmgr.LayoutManager#addAreas(PositionIterator, LayoutContext)
*/
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
- AreaAdditionUtil.addAreas(parentIter, layoutContext);
+ AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
flush();
targetRegion = null;
}
protected void addAreas(PositionIterator posIter, LayoutContext context) {
- AreaAdditionUtil.addAreas(posIter, context);
+ AreaAdditionUtil.addAreas(lm, posIter, context);
}
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
LayoutContext lc = new LayoutContext(0);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
+ Position firstPos = null;
+ Position lastPos = null;
// "unwrap" the NonLeafPositions stored in parentIter
// and put them in a new list;
Position pos;
while (parentIter.hasNext()) {
pos = (Position)parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
if (pos instanceof NonLeafPosition) {
// pos was created by a child of this ListBlockLM
positionList.add(((NonLeafPosition) pos).getPosition());
}
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+ }
+
StackingIter childPosIter = new StackingIter(positionList.listIterator());
while ((childLM = childPosIter.getNextChildLM()) != null) {
// Add the block areas to Area
childLM.addAreas(childPosIter, lc);
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+ }
+
flush();
curBlockArea = null;
LayoutContext lc = new LayoutContext(0);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
+ Position firstPos = null;
+ Position lastPos = null;
// "unwrap" the NonLeafPositions stored in parentIter
// and put them in a new list;
Position pos;
while (parentIter.hasNext()) {
pos = (Position)parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
if (pos instanceof NonLeafPosition
&& ((NonLeafPosition) pos).getPosition().getLM() != this) {
// pos was created by a child of this ListBlockLM
}
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+ }
+
StackingIter childPosIter = new StackingIter(positionList.listIterator());
while ((childLM = childPosIter.getNextChildLM()) != null) {
// Add the block areas to Area
childLM.addAreas(childPosIter, lc);
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+ }
+
flush();
// if adjusted space after
public int getBodyLastIndex() {
return iBodyLastIndex;
}
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("ListItemPosition:");
+ sb.append(getIndex()).append("(");
+ sb.append("label:").append(iLabelFirstIndex).append("-").append(iLabelLastIndex);
+ sb.append(" body:").append(iBodyFirstIndex).append("-").append(iBodyLastIndex);
+ sb.append(")");
+ return sb.toString();
+ }
}
/**
// "wrap" the Position inside each element
LinkedList tempList = returnedList;
- KnuthElement tempElement;
returnedList = new LinkedList();
- ListIterator listIter = tempList.listIterator();
- while (listIter.hasNext()) {
- tempElement = (KnuthElement)listIter.next();
- tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
- returnedList.add(tempElement);
- }
+ wrapPositionElements(tempList, returnedList, true);
if (keepWithNextPendingOnLabel || keepWithNextPendingOnBody || mustKeepWithNext()) {
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
getPSLM().addIDToPage(getListItemFO().getId());
LayoutContext lc = new LayoutContext(0);
+ Position firstPos = null;
+ Position lastPos = null;
// "unwrap" the NonLeafPositions stored in parentIter
LinkedList positionList = new LinkedList();
Position pos;
while (parentIter.hasNext()) {
pos = (Position) parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
if (pos instanceof NonLeafPosition) {
// pos contains a ListItemPosition created by this ListBlockLM
positionList.add(((NonLeafPosition) pos).getPosition());
}
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+ }
+
// use the first and the last ListItemPosition to determine the
// corresponding indexes in the original labelList and bodyList
int labelFirstIndex = ((ListItemPosition) positionList.getFirst()).getLabelFirstIndex();
curBlockArea.setBPD(savedBPD);
}
+ if (markers != null) {
+ getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+ }
+
flush();
// if adjusted space after
package org.apache.fop.layoutmgr.table;
import java.util.LinkedList;
-import java.util.List;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.Table;
private int borderAndPaddingBPD;
private boolean emptyCell = true;
- /** List of Lists containing OldGridUnit instances, one List per row. */
- private List rows = new java.util.ArrayList();
-
/**
* Create a new Cell layout manager.
* @param node table-cell FO for which to create the LM
}
- /**
- * Called by Row LM to register the grid units occupied by this cell for a row.
- * @param spannedGridUnits a List of GridUnits
- */
- public void addGridUnitsFromRow(List spannedGridUnits) {
- log.debug("Getting another row, " + spannedGridUnits.size() + " grid units");
- this.rows.add(spannedGridUnits);
-
- }
-
private int getIPIndents() {
int iIndents = 0;
int[] startEndBorderWidths = gridUnit.getStartEndBorderWidths();
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
- bBogus = false; //!bp1.generatesAreas();
- if (!isBogus()) {
- getPSLM().addIDToPage(fobj.getId());
- }
+ getPSLM().addIDToPage(fobj.getId());
if (isSeparateBorderModel()) {
if (!emptyCell || fobj.showEmptyCells()) {
- (gu.getBorders().getBorderAfterWidth(false) / 2);
}
block.setBPD(bpd);
- //TODO This needs to be fixed for row spanning
lastRowHeight = rowHeight;
int ipd = gu.getColumn().getColumnWidth().getValue();
int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2;
}
}
- AreaAdditionUtil.addAreas(parentIter, layoutContext);
+ AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
int contentBPD = getContentHeight(rowHeight, gridUnit);
curBlockArea.setBPD(contentBPD);
*/
public class EffRow {
+ /** Indicates that the row is the first in a table-body */
+ public static final int FIRST_IN_BODY = GridUnit.FIRST_IN_BODY;
+ /** Indicates that the row is the last in a table-body */
+ public static final int LAST_IN_BODY = GridUnit.LAST_IN_BODY;
+
private List gridUnits = new java.util.ArrayList();
private int index;
private int bodyType;
private MinOptMax height;
private MinOptMax explicitHeight;
+ /**
+ * Creates a new effective row instance.
+ * @param index index of the row
+ * @param bodyType type of body (one of HEADER, FOOTER, BODY as found on TableRowIterator)
+ */
public EffRow(int index, int bodyType) {
this.index = index;
this.bodyType = bodyType;
}
+ /** @return the index of the EffRow in the sequence of rows */
public int getIndex() {
return this.index;
}
+ /**
+ * @return an indicator what type of body this EffRow is in (one of HEADER, FOOTER, BODY
+ * as found on TableRowIterator)
+ */
public int getBodyType() {
return this.bodyType;
}
+ /** @return the calculated height for this EffRow. */
public MinOptMax getHeight() {
return this.height;
}
+ /**
+ * Sets the calculated height for this EffRow.
+ * @param mom the calculated height
+ */
public void setHeight(MinOptMax mom) {
this.height = mom;
}
+ /** @return the explicit height of the EffRow (as specified through properties) */
public MinOptMax getExplicitHeight() {
return this.explicitHeight;
}
+ /**
+ * Sets the height for this row that resulted from the explicit height properties specified
+ * by the user.
+ * @param mom the height
+ */
public void setExplicitHeight(MinOptMax mom) {
this.explicitHeight = mom;
}
+ /** @return the list of GridUnits for this EffRow */
public List getGridUnits() {
return gridUnits;
}
}
}
+ /**
+ * Sets a flag on all grid units of this effective row.
+ * @param flag which flag to set (on of the GridUnit.* constants)
+ * @param value new value for the flag
+ */
public void setFlagForAllGridUnits(int flag, boolean value) {
Iterator iter = gridUnits.iterator();
while (iter.hasNext()) {
}
}
+ /**
+ * Returns a flag for this effective row. Only a subset of the flags on GridUnit is supported.
+ * The flag is determined by inspecting flags on the EffRow's GridUnits.
+ * @param which the requested flag
+ * @return true if the flag is set
+ */
+ public boolean getFlag(int which) {
+ if (which == FIRST_IN_BODY) {
+ return getGridUnit(0).getFlag(GridUnit.FIRST_IN_BODY);
+ } else if (which == LAST_IN_BODY) {
+ return getGridUnit(0).getFlag(GridUnit.LAST_IN_BODY);
+ } else {
+ throw new IllegalArgumentException("Illegal flag queried: " + which);
+ }
+ }
+
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer("EffRow {");
side, resFlags), side);
}
+ /**
+ * Returns a flag for this GridUnit.
+ * @param which the requested flag
+ * @return the value of the flag
+ */
public boolean getFlag(int which) {
return (flags & (1 << which)) != 0;
}
+ /**
+ * Sets a flag on a GridUnit.
+ * @param which the flag to set
+ * @param value the new value for the flag
+ */
public void setFlag(int which, boolean value) {
if (value) {
flags |= (1 << which); //set flag
import org.apache.fop.area.Block;
import org.apache.fop.area.Trait;
import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableBody;
import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
RowPainter painter = new RowPainter(layoutContext);
List positions = new java.util.ArrayList();
+ List headerElements = null;
List footerElements = null;
+ Position firstPos = null;
Position lastPos = null;
while (parentIter.hasNext()) {
Position pos = (Position)parentIter.next();
+ if (firstPos == null) {
+ firstPos = pos;
+ }
lastPos = pos;
if (pos instanceof TableHeaderFooterPosition) {
TableHeaderFooterPosition thfpos = (TableHeaderFooterPosition)pos;
//these positions need to be unpacked
if (thfpos.header) {
- //header positions for the last part are the second-to-last element and need to
- //be handled first before all other TableContentPositions
- PositionIterator nestedIter = new KnuthPossPosIter(thfpos.nestedElements);
- while (nestedIter.hasNext()) {
- Position containedPos = (Position)nestedIter.next();
- if (containedPos instanceof TableContentPosition) {
- TableContentPosition tcpos = (TableContentPosition)containedPos;
- painter.handleTableContentPosition(tcpos);
- } else {
- log.debug("Ignoring position: " + containedPos);
- }
- }
- painter.addAreasAndFlushRow(true);
+ //Positions for header will be added first
+ headerElements = thfpos.nestedElements;
} else {
//Positions for footers are simply added at the end
footerElements = thfpos.nestedElements;
if (penaltyPos.headerElements != null) {
//Header positions for the penalty position are in the last element and need to
//be handled first before all other TableContentPositions
- PositionIterator nestedIter = new KnuthPossPosIter(penaltyPos.headerElements);
- while (nestedIter.hasNext()) {
- Position containedPos = (Position)nestedIter.next();
- if (containedPos instanceof TableContentPosition) {
- TableContentPosition tcpos = (TableContentPosition)containedPos;
- painter.handleTableContentPosition(tcpos);
- } else {
- log.debug("Ignoring position: " + containedPos);
- }
- }
- painter.addAreasAndFlushRow(true);
+ headerElements = penaltyPos.headerElements;
}
if (penaltyPos.footerElements != null) {
footerElements = penaltyPos.footerElements;
}
}
+ Map markers = getTableLM().getTable().getMarkers();
+ if (markers != null) {
+ getTableLM().getCurrentPV().addMarkers(markers,
+ true, getTableLM().isFirst(firstPos), getTableLM().isLast(lastPos));
+ }
- Iterator posIter = positions.iterator();
- //Iterate over all steps
- while (posIter.hasNext()) {
- Position pos = (Position)posIter.next();
- if (pos instanceof TableContentPosition) {
- TableContentPosition tcpos = (TableContentPosition)pos;
- painter.handleTableContentPosition(tcpos);
- } else {
- log.debug("Ignoring position: " + pos);
- }
+ if (headerElements != null) {
+ //header positions for the last part are the second-to-last element and need to
+ //be handled first before all other TableContentPositions
+ PositionIterator nestedIter = new KnuthPossPosIter(headerElements);
+ iterateAndPaintPositions(nestedIter, painter);
+ painter.addAreasAndFlushRow(true);
}
+
+ //Iterate over all steps
+ Iterator posIter = positions.iterator();
+ iterateAndPaintPositions(posIter, painter);
painter.addAreasAndFlushRow(true);
if (footerElements != null) {
//Positions for footers are simply added at the end
- PositionIterator iter = new KnuthPossPosIter(footerElements);
- while (iter.hasNext()) {
- Position pos = (Position)iter.next();
- if (pos instanceof TableContentPosition) {
- TableContentPosition tcpos = (TableContentPosition)pos;
- painter.handleTableContentPosition(tcpos);
- } else {
- log.debug("Ignoring position: " + pos);
- }
- }
+ PositionIterator nestedIter = new KnuthPossPosIter(footerElements);
+ iterateAndPaintPositions(nestedIter, painter);
painter.addAreasAndFlushRow(true);
}
painter.notifyEndOfSequence();
this.usedBPD += painter.getAccumulatedBPD();
+
+ if (markers != null) {
+ getTableLM().getCurrentPV().addMarkers(markers,
+ false, getTableLM().isFirst(firstPos), getTableLM().isLast(lastPos));
+ }
+ }
+
+ private void iterateAndPaintPositions(Iterator iterator, RowPainter painter) {
+ List lst = new java.util.ArrayList();
+ boolean firstPos = false;
+ boolean lastPos = false;
+ TableBody body = null;
+ while (iterator.hasNext()) {
+ Position pos = (Position)iterator.next();
+ //System.out.println(pos);
+ if (pos instanceof TableContentPosition) {
+ TableContentPosition tcpos = (TableContentPosition)pos;
+ lst.add(tcpos);
+ //System.out.println(tcpos.row);
+ GridUnitPart part = (GridUnitPart)tcpos.gridUnitParts.get(0);
+ if (body == null) {
+ body = part.pgu.getBody();
+ }
+ if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP)
+ && tcpos.row.getFlag(EffRow.FIRST_IN_BODY)) {
+ //System.out.println("pgu is first in body");
+ firstPos = true;
+
+ }
+ if (tcpos.getFlag(TableContentPosition.LAST_IN_ROWGROUP)
+ && tcpos.row.getFlag(EffRow.LAST_IN_BODY)) {
+ //System.out.println("pgu is last in body");
+ lastPos = true;
+ getTableLM().getCurrentPV().addMarkers(body.getMarkers(),
+ true, firstPos, lastPos);
+ int size = lst.size();
+ for (int i = 0; i < size; i++) {
+ painter.handleTableContentPosition((TableContentPosition)lst.get(i));
+ }
+ getTableLM().getCurrentPV().addMarkers(body.getMarkers(),
+ false, firstPos, lastPos);
+ //reset
+ firstPos = false;
+ lastPos = false;
+ body = null;
+ lst.clear();
+ }
+ } else {
+ log.debug("Ignoring position: " + pos);
+ }
+ }
+ if (body != null) {
+ getTableLM().getCurrentPV().addMarkers(body.getMarkers(),
+ true, firstPos, lastPos);
+ int size = lst.size();
+ for (int i = 0; i < size; i++) {
+ painter.handleTableContentPosition((TableContentPosition)lst.get(i));
+ }
+ getTableLM().getCurrentPV().addMarkers(body.getMarkers(),
+ false, firstPos, lastPos);
+ }
}
private class RowPainter {
this.end = end;
}
+ /** @return true if this part is the first part of a cell */
+ public boolean isFirstPart() {
+ return (start == 0);
+ }
+
+ /** @return true if this part is the last part of a cell */
+ public boolean isLastPart() {
+ return (end >= 0 && end == pgu.getElements().size() - 1);
+ }
+
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer("Part: ");
sb.append(start).append("-").append(end);
- sb.append(" ").append(pgu);
+ sb.append(" [").append(isFirstPart() ? "F" : "-").append(isLastPart() ? "L" : "-");
+ sb.append("] ").append(pgu);
return sb.toString();
}
*/
public static class TableContentPosition extends Position {
+ /** The position is the first of the row group. */
+ public static final int FIRST_IN_ROWGROUP = 1;
+ /** The position is the last of the row group. */
+ public static final int LAST_IN_ROWGROUP = 2;
+
/** the list of GridUnitParts making up this position */
protected List gridUnitParts;
/** effective row this position belongs to */
protected EffRow row;
+ /** flags for the position */
+ protected int flags;
/**
* Creates a new TableContentPosition.
this.row = row;
}
+ /**
+ * Returns a flag for this GridUnit.
+ * @param which the requested flag
+ * @return the value of the flag
+ */
+ public boolean getFlag(int which) {
+ return (flags & (1 << which)) != 0;
+ }
+
+ /**
+ * Sets a flag on a GridUnit.
+ * @param which the flag to set
+ * @param value the new value for the flag
+ */
+ public void setFlag(int which, boolean value) {
+ if (value) {
+ flags |= (1 << which); //set flag
+ } else {
+ flags &= ~(1 << which); //clear flag
+ }
+ }
+
/** @see java.lang.Object#toString() */
public String toString() {
- StringBuffer sb = new StringBuffer("TableContentPosition {");
+ StringBuffer sb = new StringBuffer("TableContentPosition:");
+ sb.append(getIndex());
+ sb.append("[").append(getFlag(FIRST_IN_ROWGROUP) ? "F" : "-");
+ sb.append((getFlag(LAST_IN_ROWGROUP) ? "L" : "-")).append("]");
+ sb.append("(");
sb.append(gridUnitParts);
- sb.append("}");
+ sb.append(")");
return sb.toString();
}
}
public String toString() {
StringBuffer sb = new StringBuffer("Table");
sb.append(header ? "Header" : "Footer");
- sb.append("Position {");
+ sb.append("Position:");
+ sb.append(getIndex()).append("(");
sb.append(nestedElements);
- sb.append("}");
+ sb.append(")");
return sb.toString();
}
}
/** @see java.lang.Object#toString() */
public String toString() {
- StringBuffer sb = new StringBuffer("TableHFPenaltyPosition");
- sb.append(" {");
+ StringBuffer sb = new StringBuffer("TableHFPenaltyPosition:");
+ sb.append(getIndex()).append("(");
sb.append("header:");
sb.append(headerElements);
sb.append(", footer:");
sb.append(footerElements);
- sb.append("}");
+ sb.append(")");
return sb.toString();
}
}
log.debug("TableContentLM signals pending keep-with-previous");
context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
}
+
+ //Set index values on elements coming from the content LM
+ Iterator iter = returnedList.iterator();
+ while (iter.hasNext()) {
+ KnuthElement el = (KnuthElement)iter.next();
+ notifyPos(el.getPosition());
+ }
log.debug(returnedList);
if (returnedList.size() == 1
int laststep = 0;
int step;
int addedBoxLen = 0;
+ TableContentPosition lastTCPos = null;
LinkedList returnList = new LinkedList();
while ((step = getNextStep(laststep)) >= 0) {
if (rowBacktrackForLastStep) {
}
TableContentPosition tcpos = new TableContentPosition(getTableLM(),
gridUnitParts, getActiveRow());
+ if (returnList.size() == 0) {
+ tcpos.setFlag(TableContentPosition.FIRST_IN_ROWGROUP, true);
+ }
+ lastTCPos = tcpos;
log.debug(" - " + rowBacktrackForLastStep + " - " + activeRow + " - " + tcpos);
returnList.add(new KnuthBox(boxLen, tcpos, false));
TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM());
//we have to signal the still pending last keep-with-next using the LayoutContext.
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
}
+ lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true);
return returnList;
}