/*
 * @(#)$RCSfile: BidiParagraphRenderer.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:50:03 $
 *
 * (C) Copyright IBM Corp. 1998-1999.  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 java.util.Hashtable;

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

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

import com.ibm.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.textlayout.Graphics2D;

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

import com.ibm.textlayout.AffineTransform;
import com.ibm.textlayout.GeneralPath;
import com.ibm.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;
        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 = layout.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;
    }
}