/*
 * @(#)$RCSfile: BidiParagraphRenderer.java,v $ $Revision: 1.5 $ $Date: 2003/06/03 18:49:37 $
 *
 * (C) Copyright IBM Corp. 1998-2003.  All Rights Reserved.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */
// Requires Java2
package com.ibm.richtext.textformat;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;

import java.util.Vector;

import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MTabRuler;
import com.ibm.richtext.styledtext.TabStop;

import com.ibm.richtext.textlayout.attributes.AttributeMap;
import com.ibm.richtext.textlayout.attributes.TextAttribute;

import com.ibm.richtext.textlayout.Graphics2DConversion;

///*JDK12IMPORTS
import java.awt.Graphics2D;

import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextHitInfo;

import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
//JDK12IMPORTS*/
/*JDK11IMPORTS
import com.ibm.richtext.textlayout.Graphics2D;

import com.ibm.richtext.textlayout.FontRenderContext;
import com.ibm.richtext.textlayout.TextLayout;
import com.ibm.richtext.textlayout.LineBreakMeasurer;
import com.ibm.richtext.textlayout.TextHitInfo;

import com.ibm.richtext.textlayout.AffineTransform;
import com.ibm.richtext.textlayout.GeneralPath;
import com.ibm.richtext.textlayout.Rectangle2D;
JDK11IMPORTS*/

final class BidiParagraphRenderer extends ParagraphRenderer {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
    private final class BidiSegment {
        TextLayout fLayout;
        Rectangle2D.Float fBounds;
        int fDistanceFromLeadingMargin;
    }

    private final class BidiLayoutInfo extends LayoutInfo
    {                    
        int fCharLength;      // number of characters on line (was fLength)
        int fAscent;
        int fDescent;
        int fLeading;
        int fVisibleAdvance;  // distance along line direction ie width
        int fTotalAdvance;    // distance along line direction including trailing whitespace

        int fLeadingMargin;   // screen distance from leading margin

        boolean fLeftToRight; // true iff the orientation is left-to-right

        final Vector fSegments = new Vector(); // segments to render, in logical order

        public int getCharLength() {
            return fCharLength;
        }

        public int getAscent() {
            return fAscent;
        }

        public int getDescent() {
            return fDescent;
        }

        public int getLeading() {
            return fLeading;
        }

        public int getVisibleAdvance() {
            return fVisibleAdvance;
        }

        public int getTotalAdvance() {
            return fTotalAdvance;
        }

        public int getLeadingMargin() {
            return fLeadingMargin;
        }

        public boolean isLeftToRight() {
            return fLeftToRight;
        }

        public int getHeight() {
            return fAscent + fDescent + fLeading;
        }

        public String toString()
        {
            return "LayoutInfo(charStart: " + getCharStart(0) +
                ", fCharLength: " + fCharLength +
                ", fAscent: " + fAscent +
                ", fDescent: " + fDescent +
                ", fVisibleAdvance: " + fVisibleAdvance +
                ", fTotalAdvance: " + fTotalAdvance +
                ", fLeadingMargin: " + fLeadingMargin +
                ")";
        }

        BidiParagraphRenderer fRenderer;

        // just delegate to renderer for now

        public void renderWithHighlight(int lengthBasis,
                                        Graphics2D g,
                                        int lineBound,
                                        int x,
                                        int y,
                                        TextOffset selStart,
                                        TextOffset selStop,
                                        Color highlightColor) {

            fRenderer.renderWithHighlight(this,
                                          lengthBasis,
                                          g,
                                          lineBound,
                                          x,
                                          y,
                                          selStart,
                                          selStop,
                                          highlightColor);
        }

        public void render(int lengthBasis,
                           Graphics2D g,
                           int lineBound,
                           int x,
                           int y) {
            fRenderer.render(this, lengthBasis, g, lineBound, x, y);
        }

        public void renderCaret(MConstText text,
                                int lengthBasis,
                                Graphics2D g,
                                int lineBound,
                                int x,
                                int y,
                                int charOffset,
                                Color strongCaretColor,
                                Color weakCaretColor) {
            fRenderer.renderCaret(this, text, lengthBasis, g, lineBound, x, y, charOffset,
                                        strongCaretColor, weakCaretColor);
        }

        public TextOffset pixelToOffset(int lengthBasis,
                                        TextOffset result,
                                        int lineBound,
                                        int x,
                                        int y) {
            return fRenderer.pixelToOffset(this, lengthBasis, result, lineBound, x, y);
        }

        public Rectangle caretBounds(MConstText text,
                                     int lengthBasis,
                                     int lineBound,
                                     int charOffset,
                                     int x,
                                     int y) {
            return fRenderer.caretBounds(this, text, lengthBasis, lineBound, charOffset, x, y);
        }
        
