From: Simon Pepping Date: Thu, 26 Aug 2004 20:58:30 +0000 (+0000) Subject: Moved some functionality from LMiter to the LayoutManagers. The LMs X-Git-Tag: Root_Temp_KnuthStylePageBreaking~601 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c576c48d54e356697316f73856dc3df49a255851;p=xmlgraphics-fop.git Moved some functionality from LMiter to the LayoutManagers. The LMs now hold the list of child LMs and the method preLoadNext. This makes it possible to create a new LMiter object for a LM, or even a list iterator over the list of child LMs if the latter is known to be complete. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197890 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/fop/area/AreaTreeHandler.java b/src/java/org/apache/fop/area/AreaTreeHandler.java index 02e9bd0c0..cb6d26e9a 100644 --- a/src/java/org/apache/fop/area/AreaTreeHandler.java +++ b/src/java/org/apache/fop/area/AreaTreeHandler.java @@ -432,20 +432,18 @@ public class AreaTreeHandler extends FOInputHandler { * @return the Title area */ private org.apache.fop.area.Title getTitleArea(org.apache.fop.fo.pagination.Title foTitle) { - // use special layout manager to add the inline areas - // to the Title. - InlineStackingLayoutManager lm; - lm = new InlineStackingLayoutManager(foTitle); - lm.setLMiter(new LMiter(lm, foTitle.getChildNodes())); - lm.initialize(); - // get breaks then add areas to title org.apache.fop.area.Title title = new org.apache.fop.area.Title(); ContentLayoutManager clm = new ContentLayoutManager(title); clm.setUserAgent(foTitle.getUserAgent()); - lm.setParent(clm); + + // use special layout manager to add the inline areas + // to the Title. + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager(foTitle); + clm.addChildLM(lm); clm.fillArea(lm); diff --git a/src/java/org/apache/fop/fo/FObjMixed.java b/src/java/org/apache/fop/fo/FObjMixed.java index f513998d7..8d3cc9ef1 100644 --- a/src/java/org/apache/fop/fo/FObjMixed.java +++ b/src/java/org/apache/fop/fo/FObjMixed.java @@ -75,7 +75,6 @@ public class FObjMixed extends FObj { if (getChildNodes() != null) { InlineStackingLayoutManager lm; lm = new InlineStackingLayoutManager(this); - lm.setLMiter(new LMiter(lm, getChildNodes())); list.add(lm); } } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index e1071156f..7ce205e6c 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -31,6 +31,8 @@ import org.apache.fop.fo.PropertyManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.util.List; +import java.util.ArrayList; import java.util.ListIterator; import java.util.Map; @@ -40,20 +42,24 @@ import java.util.Map; public abstract class AbstractLayoutManager implements LayoutManager, Constants { protected FOUserAgent userAgent; protected LayoutManager parentLM = null; + protected List childLMs = new ArrayList(10); protected FObj fobj; protected String foID = null; + protected ListIterator fobjIter = null; protected Map markers = null; /** True if this LayoutManager has handled all of its content. */ private boolean bFinished = false; - protected LayoutManager curChildLM = null; - protected ListIterator childLMiter; protected boolean bInited = false; + /** child LM and child LM iterator during getNextBreakPoss phase */ + protected LayoutManager curChildLM = null; + protected ListIterator childLMiter = null; + /** * logging instance */ - protected static Log log = LogFactory.getLog(AbstractLayoutManager.class); + protected static Log log = LogFactory.getLog(LayoutManager.class); /** * Abstract layout manager. @@ -82,7 +88,8 @@ public abstract class AbstractLayoutManager implements LayoutManager, Constants this.fobj = fo; foID = fobj.getID(); markers = fobj.getMarkers(); - childLMiter = new LMiter(this, fobj.getChildNodes()); + fobjIter = fobj.getChildNodes(); + childLMiter = new LMiter(this); } /** @@ -169,8 +176,6 @@ public abstract class AbstractLayoutManager implements LayoutManager, Constants } while (childLMiter.hasNext()) { curChildLM = (LayoutManager) childLMiter.next(); - curChildLM.setParent(this); - curChildLM.initialize(); return curChildLM; } return null; @@ -363,5 +368,70 @@ public abstract class AbstractLayoutManager implements LayoutManager, Constants return parentLM.retrieveMarker(name, pos, boundary); } + /** + * Convenience method: preload a number of child LMs + * @param size the requested number of child LMs + * @return the list with the preloaded child LMs + */ + protected List preLoadList(int size) { + if (fobjIter == null) { + return null; + } + AreaTreeHandler areaTreeHandler = getAreaTreeHandler(); + List newLMs = new ArrayList(size); + while (fobjIter.hasNext() && newLMs.size() < size ) { + Object theobj = fobjIter.next(); + if (theobj instanceof FObj) { + FObj fobj = (FObj) theobj; + areaTreeHandler.addLayoutManager(fobj, newLMs); + } + } + return newLMs; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#preLoadNext + */ + public boolean preLoadNext(int pos) { + List newLMs = preLoadList(pos + 1 - childLMs.size()); + addChildLMs(newLMs); + return pos < childLMs.size(); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getChildLMs + */ + public List getChildLMs() { + return childLMs; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#addChildLM + */ + public void addChildLM(LayoutManager lm) { + if (lm == null) { + return; + } + lm.setParent(this); + lm.initialize(); + childLMs.add(lm); + log.trace(this.getClass().getName() + + ": Adding child LM " + lm.getClass().getName()); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#addChildLMs + */ + public void addChildLMs(List newLMs) { + if (newLMs == null || newLMs.size() == 0) { + return; + } + ListIterator iter = newLMs.listIterator(); + while (iter.hasNext()) { + LayoutManager lm = (LayoutManager) iter.next(); + addChildLM(lm); + } + } + } diff --git a/src/java/org/apache/fop/layoutmgr/BasicLinkLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BasicLinkLayoutManager.java index 154332e78..9498f9453 100644 --- a/src/java/org/apache/fop/layoutmgr/BasicLinkLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BasicLinkLayoutManager.java @@ -39,7 +39,6 @@ public class BasicLinkLayoutManager extends InlineStackingLayoutManager { */ public BasicLinkLayoutManager(BasicLink node) { super(node); - setLMiter(new LMiter(this, node.getChildNodes())); link = node.getLink(); isExternalLink = node.isExternalLink(); } diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index fb6534577..8840fccca 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -43,6 +43,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { private Block curBlockArea; + protected ListIterator proxyLMiter; + private LayoutProps layoutProps; private CommonBorderAndPadding borderProps; private CommonBackground backgroundProps; @@ -71,7 +73,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { public BlockLayoutManager(org.apache.fop.fo.flow.Block inBlock) { super.setFObj(inBlock); - childLMiter = new BlockLMiter(this, childLMiter); + proxyLMiter = new ProxyLMiter(); userAgent = inBlock.getUserAgent(); setBlockTextInfo(inBlock.getPropertyManager().getTextLayoutProps( inBlock.getFOInputHandler().getFontInfo())); @@ -99,59 +101,75 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { } /** - * Iterator for Block layout. - * This iterator combines consecutive inline areas and - * creates a line layout manager. - * The use of this iterator means that it can be reset properly. + * Proxy iterator for Block LM. + * This iterator creates and holds the complete list + * of child LMs. + * It uses fobjIter as its base iterator. + * Block LM's preLoadNext uses this iterator + * as its base iterator. */ - protected class BlockLMiter extends LMiter { + protected class ProxyLMiter extends LMiter { - private ListIterator proxy; + public ProxyLMiter() { + super(BlockLayoutManager.this); + listLMs = new ArrayList(10); + } - public BlockLMiter(LayoutManager lp, ListIterator pr) { - super(lp, null); - proxy = pr; + public boolean hasNext() { + return (curPos < listLMs.size()) ? true : preLoadNext(curPos); } - protected boolean preLoadNext() { - while (proxy.hasNext()) { - LayoutManager lm = (LayoutManager) proxy.next(); - lm.setParent(BlockLayoutManager.this); - if (lm.generatesInlineAreas()) { - LineLayoutManager lineLM = createLineManager(lm); - listLMs.add(lineLM); - } else { - listLMs.add(lm); - } - if (curPos < listLMs.size()) { - return true; - } + protected boolean preLoadNext(int pos) { + List newLMs = preLoadList(pos + 1 - listLMs.size()); + if (newLMs != null) { + listLMs.addAll(newLMs); } - return false; + return pos < listLMs.size(); } + } - protected LineLayoutManager createLineManager( - LayoutManager firstlm) { - LayoutManager lm; - List inlines = new ArrayList(); - inlines.add(firstlm); - while (proxy.hasNext()) { - lm = (LayoutManager) proxy.next(); - lm.setParent(BlockLayoutManager.this); - if (lm.generatesInlineAreas()) { - inlines.add(lm); - } else { - proxy.previous(); - break; - } + /** + * @see org.apache.fop.layoutmgr.LayoutManager#preLoadNext + */ + public boolean preLoadNext(int pos) { + + while (proxyLMiter.hasNext()) { + LayoutManager lm = (LayoutManager) proxyLMiter.next(); + if (lm.generatesInlineAreas()) { + LineLayoutManager lineLM = createLineManager(lm); + addChildLM(lineLM); + } else { + addChildLM(lm); + } + if (pos < childLMs.size()) { + return true; } - LineLayoutManager child; - child = new LineLayoutManager(fobj, lineHeight, - lead, follow); - child.setLMiter(inlines.listIterator()); - return child; + } + return false; + } + /** + * Create a new LineLM, and collect all consecutive + * inline generating LMs as its child LMs. + * @param firstlm First LM in new LineLM + * @return the newly created LineLM + */ + private LineLayoutManager createLineManager(LayoutManager firstlm) { + LineLayoutManager llm; + llm = new LineLayoutManager(fobj, lineHeight, lead, follow); + List inlines = new ArrayList(); + inlines.add(firstlm); + while (proxyLMiter.hasNext()) { + LayoutManager lm = (LayoutManager) proxyLMiter.next(); + if (lm.generatesInlineAreas()) { + inlines.add(lm); + } else { + proxyLMiter.previous(); + break; + } } + llm.addChildLMs(inlines); + return llm; } public BreakPoss getNextBreakPoss(LayoutContext context) { diff --git a/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java index 73e023be0..ba89110fd 100644 --- a/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java @@ -27,10 +27,14 @@ import org.apache.fop.area.Resolveable; import org.apache.fop.area.PageViewport; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.ArrayList; import org.apache.fop.traits.MinOptMax; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * Content Layout Manager. * For use with objects that contain inline areas such as @@ -41,6 +45,12 @@ public class ContentLayoutManager implements LayoutManager { private Area holder; private int stackSize; private LayoutManager parentLM; + private List childLMs = new ArrayList(1); + + /** + * logging instance + */ + protected static Log log = LogFactory.getLog(LayoutManager.class); /** * Constructs a new ContentLayoutManager @@ -241,5 +251,48 @@ public class ContentLayoutManager implements LayoutManager { public Marker retrieveMarker(String name, int pos, int boundary) { return parentLM.retrieveMarker(name, pos, boundary); } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#preLoadNext + */ + public boolean preLoadNext(int pos) { + return false; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getChildLMs + */ + public List getChildLMs() { + return childLMs; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#addChildLM + */ + public void addChildLM(LayoutManager lm) { + if (lm == null) { + return; + } + lm.setParent(this); + lm.initialize(); + childLMs.add(lm); + log.trace(this.getClass().getName() + + ": Adding child LM " + lm.getClass().getName()); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#addChildLMs + */ + public void addChildLMs(List newLMs) { + if (newLMs == null || newLMs.size() == 0) { + return; + } + ListIterator iter = newLMs.listIterator(); + while (iter.hasNext()) { + LayoutManager lm = (LayoutManager) iter.next(); + addChildLM(lm); + } + } + } diff --git a/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java index 78bf35d0a..f35961eee 100644 --- a/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java @@ -94,17 +94,6 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager { super(node); } - /** - * Set the FO object for this layout manager - * - * @param fo the fo for this layout manager - */ - public void setFObj(FObj fo) { - this.fobj = fo; - foID = fobj.getID(); - childLMiter = null; - } - /** * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties() */ diff --git a/src/java/org/apache/fop/layoutmgr/LMiter.java b/src/java/org/apache/fop/layoutmgr/LMiter.java index ee62cec1f..77db73a2d 100644 --- a/src/java/org/apache/fop/layoutmgr/LMiter.java +++ b/src/java/org/apache/fop/layoutmgr/LMiter.java @@ -29,38 +29,18 @@ import java.util.NoSuchElementException; public class LMiter implements ListIterator { - private ListIterator baseIter; - private FObj curFO; protected List listLMs; protected int curPos = 0; /** The LayoutManager to which this LMiter is attached **/ private LayoutManager lp; - public LMiter(LayoutManager lp, ListIterator bIter) { + public LMiter(LayoutManager lp) { this.lp = lp; - baseIter = bIter; - listLMs = new ArrayList(10); + listLMs = lp.getChildLMs(); } public boolean hasNext() { - return (curPos < listLMs.size()) ? true : preLoadNext(); - } - - protected boolean preLoadNext() { - AreaTreeHandler areaTreeHandler = lp.getAreaTreeHandler(); - // skip over child FObj's that don't add lms - while (baseIter != null && baseIter.hasNext()) { - Object theobj = baseIter.next(); - if (theobj instanceof FObj) { - FObj fobj = (FObj) theobj; - //listLMs.add(fobj.getLayoutManager()); - areaTreeHandler.addLayoutManager(fobj, listLMs); - if (curPos < listLMs.size()) { - return true; - } - } - } - return false; + return (curPos < listLMs.size()) ? true : lp.preLoadNext(curPos); } public boolean hasPrevious() { diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java index 1ab43ed28..97a79a67b 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -18,6 +18,7 @@ package org.apache.fop.layoutmgr; +import java.util.List; import java.util.Map; import org.apache.fop.fo.flow.Marker; @@ -218,4 +219,30 @@ public interface LayoutManager { */ Marker retrieveMarker(String name, int pos, int boundary); + /** + * Load next child LMs, up to child LM index pos + * @param pos index up to which child LMs are requested + * @return if requested index does exist + */ + boolean preLoadNext(int pos); + + /** + * @return the list of child LMs + */ + List getChildLMs(); + + /** + * Add the LM in the argument to the list of child LMs; + * set this LM as the parent; + * initialize the LM. + * @param lm the LM to be added + */ + void addChildLM(LayoutManager lm); + + /** + * Add the LMs in the argument to the list of child LMs; + * @param newLMs the list of LMs to be added + */ + void addChildLMs(List newLMs); + } diff --git a/src/java/org/apache/fop/layoutmgr/LeaderLayoutManager.java b/src/java/org/apache/fop/layoutmgr/LeaderLayoutManager.java index e1b94425a..94c7f638b 100644 --- a/src/java/org/apache/fop/layoutmgr/LeaderLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LeaderLayoutManager.java @@ -108,18 +108,20 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { ldrNode.getLogger().error("Leader use-content with no content"); return null; } - InlineStackingLayoutManager lm; - lm = new InlineStackingLayoutManager(ldrNode); - lm.setLMiter(new LMiter(lm, ldrNode.getChildNodes())); - lm.initialize(); + // child FOs are assigned to the InlineStackingLM + fobjIter = null; + // get breaks then add areas to FilledArea FilledArea fa = new FilledArea(); - + ContentLayoutManager clm = new ContentLayoutManager(fa); - clm.setParent(this); clm.setUserAgent(ldrNode.getUserAgent()); - lm.setParent(clm); + addChildLM(clm); + + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager(ldrNode); + clm.addChildLM(lm); clm.fillArea(lm); int width = clm.getStackingSize(); diff --git a/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java index b9dd60ba4..70e923b15 100644 --- a/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java @@ -115,6 +115,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager { */ public LineLayoutManager(FObj node, int lh, int l, int f) { super(node); + // the child FObj are owned by the parent BlockLM + // this LM has all its childLMs preloaded + fobjIter = null; lineHeight = lh; lead = l; follow = f;