From: Joerg Pietschmann Date: Thu, 18 Jul 2002 22:25:30 +0000 (+0000) Subject: Rearranged page master calculations. X-Git-Tag: fop-0_20_5rc~126 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=64fbc69b8d86c58a77d3e9030ae89315ace63392;p=xmlgraphics-fop.git Rearranged page master calculations. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_20_2-maintain@195007 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java index fba2c52c0..bd6c9a2a4 100644 --- a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java @@ -37,127 +37,88 @@ public class ConditionalPageMasterReference extends FObj { throws FOPException { super(parent, propertyList); - this.name = getElementName(); + this.name = "fo:conditional-page-master-reference"; if (getProperty("master-reference") != null) { - setMasterName(getProperty("master-reference").getString()); + this.masterName = getProperty("master-reference").getString(); } - - validateParent(parent); - - setPagePosition(this.properties.get("page-position").getEnum()); - setOddOrEven(this.properties.get("odd-or-even").getEnum()); - setBlankOrNotBlank(this.properties.get("blank-or-not-blank").getEnum()); - - - } - - protected void setMasterName(String masterName) { - this.masterName = masterName; - } - - /** - * Returns the "master-reference" attribute of this page master reference - */ - public String getMasterName() { - return masterName; + if (parent.getName().equals("fo:repeatable-page-master-alternatives")) { + this.repeatablePageMasterAlternatives = + (RepeatablePageMasterAlternatives)parent; + if (masterName == null) { + log.warn("A fo:conditional-page-master-reference does not have a master-reference and so is being ignored"); + } else { + this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this); + } + } else { + throw new FOPException("fo:conditional-page-master-reference must be child " + + "of fo:repeatable-page-master-alternatives, not " + + parent.getName()); + } + this.pagePosition = this.properties.get("page-position").getEnum(); + this.oddOrEven = this.properties.get("odd-or-even").getEnum(); + this.blankOrNotBlank = this.properties.get("blank-or-not-blank").getEnum(); } - - protected boolean isValid(int currentPageNumber, boolean thisIsFirstPage, + protected boolean isValid(boolean isOddPage, boolean isFirstPage, boolean isEmptyPage) { // page-position - boolean okOnPagePosition = true; // default is 'any' - switch (getPagePosition()) { - case PagePosition.FIRST: - if (!thisIsFirstPage) - okOnPagePosition = false; - break; - case PagePosition.LAST: - // how the hell do you know at this point? - log.debug("LAST PagePosition NYI"); - okOnPagePosition = true; - break; - case PagePosition.REST: - if (thisIsFirstPage) - okOnPagePosition = false; - break; - case PagePosition.ANY: - okOnPagePosition = true; + if( isFirstPage ) { + if (pagePosition==PagePosition.REST) { + return false; + } else if (pagePosition==PagePosition.LAST) { + // how the hell do you know at this point? + log.debug("LAST PagePosition NYI"); + return false; + } + } else { + if (pagePosition==PagePosition.FIRST) { + return false; + } else if (pagePosition==PagePosition.LAST) { + // how the hell do you know at this point? + log.debug("LAST PagePosition NYI"); + // potentially valid, don't return + } } - // odd or even - boolean okOnOddOrEven = true; // default is 'any' - int ooe = getOddOrEven(); - boolean isOddPage = ((currentPageNumber % 2) == 1) ? true : false; - if ((OddOrEven.ODD == ooe) &&!isOddPage) { - okOnOddOrEven = false; - } - if ((OddOrEven.EVEN == ooe) && isOddPage) { - okOnOddOrEven = false; + // odd-or-even + if (isOddPage) { + if (oddOrEven==OddOrEven.EVEN) { + return false; + } + } else { + if (oddOrEven==OddOrEven.ODD) { + return false; + } } - // experimental check for blank-or-not-blank - - boolean okOnBlankOrNotBlank = true; // default is 'any' - - int bnb = getBlankOrNotBlank(); - - if ((BlankOrNotBlank.BLANK == bnb) &&!isEmptyPage) { - okOnBlankOrNotBlank = false; - } else if ((BlankOrNotBlank.NOT_BLANK == bnb) && isEmptyPage) { - okOnBlankOrNotBlank = false; + // blank-or-not-blank + if (isEmptyPage) { + if (blankOrNotBlank==BlankOrNotBlank.NOT_BLANK) { + return false; + } + } else { + if (blankOrNotBlank==BlankOrNotBlank.BLANK) { + return false; + } } - return (okOnOddOrEven && okOnPagePosition && okOnBlankOrNotBlank); - - } + return true; - protected void setPagePosition(int pagePosition) { - this.pagePosition = pagePosition; } protected int getPagePosition() { return this.pagePosition; } - protected void setOddOrEven(int oddOrEven) { - this.oddOrEven = oddOrEven; - } - protected int getOddOrEven() { return this.oddOrEven; } - protected void setBlankOrNotBlank(int blankOrNotBlank) { - this.blankOrNotBlank = blankOrNotBlank; - } - protected int getBlankOrNotBlank() { return this.blankOrNotBlank; } - protected String getElementName() { - return "fo:conditional-page-master-reference"; - } - - - protected void validateParent(FObj parent) throws FOPException { - if (parent.getName().equals("fo:repeatable-page-master-alternatives")) { - this.repeatablePageMasterAlternatives = - (RepeatablePageMasterAlternatives)parent; - - if (getMasterName() == null) { - log.warn("single-page-master-reference" - + "does not have a master-reference and so is being ignored"); - } else { - this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this); - } - } else { - throw new FOPException("fo:conditional-page-master-reference must be child " - + "of fo:repeatable-page-master-alternatives, not " - + parent.getName()); - } + public String getMasterName() { + return masterName; } - - } diff --git a/src/org/apache/fop/fo/pagination/PageMasterReference.java b/src/org/apache/fop/fo/pagination/PageMasterReference.java index 0af756abf..244919855 100644 --- a/src/org/apache/fop/fo/pagination/PageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/PageMasterReference.java @@ -18,74 +18,21 @@ import org.apache.fop.apps.FOPException; public abstract class PageMasterReference extends FObj implements SubSequenceSpecifier { - private String _masterName; - private PageSequenceMaster _pageSequenceMaster; + protected String masterName; public PageMasterReference(FObj parent, PropertyList propertyList) throws FOPException { super(parent, propertyList); - this.name = getElementName(); - if (getProperty("master-reference") != null) { - setMasterName(getProperty("master-reference").getString()); - } - validateParent(parent); - - } - - protected void setMasterName(String masterName) { - _masterName = masterName; } - /** - * Returns the "master-reference" attribute of this page master reference - */ public String getMasterName() { - return _masterName; - } - - protected void setPageSequenceMaster(PageSequenceMaster pageSequenceMaster) { - _pageSequenceMaster = pageSequenceMaster; - } - - protected PageSequenceMaster getPageSequenceMaster() { - return _pageSequenceMaster; - } - - public abstract String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage); - - /** - * Gets the formating object name for this object. Subclasses must provide this. - * - * @return the element name of this reference. e.g. fo:repeatable-page-master-reference - */ - protected abstract String getElementName(); - - /** - * Checks that the parent is the right element. The default implementation - * checks for fo:page-sequence-master - */ - protected void validateParent(FObj parent) throws FOPException { - if (parent.getName().equals("fo:page-sequence-master")) { - _pageSequenceMaster = (PageSequenceMaster)parent; - - if (getMasterName() == null) { - log.warn("" + getElementName() - + " does not have a master-reference and so is being ignored"); - } else { - _pageSequenceMaster.addSubsequenceSpecifier(this); - } - } else { - throw new FOPException(getElementName() + " must be" - + "child of fo:page-sequence-master, not " - + parent.getName()); - } + return masterName; } + + public abstract String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) + throws FOPException; public abstract void reset(); - - - - } diff --git a/src/org/apache/fop/fo/pagination/PageSequence.java b/src/org/apache/fop/fo/pagination/PageSequence.java index 7a7fd6092..4e7900c54 100644 --- a/src/org/apache/fop/fo/pagination/PageSequence.java +++ b/src/org/apache/fop/fo/pagination/PageSequence.java @@ -98,18 +98,14 @@ public class PageSequence extends FObj { // state attributes used during layout // - private Page currentPage; - // page number and related formatting variables -// private String ipnValue; private int firstPageNumber = 0; private PageNumberGenerator pageNumberGenerator; - private int currentPageNumber = 0; - private int forcePageCount = 0; + private int forcePageCount; private int pageCount = 0; - private boolean isForcing = false; + private int currentPageNumber; /** * specifies page numbering type (auto|auto-even|auto-odd|explicit) @@ -117,21 +113,10 @@ public class PageSequence extends FObj { private int pageNumberType; /** - * the current subsequence while formatting a given page sequence - */ - private SubSequenceSpecifier currentSubsequence; - - /** - * the current index in the subsequence list - */ - private int currentSubsequenceNumber = - -1; // starting case is -1 so that first getNext increments to 0 - - /** - * the name of the current page master + * the current page master */ - private String currentPageMasterName; - + private SimplePageMaster currentSimplePageMaster; + private PageSequenceMaster pageSequenceMaster; protected PageSequence(FObj parent, PropertyList propertyList) throws FOPException { @@ -170,8 +155,8 @@ public class PageSequence extends FObj { int pageStart = new Integer(ipnValue).intValue(); this.firstPageNumber = (pageStart > 0) ? pageStart : 1; } catch (NumberFormatException nfe) { - throw new FOPException("\"" + ipnValue - + "\" is not a valid value for initial-page-number"); + throw new FOPException("The value '" + ipnValue + + "' is not valid for initial-page-number"); } } @@ -199,8 +184,8 @@ public class PageSequence extends FObj { } if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { log.error("region-name '" - + flow.getFlowName() - + "' doesn't exist in the layout-master-set."); + + flow.getFlowName() + + "' doesn't exist in the layout-master-set."); } _flowMap.put(flow.getFlowName(), flow); setIsFlowSet(true); @@ -211,31 +196,28 @@ public class PageSequence extends FObj { * Runs the formatting of this page sequence into the given area tree */ public void format(AreaTree areaTree) throws FOPException { - - Status status = new Status(Status.OK); - - this.layoutMasterSet.resetPageMasters(); - PageSequence previousPageSequence=this.root.getPageSequence(); if( previousPageSequence!=null ) { - currentPageNumber = previousPageSequence.currentPageNumber; if (previousPageSequence.forcePageCount == ForcePageCount.AUTO) { if (pageNumberType == AUTO_ODD) { - if (currentPageNumber % 2 == 0) { - makeBlankPage(areaTree); + if (previousPageSequence.currentPageNumber % 2 == 0) { + previousPageSequence.makePage(areaTree,true,null); } + currentPageNumber = previousPageSequence.currentPageNumber; } else if (pageNumberType == AUTO_EVEN) { - if (currentPageNumber % 2 == 1) { - makeBlankPage(areaTree); + if (previousPageSequence.currentPageNumber % 2 == 1) { + previousPageSequence.makePage(areaTree,true,null); } + currentPageNumber = previousPageSequence.currentPageNumber; } else if (pageNumberType == EXPLICIT){ - if ((currentPageNumber % 2) - == (firstPageNumber % 2)) { - makeBlankPage(areaTree); + if ((previousPageSequence.currentPageNumber % 2) + != (firstPageNumber % 2)) { + previousPageSequence.makePage(areaTree,true,null); } currentPageNumber = firstPageNumber; } } else { + currentPageNumber = previousPageSequence.currentPageNumber; if (pageNumberType == AUTO_ODD) { if (currentPageNumber % 2 == 0) { currentPageNumber++; @@ -253,128 +235,127 @@ public class PageSequence extends FObj { } previousPageSequence = null; this.root.setPageSequence(this); - boolean isFirstPage = true; - int pageCount = 0; + this.currentSimplePageMaster = + this.layoutMasterSet.getSimplePageMaster(masterName); + if (this.currentSimplePageMaster==null) { + this.pageSequenceMaster = + this.layoutMasterSet.getPageSequenceMaster(masterName); + if (this.pageSequenceMaster==null) { + throw new FOPException("master-reference '" + masterName + + "' for fo:page-sequence matches no simple-page-master or page-sequence-master"); + } + pageSequenceMaster.reset(); + } + + // make pages and layout content + Status status = new Status(Status.OK); + Page lastPage = null; do { - boolean isEmptyPage = false; + boolean isBlankPage = false; - // for this calculation we are alreaddy on the + // for this calculation we are already on the // blank page if (status.getCode() == Status.FORCE_PAGE_BREAK_EVEN) { if ((currentPageNumber % 2) == 1) { - isEmptyPage = true; + isBlankPage = true; } } else if (status.getCode() == Status.FORCE_PAGE_BREAK_ODD) { if ((currentPageNumber % 2) == 0) { - isEmptyPage = true; + isBlankPage = true; } } + lastPage = makePage(areaTree, isBlankPage, lastPage); + // Hackery, should use special variable for flow + Region region = currentSimplePageMaster + .getRegion(RegionBody.REGION_CLASS); + Flow flow = (Flow)_flowMap.get(region.getRegionName()); + status = flow.getStatus(); + } while (flowsAreIncomplete()); - currentPage = makePage(areaTree, currentPageNumber, - isFirstPage, isEmptyPage); - - currentPage.setNumber(this.currentPageNumber); - String formattedPageNumber = - pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); - currentPage.setFormattedNumber(formattedPageNumber); - - log.info("[" + currentPageNumber + "]"); - - if (!isEmptyPage) { - BodyAreaContainer bodyArea = currentPage.getBody(); - bodyArea.setIDReferences(areaTree.getIDReferences()); - - Flow flow = getCurrentFlow(RegionBody.REGION_CLASS); - - if (null == flow) { - log.error("No flow found for region-body " - + "in page-master '" - + currentPageMasterName + "'"); - break; - } else { - status = flow.layout(bodyArea); - } - } - - // because of markers, do after fo:flow (likely also - // justifiable because of spec) - currentPage.setPageSequence(this); - formatStaticContent(areaTree); - areaTree.addPage(currentPage); - - this.currentPageNumber++; - pageCount++; // used for 'force-page-count' calculations - isFirstPage = false; - } - while (flowsAreIncomplete()); // handle cases of 'force-page-count' which do not depend // on the presence of a following page sequence if (this.forcePageCount == ForcePageCount.EVEN) { - if (pageCount % 2 != 0) { - makeBlankPage(areaTree); + if (this.pageCount % 2 != 0) { + makePage(areaTree,true, null); } } else if (this.forcePageCount == ForcePageCount.ODD) { - if (pageCount % 2 != 1) { - makeBlankPage(areaTree); + if (this.pageCount % 2 != 1) { + makePage(areaTree,true, null); } } else if (this.forcePageCount == ForcePageCount.END_ON_EVEN) { - if (currentPageNumber % 2 == 0) { - makeBlankPage(areaTree); + if (this.currentPageNumber % 2 == 0) { + makePage(areaTree,true, null); } } else if (this.forcePageCount == ForcePageCount.END_ON_ODD) { - if (currentPageNumber % 2 == 1) { - makeBlankPage(areaTree); + if (this.currentPageNumber % 2 == 1) { + makePage(areaTree,true, null); } } - currentPage = null; } /** * Creates a new page area for the given parameters * @param areaTree the area tree the page should be contained in - * @param firstAvailPageNumber the page number for this page - * @param isFirstPage true when this is the first page in the sequence - * @param isEmptyPage true if this page will be empty (e.g. forced even or odd break) + * @param isBlankPage true if this page will be empty (e.g. forced even or odd break, or forced page count) * @return a Page layout object based on the page master selected from the params */ - private Page makePage(AreaTree areaTree, int firstAvailPageNumber, - boolean isFirstPage, - boolean isEmptyPage) throws FOPException { - // layout this page sequence - - // while there is still stuff in the flow, ask the - // layoutMasterSet for a new page - - // page number is 0-indexed - PageMaster pageMaster = getNextPageMaster(masterName, - firstAvailPageNumber, - isFirstPage, isEmptyPage); - - // a legal alternative is to use the last sub-sequence - // specification which should be handled in getNextSubsequence. That's not done here. - if (pageMaster == null) { - throw new FOPException("page masters exhausted. Cannot recover."); + private Page makePage(AreaTree areaTree, + boolean isBlankPage, + Page lastPage) + throws FOPException { + if (this.pageSequenceMaster!=null) { + this.currentSimplePageMaster=this.pageSequenceMaster + .getNextSimplePageMaster(((this.currentPageNumber % 2)==1), + isBlankPage); + } + Page newPage = this.currentSimplePageMaster.getPageMaster() + .makePage(areaTree); + if (lastPage != null) { + Vector foots = lastPage.getPendingFootnotes(); + newPage.setPendingFootnotes(foots); } - Page p = pageMaster.makePage(areaTree); - if (currentPage != null) { - Vector foots = currentPage.getPendingFootnotes(); - p.setPendingFootnotes(foots); + newPage.setNumber(this.currentPageNumber); + String formattedPageNumber = + pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); + newPage.setFormattedNumber(formattedPageNumber); + newPage.setPageSequence(this); + log.info("[" + currentPageNumber + (isBlankPage?"(forced)]":"]")); + if (!isBlankPage) { + BodyAreaContainer bodyArea = newPage.getBody(); + bodyArea.setIDReferences(areaTree.getIDReferences()); + + Region region = currentSimplePageMaster + .getRegion(RegionBody.REGION_CLASS); + Flow flow = (Flow)_flowMap.get(region.getRegionName()); + if (flow != null) { + flow.layout(bodyArea); + } else { + throw new FOPException("No flow found for region-body in page-master '" + + currentSimplePageMaster.getMasterName() + "'"); + } } - return p; + // because of markers, do after fo:flow (likely also + // justifiable because of spec) + formatStaticContent(areaTree, newPage); + areaTree.addPage(newPage); + this.currentPageNumber++; + this.pageCount++; + return newPage; } /** * Formats the static content of the current page */ - private void formatStaticContent(AreaTree areaTree) throws FOPException { - SimplePageMaster simpleMaster = getCurrentSimplePageMaster(); + private void formatStaticContent(AreaTree areaTree, Page page) + throws FOPException { + SimplePageMaster simpleMaster = currentSimplePageMaster; if (simpleMaster.getRegion(RegionBefore.REGION_CLASS) != null - && (currentPage.getBefore() != null)) { + && (page.getBefore() != null)) { Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionBefore.REGION_CLASS).getRegionName()); if (staticFlow != null) { - AreaContainer beforeArea = currentPage.getBefore(); + AreaContainer beforeArea = page.getBefore(); beforeArea.setIDReferences(areaTree.getIDReferences()); layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionBefore.REGION_CLASS), @@ -383,11 +364,11 @@ public class PageSequence extends FObj { } if (simpleMaster.getRegion(RegionAfter.REGION_CLASS) != null - && (currentPage.getAfter() != null)) { + && (page.getAfter() != null)) { Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionAfter.REGION_CLASS).getRegionName()); if (staticFlow != null) { - AreaContainer afterArea = currentPage.getAfter(); + AreaContainer afterArea = page.getAfter(); afterArea.setIDReferences(areaTree.getIDReferences()); layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionAfter.REGION_CLASS), @@ -396,11 +377,11 @@ public class PageSequence extends FObj { } if (simpleMaster.getRegion(RegionStart.REGION_CLASS) != null - && (currentPage.getStart() != null)) { + && (page.getStart() != null)) { Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionStart.REGION_CLASS).getRegionName()); if (staticFlow != null) { - AreaContainer startArea = currentPage.getStart(); + AreaContainer startArea = page.getStart(); startArea.setIDReferences(areaTree.getIDReferences()); layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionStart.REGION_CLASS), @@ -409,11 +390,11 @@ public class PageSequence extends FObj { } if (simpleMaster.getRegion(RegionEnd.REGION_CLASS) != null - && (currentPage.getEnd() != null)) { + && (page.getEnd() != null)) { Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionEnd.REGION_CLASS).getRegionName()); if (staticFlow != null) { - AreaContainer endArea = currentPage.getEnd(); + AreaContainer endArea = page.getEnd(); endArea.setIDReferences(areaTree.getIDReferences()); layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionEnd.REGION_CLASS), @@ -426,191 +407,26 @@ public class PageSequence extends FObj { private void layoutStaticContent(Flow flow, Region region, AreaContainer area) throws FOPException { if (flow instanceof StaticContent) { - AreaContainer beforeArea = currentPage.getBefore(); ((StaticContent)flow).layout(area, region); } else { - log.error("" + region.getName() - + " only supports static-content flows currently. Cannot use flow named '" - + flow.getFlowName() + "'"); - } - } - - /** - * Returns the next SubSequenceSpecifier for the given page sequence master. The result - * is bassed on the current state of this page sequence. - */ - // refactored from PageSequenceMaster - private SubSequenceSpecifier getNextSubsequence(PageSequenceMaster master) { - if (master.getSubSequenceSpecifierCount() - > currentSubsequenceNumber + 1) { - - currentSubsequence = - master.getSubSequenceSpecifier(currentSubsequenceNumber + 1); - currentSubsequenceNumber++; - return currentSubsequence; - } else { - return null; - } - - } - - /** - * Returns the next simple page master for the given sequence master, page number and - * other state information - */ - private SimplePageMaster getNextSimplePageMaster(PageSequenceMaster sequenceMaster, - int currentPageNumber, boolean thisIsFirstPage, - boolean isEmptyPage) { - // handle forcing - if (isForcing) { - String nextPageMaster = getNextPageMasterName(sequenceMaster, - currentPageNumber, false, true); - return this.layoutMasterSet.getSimplePageMaster(nextPageMaster); - } - String nextPageMaster = getNextPageMasterName(sequenceMaster, - currentPageNumber, thisIsFirstPage, isEmptyPage); - return this.layoutMasterSet.getSimplePageMaster(nextPageMaster); - - } - - private String getNextPageMasterName(PageSequenceMaster sequenceMaster, - int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) { - - if (null == currentSubsequence) { - currentSubsequence = getNextSubsequence(sequenceMaster); - } - - String nextPageMaster = - currentSubsequence.getNextPageMaster(currentPageNumber, - thisIsFirstPage, - isEmptyPage); - - - if (null == nextPageMaster - || isFlowForMasterNameDone(currentPageMasterName)) { - SubSequenceSpecifier nextSubsequence = - getNextSubsequence(sequenceMaster); - if (nextSubsequence == null) { - log.error("Page subsequences exhausted. Using previous subsequence."); - thisIsFirstPage = - true; // this becomes the first page in the new (old really) page master - currentSubsequence.reset(); - - // we leave currentSubsequence alone - } - else { - currentSubsequence = nextSubsequence; - } - - nextPageMaster = - currentSubsequence.getNextPageMaster(currentPageNumber, - thisIsFirstPage, - isEmptyPage); - } - currentPageMasterName = nextPageMaster; - - return nextPageMaster; - - } - - private SimplePageMaster getCurrentSimplePageMaster() { - return this.layoutMasterSet.getSimplePageMaster(currentPageMasterName); - } - - private String getCurrentPageMasterName() { - return currentPageMasterName; - } - - // refactored from LayoutMasterSet - private PageMaster getNextPageMaster(String pageSequenceName, - int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) throws FOPException { - PageMaster pageMaster = null; - - // see if there is a page master sequence for this master name - PageSequenceMaster sequenceMaster = - this.layoutMasterSet.getPageSequenceMaster(pageSequenceName); - - if (sequenceMaster != null) { - pageMaster = getNextSimplePageMaster(sequenceMaster, - currentPageNumber, - thisIsFirstPage, - isEmptyPage).getPageMaster(); - - } else { // otherwise see if there's a simple master by the given name - SimplePageMaster simpleMaster = - this.layoutMasterSet.getSimplePageMaster(pageSequenceName); - if (simpleMaster == null) { - throw new FOPException("'master-reference' for 'fo:page-sequence'" - + "matches no 'simple-page-master' or 'page-sequence-master'"); - } - currentPageMasterName = pageSequenceName; - - pageMaster = simpleMaster.getNextPageMaster(); + log.error("The region '" + region.getRegionName() + + "' only supports static-content. Cannot use flow named '" + + flow.getFlowName() + "'"); } - return pageMaster; } - /** - * Returns true when there is more flow elements left to lay out. + * Returns true when there are more flow elements left to lay out. */ private boolean flowsAreIncomplete() { - boolean isIncomplete = false; - for (Enumeration e = _flowMap.elements(); e.hasMoreElements(); ) { Flow flow = (Flow)e.nextElement(); if (flow instanceof StaticContent) { continue; } - - Status status = flow.getStatus(); - isIncomplete |= status.isIncomplete(); - } - return isIncomplete; - } - - /** - * Returns the flow that maps to the given region class for the current - * page master. - */ - private Flow getCurrentFlow(String regionClass) { - Region region = getCurrentSimplePageMaster().getRegion(regionClass); - if (region != null) { - Flow flow = (Flow)_flowMap.get(region.getRegionName()); - return flow; - - } else { - - System.out.println("flow is null. regionClass = '" + regionClass - + "' currentSPM = " - + getCurrentSimplePageMaster()); - - return null; - } - - } - - private boolean isFlowForMasterNameDone(String masterName) { - // parameter is master-name of PMR; we need to locate PM - // referenced by this, and determine whether flow(s) are OK - if (isForcing) - return false; - if (masterName != null) { - - SimplePageMaster spm = - this.layoutMasterSet.getSimplePageMaster(masterName); - Region region = spm.getRegion(RegionBody.REGION_CLASS); - - - Flow flow = (Flow)_flowMap.get(region.getRegionName()); - if ((null == flow) || flow.getStatus().isIncomplete()) - return false; - else + if (flow.getStatus().isIncomplete()) { return true; + } } return false; } @@ -628,26 +444,7 @@ public class PageSequence extends FObj { } public int getPageCount() { - return this.pageCount; - } - - private void makeBlankPage(AreaTree areaTree) { - try { - this.isForcing = true; - currentPage = makePage(areaTree, currentPageNumber, false, - true); - String formattedPageNumber = - pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); - currentPage.setFormattedNumber(formattedPageNumber); - currentPage.setPageSequence(this); - formatStaticContent(areaTree); - log.debug("[forced-" + currentPageNumber + "]"); - areaTree.addPage(currentPage); - this.isForcing = false; - this.currentPageNumber++; - } catch (FOPException fopex) { - log.debug("'force-page-count' failure"); - } + return pageCount; } } diff --git a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java index 018356f7a..c36b14f31 100644 --- a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java +++ b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java @@ -32,7 +32,9 @@ public class PageSequenceMaster extends FObj { LayoutMasterSet layoutMasterSet; Vector subSequenceSpecifiers; - + private SubSequenceSpecifier currentSubSequence; + int currentSubSequenceNumber; + String masterName; // The terminology may be confusing. A 'page-sequence-master' consists // of a sequence of what the XSL spec refers to as @@ -45,49 +47,90 @@ public class PageSequenceMaster extends FObj { super(parent, propertyList); this.name = "fo:page-sequence-master"; - subSequenceSpecifiers = new Vector(); - if (parent.getName().equals("fo:layout-master-set")) { this.layoutMasterSet = (LayoutMasterSet)parent; - String pm = this.properties.get("master-name").getString(); - if (pm == null) { + this.masterName = this.properties.get("master-name").getString(); + if (this.masterName == null) { log.warn("page-sequence-master does not have " - + "a page-master-name and so is being ignored"); + + "a page-master-name and so is being ignored"); } else { - this.layoutMasterSet.addPageSequenceMaster(pm, this); + this.layoutMasterSet.addPageSequenceMaster(masterName, this); } } else { throw new FOPException("fo:page-sequence-master must be child " + "of fo:layout-master-set, not " + parent.getName()); } + subSequenceSpecifiers = new Vector(); + currentSubSequenceNumber = -1; + currentSubSequence = null; } protected void addSubsequenceSpecifier(SubSequenceSpecifier pageMasterReference) { subSequenceSpecifiers.addElement(pageMasterReference); } - protected SubSequenceSpecifier getSubSequenceSpecifier(int sequenceNumber) { - if (sequenceNumber >= 0 - && sequenceNumber < getSubSequenceSpecifierCount()) { - return (SubSequenceSpecifier)subSequenceSpecifiers.elementAt(sequenceNumber); + protected SubSequenceSpecifier getNextSubSequence() { + currentSubSequenceNumber++; + if (currentSubSequenceNumber >= 0 + && currentSubSequenceNumber < subSequenceSpecifiers.size()) { + return (SubSequenceSpecifier)subSequenceSpecifiers + .elementAt(currentSubSequenceNumber); } return null; - - - } - - protected int getSubSequenceSpecifierCount() { - return subSequenceSpecifiers.size(); } public void reset() { + currentSubSequenceNumber = -1; + currentSubSequence = null; for (Enumeration e = subSequenceSpecifiers.elements(); e.hasMoreElements(); ) { ((SubSequenceSpecifier)e.nextElement()).reset(); } - } - + public SimplePageMaster getNextSimplePageMaster(boolean oddPage, + boolean blankPage) + throws FOPException { + boolean firstPage = false; + if (currentSubSequence==null) { + currentSubSequence = getNextSubSequence(); + if (currentSubSequence==null) { + throw new FOPException("no subsequences in page-sequence-master '" + + masterName + "'"); + } + firstPage = true; + } + String pageMasterName = currentSubSequence + .getNextPageMasterName(oddPage, firstPage, blankPage); + boolean canRecover = true; + while (pageMasterName==null) { + SubSequenceSpecifier nextSubSequence = getNextSubSequence(); + firstPage = true; + if (nextSubSequence==null) { + if (!canRecover) { + throw new FOPException("subsequences exhausted in page-sequence-master '" + +masterName + +"', cannot recover"); + } + log.warn("subsequences exhausted in page-sequence-master '" + +masterName + +"', use previous subsequence"); + currentSubSequence.reset(); + canRecover = false; + } else { + currentSubSequence = nextSubSequence; + } + pageMasterName = currentSubSequence + .getNextPageMasterName(oddPage, firstPage, blankPage); + } + SimplePageMaster pageMaster=this.layoutMasterSet + .getSimplePageMaster(pageMasterName); + if (pageMaster==null) { + throw new FOPException("No simple-page-master matching '" + + pageMasterName + "' in page-sequence-master '" + + masterName +"'"); + } + return pageMaster; + } } diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java index a7ef8632c..db5734cbc 100644 --- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java +++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java @@ -47,38 +47,42 @@ public class RepeatablePageMasterAlternatives extends FObj super(parent, propertyList); this.name = "fo:repeatable-page-master-alternatives"; - conditionalPageMasterRefs = new Vector(); - if (parent.getName().equals("fo:page-sequence-master")) { this.pageSequenceMaster = (PageSequenceMaster)parent; this.pageSequenceMaster.addSubsequenceSpecifier(this); } else { - throw new FOPException("fo:repeatable-page-master-alternatives" + throw new FOPException("A fo:repeatable-page-master-alternatives" + "must be child of fo:page-sequence-master, not " + parent.getName()); } String mr = getProperty("maximum-repeats").getString(); if (mr.equals("no-limit")) { - setMaximumRepeats(INFINITE); + this.maximumRepeats=INFINITE; } else { try { - setMaximumRepeats(Integer.parseInt(mr)); + this.maximumRepeats = Integer.parseInt(mr); + if (this.maximumRepeats < 0) { + log.debug("negative maximum-repeats: "+this.maximumRepeats); + this.maximumRepeats = 0; + } } catch (NumberFormatException nfe) { throw new FOPException("Invalid number for " + "'maximum-repeats' property"); } } - + conditionalPageMasterRefs = new Vector(); } - public String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) { - String pm = null; + public void addConditionalPageMasterReference(ConditionalPageMasterReference cpmr) { + this.conditionalPageMasterRefs.addElement(cpmr); + } - if (getMaximumRepeats() != INFINITE) { - if (numberConsumed < getMaximumRepeats()) { + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { + if (maximumRepeats != -1) { + if (numberConsumed < maximumRepeats) { numberConsumed++; } else { return null; @@ -87,42 +91,17 @@ public class RepeatablePageMasterAlternatives extends FObj for (int i = 0; i < conditionalPageMasterRefs.size(); i++) { ConditionalPageMasterReference cpmr = - (ConditionalPageMasterReference)conditionalPageMasterRefs.elementAt(i); - - // 0-indexed page number - if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage, - isEmptyPage)) { - pm = cpmr.getMasterName(); - break; + (ConditionalPageMasterReference)conditionalPageMasterRefs + .elementAt(i); + if (cpmr.isValid(isOddPage, isFirstPage, isEmptyPage)) { + return cpmr.getMasterName(); } } - return pm; - } - - private void setMaximumRepeats(int maximumRepeats) { - if (maximumRepeats == INFINITE) { - this.maximumRepeats = maximumRepeats; - } else { - this.maximumRepeats = (maximumRepeats < 0) ? 0 : maximumRepeats; - } - - } - - private int getMaximumRepeats() { - return this.maximumRepeats; - } - - public void addConditionalPageMasterReference(ConditionalPageMasterReference cpmr) { - this.conditionalPageMasterRefs.addElement(cpmr); + return null; } public void reset() { this.numberConsumed = 0; } - - protected PageSequenceMaster getPageSequenceMaster() { - return pageSequenceMaster; - } - } diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java index 85abf8039..c4ed974c2 100644 --- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java @@ -27,59 +27,53 @@ public class RepeatablePageMasterReference extends PageMasterReference return new RepeatablePageMasterReference.Maker(); } - - private PageSequenceMaster pageSequenceMaster; - private int maximumRepeats; private int numberConsumed = 0; public RepeatablePageMasterReference(FObj parent, PropertyList propertyList) throws FOPException { super(parent, propertyList); - + name = "fo:repeatable-page-master-reference"; + if (getProperty("master-reference") != null) { + this.masterName = getProperty("master-reference").getString(); + if (parent.getName().equals("fo:page-sequence-master")) { + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; + pageSequenceMaster.addSubsequenceSpecifier(this); + } else { + throw new FOPException("A fo:repeatable-page-master-reference must be child of fo:page-sequence-master, not " + + parent.getName()); + } + } else { + log.warn("A fo:repeatable-page-master-reference does not have a master-reference and so is being ignored"); + } String mr = getProperty("maximum-repeats").getString(); if (mr.equals("no-limit")) { - setMaximumRepeats(INFINITE); + this.maximumRepeats = INFINITE; } else { try { - setMaximumRepeats(Integer.parseInt(mr)); + this.maximumRepeats = Integer.parseInt(mr); + if (this.maximumRepeats < 0) { + log.debug("negative maximum-repeats: "+this.maximumRepeats); + this.maximumRepeats = 0; + } } catch (NumberFormatException nfe) { - throw new FOPException("Invalid number for " - + "'maximum-repeats' property"); + throw new FOPException("Invalid number '" + mr + + "'for 'maximum-repeats' property"); } } - } - public String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) { - String pm = getMasterName(); - - if (getMaximumRepeats() != INFINITE) { - if (numberConsumed < getMaximumRepeats()) { + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { + if (maximumRepeats != INFINITE) { + if (numberConsumed < maximumRepeats) { numberConsumed++; } else { - pm = null; + return null; } } - return pm; - } - - private void setMaximumRepeats(int maximumRepeats) { - if (maximumRepeats == INFINITE) { - this.maximumRepeats = maximumRepeats; - } else { - this.maximumRepeats = (maximumRepeats < 0) ? 0 : maximumRepeats; - } - } - - private int getMaximumRepeats() { - return this.maximumRepeats; - } - - protected String getElementName() { - return "fo:repeatable-page-master-reference"; + return getMasterName(); } public void reset() { diff --git a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java index 7422aa257..303b1b7be 100644 --- a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java @@ -9,8 +9,7 @@ package org.apache.fop.fo.pagination; import org.apache.fop.fo.*; import org.apache.fop.apps.FOPException; -public class SinglePageMasterReference extends PageMasterReference - implements SubSequenceSpecifier { +public class SinglePageMasterReference extends PageMasterReference { public static class Maker extends FObj.Maker { public FObj make(FObj parent, @@ -32,13 +31,25 @@ public class SinglePageMasterReference extends PageMasterReference public SinglePageMasterReference(FObj parent, PropertyList propertyList) throws FOPException { super(parent, propertyList); + this.name = "fo:single-page-master-reference"; + if (getProperty("master-reference") != null) { + this.masterName = getProperty("master-reference").getString(); + if (parent.getName().equals("fo:page-sequence-master")) { + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; + pageSequenceMaster.addSubsequenceSpecifier(this); + } else { + throw new FOPException("A fo:single-page-master-reference must be child of fo:page-sequence-master, not " + + parent.getName()); + } + } else { + log.warn("A fo:single-page-master-reference does not have a master-reference and so is being ignored"); + } this.state = FIRST; - } - public String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) { + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { if (this.state == FIRST) { this.state = DONE; return getMasterName(); @@ -52,8 +63,4 @@ public class SinglePageMasterReference extends PageMasterReference this.state = FIRST; } - protected String getElementName() { - return "fo:single-page-master-reference"; - } - } diff --git a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java index e8507fa8d..2d99d5cda 100644 --- a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java +++ b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java @@ -6,15 +6,17 @@ */ package org.apache.fop.fo.pagination; +import org.apache.fop.apps.FOPException; /** * Classes that implement this interface can be added to a PageSequenceMaster, * and are capable of looking up an appropriate PageMaster. */ public interface SubSequenceSpecifier { - public String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage); + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) + throws FOPException; /** * Called before a new page sequence is rendered so subsequences can reset