        public int strongCaretBaselinePosition(int lengthBasis,
                                               int lineBound,
                                               int charOffset) {

            return fRenderer.strongCaretBaselinePosition(this, lengthBasis, lineBound, charOffset);
        }

        public int getNextOffset(int lengthBasis,
                                 int charOffset,
                                 short dir) {

            return fRenderer.getNextOffset(this, lengthBasis, charOffset, dir);
        }
    }

    private static final int FLUSH_LEADING = TextAttribute.FLUSH_LEADING.intValue();
    private static final int FLUSH_CENTER = TextAttribute.FLUSH_CENTER.intValue();
    private static final int FLUSH_TRAILING = TextAttribute.FLUSH_TRAILING.intValue();
    private static final int FULLY_JUSTIFIED = TextAttribute.FULLY_JUSTIFIED.intValue();

    private AttributeMap cacheStyle = null;

    private float fLeadingMargin;
    private float fTrailingMargin;
    private float fFirstLineIndent;
    private float fMinLineSpacing;
    private float fExtraLineSpacing;
    
    private int fFlush = -1;
    private MTabRuler fTabRuler;
    
    private boolean fLtrDefault;
    private DefaultCharacterMetric fDefaultCharMetric;
    
    BidiParagraphRenderer(AttributeMap pStyle, DefaultCharacterMetric defaultCharMetric) {

        fDefaultCharMetric = defaultCharMetric;
        initRenderer(pStyle);
    }

    private float getFloatValue(Object key, AttributeMap style) {
        return ((Float)style.get(key)).floatValue();
    }
    
    private int getIntValue(Object key, AttributeMap style) {
        return ((Integer)style.get(key)).intValue();
    }
    
    /**
     * NOTE:  it is illegal to initialize a StandardParagraphRenderer for any style
     * other than the one it was created with.
     */
    public void initRenderer(AttributeMap pStyle) {

        if (cacheStyle == null) {

            fLeadingMargin = getFloatValue(TextAttribute.LEADING_MARGIN, pStyle);
            fTrailingMargin = getFloatValue(TextAttribute.TRAILING_MARGIN, pStyle);
            fFirstLineIndent = getFloatValue(TextAttribute.FIRST_LINE_INDENT, pStyle);
            fMinLineSpacing = getFloatValue(TextAttribute.MIN_LINE_SPACING, pStyle);
            fExtraLineSpacing = getFloatValue(TextAttribute.EXTRA_LINE_SPACING, pStyle);

            fFlush = getIntValue(TextAttribute.LINE_FLUSH, pStyle);

            fTabRuler = (MTabRuler) pStyle.get(TextAttribute.TAB_RULER);
            
            Object runDir = pStyle.get(TextAttribute.RUN_DIRECTION);
            fLtrDefault = !TextAttribute.RUN_DIRECTION_RTL.equals(runDir);

            cacheStyle = pStyle;
        }
        else if (pStyle != cacheStyle) {
            if (!pStyle.equals(cacheStyle)) {
                throw new Error("Attempt to share BidiParagraphRenderer between styles!");
            }
            else {
                cacheStyle = pStyle;
            }
        }
    }

    private static boolean isTab(char ch) {
        return ch == '\t';
    }

    /**
     * Fill in info with the next line.
     * @param measurer the LineBreakMeasurer for this paragraph.
     *  Current position should be the first character on the line.
     *  If null, a 0-length line is generated.  If measurer is null
     *  then paragraphStart and paragraphLimit should be equal.
     */
    // Usually totalFormatWidth and lineBound will be the same.
    // totalFormatWidth is used for wrapping, but lineBound is
    // for flushing.  These may be different for unwrapped text,
    // for example.
    public LayoutInfo layout(MConstText text,
                             LayoutInfo layoutToReuse,
                             LineBreakMeasurer measurer,
                             FontRenderContext frc,
                             int paragraphStart,
                             int paragraphLimit,
                             int totalFormatWidth,
                             int lineBound) {

        if ((measurer==null) != (paragraphStart==paragraphLimit)) {
            throw new IllegalArgumentException(
                    "measurer, paragraphStart, paragraphLimit are wrong.");
        }
        BidiLayoutInfo line = null;

        try {
            line = (BidiLayoutInfo) layoutToReuse;
        }
        catch(ClassCastException e) {
        }

        if (line == null) {
            line = new BidiLayoutInfo();
        }

        line.fRenderer = this;

        final int lineCharStart = measurer==null? paragraphStart : measurer.getPosition();
        line.setCharStart(lineCharStart);

        final int lineIndent = (lineCharStart==paragraphStart)? (int) fFirstLineIndent : 0;

        int formatWidth = totalFormatWidth - (int) (fLeadingMargin + fTrailingMargin);
        computeLineMetrics(text, line, measurer, frc,
                            paragraphStart, paragraphLimit, formatWidth, lineIndent);

        // position the line according to the line flush
        if (fFlush == FLUSH_TRAILING || fFlush == FLUSH_CENTER) {
            int lineArea = lineBound - (int) (fLeadingMargin + fTrailingMargin);
            int advanceDifference = lineArea - line.fVisibleAdvance;

            if (fFlush == FLUSH_TRAILING) {
                line.fLeadingMargin = ((int) (fLeadingMargin)) + advanceDifference;
            }
            else if (fFlush == FLUSH_CENTER) {
                line.fLeadingMargin = (int) (fLeadingMargin + advanceDifference/2);
            }
        }
        else {
            line.fLeadingMargin = (int) fLeadingMargin;
        }

        return line;
    }

