* @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);
if (getChildNodes() != null) {
InlineStackingLayoutManager lm;
lm = new InlineStackingLayoutManager(this);
- lm.setLMiter(new LMiter(lm, getChildNodes()));
list.add(lm);
}
}
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;
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.
this.fobj = fo;
foID = fobj.getID();
markers = fobj.getMarkers();
- childLMiter = new LMiter(this, fobj.getChildNodes());
+ fobjIter = fobj.getChildNodes();
+ childLMiter = new LMiter(this);
}
/**
}
while (childLMiter.hasNext()) {
curChildLM = (LayoutManager) childLMiter.next();
- curChildLM.setParent(this);
- curChildLM.initialize();
return curChildLM;
}
return null;
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);
+ }
+ }
+
}
*/
public BasicLinkLayoutManager(BasicLink node) {
super(node);
- setLMiter(new LMiter(this, node.getChildNodes()));
link = node.getLink();
isExternalLink = node.isExternalLink();
}
private Block curBlockArea;
+ protected ListIterator proxyLMiter;
+
private LayoutProps layoutProps;
private CommonBorderAndPadding borderProps;
private CommonBackground backgroundProps;
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()));
}
/**
- * 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) {
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
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
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);
+ }
+ }
+
}
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()
*/
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() {
package org.apache.fop.layoutmgr;
+import java.util.List;
import java.util.Map;
import org.apache.fop.fo.flow.Marker;
*/
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);
+
}
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();
*/
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;