From d38a721c3023236a70828b28f0df12d0293632d4 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Tue, 8 Nov 2016 14:34:28 +0000 Subject: [PATCH] FOP-2664: Use page-position=only if there is enough space git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1768702 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/layoutmgr/AbstractBreaker.java | 8 +- .../AbstractPageSequenceLayoutManager.java | 1 + .../java/org/apache/fop/layoutmgr/Page.java | 4 +- .../org/apache/fop/layoutmgr/PageBreaker.java | 5 +- .../apache/fop/layoutmgr/PageProvider.java | 14 +++- .../layoutmgr/PageSequenceLayoutManager.java | 20 +++-- .../page-position_only_2.xml | 80 +++++++++++++++++++ 7 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 fop/test/layoutengine/standard-testcases/page-position_only_2.xml diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBreaker.java index 36dd6f407..25fa35885 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBreaker.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBreaker.java @@ -45,6 +45,7 @@ public abstract class AbstractBreaker { private LayoutManager originalRestartAtLM; private Position positionAtBreak; private List firstElementsForRestart; + protected PageSequenceLayoutManager pslm; /** * A page break position. @@ -368,7 +369,7 @@ public abstract class AbstractBreaker { * @param autoHeight true if warnings about overflows should be disabled because the * the BPD is really undefined (for footnote-separators, for example) */ - public void doLayout(int flowBPD, boolean autoHeight) { + public boolean doLayout(int flowBPD, boolean autoHeight) { LayoutContext childLC = createLayoutContext(); childLC.setStackLimitBP(MinOptMax.getInstance(flowBPD)); alignment = Constants.EN_START; @@ -418,6 +419,10 @@ public abstract class AbstractBreaker { onLastPageAndIPDChanges = (lastPageHasIPDChange() && !thereIsANonRestartableLM(alg) && (shouldRedoLayout() || (wasLayoutRedone() && optimalPageCount > 1))); } + if ((ipdChangesOnNextPage || hasMoreContent() || optimalPageCount > 1) + && pslm != null && pslm.getCurrentPage().isPagePositionOnly) { + return false; + } if (alg.handlingFloat()) { nextSequenceStartsOn = handleFloatLayout(alg, optimalPageCount, blockList, childLC); } else if (ipdChangesOnNextPage || onLastPageAndIPDChanges) { @@ -457,6 +462,7 @@ public abstract class AbstractBreaker { // done blockLists = null; + return true; } private LayoutManager getRestartAtLM(PageBreakingAlgorithm alg, boolean ipdChangesOnNextPage, diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java index 8435ad093..64f87757a 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java @@ -111,6 +111,7 @@ public abstract class AbstractPageSequenceLayoutManager extends AbstractLayoutMa public void initialize() { startPageNum = pageSeq.getStartingPageNumber(); currentPageNum = startPageNum - 1; + curPage = null; } /** diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/Page.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/Page.java index d8ec66e82..6f3b97cd4 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/Page.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/Page.java @@ -34,6 +34,7 @@ public class Page { private SimplePageMaster spm; private PageViewport pageViewport; + protected boolean isPagePositionOnly; /** * Main constructor @@ -44,9 +45,10 @@ public class Page { * @param spanAll true if the first span area spans all columns */ public Page(SimplePageMaster spm, int pageNumber, String pageNumberStr, - boolean blank, boolean spanAll) { + boolean blank, boolean spanAll, boolean isPagePositionOnly) { this.spm = spm; this.pageViewport = new PageViewport(spm, pageNumber, pageNumberStr, blank, spanAll); + this.isPagePositionOnly = isPagePositionOnly; } /** diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageBreaker.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageBreaker.java index 9c1315640..43fca99a2 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageBreaker.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageBreaker.java @@ -43,7 +43,6 @@ import org.apache.fop.traits.MinOptMax; */ public class PageBreaker extends AbstractBreaker { - private PageSequenceLayoutManager pslm; private boolean firstPart = true; private boolean pageBreakHandled; private boolean needColumnBalancing; @@ -109,8 +108,8 @@ public class PageBreaker extends AbstractBreaker { * Starts the page breaking process. * @param flowBPD the constant available block-progression-dimension (used for every part) */ - void doLayout(int flowBPD) { - doLayout(flowBPD, false); + boolean doLayout(int flowBPD) { + return doLayout(flowBPD, false); } /** {@inheritDoc} */ diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageProvider.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageProvider.java index ca41c8c1e..ff6a277c7 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageProvider.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageProvider.java @@ -75,6 +75,8 @@ public class PageProvider implements Constants { */ private PageSequence pageSeq; + protected boolean skipPagePositionOnly; + /** * Main constructor. * @param ath the area tree handler @@ -86,6 +88,10 @@ public class PageProvider implements Constants { this.startPageOfPageSequence = ps.getStartingPageNumber(); } + public void initialize() { + cachedPages.clear(); + } + /** * The page breaker notifies the provider about the page number an element list starts * on so it can later retrieve PageViewports relative to this first page. @@ -346,7 +352,11 @@ public class PageProvider implements Constants { boolean isFirstPage = (startPageOfPageSequence == index); SimplePageMaster spm = pageSeq.getNextSimplePageMaster( index, isFirstPage, isLastPage, isBlank); - Page page = new Page(spm, index, pageNumberString, isBlank, spanAll); + boolean isPagePositionOnly = pageSeq.hasPagePositionOnly() && !skipPagePositionOnly; + if (isPagePositionOnly) { + spm = pageSeq.getNextSimplePageMaster(index, isFirstPage, true, isBlank); + } + Page page = new Page(spm, index, pageNumberString, isBlank, spanAll, isPagePositionOnly); //Set unique key obtained from the AreaTreeHandler page.getPageViewport().setKey(areaTreeHandler.generatePageViewportKey()); page.getPageViewport().setForeignAttributes(spm.getForeignAttributes()); @@ -372,7 +382,7 @@ public class PageProvider implements Constants { int index = this.cachedPages.size(); boolean isFirstPage = (startPageOfPageSequence == index); SimplePageMaster spm = pageSeq.getLastSimplePageMaster(index, isFirstPage, false); - Page page = new Page(spm, index, "", false, false); + Page page = new Page(spm, index, "", false, false, false); if (pageSeq.getRoot().getLastSeq() != null && pageSeq.getRoot().getLastSeq() != pageSeq) { return -1; } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java index 0ee7121af..cfcaabb33 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java @@ -131,15 +131,25 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager log.debug("Starting layout"); } - curPage = makeNewPage(false); - - pageBreaker = new PageBreaker(this); - int flowBPD = getCurrentPV().getBodyRegion().getRemainingBPD(); - pageBreaker.doLayout(flowBPD); + boolean finished = false; + while (!finished) { + initialize(); + curPage = makeNewPage(false); + + pageBreaker = new PageBreaker(this); + int flowBPD = getCurrentPV().getBodyRegion().getRemainingBPD(); + finished = pageBreaker.doLayout(flowBPD); + pageProvider.skipPagePositionOnly = true; + } finishPage(); } + public void initialize() { + super.initialize(); + pageProvider.initialize(); + } + /** {@inheritDoc} */ public void finishPageSequence() { if (pageSeq.hasId()) { diff --git a/fop/test/layoutengine/standard-testcases/page-position_only_2.xml b/fop/test/layoutengine/standard-testcases/page-position_only_2.xml new file mode 100644 index 000000000..08a485a8f --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/page-position_only_2.xml @@ -0,0 +1,80 @@ + + + + + +

+ This test checks for the use of an 'only' conditional-page-master-reference (XSL 1.1) +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + 1test + 2test + 3test + 4test + 5test + 6test + 7test + 8test + 9test + 10test + 11test + 12test + 13test + 14test + 15test + 16test + 17test + 18test + 19test + 20test + 21test + + + + + + + + + +
-- 2.39.5