From 3fcefdeb4be4b7b1d204c3e9d936b0d140276e83 Mon Sep 17 00:00:00 2001 From: Joerg Pietschmann Date: Sat, 17 Aug 2002 23:51:08 +0000 Subject: [PATCH] Attempt at adding static content. Moved subsequence handling to PageSequenceMaster. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195091 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/area/RegionReference.java | 2 +- src/org/apache/fop/fo/flow/StaticContent.java | 10 + .../ConditionalPageMasterReference.java | 106 ++-- .../fop/fo/pagination/LayoutMasterSet.java | 23 +- .../fo/pagination/PageMasterReference.java | 29 +- .../fop/fo/pagination/PageSequence.java | 510 +++++++++--------- .../fop/fo/pagination/PageSequenceMaster.java | 66 ++- src/org/apache/fop/fo/pagination/Region.java | 10 +- .../RepeatablePageMasterAlternatives.java | 54 +- .../RepeatablePageMasterReference.java | 37 +- .../fop/fo/pagination/SimplePageMaster.java | 6 +- .../pagination/SinglePageMasterReference.java | 6 +- .../fo/pagination/SubSequenceSpecifier.java | 8 +- .../fop/layoutmgr/PageLayoutManager.java | 48 +- .../layoutmgr/StaticContentLayoutManager.java | 103 ++++ 15 files changed, 573 insertions(+), 445 deletions(-) create mode 100644 src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java diff --git a/src/org/apache/fop/area/RegionReference.java b/src/org/apache/fop/area/RegionReference.java index 7d1f60674..2a4519658 100644 --- a/src/org/apache/fop/area/RegionReference.java +++ b/src/org/apache/fop/area/RegionReference.java @@ -39,7 +39,6 @@ public class RegionReference extends Area implements Serializable, Cloneable { return this.ctm; } - // the list of block areas from the static flow ArrayList blocks = new ArrayList(); @@ -61,4 +60,5 @@ public class RegionReference extends Area implements Serializable, Cloneable { rr.setIPD(getIPD()); return rr; } + } diff --git a/src/org/apache/fop/fo/flow/StaticContent.java b/src/org/apache/fop/fo/flow/StaticContent.java index 77f6fbb8f..0bf5f64a9 100644 --- a/src/org/apache/fop/fo/flow/StaticContent.java +++ b/src/org/apache/fop/fo/flow/StaticContent.java @@ -12,6 +12,7 @@ import org.apache.fop.fo.*; import org.apache.fop.fo.properties.*; import org.apache.fop.fo.pagination.*; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.StaticContentLayoutManager; public class StaticContent extends Flow { @@ -34,4 +35,13 @@ public class StaticContent extends Flow { } + private StaticContentLayoutManager lm; + + public StaticContentLayoutManager getLayoutManager() { + if (lm == null) { + lm = new StaticContentLayoutManager(this); + } + return lm; + } + } diff --git a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java index dcaf01180..a85ddd43a 100644 --- a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java @@ -43,9 +43,9 @@ public class ConditionalPageMasterReference extends FObj { 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()); + 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 void setMasterName(String masterName) { @@ -64,77 +64,49 @@ public class ConditionalPageMasterReference extends FObj { * checks the page number and emptyness to determine if this * matches. */ - 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? - getLogger().warn("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? + getLogger().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? + getLogger().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); - - } - - 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; + return true; } /** diff --git a/src/org/apache/fop/fo/pagination/LayoutMasterSet.java b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java index b35ea1f83..c415b1e4e 100644 --- a/src/org/apache/fop/fo/pagination/LayoutMasterSet.java +++ b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java @@ -31,7 +31,6 @@ import org.xml.sax.Attributes; public class LayoutMasterSet extends FObj { private HashMap simplePageMasters; private HashMap pageSequenceMasters; - private HashMap allRegions; public LayoutMasterSet(FONode parent) { super(parent); @@ -50,7 +49,6 @@ public class LayoutMasterSet extends FObj { this.simplePageMasters = new HashMap(); this.pageSequenceMasters = new HashMap(); - allRegions = new HashMap(); } /** @@ -109,20 +107,10 @@ public class LayoutMasterSet extends FObj { return false; } - /** - * Reset the state of the page sequence masters. - * Use when starting a new page sequence. - */ - protected void resetPageMasters() { - for (Iterator e = pageSequenceMasters.values().iterator(); - e.hasNext(); ) { - ((PageSequenceMaster)e.next()).reset(); - } - } - protected void checkRegionNames() throws FOPException { // Section 7.33.15 check to see that if a region-name is a // duplicate, that it maps to the same region-class. + HashMap allRegions = new HashMap(); for (Iterator spm = simplePageMasters.values().iterator(); spm.hasNext(); ) { SimplePageMaster simplePageMaster = @@ -155,16 +143,13 @@ public class LayoutMasterSet extends FObj { * @returns true when the region name specified has a region in this LayoutMasterSet */ protected boolean regionNameExists(String regionName) { - boolean result = false; for (Iterator e = simplePageMasters.values().iterator(); e.hasNext(); ) { - result = - ((SimplePageMaster)e.next()).regionNameExists(regionName); - if (result) { - return result; + if (((SimplePageMaster)e.next()).regionNameExists(regionName)) { + return true; } } - return result; + return false; } } diff --git a/src/org/apache/fop/fo/pagination/PageMasterReference.java b/src/org/apache/fop/fo/pagination/PageMasterReference.java index e13e517ff..fd5ec7770 100644 --- a/src/org/apache/fop/fo/pagination/PageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/PageMasterReference.java @@ -20,8 +20,7 @@ import org.xml.sax.Attributes; public abstract class PageMasterReference extends FObj implements SubSequenceSpecifier { - private String _masterName; - private PageSequenceMaster _pageSequenceMaster; + private String masterName; public PageMasterReference(FONode parent) { super(parent); @@ -30,48 +29,32 @@ public abstract class PageMasterReference extends FObj public void handleAttrs(Attributes attlist) throws FOPException { super.handleAttrs(attlist); if (getProperty("master-reference") != null) { - setMasterName(getProperty("master-reference").getString()); + this.masterName = 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; + return masterName; } - protected PageSequenceMaster getPageSequenceMaster() { - return _pageSequenceMaster; - } - - public abstract String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage); - /** * Checks that the parent is the right element. The default implementation * checks for fo:page-sequence-master */ protected void validateParent(FONode parent) throws FOPException { if (parent.getName().equals("fo:page-sequence-master")) { - _pageSequenceMaster = (PageSequenceMaster)parent; + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; if (getMasterName() == null) { getLogger().warn("" + getName() + " does not have a master-reference and so is being ignored"); } else { - _pageSequenceMaster.addSubsequenceSpecifier(this); + pageSequenceMaster.addSubsequenceSpecifier(this); } } else { throw new FOPException(getName() + " must be" @@ -80,6 +63,4 @@ public abstract class PageMasterReference extends FObj } } - 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 af0d043f1..8664d663c 100644 --- a/src/org/apache/fop/fo/pagination/PageSequence.java +++ b/src/org/apache/fop/fo/pagination/PageSequence.java @@ -66,16 +66,11 @@ public class PageSequence extends FObj { */ private HashMap _flowMap; - /** - * the "master-reference" attribute - */ - private String masterName; - // according to communication from Paul Grosso (XSL-List, // 001228, Number 406), confusion in spec section 6.4.5 about // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1) // fo:flow per fo:page-sequence only. - private boolean isFlowSet = false; +// private boolean isFlowSet = false; // for structure handler private boolean sequenceStarted = false; @@ -108,20 +103,14 @@ public class PageSequence extends FObj { private boolean thisIsFirstPage; /** - * the current subsequence while formatting a given page sequence - */ - private SubSequenceSpecifier currentSubsequence; - - /** - * the current index in the subsequence list + * The currentSimplePageMaster is either the page master for the + * whole page sequence if master-reference refers to a simple-page-master, + * or the simple page master produced by the page sequence mster otherwise. + * The pageSequenceMaster is null if master-reference refers to a + * simple-page-master. */ - private int currentSubsequenceNumber = - -1; // starting case is -1 so that first getNext increments to 0 - - /** - * the name of the current page master - */ - private String currentPageMasterName; + private SimplePageMaster currentSimplePageMaster; + private PageSequenceMaster pageSequenceMaster; /** * The main content flow for this page-sequence. @@ -179,10 +168,17 @@ public class PageSequence extends FObj { } - masterName = this.properties.get("master-reference").getString(); - // TODO: Add code here to set a reference to the PageSequenceMaster - // if the masterName names a page-sequence-master, else get a - // reference to the SimplePageMaster. Throw an exception if neither? + String masterName = this.properties.get("master-reference").getString(); + 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"); + } + } // get the 'format' properties this.pageNumberGenerator = @@ -207,18 +203,18 @@ public class PageSequence extends FObj { * based on the names given to the regions in the page-master used to * generate that page. */ - private void addFlow(Flow flow) throws FOPException { - if (_flowMap.containsKey(flow.getFlowName())) { - throw new FOPException("flow-names must be unique within an fo:page-sequence"); - } - if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { - getLogger().error("region-name '" - + flow.getFlowName() - + "' doesn't exist in the layout-master-set."); - } - _flowMap.put(flow.getFlowName(), flow); - //setIsFlowSet(true); - } +// private void addFlow(Flow flow) throws FOPException { +// if (_flowMap.containsKey(flow.getFlowName())) { +// throw new FOPException("flow-names must be unique within an fo:page-sequence"); +// } +// if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { +// getLogger().error("region-name '" +// + flow.getFlowName() +// + "' doesn't exist in the layout-master-set."); +// } +// _flowMap.put(flow.getFlowName(), flow); +// //setIsFlowSet(true); +// } /** @@ -242,26 +238,47 @@ public class PageSequence extends FObj { } else if (childName.equals("fo:flow")) { if (this.mainFlow != null) { throw new FOPException("Only a single fo:flow permitted" - + " per fo:page-sequence"); + + " per fo:page-sequence"); } else { + this.mainFlow = (Flow)child; + String flowName = this.mainFlow.getFlowName(); + if (_flowMap.containsKey(flowName)) { + throw new FOPException("flow-name " + + flowName + + " is not unique within an fo:page-sequence"); + } + if (!this.layoutMasterSet.regionNameExists(flowName)) { + getLogger().error("region-name '" + + flowName + + "' doesn't exist in the layout-master-set."); + } + // Don't add main flow to the flow map +// addFlow(mainFlow); if(!sequenceStarted) { structHandler.startPageSequence(this, titleFO, layoutMasterSet); sequenceStarted = true; } - this.mainFlow = (Flow)child; - addFlow(mainFlow); super.addChild(child); // For getChildren } } else if (childName.equals("fo:static-content")) { if (this.mainFlow != null) { - throw new FOPException(childName + - " must precede fo:flow; ignoring"); - } else { - if(!sequenceStarted) { - structHandler.startPageSequence(this, titleFO, layoutMasterSet); - sequenceStarted = true; - } - addFlow((Flow)child); + throw new FOPException(childName + + " must precede fo:flow; ignoring"); + } + String flowName = ((StaticContent)child).getFlowName(); + if (_flowMap.containsKey(flowName)) { + throw new FOPException("flow-name " + flowName + + " is not unique within an fo:page-sequence"); + } + if (!this.layoutMasterSet.regionNameExists(flowName)) { + getLogger().error("region-name '" + flowName + + "' doesn't exist in the layout-master-set."); + } + _flowMap.put(flowName, child); +// addFlow((Flow)child); + if(!sequenceStarted) { + structHandler.startPageSequence(this, titleFO, layoutMasterSet); + sequenceStarted = true; } } else { // Ignore it! @@ -284,51 +301,33 @@ public class PageSequence extends FObj { } } - -// /** -// * Return children for layout. Only the main flow is laid out directly. -// */ -// public ListIterator getChildren() { -// return new ListIterator() { -// boolean bFirst=true; -// public boolean hasNext() { -// return (bFirst==true && mainFlow != null); -// } -// public Object next() { -// if (bFirst==true && mainFlow != null) { -// bFirst=false; -// return mainFlow; -// } -// else throw new NoSuchElementException(); -// } -// public void remove() { -// throw new UnsupportedOperationException(); -// } -// }; -// } - /** * Runs the formatting of this page sequence into the given area tree */ public void format(AreaTree areaTree) throws FOPException { - // Make a new PageLayoutManager and a FlowLayoutManager - // Run the PLM in a thread - // Wait for them to finish. + // Make a new PageLayoutManager and a FlowLayoutManager + // Run the PLM in a thread + // Wait for them to finish. - // If no main flow, nothing to layout! - if (this.mainFlow == null) return; + // If no main flow, nothing to layout! + if (this.mainFlow == null) { + return; + } - // Initialize if already used? - this.layoutMasterSet.resetPageMasters(); + // Initialize if already used? + // this.layoutMasterSet.resetPageMasters(); + if (pageSequenceMaster != null ) { + pageSequenceMaster.reset(); + } int firstAvailPageNumber = 0; - // This will layout pages and add them to the area tree - PageLayoutManager pageLM = new PageLayoutManager(areaTree, this); - // For now, skip the threading and just call run directly. - pageLM.run(); + // This will layout pages and add them to the area tree + PageLayoutManager pageLM = new PageLayoutManager(areaTree, this); + // For now, skip the threading and just call run directly. + pageLM.run(); -// Thread layoutThread = new Thread(pageLM); + // Thread layoutThread = new Thread(pageLM); // layoutThread.start(); // log.debug("Layout thread started"); @@ -339,8 +338,8 @@ public class PageSequence extends FObj { // } catch (InterruptedException ie) { // log.error("PageSequence.format() interrupted waiting on layout"); // } - // Tell the root the last page number we created. - this.root.setRunningPageNumberCounter(this.currentPageNumber); + // Tell the root the last page number we created. + this.root.setRunningPageNumberCounter(this.currentPageNumber); } private void initPageNumber() { @@ -352,7 +351,7 @@ public class PageSequence extends FObj { // Use force-page-count=auto // on preceding page-sequence to make sure that there is no gap! if (currentPageNumber % 2 == 0) { - this.currentPageNumber++; + this.currentPageNumber++; } } else if (pageNumberType == AUTO_EVEN) { if (currentPageNumber % 2 == 1) { @@ -373,17 +372,26 @@ public class PageSequence extends FObj { * @param bIsLast If true, use the master for the last page in the sequence. */ public PageViewport createPage(boolean bIsBlank, boolean bIsLast) - throws FOPException - { - - // Set even/odd flag and first flag based on current state - // Should do it this way, but fix it later.... - /*boolean bEvenPage = ((this.currentPageNumber %2)==0); - currentPage = makePage(bEvenPage, */ - currentPage = makePage(this.currentPageNumber, - this.currentPageNumber==this.firstPageNumber, - bIsLast, bIsBlank); - return currentPage; + throws FOPException { + if (this.pageSequenceMaster!=null) { + this.currentSimplePageMaster = this.pageSequenceMaster + .getNextSimplePageMaster(((this.currentPageNumber % 2)==1), + thisIsFirstPage, + bIsBlank); + } + Region body = currentSimplePageMaster.getRegion(Region.BODY); + if (!this.mainFlow.getFlowName().equals(body.getRegionName())) { + throw new FOPException("Flow '" + this.mainFlow.getFlowName() + + "' does not map to the region-body in page-master '" + + currentSimplePageMaster.getMasterName() + "'"); + } + PageMaster pageMaster = this.currentSimplePageMaster.getPageMaster(); + PageViewport p = pageMaster.makePage(); +// if (currentPage != null) { +// Vector foots = currentPage.getPendingFootnotes(); +// p.setPendingFootnotes(foots); +// } + return p; // The page will have a viewport/reference area pair defined // for each region in the master. // Set up the page itself @@ -422,32 +430,32 @@ public class PageSequence extends FObj { * from the params * TODO: modify the other methods to use even/odd flag and bIsLast */ - private PageViewport makePage(int firstAvailPageNumber, - boolean isFirstPage, boolean bIsLast, - 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."); - } - PageViewport p = pageMaster.makePage(); -// if (currentPage != null) { -// Vector foots = currentPage.getPendingFootnotes(); -// p.setPendingFootnotes(foots); -// } - return p; - } +// private PageViewport makePage(int firstAvailPageNumber, +// boolean isFirstPage, boolean bIsLast, +// 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."); +// } +// PageViewport p = pageMaster.makePage(); +// // if (currentPage != null) { +// // Vector foots = currentPage.getPendingFootnotes(); +// // p.setPendingFootnotes(foots); +// // } +// return p; +// } /** * Formats the static content of the current page @@ -525,37 +533,37 @@ public class PageSequence extends FObj { * Returns the next SubSequenceSpecifier for the given page sequence master. * The result is bassed on the current state of this page sequence. */ - private SubSequenceSpecifier getNextSubsequence(PageSequenceMaster master) { - if (master.getSubSequenceSpecifierCount() - > currentSubsequenceNumber + 1) { - - currentSubsequence = - master.getSubSequenceSpecifier(currentSubsequenceNumber + 1); - currentSubsequenceNumber++; - return currentSubsequence; - } else { - return null; - } - } +// 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 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); + +// } /** * Get the next page master name. @@ -563,86 +571,86 @@ public class PageSequence extends FObj { * is exhausted then an error is indicated and the last page * master name is used. */ - 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) { - getLogger().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; - } +// 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) { +// getLogger().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(); - } - return pageMaster; - } +// 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(); +// } +// return pageMaster; +// } // /** @@ -684,34 +692,34 @@ public class PageSequence extends FObj { // } - 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) { +// 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(Region.BODY); +// SimplePageMaster spm = +// this.layoutMasterSet.getSimplePageMaster(masterName); +// Region region = spm.getRegion(Region.BODY); - Flow flow = (Flow)_flowMap.get(region.getRegionName()); - /*if ((null == flow) || flow.getStatus().isIncomplete()) - return false; - else - return true;*/ - } - return false; - } +// Flow flow = (Flow)_flowMap.get(region.getRegionName()); +// /*if ((null == flow) || flow.getStatus().isIncomplete()) +// return false; +// else +// return true;*/ +// } +// return false; +// } - public boolean isFlowSet() { - return isFlowSet; - } +// public boolean isFlowSet() { +// return isFlowSet; +// } - public void setIsFlowSet(boolean isFlowSet) { - this.isFlowSet = isFlowSet; - } +// public void setIsFlowSet(boolean isFlowSet) { +// this.isFlowSet = isFlowSet; +// } public String getIpnValue() { return ipnValue; @@ -788,4 +796,10 @@ public class PageSequence extends FObj { // } // } + public SimplePageMaster getCurrentSimplePageMaster() { + return currentSimplePageMaster; + } + public StaticContent getStaticContent(String name) { + return (StaticContent)_flowMap.get(name); + } } diff --git a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java index e32819ba7..eb0356235 100644 --- a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java +++ b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java @@ -27,6 +27,9 @@ import org.xml.sax.Attributes; public class PageSequenceMaster extends FObj { LayoutMasterSet layoutMasterSet; ArrayList subSequenceSpecifiers; + private SubSequenceSpecifier currentSubSequence; + private int currentSubSequenceNumber; + private String masterName; // The terminology may be confusing. A 'page-sequence-master' consists // of a sequence of what the XSL spec refers to as @@ -63,23 +66,66 @@ public class PageSequenceMaster extends FObj { subSequenceSpecifiers.add(pageMasterReference); } - protected SubSequenceSpecifier getSubSequenceSpecifier(int sequenceNumber) { - if (sequenceNumber >= 0 - && sequenceNumber < getSubSequenceSpecifierCount()) { - return (SubSequenceSpecifier)subSequenceSpecifiers.get(sequenceNumber); + private SubSequenceSpecifier getNextSubSequence() { + currentSubSequenceNumber++; + if (currentSubSequenceNumber >= 0 + && currentSubSequenceNumber < subSequenceSpecifiers.size()) { + return (SubSequenceSpecifier)subSequenceSpecifiers + .get(currentSubSequenceNumber); } return null; } - protected int getSubSequenceSpecifierCount() { - return subSequenceSpecifiers.size(); + public void reset() { + currentSubSequenceNumber = -1; + currentSubSequence = null; + for (int i = 0; i< subSequenceSpecifiers.size(); i++ ) { + ((SubSequenceSpecifier)subSequenceSpecifiers.get(i)).reset(); + } } - public void reset() { - for (Iterator e = subSequenceSpecifiers.iterator(); - e.hasNext(); ) { - ((SubSequenceSpecifier)e.next()).reset(); + public SimplePageMaster getNextSimplePageMaster(boolean oddPage, + boolean firstPage, + boolean blankPage) + throws FOPException { + if (currentSubSequence==null) { + currentSubSequence = getNextSubSequence(); + if (currentSubSequence==null) { + throw new FOPException("no subsequences in page-sequence-master '" + + masterName + "'"); + } } + String pageMasterName = currentSubSequence + .getNextPageMasterName(oddPage, firstPage, blankPage); + boolean canRecover = true; + while (pageMasterName==null) { + SubSequenceSpecifier nextSubSequence = getNextSubSequence(); + if (nextSubSequence==null) { + if (!canRecover) { + throw new FOPException("subsequences exhausted in page-sequence-master '" + + masterName + + "', cannot recover"); + } + getLogger().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/Region.java b/src/org/apache/fop/fo/pagination/Region.java index eec03b821..a259d7749 100644 --- a/src/org/apache/fop/fo/pagination/Region.java +++ b/src/org/apache/fop/fo/pagination/Region.java @@ -31,11 +31,11 @@ import org.xml.sax.Attributes; public abstract class Region extends FObj { public static final String PROP_REGION_NAME = "region-name"; - final static String BEFORE = "before"; - final static String START = "start"; - final static String END = "end"; - final static String AFTER = "after"; - final static String BODY = "body"; + public final static String BEFORE = "before"; + public final static String START = "start"; + public final static String END = "end"; + public final static String AFTER = "after"; + public final static String BODY = "body"; private SimplePageMaster _layoutMaster; private String _regionName; diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java index 1acc24f42..e9469b41e 100644 --- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java +++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java @@ -26,8 +26,6 @@ public class RepeatablePageMasterAlternatives extends FObj private static final int INFINITE = -1; - private PageSequenceMaster pageSequenceMaster; - /** * Max times this page master can be repeated. * INFINITE is used for the unbounded case @@ -47,20 +45,25 @@ public class RepeatablePageMasterAlternatives extends FObj conditionalPageMasterRefs = new ArrayList(); if (parent.getName().equals("fo:page-sequence-master")) { - this.pageSequenceMaster = (PageSequenceMaster)parent; - this.pageSequenceMaster.addSubsequenceSpecifier(this); + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; + 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) { + getLogger().debug("negative maximum-repeats: " + + this.maximumRepeats); + this.maximumRepeats = 0; + } } catch (NumberFormatException nfe) { throw new FOPException("Invalid number for " + "'maximum-repeats' property"); @@ -72,13 +75,11 @@ public class RepeatablePageMasterAlternatives extends FObj * Get the next matching page master from the conditional * page master references. */ - public String getNextPageMaster(int currentPageNumber, - boolean thisIsFirstPage, - boolean isEmptyPage) { - String pm = null; - - if (getMaximumRepeats() != INFINITE) { - if (numberConsumed < getMaximumRepeats()) { + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { + if (maximumRepeats != INFINITE) { + if (numberConsumed < maximumRepeats) { numberConsumed++; } else { return null; @@ -88,28 +89,13 @@ public class RepeatablePageMasterAlternatives extends FObj for (int i = 0; i < conditionalPageMasterRefs.size(); i++) { ConditionalPageMasterReference cpmr = (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i); - - // 0-indexed page number - if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage, - isEmptyPage)) { - pm = cpmr.getMasterName(); - break; + 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; - } + return null; } - private int getMaximumRepeats() { - return this.maximumRepeats; - } public void addConditionalPageMasterReference(ConditionalPageMasterReference cpmr) { this.conditionalPageMasterRefs.add(cpmr); @@ -119,8 +105,4 @@ public class RepeatablePageMasterAlternatives extends FObj 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 5ef14e96b..869babd8e 100644 --- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java @@ -36,10 +36,15 @@ public class RepeatablePageMasterReference extends PageMasterReference 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) { + getLogger().debug("negative maximum-repeats: " + + this.maximumRepeats); + this.maximumRepeats = 0; + } } catch (NumberFormatException nfe) { throw new FOPException("Invalid number for " + "'maximum-repeats' property"); @@ -47,31 +52,17 @@ public class RepeatablePageMasterReference extends PageMasterReference } } - 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; + return getMasterName(); } public void reset() { diff --git a/src/org/apache/fop/fo/pagination/SimplePageMaster.java b/src/org/apache/fop/fo/pagination/SimplePageMaster.java index e08c34de1..243474bb5 100644 --- a/src/org/apache/fop/fo/pagination/SimplePageMaster.java +++ b/src/org/apache/fop/fo/pagination/SimplePageMaster.java @@ -154,8 +154,8 @@ public class SimplePageMaster extends FObj { String key = region.getRegionClass(); if (_regions.containsKey(key)) { getLogger().error("Only one region of class " - + key - + " allowed within a simple-page-master."); + + key + + " allowed within a simple-page-master."); // throw new FOPException("Only one region of class " // + key // + " allowed within a simple-page-master."); @@ -164,7 +164,7 @@ public class SimplePageMaster extends FObj { } } - protected Region getRegion(String regionClass) { + public Region getRegion(String regionClass) { return (Region)_regions.get(regionClass); } diff --git a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java index caa7457cf..6ed306b8d 100644 --- a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java +++ b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java @@ -26,9 +26,9 @@ public class SinglePageMasterReference extends PageMasterReference 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(); diff --git a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java index e8507fa8d..4a4c8bdb9 100644 --- a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java +++ b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java @@ -7,14 +7,16 @@ 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 diff --git a/src/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/org/apache/fop/layoutmgr/PageLayoutManager.java index 2fde2b55d..822a40ada 100644 --- a/src/org/apache/fop/layoutmgr/PageLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/PageLayoutManager.java @@ -9,7 +9,10 @@ package org.apache.fop.layoutmgr; import org.apache.fop.apps.FOPException; import org.apache.fop.area.*; +import org.apache.fop.fo.flow.StaticContent; import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.Region; +import org.apache.fop.fo.pagination.SimplePageMaster; import org.apache.fop.fo.properties.Constants; import java.util.ArrayList; @@ -109,13 +112,13 @@ public class PageLayoutManager extends AbstractBPLayoutManager implements Runnab BPLayoutManager curLM ; // currently active LM while ((curLM = getChildLM()) != null) { - BreakPoss bp; ArrayList vecBreakPoss = new ArrayList(); LayoutContext childLC = new LayoutContext(0); childLC.setStackLimit(new MinOptMax(flowBPD)); if (!curLM.isFinished()) { + BreakPoss bp; if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) { vecBreakPoss.add(bp); } @@ -171,7 +174,7 @@ public class PageLayoutManager extends AbstractBPLayoutManager implements Runnab // The Flow LM sets the "finished" flag on the Flow Area if it has // completely filled it. In this case, if on the last column // end the page. -getParentArea(area); + getParentArea(area); // Alternatively the child LM indicates to parent that it's full? //System.out.println("size: " + area.getAllocationBPD().max + // ":" + curSpan.getMaxBPD().min); @@ -214,17 +217,56 @@ getParentArea(area); } catch (FOPException fopex) { /* ???? */ fopex.printStackTrace(); } - RegionViewport reg = curPage.getPage(). getRegion( + RegionViewport reg = curPage.getPage().getRegion( RegionReference.BODY); curBody = (BodyRegion) reg.getRegion(); flowBPD = (int)reg.getViewArea().getHeight(); return curPage; } + private void layoutStaticContent(Region region, int regionClass) { + if (region != null ) { + StaticContent flow = pageSequence + .getStaticContent(region.getRegionName()); + if (flow != null) { + RegionViewport reg = curPage.getPage() + .getRegion(regionClass); + reg.getRegion().setIPD((int)reg.getViewArea().getWidth()); + if (reg == null ) { + System.out.println("no region viewport: shouldn't happen"); + } + StaticContentLayoutManager lm = flow.getLayoutManager(); + lm.init(); + lm.setRegionReference(reg.getRegion()); + lm.setParentLM(this); + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(new MinOptMax((int)curPage.getViewArea().getHeight())); + while (!lm.isFinished()) { + BreakPoss bp = lm.getNextBreakPoss(childLC, null); + if (bp != null) { + ArrayList vecBreakPoss = new ArrayList(); + vecBreakPoss.add(bp); + lm.addAreas( new BreakPossPosIter(vecBreakPoss, 0, + vecBreakPoss.size()), null); + } else { + System.out.println("bp==null cls="+regionClass); + } + } + //lm.flush(); + lm.reset(null); + } + } + } + private void finishPage() { if (curPage != null) { // Layout static content into the regions // Need help from pageseq for this + SimplePageMaster spm = pageSequence.getCurrentSimplePageMaster(); + layoutStaticContent(spm.getRegion(Region.BEFORE), RegionReference.BEFORE); + layoutStaticContent(spm.getRegion(Region.AFTER), RegionReference.AFTER); + layoutStaticContent(spm.getRegion(Region.START), RegionReference.START); + layoutStaticContent(spm.getRegion(Region.END), RegionReference.END); // Queue for ID resolution and rendering areaTree.addPage(curPage); curPage = null; diff --git a/src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java new file mode 100644 index 000000000..8d1859731 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java @@ -0,0 +1,103 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.Constants; +import org.apache.fop.area.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for an fo:flow object. + * Its parent LM is the PageLayoutManager. + * This LM is responsible for getting columns of the appropriate size + * and filling them with block-level areas generated by its children. + */ +public class StaticContentLayoutManager extends BlockStackingLayoutManager { + + private RegionReference region; + ArrayList blockBreaks = new ArrayList(); + + public StaticContentLayoutManager(FObj fobj) { + super(fobj); + } + + public void setRegionReference(RegionReference region) { + this.region = region; + } + + public BreakPoss getNextBreakPoss(LayoutContext context, + Position prevLineBP) { + + BPLayoutManager curLM ; // currently active LM + + while ((curLM = getChildLM()) != null) { + // Make break positions and return page break + // Set up a LayoutContext + BreakPoss bp; + LayoutContext childLC = context; + if (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) { + blockBreaks.add(bp); + if(bp.isForcedBreak()) { + System.out.println("Forced breaks are not allowed in static content"); + return null; + } + } + } + } + setFinished(true); + if (blockBreaks.size() > 0) { + return new BreakPoss( + new LeafPosition(this, blockBreaks.size() - 1)); + } + return null; + } + + public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { + + BPLayoutManager childLM ; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(blockBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + flush(); + // clear the breaks for the page to start for the next page + blockBreaks.clear(); + } + + + /** + * Add child area to a the correct container, depending on its + * area class. A Flow can fill at most one area container of any class + * at any one time. The actual work is done by BlockStackingLM. + */ + public boolean addChild(Area childArea) { + region.addBlock((Block)childArea); + return true; + } + + public Area getParentArea(Area childArea) { + return region; + } + +} + -- 2.39.5