    /**
     * Fill in the following fields in line:
     * fCharLength, fAscent, fDescent, fLeading, fVisibleAdvance,
     * fTotalAdvance.
     * Uses: line.fLeadingMargin
     * @param formatWidth the width to fit the line into.
     */
    private void computeLineMetrics(MConstText text,
                                    BidiLayoutInfo line,
                                    LineBreakMeasurer measurer,
                                    FontRenderContext frc,
                                    final int paragraphStart,
                                    final int paragraphLimit,
                                    final int formatWidth,
                                    final int lineIndent) {

        int segmentCount = 0;
        /* variable not used boolean firstLine = measurer==null ||
                            measurer.getPosition() == paragraphStart; */

        if (measurer != null) {
            computeSegments(text, line, measurer, paragraphLimit, formatWidth, lineIndent);

            // iterate through segments and accumulate ascent, descent,
            // leading, char length
            float ascent = 0;
            float descent = 0;
            float descentPlusLeading = 0;

            segmentCount = line.fSegments.size();
            for (int i=0; i < segmentCount; i++) {
                TextLayout layout = ((BidiSegment)line.fSegments.elementAt(i)).fLayout;
                ascent = Math.max(ascent, layout.getAscent());
                float segDescent = layout.getDescent();
                descent = Math.max(descent, segDescent);
                descentPlusLeading = Math.max(descentPlusLeading, segDescent+layout.getLeading());
                line.fCharLength += layout.getCharacterCount();
            }

            line.fAscent = (int) Math.ceil(ascent);
            line.fDescent = (int) Math.ceil(descent);
            line.fLeading = (int) Math.ceil(descentPlusLeading) - line.fDescent;
        }
        else {
            line.fLeftToRight = fLtrDefault;
            line.fSegments.removeAllElements();

            line.fCharLength = 0;

            AttributeMap style = text.characterStyleAt(paragraphStart);
            DefaultCharacterMetric.Metric cm = fDefaultCharMetric.getMetricForStyle(style);
            line.fAscent = cm.getAscent();
            line.fDescent = cm.getDescent();
            line.fLeading = cm.getLeading();

            line.fVisibleAdvance = line.fTotalAdvance = 0;
        }

        if (fExtraLineSpacing != 0) {
            line.fAscent += (int) Math.ceil(fExtraLineSpacing);
        }

        if (fMinLineSpacing != 0){
            int height = line.getHeight();
            if (height < fMinLineSpacing) {
                line.fAscent += Math.ceil(fMinLineSpacing - height);
            }
        }

        final int lineNaturalAdvance = line.fTotalAdvance;

        line.fTotalAdvance += lineIndent;
        line.fVisibleAdvance += lineIndent;

        if (measurer != null) {
            // Now fill in fBounds field of BidiSegments.  fBounds should tile
            // the line.
            final float lineHeight = line.getHeight();

            for (int i=1; i < segmentCount; i++) {

                BidiSegment currentSegment = (BidiSegment) line.fSegments.elementAt(i-1);
                BidiSegment nextSegment = (BidiSegment) line.fSegments.elementAt(i);

                float origin;
                float width;

                if (line.fLeftToRight) {
                    origin = 0;
                    width = nextSegment.fDistanceFromLeadingMargin -
                                currentSegment.fDistanceFromLeadingMargin;
                }
                else {
                    origin = currentSegment.fDistanceFromLeadingMargin;
                    origin -= nextSegment.fDistanceFromLeadingMargin;
                    origin += (float) Math.ceil(nextSegment.fLayout.getAdvance());
                    width = (float) Math.ceil(currentSegment.fLayout.getAdvance()) - origin;
                }
                currentSegment.fBounds = new Rectangle2D.Float(origin, -line.fAscent, width, lineHeight);
            }

            // set last segment's bounds
            {
                BidiSegment currentSegment = (BidiSegment) line.fSegments.elementAt(segmentCount-1);
                float origin;
                float width;

                if (line.fLeftToRight) {
                    origin = 0;
                    width = lineNaturalAdvance - currentSegment.fDistanceFromLeadingMargin;
                }
                else {
                    origin = currentSegment.fDistanceFromLeadingMargin - lineNaturalAdvance;
                    width = (float) Math.ceil(currentSegment.fLayout.getAdvance()) - origin;
                }

                currentSegment.fBounds = new Rectangle2D.Float(origin, -line.fAscent, width, lineHeight);
            }
        }
    }

