You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by de...@apache.org on 2002/04/12 16:36:48 UTC

cvs commit: xml-batik/sources/org/apache/batik/gvt/text GlyphIterator.java GlyphLayout.java MarginInfo.java

deweese     02/04/12 07:36:48

  Modified:    samples/extensions flowText.svg
               sources/org/apache/batik/extension/svg
                        BatikDomExtension.java BatikExtConstants.java
                        SVGFlowTextElementBridge.java
               sources/org/apache/batik/gvt/renderer
                        StrokingTextPainter.java
               sources/org/apache/batik/gvt/text GlyphIterator.java
                        GlyphLayout.java MarginInfo.java
  Added:       sources/org/apache/batik/extension/svg
                        FlowRegionBreakElement.java
  Log:
  1) Added new flowRegionBreak element that is the same as a flowPara element
     but causes the text to move to the next flow rectangle after it ends
     (it can be empty).
  2) Text wrapping is now done on the visual advance of the glyph not the
     glyph advance.  This is usually a small difference but because everything
     else is done with visual advance (centering/right/full
     justification) this is the right thing to do.
  3) Now handles paragraphs and margins when moving between flow regions
     in accordance to current WG thinking (especially empty paragraphs).
  4) Multiple empty flowLine elements collapse (also in accordance with
     current WG thinking - this is what happens in XHTML or so I'm told).
  5) Fixed a bug or two in text chunking.
  
  Revision  Changes    Path
  1.4       +3 -3      xml-batik/samples/extensions/flowText.svg
  
  Index: flowText.svg
  ===================================================================
  RCS file: /home/cvs/xml-batik/samples/extensions/flowText.svg,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- flowText.svg	4 Apr 2002 03:29:57 -0000	1.3
  +++ flowText.svg	12 Apr 2002 14:36:47 -0000	1.4
  @@ -14,7 +14,7 @@
   <!-- Tests various text on a path                                           -->
   <!--                                                                        -->
   <!-- @author bella.robinson@cmis.csiro.au                                   -->
  -<!-- @version $Id: flowText.svg,v 1.3 2002/04/04 03:29:57 deweese Exp $   -->
  +<!-- @version $Id: flowText.svg,v 1.4 2002/04/12 14:36:47 deweese Exp $   -->
   <!-- ====================================================================== -->
   
   <?xml-stylesheet type="text/css" href="extension.css" ?>
  @@ -42,9 +42,9 @@
            </batik:flowRegion>
            <batik:flowDiv>
   	    <batik:flowPara bottom-margin="10" >This is an <batik:flowSpan font-size="40" fill="crimson">ex&#x00AD;ample</batik:flowSpan> of a very long string that is split &#x200D;across multi&#x00AD;ple lines via text wrap&#x0AD;ping.</batik:flowPara>
  -	    <batik:flowPara justification="middle" top-margin="10" left-margin="10" right-margin="10" bottom-margin="10"><batik:flowLine>Now check if text wrapping handles a number of tricky situations: </batik:flowLine>averylongrunonwordthatspansmultiplelines<batik:flowSpan font-weight="bold">with<batik:flowSpan fill="crimson">embedded</batik:flowSpan>span</batik:flowSpan>elements &amp; <batik:flowSpan fill="green" dy="-.3em" font-size="80%">super</batik:flowSpan><batik:flowSpan dy=".3em"> or </batik:flowSpan><batik:flowSpan fill="darkgreen" dy=".3em" font-size="80%">sub</batik:flowSpan><batik:flowSpan dy="-.3em"> scripts.</batik:flowSpan></batik:flowPara>
  +	    <batik:flowPara justification="middle" top-margin="10" left-margin="10" right-margin="10" bottom-margin="10"><batik:flowLine>Now check if text wrapping handles a number of tricky</batik:flowLine> situations: averylongrunonwordthatspansmultiplelines<batik:flowSpan font-weight="bold">with<batik:flowSpan fill="crimson">embedded</batik:flowSpan>span</batik:flowSpan>elements &amp; <batik:flowSpan fill="green" dy="-.3em" font-size="80%">super</batik:flowSpan><batik:flowSpan dy=".3em"> or </batik:flowSpan><batik:flowSpan fill="darkgreen" dy=".3em" font-size="80%">sub</batik:flowSpan><batik:flowSpan dy="-.3em"> scripts.</batik:flowSpan></batik:flowPara>
   	    <batik:flowPara top-margin="10" justification="end">Now we are just <batik:flowSpan font-size="30" fill="blue">about</batik:flowSpan> to go to the next flow rect <batik:flowSpan font-size="10">(note if the 'about' were included on the last line of the previous flow rect the line would not have fit and the whole line would have moved here).</batik:flowSpan></batik:flowPara>
  -	    <batik:flowPara margin="10" justification="full">     I'll keep going because I want to make sure that it properly stops when it hits the end of the flow regions. I'm going to try and trick it by having the last line include larger text so it wouldn't fit vertically. The end of this sentence will be cut off because the line size gets larg<batik:flowSpan font-size="35">er</batik:flowSpan></batik:flowPara>
  +	    <batik:flowPara margin="10" justification="full">     I'll keep going because I want to make sure that it properly stops when it hits the end of all of the the flow regions defined. Also the last line includes text in a larger font size so it will not fit. Thus the end of this sentence will be cut off because the line size gets <batik:flowSpan font-size="35">tall</batik:flowSpan>er</batik:flowPara>
            </batik:flowDiv>
         </batik:flowText>
      </g>
  
  
  
  1.10      +20 -0     xml-batik/sources/org/apache/batik/extension/svg/BatikDomExtension.java
  
  Index: BatikDomExtension.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/extension/svg/BatikDomExtension.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- BatikDomExtension.java	29 Mar 2002 20:00:54 -0000	1.9
  +++ BatikDomExtension.java	12 Apr 2002 14:36:47 -0000	1.10
  @@ -117,6 +117,11 @@
   
           di.registerCustomElementFactory
               (BATIK_EXT_NAMESPACE_URI,
  +             BATIK_EXT_FLOW_REGION_BREAK_TAG,
  +             new FlowRegionBreakElementFactory());
  +
  +        di.registerCustomElementFactory
  +            (BATIK_EXT_NAMESPACE_URI,
                BATIK_EXT_FLOW_LINE_TAG,
                new FlowLineElementFactory());
   
  @@ -269,6 +274,21 @@
            */
           public Element create(String prefix, Document doc) {
               return new FlowParaElement(prefix, (AbstractDocument)doc);
  +        }
  +    }
  +
  +    /**
  +     * To create a 'flowRegionBreak' element.
  +     */
  +    protected static class FlowRegionBreakElementFactory 
  +        implements SVGDOMImplementation.ElementFactory {
  +        public FlowRegionBreakElementFactory() {
  +        }
  +        /**
  +         * Creates an instance of the associated element type.
  +         */
  +        public Element create(String prefix, Document doc) {
  +            return new FlowRegionBreakElement(prefix, (AbstractDocument)doc);
           }
       }
   
  
  
  
  1.9       +5 -0      xml-batik/sources/org/apache/batik/extension/svg/BatikExtConstants.java
  
  Index: BatikExtConstants.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/extension/svg/BatikExtConstants.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BatikExtConstants.java	29 Mar 2002 20:00:54 -0000	1.8
  +++ BatikExtConstants.java	12 Apr 2002 14:36:47 -0000	1.9
  @@ -75,6 +75,11 @@
       public static final String BATIK_EXT_FLOW_PARA_TAG = 
           "flowPara";
   
  +    /** Tag name for Batik's flowText extension flow Region break 
  +     *  element SVG 1.1). */
  +    public static final String BATIK_EXT_FLOW_REGION_BREAK_TAG = 
  +        "flowRegionBreak";
  +
       /** Tag name for Batik's flowText extension line element SVG 1.1). */
       public static final String BATIK_EXT_FLOW_LINE_TAG = 
           "flowLine";
  
  
  
  1.2       +22 -6     xml-batik/sources/org/apache/batik/extension/svg/SVGFlowTextElementBridge.java
  
  Index: SVGFlowTextElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/extension/svg/SVGFlowTextElementBridge.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SVGFlowTextElementBridge.java	29 Mar 2002 20:00:54 -0000	1.1
  +++ SVGFlowTextElementBridge.java	12 Apr 2002 14:36:47 -0000	1.2
  @@ -39,7 +39,7 @@
    * Bridge class for the &lt;flowText> element.
    *
    * @author <a href="deweese@apache.org">Thomas DeWeese</a>
  - * @version $Id: SVGFlowTextElementBridge.java,v 1.1 2002/03/29 20:00:54 deweese Exp $
  + * @version $Id: SVGFlowTextElementBridge.java,v 1.2 2002/04/12 14:36:47 deweese Exp $
    */
   public class SVGFlowTextElementBridge extends SVGTextElementBridge 
       implements BatikExtConstants {
  @@ -169,6 +169,7 @@
               }
               String ln = child.getLocalName();
               if (ln.equals(BATIK_EXT_FLOW_PARA_TAG) ||
  +                ln.equals(BATIK_EXT_FLOW_REGION_BREAK_TAG) ||
                   ln.equals(BATIK_EXT_FLOW_LINE_TAG) ||
                   ln.equals(BATIK_EXT_FLOW_SPAN_TAG) ||
                   ln.equals(SVG_A_TAG) ||
  @@ -230,6 +231,7 @@
               }
               String ln = child.getLocalName();
               if (ln.equals(BATIK_EXT_FLOW_PARA_TAG) ||
  +                ln.equals(BATIK_EXT_FLOW_REGION_BREAK_TAG) ||
                   ln.equals(BATIK_EXT_FLOW_LINE_TAG) ||
                   ln.equals(BATIK_EXT_FLOW_SPAN_TAG) ||
                   ln.equals(SVG_A_TAG) ||
  @@ -276,6 +278,11 @@
   
                   paraElems.add(e);
                   paraEnds.add(new Integer(asb.length()));
  +            } else if (ln.equals(BATIK_EXT_FLOW_REGION_BREAK_TAG)) {
  +                fillAttributedStringBuffer(ctx, e, true, asb, lnLocs);
  +
  +                paraElems.add(e);
  +                paraEnds.add(new Integer(asb.length()));
               }
           }
   
  @@ -286,6 +293,10 @@
           List emptyPara = null;
           int prevLN = -1;
           Iterator lnIter = lnLocs.iterator();
  +
  +        // The Working Group (in conjunction with XHTML working group
  +        // has decided that multiple line elements collapse so I don't
  +        // use the counting I do.
           int lnCount = 0;
           while (lnIter.hasNext()) {
               int nextLN = ((Integer)lnIter.next()).intValue();
  @@ -293,21 +304,22 @@
                   lnCount++;
               } else {
                   if (prevLN != -1)
  -                    ret.addAttribute(FLOW_LINE_BREAK, new Integer(lnCount), 
  +                    ret.addAttribute(FLOW_LINE_BREAK, 
  +                                     new Integer(1), // new Integer(lnCount), 
                                        prevLN-1, prevLN);
                   prevLN  = nextLN;
                   lnCount = 1;
               }
           }
           if (prevLN != -1)
  -            ret.addAttribute(FLOW_LINE_BREAK, new Integer(lnCount), 
  +            ret.addAttribute(FLOW_LINE_BREAK,
  +                             new Integer(1), // new Integer(lnCount), 
                                prevLN-1, prevLN);
   
           int end;
           for (int i=0; i<paraElems.size(); i++, start=end) {
               Element elem = (Element)paraElems.get(i);
               end  = ((Integer)paraEnds.get(i)).intValue();
  -
               if (start == end) {
                   if (emptyPara == null)
                       emptyPara = new LinkedList();
  @@ -550,7 +562,7 @@
            * @param breakIdx   The character after which to break.
            * @param lineAdvAdj The line advance adjustment.
            * @param relative   If true lineAdvAdj must be multiplied by
  -1         *                   the line height.
  +         *                   the line height.
            */
           public LineBreakInfo(int breakIdx, float lineAdvAdj, boolean relative){
               this.breakIdx = breakIdx;
  @@ -565,6 +577,7 @@
       public MarginInfo makeMarginInfo(Element e) {
           String s;
           float top=0, right=0, bottom=0, left=0;
  +
           s = e.getAttributeNS(null, BATIK_EXT_MARGIN_ATTRIBUTE);
           try {
               if (s.length() != 0) {
  @@ -617,7 +630,10 @@
                   }
               }
           } catch(NumberFormatException nfe) { /* nothing */ }
  -        return new MarginInfo(top, right, bottom, left, justification);
  +
  +        String ln = e.getLocalName();
  +        boolean rgnBr = ln.equals(BATIK_EXT_FLOW_REGION_BREAK_TAG);
  +        return new MarginInfo(top, right, bottom, left, justification, rgnBr);
       }
   
   
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/extension/svg/FlowRegionBreakElement.java
  
  Index: FlowRegionBreakElement.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.extension.svg;
  
  import org.w3c.dom.Node;
  
  import org.apache.batik.dom.AbstractDocument;
  import org.apache.batik.extension.PrefixableStylableExtensionElement;
  
  /**
   * This class implements a regular polygon extension to SVG
   *
   * @author <a href="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
   * @version $Id: FlowRegionBreakElement.java,v 1.1 2002/04/12 14:36:47 deweese Exp $
   */
  public class FlowRegionBreakElement
      extends    PrefixableStylableExtensionElement 
      implements BatikExtConstants {
  
      /**
       * Creates a new BatikRegularPolygonElement object.
       */
      protected FlowRegionBreakElement() {
      }
  
      /**
       * Creates a new BatikRegularPolygonElement object.
       * @param prefix The namespace prefix.
       * @param owner The owner document.
       */
      public FlowRegionBreakElement(String prefix, AbstractDocument owner) {
          super(prefix, owner);
      }
  
      /**
       * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getLocalName()}.
       */
      public String getLocalName() {
          return BATIK_EXT_FLOW_REGION_BREAK_TAG;
      }
  
      /**
       * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getNamespaceURI()}.
       */
      public String getNamespaceURI() {
          return BATIK_EXT_NAMESPACE_URI;
      }
  
      /**
       * Returns a new uninitialized instance of this object's class.
       */
      protected Node newNode() {
          return new FlowRegionBreakElement();
      }
  }
  
  
  
  1.32      +8 -10     xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java
  
  Index: StrokingTextPainter.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- StrokingTextPainter.java	3 Apr 2002 04:58:21 -0000	1.31
  +++ StrokingTextPainter.java	12 Apr 2002 14:36:48 -0000	1.32
  @@ -61,7 +61,7 @@
    * @see org.apache.batik.gvt.text.GVTAttributedCharacterIterator
    *
    * @author <a href="bill.haneman@ireland.sun.com>Bill Haneman</a>
  - * @version $Id: StrokingTextPainter.java,v 1.31 2002/04/03 04:58:21 deweese Exp $
  + * @version $Id: StrokingTextPainter.java,v 1.32 2002/04/12 14:36:48 deweese Exp $
    */
   public class StrokingTextPainter extends BasicTextPainter {
   
  @@ -243,18 +243,15 @@
               List layouts = new ArrayList();
               chunkLayouts.add(layouts);
               layouts.add(tr.getLayout());
  -            while (true) {
  -                while (i.hasNext()) {
  -                    tr = (TextRun)i.next();
  -                    if (tr.isFirstRunInChunk()) break;
  -                    layouts.add(tr.getLayout());
  +            while (i.hasNext()) {
  +                tr = (TextRun)i.next();
  +                if (tr.isFirstRunInChunk()) {
  +                    layouts = new ArrayList();
  +                    chunkLayouts.add(layouts);
                   }
  -
  -                if (!i.hasNext()) break;
  -                layouts = new ArrayList();
  -                chunkLayouts.add(layouts);
                   layouts.add(tr.getLayout());
               }
  +
               org.apache.batik.gvt.text.GlyphLayout.textWrapTextChunk
                   (chunkACIs, chunkLayouts, rgns);
           }
  @@ -305,6 +302,7 @@
                   // This prevents BIDI reordering across paragraphs.
                   if (aci.getAttribute(FLOW_PARAGRAPH) != null) {
                       end = aci.getRunLimit(FLOW_PARAGRAPH);
  +                    // System.out.println("End: " + end);
                       aci.setIndex(end);
                       break;
                   }
  
  
  
  1.3       +27 -13    xml-batik/sources/org/apache/batik/gvt/text/GlyphIterator.java
  
  Index: GlyphIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/GlyphIterator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- GlyphIterator.java	3 Apr 2002 04:58:21 -0000	1.2
  +++ GlyphIterator.java	12 Apr 2002 14:36:48 -0000	1.3
  @@ -103,7 +103,8 @@
   
           this.numGlyphs   = gv.getNumGlyphs();
           this.gp          = gv.getGlyphPositions(0, this.numGlyphs+1, null);
  -        this.adv = this.adj = getCharAdvance();
  +        this.adv = getCharWidth();
  +        this.adj = getCharAdvance();
       }
   
       public GlyphIterator(GlyphIterator gi) {
  @@ -239,7 +240,8 @@
               // Special handling for soft hyphens and zero-width spaces
               gv.setGlyphVisible(idx, false);
               float chAdv = getCharAdvance();
  -            adv -= chAdv;
  +            float chW   = getCharWidth();
  +            adv -= chW;
               adj -= chAdv;
               if (leftShiftIdx == null) {
                   leftShiftIdx = new int[1];
  @@ -281,7 +283,8 @@
           adj += chAdv;
           if (isPrinting()) {
               chIdx = idx;
  -            adv = adj;
  +            float chW   = getCharWidth();
  +            adv = adj-(chAdv-chW);
           }
       }
   
  @@ -303,15 +306,6 @@
               gv.setGlyphVisible(idx, true);
           }
   
  -        // Tweak line advance to account for visual bounds of last 
  -        // printing glyph.
  -        Rectangle2D lcBound = gv.getGlyphVisualBounds(chIdx).getBounds2D();
  -        Point2D     lcLoc   = gv.getGlyphPosition(chIdx);
  -        float       charW   = (float)(lcBound.getX()+lcBound.getWidth()-
  -                                      lcLoc.getX());
  -        float charAdv = getCharAdvance(chIdx);
  -        adv -= charAdv-charW;
  -
           int lsi = 0;
           int nextLSI;
           if (leftShiftIdx != null) nextLSI = leftShiftIdx[lsi];
  @@ -329,7 +323,7 @@
           leftShiftAmt = null;
   
           return new LineInfo(aci, gv, lineIdx, idx+1, loc, adv, adj,
  -                            charW, lineWidth, partial);
  +                            getCharWidth(chIdx), lineWidth, partial);
       }
   
       public void newLine() {
  @@ -359,9 +353,29 @@
       }
   
       /**
  +     * Get the visual advance associated with the current glyph.
  +     * This is the distance from the location of the glyph to
  +     * the rightmost part of the glyph.
  +     */
  +    public float getCharWidth() {
  +        return getCharWidth(idx);
  +    }
  +
  +    /**
        * Get the advance associated with any glyph
        */
       protected float getCharAdvance(int gvIdx) {
           return gp[2*gvIdx+2] - gp[2*gvIdx];
  +    }
  +
  +    /**
  +     * Get the visual advance associated with the current glyph.
  +     * This is the distance from the location of the glyph to
  +     * the rightmost part of the glyph.
  +     */
  +    protected float getCharWidth(int gvIdx) {
  +        Rectangle2D lcBound = gv.getGlyphVisualBounds(chIdx).getBounds2D();
  +        Point2D     lcLoc   = gv.getGlyphPosition(chIdx);
  +        return (float)(lcBound.getX()+lcBound.getWidth()- lcLoc.getX());
       }
   }
  
  
  
  1.39      +114 -15   xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java
  
  Index: GlyphLayout.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- GlyphLayout.java	3 Apr 2002 04:58:21 -0000	1.38
  +++ GlyphLayout.java	12 Apr 2002 14:36:48 -0000	1.39
  @@ -47,7 +47,7 @@
    * @see org.apache.batik.gvt.text.TextSpanLayout
    *
    * @author <a href="bill.haneman@ireland.sun.com>Bill Haneman</a>
  - * @version $Id: GlyphLayout.java,v 1.38 2002/04/03 04:58:21 deweese Exp $
  + * @version $Id: GlyphLayout.java,v 1.39 2002/04/12 14:36:48 deweese Exp $
    */
   public class GlyphLayout implements TextSpanLayout {
   
  @@ -1803,6 +1803,27 @@
       //   Should dy be considered for line offsets? (super scripts)
       //   Should p's & br's carry over from flow rect to flow rect if
       //   so how much????
  +
  +    // In cases where 1/2 leading is negative (lineBox is smaller than
  +    // lineAscent+lineDescent) do we use the lineBox (some glyphs will
  +    // go outside flowRegion) or the visual box.  My feeling is that
  +    // we should use the larger of the two.
  +
  +    // We stated that for empty para elements it moves to the new flow
  +    // region if the zero-height line is outside the flow region.  In
  +    // this case the para elements top-margin is used in the new flow
  +    // region (and it's bottom-margin is collapsed with the next
  +    // flowPara element if any).  What happens when the first line of
  +    // a non-empty flowPara doesn't fit (so the top margin does fit
  +    // but the first line of text doesn't).  I think the para should
  +    // move to the next flow region and the top margin should apply in
  +    // the new flow region.  The top margin does not apply if
  +    // subsequint lines move to a new flow region.
  +
  +    // Note that line wrapping is done on visual bounds of glyph
  +    // not the glyph advance (which often includes some whitespace
  +    // after the right edge of the glyph char).
  +
       //
       //   How are Margins done?  Can't figure out Box size until
       //   after we know the margins.
  @@ -1818,8 +1839,14 @@
       //         bit as well as grow (pretty easy to add).
       //
       // This Only does horizontal languages.
  -    // text-decoration won't work on this text.
  -    // Soft hyphen isn't handled yet.
  +    // Supports Zero Width Spaces (0x200B) Zero Width Joiner( 0x200D), 
  +    // and soft hyphens (0x00AD).
  +    // 
  +    // Does not properly handle Bi-DI languages (does text wrapping on
  +    // display order not logical order).
  +    //
  +    // Does not drop leading non-printing chars on a line..
  +
       /**
        * This will wrap the text associated with <tt>aci</tt> and
        * <tt>layouts</tt>.
  @@ -1853,8 +1880,8 @@
           Iterator flowRectsIter = flowRects.iterator();
           // Get info for new flow rect.
           Rectangle2D cRect = (Rectangle2D)flowRectsIter.next();
  -        float y0     = (float)cRect.getY();
  -        float x0, width, height;
  +        float y0, x0, width, height;
  +        height = (float)cRect.getHeight();
   
           boolean lineHeightRelative = true;
           float lineHeight           = 1.0f;
  @@ -1873,11 +1900,29 @@
                       Iterator epi = extraP.iterator();
                       while (epi.hasNext()) {
                           MarginInfo emi = (MarginInfo)epi.next();
  -                        dy += ((prevBotMargin > emi.getTopMargin()) 
  -                               ? prevBotMargin 
  -                               : emi.getTopMargin());
  +                        float inc = ((prevBotMargin > emi.getTopMargin()) 
  +                                     ? prevBotMargin 
  +                                     : emi.getTopMargin());
  +                        if ((dy + inc <= height) &&
  +                            !emi.isFlowRegionBreak()) {
  +                            dy += inc;
  +                        } else {
  +                            // Move to next flow region..
  +                            if (!flowRectsIter.hasNext()) {
  +                                cRect = null;
  +                                break; // No flow rect stop layout here...
  +                            }
  +
  +                            cRect = (Rectangle2D)flowRectsIter.next();
  +                            height = (float)cRect.getHeight();
  +
  +                            // New rect so no previous row to consider...
  +                            dy        = emi.getTopMargin();
  +                        }
                           prevBotMargin = emi.getBottomMargin();
                       }
  +
  +                    if (cRect == null) break;
                   }
               }
               aci.first();
  @@ -1903,11 +1948,27 @@
                   continue;
               }
   
  -            dy += ((prevBotMargin > mi.getTopMargin()) ? 
  -                   prevBotMargin : mi.getTopMargin());
  +            float inc = ((prevBotMargin > mi.getTopMargin()) 
  +                         ? prevBotMargin : mi.getTopMargin());
  +            if (dy + inc <= height) {
  +                dy += inc;
  +            } else {
  +                // Move to next flow region..
  +                if (!flowRectsIter.hasNext()) {
  +                    cRect = null;
  +                    break; // No flow rect stop layout here...
  +                }
  +
  +                cRect = (Rectangle2D)flowRectsIter.next();
  +                height = (float)cRect.getHeight();
  +
  +                            // New rect so no previous row to consider...
  +                dy        = mi.getTopMargin();
  +            }
               prevBotMargin = mi.getBottomMargin();
   
               x0    = (float)cRect.getX() + mi.getLeftMargin();
  +            y0    = (float)cRect.getY();
               width = (float)(cRect.getWidth() - 
                               (mi.getLeftMargin()+mi.getRightMargin()));
               height = (float)cRect.getHeight();
  @@ -1918,13 +1979,36 @@
               GlyphIterator gi = new GlyphIterator(aci, gv);
               GlyphIterator breakGI  = null, newBreakGI = null;
               GlyphIterator lineGI   =  gi.copy();
  +            boolean firstLine = true;
               while (!gi.done()) {
                   boolean doBreak = false;
                   boolean partial = false;
   
  -                if (gi.isPrinting() &&
  -                    (breakGI != null) && // Don't break at first char in line
  -                    (gi.getAdv() > width)) {
  +                if (gi.isPrinting() && (gi.getAdv() > width)) {
  +                    if (breakGI == null) {
  +                        // first char on line didn't fit.
  +                        // move to next flow rect.
  +                        if (!flowRectsIter.hasNext()) {
  +                            cRect = null;
  +                            gi = lineGI.copy(gi);
  +                            break; // No flow rect stop layout here...
  +                        }
  +
  +                        cRect = (Rectangle2D)flowRectsIter.next();
  +                        x0    = (float) cRect.getX() + mi.getLeftMargin();
  +                        y0    = (float) cRect.getY();
  +                        width = (float)(cRect.getWidth() - 
  +                                        (mi.getLeftMargin()+
  +                                         mi.getRightMargin()));
  +                        height = (float)cRect.getHeight();
  +
  +                        // New rect so no previous row to consider...
  +                        dy        = firstLine?mi.getTopMargin():0; ;
  +                        prevDesc  = 0;
  +                        gi = lineGI.copy(gi);
  +                        continue;
  +                    }
  +
                       gi = breakGI.copy(gi);  // Back up to break loc...
   
                       nextLineMult = 1;
  @@ -1992,7 +2076,11 @@
                   float newDesc = halfLeading + gi.getMaxDescent();
   
                   dy += ladv;
  -                if ((dy + newDesc) > height)  {
  +                float bottomEdge = newDesc;
  +                if (newDesc < gi.getMaxDescent()) 
  +                    bottomEdge = gi.getMaxDescent();
  +
  +                if ((dy + bottomEdge) > height)  {
                       // The current Line doesn't fit in the
                       // current flow rectangle so we need to
                       // move line to the next flow rect.
  @@ -2017,7 +2105,7 @@
                       height = (float)cRect.getHeight();
   
                       // New rect so no previous row to consider...
  -                    dy        = 0; // mi.getTopMargin();
  +                    dy        = firstLine?mi.getTopMargin():0; ;
                       prevDesc  = 0;
                       // previous flows?
   
  @@ -2038,6 +2126,7 @@
                                  width,
                                  partial));
                   gi.newLine();
  +                firstLine = false;
                   // The line fits in the current flow rectangle.
                   lineGI  = gi.copy(lineGI);
                   breakGI = null;
  @@ -2049,6 +2138,16 @@
                   gv.setGlyphVisible(idx++, false);
   
               layoutChunk(aci, gv, justification, lineInfos);
  +
  +            if (mi.isFlowRegionBreak()) {
  +                // Move to next flow region..
  +                cRect = null;
  +                if (flowRectsIter.hasNext()) {
  +                    cRect  = (Rectangle2D)flowRectsIter.next();
  +                    height = (float)cRect.getHeight();
  +                    dy     = mi.getTopMargin();
  +                }
  +            }
           }
       }
   
  
  
  
  1.2       +15 -11    xml-batik/sources/org/apache/batik/gvt/text/MarginInfo.java
  
  Index: MarginInfo.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/MarginInfo.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MarginInfo.java	29 Mar 2002 20:00:55 -0000	1.1
  +++ MarginInfo.java	12 Apr 2002 14:36:48 -0000	1.2
  @@ -14,19 +14,22 @@
       public final static int JUSTIFY_END    = 2;
       public final static int JUSTIFY_FULL   = 3;
   
  -    protected float top;
  -    protected float right;
  -    protected float bottom;
  -    protected float left;
  -    protected int   justification;
  +    protected float   top;
  +    protected float   right;
  +    protected float   bottom;
  +    protected float   left;
  +    protected int     justification;
  +    protected boolean flowRegionBreak;
  +
   
       public MarginInfo(float top, float right, float bottom, float left,
  -                      int justification) {
  +                      int justification, boolean flowRegionBreak) {
           this.top    = top;
           this.right  = right;
           this.bottom = bottom;
           this.left   = left;
           this.justification = justification;
  +        this.flowRegionBreak = flowRegionBreak;
       }
   
       public MarginInfo(float margin, int justification) {
  @@ -39,9 +42,10 @@
           this.bottom = margin;
           this.left   = margin;
       }
  -    public float getTopMargin()     { return top; }
  -    public float getRightMargin()   { return right; }
  -    public float getBottomMargin()  { return bottom; }
  -    public float getLeftMargin()    { return left; }
  -    public int   getJustification() { return justification; }
  +    public float   getTopMargin()      { return top; }
  +    public float   getRightMargin()    { return right; }
  +    public float   getBottomMargin()   { return bottom; }
  +    public float   getLeftMargin()     { return left; }
  +    public int     getJustification()  { return justification; }
  +    public boolean isFlowRegionBreak() { return flowRegionBreak; }
   }
  
  
  

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