package org.apache.fop.layoutmgr;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.fop.area.Block;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.Footnote;
import org.apache.fop.area.PageViewport;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
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.layoutmgr.list.ListItemLayoutManager;
import org.apache.fop.traits.MinOptMax;
public class PageBreaker extends AbstractBreaker {
private boolean firstPart = true;
private boolean pageBreakHandled;
private boolean needColumnBalancing;
private PageProvider pageProvider;
private Block separatorArea;
private boolean spanAllActive;
private boolean layoutRedone;
private int previousIndex;
private boolean handlingStartOfFloat;
private boolean handlingEndOfFloat;
private int floatHeight;
private int floatYOffset;
private List ;
private List relayedLengthList;
private int ;
private int ;
private boolean ;
private boolean ;
private int ;
private int ;
private int = -1;
private MinOptMax ;
private int = -2;
private int = -2;
private FlowLayoutManager childFLM;
private StaticContentLayoutManager ;
public PageBreaker(PageSequenceLayoutManager pslm) {
this.pslm = pslm;
this.pageProvider = pslm.getPageProvider();
this.childFLM = pslm.getLayoutManagerMaker().makeFlowLayoutManager(
pslm, pslm.getPageSequence().getMainFlow());
}
protected void updateLayoutContext(LayoutContext context) {
int flowIPD = pslm.getCurrentColumnWidth();
context.setRefIPD(flowIPD);
}
protected LayoutManager getTopLevelLM() {
return pslm;
}
protected PageProvider getPageProvider() {
return pslm.getPageProvider();
}
boolean doLayout(int flowBPD) {
return doLayout(flowBPD, false);
}
protected PageBreakingLayoutListener createLayoutListener() {
return new PageBreakingLayoutListener() {
public void notifyOverflow(int part, int amount, FObj obj) {
Page p = pageProvider.getPageFromColumnIndex(part);
RegionBody body = (RegionBody)p.getSimplePageMaster().getRegion(
Region.FO_REGION_BODY);
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
body.getUserAgent().getEventBroadcaster());
boolean canRecover = (body.getOverflow() != Constants.EN_ERROR_IF_OVERFLOW);
boolean needClip = (body.getOverflow() == Constants.EN_HIDDEN
|| body.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW);
eventProducer.regionOverflow(this, body.getName(),
p.getPageViewport().getPageNumberString(),
amount, needClip, canRecover,
body.getLocator());
}
};
}
protected int handleSpanChange(LayoutContext childLC, int nextSequenceStartsOn) {
needColumnBalancing = false;
if (childLC.getNextSpan() != Constants.NOT_SET) {
nextSequenceStartsOn = childLC.getNextSpan();
needColumnBalancing = childLC.getNextSpan() == Constants.EN_ALL
&& childLC.getDisableColumnBalancing() == Constants.EN_FALSE;
}
if (needColumnBalancing) {
log.debug(
"Column balancing necessary for the next element list!!!");
}
return nextSequenceStartsOn;
}
protected int getNextBlockList(LayoutContext childLC,
int nextSequenceStartsOn) {
return getNextBlockList(childLC, nextSequenceStartsOn, null, null, null);
}
protected int getNextBlockList(LayoutContext childLC, int nextSequenceStartsOn,
Position positionAtIPDChange, LayoutManager restartLM, List firstElements) {
if (!layoutRedone && !handlingFloat()) {
if (!firstPart) {
handleBreakTrait(nextSequenceStartsOn);
}
firstPart = false;
pageBreakHandled = true;
pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(), pslm.getCurrentPV()
.getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);
}
return super.getNextBlockList(childLC, nextSequenceStartsOn, positionAtIPDChange,
restartLM, firstElements);
}
private boolean (List contentList, LayoutContext context) {
boolean containsFootnotes = false;
if (contentList != null) {
for (Object aContentList : contentList) {
ListElement element = (ListElement) aContentList;
if (element instanceof KnuthBlockBox
&& ((KnuthBlockBox) element).hasAnchors()) {
containsFootnotes = true;
KnuthBlockBox box = (KnuthBlockBox) element;
List<List<KnuthElement>> footnotes = getFootnoteKnuthElements(childFLM, context,
box.getFootnoteBodyLMs());
for (List<KnuthElement> footnote : footnotes) {
box.addElementList(footnote);
}
}
}
}
return containsFootnotes;
}
public static List<List<KnuthElement>> (FlowLayoutManager flowLM, LayoutContext context,
List<FootnoteBodyLayoutManager> footnoteBodyLMs) {
List<List<KnuthElement>> footnotes = new ArrayList<List<KnuthElement>>();
LayoutContext footnoteContext = LayoutContext.copyOf(context);
footnoteContext.setStackLimitBP(context.getStackLimitBP());
footnoteContext.setRefIPD(flowLM.getPSLM()
.getCurrentPV().getRegionReference(Constants.FO_REGION_BODY).getIPD());
for (FootnoteBodyLayoutManager fblm : footnoteBodyLMs) {
fblm.setParent(flowLM);
fblm.initialize();
List<KnuthElement> footnote = fblm.getNextKnuthElements(footnoteContext, Constants.EN_START);
SpaceResolver.resolveElementList(footnote);
footnotes.add(footnote);
}
return footnotes;
}
private void handleFootnoteSeparator() {
StaticContent footnoteSeparator;
footnoteSeparator = pslm.getPageSequence().getStaticContent("xsl-footnote-separator");
if (footnoteSeparator != null) {
separatorArea = new Block();
separatorArea.setIPD(pslm.getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
footnoteSeparatorLM
= pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();
footnoteSeparatorLength = MinOptMax.getInstance(separatorArea.getBPD());
}
}
protected List getNextKnuthElements(LayoutContext context, int alignment) {
List contentList = null;
while (!childFLM.isFinished() && contentList == null) {
contentList = childFLM.getNextKnuthElements(context, alignment);
}
if (containsFootnotes(contentList, context)) {
handleFootnoteSeparator();
}
return contentList;
}
protected List getNextKnuthElements(LayoutContext context, int alignment,
Position positionAtIPDChange, LayoutManager restartAtLM) {
List contentList = null;
do {
contentList = childFLM.getNextKnuthElements(context, alignment, positionAtIPDChange,
restartAtLM);
} while (!childFLM.isFinished() && contentList == null);
if (containsFootnotes(contentList, context)) {
handleFootnoteSeparator();
}
return contentList;
}
protected int getCurrentDisplayAlign() {
return pslm.getCurrentPage().getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY).getDisplayAlign();
}
protected boolean hasMoreContent() {
return !childFLM.isFinished();
}
protected void addAreas(PositionIterator posIter, LayoutContext context) {
if (footnoteSeparatorLM != null) {
StaticContent footnoteSeparator = pslm.getPageSequence().getStaticContent(
"xsl-footnote-separator");
separatorArea = new Block();
separatorArea.setIPD(
pslm.getCurrentPV().getRegionReference(Constants.FO_REGION_BODY).getIPD());
footnoteSeparatorLM = pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();
}
childFLM.addAreas(posIter, context);
}
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
if (needColumnBalancing) {
redoLayout(alg, partCount, originalList, effectiveList);
return;
}
if (shouldRedoLayout(partCount)) {
redoLayout(alg, partCount, originalList, effectiveList);
return;
}
addAreas(alg, partCount, originalList, effectiveList);
}
protected void prepareToRedoLayout(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList,
BlockSequence effectiveList) {
int newStartPos = 0;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0 && !layoutRedone) {
addAreas(alg, restartPoint, originalList, effectiveList);
PageBreakPosition pbp = alg.getPageBreaks().get(restartPoint - 1);
newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
if (newStartPos > 0) {
handleBreakTrait(Constants.EN_PAGE);
}
}
pageBreakHandled = true;
int currentPageNum = pslm.getCurrentPageNum();
int currentColumn = pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex();
pageProvider.setStartOfNextElementList(currentPageNum, currentColumn, spanAllActive);
effectiveList.ignoreAtStart = newStartPos;
if (!layoutRedone) {
setLastPageIndex(currentPageNum);
pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
previousIndex = pageProvider.getIndexOfCachedLastPage();
} else {
setLastPageIndex(currentPageNum + 1);
pageProvider.discardCacheStartingWith(previousIndex);
pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
}
layoutRedone = true;
}
private void redoLayout(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
int newStartPos = 0;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0) {
addAreas(alg, restartPoint, originalList, effectiveList);
PageBreakPosition pbp = alg.getPageBreaks().get(restartPoint - 1);
newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
if (newStartPos > 0) {
handleBreakTrait(Constants.EN_PAGE);
}
}
log.debug("Restarting at " + restartPoint
+ ", new start position: " + newStartPos);
pageBreakHandled = true;
int currentPageNum = pslm.getCurrentPageNum();
pageProvider.setStartOfNextElementList(currentPageNum,
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);
effectiveList.ignoreAtStart = newStartPos;
PageBreakingAlgorithm algRestart;
if (needColumnBalancing) {
log.debug("Column balancing now!!!");
log.debug("===================================================");
algRestart = new BalancingColumnBreakingAlgorithm(
getTopLevelLM(), getPageProvider(), createLayoutListener(),
alignment, Constants.EN_START, footnoteSeparatorLength,
isPartOverflowRecoveryActivated(),
pslm.getCurrentPV().getBodyRegion().getColumnCount());
log.debug("===================================================");
} else {
BodyRegion currentBody = pageProvider.getPage(false, currentPageNum)
.getPageViewport().getBodyRegion();
setLastPageIndex(currentPageNum);
BodyRegion lastBody = pageProvider.getPage(false, currentPageNum)
.getPageViewport().getBodyRegion();
lastBody.getMainReference().setSpans(currentBody.getMainReference().getSpans());
log.debug("Last page handling now!!!");
log.debug("===================================================");
algRestart = new PageBreakingAlgorithm(
getTopLevelLM(), getPageProvider(), createLayoutListener(),
alg.getAlignment(), alg.getAlignmentLast(),
footnoteSeparatorLength,
isPartOverflowRecoveryActivated(), false, false);
log.debug("===================================================");
}
int optimalPageCount = algRestart.findBreakingPoints(effectiveList,
newStartPos,
1, true, BreakingAlgorithm.ALL_BREAKS);
log.debug("restart: optimalPageCount= " + optimalPageCount
+ " pageBreaks.size()= " + algRestart.getPageBreaks().size());
boolean fitsOnePage
= optimalPageCount <= pslm.getCurrentPV()
.getBodyRegion().getMainReference().getCurrentSpan().getColumnCount();
if (needColumnBalancing) {
if (!fitsOnePage) {
log.warn(
"Breaking algorithm produced more columns than are available.");
}
} else {
boolean ipdChange = algRestart.getIPDdifference() != 0;
if (fitsOnePage && !ipdChange) {
pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
} else {
addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
if (!ipdChange) {
setLastPageIndex(currentPageNum + 1);
pslm.setCurrentPage(pslm.makeNewPage(true));
}
return;
}
}
addAreas(algRestart, optimalPageCount, originalList, effectiveList);
}
private void setLastPageIndex(int currentPageNum) {
int lastPageIndex = pslm.getForcedLastPageNum(currentPageNum);
pageProvider.setLastPageIndex(lastPageIndex);
}
protected void startPart(BlockSequence list, int breakClass, boolean emptyContent) {
log.debug("startPart() breakClass=" + getBreakClassName(breakClass));
if (pslm.getCurrentPage() == null) {
throw new IllegalStateException("curPage must not be null");
}
if (!pageBreakHandled) {
if (!firstPart) {
handleBreakTrait(breakClass, emptyContent);
}
pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(),
this.spanAllActive);
}
pageBreakHandled = false;
firstPart = false;
}
protected void handleEmptyContent() {
pslm.getCurrentPV().getPage().fakeNonEmpty();
}
protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
if (!pslm.getTableHeaderFootnotes().isEmpty()
|| pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
|| pbp.footnoteFirstElementIndex <= pbp.footnoteLastElementIndex
|| !pslm.getTableFooterFootnotes().isEmpty()) {
for (List<KnuthElement> footnote : pslm.getTableHeaderFootnotes()) {
addFootnoteAreas(footnote);
}
for (int i = pbp.footnoteFirstListIndex; i <= pbp.footnoteLastListIndex; i++) {
List elementList = alg.getFootnoteList(i);
int firstIndex = (i == pbp.footnoteFirstListIndex
? pbp.footnoteFirstElementIndex : 0);
int lastIndex = (i == pbp.footnoteLastListIndex
? pbp.footnoteLastElementIndex : elementList.size() - 1);
addFootnoteAreas(elementList, firstIndex, lastIndex + 1);
}
for (List<KnuthElement> footnote : pslm.getTableFooterFootnotes()) {
addFootnoteAreas(footnote);
}
Footnote parentArea = pslm.getCurrentPV().getBodyRegion().getFootnote();
int topOffset = pslm.getCurrentPV().getBodyRegion().getBPD() - parentArea.getBPD();
if (separatorArea != null) {
topOffset -= separatorArea.getBPD();
}
parentArea.setTop(topOffset);
parentArea.setSeparator(separatorArea);
}
pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished();
pslm.clearTableHeadingFootnotes();
}
private void (List<KnuthElement> footnote) {
addFootnoteAreas(footnote, 0, footnote.size());
}
private void (List<KnuthElement> footnote, int startIndex, int endIndex) {
SpaceResolver.performConditionalsNotification(footnote, startIndex, endIndex - 1, -1);
LayoutContext childLC = LayoutContext.newInstance();
AreaAdditionUtil.addAreas(null, new KnuthPossPosIter(footnote, startIndex, endIndex), childLC);
}
protected FlowLayoutManager getCurrentChildLM() {
return childFLM;
}
protected void observeElementList(List elementList) {
ElementListObserver.observe(elementList, "breaker",
pslm.getFObj().getId());
}
private void handleBreakTrait(int breakVal) {
handleBreakTrait(breakVal, false);
}
private void handleBreakTrait(int breakVal, boolean emptyContent) {
Page curPage = pslm.getCurrentPage();
switch (breakVal) {
case Constants.EN_ALL:
curPage.getPageViewport().createSpan(true);
this.spanAllActive = true;
return;
case Constants.EN_NONE:
curPage.getPageViewport().createSpan(false);
this.spanAllActive = false;
return;
case Constants.EN_COLUMN:
case Constants.EN_AUTO:
case Constants.EN_PAGE:
case -1:
PageViewport pv = curPage.getPageViewport();
boolean forceNewPageWithSpan = false;
RegionBody rb = (RegionBody)curPage.getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY);
forceNewPageWithSpan
= (rb.getColumnCount() > 1
&& pv.getCurrentSpan().getColumnCount() == 1);
if (forceNewPageWithSpan) {
log.trace("Forcing new page with span");
curPage = pslm.makeNewPage(false);
curPage.getPageViewport().createSpan(true);
} else {
if (breakVal == Constants.EN_PAGE) {
handleBreakBeforeFollowingPage(breakVal);
} else {
if (pv.getCurrentSpan().hasMoreFlows()) {
log.trace("Moving to next flow");
pv.getCurrentSpan().moveToNextFlow();
} else {
log.trace("Making new page");
pslm.makeNewPage(false, emptyContent);
}
}
}
return;
default:
handleBreakBeforeFollowingPage(breakVal);
}
}
private void handleBreakBeforeFollowingPage(int breakVal) {
log.debug("handling break-before after page " + pslm.getCurrentPageNum() + " breakVal="
+ getBreakClassName(breakVal));
if (needBlankPageBeforeNew(breakVal)) {
log.trace("Inserting blank page");
pslm.makeNewPage(true);
}
if (needNewPage(breakVal)) {
log.trace("Making new page");
pslm.makeNewPage(false);
}
}
private boolean needBlankPageBeforeNew(int breakVal) {
if (breakVal == Constants.EN_PAGE
|| (pslm.getCurrentPage().getPageViewport().getPage().isEmpty())) {
return false;
} else {
if (pslm.getCurrentPageNum() % 2 == 0) {
return (breakVal == Constants.EN_EVEN_PAGE);
} else {
return (breakVal == Constants.EN_ODD_PAGE);
}
}
}
private boolean needNewPage(int breakVal) {
if (pslm.getCurrentPage().getPageViewport().getPage().isEmpty()) {
if (breakVal == Constants.EN_PAGE) {
return false;
} else if (pslm.getCurrentPageNum() % 2 == 0) {
return (breakVal == Constants.EN_ODD_PAGE);
} else {
return (breakVal == Constants.EN_EVEN_PAGE);
}
} else {
return true;
}
}
protected boolean shouldRedoLayout() {
return shouldRedoLayout(-1);
}
protected boolean shouldRedoLayout(int partCount) {
boolean lastPageMasterDefined = pslm.getPageSequence().hasPagePositionLast();
if (!lastPageMasterDefined && partCount != -1) {
lastPageMasterDefined = pslm.getPageSequence().hasPagePositionOnly() && pslm.isOnFirstPage(partCount - 1);
}
return (!hasMoreContent() && lastPageMasterDefined && !layoutRedone);
}
protected boolean wasLayoutRedone() {
return layoutRedone;
}
protected boolean lastPageHasIPDChange() {
boolean lastPageMasterDefined = pslm.getPageSequence().hasPagePositionLast();
boolean onlyPageMasterDefined = pslm.getPageSequence().hasPagePositionOnly();
if (lastPageMasterDefined && !onlyPageMasterDefined) {
int currentIPD = this.pageProvider.getCurrentIPD();
int lastPageIPD = this.pageProvider.getLastPageIPD();
if (lastPageIPD != -1 && currentIPD != lastPageIPD) {
return true;
}
}
return false;
}
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);
}
positionAtBreak = positionAtBreak.getPosition();
addAreas(alg, optimalPageCount, blockList, blockList);
blockLists.clear();
blockListIndex = -1;
LayoutManager restartAtLM = null;
if (positionAtBreak != null && positionAtBreak.getIndex() == -1) {
if (positionAtBreak instanceof ListItemLayoutManager.ListItemPosition) {
restartAtLM = positionAtBreak.getLM();
} else {
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();
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) {
lastBreakClass = Constants.EN_COLUMN;
} else {
lastBreakClass = pen.getBreakClass();
}
} else {
lastBreakClass = Constants.EN_COLUMN;
}
}
endElementIndex = pbp.getLeafPos();
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, false);
int displayAlign = getCurrentDisplayAlign();
int notificationEndElementIndex = endElementIndex;
endElementIndex -= (endElementIndex == (originalList.size() - 1)) ? effectiveList.ignoreAtEnd : 0;
if (((KnuthElement) effectiveList.get(endElementIndex)).isGlue()) {
endElementIndex--;
}
startElementIndex = alg.par.getFirstBoxIndex(startElementIndex);
if (startElementIndex <= endElementIndex) {
if (log.isDebugEnabled()) {
log.debug(" addAreas from " + startElementIndex + " to " + endElementIndex);
}
childLC.setSpaceAdjust(pbp.bpdAdjust);
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);
}
SpaceResolver.performConditionalsNotification(effectiveList, startElementIndex,
notificationEndElementIndex, lastBreak);
addAreas(new KnuthPossPosIter(effectiveList, startElementIndex, endElementIndex + 1), childLC);
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);
}
if (alg.handlingFloat()) {
PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) getTopLevelLM();
alg.relayFootnotes(pslm);
}
} else {
handleEmptyContent();
}
pageBreakHandled = true;
}
public void (List fl, List ll, int tfl, int ifl, boolean fp, boolean nf, int fnfi, int fli,
int fei, MinOptMax fsl, int pfli, int pfei) {
relayedFootnotesList = fl;
relayedLengthList = ll;
relayedTotalFootnotesLength = tfl;
relayedInsertedFootnotesLength = ifl;
relayedFootnotesPending = fp;
relayedNewFootnotes = nf;
relayedFirstNewFootnoteIndex = fnfi;
relayedFootnoteListIndex = fli;
relayedFootnoteElementIndex = fei;
relayedFootnoteSeparatorLength = fsl;
previousFootnoteListIndex = pfli;
previousFootnoteElementIndex = pfei;
}
public void (PageBreakingAlgorithm alg) {
if (relayedFootnotesList != null && relayedFootnotesList.size() > 0) {
alg.loadFootnotes(relayedFootnotesList, relayedLengthList, relayedTotalFootnotesLength,
relayedInsertedFootnotesLength, relayedFootnotesPending, relayedNewFootnotes,
relayedFirstNewFootnoteIndex, relayedFootnoteListIndex, relayedFootnoteElementIndex,
relayedFootnoteSeparatorLength, previousFootnoteListIndex,
previousFootnoteElementIndex);
relayedFootnotesList = null;
relayedLengthList = null;
relayedTotalFootnotesLength = 0;
relayedInsertedFootnotesLength = 0;
relayedFootnotesPending = false;
relayedNewFootnotes = false;
relayedFirstNewFootnoteIndex = 0;
relayedFootnoteListIndex = 0;
relayedFootnoteElementIndex = -1;
relayedFootnoteSeparatorLength = null;
}
}
}