/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

package org.apache.batik.gvt.renderer;

import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.CharacterIterator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.TextPainter;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.gvt.font.GVTFont;
import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.font.GVTGlyphMetrics;
import org.apache.batik.gvt.font.GVTLineMetrics;
import org.apache.batik.gvt.text.AttributedCharacterSpanIterator;
import org.apache.batik.gvt.text.BidiAttributedCharacterIterator;
import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
import org.apache.batik.gvt.text.Mark;
import org.apache.batik.gvt.text.TextHit;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextPath;
import org.apache.batik.gvt.text.TextSpanLayout;


/**
 * More sophisticated implementation of TextPainter which
 * renders the attributed character iterator of a <code>TextNode</code>.
 * <em>StrokingTextPainter includes support for stroke, fill, opacity,
 * text-decoration, and other attributes.</em>
 *
 * @see org.apache.batik.gvt.TextPainter
 * @see org.apache.batik.gvt.text.GVTAttributedCharacterIterator
 *
 * @author <a href="mailto:bill.haneman@ireland.sun.com">Bill Haneman</a>
 * @version $Id$
 */
public class StrokingTextPainter extends BasicTextPainter {

    public static final
        AttributedCharacterIterator.Attribute PAINT_INFO =
        GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO;

    public static final
        AttributedCharacterIterator.Attribute FLOW_REGIONS =
        GVTAttributedCharacterIterator.TextAttribute.FLOW_REGIONS;

    public static final
        AttributedCharacterIterator.Attribute FLOW_PARAGRAPH =
        GVTAttributedCharacterIterator.TextAttribute.FLOW_PARAGRAPH;

    public static final
        AttributedCharacterIterator.Attribute TEXT_COMPOUND_ID
        = GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_ID;

    public static final
        AttributedCharacterIterator.Attribute GVT_FONT
        = GVTAttributedCharacterIterator.TextAttribute.GVT_FONT;

    public static final
        AttributedCharacterIterator.Attribute GVT_FONTS
        = GVTAttributedCharacterIterator.TextAttribute.GVT_FONTS;

    public static final
        AttributedCharacterIterator.Attribute BIDI_LEVEL
        = GVTAttributedCharacterIterator.TextAttribute.BIDI_LEVEL;

    public static final
        AttributedCharacterIterator.Attribute XPOS
        = GVTAttributedCharacterIterator.TextAttribute.X;

    public static final
        AttributedCharacterIterator.Attribute YPOS
        = GVTAttributedCharacterIterator.TextAttribute.Y;

    public static final
        AttributedCharacterIterator.Attribute TEXTPATH
        = GVTAttributedCharacterIterator.TextAttribute.TEXTPATH;


    public static final AttributedCharacterIterator.Attribute WRITING_MODE
        = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE;

    public static final Integer WRITING_MODE_TTB
        = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_TTB;

    public static final Integer WRITING_MODE_RTL
        = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_RTL;

    public static final
        AttributedCharacterIterator.Attribute ANCHOR_TYPE
        = GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE;

    public static final Integer ADJUST_SPACING =
        GVTAttributedCharacterIterator.TextAttribute.ADJUST_SPACING;
    public static final Integer ADJUST_ALL =
        GVTAttributedCharacterIterator.TextAttribute.ADJUST_ALL;
    public static final GVTAttributedCharacterIterator.TextAttribute ALT_GLYPH_HANDLER =
        GVTAttributedCharacterIterator.TextAttribute.ALT_GLYPH_HANDLER;

    static Set extendedAtts = new HashSet();

    static {
        extendedAtts.add(FLOW_PARAGRAPH);
        extendedAtts.add(TEXT_COMPOUND_ID);
        extendedAtts.add(GVT_FONT);
        // extendedAtts.add(BIDI_LEVEL);
    }

    /**
     * A unique instance of this class.
     */
    protected static TextPainter singleton = new StrokingTextPainter();

    /**
     * Returns a unique instance of this class.
     */
    public static TextPainter getInstance() {
        return singleton;
    }

    /**
     * Paints the specified text node using the specified Graphics2D.
     *
     * @param node the text node to paint
     * @param g2d the Graphics2D to use
     */
    public void paint(TextNode node, Graphics2D g2d) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return;

        List textRuns = getTextRuns(node, aci);