    /**
     * Fill in fSegments, fLeftToRight.  measurer must not be null
     */
    private void computeSegments(MConstText text,
                                 BidiLayoutInfo line,
                                 LineBreakMeasurer measurer,
                                 final int paragraphLimit,
                                 final int formatWidth,
                                 final int lineIndent) {

        // Note on justification:  only the last segment of a line is
        // justified.  
        // Also, if a line ends in a tab it will not be justified.
        // This behavior is consistent with other word processors
        // I tried (MS Word and Lotus Word Pro).
        
        line.fSegments.removeAllElements();
        line.fCharLength = 0;

        TabStop currentTabStop = new TabStop((int)fLeadingMargin+lineIndent, TabStop.kLeading);

        int segmentLimit = measurer.getPosition();
        boolean firstSegment = true;

        int advanceFromLeadingMargin = lineIndent;

        boolean computeSegs = true;
        
        computeTabbedSegments: do {

            // compute sementLimit:
            if (segmentLimit <= measurer.getPosition()) {
                while (segmentLimit < paragraphLimit) {
                    if (isTab(text.at(segmentLimit++))) {
                        break;
                    }
                }
            }

            // NOTE:  adjust available width for center tab!!!
            //System.out.println("Format width: " + (formatWidth-advanceFromLeadingMargin) +
            //                   ";  segmentLimit: " + segmentLimit);

            int wrappingWidth = Math.max(formatWidth-advanceFromLeadingMargin, 0);
            TextLayout layout = null;
            if (firstSegment || wrappingWidth > 0 || segmentLimit > measurer.getPosition()+1) {
                layout = measurer.nextLayout(wrappingWidth, segmentLimit, !firstSegment);
            }

            if (layout == null) {
                if (firstSegment) {
                    // I doubt this would happen, but check anyway
                    throw new Error("First layout is null!");
                }
                break computeTabbedSegments;
            }
            
            final int measurerPos = measurer.getPosition();
            if (measurerPos < segmentLimit) {
                computeSegs = false;
                if (fFlush == FULLY_JUSTIFIED) {
                    layout = layout.getJustifiedLayout(wrappingWidth);
                }
            }
            else {
                computeSegs = !(measurerPos == paragraphLimit);
            }

            if (firstSegment) {
                firstSegment = false;
                // Have to get ltr off of layout.  Not available from measurer,
                // unfortunately.
                line.fLeftToRight = layout.isLeftToRight();
            }

            BidiSegment segment = new BidiSegment();
            segment.fLayout = layout;
            int layoutAdvance = (int) Math.ceil(layout.getAdvance());

            // position layout relative to leading margin, update logicalPositionOnLine
            
            int relativeTabPosition = currentTabStop.getPosition()-(int)fLeadingMargin;
            int logicalPositionOfLayout;
            switch (currentTabStop.getType()) {
                case TabStop.kTrailing:
                    logicalPositionOfLayout = Math.max(
                                    relativeTabPosition-layoutAdvance,
                                    advanceFromLeadingMargin);
                    break;
                case TabStop.kCenter:
                    logicalPositionOfLayout = Math.max(
                                    relativeTabPosition-(layoutAdvance/2),
                                    advanceFromLeadingMargin);
                    break;
                default:  // includes decimal tab right now
                    logicalPositionOfLayout = relativeTabPosition;
                    break;
            }

            // position layout in segment
            if (line.fLeftToRight) {
                segment.fDistanceFromLeadingMargin = logicalPositionOfLayout;
            }
            else {
                segment.fDistanceFromLeadingMargin = logicalPositionOfLayout+layoutAdvance;
            }

            // update advanceFromLeadingMargin
            advanceFromLeadingMargin = logicalPositionOfLayout + layoutAdvance;

            // add segment to segment Vector
            line.fSegments.addElement(segment);

            // get next tab
            currentTabStop = fTabRuler.nextTab((int)fLeadingMargin+advanceFromLeadingMargin);
            if (currentTabStop.getType() == TabStop.kLeading ||
                            currentTabStop.getType() == TabStop.kAuto)  {
                advanceFromLeadingMargin = currentTabStop.getPosition();
                //System.out.println("Advance from leading margin:" + advanceFromLeadingMargin);

            }
            else {
               //System.out.println("Non-leading tab, type=" + currentTabStop.getType());
            }

        } while (computeSegs);

        // Now compute fTotalAdvance, fVisibleAdvance.  These metrics may be affected
        // by a trailing tab.

        {
            BidiSegment lastSegment = (BidiSegment) line.fSegments.lastElement();
            TextLayout lastLayout = lastSegment.fLayout;

            if (line.fLeftToRight) {
                line.fTotalAdvance = (int) Math.ceil(lastLayout.getAdvance()) +
                                        lastSegment.fDistanceFromLeadingMargin;
                line.fVisibleAdvance = (int) Math.ceil(lastLayout.getVisibleAdvance()) +
                                        lastSegment.fDistanceFromLeadingMargin;
            }
            else {
                line.fTotalAdvance = lastSegment.fDistanceFromLeadingMargin;
                line.fVisibleAdvance = lastSegment.fDistanceFromLeadingMargin -
                                        (int) Math.ceil(lastLayout.getAdvance() -
                                            lastLayout.getVisibleAdvance());
            }

            if (isTab(text.at(measurer.getPosition()-1))) {
                line.fTotalAdvance = Math.max(line.fTotalAdvance,
                                                currentTabStop.getPosition());
            }
        }
    }

