klease 02/05/10 05:38:16 Modified: src/org/apache/fop/render AbstractRenderer.java Renderer.java src/org/apache/fop/render/xml XMLRenderer.java src/org/apache/fop/layoutmgr AbstractBPLayoutManager.java BPLayoutManager.java BlockLayoutManager.java BreakPoss.java BreakPossPosIter.java LineBPLayoutManager.java LineLayoutManager.java SpaceSpecifier.java TextBPLayoutManager.java Added: src/org/apache/fop/layoutmgr InlineStackingBPLayoutManager.java LMiter.java Log: Add support for line-breaking in nested inlines using BreakPoss strategy Revision Changes Path 1.15 +10 -3 xml-fop/src/org/apache/fop/render/AbstractRenderer.java Index: AbstractRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/AbstractRenderer.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- AbstractRenderer.java 11 Apr 2002 09:33:31 -0000 1.14 +++ AbstractRenderer.java 10 May 2002 12:38:15 -0000 1.15 @@ -1,5 +1,5 @@ /* - * $Id: AbstractRenderer.java,v 1.14 2002/04/11 09:33:31 keiron Exp $ + * $Id: AbstractRenderer.java,v 1.15 2002/05/10 12:38:15 klease Exp $ * 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. @@ -10,10 +10,8 @@ // FOP import org.apache.fop.apps.FOPException; import org.apache.fop.area.*; -import org.apache.fop.area.Span; import org.apache.fop.area.inline.*; import org.apache.fop.area.inline.Character; -import org.apache.fop.area.inline.Space; import org.apache.fop.fo.FOUserAgent; // Avalon @@ -25,6 +23,7 @@ import java.io.OutputStream; import java.util.HashMap; import java.util.List; +import java.util.Iterator; /** * Abstract base class for all renderers. @@ -306,6 +305,14 @@ public void renderWord(Word word) { currentBlockIPPosition += word.getWidth(); + } + + public void renderInlineParent(InlineParent ip) { + // currentBlockIPPosition += ip.getWidth(); + Iterator iter = ip.getChildAreas().iterator(); + while (iter.hasNext()) { + ((InlineArea)iter.next()).render(this); + } } protected void renderBlocks(List blocks) { 1.25 +3 -1 xml-fop/src/org/apache/fop/render/Renderer.java Index: Renderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/Renderer.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- Renderer.java 11 Apr 2002 09:33:31 -0000 1.24 +++ Renderer.java 10 May 2002 12:38:15 -0000 1.25 @@ -1,5 +1,5 @@ /* - * $Id: Renderer.java,v 1.24 2002/04/11 09:33:31 keiron Exp $ + * $Id: Renderer.java,v 1.25 2002/05/10 12:38:15 klease Exp $ * 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. @@ -74,6 +74,8 @@ public void renderContainer(Container cont); public void renderWord(Word area); + + public void renderInlineParent(InlineParent ip); public void renderCharacter( org.apache.fop.area.inline.Character ch); 1.37 +12 -1 xml-fop/src/org/apache/fop/render/xml/XMLRenderer.java Index: XMLRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/xml/XMLRenderer.java,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- XMLRenderer.java 11 Apr 2002 09:33:31 -0000 1.36 +++ XMLRenderer.java 10 May 2002 12:38:15 -0000 1.37 @@ -1,5 +1,5 @@ /* - * $Id: XMLRenderer.java,v 1.36 2002/04/11 09:33:31 keiron Exp $ + * $Id: XMLRenderer.java,v 1.37 2002/05/10 12:38:15 klease Exp $ * 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. @@ -346,6 +346,17 @@ } writeElement("<word" + prop + ">" + word.getWord() + "</word>"); super.renderWord(word); + } + + public void renderInlineParent(InlineParent ip) { + String prop = ""; + List list = ip.getTraitList(); + if (list != null) { + prop = " props=\"" + getPropString(list) + "\""; + } + writeStartTag("<inlineparent" + prop + ">"); + super.renderInlineParent(ip); + writeEndTag("</inlineparent>"); } public void renderLeader(Leader area) { 1.2 +72 -3 xml-fop/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java Index: AbstractBPLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AbstractBPLayoutManager.java 28 Apr 2002 21:31:00 -0000 1.1 +++ AbstractBPLayoutManager.java 10 May 2002 12:38:15 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: AbstractBPLayoutManager.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: AbstractBPLayoutManager.java,v 1.2 2002/05/10 12:38:15 klease Exp $ * 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. @@ -24,10 +24,78 @@ /** True if this LayoutManager has handled all of its content. */ private boolean m_bFinished = false; + private BPLayoutManager m_curChildLM=null; + private ListIterator m_childLMiter; + private boolean m_bInited=false; public AbstractBPLayoutManager(FObj fobj) { + this(fobj, new LMiter(fobj.getChildren())); + } + + + public AbstractBPLayoutManager(FObj fobj, ListIterator lmIter) { super(fobj); + m_childLMiter = lmIter; + } + + + /** + * Return currently active child LayoutManager or null if + * all children have finished layout. + * Note: child must implement BPLayoutManager! If it doesn't, skip it + * and print a warning. + */ + protected BPLayoutManager getChildLM() { + if (m_curChildLM != null && !m_curChildLM.isFinished()) { + return m_curChildLM; + } + while (m_childLMiter.hasNext()) { + Object obj = m_childLMiter.next(); + if (obj instanceof BPLayoutManager) { + m_curChildLM = (BPLayoutManager)obj; + m_curChildLM.setParentLM(this); + m_curChildLM.init(); + return m_curChildLM; + } + else { + m_childLMiter.remove(); + System.err.println("WARNING: child LM not a BPLayoutManager: " + + obj.getClass().getName()); + } + } + return null; + } + + + /** + * Reset the layoutmanager "iterator" so that it will start + * with the passed bplm on the next call to getChildLM. + * @param bplm Reset iterator to this LayoutManager. + */ + protected void reset(LayoutManager lm, BreakPoss.Position pos) { + //if (lm == null) return; + if (m_curChildLM != lm) { + // ASSERT m_curChildLM == (BPLayoutManager)m_childLMiter.previous() + if (m_curChildLM != (BPLayoutManager)m_childLMiter.previous()) { + System.err.println("LMiter problem!"); + } + while (m_curChildLM != lm && m_childLMiter.hasPrevious()) { + m_curChildLM.resetPosition(null); + m_curChildLM = (BPLayoutManager)m_childLMiter.previous(); + } + m_childLMiter.next(); // Otherwise next returns same object + } + m_curChildLM.resetPosition(pos); + if (isFinished()) { + setFinished(false); + } + } + + public void resetPosition(BreakPoss.Position resetPos) { + if (resetPos == null) { + reset(null, null); + } } @@ -35,9 +103,10 @@ * This method provides a hook for a LayoutManager to intialize traits * for the areas it will create, based on Properties set on its FO. */ - protected final void initProperties() { - if (fobj != null) { + public void init() { + if (fobj != null && m_bInited == false) { initProperties(fobj.getPropertyManager()); + m_bInited=true; } } 1.2 +5 -1 xml-fop/src/org/apache/fop/layoutmgr/BPLayoutManager.java Index: BPLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/BPLayoutManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- BPLayoutManager.java 28 Apr 2002 21:31:00 -0000 1.1 +++ BPLayoutManager.java 10 May 2002 12:38:15 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: BPLayoutManager.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: BPLayoutManager.java,v 1.2 2002/05/10 12:38:15 klease Exp $ * 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. @@ -63,5 +63,9 @@ * Iterator. */ public void addAreas(PositionIterator posIter) ; + + public void init() ; + + public void resetPosition(BreakPoss.Position position); } 1.8 +3 -3 xml-fop/src/org/apache/fop/layoutmgr/BlockLayoutManager.java Index: BlockLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/BlockLayoutManager.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- BlockLayoutManager.java 28 Apr 2002 21:28:01 -0000 1.7 +++ BlockLayoutManager.java 10 May 2002 12:38:15 -0000 1.8 @@ -1,5 +1,5 @@ /* - * $Id: BlockLayoutManager.java,v 1.7 2002/04/28 21:28:01 klease Exp $ + * $Id: BlockLayoutManager.java,v 1.8 2002/05/10 12:38:15 klease Exp $ * 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. @@ -83,13 +83,13 @@ break; } } + /* lm = new LineLayoutManager(curFobj, inlines, lineHeight, lead, follow); + */ // !!!! To test BreakPoss Line LayoutManager, uncomment! - /* lm = new LineBPLayoutManager(curFobj, inlines, lineHeight, lead, follow); - */ lms.set(count, lm); } lm.setParentLM(this); 1.2 +6 -2 xml-fop/src/org/apache/fop/layoutmgr/BreakPoss.java Index: BreakPoss.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/BreakPoss.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- BreakPoss.java 28 Apr 2002 21:31:00 -0000 1.1 +++ BreakPoss.java 10 May 2002 12:38:15 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: BreakPoss.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: BreakPoss.java,v 1.2 2002/05/10 12:38:15 klease Exp $ * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -84,7 +84,7 @@ this(lm,position,0); } - public BreakPoss(BPLayoutManager lm, Position position, int flags) { + public BreakPoss(BPLayoutManager lm, Position position, long flags) { m_lm = lm; m_position = position; m_flags = flags; @@ -126,6 +126,10 @@ public MinOptMax getNonStackingSize() { return this.m_nonStackSize ; + } + + public long getFlags() { + return m_flags; } public void setFlag(int flagBit) { 1.2 +8 -2 xml-fop/src/org/apache/fop/layoutmgr/BreakPossPosIter.java Index: BreakPossPosIter.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/BreakPossPosIter.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- BreakPossPosIter.java 28 Apr 2002 21:31:00 -0000 1.1 +++ BreakPossPosIter.java 10 May 2002 12:38:15 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: BreakPossPosIter.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: BreakPossPosIter.java,v 1.2 2002/05/10 12:38:15 klease Exp $ * 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. @@ -21,7 +21,13 @@ // Check position < endPos protected boolean checkNext() { - return (m_iterCount > 0 && super.checkNext()); + if (m_iterCount > 0) { + return super.checkNext(); + } + else { + endIter(); + return false; + } } public Object next() { 1.2 +24 -85 xml-fop/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java Index: LineBPLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- LineBPLayoutManager.java 28 Apr 2002 21:31:00 -0000 1.1 +++ LineBPLayoutManager.java 10 May 2002 12:38:15 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: LineBPLayoutManager.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: LineBPLayoutManager.java,v 1.2 2002/05/10 12:38:15 klease Exp $ * 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. @@ -33,7 +33,8 @@ * BPLayoutManager for lines. It builds one or more lines containing * inline areas generated by its sub layout managers. */ -public class LineBPLayoutManager extends LineLayoutManager { +public class LineBPLayoutManager extends + InlineStackingBPLayoutManager { /** * Private class to store information about inline breaks. @@ -48,8 +49,6 @@ } } - private BPLayoutManager m_curChildLM=null; - private ListIterator m_childLMiter; private LineArea m_lineArea; // LineArea currently being filled @@ -64,13 +63,13 @@ public LineBPLayoutManager(FObj fobj, List lms, int lh, int l, int f) { - super(fobj, lms, lh, l, f); - m_childLMiter = lms.listIterator(); - initProperties(); + //super(fobj, lms, lh, l, f); + super(fobj, lms.listIterator()); + // initProperties(); } protected void initProperties(PropertyManager propMgr) { - super.initProperties(propMgr); + // super.initProperties(propMgr); System.err.println("LineBPLayoutManager.initProperties called"); MarginProps marginProps = propMgr.getMarginProps(); m_iIndents = marginProps.startIndent + marginProps.endIndent; @@ -80,47 +79,6 @@ } - /** - * Return next child LayoutManager or null if there is none. - * Note: child must implement BPLayoutManager! If it doesn't, skip it - * and print a warning. - * The list of all child layout managers is in lmList (in superclass!) - */ - private BPLayoutManager getChildLM() { - if (m_curChildLM != null && !m_curChildLM.isFinished()) { - return m_curChildLM; - } - while (m_childLMiter.hasNext()) { - Object obj = m_childLMiter.next(); - if (obj instanceof BPLayoutManager) { - m_curChildLM = (BPLayoutManager)obj; - m_curChildLM.setParentLM(this); - return m_curChildLM; - } - else { - m_childLMiter.remove(); - System.err.println("WARNING: child of LineLPLayoutManager not a BPLayoutManager: " + obj.getClass().getName()); - } - } - return null; - } - - /** - * Reset the layoutmanager "iterator" so that it will start - * with the passed bplm on the next call to getChildLM. - * @param bplm Reset iterator to this LayoutManager. - */ - private void resetChildLM(BPLayoutManager bplm) { - if (bplm == null) return; - while (m_curChildLM != bplm && m_childLMiter.hasPrevious()) { - m_curChildLM = (BPLayoutManager)m_childLMiter.previous(); - } - if ( m_curChildLM.isFinished()) { - m_curChildLM.setFinished(false); - } - } - - /** * Call child layout managers to generate content as long as they @@ -183,10 +141,7 @@ inlineLC.unsetFlags(LayoutContext.SUPPRESS_LEADING_SPACE); } // GET NEXT POSSIBLE BREAK FROM CHILD LM - if ((bp = curLM.getNextBreakPoss(inlineLC, - (m_prevBP !=null ? - m_prevBP.getPosition() : - null))) != null) { + if ((bp = curLM.getNextBreakPoss(inlineLC, null)) != null) { // check if this bp fits in line MinOptMax bpDim = (MinOptMax)bp.getStackingSize().clone(); /* If first BP for this LM (in this call) @@ -232,8 +187,12 @@ * This includes any previosly pending size, * already calculated above. */ - pendingIPD = bpDim; - // Add BP to the pending list + if (bp.isLastArea()) { + pendingIPD = bpDim; + } + // Add BP to the list even though we can't break here + // We need to keep it for area generation + m_vecInlineBreaks.add(bp); } } else if (bpDim.min > availIPD.max) { @@ -290,36 +249,17 @@ // No more content to layout! setFinished(true); } - // Backup layoutmanager if necessary - resetChildLM(m_prevBP.getLayoutManager()); + // Backup child LM if necessary + if (bp != m_prevBP) { + // Remove any pending breaks from the vector + while (m_vecInlineBreaks.lastElement()!=m_prevBP) { + m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1); + } + reset(m_prevBP.getLayoutManager(), m_prevBP.getPosition()); + } return makeLineBreak(m_prevBP); } - /** - * Return whether we could end the line at the proposed Position. - * TODO: take keeps into account and distinguish the cost of a - * the break-completely forbidden or some non-0 cost. - * QUESTION: do we need to pass the current LineLM or childLM - * LayoutContext? - */ - private boolean couldEndLine(BreakPoss bp) { - if (bp.canBreakAfter()) { - return true; // no keep, ends on break char - } - else if (bp.isSuppressible()) { - // NOTE: except at end of content for this LM!! - // Never break after only space chars or any other sequence - // of areas which would be suppressed at the end of the line. - return false; - } - else { - // See if could break before next area - LayoutContext lc=new LayoutContext(); - BPLayoutManager nextLM = getChildLM(); - return (nextLM == null || - nextLM.canBreakBefore(lc)); - } - } private BreakPoss findHyphenPoss(BreakPoss prevBP, BreakPoss newBP) { @@ -356,11 +296,10 @@ new BreakPossPosIter(m_vecInlineBreaks, iStartPos, lbp.m_iPos+1); iStartPos = lbp.m_iPos+1; - while (inlinePosIter.hasNext() && - (childLM = inlinePosIter.getNextChildLM())!= null) { + while ((childLM = inlinePosIter.getNextChildLM())!= null) { childLM.addAreas(inlinePosIter); } - verticalAlign(m_lineArea); + // verticalAlign(m_lineArea); parentLM.addChild(m_lineArea); } m_lineArea = null; 1.8 +2 -2 xml-fop/src/org/apache/fop/layoutmgr/LineLayoutManager.java Index: LineLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/LineLayoutManager.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- LineLayoutManager.java 28 Apr 2002 21:28:01 -0000 1.7 +++ LineLayoutManager.java 10 May 2002 12:38:15 -0000 1.8 @@ -1,5 +1,5 @@ /* - * $Id: LineLayoutManager.java,v 1.7 2002/04/28 21:28:01 klease Exp $ + * $Id: LineLayoutManager.java,v 1.8 2002/05/10 12:38:15 klease Exp $ * 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. @@ -44,7 +44,7 @@ * * How do we handle Unicode BIDI? */ -public class LineLayoutManager extends AbstractBPLayoutManager { +public class LineLayoutManager extends AbstractLayoutManager { private LineInfo currentLine = null; private boolean bFirstLine = true; private MinOptMax totalIPD; 1.4 +15 -2 xml-fop/src/org/apache/fop/layoutmgr/SpaceSpecifier.java Index: SpaceSpecifier.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/SpaceSpecifier.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SpaceSpecifier.java 28 Apr 2002 21:28:01 -0000 1.3 +++ SpaceSpecifier.java 10 May 2002 12:38:16 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: SpaceSpecifier.java,v 1.3 2002/04/28 21:28:01 klease Exp $ + * $Id: SpaceSpecifier.java,v 1.4 2002/05/10 12:38:16 klease Exp $ * 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. @@ -16,7 +16,7 @@ * areas with a stacking constraint. Provide a way to resolve these into * a single MinOptMax value. */ -public class SpaceSpecifier { +public class SpaceSpecifier implements Cloneable { private boolean m_bStartsRefArea; @@ -26,6 +26,19 @@ public SpaceSpecifier(boolean bStartsRefArea) { m_bStartsRefArea = bStartsRefArea; + } + + public Object clone() { + try { + SpaceSpecifier ss = (SpaceSpecifier)super.clone(); + // Clone the vector, but share the objects in it! + ss.m_vecSpaceVals = new Vector(this.m_vecSpaceVals.size()); + ss.m_vecSpaceVals.addAll(this.m_vecSpaceVals); + return ss; + } catch (CloneNotSupportedException cnse) { + return null; + } + } /** 1.2 +30 -12 xml-fop/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java Index: TextBPLayoutManager.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TextBPLayoutManager.java 28 Apr 2002 21:31:00 -0000 1.1 +++ TextBPLayoutManager.java 10 May 2002 12:38:16 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: TextBPLayoutManager.java,v 1.1 2002/04/28 21:31:00 klease Exp $ + * $Id: TextBPLayoutManager.java,v 1.2 2002/05/10 12:38:16 klease Exp $ * 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. @@ -195,6 +195,30 @@ (CharUtilities.isSpace(c) || s_breakChars.indexOf(c)>=0))); } + /** Reset position for returning next BreakPossibility. */ + + public void resetPosition(BreakPoss.Position prevPos) { + if (prevPos != null) { + TextBreakPosition tbp = (TextBreakPosition)prevPos; + AreaInfo ai = + (AreaInfo) m_vecAreaInfo.elementAt(tbp.m_iAreaIndex); + if (ai.m_iBreakIndex != m_iNextStart) { + m_iNextStart = ai.m_iBreakIndex; + m_vecAreaInfo.setSize(tbp.m_iAreaIndex+1); + System.err.println("Discarded previous text break pos"); + setFinished(false); + } + } + else { + // Reset to beginning! + System.err.println("TextBPLM: resetPosition(null)"); + m_vecAreaInfo.setSize(0); + m_iNextStart = 0; + setFinished(false); + } + } + + /** * Return the next break possibility that fits the constraints. * @param context An object specifying the flags and input information @@ -229,17 +253,6 @@ iFlags |= BreakPoss.ISFIRST; } - if (prevPos != null) { - TextBreakPosition tbp = (TextBreakPosition)prevPos; - AreaInfo ai = - (AreaInfo) m_vecAreaInfo.elementAt(tbp.m_iAreaIndex); - if (ai.m_iBreakIndex != m_iNextStart) { - m_iNextStart = ai.m_iBreakIndex; - m_vecAreaInfo.setSize(tbp.m_iAreaIndex+1); - System.err.println("Discarded previous text break pos"); - } - } - // HANDLE SUPPRESSED LEADING SPACES if ((context.flags & LayoutContext.SUPPRESS_LEADING_SPACE)!=0) { @@ -249,6 +262,7 @@ chars[m_iNextStart]==SPACE; m_iNextStart++); // If now at end, nothing to compose here! if (m_iNextStart >= chars.length) { + setFinished(true); return null; // Or an "empty" BreakPoss? } } @@ -364,6 +378,10 @@ if (trailingSpace != null) { bp.setTrailingSpace(trailingSpace); } + else { + bp.setTrailingSpace(new SpaceSpecifier(false)); + } + bp.setLeadingSpace(new SpaceSpecifier(false)); return bp; } 1.1 xml-fop/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java Index: InlineStackingBPLayoutManager.java =================================================================== /* * $Id: InlineStackingBPLayoutManager.java,v 1.1 2002/05/10 12:38:15 klease Exp $ * 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.fo.FObj; import org.apache.fop.fo.PropertyManager; import org.apache.fop.layout.BorderAndPadding; import org.apache.fop.traits.InlineProps; import org.apache.fop.area.Area; import org.apache.fop.area.MinOptMax; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.InlineParent; import java.util.Iterator; import java.util.ListIterator; /** * LayoutManager for objects which stack children in the inline direction, * such as Inline or Line */ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { /** * Private class to store information about a lower-level BreakPosition. * Note: fields are directly readable in this class */ private static class WrappedPosition implements BreakPoss.Position { BPLayoutManager m_childLM; BreakPoss.Position m_childPosition; WrappedPosition(BPLayoutManager childLM, BreakPoss.Position childPosition) { m_childLM = childLM; m_childPosition = childPosition; } } private static class StackingIter extends PositionIterator { StackingIter(Iterator parentIter) { super(parentIter); } protected BPLayoutManager getLM(Object nextObj) { return ((WrappedPosition)nextObj).m_childLM; } protected BreakPoss.Position getPos(Object nextObj) { return ((WrappedPosition)nextObj).m_childPosition; } } /** * Holds IPD of all areas which would be generated by previously * complete childLM since last area was generated. */ private MinOptMax m_prevContentIPD = new MinOptMax(0); /** * Size of any start or end borders and padding. */ private MinOptMax m_allocIPD = new MinOptMax(0); /** * Size of border and padding in BPD (ie, before and after). */ private MinOptMax m_extraBPD; /** Holds IPD of a child BP which had no break-after flag. We don't * add this to m_previousIPD until we are sure that the next break * position can really fit. */ private MinOptMax m_pendingIPD = new MinOptMax(0); private InlineProps m_inlineProps = null; private BorderAndPadding m_borderProps = null; private InlineParent m_inlineArea; private boolean m_bFirstArea; private BreakPoss m_prevBP; public InlineStackingBPLayoutManager(FObj fobj, ListIterator childLMiter) { super(fobj, childLMiter); m_bFirstArea = true; // Initialize inline properties (borders, padding, space) // initProperties(); } public boolean generatesInlineAreas() { return true; } protected void initProperties(PropertyManager propMgr) { // super.initProperties(propMgr); System.err.println("InlineStackingBPLayoutManager.initProperties called"); m_inlineProps = propMgr.getInlineProps(); m_borderProps = propMgr.getBorderAndPadding(); // Calculdate border and padding size in BPD int iPad = m_borderProps.getPadding(BorderAndPadding.BEFORE, false); iPad += m_borderProps.getBorderWidth(BorderAndPadding.BEFORE, false); iPad += m_borderProps.getPadding(BorderAndPadding.AFTER, false); iPad += m_borderProps.getBorderWidth(BorderAndPadding.AFTER, false); m_extraBPD = new MinOptMax(iPad); } private MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) { int iBP = m_borderProps.getPadding(BorderAndPadding.START, bNotFirst); iBP += m_borderProps.getBorderWidth(BorderAndPadding.START, bNotFirst); iBP += m_borderProps.getPadding(BorderAndPadding.END, bNotLast); iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast); return new MinOptMax(iBP); } private boolean hasLeadingFence(boolean bNotFirst) { int iBP = m_borderProps.getPadding(BorderAndPadding.START, bNotFirst); iBP += m_borderProps.getBorderWidth(BorderAndPadding.START, bNotFirst); return (iBP > 0); } private boolean hasTrailingFence(boolean bNotLast) { int iBP = m_borderProps.getPadding(BorderAndPadding.END, bNotLast); iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast); return (iBP > 0); } /** Reset position for returning next BreakPossibility. */ public void resetPosition(BreakPoss.Position prevPos) { WrappedPosition wrappedPos = (WrappedPosition)prevPos; if (wrappedPos != null) { // Back up the layout manager iterator reset(wrappedPos.m_childLM, wrappedPos.m_childPosition); } else { // Backup to first child layout manager System.err.println("InlineStackingBPLM: resetPosition(null)"); super.resetPosition(prevPos); } // Do we need to reset some context like pending or prevContent? } /** * Return value indicating whether the next area to be generated could * start a new line. This should only be called in the "START" condition * if a previous inline BP couldn't end the line. * Return true if any space-start, border-start or padding-start, else * propagate to first child LM */ public boolean canBreakBefore(LayoutContext context) { if (m_inlineProps.spaceStart.space.min > 0 || hasLeadingFence(false)) { return true; } BPLayoutManager lm = getChildLM(); if (lm != null) { return lm.canBreakBefore(context); } else return false; // ??? NO child LM? } public BreakPoss getNextBreakPoss(LayoutContext lc, BreakPoss.Position pbp) { // Get a break from currently active child LM BreakPoss bp =null; BPLayoutManager curLM ; // Handle space before boolean bIncludeStartSpace=false; LayoutContext childLC = new LayoutContext(lc); if (lc.isStart()) { // First call to this LM in new parent "area", ie, this may // not be the first area created by this inline lc.getPendingSpace().addSpace(m_inlineProps.spaceStart); // Check for "fence" if (hasLeadingFence(!m_bFirstArea)) { bIncludeStartSpace=true; // Reset leading space sequence for child areas childLC.setPendingSpace(new SpaceSpecifier(false)); } // Reset state variables m_pendingIPD = new MinOptMax(0); m_prevContentIPD = new MinOptMax(0); } else { // Handle pending IPD: if we are called again, we assume previous // break was OK m_prevContentIPD.add(m_pendingIPD); m_pendingIPD = new MinOptMax(0); } // if (m_prevChildLM != curLM && m_prevChildLM != null) { // // Change child LM // m_prevContentIPD.add(m_pendingIPD); // } while ((curLM = getChildLM()) != null) { // ???? /* If first break for this child, set START_AREA flag */ if (m_prevBP == null || m_prevBP.getLayoutManager()!=curLM) { childLC.setFlags(LayoutContext.START_AREA); if (m_prevBP != null) { childLC.setPendingSpace(m_prevBP.getTrailingSpace()); } } if (((bp = curLM.getNextBreakPoss(childLC)) != null)) { // && couldEndLine(bp)) { break; } // if (bp.isLastArea()) { // // NORMALLY IT MUST BE! // m_pendingIPD.add(bp.getStackingSize()); // m_prevBP = bp; // } } if (bp==null) { setFinished(true); return null; // There was no childLM // Alternative is to return a BP with the isLast flag set } else { // TODO! need to know whether this BP is in the first area for FO! return makeBreakPoss(bp, lc.isStart(), (getChildLM() == null), lc); } } protected boolean couldEndLine(BreakPoss bp) { if (bp.canBreakAfter()) { return true; // no keep, ends on break char } else if (bp.isSuppressible()) { // NOTE: except at end of content for this LM!! // Never break after only space chars or any other sequence // of areas which would be suppressed at the end of the line. return false; } else { // See if could break before next area LayoutContext lc=new LayoutContext(); BPLayoutManager nextLM = getChildLM(); return (nextLM == null || nextLM.canBreakBefore(lc)); } } protected BreakPoss makeBreakPoss(BreakPoss bp, boolean bIsFirst, boolean bIsLast, LayoutContext lc) { WrappedPosition inlbp = new WrappedPosition(bp.getLayoutManager(), bp.getPosition()); BreakPoss myBP = new BreakPoss(this, inlbp, bp.getFlags()); // Update dimension information for our allocation area, // including child areas // generated by previous childLM which have completed layout // Update pending area measure // This includes all previous breakinfo MinOptMax bpDim = (MinOptMax)bp.getStackingSize().clone(); if (m_prevBP == null || m_prevBP.getLayoutManager() != bp.getLayoutManager()) { /* This is first bp generated by child (in this parent area). * Calculate space-start on this area in combination with any * pending space-end on previously generated break possibilities. * Can also have leading space if this FO has fence-preceding. */ bpDim.add(bp.resolveLeadingSpace()); } if (bp.isLastArea()) { m_pendingIPD.add(bpDim); // See if our area is also done } // Start and end borders and padding bpDim.add(m_prevContentIPD); bpDim.add(getExtraIPD(!bIsFirst, !bIsLast)); myBP.setStackingSize(bpDim); myBP.setNonStackingSize(MinOptMax.add(bp.getNonStackingSize(), m_extraBPD)); if (bIsLast) { setFinished(true); // Our last area, so indicate done myBP.setFlag(BreakPoss.ISLAST, true); } else { myBP.setFlag(BreakPoss.ISLAST, false); } myBP.setTrailingSpace((SpaceSpecifier)bp.getTrailingSpace().clone()); myBP.getTrailingSpace().addSpace(m_inlineProps.spaceEnd); // If this FO doesn't have fence-start, then this value should // come from the lower level BP! myBP.setLeadingSpace(new SpaceSpecifier(false)); m_prevBP = bp; return myBP; } /****** protected BreakableText getText(BreakPoss prevBP, BreakPoss lastBP) { } *****/ // Generate and add areas to parent area // Set size etc public void addAreas(PositionIterator parentIter) { // Make areas from start to end // Update childLM based on bpEnd // It might be a previous sibling of the current one! m_inlineArea = new InlineParent(); // Note: if first, bpStart is perhaps null???? // If we are first in parent, set ISFIRST... // posIter iterates over positions returned by this LM StackingIter childPosIter = new StackingIter(parentIter); BPLayoutManager childLM ; while ((childLM = childPosIter.getNextChildLM())!= null) { childLM.addAreas(childPosIter); } parentLM.addChild(m_inlineArea); } // protected Area createArea() { // return new InlineParent(); // } public boolean addChild(Area childArea) { // Make sure childArea is inline area if (childArea instanceof InlineArea) { m_inlineArea.addChild((InlineArea)childArea); } return false; } } 1.1 xml-fop/src/org/apache/fop/layoutmgr/LMiter.java Index: LMiter.java =================================================================== /* * $Id: LMiter.java,v 1.1 2002/05/10 12:38:15 klease Exp $ * 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.fo.FObj; import java.util.ArrayList; import java.util.ListIterator; import java.util.NoSuchElementException; public class LMiter implements ListIterator { private ListIterator m_baseIter; private FObj m_curFO; private ArrayList m_listLMs; private int m_curPos=0; public LMiter(ListIterator baseIter) { m_baseIter = baseIter; m_listLMs = new ArrayList(10); } public boolean hasNext() { return (m_curPos < m_listLMs.size())? true : preLoadNext(); } private boolean preLoadNext() { if (m_baseIter.hasNext()) { FObj fobj = (FObj)m_baseIter.next(); //m_listLMs.add(fobj.getLayoutManager()); fobj.addLayoutManager(m_listLMs); return true; } else return false; } public boolean hasPrevious() { return (m_curPos > 0); } public Object previous() throws NoSuchElementException { if (m_curPos > 0) { return m_listLMs.get(--m_curPos); } else throw new NoSuchElementException(); } public Object next() throws NoSuchElementException { if (m_curPos < m_listLMs.size()) { return m_listLMs.get(m_curPos++); } else throw new NoSuchElementException(); } public void remove() throws NoSuchElementException { if (m_curPos > 0) { m_listLMs.remove(--m_curPos); // Note: doesn't actually remove it from the base! } else throw new NoSuchElementException(); } public void add(Object o) throws UnsupportedOperationException { throw new UnsupportedOperationException("LMiter doesn't support add"); } public void set(Object o) throws UnsupportedOperationException { throw new UnsupportedOperationException("LMiter doesn't support set"); } public int nextIndex() { return m_curPos; } public int previousIndex() { return m_curPos - 1; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]