        // draw the underline and overline first, then the actual text
        // and finally the strikethrough
        paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_UNDERLINE);
        paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_OVERLINE);
        paintTextRuns(textRuns, g2d);
        paintDecorations
            (textRuns, g2d, TextSpanLayout.DECORATION_STRIKETHROUGH);
    }

    protected void printAttrs(AttributedCharacterIterator aci) {
        aci.first();
        int start = aci.getBeginIndex();
        System.out.print("AttrRuns: ");
        while (aci.current() != CharacterIterator.DONE) {
            int end   = aci.getRunLimit();
            System.out.print(""+(end-start)+", ");
            aci.setIndex(end);
            start = end;
        }
        System.out.println("");
    }

    // static long reorderTime, fontMatchingTime, layoutTime;
    public List getTextRuns(TextNode node, AttributedCharacterIterator aci) {
        List textRuns = node.getTextRuns();
        if (textRuns != null) {
            return textRuns;
        }

        AttributedCharacterIterator[] chunkACIs = getTextChunkACIs(aci);
        textRuns = computeTextRuns(node, aci, chunkACIs);

        // t1 = System.currentTimeMillis();
        // layoutTime += t1-t0;
        // System.out.println("Reorder: " + reorderTime + " FontMatching: " + fontMatchingTime + " Layout: " + layoutTime);
        // cache the textRuns so don't need to recalculate
        node.setTextRuns(textRuns);
        return node.getTextRuns();
   }

    public List computeTextRuns(TextNode node,
                                AttributedCharacterIterator aci,
                                AttributedCharacterIterator [] chunkACIs) {
        int [][] chunkCharMaps = new int[chunkACIs.length][];

        // long t0, t1;
        // t0 = System.currentTimeMillis();
        // reorder each chunk ACI for bidi text
        int chunkStart = aci.getBeginIndex();
        for (int i = 0; i < chunkACIs.length; i++) {
            BidiAttributedCharacterIterator iter;
            iter = new BidiAttributedCharacterIterator
                (chunkACIs[i], fontRenderContext, chunkStart);
            chunkACIs    [i] = iter;
            chunkCharMaps[i] = iter.getCharMap();
            // t1 = System.currentTimeMillis();
            // reorderTime += t1-t0;
            // t0=t1;
            chunkACIs    [i] = createModifiedACIForFontMatching
                (chunkACIs[i]);

            chunkStart += (chunkACIs[i].getEndIndex()-
                           chunkACIs[i].getBeginIndex());
            // t1 = System.currentTimeMillis();
            // fontMatchingTime += t1-t0;
            // t0 = t1;
        }

        // create text runs for each chunk and add them to the list
        List textRuns = new ArrayList();
        TextChunk chunk, prevChunk=null;
        int currentChunk = 0;

        Point2D location = node.getLocation();
        do {
            // Text Chunks contain one or more TextRuns, which they
            // create from the ACI.
            chunkACIs[currentChunk].first();

            chunk = getTextChunk(node,
                                 chunkACIs[currentChunk],
                                 chunkCharMaps[currentChunk],
                                 textRuns,
                                 prevChunk);

            // Adjust according to text-anchor property value
            chunkACIs[currentChunk].first();
            if (chunk != null) {
                location = adjustChunkOffsets(location, textRuns, chunk);
            }
            prevChunk = chunk;
            currentChunk++;

        } while (chunk != null && currentChunk < chunkACIs.length);

        return textRuns;
    }

    /**
     * Returns an array of ACIs, one for each text chunk within the given
     * text node.
     */
    protected AttributedCharacterIterator[] getTextChunkACIs
        (AttributedCharacterIterator aci) {

        List aciList = new ArrayList();
        int chunkStartIndex = aci.getBeginIndex();
        aci.first();
        Object writingMode = aci.getAttribute(WRITING_MODE);
        boolean vertical = (writingMode == WRITING_MODE_TTB);

        while (aci.setIndex(chunkStartIndex) != CharacterIterator.DONE) {
            TextPath prevTextPath = null;
            for (int start=chunkStartIndex, end=0;
                 aci.setIndex(start) != CharacterIterator.DONE; start=end) {

                TextPath textPath = (TextPath) aci.getAttribute(TEXTPATH);

                if (start != chunkStartIndex) {
                    // If we aren't the first composite in a chunck see
                    // if we need to form a new TextChunk...
                    // We only create new chunks when given an absolute
                    // location in progression direction [Spec says
                    // to do it for either but this doesn't make sense].
                    if (vertical) {
                        Float runY = (Float) aci.getAttribute(YPOS);
                        // Check for absolute location in layout direction.
                        if ((runY != null) && !runY.isNaN())
                            break; // If so end of chunk...
                    } else {
                        Float runX = (Float) aci.getAttribute(XPOS);
                        // Check for absolute location in layout direction.
                        if ((runX != null) && !runX.isNaN())
                            break; // If so end of chunk...
                    }

                    // Do additional check for the start of a textPath
                    if ((prevTextPath == null) && (textPath != null))
                        break;  // If so end of chunk.

                    // Form a new chunk at the end of a text path.
                    // [ This is not mentioned in the spec but makes
                    //   sense].
                    if ((prevTextPath != null) && (textPath == null))
                        break;
                }

                prevTextPath = textPath;

                // We need to text chunk based on flow paragraphs.
                // 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;
                }

                // find end of compound.
                end   = aci.getRunLimit(TEXT_COMPOUND_ID);

                if (start != chunkStartIndex)
                    // If we aren't starting a new chunk then we know
                    // we don't have any absolute positioning so there
                    // is no reason to consider spliting the chunk further.
                    continue;

                // We are starting a new chunk
                // So check if we need to split it further...
                TextNode.Anchor anchor;
                anchor = (TextNode.Anchor) aci.getAttribute(ANCHOR_TYPE);
                if (anchor == TextNode.Anchor.START)
                    continue;

                // We need to check if we have a list of X's & Y's if
                // so we need to create TextChunk ACI's for each char
                // (technically we have to do this for
                // text-anchor:start as well but since that is the
                // default layout it doesn't matter in that case.
                if (vertical) {
                    Float runY = (Float) aci.getAttribute(YPOS);
                    // Check for absolute location in layout direction.
                    if ((runY == null) || runY.isNaN())
                        // No absolute positioning in text direction continue
                        continue;
                } else {
                    Float runX = (Float) aci.getAttribute(XPOS);
                    // Check for absolute location in layout direction.
                    if ((runX == null) || runX.isNaN())
                        // No absolute positioning in text direction continue
                        continue;
                }

                // Splitting the compound into one char chunks until
                // we run out of Xs.
                for (int i=start+1; i< end; i++) {
                    aci.setIndex(i);
                    if (vertical) {
                        Float runY = (Float) aci.getAttribute(YPOS);
                        if ((runY == null) || runY.isNaN())
                            break;
                    } else {
                        Float runX = (Float) aci.getAttribute(XPOS);
                        if ((runX == null) || runX.isNaN())
                            break;
                    }
                    aciList.add(new AttributedCharacterSpanIterator
                        (aci, i-1, i));
                    chunkStartIndex = i;
                }
            }

            // found the end of a text chunck
            int chunkEndIndex = aci.getIndex();
            // System.out.println("Bounds: " + chunkStartIndex +
            //                    "," + chunkEndIndex);
            aciList.add(new AttributedCharacterSpanIterator
                (aci, chunkStartIndex, chunkEndIndex));

            chunkStartIndex = chunkEndIndex;
        }

        // copy the text chunks into an array
        AttributedCharacterIterator[] aciArray =
            new AttributedCharacterIterator[aciList.size()];
        Iterator iter = aciList.iterator();
        for (int i=0; iter.hasNext(); ++i) {
            aciArray[i] = (AttributedCharacterIterator)iter.next();
        }
        return aciArray;
    }

    /**
     * Returns a new AttributedCharacterIterator that contains resolved GVTFont
     * attributes. This is then used when creating the text runs so that the
     * text can be split on changes of font as well as tspans and trefs.
     *
     * @param aci The aci to be modified should already be split into
     *            text chunks.
     *
     * @return The new modified aci.
     */
    protected AttributedCharacterIterator createModifiedACIForFontMatching
        (AttributedCharacterIterator aci) {

        aci.first();
        AttributedString as = null;
        int asOff = 0;
        int begin = aci.getBeginIndex();
        boolean moreChunks = true;
        int start, end   = aci.getRunStart(TEXT_COMPOUND_ID);
        while (moreChunks) {
            start = end;
            end = aci.getRunLimit(TEXT_COMPOUND_ID);
            int aciLength = end-start;

            List fonts;
            fonts = (List)aci.getAttribute(GVT_FONTS);


            float fontSize = 12;
            Float fsFloat = (Float)aci.getAttribute(TextAttribute.SIZE);
            if (fsFloat != null)
                fontSize = fsFloat.floatValue();

            // if could not resolve at least one of the fontFamilies
            // then use the default font
            if (fonts.size() == 0) {
                // create a list of fonts of the correct size
                fonts.add(getFontFamilyResolver().getDefault().deriveFont(fontSize, aci));
            }

            // now for each char or group of chars in the string,
            // find a font that can display it.
            boolean[] fontAssigned = new boolean[aciLength];

            if (as == null)
                as = new AttributedString(aci);

            GVTFont defaultFont = null;
            int numSet=0;
            int firstUnset=start;
            boolean firstUnsetSet;
            for (int i = 0; i < fonts.size(); i++) {
                // assign this font to all characters it can display if it has
                // not already been assigned
                int currentIndex = firstUnset;
                firstUnsetSet = false;
                aci.setIndex(currentIndex);

                GVTFont font = (GVTFont)fonts.get(i);
                if (defaultFont == null)
                    defaultFont = font;

                while (currentIndex < end) {
                    int displayUpToIndex = font.canDisplayUpTo
                        (aci, currentIndex, end);

                    Object altGlyphElement;
                    altGlyphElement = aci.getAttribute(ALT_GLYPH_HANDLER);
                    if ( altGlyphElement != null ){
                        //found all the glyph to be displayed
                        //consider the font matching done
                        displayUpToIndex = -1;
                    }

                    if (displayUpToIndex == -1) {
                        // Can handle the whole thing...
                        displayUpToIndex = end;
                    }

                    if (displayUpToIndex <= currentIndex) {
                        if (!firstUnsetSet) {
                            firstUnset = currentIndex;
                            firstUnsetSet = true;
                        }
                        // couldn't display the current char
                        currentIndex++;
                    } else {
                        // could display some text, so for each
                        // char it can display, if char not already
                        // assigned a font, assign this font to it
                        int runStart = -1;
                        for (int j = currentIndex; j < displayUpToIndex; j++) {
                            if (fontAssigned[j - start]) {
                                if (runStart != -1) {
                                    // System.out.println("Font 1: " + font);
                                    as.addAttribute(GVT_FONT, font,
                                                    runStart-begin, j-begin);
                                    runStart=-1;
                                }
                            } else {
                                if (runStart == -1)
                                    runStart = j;
                            }
                            fontAssigned[j - start] = true;
                            numSet++;
                        }
                        if (runStart != -1) {
                            // System.out.println("Font 2: " + font);
                            as.addAttribute(GVT_FONT, font,
                                            runStart-begin,
                                            displayUpToIndex-begin);
                        }

                        // set currentIndex to be one after the char
                        // that couldn't display
                        currentIndex = displayUpToIndex+1;
                    }
                }

                if (numSet == aciLength) // all chars have font set;
                    break;
            }

            // assign the first font to any chars haven't alreay been assigned
            int           runStart = -1;
            GVTFontFamily prevFF   = null;
            GVTFont       prevF    = defaultFont;
            for (int i = 0; i < aciLength; i++) {
                if (fontAssigned[i]) {
                    if (runStart != -1) {
                        // System.out.println("Font 3: " + prevF);
                        as.addAttribute(GVT_FONT, prevF,
                                        runStart+asOff, i+asOff);
                        runStart = -1;
                        prevF  = null;
                        prevFF = null;
                    }
                } else {
                    char c = aci.setIndex(start+i);
                    GVTFontFamily fontFamily;
                    fontFamily = getFontFamilyResolver().getFamilyThatCanDisplay(c);
                    // fontFamily = (GVTFontFamily)resolvedFontFamilies.get(0);

                    if (runStart == -1) {
                        // Starting a new run...
                        runStart = i;
                        prevFF   = fontFamily;
                        if (prevFF == null)
                            prevF = defaultFont;
                        else
                            prevF = fontFamily.deriveFont(fontSize, aci);
                    } else if (prevFF != fontFamily) {
                        // Font family changed...
                        // System.out.println("Font 4: " + prevF);
                        as.addAttribute(GVT_FONT, prevF,
                                        runStart+asOff, i+asOff);

                        runStart = i;
                        prevFF = fontFamily;
                        if (prevFF == null)
                            prevF = defaultFont;
                        else
                            prevF = fontFamily.deriveFont(fontSize, aci);
                    }
                }
            }
            if (runStart != -1) {
                // System.out.println("Font 5: " + prevF);
                as.addAttribute(GVT_FONT, prevF,
                                runStart+asOff, aciLength+asOff);
            }

            asOff += aciLength;
            if (aci.setIndex(end) == AttributedCharacterIterator.DONE) {
                moreChunks = false;
            }
            start = end;
        }
        if (as != null)
            return as.getIterator();

        // Didn't do anything return original ACI
        return aci;
    }

    protected FontFamilyResolver getFontFamilyResolver() {
        return DefaultFontFamilyResolver.SINGLETON;
    }

    protected TextChunk getTextChunk(TextNode node,
                                     AttributedCharacterIterator aci,
                                     int [] charMap,
                                     List textRuns,
                                     TextChunk prevChunk) {
        int beginChunk = 0;
        if (prevChunk != null)
            beginChunk = prevChunk.end;
        int endChunk = beginChunk;
        int begin    = aci.getIndex();
        // System.out.println("New Chunk");
        if (aci.current() == CharacterIterator.DONE)
            return null;

        // we now lay all aci's out at 0,0 then move them
        // when we adjust the chunk offsets.
        Point2D.Float offset        = new Point2D.Float(0,0);
        Point2D.Float advance       = new Point2D.Float(0,0);
        boolean isChunkStart  = true;
        TextSpanLayout layout = null;
        do {
            int start = aci.getRunStart(extendedAtts);
            int end   = aci.getRunLimit(extendedAtts);

            AttributedCharacterIterator runaci;
            runaci = new AttributedCharacterSpanIterator(aci, start, end);

            int [] subCharMap = new int[end-start];
            System.arraycopy( charMap, start - begin, subCharMap, 0, subCharMap.length );

            FontRenderContext frc = fontRenderContext;
            RenderingHints rh = node.getRenderingHints();
            // Check for optimizeSpeed, optimizeLegibility
            // in these cases setup hintedFRC
            if ((rh != null) &&
                (rh.get(RenderingHints.KEY_TEXT_ANTIALIASING) ==
                  RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
                // In both these cases we want the non-antialiased
                // font render context.
                frc = aaOffFontRenderContext;
            }

            layout = getTextLayoutFactory().createTextLayout
                (runaci, subCharMap, offset, frc);

            textRuns.add(new TextRun(layout, runaci, isChunkStart));
            // System.out.println("TextRun: " + start +  "->" + end +
            //                    " Start: " + isChunkStart);

            Point2D layoutAdvance = layout.getAdvance2D();
            // System.out.println("layoutAdv: " + layoutAdvance);
            advance.x +=  (float)layoutAdvance.getX();
            advance.y +=  (float)layoutAdvance.getY();

            ++endChunk;
            if (aci.setIndex(end) == CharacterIterator.DONE) break;
            isChunkStart = false;
        } while (true);

        // System.out.println("Adv: " + advance);
        // System.out.println("Chunks: [" + beginChunk + ", " +
        //                    endChunk + "]");
        return new TextChunk(beginChunk, endChunk, advance);
    }



    /**
     * Adjusts the position of the text runs within the specified text chunk
     * to account for any text anchor properties.
     */
    protected Point2D adjustChunkOffsets(Point2D location,
                                         List textRuns,
                                         TextChunk chunk) {
        TextRun r          = (TextRun) textRuns.get(chunk.begin);
        int     anchorType = r.getAnchorType();
        Float   length     = r.getLength();
        Integer lengthAdj  = r.getLengthAdjust();

        boolean doAdjust = true;
        if ((length == null) || length.isNaN())
            doAdjust = false;

        int numChars = 0;
        for (int n=chunk.begin; n<chunk.end; ++n) {
            r = (TextRun) textRuns.get(n);
            AttributedCharacterIterator aci = r.getACI();
            numChars += aci.getEndIndex()-aci.getBeginIndex();
        }
        if ((lengthAdj ==
             GVTAttributedCharacterIterator.TextAttribute.ADJUST_SPACING) &&
            (numChars == 1))
            doAdjust = false;

        float xScale = 1;
        float yScale = 1;

        r = (TextRun)textRuns.get(chunk.end-1);
        TextSpanLayout  layout          = r.getLayout();
        GVTGlyphMetrics lastMetrics =
            layout.getGlyphMetrics(layout.getGlyphCount()-1);
        GVTLineMetrics  lastLineMetrics = layout.getLineMetrics();
        Rectangle2D     lastBounds  = lastMetrics.getBounds2D();
        float halfLeading = (lastMetrics.getVerticalAdvance()-
                               (lastLineMetrics.getAscent() +
                                lastLineMetrics.getDescent()))/2;
        float lastW = (float)(lastBounds.getWidth()  + lastBounds.getX());
        float lastH = (float)(halfLeading + lastLineMetrics.getAscent() +
                              (lastBounds.getHeight() + lastBounds.getY()));
        Point2D visualAdvance;

        if (!doAdjust) {
            // System.err.println("Anchor: " + anchorType);
            // System.err.println("Advance: " + chunk.advance);
            // System.err.println("LastBounds: " + lastBounds);
            // System.err.println("LastMetrics.hadv: " +
            //                    lastMetrics.getHorizontalAdvance());
            // System.err.println("LastMetrics.vadv: " +
            //                    lastMetrics.getVerticalAdvance());

            visualAdvance = new Point2D.Float
            ((float)(chunk.advance.getX() + lastW -
                     lastMetrics.getHorizontalAdvance()),
             (float)(chunk.advance.getY() - lastMetrics.getVerticalAdvance() +
                     lastH));
        } else {
            Point2D advance    = chunk.advance;

            // We have to do this here since textLength needs to be
            // handled at the text chunk level. Otherwise tspans get
            // messed up.
            if (layout.isVertical()) {
                if (lengthAdj == ADJUST_SPACING) {
                    yScale = (float)
                        ((length.floatValue()-lastH)/
                         (advance.getY()-lastMetrics.getVerticalAdvance()));
                } else {
                    double adv =(advance.getY()-
                                 lastMetrics.getVerticalAdvance() + lastH);
                    yScale = (float)(length.floatValue()/adv);
                }
                visualAdvance = new Point2D.Float(0, length.floatValue());
            } else {
                if (lengthAdj == ADJUST_SPACING) {
                    xScale = (float)
                        ((length.floatValue()-lastW)/
                         (advance.getX()-lastMetrics.getHorizontalAdvance()));
                } else {
                    double adv = (advance.getX() + lastW -
                                  lastMetrics.getHorizontalAdvance());
                    xScale = (float)(length.floatValue()/adv);
                }
                visualAdvance = new Point2D.Float(length.floatValue(), 0);
            }

            // System.out.println("Adv: " + advance + " Len: " + length +
            //                    " scale: [" + xScale + ", " + yScale + "]");
            Point2D.Float adv = new Point2D.Float(0,0);
            for (int n=chunk.begin; n<chunk.end; ++n) {
                r = (TextRun) textRuns.get(n);
                layout = r.getLayout();
                layout.setScale(xScale, yScale, lengthAdj==ADJUST_SPACING);
                Point2D lAdv = layout.getAdvance2D();
                adv.x += (float)lAdv.getX();
                adv.y += (float)lAdv.getY();
            }
            chunk.advance = adv;
        }

        float dx = 0f;
        float dy = 0f;
        switch(anchorType){
        case TextNode.Anchor.ANCHOR_MIDDLE:
            dx = (float) (-visualAdvance.getX()/2d);
            dy = (float) (-visualAdvance.getY()/2d);
            break;
        case TextNode.Anchor.ANCHOR_END:
            dx = (float) (-visualAdvance.getX());
            dy = (float) (-visualAdvance.getY());
            break;
        default:
            break;
            // leave untouched
        }

        // System.out.println("DX/DY: [" + dx + ", " + dy + "]");

        r = (TextRun) textRuns.get(chunk.begin);
        layout = r.getLayout();
        AttributedCharacterIterator runaci = r.getACI();
        runaci.first();
        boolean vertical = layout.isVertical();
        Float runX = (Float) runaci.getAttribute(XPOS);
        Float runY = (Float) runaci.getAttribute(YPOS);
        TextPath textPath =  (TextPath) runaci.getAttribute(TEXTPATH);

        // The point that the next peice of normal text should be
        // layed out from, only used for normal text not text on a path.
        float absX = (float)location.getX();
        float absY = (float)location.getY();
        // TextPath Shift used to account for startOffset.
        float tpShiftX = 0;
        float tpShiftY = 0;

        // Of course X and Y override that, but they don't apply for
        // text on a path.
        if ((runX != null) && (!runX.isNaN())) {
            absX = runX.floatValue();
            tpShiftX = absX;
        }

        if ((runY != null) && (!runY.isNaN())) {
            absY = runY.floatValue();
            tpShiftY = absY;
        }

        // Factor in text-anchor in writing direction.
        // Ignore tpShift in non-writing direction.
        if (vertical) {
            absY     += dy;
            tpShiftY += dy;
            tpShiftX  = 0;
        } else {
            absX     += dx;
            tpShiftX += dx;
            tpShiftY  = 0;
        }

        // System.out.println("ABS: [" + absX + "," + absY + "," +
        //                    visualAdvance.getX() + "," +
        //                    visualAdvance.getY() + "]");
        for (int n=chunk.begin; n<chunk.end; ++n) {
            r = (TextRun) textRuns.get(n);
            layout = r.getLayout();
            runaci = r.getACI();
            runaci.first();
            textPath =  (TextPath) runaci.getAttribute(TEXTPATH);
            if (vertical) {
                runX = (Float) runaci.getAttribute(XPOS);
                if ((runX != null) && (!runX.isNaN())) {
                    absX = runX.floatValue();
                }
            } else {
                runY = (Float) runaci.getAttribute(YPOS);
                if ((runY != null) && (!runY.isNaN())) {
                    absY = runY.floatValue();
                }
            }

            if (textPath == null) {
                layout.setOffset(new Point2D.Float(absX, absY));

                Point2D ladv = layout.getAdvance2D();
                absX += ladv.getX();
                absY += ladv.getY();
            } else {
                layout.setOffset(new Point2D.Float(tpShiftX, tpShiftY));

                Point2D ladv = layout.getAdvance2D();
                tpShiftX += (float)ladv.getX();
                tpShiftY += (float)ladv.getY();

                ladv = layout.getTextPathAdvance();
                absX = (float)ladv.getX();
                absY = (float)ladv.getY();
            }
        }
        return new Point2D.Float(absX, absY);
    }

    /**
     * Paints decorations of the specified type.
     */
    protected void paintDecorations(List textRuns,
                                  Graphics2D g2d,
                                  int decorationType) {
        Paint prevPaint = null;
        Paint prevStrokePaint = null;
        Stroke prevStroke = null;
        boolean prevVisible = true;
        Rectangle2D decorationRect = null;
        double yLoc = 0, height = 0;

        for (int i = 0; i < textRuns.size(); i++) {
            TextRun textRun = (TextRun)textRuns.get(i);
            AttributedCharacterIterator runaci = textRun.getACI();
            runaci.first();

            Paint  paint       = null;
            Stroke stroke      = null;
            Paint  strokePaint = null;
            boolean visible    = true;
            TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
            if (tpi != null) {
                visible = tpi.visible;
                if (tpi.composite != null) {
                    g2d.setComposite(tpi.composite);
                }
                switch (decorationType) {
                case TextSpanLayout.DECORATION_UNDERLINE :
                    paint       = tpi.underlinePaint;
                    stroke      = tpi.underlineStroke;
                    strokePaint = tpi.underlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_OVERLINE :
                    paint       = tpi.overlinePaint;
                    stroke      = tpi.overlineStroke;
                    strokePaint = tpi.overlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_STRIKETHROUGH :
                    paint       = tpi.strikethroughPaint;
                    stroke      = tpi.strikethroughStroke;
                    strokePaint = tpi.strikethroughStrokePaint;
                    break;
                default:
                    // should never get here
                    return;
                }
            }

            if (textRun.isFirstRunInChunk()) {
                Shape s = textRun.getLayout().getDecorationOutline
                    (decorationType);
                Rectangle2D r2d = s.getBounds2D();
                yLoc   = r2d.getY();
                height = r2d.getHeight();
            }

            if (textRun.isFirstRunInChunk() ||
                (paint != prevPaint) ||
                (stroke != prevStroke) ||
                (strokePaint != prevStrokePaint) ||
                (visible != prevVisible)) {
                // if there is a current visible decoration, draw it now
                if (prevVisible && (decorationRect != null)) {
                    if (prevPaint != null) {
                        // fill the decoration
                        g2d.setPaint(prevPaint);
                        g2d.fill(decorationRect);
                    }
                    if (prevStroke != null && prevStrokePaint != null) {
                        // stroke the decoration
                        g2d.setPaint(prevStrokePaint);
                        g2d.setStroke(prevStroke);
                        g2d.draw(decorationRect);
                    }
                }
                decorationRect = null;
            }

            if ((paint != null || strokePaint != null)
                && !textRun.getLayout().isVertical()
                && !textRun.getLayout().isOnATextPath()) {

                // this text run should be decorated with the
                // specified decoration type
                // NOTE: decorations are only supported for plain
                // horizontal layouts

                Shape decorationShape =
                    textRun.getLayout().getDecorationOutline(decorationType);
                if (decorationRect == null) {
                    // create a new one
                    Rectangle2D r2d = decorationShape.getBounds2D();
                    decorationRect = new Rectangle2D.Double
                        (r2d.getX(), yLoc, r2d.getWidth(), height);
                } else {
                    // extend the current one
                    Rectangle2D bounds = decorationShape.getBounds2D();
                    double minX = Math.min(decorationRect.getX(),
                                           bounds.getX());
                    double maxX = Math.max(decorationRect.getMaxX(),
                                           bounds.getMaxX());
                    decorationRect.setRect(minX, yLoc, maxX-minX, height);
                }
            }
            prevPaint = paint;
            prevStroke = stroke;
            prevStrokePaint = strokePaint;
            prevVisible = visible;
        }

        // if there is a decoration rect that hasn't been drawn yet and
        // the text paint info says the test is visible, draw it now.
        if (prevVisible && (decorationRect != null)) {
            if (prevPaint != null) {
                // fill the decoration
                g2d.setPaint(prevPaint);
                g2d.fill(decorationRect);
            }
            if (prevStroke != null && prevStrokePaint != null) {
                // stroke the decoration
                g2d.setPaint(prevStrokePaint);
                g2d.setStroke(prevStroke);
                g2d.draw(decorationRect);
            }
        }
    }


    /**
     * Paints the text in each text run. Decorations are not painted here.
     */
    protected void paintTextRuns(List textRuns,
                               Graphics2D g2d) {
        for (int i = 0; i < textRuns.size(); i++) {
            TextRun textRun = (TextRun)textRuns.get(i);
            AttributedCharacterIterator runaci = textRun.getACI();
            runaci.first();

            TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
            if ((tpi != null) && (tpi.composite != null)) {
                g2d.setComposite(tpi.composite);
            }
            textRun.getLayout().draw(g2d);
        }
    }

    /**
     * Get a Shape in userspace coords which defines the textnode glyph outlines.
     * @param node the TextNode to measure
     */
    public Shape getOutline(TextNode node) {

        GeneralPath outline = null;
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        // get the list of text runs
        List textRuns = getTextRuns(node, aci);

        // for each text run, get its outline and append it to the overall
        // outline

        for (int i = 0; i < textRuns.size(); ++i) {
            TextRun textRun = (TextRun)textRuns.get(i);
            TextSpanLayout textRunLayout = textRun.getLayout();
            GeneralPath textRunOutline =
                new GeneralPath(textRunLayout.getOutline());

            if (outline == null) {
               outline = textRunOutline;
            } else {
                outline.setWindingRule(GeneralPath.WIND_NON_ZERO);
                outline.append(textRunOutline, false);
            }
        }

        // append any decoration outlines
        Shape underline = getDecorationOutline
            (textRuns, TextSpanLayout.DECORATION_UNDERLINE);

        Shape strikeThrough = getDecorationOutline
            (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH);

        Shape overline = getDecorationOutline
            (textRuns, TextSpanLayout.DECORATION_OVERLINE);

        if (underline != null) {
            if (outline == null) {
                outline = new GeneralPath(underline);
            } else {
                outline.setWindingRule(GeneralPath.WIND_NON_ZERO);
                outline.append(underline, false);
            }
        }
        if (strikeThrough != null) {
            if (outline == null) {
                outline = new GeneralPath(strikeThrough);
            } else {
                outline.setWindingRule(GeneralPath.WIND_NON_ZERO);
                outline.append(strikeThrough, false);
            }
        }
        if (overline != null) {
            if (outline == null) {
                outline = new GeneralPath(overline);
            } else {
                outline.setWindingRule(GeneralPath.WIND_NON_ZERO);
                outline.append(overline, false);
            }
        }

        return outline;
    }


    /**
     * Get a Rectangle2D in userspace coords which encloses the textnode
     * glyphs including stroke etc.
     */
     public Rectangle2D getBounds2D(TextNode node) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        // get the list of text runs
        List textRuns = getTextRuns(node, aci);

        Rectangle2D bounds = null;
        // for each text run, get its stroke outline and append it to
        // the overall outline
        for (int i = 0; i < textRuns.size(); ++i) {
            TextRun textRun = (TextRun)textRuns.get(i);
            TextSpanLayout textRunLayout = textRun.getLayout();
            Rectangle2D runBounds = textRunLayout.getBounds2D();
            if (runBounds != null) {
                if (bounds == null)
                    bounds = runBounds;
                else
                    //bounds = bounds.createUnion(runBounds);
                    bounds.add( runBounds );
            }
        }


        // append any stroked decoration outlines
        Shape underline = getDecorationStrokeOutline
            (textRuns, TextSpanLayout.DECORATION_UNDERLINE);

        if (underline != null) {
            if (bounds == null)
                bounds = underline.getBounds2D();
            else
                //bounds = bounds.createUnion(underline.getBounds2D());
                bounds.add( underline.getBounds2D() );
        }

        Shape strikeThrough = getDecorationStrokeOutline
            (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH);
        if (strikeThrough != null) {
            if (bounds == null)
                bounds = strikeThrough.getBounds2D();
            else
                //bounds = bounds.createUnion(strikeThrough.getBounds2D());
                bounds.add( strikeThrough.getBounds2D() );
        }

        Shape overline = getDecorationStrokeOutline
            (textRuns, TextSpanLayout.DECORATION_OVERLINE);
        if (overline != null) {
            if (bounds == null)
                bounds = overline.getBounds2D();
            else
                //bounds = bounds.createUnion(overline.getBounds2D());
                bounds.add( overline.getBounds2D() );
        }
        return bounds;
    }


    /**
     * Returns the outline of the specified decoration type.
     *
     * @param textRuns The list of text runs to get the decoration outline for.
     * @param decorationType Indicates the type of decoration required.
     * eg. underline, overline or strikethrough.
     *
     * @return The decoration outline or null if the text is not decorated.
     */
    protected Shape getDecorationOutline(List textRuns, int decorationType) {

        GeneralPath outline = null;

        Paint prevPaint = null;
        Paint prevStrokePaint = null;
        Stroke prevStroke = null;
        Rectangle2D decorationRect = null;
        double yLoc = 0, height = 0;

        for (int i = 0; i < textRuns.size(); i++) {
            TextRun textRun = (TextRun)textRuns.get(i);
            AttributedCharacterIterator runaci = textRun.getACI();
            runaci.first();

            Paint paint = null;
            Stroke stroke = null;
            Paint strokePaint = null;
            TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
            if (tpi != null) {
                switch (decorationType) {
                case TextSpanLayout.DECORATION_UNDERLINE :
                    paint       = tpi.underlinePaint;
                    stroke      = tpi.underlineStroke;
                    strokePaint = tpi.underlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_OVERLINE :
                    paint       = tpi.overlinePaint;
                    stroke      = tpi.overlineStroke;
                    strokePaint = tpi.overlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_STRIKETHROUGH :
                    paint       = tpi.strikethroughPaint;
                    stroke      = tpi.strikethroughStroke;
                    strokePaint = tpi.strikethroughStrokePaint;
                    break;
                default:
                    // should never get here
                    return null;
                }
            }

            if (textRun.isFirstRunInChunk()) {
                Shape s = textRun.getLayout().getDecorationOutline
                    (decorationType);
                Rectangle2D r2d = s.getBounds2D();
                yLoc   = r2d.getY();
                height = r2d.getHeight();
            }

            if (textRun.isFirstRunInChunk() ||
                paint != prevPaint ||
                stroke != prevStroke ||
                strokePaint != prevStrokePaint) {

                // if there is a current decoration, added it to the overall
                // outline
                if (decorationRect != null) {
                    if (outline == null) {
                        outline = new GeneralPath(decorationRect);
                    } else {
                        outline.append(decorationRect, false);
                    }
                    decorationRect = null;
                }
            }

            if ((paint != null || strokePaint != null)
                && !textRun.getLayout().isVertical()
                && !textRun.getLayout().isOnATextPath()) {

                // this text run should be decorated with the specified
                // decoration type note: decorations are only supported for
                // plain horizontal layouts

                Shape decorationShape =
                    textRun.getLayout().getDecorationOutline(decorationType);
                if (decorationRect == null) {
                    // create a new one
                    Rectangle2D r2d = decorationShape.getBounds2D();
                    decorationRect = new Rectangle2D.Double
                        (r2d.getX(), yLoc, r2d.getWidth(), height);
                } else {
                    // extend the current one
                    Rectangle2D bounds = decorationShape.getBounds2D();
                    double minX = Math.min(decorationRect.getX(),
                                           bounds.getX());
                    double maxX = Math.max(decorationRect.getMaxX(),
                                           bounds.getMaxX());
                    decorationRect.setRect(minX, yLoc, maxX-minX, height);
                }
            }

            prevPaint = paint;
            prevStroke = stroke;
            prevStrokePaint = strokePaint;
        }

        // if there is a decoration rect that hasn't been added to the overall outline
        if (decorationRect != null) {
            if (outline == null) {
                outline = new GeneralPath(decorationRect);
            } else {
                outline.append(decorationRect, false);
            }
        }

        return outline;
    }

    /**
     * Returns the stroked outline of the specified decoration type.
     * If the decoration has no stroke it will return the fill outline
     *
     * @param textRuns The list of text runs to get the decoration outline for.
     * @param decorationType Indicates the type of decoration required.
     * eg. underline, overline or strikethrough.
     *
     * @return The decoration outline or null if the text is not decorated.
     */
    protected Shape getDecorationStrokeOutline
        (List textRuns, int decorationType) {

        GeneralPath outline = null;

        Paint prevPaint = null;
        Paint prevStrokePaint = null;
        Stroke prevStroke = null;
        Rectangle2D decorationRect = null;
        double yLoc = 0, height = 0;

        for (int i = 0; i < textRuns.size(); i++) {

            TextRun textRun = (TextRun)textRuns.get(i);
            AttributedCharacterIterator runaci = textRun.getACI();
            runaci.first();

            Paint paint = null;
            Stroke stroke = null;
            Paint strokePaint = null;
            TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
            if (tpi != null) {
                switch (decorationType) {
                case TextSpanLayout.DECORATION_UNDERLINE :
                    paint       = tpi.underlinePaint;
                    stroke      = tpi.underlineStroke;
                    strokePaint = tpi.underlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_OVERLINE :
                    paint       = tpi.overlinePaint;
                    stroke      = tpi.overlineStroke;
                    strokePaint = tpi.overlineStrokePaint;
                    break;
                case TextSpanLayout.DECORATION_STRIKETHROUGH :
                    paint       = tpi.strikethroughPaint;
                    stroke      = tpi.strikethroughStroke;
                    strokePaint = tpi.strikethroughStrokePaint;
                    break;
                default:
                    // should never get here
                    return null;
                }
            }

            if (textRun.isFirstRunInChunk()) {
                Shape s = textRun.getLayout().getDecorationOutline
                    (decorationType);
                Rectangle2D r2d = s.getBounds2D();
                yLoc   = r2d.getY();
                height = r2d.getHeight();
            }

            if (textRun.isFirstRunInChunk() ||
                paint != prevPaint ||
                stroke != prevStroke ||
                strokePaint != prevStrokePaint) {

                // if there is a current decoration, added it to the overall
                // outline
                if (decorationRect != null) {

                    Shape s = null;
                    if (prevStroke != null &&
                        prevStrokePaint != null)
                        s = prevStroke.createStrokedShape(decorationRect);
                    else if (prevPaint != null)
                        s = decorationRect;
                    if (s != null) {
                        if (outline == null)
                            outline = new GeneralPath(s);
                        else
                            outline.append(s, false);
                    }
                    decorationRect = null;
                }
            }

            if ((paint != null || strokePaint != null)
                && !textRun.getLayout().isVertical()
                && !textRun.getLayout().isOnATextPath()) {

                // this text run should be decorated with the specified
                // decoration type note: decorations are only supported for
                // plain horizontal layouts

                Shape decorationShape =
                    textRun.getLayout().getDecorationOutline(decorationType);

                if (decorationRect == null) {
                    // create a new one
                    Rectangle2D r2d = decorationShape.getBounds2D();
                    decorationRect = new Rectangle2D.Double
                        (r2d.getX(), yLoc, r2d.getWidth(), height);
                } else {
                    // extend the current one
                    Rectangle2D bounds = decorationShape.getBounds2D();
                    double minX = Math.min(decorationRect.getX(),
                                           bounds.getX());
                    double maxX = Math.max(decorationRect.getMaxX(),
                                           bounds.getMaxX());
                    decorationRect.setRect(minX, yLoc, maxX-minX, height);
                }
            }

            prevPaint = paint;
            prevStroke = stroke;
            prevStrokePaint = strokePaint;
        }

        // if there is a decoration rect that hasn't been added to the overall
        // outline
        if (decorationRect != null) {
            Shape s = null;
            if (prevStroke != null &&
                prevStrokePaint != null)
                s = prevStroke.createStrokedShape(decorationRect);
            else if (prevPaint != null)
                s = decorationRect;
            if (s != null) {
                if (outline == null)
                    outline = new GeneralPath(s);
                else
                    outline.append(s, false);
            }
        }

        return outline;
    }


    public Mark getMark(TextNode node, int index, boolean leadingEdge) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        if ((index < aci.getBeginIndex()) ||
            (index > aci.getEndIndex()))
            return null;

        TextHit textHit = new TextHit(index, leadingEdge);
        return new BasicTextPainter.BasicMark(node, textHit);
    }

    protected Mark hitTest(double x, double y, TextNode node) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        // get the list of text runs
        List textRuns = getTextRuns(node, aci);
        if (textRuns != null) {
            // for each text run, see if its been hit
            for (int i = 0; i < textRuns.size(); ++i) {
                TextRun textRun = (TextRun)textRuns.get(i);
                TextSpanLayout layout = textRun.getLayout();
                TextHit textHit = layout.hitTestChar((float) x, (float) y);
                Rectangle2D bounds = layout.getBounds2D();
                if ((textHit != null) && 
                    (bounds != null) && bounds.contains(x,y))
                    return new BasicTextPainter.BasicMark(node, textHit);
            }
        }

        return null;
    }

    /**
     * Selects the first glyph in the text node.
     */
    public Mark selectFirst(TextNode node) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        TextHit textHit = new TextHit(aci.getBeginIndex(), false);
        return new BasicTextPainter.BasicMark(node, textHit);
    }

    /**
     * Selects the last glyph in the text node.
     */
    public Mark selectLast(TextNode node) {
        AttributedCharacterIterator aci;
        aci = node.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        TextHit textHit = new TextHit(aci.getEndIndex()-1, false);
        return  new BasicTextPainter.BasicMark(node, textHit);
    }

    /**
     * Returns an array of ints representing begin/end index pairs into
     * an AttributedCharacterIterator which represents the text
     * selection delineated by two Mark instances.
     * <em>Note: The Mark instances passed must have been instantiated by
     * an instance of this enclosing TextPainter implementation.</em>
     */
    public int[] getSelected(Mark startMark,
                             Mark finishMark) {

        if (startMark == null || finishMark == null) {
            return null;
        }
        BasicTextPainter.BasicMark start;
        BasicTextPainter.BasicMark finish;
        try {
            start = (BasicTextPainter.BasicMark) startMark;
            finish = (BasicTextPainter.BasicMark) finishMark;
        } catch (ClassCastException cce) {
            throw new Error
                ("This Mark was not instantiated by this TextPainter class!");
        }

        TextNode textNode = start.getTextNode();
        if (textNode == null)
            return null;
        if (textNode != finish.getTextNode())
            throw new Error("Markers are from different TextNodes!");

        AttributedCharacterIterator aci;
        aci = textNode.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        int[] result = new int[2];
        result[0] = start.getHit().getCharIndex();
        result[1] = finish.getHit().getCharIndex();

        // get the list of text runs
        List textRuns = getTextRuns(textNode, aci);
        Iterator trI = textRuns.iterator();
        int startGlyphIndex = -1;
        int endGlyphIndex = -1;
        TextSpanLayout startLayout=null, endLayout=null;
        while (trI.hasNext()) {
            TextRun tr = (TextRun)trI.next();
            TextSpanLayout tsl = tr.getLayout();
            if (startGlyphIndex == -1) {
                startGlyphIndex  = tsl.getGlyphIndex(result[0]);
                if (startGlyphIndex != -1)
                    startLayout = tsl;
            }

            if (endGlyphIndex == -1) {
                endGlyphIndex = tsl.getGlyphIndex(result[1]);
                if (endGlyphIndex != -1)
                    endLayout = tsl;
            }
            if ((startGlyphIndex != -1) && (endGlyphIndex != -1))
                break;
        }
        if ((startLayout == null) || (endLayout == null))
            return null;

        int startCharCount = startLayout.getCharacterCount
            (startGlyphIndex, startGlyphIndex);
        int endCharCount = endLayout.getCharacterCount
            (endGlyphIndex, endGlyphIndex);
        if (startCharCount > 1) {
            if (result[0] > result[1] && startLayout.isLeftToRight()) {
                result[0] += startCharCount-1;
            } else if (result[1] > result[0] && !startLayout.isLeftToRight()) {
                result[0] -= startCharCount-1;
            }
        }
        if (endCharCount > 1) {
            if (result[1] > result[0] && endLayout.isLeftToRight()) {
                result[1] += endCharCount-1;
            } else if (result[0] > result[1] && !endLayout.isLeftToRight()) {
                result[1] -= endCharCount-1;
            }
        }

        return result;
    }

   /**
     * Return a Shape, in the coordinate system of the text layout,
     * which encloses the text selection delineated by two Mark instances.
     * <em>Note: The Mark instances passed must have been instantiated by
     * an instance of this enclosing TextPainter implementation.</em>
     */
    public Shape getHighlightShape(Mark beginMark, Mark endMark) {

        if (beginMark == null || endMark == null) {
            return null;
        }

        BasicTextPainter.BasicMark begin;
        BasicTextPainter.BasicMark end;
        try {
            begin = (BasicTextPainter.BasicMark) beginMark;
            end = (BasicTextPainter.BasicMark) endMark;
        } catch (ClassCastException cce) {
            throw new Error
                ("This Mark was not instantiated by this TextPainter class!");
        }

        TextNode textNode = begin.getTextNode();
        if (textNode == null)
            return null;
        if (textNode != end.getTextNode())
            throw new Error("Markers are from different TextNodes!");

        AttributedCharacterIterator aci;
        aci = textNode.getAttributedCharacterIterator();
        if (aci == null)
            return null;

        int beginIndex = begin.getHit().getCharIndex();
        int endIndex   = end.getHit().getCharIndex();
        if (beginIndex > endIndex) {
            // Swap them...
            BasicTextPainter.BasicMark tmpMark = begin;
            begin = end; end = tmpMark;

            int tmpIndex = beginIndex;
            beginIndex = endIndex; endIndex = tmpIndex;
        }

        // get the list of text runs
        List textRuns = getTextRuns(textNode, aci);

        GeneralPath highlightedShape = new GeneralPath();

        // for each text run, append any highlight it may contain for
        // the current selection
        for (int i = 0; i < textRuns.size(); ++i) {
            TextRun textRun = (TextRun)textRuns.get(i);
            TextSpanLayout layout = textRun.getLayout();

            Shape layoutHighlightedShape = layout.getHighlightShape
                (beginIndex, endIndex);

            // append the highlighted shape of this layout to the
            // overall hightlighted shape
            if (( layoutHighlightedShape != null) &&
                (!layoutHighlightedShape.getBounds().isEmpty())) {
                highlightedShape.append(layoutHighlightedShape, false);
            }
        }
        return highlightedShape;
    }