    /**
     * Return the highlight shape for the given character offsets.
     * The Shape returned is relative to the leftmost point on the
     * baseline of line.
     */
    private Shape getHighlightShape(BidiLayoutInfo line,
                                    int lengthBasis,
                                    int lineBound,
                                    int hlStart,
                                    int hlLimit) {

        if (hlStart >= hlLimit) {
            throw new IllegalArgumentException("Highlight range length is not positive.");
        }

        final int leadingMargin = (line.fLeftToRight)?
                line.fLeadingMargin : lineBound - line.fLeadingMargin;
        final int segmentCount = line.fSegments.size();

        Shape rval = null;
        GeneralPath highlightPath = null;

        int currentLayoutStart = line.getCharStart(lengthBasis);

        for (int i=0; i < segmentCount; i++) {

            BidiSegment segment = (BidiSegment) line.fSegments.elementAt(i);
            TextLayout layout = segment.fLayout;
            int charCount = layout.getCharacterCount();
            int currentLayoutLimit = currentLayoutStart + charCount;
            boolean rangesIntersect;
            if (hlStart <= currentLayoutStart) {
                rangesIntersect = hlLimit > currentLayoutStart;
            }
            else {
                rangesIntersect = hlStart < currentLayoutLimit;
            }

            if (rangesIntersect) {

                Shape currentHl = layout.getLogicalHighlightShape(
                                        Math.max(hlStart-currentLayoutStart, 0),
                                        Math.min(hlLimit-currentLayoutStart, charCount),
                                        segment.fBounds);

                float xTranslate;
                if (line.fLeftToRight) {
                    xTranslate = leadingMargin +
                                 segment.fDistanceFromLeadingMargin;
                }
                else {
                    xTranslate = leadingMargin -
                                 segment.fDistanceFromLeadingMargin;
                }

                if (xTranslate != 0) {
                    AffineTransform xform =
                        AffineTransform.getTranslateInstance(xTranslate, 0);
                    currentHl = xform.createTransformedShape(currentHl);
                }

                if (rval == null) {
                    rval = currentHl;
                }
                else {
                    if (highlightPath == null) {
                        highlightPath = new GeneralPath();
                        highlightPath.append(rval, false);
                        rval = highlightPath;
                    }
                    highlightPath.append(currentHl, false);
                }
            }
            currentLayoutStart = currentLayoutLimit;
        }

        return rval;
    }

    private void renderWithHighlight(BidiLayoutInfo line,
                                     int lengthBasis,
                                     Graphics2D g,
                                     int lineBound,
                                     int x,
                                     int y,
                                     TextOffset selStart,
                                     TextOffset selStop,
                                     Color highlightColor) {

        final int lineCharStart = line.getCharStart(lengthBasis);

        if (selStart != null && selStop != null && !selStart.equals(selStop) &&
                line.fCharLength != 0 &&
                selStart.fOffset < lineCharStart + line.fCharLength &&
                selStop.fOffset > lineCharStart) {

            Shape highlight = getHighlightShape(line, lengthBasis, lineBound, selStart.fOffset, selStop.fOffset);
            if (highlight != null) {
                Graphics2D hl = (Graphics2D) g.create();
                hl.setColor(highlightColor);
                hl.translate(x, y + line.fAscent);
                hl.fill(highlight);
            }
        }

        render(line, lengthBasis, g, lineBound, x, y);
    }

