package org.apache.fop.layoutmgr;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.CTM;
import org.apache.fop.area.Trait;
import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.properties.CommonAbsolutePosition;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
implements BreakOpportunity {
private static Log log = LogFactory.getLog(BlockContainerLayoutManager.class);
private BlockViewport viewportBlockArea;
private Block referenceArea;
private CommonAbsolutePosition abProps;
private FODimension relDims;
private CTM absoluteCTM;
private Length width;
private Length height;
private int vpContentBPD;
private boolean autoHeight = true;
private boolean inlineElementList;
private MinOptMax foBlockSpaceBefore;
private MinOptMax foBlockSpaceAfter;
private int horizontalOverflow;
private double contentRectOffsetX;
private double contentRectOffsetY;
public BlockContainerLayoutManager(BlockContainer node) {
super(node);
setGeneratesBlockArea(true);
}
@Override
public void initialize() {
abProps = getBlockContainerFO().getCommonAbsolutePosition();
foBlockSpaceBefore = new SpaceVal(getBlockContainerFO().getCommonMarginBlock()
.spaceBefore, this).getSpace();
foBlockSpaceAfter = new SpaceVal(getBlockContainerFO().getCommonMarginBlock()
.spaceAfter, this).getSpace();
startIndent = getBlockContainerFO().getCommonMarginBlock().startIndent.getValue(this);
endIndent = getBlockContainerFO().getCommonMarginBlock().endIndent.getValue(this);
if (blockProgressionDirectionChanges()) {
height = getBlockContainerFO().getInlineProgressionDimension()
.getOptimum(this).getLength();
width = getBlockContainerFO().getBlockProgressionDimension()
.getOptimum(this).getLength();
} else {
height = getBlockContainerFO().getBlockProgressionDimension()
.getOptimum(this).getLength();
width = getBlockContainerFO().getInlineProgressionDimension()
.getOptimum(this).getLength();
}
adjustedSpaceBefore = getBlockContainerFO().getCommonMarginBlock()
.spaceBefore.getSpace().getOptimum(this).getLength().getValue(this);
adjustedSpaceAfter = getBlockContainerFO().getCommonMarginBlock()
.spaceAfter.getSpace().getOptimum(this).getLength().getValue(this);
}
@Override
protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return getBlockContainerFO().getCommonBorderPaddingBackground();
}
private void resetSpaces() {
this.discardBorderBefore = false;
this.discardBorderAfter = false;
this.discardPaddingBefore = false;
this.discardPaddingAfter = false;
this.effSpaceBefore = null;
this.effSpaceAfter = null;
}
protected int getRotatedIPD() {
return getBlockContainerFO().getInlineProgressionDimension()
.getOptimum(this).getLength().getValue(this);
}
private boolean needClip() {
int overflow = getBlockContainerFO().getOverflow();
return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW);
}
private int getBPIndents() {
int indents = 0;
indents += getBlockContainerFO().getCommonBorderPaddingBackground()
.getBPPaddingAndBorder(false, this);
return indents;
}
private boolean isAbsoluteOrFixed() {
return (abProps.absolutePosition == EN_ABSOLUTE
|| abProps.absolutePosition == EN_FIXED);
}
private boolean isFixed() {
return (abProps.absolutePosition == EN_FIXED);
}
@Override
public int getContentAreaBPD() {
if (autoHeight) {
return -1;
} else {
return this.vpContentBPD;
}
}
@Override
public List getNextKnuthElements(LayoutContext context, int alignment) {
return getNextKnuthElements(context, alignment, null, null, null);
}
@Override
protected LayoutContext makeChildLayoutContext(LayoutContext context) {
LayoutContext childLC = LayoutContext.newInstance();
childLC.setStackLimitBP(
context.getStackLimitBP().minus(MinOptMax.getInstance(relDims.bpd)));
childLC.setRefIPD(relDims.ipd);
childLC.setWritingMode(getBlockContainerFO().getWritingMode());
return childLC;
}
@Override
public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
Position restartPosition, LayoutManager restartAtLM) {
resetSpaces();
if (isAbsoluteOrFixed()) {
return getNextKnuthElementsAbsolute(context);
}
boolean isRestart = (lmStack != null);
boolean emptyStack = (!isRestart || lmStack.isEmpty());
setupAreaDimensions(context);
List<ListElement> returnedList;
List<ListElement> contentList = new LinkedList<ListElement>();
List<ListElement> returnList = new LinkedList<ListElement>();
if (!breakBeforeServed(context, returnList)) {
return returnList;
}
addFirstVisibleMarks(returnList, context, alignment);
if (autoHeight && inlineElementList) {
LayoutManager curLM;
LayoutManager prevLM = null;
LayoutContext childLC;
if (isRestart) {
if (emptyStack) {
assert restartAtLM != null && restartAtLM.getParent() == this;
curLM = restartAtLM;
} else {
curLM = (LayoutManager) lmStack.pop();
}
setCurrentChildLM(curLM);
} else {
curLM = getChildLM();
}
while (curLM != null) {
childLC = makeChildLayoutContext(context);
if (!isRestart || emptyStack) {
if (isRestart) {
curLM.reset();
}
returnedList = getNextChildElements(curLM, context, childLC, alignment,
null, null, null);
} else {
returnedList = getNextChildElements(curLM, context, childLC, alignment,
lmStack, restartPosition, restartAtLM);
emptyStack = true;
}
if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
childLC.clearKeepWithPreviousPending();
}
if (returnedList.size() == 1
&& ElementListUtils.startsWithForcedBreak(returnedList)) {
contentList.addAll(returnedList);
wrapPositionElements(contentList, returnList);
return returnList;
} else {
if (prevLM != null) {
addInBetweenBreak(contentList, context, childLC);
}
contentList.addAll(returnedList);
if (returnedList.isEmpty()) {
continue;
}
if (ElementListUtils.endsWithForcedBreak(returnedList)) {
if (curLM.isFinished() && !hasNextChildLM()) {
setFinished(true);
}
wrapPositionElements(contentList, returnList);
return returnList;
}
}
context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
childLC.clearKeepsPending();
prevLM = curLM;
curLM = getChildLM();
}
wrapPositionElements(contentList, returnList);
} else {
returnList.add(generateNonInlinedBox());
}
addLastVisibleMarks(returnList, context, alignment);
addKnuthElementsForBreakAfter(returnList, context);
context.updateKeepWithNextPending(getKeepWithNext());
setFinished(true);
return returnList;
}
private void setupAreaDimensions(LayoutContext context) {
autoHeight = false;
int maxbpd = context.getStackLimitBP().getOpt();
int allocBPD;
BlockContainer fo = getBlockContainerFO();
if (height.getEnum() == EN_AUTO
|| (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
allocBPD = maxbpd;
autoHeight = true;
inlineElementList = (fo.getReferenceOrientation() == 0);
} else {
allocBPD = height.getValue(this);
allocBPD += getBPIndents();
}
vpContentBPD = allocBPD - getBPIndents();
referenceIPD = context.getRefIPD();
if (width.getEnum() == EN_AUTO) {
updateContentAreaIPDwithOverconstrainedAdjust();
} else {
int contentWidth = width.getValue(this);
updateContentAreaIPDwithOverconstrainedAdjust(contentWidth);
}
contentRectOffsetX = 0;
contentRectOffsetY = 0;
int level = fo.getBidiLevel();
if ((level < 0) || ((level & 1) == 0)) {
contentRectOffsetX += fo.getCommonMarginBlock().startIndent.getValue(this);
} else {
contentRectOffsetX += fo.getCommonMarginBlock().endIndent.getValue(this);
}
contentRectOffsetY += fo.getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
contentRectOffsetY += fo.getCommonBorderPaddingBackground().getPaddingBefore(false, this);
updateRelDims();
int availableIPD = referenceIPD - getIPIndents();
if (getContentAreaIPD() > availableIPD) {
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
fo.getUserAgent().getEventBroadcaster());
eventProducer.objectTooWide(this, fo.getName(),
getContentAreaIPD(), context.getRefIPD(),
fo.getLocator());
}
}
private KnuthBox generateNonInlinedBox() {
MinOptMax range = MinOptMax.getInstance(relDims.ipd);
BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
breaker.doLayout(relDims.bpd, autoHeight);
boolean contentOverflows = breaker.isOverflow();
if (autoHeight) {
int newHeight = breaker.deferredAlg.totalWidth;
if (blockProgressionDirectionChanges()) {
setContentAreaIPD(newHeight);
} else {
vpContentBPD = newHeight;
}
updateRelDims();
}
Position bcPosition = new BlockContainerPosition(this, breaker);
KnuthBox knuthBox = new KnuthBox(vpContentBPD, notifyPos(bcPosition), false);
if (contentOverflows) {
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
getBlockContainerFO().getUserAgent().getEventBroadcaster());
boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
eventProducer.viewportBPDOverflow(this, getBlockContainerFO().getName(),
breaker.getOverflowAmount(), needClip(), canRecover,
getBlockContainerFO().getLocator());
}
return knuthBox;
}
private boolean blockProgressionDirectionChanges() {
return getBlockContainerFO().getReferenceOrientation() % 180 != 0;
}
@Override
public boolean isRestartable() {
return true;
}
private List<ListElement> getNextKnuthElementsAbsolute(LayoutContext context) {
autoHeight = false;
boolean bpDirectionChanges = blockProgressionDirectionChanges();
Point offset = getAbsOffset();
int allocBPD;
int allocIPD;
if (height.getEnum() == EN_AUTO
|| (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
allocBPD = 0;
if (abProps.bottom.getEnum() != EN_AUTO) {
int availHeight;
if (isFixed()) {
availHeight = (int)getCurrentPV().getViewArea().getHeight();
} else {
availHeight = context.getStackLimitBP().getOpt();
}
allocBPD = availHeight;
allocBPD -= offset.y;
if (abProps.bottom.getEnum() != EN_AUTO) {
allocBPD -= abProps.bottom.getValue(this);
if (allocBPD < 0) {
allocBPD = 0;
}
} else {
if (allocBPD < 0) {
allocBPD = 0;
}
}
} else {
allocBPD = context.getStackLimitBP().getOpt();
if (!bpDirectionChanges) {
autoHeight = true;
}
}
} else {
allocBPD = height.getValue(this);
allocBPD += getBPIndents();
}
if (width.getEnum() == EN_AUTO) {
int availWidth;
if (isFixed()) {
availWidth = (int)getCurrentPV().getViewArea().getWidth();
} else {
availWidth = context.getRefIPD();
}
allocIPD = availWidth;
if (abProps.left.getEnum() != EN_AUTO) {
allocIPD -= abProps.left.getValue(this);
}
if (abProps.right.getEnum() != EN_AUTO) {
allocIPD -= abProps.right.getValue(this);
if (allocIPD < 0) {
allocIPD = 0;
}
} else {
if (allocIPD < 0) {
allocIPD = 0;
}
if (bpDirectionChanges) {
autoHeight = true;
}
}
} else {
allocIPD = width.getValue(this);
allocIPD += getIPIndents();
}
vpContentBPD = allocBPD - getBPIndents();
setContentAreaIPD(allocIPD - getIPIndents());
contentRectOffsetX = 0;
contentRectOffsetY = 0;
updateRelDims();
MinOptMax range = MinOptMax.getInstance(relDims.ipd);
BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight);
boolean contentOverflows = breaker.isOverflow();
if (autoHeight) {
int newHeight = breaker.deferredAlg.totalWidth;
if (bpDirectionChanges) {
setContentAreaIPD(newHeight);
} else {
vpContentBPD = newHeight;
}
updateRelDims();
}
List<ListElement> returnList = new LinkedList<ListElement>();
if (!breaker.isEmpty()) {
Position bcPosition = new BlockContainerPosition(this, breaker);
returnList.add(new KnuthBox(0, notifyPos(bcPosition), false));
if (!autoHeight & (contentOverflows)) {
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
getBlockContainerFO().getUserAgent().getEventBroadcaster());
boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
eventProducer.viewportBPDOverflow(this, getBlockContainerFO().getName(),
breaker.getOverflowAmount(), needClip(), canRecover,
getBlockContainerFO().getLocator());
}
if (this.horizontalOverflow > 0) {
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider
.get(getBlockContainerFO().getUserAgent().getEventBroadcaster());
boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
eventProducer.viewportIPDOverflow(this, getBlockContainerFO().getName(),
this.horizontalOverflow, needClip(), canRecover, getBlockContainerFO().getLocator());
}
}
setFinished(true);
return returnList;
}
private void updateRelDims() {
Rectangle2D rect = new Rectangle2D.Double(
contentRectOffsetX, contentRectOffsetY,
getContentAreaIPD(),
this.vpContentBPD);
relDims = new FODimension(0, 0);
absoluteCTM = CTM.getCTMandRelDims(
getBlockContainerFO().getReferenceOrientation(),
getBlockContainerFO().getWritingMode(),
rect, relDims);
}
private class BlockContainerPosition extends NonLeafPosition {
private BlockContainerBreaker breaker;
public BlockContainerPosition(LayoutManager lm, BlockContainerBreaker breaker) {
super(lm, null);
this.breaker = breaker;
}
public BlockContainerBreaker getBreaker() {
return this.breaker;
}
}
private class BlockContainerBreaker extends AbstractBreaker {
private BlockContainerLayoutManager bclm;
private MinOptMax ipd;
private PageBreakingAlgorithm deferredAlg;
private BlockSequence deferredOriginalList;
private BlockSequence deferredEffectiveList;
public BlockContainerBreaker(BlockContainerLayoutManager bclm, MinOptMax ipd) {
this.bclm = bclm;
this.ipd = ipd;
}
protected void observeElementList(List elementList) {
ElementListObserver.observe(elementList, "block-container",
bclm.getBlockContainerFO().getId());
}
protected boolean isPartOverflowRecoveryActivated() {
return false;
}
protected boolean isSinglePartFavored() {
return true;
}
public int getDifferenceOfFirstPart() {
PageBreakPosition pbp = this.deferredAlg.getPageBreaks().getFirst();
return pbp.difference;
}
public boolean isOverflow() {
return !isEmpty()
&& ((deferredAlg.getPageBreaks().size() > 1)
|| (deferredAlg.totalWidth - deferredAlg.totalShrink)
> deferredAlg.getLineWidth());
}
public int getOverflowAmount() {
return (deferredAlg.totalWidth - deferredAlg.totalShrink)
- deferredAlg.getLineWidth();
}
protected LayoutManager getTopLevelLM() {
return bclm;
}
protected LayoutContext createLayoutContext() {
LayoutContext lc = super.createLayoutContext();
lc.setRefIPD(ipd.getOpt());
lc.setWritingMode(getBlockContainerFO().getWritingMode());
return lc;
}
protected List getNextKnuthElements(LayoutContext context, int alignment) {
LayoutManager curLM;
List<ListElement> returnList = new LinkedList<ListElement>();
while ((curLM = getChildLM()) != null) {
LayoutContext childLC = makeChildLayoutContext(context);
List returnedList = null;
if (!curLM.isFinished()) {
returnedList = curLM.getNextKnuthElements(childLC, alignment);
}
if (returnedList != null) {
bclm.wrapPositionElements(returnedList, returnList);
}
}
SpaceResolver.resolveElementList(returnList);
setFinished(true);
return returnList;
}
protected int getCurrentDisplayAlign() {
return getBlockContainerFO().getDisplayAlign();
}
protected boolean hasMoreContent() {
return !isFinished();
}
protected void addAreas(PositionIterator posIter, LayoutContext context) {
AreaAdditionUtil.addAreas(bclm, posIter, context);
}
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
this.deferredAlg = alg;
this.deferredOriginalList = originalList;
this.deferredEffectiveList = effectiveList;
}
protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
}
protected LayoutManager getCurrentChildLM() {
return curChildLM;
}
public void addContainedAreas(LayoutContext layoutContext) {
if (isEmpty()) {
return;
}
this.deferredAlg.removeAllPageBreaks();
this.addAreas(this.deferredAlg,
0,
this.deferredAlg.getPageBreaks().size(),
this.deferredOriginalList, this.deferredEffectiveList,
LayoutContext.offspringOf(layoutContext));
}
}
private Point getAbsOffset() {
int x = 0;
int y = 0;
if (abProps.left.getEnum() != EN_AUTO) {
x = abProps.left.getValue(this);
} else if (abProps.right.getEnum() != EN_AUTO
&& width.getEnum() != EN_AUTO) {
x = getReferenceAreaIPD()
- abProps.right.getValue(this) - width.getValue(this);
}
if (abProps.top.getEnum() != EN_AUTO) {
y = abProps.top.getValue(this);
} else if (abProps.bottom.getEnum() != EN_AUTO
&& height.getEnum() != EN_AUTO) {
y = getReferenceAreaBPD()
- abProps.bottom.getValue(this) - height.getValue(this);
}
return new Point(x, y);
}
@Override
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
getParentArea(null);
if (layoutContext.getSpaceBefore() > 0) {
addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
LayoutManager childLM;
LayoutManager lastLM = null;
LayoutContext lc = LayoutContext.offspringOf(layoutContext);
lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
if (layoutContext.getSpaceAfter() > 0) {
lc.setSpaceAfter(layoutContext.getSpaceAfter());
}
BlockContainerPosition bcpos = null;
PositionIterator childPosIter;
List<Position> positionList = new LinkedList<Position>();
Position pos;
Position firstPos = null;
Position lastPos = null;
while (parentIter.hasNext()) {
pos = parentIter.next();
if (pos.getIndex() >= 0) {
if (firstPos == null) {
firstPos = pos;
}
lastPos = pos;
}
Position innerPosition = pos;
if (pos instanceof NonLeafPosition) {
innerPosition = pos.getPosition();
}
if (pos instanceof BlockContainerPosition) {
if (bcpos != null) {
throw new IllegalStateException("Only one BlockContainerPosition allowed");
}
bcpos = (BlockContainerPosition)pos;
} else if (innerPosition == null) {
} else if (innerPosition.getLM() == this
&& !(innerPosition instanceof MappingPosition)) {
} else {
positionList.add(innerPosition);
lastLM = innerPosition.getLM();
}
}
addId();
registerMarkers(true, isFirst(firstPos), isLast(lastPos));
if (bcpos == null) {
childPosIter = new PositionIterator(positionList.listIterator());
while ((childLM = childPosIter.getNextChildLM()) != null) {
lc.setFlags(LayoutContext.LAST_AREA,
(layoutContext.isLastArea() && childLM == lastLM));
lc.setStackLimitBP(layoutContext.getStackLimitBP());
childLM.addAreas(childPosIter, lc);
}
} else {
bcpos.getBreaker().addContainedAreas(layoutContext);
}
registerMarkers(false, isFirst(firstPos), isLast(lastPos));
TraitSetter.addSpaceBeforeAfter(viewportBlockArea, layoutContext.getSpaceAdjust(),
effSpaceBefore, effSpaceAfter);
flush();
viewportBlockArea = null;
referenceArea = null;
resetSpaces();
notifyEndOfLayout();
}
@Override
public Area getParentArea(Area childArea) {
if (referenceArea == null) {
boolean switchedProgressionDirection = blockProgressionDirectionChanges();
boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection;
int level = getBlockContainerFO().getBidiLevel();
viewportBlockArea = new BlockViewport(allowBPDUpdate);
viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
if (level >= 0) {
viewportBlockArea.setBidiLevel(level);
}
viewportBlockArea.setIPD(getContentAreaIPD());
if (allowBPDUpdate) {
viewportBlockArea.setBPD(0);
} else {
viewportBlockArea.setBPD(this.vpContentBPD);
}
transferForeignAttributes(viewportBlockArea);
TraitSetter.setProducerID(viewportBlockArea, getBlockContainerFO().getId());
TraitSetter.setLayer(viewportBlockArea, getBlockContainerFO().getLayer());
TraitSetter.addBorders(viewportBlockArea,
getBlockContainerFO().getCommonBorderPaddingBackground(),
discardBorderBefore, discardBorderAfter, false, false, this);
TraitSetter.addPadding(viewportBlockArea,
getBlockContainerFO().getCommonBorderPaddingBackground(),
discardPaddingBefore, discardPaddingAfter, false, false, this);
TraitSetter.addMargins(viewportBlockArea,
getBlockContainerFO().getCommonBorderPaddingBackground(),
startIndent, endIndent,
this);
viewportBlockArea.setCTM(absoluteCTM);
viewportBlockArea.setClip(needClip());
if (abProps.absolutePosition == EN_ABSOLUTE
|| abProps.absolutePosition == EN_FIXED) {
Point offset = getAbsOffset();
viewportBlockArea.setXOffset(offset.x);
viewportBlockArea.setYOffset(offset.y);
} else {
}
referenceArea = new Block();
referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
if (level >= 0) {
referenceArea.setBidiLevel(level);
}
TraitSetter.setProducerID(referenceArea, getBlockContainerFO().getId());
if (abProps.absolutePosition == EN_ABSOLUTE) {
viewportBlockArea.setPositioning(Block.ABSOLUTE);
} else if (abProps.absolutePosition == EN_FIXED) {
viewportBlockArea.setPositioning(Block.FIXED);
}
parentLayoutManager.getParentArea(referenceArea);
referenceArea.setIPD(relDims.ipd);
setCurrentArea(viewportBlockArea);
}
return referenceArea;
}
@Override
public void addChildArea(Area childArea) {
if (referenceArea != null) {
referenceArea.addBlock((Block) childArea);
}
}
@Override
protected void flush() {
viewportBlockArea.addBlock(referenceArea, autoHeight);
TraitSetter.addBackground(viewportBlockArea,
getBlockContainerFO().getCommonBorderPaddingBackground(),
this);
super.flush();
}
@Override
public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
return 0;
}
@Override
public void discardSpace(KnuthGlue spaceGlue) {
}
@Override
public KeepProperty getKeepTogetherProperty() {
return getBlockContainerFO().getKeepTogether();
}
@Override
public KeepProperty getKeepWithPreviousProperty() {
return getBlockContainerFO().getKeepWithPrevious();
}
@Override
public KeepProperty getKeepWithNextProperty() {
return getBlockContainerFO().getKeepWithNext();
}
protected BlockContainer getBlockContainerFO() {
return (BlockContainer) fobj;
}
@Override
public boolean getGeneratesReferenceArea() {
return true;
}
@Override
public boolean getGeneratesBlockArea() {
return true;
}
public boolean handleOverflow(int milliPoints) {
if (milliPoints > this.horizontalOverflow) {
this.horizontalOverflow = milliPoints;
}
return true;
}
}