]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Rearranged page master calculations.
authorJoerg Pietschmann <pietsch@apache.org>
Thu, 18 Jul 2002 22:25:30 +0000 (22:25 +0000)
committerJoerg Pietschmann <pietsch@apache.org>
Thu, 18 Jul 2002 22:25:30 +0000 (22:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_20_2-maintain@195007 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
src/org/apache/fop/fo/pagination/PageMasterReference.java
src/org/apache/fop/fo/pagination/PageSequence.java
src/org/apache/fop/fo/pagination/PageSequenceMaster.java
src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
src/org/apache/fop/fo/pagination/SinglePageMasterReference.java
src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java

index fba2c52c0fe4e6cff660f9bbeb079b1418a89df7..bd6c9a2a41f7eb79ae0ca5809abb483947dec58a 100644 (file)
@@ -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;
     }
-
-
 }
index 0af756abf565ad2ae7ec5025b97926a2c169b4fa..244919855887f352bc969dc660b2b1aba3054da4 100644 (file)
@@ -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();
-
-
-
-
 }
index 7a7fd6092a166373019af49f69efb406c0adff56..4e7900c5432cbcec4d545bc2893685504c8c4488 100644 (file)
@@ -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;
     }
 
 }
index 018356f7a782507cac24675e747497ea373a0af8..c36b14f31f3ba428405d3d030344fa267259b68b 100644 (file)
@@ -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;
+    }
 }
index a7ef8632c689393805aa3436810fa87f66ab10fa..db5734cbc250622d50cf0ee8536768a56d3b5282 100644 (file)
@@ -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("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;
-    }
-
 }
index 85abf8039d15f7bdb0f39b1968409e102ce0d731..c4ed974c258231d079255b5084fa173b7fbe763d 100644 (file)
@@ -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() {
index 7422aa25793e08457a1466cfa198fda5c33516b4..303b1b7be7ac33baf2429bc08a54b5ab92657f27 100644 (file)
@@ -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";
-    }
-
 }
index e8507fa8d876fb5c09f63d00b79930bf565b498a..2d99d5cda4a212f2041efd71ecd010c9d891038f 100644 (file)
@@ -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