    /**
     * Draw the line into the graphics.  (x, y) is the upper-left corner
     * of the line.  The leading edge of a right-aligned line is aligned
     * to (x + lineBound).
     */
    private void render(BidiLayoutInfo line,
                        int lengthBasis,
                        Graphics2D g,
                        int lineBound,
                        int x,
                        int y) {

        final int leadingMargin = (line.fLeftToRight)?
                x + line.fLeadingMargin : x + lineBound - line.fLeadingMargin;
        final int baseline = y + line.fAscent;
        final int segmentCount = line.fSegments.size();

        for (int i=0; i < segmentCount; i++) {

            BidiSegment segment = (BidiSegment) line.fSegments.elementAt(i);

            float drawX;
            if (line.fLeftToRight) {
                drawX = leadingMargin + segment.fDistanceFromLeadingMargin;
            }
            else {
                drawX = leadingMargin - segment.fDistanceFromLeadingMargin;
            }

            segment.fLayout.draw(g, drawX, baseline);
        }
    }

    private TextOffset hitTestSegment(TextOffset result,
                                      int segmentCharStart,
                                      BidiSegment segment,
                                      int xInSegment,
                                      int yInSegment) {

        final TextLayout layout = segment.fLayout;
        final int charCount = layout.getCharacterCount();
        final int layoutAdvance = (int) Math.ceil(layout.getAdvance());
        Rectangle2D bounds = segment.fBounds;

        final boolean ltr = layout.isLeftToRight();

        if (ltr && (xInSegment >= layoutAdvance) || !ltr && (xInSegment <= 0)) {

            // pretend the extra space at the end of the line is a
            // tab and 'hit-test' it.
            double tabCenter;
            if (ltr) {
                tabCenter = (layoutAdvance+bounds.getMaxX()) / 2;
            }
            else {
                tabCenter = bounds.getX() / 2;
            }

            if ((xInSegment >= tabCenter) == ltr) {
                result.fOffset = charCount;
                result.fPlacement = TextOffset.BEFORE_OFFSET;
            }
            else {
                result.fOffset = charCount-1;
                result.fPlacement = TextOffset.AFTER_OFFSET;
            }
        }
        else {
            TextHitInfo info = layout.hitTestChar(xInSegment, yInSegment, segment.fBounds);
            result.fOffset = info.getInsertionIndex();
            if (result.fOffset == 0) {
                result.fPlacement = TextOffset.AFTER_OFFSET;
            }
            else if (result.fOffset == charCount) {
                result.fPlacement = TextOffset.BEFORE_OFFSET;
            }
            else {
                result.fPlacement = info.isLeadingEdge()?
                        TextOffset.AFTER_OFFSET : TextOffset.BEFORE_OFFSET;
            }
        }

        result.fOffset += segmentCharStart;
        return result;
    }

    /**
     * Return the offset at the point (x, y).  (x, y) is relative to the top-left
     * of the line.  The leading edge of a right-aligned line is aligned
     * to lineBound.
     */
    private TextOffset pixelToOffset(BidiLayoutInfo line,
                                     int lengthBasis,
                                     TextOffset result,
                                     int lineBound,
                                     int x,
                                     int y) {

        if (result == null) {
            result = new TextOffset();
        }

        final int yInSegment = y - line.fAscent;
        final int leadingMargin = (line.fLeftToRight)?
                line.fLeadingMargin : lineBound - line.fLeadingMargin;
        final int lineCharStart = line.getCharStart(lengthBasis);

        // first see if point is before leading edge of line
        final int segmentCount = line.fSegments.size();
        {
            int segLeadingMargin = leadingMargin;
            if (segmentCount > 0) {
                BidiSegment firstSeg = (BidiSegment) line.fSegments.elementAt(0);
                if (line.fLeftToRight) {
                    segLeadingMargin += firstSeg.fDistanceFromLeadingMargin;
                }
                else {
                    segLeadingMargin -= firstSeg.fDistanceFromLeadingMargin;
                    segLeadingMargin += (float) firstSeg.fBounds.getMaxX();
                }
            }
            if (line.fLeftToRight == (x <= segLeadingMargin)) {
                result.fOffset = lineCharStart;
                result.fPlacement = TextOffset.AFTER_OFFSET;
                return result;
            }
        }

        int segmentCharStart = lineCharStart;

        for (int i=0; i < segmentCount; i++) {

            BidiSegment segment = (BidiSegment) line.fSegments.elementAt(i);
            int segmentOrigin = line.fLeftToRight?
                            leadingMargin+segment.fDistanceFromLeadingMargin :
                            leadingMargin-segment.fDistanceFromLeadingMargin;
            int xInSegment = x - segmentOrigin;
            if (line.fLeftToRight) {
                if (segment.fBounds.getMaxX() > xInSegment) {
                    return hitTestSegment(result, segmentCharStart, segment, xInSegment, yInSegment);
                }
            }
            else {
                if (segment.fBounds.getX() < xInSegment) {
                    return hitTestSegment(result, segmentCharStart, segment, xInSegment, yInSegment);
                }
            }
            segmentCharStart += segment.fLayout.getCharacterCount();
        }

        result.fOffset = lineCharStart + line.fCharLength;
        result.fPlacement = TextOffset.BEFORE_OFFSET;
        return result;
    }

    private void renderCaret(BidiLayoutInfo line,
                             MConstText text,
                             int lengthBasis,
                             Graphics2D g,
                             int lineBound,
                             int x,
                             int y,
                             final int charOffset,
                             Color strongCaretColor,
                             Color weakCaretColor)
    {
        final int segmentCount = line.fSegments.size();
        final int lineStart = line.getCharStart(lengthBasis);

        int currentStart = lineStart;
        BidiSegment segment = null;
        int segmentIndex;

        for (segmentIndex=0; segmentIndex < segmentCount; segmentIndex++) {
            segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
            int currentEndpoint = currentStart + segment.fLayout.getCharacterCount();
            if (currentEndpoint > charOffset) {
                break;
            }
            currentStart = currentEndpoint;
        }

        /*
            There are two choices here:
            1. get carets from a TextLayout and render them, or
            2. make up a caret ourselves and render it.
            We want to do 2 when:
                * there is no text on the line, or
                * the line ends with a tab and we are drawing the last caret on the line
            Otherwise, we want 1.
        */

        if (segmentIndex == segmentCount && segmentCount > 0) {
            // If we get here, line length is not 0, and charOffset is at end of line
            if (!isTab(text.at(charOffset-1))) {
                segmentIndex = segmentCount-1;
                segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
                currentStart = lineStart + line.getCharLength() -
                                    segment.fLayout.getCharacterCount();
            }
        }

        Object savedPaint = Graphics2DConversion.getColorState(g);

        try {
            if (segmentIndex < segmentCount) {
                TextLayout layout = segment.fLayout;
                int offsetInLayout = charOffset - currentStart;
                Shape[] carets = layout.getCaretShapes(offsetInLayout, segment.fBounds);
                g.setColor(strongCaretColor);
                int layoutPos = line.fLeadingMargin + segment.fDistanceFromLeadingMargin;
                int layoutX = line.fLeftToRight?
                        x + layoutPos : x + lineBound - layoutPos;
                int layoutY = y + line.fAscent;

                // Translating and then clipping doesn't work.  Try this:
                Rectangle2D.Float clipRect = new Rectangle2D.Float();
                clipRect.setRect(segment.fBounds);
                clipRect.x += layoutX;
                clipRect.y += layoutY;
                clipRect.width += 1;
                clipRect.height -= 1;

                Object savedClip = ClipWorkaround.saveClipState(g);
                try {
                    ClipWorkaround.translateAndDrawShapeWithClip(g,
                                                                layoutX,
                                                                layoutY,
                                                                clipRect,
                                                                carets[0]);
                    if (carets[1] != null) {
                        g.setColor(weakCaretColor);
                        ClipWorkaround.translateAndDrawShapeWithClip(g,
                                                                    layoutX,
                                                                    layoutY,
                                                                    clipRect,
                                                                    carets[1]);
                    }
                }
                finally {
                    ClipWorkaround.restoreClipState(g, savedClip);
                }
            }
            else {
                int lineEnd = line.fLeadingMargin + line.fTotalAdvance;
                int endX = line.fLeftToRight? lineEnd : lineBound-lineEnd;
                endX += x;
                g.drawLine(endX, y, endX, y+line.getHeight()-1);
            }
        }
        finally {
            Graphics2DConversion.restoreColorState(g, savedPaint);
        }
    }