// inner classes

    class TextChunk {

        public int begin;
        public int end;
        public Point2D advance;

        public TextChunk(int begin, int end, Point2D advance) {
            this.begin = begin;
            this.end = end;
            this.advance = new Point2D.Float((float) advance.getX(),
                                             (float) advance.getY());
        }
    }


    /**
     * Inner convenience class for associating a TextLayout for
     * sub-spans, and the ACI which iterates over that subspan.
     */
    public class TextRun {

        protected AttributedCharacterIterator aci;
        protected TextSpanLayout layout;
        protected int anchorType;
        protected boolean firstRunInChunk;
        protected Float length;
        protected Integer lengthAdjust;

        public TextRun(TextSpanLayout layout,
                       AttributedCharacterIterator aci,
                       boolean firstRunInChunk) {

            this.layout = layout;
            this.aci = aci;
            this.aci.first();
            this.firstRunInChunk = firstRunInChunk;
            this.anchorType = TextNode.Anchor.ANCHOR_START;

            TextNode.Anchor anchor = (TextNode.Anchor) aci.getAttribute
                (GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
            if (anchor != null) {
                this.anchorType = anchor.getType();
            }

            // if writing mode is right to left, then need to reverse the
            // text anchor positions
            if (aci.getAttribute(WRITING_MODE) == WRITING_MODE_RTL) {
                if (anchorType == TextNode.Anchor.ANCHOR_START) {
                    anchorType = TextNode.Anchor.ANCHOR_END;
                } else if (anchorType == TextNode.Anchor.ANCHOR_END) {
                    anchorType = TextNode.Anchor.ANCHOR_START;
                }
                // leave middle as is
            }

            length = (Float) aci.getAttribute
                (GVTAttributedCharacterIterator.TextAttribute.BBOX_WIDTH);
            lengthAdjust = (Integer) aci.getAttribute
                (GVTAttributedCharacterIterator.TextAttribute.LENGTH_ADJUST);
        }

        public AttributedCharacterIterator getACI() {
            return aci;
        }

        public TextSpanLayout getLayout() {
            return layout;
        }

        public int getAnchorType() {
            return anchorType;
        }

        public Float getLength() {
            return length;
        }

        public Integer getLengthAdjust() {
            return lengthAdjust;
        }

        public boolean isFirstRunInChunk() {
            return firstRunInChunk;
        }

    }
}
