diff options
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java')
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java | 383 |
1 files changed, 24 insertions, 359 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java index abf1644c9..efe64d284 100644 --- a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java @@ -21,61 +21,26 @@ package org.apache.fop.layoutmgr; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.datatypes.Numeric; import org.apache.fop.area.AreaTreeHandler; -import org.apache.fop.area.AreaTreeModel; -import org.apache.fop.area.IDTracker; -import org.apache.fop.area.PageViewport; import org.apache.fop.area.LineArea; -import org.apache.fop.area.Resolvable; - -import org.apache.fop.fo.Constants; -import org.apache.fop.fo.flow.Marker; -import org.apache.fop.fo.flow.RetrieveMarker; - import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.fo.pagination.PageSequenceMaster; import org.apache.fop.fo.pagination.SideRegion; import org.apache.fop.fo.pagination.StaticContent; import org.apache.fop.layoutmgr.inline.ContentLayoutManager; -import java.util.List; - /** * LayoutManager for a PageSequence. This class is instantiated by * area.AreaTreeHandler for each fo:page-sequence found in the * input document. */ -public class PageSequenceLayoutManager extends AbstractLayoutManager { +public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager { private static Log log = LogFactory.getLog(PageSequenceLayoutManager.class); - /** - * AreaTreeHandler which activates the PSLM and controls - * the rendering of its pages. - */ - private AreaTreeHandler areaTreeHandler; - - /** - * fo:page-sequence formatting object being - * processed by this class - */ - private PageSequence pageSeq; - private PageProvider pageProvider; - private IDTracker idTracker; - - /** - * Current page with page-viewport-area being filled by - * the PSLM. - */ - private Page curPage; - - private int startPageNum = 0; - private int currentPageNum = 0; - /** * Constructor * @@ -83,20 +48,10 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { * @param pseq fo:page-sequence to process */ public PageSequenceLayoutManager(AreaTreeHandler ath, PageSequence pseq) { - super(pseq); - this.areaTreeHandler = ath; - this.idTracker = ath.getIDTracker(); - this.pageSeq = pseq; + super(ath, pseq); this.pageProvider = new PageProvider(ath, pseq); } - /** - * @return the LayoutManagerMaker object associated to the areaTreeHandler - */ - public LayoutManagerMaker getLayoutManagerMaker() { - return areaTreeHandler.getLayoutManagerMaker(); - } - /** @return the PageProvider applicable to this page-sequence. */ public PageProvider getPageProvider() { return this.pageProvider; @@ -106,25 +61,27 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { * @return the PageSequence being managed by this layout manager */ protected PageSequence getPageSequence() { - return pageSeq; + return (PageSequence)pageSeq; } /** - * Activate the layout of this page sequence. - * PageViewports corresponding to each page generated by this - * page sequence will be created and sent to the AreaTreeModel - * for rendering. + * Provides access to this object + * @return this PageSequenceLayoutManager instance */ + public PageSequenceLayoutManager getPSLM() { + return this; + } + + /** {@inheritDoc} */ public void activateLayout() { - startPageNum = pageSeq.getStartingPageNumber(); - currentPageNum = startPageNum - 1; + initialize(); LineArea title = null; - if (pageSeq.getTitleFO() != null) { + if (getPageSequence().getTitleFO() != null) { try { ContentLayoutManager clm = getLayoutManagerMaker(). - makeContentLayoutManager(this, pageSeq.getTitleFO()); + makeContentLayoutManager(this, getPageSequence().getTitleFO()); title = (LineArea) clm.getParentArea(null); } catch (IllegalStateException e) { // empty title; do nothing @@ -145,9 +102,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { finishPage(); } - /** - * Finished the page-sequence and notifies everyone about it. - */ + /** {@inheritDoc} */ public void finishPageSequence() { if (pageSeq.hasId()) { idTracker.signalIDProcessed(pageSeq.getId()); @@ -157,11 +112,11 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { (currentPageNum - startPageNum) + 1); areaTreeHandler.notifyPageSequenceFinished(pageSeq, (currentPageNum - startPageNum) + 1); - pageSeq.releasePageSequence(); + getPageSequence().releasePageSequence(); // If this sequence has a page sequence master so we must reset // it in preparation for the next sequence - String masterReference = pageSeq.getMasterReference(); + String masterReference = getPageSequence().getMasterReference(); PageSequenceMaster pageSeqMaster = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(masterReference); if (pageSeqMaster != null) { @@ -173,229 +128,18 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { } } - /** - * Provides access to the current page. - * @return the current Page - */ - public Page getCurrentPage() { - return curPage; - } - - /** - * Provides access for setting the current page. - * @param currentPage the new current Page - */ - protected void setCurrentPage(Page currentPage) { - this.curPage = currentPage; - } - - /** - * Provides access to the current page number - * @return the current page number - */ - protected int getCurrentPageNum() { - return currentPageNum; - } - - /** - * Provides access to the current page viewport. - * @return the current PageViewport - *//* - public PageViewport getCurrentPageViewport() { - return curPage.getPageViewport(); - }*/ - - /** - * Provides access to this object - * @return this PageSequenceLayoutManager instance - */ - public PageSequenceLayoutManager getPSLM() { - return this; + /** {@inheritDoc} */ + protected Page createPage(int pageNumber, boolean isBlank) { + return pageProvider.getPage(isBlank, + pageNumber, PageProvider.RELTO_PAGE_SEQUENCE); } - /** - * This returns the first PageViewport that contains an id trait - * matching the idref argument, or null if no such PV exists. - * - * @param idref the idref trait needing to be resolved - * @return the first PageViewport that contains the ID trait - */ - public PageViewport getFirstPVWithID(String idref) { - List list = idTracker.getPageViewportsContainingID(idref); - if (list != null && list.size() > 0) { - return (PageViewport) list.get(0); - } - return null; - } - - /** - * This returns the last PageViewport that contains an id trait - * matching the idref argument, or null if no such PV exists. - * - * @param idref the idref trait needing to be resolved - * @return the last PageViewport that contains the ID trait - */ - public PageViewport getLastPVWithID(String idref) { - List list = idTracker.getPageViewportsContainingID(idref); - if (list != null && list.size() > 0) { - return (PageViewport) list.get(list.size() - 1); - } - return null; - } - - /** - * Add an ID reference to the current page. - * When adding areas the area adds its ID reference. - * For the page layout manager it adds the id reference - * with the current page to the area tree. - * - * @param id the ID reference to add - */ - public void addIDToPage(String id) { - if (id != null && id.length() > 0) { - idTracker.associateIDWithPageViewport(id, curPage.getPageViewport()); - } - } - - /** - * Add an id reference of the layout manager in the AreaTreeHandler, - * if the id hasn't been resolved yet - * @param id the id to track - * @return a boolean indicating if the id has already been resolved - * TODO Maybe give this a better name - */ - public boolean associateLayoutManagerID(String id) { - if (log.isDebugEnabled()) { - log.debug("associateLayoutManagerID(" + id + ")"); - } - if (!idTracker.alreadyResolvedID(id)) { - idTracker.signalPendingID(id); - return false; - } else { - return true; - } - } - - /** - * Notify the areaTreeHandler that the LayoutManagers containing - * idrefs have finished creating areas - * @param id the id for which layout has finished - */ - public void notifyEndOfLayout(String id) { - idTracker.signalIDProcessed(id); - } - - /** - * Identify an unresolved area (one needing an idref to be - * resolved, e.g. the internal-destination of an fo:basic-link) - * for both the AreaTreeHandler and PageViewport object. - * - * The IDTracker keeps a document-wide list of idref's - * and the PV's needing them to be resolved. It uses this to - * send notifications to the PV's when an id has been resolved. - * - * The PageViewport keeps lists of id's needing resolving, along - * with the child areas (page-number-citation, basic-link, etc.) - * of the PV needing their resolution. - * - * @param id the ID reference to add - * @param res the resolvable object that needs resolving - */ - public void addUnresolvedArea(String id, Resolvable res) { - curPage.getPageViewport().addUnresolvedIDRef(id, res); - idTracker.addUnresolvedIDRef(id, curPage.getPageViewport()); - } - - /** - * Bind the RetrieveMarker to the corresponding Marker subtree. - * If the boundary is page then it will only check the - * current page. For page-sequence and document it will - * lookup preceding pages from the area tree and try to find - * a marker. - * If we retrieve a marker from a preceding page, - * then the containing page does not have a qualifying area, - * and all qualifying areas have ended. - * Therefore we use last-ending-within-page (Constants.EN_LEWP) - * as the position. - * - * @param rm the RetrieveMarker instance whose properties are to - * used to find the matching Marker. - * @return a bound RetrieveMarker instance, or null if no Marker - * could be found. - */ - public RetrieveMarker resolveRetrieveMarker(RetrieveMarker rm) { - AreaTreeModel areaTreeModel = areaTreeHandler.getAreaTreeModel(); - String name = rm.getRetrieveClassName(); - int pos = rm.getRetrievePosition(); - int boundary = rm.getRetrieveBoundary(); - - // get marker from the current markers on area tree - Marker mark = (Marker)getCurrentPV().getMarker(name, pos); - if (mark == null && boundary != EN_PAGE) { - // go back over pages until mark found - // if document boundary then keep going - boolean doc = boundary == EN_DOCUMENT; - int seq = areaTreeModel.getPageSequenceCount(); - int page = areaTreeModel.getPageCount(seq) - 1; - while (page < 0 && doc && seq > 1) { - seq--; - page = areaTreeModel.getPageCount(seq) - 1; - } - while (page >= 0) { - PageViewport pv = areaTreeModel.getPage(seq, page); - mark = (Marker)pv.getMarker(name, Constants.EN_LEWP); - if (mark != null) { - break; - } - page--; - if (page < 0 && doc && seq > 1) { - seq--; - page = areaTreeModel.getPageCount(seq) - 1; - } - } - } - - if (mark == null) { - log.debug("found no marker with name: " + name); - return null; - } else { - rm.bindMarker(mark); - return rm; - } - } - - /** - * Makes a new page - * - * @param bIsBlank whether this page is blank or not - * @param bIsLast whether this page is the last page or not - * @return a new page - */ - protected Page makeNewPage(boolean bIsBlank, boolean bIsLast) { - if (curPage != null) { - finishPage(); - } - - currentPageNum++; - - curPage = pageProvider.getPage(bIsBlank, - currentPageNum, PageProvider.RELTO_PAGE_SEQUENCE); - - if (log.isDebugEnabled()) { - log.debug("[" + curPage.getPageViewport().getPageNumberString() - + (bIsBlank ? "*" : "") + "]"); - } - - addIDToPage(pageSeq.getId()); - return curPage; - } - private void layoutSideRegion(int regionID) { SideRegion reg = (SideRegion)curPage.getSimplePageMaster().getRegion(regionID); if (reg == null) { return; } - StaticContent sc = pageSeq.getStaticContent(reg.getRegionName()); + StaticContent sc = getPageSequence().getStaticContent(reg.getRegionName()); if (sc == null) { return; } @@ -406,94 +150,15 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager { lm.doLayout(); } - private void finishPage() { - if (log.isTraceEnabled()) { - curPage.getPageViewport().dumpMarkers(); - } + /** {@inheritDoc} */ + protected void finishPage() { // Layout side regions layoutSideRegion(FO_REGION_BEFORE); layoutSideRegion(FO_REGION_AFTER); layoutSideRegion(FO_REGION_START); layoutSideRegion(FO_REGION_END); - // Try to resolve any unresolved IDs for the current page. - // - idTracker.tryIDResolution(curPage.getPageViewport()); - // Queue for ID resolution and rendering - areaTreeHandler.getAreaTreeModel().addPage(curPage.getPageViewport()); - if (log.isDebugEnabled()) { - log.debug("page finished: " + curPage.getPageViewport().getPageNumberString() - + ", current num: " + currentPageNum); - } - curPage = null; + super.finishPage(); } - /** - * Act upon the force-page-count trait, - * in relation to the initial-page-number trait of the following page-sequence. - * @param nextPageSeqInitialPageNumber initial-page-number trait of next page-sequence - */ - public void doForcePageCount(Numeric nextPageSeqInitialPageNumber) { - - int forcePageCount = pageSeq.getForcePageCount(); - - // xsl-spec version 1.0 (15.oct 2001) - // auto | even | odd | end-on-even | end-on-odd | no-force | inherit - // auto: - // Force the last page in this page-sequence to be an odd-page - // if the initial-page-number of the next page-sequence is even. - // Force it to be an even-page - // if the initial-page-number of the next page-sequence is odd. - // If there is no next page-sequence - // or if the value of its initial-page-number is "auto" do not force any page. - - // if force-page-count is auto then set the value of forcePageCount - // depending on the initial-page-number of the next page-sequence - if (nextPageSeqInitialPageNumber != null && forcePageCount == Constants.EN_AUTO) { - if (nextPageSeqInitialPageNumber.getEnum() != 0) { - // auto | auto-odd | auto-even - int nextPageSeqPageNumberType = nextPageSeqInitialPageNumber.getEnum(); - if (nextPageSeqPageNumberType == Constants.EN_AUTO_ODD) { - forcePageCount = Constants.EN_END_ON_EVEN; - } else if (nextPageSeqPageNumberType == Constants.EN_AUTO_EVEN) { - forcePageCount = Constants.EN_END_ON_ODD; - } else { // auto - forcePageCount = Constants.EN_NO_FORCE; - } - } else { // <integer> for explicit page number - int nextPageSeqPageStart = nextPageSeqInitialPageNumber.getValue(); - // spec rule - nextPageSeqPageStart = (nextPageSeqPageStart > 0) ? nextPageSeqPageStart : 1; - if (nextPageSeqPageStart % 2 == 0) { // explicit even startnumber - forcePageCount = Constants.EN_END_ON_ODD; - } else { // explicit odd startnumber - forcePageCount = Constants.EN_END_ON_EVEN; - } - } - } - - if (forcePageCount == Constants.EN_EVEN) { - if ((currentPageNum - startPageNum + 1) % 2 != 0) { // we have an odd number of pages - curPage = makeNewPage(true, false); - } - } else if (forcePageCount == Constants.EN_ODD) { - if ((currentPageNum - startPageNum + 1) % 2 == 0) { // we have an even number of pages - curPage = makeNewPage(true, false); - } - } else if (forcePageCount == Constants.EN_END_ON_EVEN) { - if (currentPageNum % 2 != 0) { // we are now on an odd page - curPage = makeNewPage(true, false); - } - } else if (forcePageCount == Constants.EN_END_ON_ODD) { - if (currentPageNum % 2 == 0) { // we are now on an even page - curPage = makeNewPage(true, false); - } - } else if (forcePageCount == Constants.EN_NO_FORCE) { - // i hope: nothing special at all - } - - if (curPage != null) { - finishPage(); - } - } } |