    private Rectangle caretBounds(BidiLayoutInfo line,
                                  MConstText text,
                                  int lengthBasis,
                                  int lineBound,
                                  int charOffset,
                                  int x,
                                  int y) {

        final int segmentCount = line.fSegments.size();
        final int lineStart = line.getCharStart(lengthBasis);
        int currentStart = lineStart;
        BidiSegment segment = null;
        int segmentIndex;

        for (segmentIndex=0; segmentIndex < segmentCount; segmentIndex++) {
            segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
            int currentEndpoint = currentStart + segment.fLayout.getCharacterCount();
            if (currentEndpoint > charOffset) {
                break;
            }
            currentStart = currentEndpoint;
        }

        if (segmentIndex == segmentCount && segmentCount > 0) {
            // If we get here, line length is not 0, and charOffset is at end of line
            if (!isTab(text.at(charOffset-1))) {
                segmentIndex = segmentCount-1;
                segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
                currentStart = lineStart + line.getCharLength() -
                                    segment.fLayout.getCharacterCount();
            }
        }

        Rectangle r;
        
        if (segmentIndex < segmentCount) {
            TextLayout layout = segment.fLayout;
            int offsetInLayout = charOffset - currentStart;
            Shape[] carets = layout.getCaretShapes(offsetInLayout, segment.fBounds);
            r = carets[0].getBounds();
            if (carets[1] != null) {
                r.add(carets[1].getBounds());
            }
            r.width += 1;
            
            int layoutPos = line.fLeadingMargin + segment.fDistanceFromLeadingMargin;
            if (line.fLeftToRight) {
                r.x += layoutPos;
            }
            else {
                r.x += lineBound - layoutPos;
            }
            r.y += line.fAscent;
        }
        else {
            r = new Rectangle();
            r.height = line.getHeight();
            r.width = 1;
            int lineEnd = line.fLeadingMargin + line.fTotalAdvance;
            if (line.fLeftToRight) {
                r.x = lineEnd;
            }
            else {
                r.x = lineBound - lineEnd;
            }
        }
        
        r.translate(x, y);
        return r;
    }

    private int strongCaretBaselinePosition(BidiLayoutInfo line,
                                            int lengthBasis,
                                            int lineBound,
                                            int charOffset) {

        final int segmentCount = line.fSegments.size();
        int currentStart = line.getCharStart(lengthBasis);
        BidiSegment segment = null;
        int segmentIndex;

        for (segmentIndex=0; segmentIndex < segmentCount; segmentIndex++) {
            segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
            int currentEndpoint = currentStart + segment.fLayout.getCharacterCount();
            if (currentEndpoint > charOffset) {
                break;
            }
            currentStart = currentEndpoint;
        }

        if (segmentIndex < segmentCount) {
            TextLayout layout = segment.fLayout;
            int offsetInLayout = charOffset - currentStart;
            TextHitInfo hit = TextHitInfo.afterOffset(offsetInLayout);
            hit = TextLayout.DEFAULT_CARET_POLICY.getStrongCaret(hit, hit.getOtherHit(), layout);
            float[] info = layout.getCaretInfo(hit);
            int layoutPos = line.fLeadingMargin + segment.fDistanceFromLeadingMargin;
            if (line.fLeftToRight) {
                return layoutPos + (int) info[0];
            }
            else {
                return lineBound - layoutPos + (int) info[0];
            }
        }
        else {
            int lineEnd = line.fLeadingMargin + line.fTotalAdvance;
            if (line.fLeftToRight) {
                return lineEnd;
            }
            else {
                return lineBound - lineEnd;
            }
        }
    }

    private int getNextOffset(BidiLayoutInfo line,
                              int lengthBasis,
                              int charOffset,
                              short dir) {

        if (dir != MFormatter.eLeft && dir != MFormatter.eRight) {
            throw new IllegalArgumentException("Invalid direction.");
        }

        // find segment containing offset:
        final int segmentCount = line.fSegments.size();
        final int lineCharStart = line.getCharStart(lengthBasis);

        int currentStart = lineCharStart;
        BidiSegment segment = null;
        int segmentIndex;

        for (segmentIndex=0; segmentIndex < segmentCount; segmentIndex++) {
            segment = (BidiSegment) line.fSegments.elementAt(segmentIndex);
            int currentEndpoint = currentStart + segment.fLayout.getCharacterCount();
            if (currentEndpoint > charOffset ||
                    (segmentIndex == segmentCount-1 && currentEndpoint==charOffset)) {
                break;
            }
            currentStart = currentEndpoint;
        }

        final boolean logAdvance = (dir==MFormatter.eRight)==(line.fLeftToRight);

        int result;

        if (segmentIndex < segmentCount) {
            TextLayout layout = segment.fLayout;
            int offsetInLayout = charOffset - currentStart;
            TextHitInfo hit = (dir==MFormatter.eLeft)?
                        layout.getNextLeftHit(offsetInLayout) :
                        layout.getNextRightHit(offsetInLayout);
            if (hit == null) {
                result = logAdvance?
                    currentStart+layout.getCharacterCount()+1 : currentStart-1;
            }
            else {
                result = hit.getInsertionIndex() + currentStart;
            }
        }
        else {
            result = logAdvance? lineCharStart + line.fCharLength + 1 :
                                         lineCharStart - 1;
        }

        return result;
    }
}