[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fop-cvs
Subject:    cvs commit: xml-fop/src/org/apache/fop/layoutmgr HyphContext.java AbstractBPLayoutManager.java BPLay
From:       klease () apache ! org
Date:       2002-05-22 20:20:50
[Download RAW message or body]

klease      02/05/22 13:20:50

  Modified:    src/org/apache/fop/layoutmgr AbstractBPLayoutManager.java
                        BPLayoutManager.java BreakPoss.java
                        BreakPossPosIter.java
                        InlineStackingBPLayoutManager.java
                        LayoutContext.java LineBPLayoutManager.java
                        PositionIterator.java TextBPLayoutManager.java
  Added:       src/org/apache/fop/layoutmgr HyphContext.java
  Log:
  Add support for hyphenation and some space distribution among inline areas
  
  Revision  Changes    Path
  1.3       +7 -14     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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractBPLayoutManager.java	10 May 2002 12:38:15 -0000	1.2
  +++ AbstractBPLayoutManager.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: AbstractBPLayoutManager.java,v 1.2 2002/05/10 12:38:15 klease Exp $
  + * $Id: AbstractBPLayoutManager.java,v 1.3 2002/05/22 20:20:50 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.
  @@ -134,18 +134,6 @@
       }
   
   
  -//     /**
  -//      * Get the BreakPoss at the start of the next "area".
  -//      * @param lc The LayoutContext for this LayoutManager.
  -//      * @param bpPrevEnd The Position returned by the previous call
  -//      * to getNextBreakPoss, or null if none.
  -//      */
  -//     public BreakPoss getStartBreakPoss(LayoutContext lc,
  -// 				       BreakPoss.Position bpPrevEnd) {
  -// 	return null;
  -//     }
  -
  -
       /**
        * Generate and return the next break possibility.
        * Each layout manager must implement this.
  @@ -179,7 +167,12 @@
       }
   
   
  -    public void addAreas(PositionIterator parentIter) {
  +    public void addAreas(PositionIterator parentIter, double dSpaceAdjust) {
  +    }
  +
  +    
  +    public void getWordChars(StringBuffer sbChars,
  +			     BreakPoss.Position bp1, BreakPoss.Position bp2) {
       }
   
       /* ---------------------------------------------------------
  
  
  
  1.3       +5 -6      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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BPLayoutManager.java	10 May 2002 12:38:15 -0000	1.2
  +++ BPLayoutManager.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: BPLayoutManager.java,v 1.2 2002/05/10 12:38:15 klease Exp $
  + * $Id: BPLayoutManager.java,v 1.3 2002/05/22 20:20:50 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.
  @@ -39,10 +39,6 @@
   
       public BreakPoss getNextBreakPoss(LayoutContext context);
   
  -    /** CURRENTLY NOT USED
  -    public BreakPoss getStartBreakPoss(LayoutContext lc,
  -				       BreakPoss.Position bpPrevEnd);
  -    **/
   
       /**
        * Return a value indicating whether this LayoutManager has laid out
  @@ -62,10 +58,13 @@
        * by BreakPoss.Position objectw which will be returned by the
        * Iterator.
        */
  -    public void addAreas(PositionIterator posIter) ;
  +    public void addAreas(PositionIterator posIter, double dSpaceAdjust) ;
   
       public void init() ;
   
       public void resetPosition(BreakPoss.Position position);
  +
  +    public void getWordChars(StringBuffer sbChars,
  +			     BreakPoss.Position bp1, BreakPoss.Position bp2);
   
   }
  
  
  
  1.3       +3 -1      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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BreakPoss.java	10 May 2002 12:38:15 -0000	1.2
  +++ BreakPoss.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: BreakPoss.java,v 1.2 2002/05/10 12:38:15 klease Exp $
  + * $Id: BreakPoss.java,v 1.3 2002/05/22 20:20:50 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.
  @@ -40,6 +40,8 @@
       // Set this flag if all fo:character generated Areas would
       // suppressed at the end or beginning of a line
       public static final int ALL_ARE_SUPPRESS_AT_LB =    0x80;
  +    /** This break possibility is a hyphenation */
  +    public static final int HYPHENATED =    0x100;
   
   
       /** The top-level layout manager which generated this BreakPoss. */
  
  
  
  1.3       +5 -1      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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BreakPossPosIter.java	10 May 2002 12:38:15 -0000	1.2
  +++ BreakPossPosIter.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: BreakPossPosIter.java,v 1.2 2002/05/10 12:38:15 klease Exp $
  + * $Id: BreakPossPosIter.java,v 1.3 2002/05/22 20:20:50 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,6 +33,10 @@
       public Object next() {
   	--m_iterCount;
   	return super.next();
  +    }
  +
  +    public BreakPoss getBP() {
  +	return (BreakPoss)peekNext();
       }
   
       protected BPLayoutManager getLM(Object nextObj) {
  
  
  
  1.3       +31 -63    xml-fop/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java
  
  Index: InlineStackingBPLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- InlineStackingBPLayoutManager.java	13 May 2002 06:12:42 -0000	1.2
  +++ InlineStackingBPLayoutManager.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: InlineStackingBPLayoutManager.java,v 1.2 2002/05/13 06:12:42 klease Exp $
  + * $Id: InlineStackingBPLayoutManager.java,v 1.3 2002/05/22 20:20:50 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.
  @@ -15,6 +15,7 @@
   import org.apache.fop.area.MinOptMax;
   import org.apache.fop.area.inline.InlineArea;
   import org.apache.fop.area.inline.InlineParent;
  +import org.apache.fop.area.inline.Space;
   
   import java.util.Iterator;
   import java.util.ListIterator;
  @@ -92,7 +93,6 @@
   
       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
  @@ -140,7 +140,6 @@
   	}
   	else {
   	    // Backup to start of first child layout manager
  -	    System.err.println("InlineStackingBPLM: resetPosition(null)");
   	    m_prevBP = null;
   	    super.resetPosition(prevPos);
   	}
  @@ -172,6 +171,7 @@
   	return (MinOptMax)m_hmPrevIPD.get(lm);
       }
   
  +
       protected void clearPrevIPD() {
   	m_hmPrevIPD.clear();
       }
  @@ -210,8 +210,12 @@
   
   	    initChildLC(m_childLC, m_prevBP, lc.startsNewArea(), bFirstChildBP,
   			leadingSpace);
  +	    if (lc.tryHyphenate()) {
  +		m_childLC.setHyphContext(lc.getHyphContext());
  +	    }
   
  -	    if (((bp = curLM.getNextBreakPoss(m_childLC)) != null)) {
  +	    if (((bp = curLM.getNextBreakPoss(m_childLC)) != null) ||
  +		(lc.tryHyphenate() && !lc.getHyphContext().hasMoreHyphPoints())) {
   		break;
   	    }
   	    // If LM has no content, should it generate any area? If not,
  @@ -251,26 +255,6 @@
   
       }
   
  -//     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));
  -// 	}
  -//     }
  -
  -
   
       private BreakPoss makeBreakPoss(BreakPoss bp, LayoutContext lc,
   				   boolean bIsLast) {
  @@ -295,39 +279,9 @@
   	    myBP.setLeadingSpace(lc.getPendingSpace());
   	}
   
  -// 	if (lc.startsNewArea()) {
  -// 	    if (hasLeadingFence(!lc.isFirstArea())) {
  -// 		// Space-start before first child area placed
  -// 		prevIPD.add(bp.resolveLeadingSpace());
  -// 	    }
  -// 	    // Space-start sequence passed to ancestors
  -// 	    myBP.setLeadingSpace(lc.getPendingSpace());
  -// 	    m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
  -// 	}
  -// 	else {
  -// 	    // In case of reset to a previous position, it may already
  -// 	    // be calculated
  -// 	    prevIPD = (MinOptMax)m_hmPrevIPD.get(bp.getLayoutManager());
  -// 	    if (prevIPD == null) {
  -// 		// ASSERT(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 with previous break.
  -// 		 * Corresponds to Space between two child areas.
  -// 		 */
  -// 		prevIPD = 
  -// 		    (MinOptMax)m_hmPrevIPD.get(m_prevBP.getLayoutManager());
  -// 		prevIPD = MinOptMax.add(prevIPD,  bp.resolveLeadingSpace());
  -// 		prevIPD.add(m_prevBP.getStackingSize());
  -// 		m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
  -// 	    }
  -// 	}
  +
   	// Add size of previous child areas which are finished
   	bpDim.add(prevIPD);
  -//         if (bp.isLastArea()) {
  -// 	    m_childLC.setPendingSpace((SpaceSpecifier)bp.getTrailingSpace().
  -// 				      clone());
  -//         }
   
   	SpaceSpecifier trailingSpace = bp.getTrailingSpace();
   	if (hasTrailingFence(!bIsLast)) {
  @@ -362,8 +316,6 @@
   		// Space-start before first child area placed
   		prevIPD.add(bp.resolveLeadingSpace());
   	    }
  -	    // Space-start sequence passed to ancestors
  -	    // myBP.setLeadingSpace(lc.getPendingSpace());
   	    m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
   	}
   	else {
  @@ -377,8 +329,7 @@
   		 * pending space-end with previous break.
   		 * Corresponds to Space between two child areas.
   		 */
  -		prevIPD = 
  -		    (MinOptMax)m_hmPrevIPD.get(prevBP.getLayoutManager());
  + 		prevIPD = (MinOptMax)m_hmPrevIPD.get(prevBP.getLayoutManager());
   		prevIPD = MinOptMax.add(prevIPD,  bp.resolveLeadingSpace());
   		prevIPD.add(prevBP.getStackingSize());
   		m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
  @@ -387,15 +338,32 @@
   	return prevIPD;
       }
   
  +    public void getWordChars(StringBuffer sbChars,
  +				BreakPoss.Position bp1, BreakPoss.Position bp2) {
  +	WrappedPosition endPos = (WrappedPosition)bp2;
  +	if (bp1 != null) {
  +	    WrappedPosition prevPos = (WrappedPosition)bp1;
  +	    if (prevPos.m_childLM == endPos.m_childLM) {
  +		bp1 = prevPos.m_childPosition;
  +	    }
  +	}
  +	endPos.m_childLM.getWordChars(sbChars, bp1, endPos.m_childPosition);
  +    }
   
       /******
       protected BreakableText getText(BreakPoss prevBP, BreakPoss lastBP) {
       }
       *****/
   
  -    // Generate and add areas to parent area
  -    // Set size etc
  -    public void addAreas(PositionIterator parentIter) {
  +    /**
  +     * Generate and add areas to parent area.
  +     * Set size of each area.
  +     * @param parentIter Iterator over BreakPoss.Position information returned
  +     * by this LayoutManager.
  +     * @param dSpaceAdjust Factor controlling how much extra space to add
  +     * in order to justify the line.
  +     */
  +    public void addAreas(PositionIterator parentIter, double dSpaceAdjust) {
           // Make areas from start to end
           // Update childLM based on bpEnd
           // It might be a previous sibling of the current one!
  @@ -410,7 +378,7 @@
   	StackingIter childPosIter = new StackingIter(parentIter);
   	BPLayoutManager childLM ;
   	while  ((childLM = childPosIter.getNextChildLM())!= null) {
  -	    childLM.addAreas(childPosIter);
  + 	    childLM.addAreas(childPosIter, dSpaceAdjust);
   	}
   	
   	parentLM.addChild(m_inlineArea);
  
  
  
  1.3       +18 -1     xml-fop/src/org/apache/fop/layoutmgr/LayoutContext.java
  
  Index: LayoutContext.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/LayoutContext.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LayoutContext.java	13 May 2002 06:12:42 -0000	1.2
  +++ LayoutContext.java	22 May 2002 20:20:50 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: LayoutContext.java,v 1.2 2002/05/13 06:12:42 klease Exp $
  + * $Id: LayoutContext.java,v 1.3 2002/05/22 20:20:50 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.
  @@ -34,6 +34,7 @@
        */
       public static final int SUPPRESS_LEADING_SPACE =       0x10;
       public static final int FIRST_AREA =                   0x20;
  +    public static final int TRY_HYPHENATE =                0x40;
   
   
       public int flags;  // Contains some set of flags defined above
  @@ -56,11 +57,15 @@
       /** Current pending space-after or space-end from preceding area */
       SpaceSpecifier m_pendingSpace;
   
  +    /** Current hyphenation context. May be null. */
  +    private HyphContext m_hyphContext=null;
  +
       public LayoutContext(LayoutContext parentLC) {
           this.flags = parentLC.flags;
           this.refIPD = parentLC.refIPD;
           this.m_stackLimit = null; // Don't reference parent MinOptMax!
   	this.m_pendingSpace = parentLC.m_pendingSpace; //???
  +	this.m_hyphContext = parentLC.m_hyphContext;
           // Copy other fields as necessary. Use clone???
       }
   
  @@ -118,5 +123,17 @@
   
       public MinOptMax getStackLimit() {
   	return m_stackLimit ;
  +    }
  +
  +    public void setHyphContext(HyphContext hyphContext) {
  +	m_hyphContext = hyphContext;
  +    }
  +
  +    public HyphContext getHyphContext() {
  +	return m_hyphContext;
  +    }
  +
  +    public boolean tryHyphenate() {
  +	return ((this.flags & TRY_HYPHENATE) != 0);
       }
   }
  
  
  
  1.5       +138 -58   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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LineBPLayoutManager.java	17 May 2002 08:56:03 -0000	1.4
  +++ LineBPLayoutManager.java	22 May 2002 20:20:50 -0000	1.5
  @@ -1,5 +1,5 @@
   /*
  - * $Id: LineBPLayoutManager.java,v 1.4 2002/05/17 08:56:03 keiron Exp $
  + * $Id: LineBPLayoutManager.java,v 1.5 2002/05/22 20:20:50 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.
  @@ -12,6 +12,9 @@
   import org.apache.fop.fo.TextInfo;
   import org.apache.fop.fo.PropertyManager;
   import org.apache.fop.layout.MarginProps;
  +import org.apache.fop.layout.HyphenationProps;
  +import org.apache.fop.layout.hyphenation.Hyphenation;
  +import org.apache.fop.layout.hyphenation.Hyphenator;
   import org.apache.fop.traits.BlockProps;
   import org.apache.fop.area.Area;
   import org.apache.fop.area.LineArea;
  @@ -62,6 +65,7 @@
       private boolean m_bJustify = false; // True if fo:block text-align=JUSTIFY
       private int m_iTextIndent = 0;
       private int m_iIndents = 0;
  +    private HyphenationProps m_hyphProps;
   
       private int lineHeight;
       private int lead;
  @@ -77,13 +81,12 @@
       }
   
       protected void initProperties(PropertyManager propMgr) {
  -	// super.initProperties(propMgr);
  -	System.err.println("LineBPLayoutManager.initProperties called");
           MarginProps marginProps = propMgr.getMarginProps();
           m_iIndents = marginProps.startIndent + marginProps.endIndent;
   	BlockProps blockProps = propMgr.getBlockProps();
   	m_bJustify = (blockProps.textAlign == TextAlign.JUSTIFY);
   	m_iTextIndent = blockProps.firstIndent;
  +	m_hyphProps = propMgr.getHyphenationProps();
       }
       
   
  @@ -120,6 +123,7 @@
   	LayoutContext inlineLC = new LayoutContext(context);
   
   	clearPrevIPD();
  +	int iPrevLineEnd = m_vecInlineBreaks.size();
   
           while ((curLM = getChildLM()) != null) {
   	    // INITIALIZE LAYOUT CONTEXT FOR CALL TO CHILD LM
  @@ -129,39 +133,31 @@
   		 (((BreakPoss)m_vecInlineBreaks.lastElement()).
   		  getLayoutManager() != curLM));
   
  -	    initChildLC(inlineLC, bp, (bp==null), bFirstBPforLM,
  +	    // Need previous breakpoint! ATTENTION when backing up for hyphenation!
  +	    prevBP =  (m_vecInlineBreaks.isEmpty())? null:
  +		(BreakPoss)m_vecInlineBreaks.lastElement();	
  +	    initChildLC(inlineLC, prevBP,
  +			(m_vecInlineBreaks.size()==iPrevLineEnd), bFirstBPforLM,
   			new SpaceSpecifier(true));
   
  -// 	    if (bp == null) {
  -// 		// Start of a new line area
  -// 		inlineLC.setFlags(LayoutContext.FIRST_AREA, bFirstBPforLM );
  -// 		inlineLC.setPendingSpace(new SpaceSpecifier(true));
  -// 	    }
  -// 	    else if (bFirstBPforLM) {
  -// 		// Space-after sequence from previous "area"
  -// 		inlineLC.setFlags(LayoutContext.FIRST_AREA, true);
  -// 		inlineLC.setPendingSpace(bp.getTrailingSpace());
  -// 	    }
  -// 	    else {
  -// 		inlineLC.setPendingSpace(null);
  -// 	    }
  -
   
               /* If first BP in this line but line is not first in this
                * LM and previous line end decision was not forced (LINEFEED),
                * then set the SUPPRESS_LEADING_SPACE flag.
                */
   	    inlineLC.setFlags(LayoutContext.SUPPRESS_LEADING_SPACE,
  -			      (bp == null && !m_vecInlineBreaks.isEmpty() &&
  +			      (prevBP == null && !m_vecInlineBreaks.isEmpty() &&
   			       ((BreakPoss)m_vecInlineBreaks.lastElement()).
   			       isForcedBreak()==false));
   
   	    // GET NEXT POSSIBLE BREAK FROM CHILD LM
  -	    prevBP = bp;
  +	    // prevBP = bp;
               if ((bp = curLM.getNextBreakPoss(inlineLC, null)) != null) {
   		// Add any space before and previous content dimension
  -		MinOptMax prevIPD = updatePrevIPD(bp, prevBP, (prevBP==null),
  -						  inlineLC.isFirstArea());
  +		MinOptMax prevIPD =
  +		    updatePrevIPD(bp, prevBP,
  +				  (m_vecInlineBreaks.size()==iPrevLineEnd),
  +				  inlineLC.isFirstArea());
   		MinOptMax bpDim = MinOptMax.add(bp.getStackingSize(), prevIPD);
   
   		// check if this bp fits in line
  @@ -175,41 +171,40 @@
   		// TODO: stop if linebreak is forced (NEWLINE)
   		// PROBLEM: interaction with wrap which can be set
   		// at lower levels!
  -		System.err.println("BPdim=" + bpDim.opt);
  +		// System.err.println("BPdim=" + bpDim.opt);
   
   		// Check if proposed area would fit in line
   		if (bpDim.min > availIPD.max) {
   		    // See if we have already found a potential break
  -		    if (vecPossEnd.size() > 0) break;
  +		    //if (vecPossEnd.size() > 0) break;
   
   		    // This break position doesn't fit
   		    // TODO: If we are in nowrap, we use it as is!
   		    if (m_bJustify || m_prevBP == null) {
  -			// try to find a hyphenation point in the word
  -			// which spans the queued breaks and the proposed bp
  -			// Even if not justified, we must try to hyphenate if
  -			// there is no breakpoint at all up to this point!
  -			do {
  -			    bp = findHyphenPoss(m_prevBP, bp);
  -			} while (bp != null &&
  -				 (bp.getStackingSize().min > availIPD.max));
  -			if (bp == null) {
  -			    // Couldn't find a hyphenation point. The line
  -			    // will be "short".
  +			// If we are already in a hyphenation loop, then stop.
  +
  +			if (inlineLC.tryHyphenate()) {
  +			    break;
   			}
  -			else {
  -			    m_prevBP = bp;
  +			// Otherwise, prepare to try hyphenation
  +			if (!bBreakOK) {
  +			    // Make sure we collect the entire word!
  +			    m_vecInlineBreaks.add(bp);
  +			    continue;
   			}
  -			// Handle pendingIPD if any. The hyphenation point
  -			// may be within the "pending" content or after it.
  -                        /* Make sure child LM are updated concerning the actual
  -                         * hyphenation BreakPoss for their next call!
  -                         */
  +			
  +			inlineLC.setHyphContext(getHyphenContext(m_prevBP, bp));
  +			if (inlineLC.getHyphContext()==null) break;
  +			inlineLC.setFlags(LayoutContext.TRY_HYPHENATE, true);
  +			// Reset to previous acceptable break
  +			reset();
   		    }
   		    /* If we are not in justified text, we can end the line at
   		     * prevBP.
   		     */
  -		    break;
  +		    else {
  +			break;
  +		    }
   		}
   		else {
   		    // Add the BP to the list whether or not we can break
  @@ -229,7 +224,6 @@
   			     * (ie, bpDim.opt closes to availIPD.opt), keeps
   			     * and hyphenation.
   			     */
  -			    System.err.println("Found potential linebreak");
   			    vecPossEnd.add(new BreakCost(bp,
   			     Math.abs(availIPD.opt - bpDim.opt )));
   			}
  @@ -246,13 +240,17 @@
   		 * up. Just try the next child LM.
   		 */
   	    }
  +	    if (inlineLC.tryHyphenate() &&
  +		!inlineLC.getHyphContext().hasMoreHyphPoints()) {
  +		break;
  +	    }
   	} // end of while on child LM
   	if ((curLM = getChildLM())== null) {
   	    // No more content to layout!
   	    setFinished(true);
   	}
   
  -if(bp == null) return null;
  +	if(bp == null) return null;
   
   	// Choose the best break
   	if (!bp.isForcedBreak() && vecPossEnd.size()>0) {
  @@ -260,11 +258,7 @@
   	}
   	// 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());
  +	    reset();
   	}
   	// Distribute space in the line
   	MinOptMax actual = MinOptMax.add(m_prevBP.getStackingSize(),
  @@ -282,6 +276,14 @@
           return makeLineBreak(m_prevBP, availIPD, actual, bJustify);
       }
   
  +
  +    private void reset() {
  +	while (m_vecInlineBreaks.lastElement()!=m_prevBP) {
  +	    m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1);
  +	}
  +	reset(m_prevBP.getLayoutManager(), m_prevBP.getPosition());
  +    }
  +
       protected boolean couldEndLine(BreakPoss bp) {
   	if (bp.canBreakAfter()) {
   	    return true; // no keep, ends on break char
  @@ -303,6 +305,7 @@
       }
   
   
  +
       private BreakPoss getBestBP(Vector vecPossEnd) {
   	if (vecPossEnd.size()==1) {
   	    return ((BreakCost)vecPossEnd.elementAt(0)).getBP();
  @@ -333,13 +336,62 @@
       
   
   
  -    private BreakPoss findHyphenPoss(BreakPoss prevBP, BreakPoss newBP) {
  +    private HyphContext getHyphenContext(BreakPoss prevBP, BreakPoss newBP) {
   	// Get a "word" to hyphenate by getting characters from all
   	// pending break poss which are in m_vecInlineBreaks, starting
  -	// with the position just AFTER prevBP.getPosition()
  -	return null;
  +	// with the position just AFTER prevBP.getPosition() 
  +
  +	m_vecInlineBreaks.add(newBP);
  +	ListIterator bpIter = m_vecInlineBreaks.
  +	    listIterator(m_vecInlineBreaks.size());
  +	while (bpIter.hasPrevious() && bpIter.previous() != prevBP);
  +	if (bpIter.next() != prevBP) {
  +	    System.err.println("findHyphenPoss: problem!");
  +	    return null;
  +	}
  +	StringBuffer sbChars = new StringBuffer(30);
  +	while (bpIter.hasNext()) {
  +	    BreakPoss bp = (BreakPoss)bpIter.next();
  +	    if (bp.getLayoutManager() == prevBP.getLayoutManager()) {
  +		bp.getLayoutManager().getWordChars(sbChars, prevBP.getPosition(),
  +						   bp.getPosition());
  +	    }
  +	    else {
  +		bp.getLayoutManager().getWordChars(sbChars, null, bp.getPosition());
  +	    }
  +	    prevBP = bp;
  +	}
  +	m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1); // remove last
  +	System.err.println("Word to hyphenate: " + sbChars.toString());
  +
  +	// Now find all hyphenation points in this word (get in an array of offsets)
  +	// hyphProps are from the block level?. Note that according to the spec,
  +	// they also "apply to" fo:character. I don't know what that means, since
  +	// if we change language in the middle of a "word", the effect would seem
  +	// quite strange! Or perhaps in that case, we say that it's several words.
  +	// We probably should bring the hyphenation props up from the actual
  +	// TextLM which generate the hyphenation buffer, since these properties
  +	// inherit and could be specified on an inline or wrapper below the block
  +	// level.
  +	Hyphenation hyph =
  +            Hyphenator.hyphenate(m_hyphProps.language, m_hyphProps.country,
  +                                 sbChars.toString(),
  +                                 m_hyphProps.hyphenationRemainCharacterCount,
  +                                 m_hyphProps.hyphenationPushCharacterCount);
  +	// They hyph structure contains the information we need
  +	// Now start from prevBP: reset to that position, ask that LM to get
  +	// a Position for the first hyphenation offset. If the offset isn't in
  +	// its characters, it returns null, but must tell how many chars it had.
  +	// Keep looking at currentBP using next hyphenation point until the
  +	// returned size is greater than the available size or no more hyphenation
  +	// points remain. Choose the best break.
  +	if (hyph != null) {
  +	    return new HyphContext(hyph.getHyphenationPoints());
  +	}
  +	else return null;
       }
   
  +
       private BreakPoss makeLineBreak(BreakPoss inlineBP, MinOptMax target,
   				    MinOptMax actual, boolean bJustify) {
           // make a new BP
  @@ -377,20 +429,28 @@
   
       // Generate and add areas to parent area
       // Set size etc
  -    public void addAreas(PositionIterator parentIter) {
  +    // dSpaceAdjust should reference extra space in the BPD
  +    public void addAreas(PositionIterator parentIter, double dSpaceAdjust) {
   	BPLayoutManager childLM ;
   	int iStartPos = 0;
   	while  (parentIter.hasNext()) {
   	    LineBreakPosition lbp  = (LineBreakPosition)parentIter.next();
  -	    System.err.println("lbp.endpos=" + lbp.m_iPos);
   	    m_lineArea = new LineArea();
   	    // Add the inline areas to lineArea
  -	    PositionIterator inlinePosIter =
  +	    BreakPossPosIter inlinePosIter =
   		new BreakPossPosIter(m_vecInlineBreaks,
   				     iStartPos, lbp.m_iPos+1);
   	    iStartPos = lbp.m_iPos+1;
   	    while  ((childLM = inlinePosIter.getNextChildLM())!= null) {
  -		childLM.addAreas(inlinePosIter);
  +		BreakPoss bp = inlinePosIter.getBP();
  +		int iSpaceSize = getLeadingSpace(bp,  lbp.m_dAdjust);
  +		if (iSpaceSize != 0) {
  +		    System.err.println("Add leading space: " + iSpaceSize);
  +		    Space ls = new Space();
  +		    ls.setWidth(iSpaceSize);
  +		    addChild(ls);
  +		}
  +		childLM.addAreas(inlinePosIter, lbp.m_dAdjust);
   	    }
   	    m_lineArea.verticalAlign(lineHeight, lead, follow);
   	    parentLM.addChild(m_lineArea);
  @@ -398,6 +458,26 @@
   	m_lineArea = null;
       }
   
  +    protected int getLeadingSpace(BreakPoss bp, double dSpaceAdjust) {
  +	MinOptMax leadSpace = bp.resolveLeadingSpace();
  +	if (leadSpace != null) {
  +	    int iAdjust=0;
  +	    if (dSpaceAdjust > 0.0) {
  +		// Stretch by factor
  +		iAdjust = (int)((double)(leadSpace.max - leadSpace.opt) *
  +				dSpaceAdjust);
  +	    }
  +	    else if (dSpaceAdjust < 0.0)  {
  +		// Shrink by factor
  +		iAdjust = (int)((double)(leadSpace.opt - leadSpace.min) *
  +				dSpaceAdjust);
  +	    }
  +	    return leadSpace.opt + iAdjust;
  +	}
  +	else return 0;
  +   }
  +
  +
       public boolean addChild(Area childArea) {
   	// Make sure childArea is inline area
   	if (childArea instanceof InlineArea) {
  @@ -440,7 +520,7 @@
   		}
   	    }
           }
  -	addAreas(new BreakPossPosIter(vecBreakPoss, 0, vecBreakPoss.size()));
  +	addAreas(new BreakPossPosIter(vecBreakPoss, 0, vecBreakPoss.size()), 0.0);
           return false;
       }
   
  
  
  
  1.2       +5 -1      xml-fop/src/org/apache/fop/layoutmgr/PositionIterator.java
  
  Index: PositionIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/layoutmgr/PositionIterator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PositionIterator.java	28 Apr 2002 21:31:00 -0000	1.1
  +++ PositionIterator.java	22 May 2002 20:20:50 -0000	1.2
  @@ -1,5 +1,5 @@
   /*
  - * $Id: PositionIterator.java,v 1.1 2002/04/28 21:31:00 klease Exp $
  + * $Id: PositionIterator.java,v 1.2 2002/05/22 20:20:50 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.
  @@ -81,6 +81,10 @@
   	else {
   	    throw new NoSuchElementException("PosIter");
   	}
  +    }
  +
  +    protected Object peekNext() {
  +	return m_nextObj;
       }
   
       public void remove() throws UnsupportedOperationException {
  
  
  
  1.4       +188 -116  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.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TextBPLayoutManager.java	13 May 2002 06:12:42 -0000	1.3
  +++ TextBPLayoutManager.java	22 May 2002 20:20:50 -0000	1.4
  @@ -1,5 +1,5 @@
   /*
  - * $Id: TextBPLayoutManager.java,v 1.3 2002/05/13 06:12:42 klease Exp $
  + * $Id: TextBPLayoutManager.java,v 1.4 2002/05/22 20:20:50 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.
  @@ -52,10 +52,13 @@
       private class AreaInfo {
   	short m_iStartIndex;
   	short m_iBreakIndex;
  +	short m_iWScount;
   	MinOptMax m_ipdArea;
  -	AreaInfo(short iStartIndex, short iBreakIndex, MinOptMax ipdArea) {
  +	AreaInfo(short iStartIndex, short iBreakIndex, short iWScount,
  +		 MinOptMax ipdArea) {
   	    m_iStartIndex = iStartIndex;
   	    m_iBreakIndex = iBreakIndex;
  +	    m_iWScount = iWScount;
   	    m_ipdArea = ipdArea;
   	}
       }
  @@ -71,19 +74,13 @@
       private TextInfo textInfo;
   
       private static final char NEWLINE = '\n';
  -    private static final char RETURN = '\r';
  -    private static final char TAB = '\t';
  -    private static final char SPACE = ' ';
  +    private static final char SPACE = '\u0020';   // Normal space
  +    private static final char NBSPACE = '\u00A0'; // Non-breaking space
       private static final char LINEBREAK = '\u2028';
       private static final char ZERO_WIDTH_SPACE = '\u200B';
       // byte order mark
       private static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
   
  -    /* values that prev (below) may take */
  -    protected static final int NOTHING = 0;
  -    protected static final int WHITESPACE = 1;
  -    protected static final int TEXT = 2;
  -
       /** Start index of first character in this parent Area */
       private short m_iAreaStart = 0;
       /** Start index of next "word" */
  @@ -94,6 +91,8 @@
       // private MinOptMax m_nextIPD= new MinOptMax(0);
       /** size of a space character (U+0020) glyph in current font */
       private int m_spaceIPD;
  +    /** size of the hyphen character glyph in current font */
  +    private int m_hyphIPD;
       /** 1/2 of word-spacing value */
       private SpaceVal m_halfWS;
       /** Number of space characters after previous possible break position. */
  @@ -109,6 +108,8 @@
   
           // With CID fonts, space isn't neccesary currentFontState.width(32)
           m_spaceIPD = CharUtilities.getCharWidth(' ', textInfo.fs);
  +	// Use hyphenationChar property
  +        m_hyphIPD = CharUtilities.getCharWidth('-', textInfo.fs);
   	// Make half-space: <space> on either side of a word-space)
   	SpaceVal ws = textInfo.wordSpacing;
   	m_halfWS = new SpaceVal(MinOptMax.multiply(ws.space, 0.5),
  @@ -145,42 +146,17 @@
       }
   
   
  -    // NOTE: currently not used. Remove if decide it isn't necessary!
  -//     /**
  -//      * Get the BreakPoss at the start of the next line.
  -//      * @param bpPrevEnd The BreakPoss at the end of the previous line
  -//      * or null if we should return the point at the beginning of this
  -//      * text run.
  -//      */
  -//     public BreakPoss getStartBreakPoss(LayoutContext lc,
  -// 				       BreakPoss.Position bpPrevEnd) {
  -// 	BreakPoss bp = null;
  -// 	if (bpPrevEnd == null) {
  -// 	    bp = new BreakPoss(this, new TextBreakPosition(0));
  -// 	    // Set minimum bpd (character ascent and descent)
  -// 	    // Or do this at the line level???
  -// 	}
  -// 	else {
  -// 	    // Skip suppressible white-space
  -// 	    // ASSERT (((TextBreakPosition)bpPrevEnd).m_iAreaIndex =
  -// 	    //         m_iNextStart)
  -// 	    if ((lc.flags & LayoutContext.SUPPRESS_LEADING_SPACE)!=0) {
  -// 		/* Skip any leading word-space characters. */
  -// 		for (; m_iNextStart < chars.length &&
  -// 		     chars[m_iNextStart]==SPACE; m_iNextStart++);
  -// 	    }
  -// 	    // If now at end, nothing to compose here!
  -// 	    if (m_iNextStart >= chars.length) {
  -// 		return null; // Or an "empty" BreakPoss?
  -// 	    }
  -// 	    else {
  -// 		bp = new BreakPoss(this,
  -// 				   new TextBreakPosition(m_iNextStart));
  -// 	    }
  -// 	}
  -// 	return bp;
  -//     }
  -
  +    public void getWordChars(StringBuffer sbChars,
  +			     BreakPoss.Position bp1, BreakPoss.Position bp2) {
  +	TextBreakPosition endPos = (TextBreakPosition)bp2;
  +	AreaInfo ai =
  +	    (AreaInfo) m_vecAreaInfo.elementAt(endPos.m_iAreaIndex);
  +	// Skip all leading spaces for hyphenation
  +	int i;
  +        for (i=ai.m_iStartIndex;i < ai.m_iBreakIndex && 
  +		 CharUtilities.isAnySpace(chars[i])==true ;i++);
  +	sbChars.append(new String(chars, i, ai.m_iBreakIndex-i));
  +    }
   
       /**
        * Return value indicating whether the next area to be generated could
  @@ -204,13 +180,14 @@
   	    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");
  +		// TODO: reset or recalculate total IPD = sum of all word IPD
  +		// up to the break position
  +		m_ipdTotal = ai.m_ipdArea;
   		setFinished(false);
   	    }
   	}
   	else {
   	    // Reset to beginning!
  -	    System.err.println("TextBPLM: resetPosition(null)");
   	    m_vecAreaInfo.setSize(0);
   	    m_iNextStart = 0;
   	    setFinished(false);
  @@ -218,6 +195,30 @@
       }
   
   
  +    // TODO: see if we can use normal getNextBreakPoss for this with
  +    // extra hyphenation information in LayoutContext
  +    private boolean getHyphenIPD(HyphContext hc, MinOptMax hyphIPD) {
  +	// Skip leading word-space before calculating count?
  +	boolean bCanHyphenate = true;
  +	int iStopIndex =  m_iNextStart + hc.getNextHyphPoint();
  +
  +	if (chars.length < iStopIndex || textInfo.bCanHyphenate==false ) {
  +	    iStopIndex = chars.length;
  +	    bCanHyphenate = false;
  +	}
  +	hc.updateOffset(iStopIndex - m_iNextStart);
  +
  +        for (; m_iNextStart < iStopIndex; m_iNextStart++) {
  +            char c = chars[m_iNextStart];
  +	    hyphIPD.opt += CharUtilities.getCharWidth(c, textInfo.fs);
  +	    // letter-space?
  +	}
  +	// Need to include hyphen size too, but don't count it in the
  +	// stored running total, since it would be double counted
  +	// with later hyphenation points
  +	return bCanHyphenate;
  +    }
  +
       /**
        * Return the next break possibility that fits the constraints.
        * @param context An object specifying the flags and input information
  @@ -250,15 +251,17 @@
   	     */
   	    m_ipdTotal = new MinOptMax(0);
   	    iFlags |= BreakPoss.ISFIRST;
  -	    // May have leading space too which can combine with a
  -	    // leading word-space or letter-space
   	}
   
   
  -        // HANDLE SUPPRESSED LEADING SPACES
  +        /* HANDLE SUPPRESSED LEADING SPACES
  +	 * See W3C XSL Rec. 7.16.3.
  +	 * Suppress characters whose "suppress-at-line-break" property = "suppress"
  +	 * This can only be set on an explicit fo:character object. The default
  +	 * behavior is that U+0020 is suppressed; all other character codes are
  +	 * retained.
  +	 */
   	if (context.suppressLeadingSpace()) {
  -	    /* If any leading space characters, ignore them. */ 
  -	    // NOTE: Skips word-space chars only, not other white-space!
   	    for (; m_iNextStart < chars.length &&
   		     chars[m_iNextStart]==SPACE; m_iNextStart++);
   	    // If now at end, nothing to compose here!
  @@ -269,23 +272,33 @@
   	}
   
   
  -	// Start of this "word", plus any non-suppressed leading space
  -	// This is any kind of white-space, not just word spaces
  +	/* Start of this "word", plus any non-suppressed leading space.
  +	 * Collapse any remaining word-space with leading space from
  +	 * ancestor FOs.
  +	 * Add up other leading space which is counted in the word IPD.
  +	 */
   
  -        short iThisStart = m_iNextStart;
  -        MinOptMax spaceIPD = new MinOptMax(0); // Variable IPD
  -        int wordIPD = 0;  // Non-stretching IPD (length in base units)
  -
  -	// Handle inter-character spacing (word-space + letter-space)
  -	// What about context.getPendingSpace() on first char in word?
  -	SpaceSpecifier pendingSpace = new SpaceSpecifier(false);
  +	SpaceSpecifier pendingSpace= new SpaceSpecifier(false);
  +        short iThisStart = m_iNextStart; // Index of first character counted
  +        MinOptMax spaceIPD = new MinOptMax(0); // Extra IPD from word-spacing
  +	// Sum of glyph IPD of all characters in a word, inc. leading space
  +        int wordIPD = 0;
  +	short iWScount=0; // Count of word spaces
   
           for (; m_iNextStart < chars.length; m_iNextStart++) {
               char c = chars[m_iNextStart];
   	    if (CharUtilities.isAnySpace(c)==false) break;
  -            if (c==SPACE) {
  -		pendingSpace.addSpace(m_halfWS);
  -		spaceIPD.add(pendingSpace.resolve(false));
  +            if (c==SPACE || c==NBSPACE) {
  +		++iWScount;
  +		// Counted as word-space
  +		if (m_iNextStart == iThisStart &&
  +		    (iFlags & BreakPoss.ISFIRST) !=0 ) {
  +		    context.getPendingSpace().addSpace(m_halfWS);
  +		}
  +		else {
  +		    pendingSpace.addSpace(m_halfWS);
  +		    spaceIPD.add(pendingSpace.resolve(false));
  +		}
   		wordIPD += m_spaceIPD; // Space glyph IPD
   		pendingSpace.clear();
   		pendingSpace.addSpace(m_halfWS);
  @@ -305,64 +318,79 @@
   	else {
   	    // This FO ended with spaces. Return the BP
   	    iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB;
  -	    // lc.trailingSpaceSeq.addSpace(m_halfWS);
  -	    // Need to make SpaceSpecifier from m_halfWS!
  -	    // Or at least a spaceval
  -	    return makeBreakPoss(iThisStart, spaceIPD, 0, pendingSpace,
  -				 iFlags);
  +	    return makeBreakPoss(iThisStart, spaceIPD, wordIPD, 
  +				 context.getPendingSpace(), pendingSpace,
  +				 iFlags, iWScount);
   	}
   
  +	if (context.tryHyphenate()) {
  +	    // Get the size of the next syallable
  +	    MinOptMax hyphIPD = new MinOptMax(0);
  +	    if (getHyphenIPD(context.getHyphContext(), hyphIPD)) {
  +		iFlags |= (BreakPoss.CAN_BREAK_AFTER | BreakPoss.HYPHENATED);
  +	    }
  +	    wordIPD += hyphIPD.opt;
  +	}
  +	else {
           // Look for a legal line-break: breakable white-space and certain
           // characters such as '-' which can serve as word breaks.
           // Don't look for hyphenation points here though
  -
  -        for (; m_iNextStart < chars.length; m_iNextStart++) {
  -            char c = chars[m_iNextStart];
  -            if ((c == NEWLINE) ||
  -		// Include any breakable white-space as break char
  -		//  even if fixed width
  -                (textInfo.bWrap &&
  -		 (CharUtilities.isSpace(c) ||
  -		  s_breakChars.indexOf(c)>=0))) {
  -		iFlags |= BreakPoss.CAN_BREAK_AFTER;
  -                if (c != SPACE) {
  -                    m_iNextStart++;
  -                    if (c != NEWLINE) {
  -                        wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
  -                    }
  -		    else {
  -			iFlags |= BreakPoss.FORCE;
  +	    for (; m_iNextStart < chars.length; m_iNextStart++) {
  +		char c = chars[m_iNextStart];
  +		if ((c == NEWLINE) ||
  +		    // Include any breakable white-space as break char
  +		    //  even if fixed width
  +		    (textInfo.bWrap &&
  +		     (CharUtilities.isSpace(c) ||
  +		      s_breakChars.indexOf(c)>=0))) {
  +		    iFlags |= BreakPoss.CAN_BREAK_AFTER;
  +		    if (c != SPACE) {
  +			m_iNextStart++;
  +			if (c != NEWLINE) {
  +			    wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
  +			}
  +			else {
  +			    iFlags |= BreakPoss.FORCE;
  +			}
   		    }
  -                }
  -		return makeBreakPoss(iThisStart, spaceIPD, wordIPD, null,
  -				     iFlags);
  -            }
  -	    wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
  -	    // Note, if a normal non-breaking space, is it stretchable???
  -	    // If so, keep a count of these embedded spaces.
  -        }
  -	return makeBreakPoss(iThisStart, spaceIPD, wordIPD, null, iFlags);
  +		    return makeBreakPoss(iThisStart, spaceIPD, wordIPD,
  +					 context.getPendingSpace(), null,
  +					 iFlags, iWScount);
  +		}
  +		wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
  +		// Note, if a normal non-breaking space, is it stretchable???
  +		// If so, keep a count of these embedded spaces.
  +	    }
  +	}
  +	return makeBreakPoss(iThisStart, spaceIPD, wordIPD, 
  +			     context.getPendingSpace(), null, iFlags, iWScount);
       }
   
   
       private BreakPoss makeBreakPoss(short iWordStart, MinOptMax spaceIPD,
  -				    int wordDim,
  +				    int wordDim, SpaceSpecifier leadingSpace,
   				    SpaceSpecifier trailingSpace,
  -				    int flags)
  +				    int flags, short iWScount)
       {
   	MinOptMax ipd = new MinOptMax(wordDim);
   	ipd.add(spaceIPD);
  +	ipd.add(m_ipdTotal); // sum of all words so far in line
  +	// Note: break position now stores total size to here
   
   	// Position is the index of the info for this word in the vector
  -	m_vecAreaInfo.add(new AreaInfo(iWordStart, m_iNextStart, ipd));
  +	m_vecAreaInfo.add(new AreaInfo(iWordStart, m_iNextStart, iWScount, ipd));
           BreakPoss bp =
   	    new BreakPoss(this,
   			  new TextBreakPosition(m_vecAreaInfo.size()-1));
  -
  -	ipd.add(m_ipdTotal); // sum of all words so far in line
  -	bp.setStackingSize(ipd);
   	m_ipdTotal = ipd;
  -	// TODO: make this correct (see Keiron's code below!)
  +	if ((flags & BreakPoss.HYPHENATED)!=0) {
  +	    // Add the hyphen size, but don't change total IPD!
  +	    bp.setStackingSize(MinOptMax.add(ipd, new MinOptMax(m_hyphIPD)));
  +	}
  +	else {
  +	    bp.setStackingSize(ipd);
  +	}
  +	// TODO: make this correct (see Keiron's vertical alignment code)
   	bp.setNonStackingSize(new MinOptMax(textInfo.lineHeight));
   
   	/* Set max ascender and descender (offset from baseline),
  @@ -382,28 +410,72 @@
   	else {
   	    bp.setTrailingSpace(new SpaceSpecifier(false));
   	}
  -	bp.setLeadingSpace(new SpaceSpecifier(false));
  +	if (leadingSpace != null) {
  +	    bp.setLeadingSpace(leadingSpace);
  +	}
  +	else {
  +	    bp.setLeadingSpace(new SpaceSpecifier(false));
  +	}
           return bp;
       }
   
   
       /**
  -     * Add an area for each word and space (or one big one????)
  +     * Generate and add areas to parent area.
  +     * This can either generate an area for each "word" and each space, or
  +     * an area containing all text with a parameter controlling the size of
  +     * the word space. The latter is most efficient for PDF generation.
  +     * Set size of each area.
  +     * @param parentIter Iterator over BreakPoss.Position information returned
  +     * by this LayoutManager.
  +     * @param dSpaceAdjust Factor controlling how much extra space to add
  +     * in order to justify the line.
        */
  -    public void addAreas(PositionIterator posIter) {
  +    public void addAreas(PositionIterator posIter, double dSpaceAdjust) {
   	// Add word areas
  -	TextBreakPosition tbpStart, tbpNext;
  +	AreaInfo ai=null ;
  +	int iStart = -1;
  +	int iWScount = 0;
  +
  +	/* On first area created, add any leading space.
  +	 * Calculate word-space stretch value.
  +	 */
   	while (posIter.hasNext()) {
  -	    tbpNext = (TextBreakPosition)posIter.next();
  -	    // System.err.println("tbp.pos = " + tbpNext.m_iAreaIndex);
  -	    AreaInfo ai = (AreaInfo)m_vecAreaInfo.
  -		elementAt(tbpNext.m_iAreaIndex);
  -	    // Make an area containing all characters between start and end.
  -	    Word word = createWord(new String(chars, ai.m_iStartIndex, 
  -				      ai.m_iBreakIndex- ai.m_iStartIndex),
  -				   ai.m_ipdArea.opt);
  -	    parentLM.addChild(word);
  +	    TextBreakPosition tbpNext =	(TextBreakPosition)posIter.next();
  +	    ai = (AreaInfo)m_vecAreaInfo.elementAt(tbpNext.m_iAreaIndex);
  +	    if (iStart == -1) {
  +		iStart = ai.m_iStartIndex;
  +	    }
  +	    iWScount += ai.m_iWScount;
  +	}
  +	// Calculate total adjustment
  +	int iAdjust = 0;
  +	if (dSpaceAdjust > 0.0) {
  +	    // Stretch by factor
  +	    System.err.println("Potential stretch = " +
  +			       (ai.m_ipdArea.max - ai.m_ipdArea.opt));
  +	    iAdjust = (int)((double)(ai.m_ipdArea.max - ai.m_ipdArea.opt) *
  +		dSpaceAdjust);
  +	}
  +	else if (dSpaceAdjust < 0.0)  {
  +	    // Shrink by factor
  +	    System.err.println("Potential shrink = " +
  +			       (ai.m_ipdArea.opt - ai.m_ipdArea.min));
  +	    iAdjust = (int)((double)(ai.m_ipdArea.opt - ai.m_ipdArea.min) *
  +		dSpaceAdjust);
  +	}
  +	System.err.println("Text adjustment factor = " + dSpaceAdjust +
  +			   " total=" + iAdjust);
  +	if (iWScount > 0) {
  +	    System.err.println("Adjustment per word-space= " + iAdjust/iWScount);
  +	}
  +	// Make an area containing all characters between start and end.
  +	Word word = createWord(new String(chars, iStart, ai.m_iBreakIndex - iStart),
  +			       ai.m_ipdArea.opt + iAdjust);
  +	if (chars[iStart] == SPACE || chars[iStart] == NBSPACE ) {
  +	    // word.setLeadingSpace(m_halfWS);
   	}
  +	parentLM.addChild(word);
       }
   
   
  
  
  
  1.1                  xml-fop/src/org/apache/fop/layoutmgr/HyphContext.java
  
  Index: HyphContext.java
  ===================================================================
  /*
   * $Id: HyphContext.java,v 1.1 2002/05/22 20:20:50 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.
   */
  package org.apache.fop.layoutmgr;
  
  
  /**
   * This class is used to pass information to the getNextBreakPoss()
   * method concerning hyphenation. A reference to an instance of the
   * class is contained in the LayoutContext object passed to each
   * LayoutManager. It contains information concerning the hyphenation
   * points in a word and the how many of those have previously been
   * processed by a Layout Manager to generate size information.
   */
  public class HyphContext {
      private int[] m_hyphPoints;
      private int m_iCurOffset=0;
      private int m_iCurIndex=0;
  
      public HyphContext(int[] hyphPoints) {
  	m_hyphPoints = hyphPoints;
      }
  
      public int getNextHyphPoint() {
  	for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
  	    if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
  		return (m_hyphPoints[m_iCurIndex] - m_iCurOffset);
  	    }
  	}
  	return -1; // AT END!
      }
  
      public boolean hasMoreHyphPoints() {
  	for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
  	    if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
  		return true;
  	    }
  	}
  	return false;
      }
  
      public void updateOffset(int iCharsProcessed) {
  	m_iCurOffset += iCharsProcessed;
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: fop-cvs-help@xml.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic