/*
 * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 *
 * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
 */

package sun.font;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;

import java.awt.font.FontRenderContext;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import java.util.Map;

/**
 * Default implementation of ExtendedTextLabel.
 */

// {jbr} I made this class package-private to keep the
// Decoration.Label API package-private.

/* public */
class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.Label {

  TextSource source;
  private Decoration decorator;

  // caches
  private Font font;
  private AffineTransform baseTX;
  private CoreMetrics cm;

  Rectangle2D lb;
  Rectangle2D ab;
  Rectangle2D vb;
  Rectangle2D ib;
  StandardGlyphVector gv;
  float[] charinfo;

  /**
   * Create from a TextSource.
   */
  public ExtendedTextSourceLabel(TextSource source, Decoration decorator) {
    this.source = source;
    this.decorator = decorator;
    finishInit();
  }

  /**
   * Create from a TextSource, optionally using cached data from oldLabel starting at the offset.
   * If present oldLabel must have been created from a run of text that includes the text used in
   * the new label.  Start in source corresponds to logical character offset in oldLabel.
   */
  public ExtendedTextSourceLabel(TextSource source, ExtendedTextSourceLabel oldLabel, int offset) {
    // currently no optimization.
    this.source = source;
    this.decorator = oldLabel.decorator;
    finishInit();
  }

  private void finishInit() {
    font = source.getFont();

    Map<TextAttribute, ?> atts = font.getAttributes();
    baseTX = AttributeValues.getBaselineTransform(atts);
    if (baseTX == null){
        cm = source.getCoreMetrics();
    } else {
      AffineTransform charTX = AttributeValues.getCharTransform(atts);
      if (charTX == null) {
          charTX = new AffineTransform();
      }
      font = font.deriveFont(charTX);

      LineMetrics lm = font.getLineMetrics(source.getChars(), source.getStart(),
          source.getStart() + source.getLength(), source.getFRC());
      cm = CoreMetrics.get(lm);
    }
  }


  // TextLabel API

  public Rectangle2D getLogicalBounds() {
    return getLogicalBounds(0, 0);
  }

  public Rectangle2D getLogicalBounds(float x, float y) {
    if (lb == null) {
      lb = createLogicalBounds();
    }
    return new Rectangle2D.Float((float)(lb.getX() + x),
                                 (float)(lb.getY() + y),
                                 (float)lb.getWidth(),
                                 (float)lb.getHeight());
  }

    public float getAdvance() {
        if (lb == null) {
            lb = createLogicalBounds();
        }
        return (float)lb.getWidth();
    }

  public Rectangle2D getVisualBounds(float x, float y) {
    if (vb == null) {
      vb = decorator.getVisualBounds(this);
    }
    return new Rectangle2D.Float((float)(vb.getX() + x),
                                 (float)(vb.getY() + y),
                                 (float)vb.getWidth(),
                                 (float)vb.getHeight());
  }

  public Rectangle2D getAlignBounds(float x, float y) {
    if (ab == null) {
      ab = createAlignBounds();
    }
    return new Rectangle2D.Float((float)(ab.getX() + x),
                                 (float)(ab.getY() + y),
                                 (float)ab.getWidth(),
                                 (float)ab.getHeight());

  }

  public Rectangle2D getItalicBounds(float x, float y) {
    if (ib == null) {
      ib = createItalicBounds();
    }
    return new Rectangle2D.Float((float)(ib.getX() + x),
                                 (float)(ib.getY() + y),
                                 (float)ib.getWidth(),
                                 (float)ib.getHeight());

  }

  public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
      return getGV().getPixelBounds(frc, x, y);
  }

  public boolean isSimple() {
      return decorator == Decoration.getPlainDecoration() &&
             baseTX == null;
  }

  public AffineTransform getBaselineTransform() {
      return baseTX; // passing internal object, caller must not modify!
  }

  public Shape handleGetOutline(float x, float y) {
    return getGV().getOutline(x, y);
  }

  public Shape getOutline(float x, float y) {
    return decorator.getOutline(this, x, y);
  }

  public void handleDraw(Graphics2D g, float x, float y) {
    g.drawGlyphVector(getGV(), x, y);
  }

  public void draw(Graphics2D g, float x, float y) {
    decorator.drawTextAndDecorations(this, g, x, y);
  }

  /**
   * The logical bounds extends from the origin of the glyphvector to the
   * position at which a following glyphvector's origin should be placed.
   * We always assume glyph vectors are rendered from left to right, so
   * the origin is always to the left.
   * <p> On a left-to-right run, combining marks and 'ligatured away'
   * characters are to the right of their base characters.  The charinfo
   * array will record the character positions for these 'missing' characters
   * as being at the origin+advance of the base glyph, with zero advance.
   * (This is not necessarily the same as the glyph position, for example,
   * an umlaut glyph may have a position to the left of this point, it depends
   * on whether the font was designed so that such glyphs overhang to the left
   * of their origin, or whether it presumes some kind of kerning to position
   * the glyphs).  Anyway, the left of the bounds is the origin of the first
   * logical (leftmost) character, and the right is the origin + advance of the
   * last logical (rightmost) character.
   * <p> On a right-to-left run, these special characters are to the left
   * of their base characters.  Again, since 'glyph position' has been abstracted
   * away, we can use the origin of the leftmost character, and the origin +
   * advance of the rightmost character.
   * <p> On a mixed run (hindi) we can't rely on the first logical character
   * being the leftmost character.  However we can again rely on the leftmost
   * character origin and the rightmost character + advance.
   */
  protected Rectangle2D createLogicalBounds() {
    return getGV().getLogicalBounds();
  }

  public Rectangle2D handleGetVisualBounds() {
    return getGV().getVisualBounds();
  }

  /**
   * Like createLogicalBounds except ignore leading and logically trailing white space.
   * this assumes logically trailing whitespace is also visually trailing.
   * Whitespace is anything that has a zero visual width, regardless of its advance.
   * <p> We make the same simplifying assumptions as in createLogicalBounds, namely
   * that we can rely on the charinfo to shield us from any glyph positioning oddities
   * in the font that place the glyph for a character at other than the pos + advance
   * of the character to its left.  So we no longer need to skip chars with zero
   * advance, as their bounds (right and left) are already correct.
   */
  protected Rectangle2D createAlignBounds() {
    float[] info = getCharinfo();

    float al = 0f;
    float at = -cm.ascent;
    float aw = 0f;
    float ah = cm.ascent + cm.descent;

    boolean lineIsLTR = (source.getLayoutFlags() & 0x8) == 0;
    int rn = info.length - numvals;
    if (lineIsLTR) {
      while (rn > 0 && info[rn+visw] == 0) {
        rn -= numvals;
      }
    }

    if (rn >= 0) {
      int ln = 0;
      while (ln < rn && ((info[ln+advx] == 0) || (!lineIsLTR && info[ln+visw] == 0))) {
        ln += numvals;
      }

      al = Math.max(0f, info[ln+posx]);
      aw = info[rn+posx] + info[rn+advx] - al;
    }

    /*
      boolean lineIsLTR = source.lineIsLTR();
      int rn = info.length - numvals;
      while (rn > 0 && ((info[rn+advx] == 0) || (lineIsLTR && info[rn+visw] == 0))) {
      rn -= numvals;
      }

      if (rn >= 0) {
      int ln = 0;
      while (ln < rn && ((info[ln+advx] == 0) || (!lineIsLTR && info[ln+visw] == 0))) {
      ln += numvals;
      }

      al = Math.max(0f, info[ln+posx]);
      aw = info[rn+posx] + info[rn+advx] - al;
      }
      */

    return new Rectangle2D.Float(al, at, aw, ah);
  }

  public Rectangle2D createItalicBounds() {
    float ia = cm.italicAngle;

    Rectangle2D lb = getLogicalBounds();
    float l = (float)lb.getMinX();
    float t = -cm.ascent;
    float r = (float)lb.getMaxX();
    float b = cm.descent;
    if (ia != 0) {
        if (ia > 0) {
            l -= ia * (b - cm.ssOffset);
            r -= ia * (t - cm.ssOffset);
        } else {
            l -= ia * (t - cm.ssOffset);
            r -= ia * (b - cm.ssOffset);
        }
    }
    return new Rectangle2D.Float(l, t, r - l, b - t);
  }

  private final StandardGlyphVector getGV() {
    if (gv == null) {
      gv = createGV();
    }

    return gv;
  }

  protected StandardGlyphVector createGV() {
    FontRenderContext frc = source.getFRC();
    int flags = source.getLayoutFlags();
    char[] context = source.getChars();
    int start = source.getStart();
    int length = source.getLength();

    GlyphLayout gl = GlyphLayout.get(null); // !!! no custom layout engines
    gv = gl.layout(font, frc, context, start, length, flags, null); // ??? use textsource
    GlyphLayout.done(gl);

    return gv;
  }

  // ExtendedTextLabel API

  private static final int posx = 0,
    posy = 1,
    advx = 2,
    advy = 3,
    visx = 4,
    visy = 5,
    visw = 6,
    vish = 7;
  private static final int numvals = 8;

  public int getNumCharacters() {
    return source.getLength();
  }

  public CoreMetrics getCoreMetrics() {
    return cm;
  }

  public float getCharX(int index) {
    validate(index);
    return getCharinfo()[l2v(index) * numvals + posx];
  }

  public float getCharY(int index) {
    validate(index);
    return getCharinfo()[l2v(index) * numvals + posy];
  }

  public float getCharAdvance(int index) {
    validate(index);
    return getCharinfo()[l2v(index) * numvals + advx];
  }

  public Rectangle2D handleGetCharVisualBounds(int index) {
    validate(index);
    float[] charinfo = getCharinfo();
    index = l2v(index) * numvals;
    return new Rectangle2D.Float(
                                 charinfo[index + visx],
                                 charinfo[index + visy],
                                 charinfo[index + visw],
                                 charinfo[index + vish]);
  }

  public Rectangle2D getCharVisualBounds(int index, float x, float y) {

    Rectangle2D bounds = decorator.getCharVisualBounds(this, index);
    if (x != 0 || y != 0) {
        bounds.setRect(bounds.getX()+x,
                       bounds.getY()+y,
                       bounds.getWidth(),
                       bounds.getHeight());
    }
    return bounds;
  }

  private void validate(int index) {
    if (index < 0) {
      throw new IllegalArgumentException("index " + index + " < 0");
    } else if (index >= source.getLength()) {
      throw new IllegalArgumentException("index " + index + " < " + source.getLength());
    }
  }

  /*
    public int hitTestChar(float x, float y) {
    // !!! return index of char hit, for swing
    // result is negative for trailing-edge hits
    // no italics so no problem at margins.
    // for now, ignore y since we assume horizontal text

    // find non-combining char origin to right of x
    float[] charinfo = getCharinfo();

    int n = 0;
    int e = source.getLength();
    while (n < e && charinfo[n + advx] != 0 && charinfo[n + posx] > x) {
    n += numvals;
    }
    float rightx = n < e ? charinfo[n+posx] : charinfo[e - numvals + posx] + charinfo[e - numvals + advx];

    // find non-combining char to left of that char
    n -= numvals;
    while (n >= 0 && charinfo[n+advx] == 0) {
    n -= numvals;
    }
    float leftx = n >= 0 ? charinfo[n+posx] : 0;
    float lefta = n >= 0 ? charinfo[n+advx] : 0;

    n /= numvals;

    boolean left = true;
    if (x < leftx + lefta / 2f) {
    // left of prev char
    } else if (x < (leftx + lefta + rightx) / 2f) {
    // right of prev char
    left = false;
    } else {
    // left of follow char
    n += 1;
    }

    if ((source.getLayoutFlags() & 0x1) != 0) {
    n = getNumCharacters() - 1 - n;
    left = !left;
    }

    return left ? n : -n;
    }
    */

  public int logicalToVisual(int logicalIndex) {
    validate(logicalIndex);
    return l2v(logicalIndex);
  }

  public int visualToLogical(int visualIndex) {
    validate(visualIndex);
    return v2l(visualIndex);
  }

  public int getLineBreakIndex(int start, float width) {
    float[] charinfo = getCharinfo();
    int length = source.getLength();
    --start;
    while (width >= 0 && ++start < length) {
      float adv = charinfo[l2v(start) * numvals + advx];
      width -= adv;
    }

    return start;
  }

  public float getAdvanceBetween(int start, int limit) {
    float a = 0f;

    float[] charinfo = getCharinfo();
    --start;
    while (++start < limit) {
      a += charinfo[l2v(start) * numvals + advx];
    }

    return a;
  }

  public boolean caretAtOffsetIsValid(int offset) {
      // REMIND: improve this implementation

      // Ligature formation can either be done in logical order,
      // with the ligature glyph logically preceding the null
      // chars;  or in visual order, with the ligature glyph to
      // the left of the null chars.  This method's implementation
      // must reflect which strategy is used.

      if (offset == 0 || offset == source.getLength()) {
          return true;
      }
      char c = source.getChars()[source.getStart() + offset];
      if (c == '\t' || c == '\n' || c == '\r') { // hack
          return true;
      }
      int v = l2v(offset);

      // If ligatures are always to the left, do this stuff:
      //if (!(source.getLayoutFlags() & 0x1) == 0) {
      //    v += 1;
      //    if (v == source.getLength()) {
      //        return true;
      //    }
      //}

      return getCharinfo()[v * numvals + advx] != 0;
  }

  private final float[] getCharinfo() {
    if (charinfo == null) {
      charinfo = createCharinfo();
    }
    return charinfo;
  }

/*
* This takes the glyph info record obtained from the glyph vector and converts it into a similar record
* adjusted to represent character data instead.  For economy we don't use glyph info records in this processing.
*
* Here are some constraints:
* - there can be more glyphs than characters (glyph insertion, perhaps based on normalization, has taken place)
* - there can not be fewer glyphs than characters (0xffff glyphs are inserted for characters ligaturized away)
* - each glyph maps to a single character, when multiple glyphs exist for a character they all map to it, but
*   no two characters map to the same glyph
* - multiple glyphs mapping to the same character need not be in sequence (thai, tamil have split characters)
* - glyphs may be arbitrarily reordered (Indic reorders glyphs)
* - all glyphs share the same bidi level
* - all glyphs share the same horizontal (or vertical) baseline
* - combining marks visually follow their base character in the glyph array-- i.e. in an rtl gv they are
*   to the left of their base character-- and have zero advance.
*
* The output maps this to character positions, and therefore caret positions, via the following assumptions:
* - zero-advance glyphs do not contribute to the advance of their character (i.e. position is ignored), conversely
*   if a glyph is to contribute to the advance of its character it must have a non-zero (float) advance
* - no carets can appear between a zero width character and its preceeding character, where 'preceeding' is
*   defined logically.
* - no carets can appear within a split character
* - no carets can appear within a local reordering (i.e. Indic reordering, or non-adjacent split characters)
* - all characters lie on the same baseline, and it is either horizontal or vertical
* - the charinfo is in uniform ltr or rtl order (visual order), since local reorderings and split characters are removed
*
* The algorithm works in the following way:
* 1) we scan the glyphs ltr or rtl based on the bidi run direction
* 2) we can work in place, since we always consume a glyph for each char we write
*    a) if the line is ltr, we start writing at position 0 until we finish, there may be leftver space
*    b) if the line is rtl and 1-1, we start writing at position numChars/glyphs - 1 until we finish at 0
*    c) otherwise if we don't finish at 0, we have to copy the data down
* 3) we consume clusters in the following way:
*    a) the first element is always consumed
*    b) subsequent elements are consumed if:
*       i) their advance is zero
*       ii) their character index <= the character index of any character seen in this cluster
*       iii) the minimum character index seen in this cluster isn't adjacent to the previous cluster
*    c) character data is written as follows for horizontal lines (x/y and w/h are exchanged on vertical lines)
*       i) the x position is the position of the leftmost glyph whose advance is not zero
*       ii)the y position is the baseline
*       iii) the x advance is the distance to the maximum x + adv of all glyphs whose advance is not zero
*       iv) the y advance is the baseline
*       v) vis x,y,w,h tightly encloses the vis x,y,w,h of all the glyphs with nonzero w and h
* 4) we can make some simple optimizations if we know some things:
*    a) if the mapping is 1-1, unidirectional, and there are no zero-adv glyphs, we just return the glyphinfo
*    b) if the mapping is 1-1, unidirectional, we just adjust the remaining glyphs to originate at right/left of the base
*    c) if the mapping is 1-1, we compute the base position and advance as we go, then go back to adjust the remaining glyphs
*    d) otherwise we keep separate track of the write position as we do (c) since no glyph in the cluster may be in the
*    position we are writing.
*    e) most clusters are simply the single base glyph in the same position as its character, so we try to avoid
*    copying its data unnecessarily.
* 5) the glyph vector ought to provide access to these 'global' attributes to enable these optimizations.  A single
*    int with flags set is probably ok, we could also provide accessors for each attribute.  This doesn't map to
*    the GlyphMetrics flags very well, so I won't attempt to keep them similar.  It might be useful to add those
*    in addition to these.
*    int FLAG_HAS_ZERO_ADVANCE_GLYPHS = 1; // set if there are zero-advance glyphs
*    int FLAG_HAS_NONUNIFORM_ORDER = 2; // set if some glyphs are rearranged out of character visual order
*    int FLAG_HAS_SPLIT_CHARACTERS = 4; // set if multiple glyphs per character
*    int getDescriptionFlags(); // return an int containing the above flags
*    boolean hasZeroAdvanceGlyphs();
*    boolean hasNonuniformOrder();
*    boolean hasSplitCharacters();
*    The optimized cases in (4) correspond to values 0, 1, 3, and 7 returned by getDescriptionFlags().
*/
  protected float[] createCharinfo() {
    StandardGlyphVector gv = getGV();
    float[] glyphinfo = null;
    try {
        glyphinfo = gv.getGlyphInfo();
    }
    catch (Exception e) {
        System.out.println(source);
    }

    /*
    if ((gv.getDescriptionFlags() & 0x7) == 0) {
        return glyphinfo;
    }
    */

    int numGlyphs = gv.getNumGlyphs();
    int[] indices = gv.getGlyphCharIndices(0, numGlyphs, null);

    boolean DEBUG = false;
    if (DEBUG) {
      System.err.println("number of glyphs: " + numGlyphs);
      for (int i = 0; i < numGlyphs; ++i) {
        System.err.println("g: " + i +
            ", x: " + glyphinfo[i*numvals+posx] +
            ", a: " + glyphinfo[i*numvals+advx] +
            ", n: " + indices[i]);
      }
    }

    int minIndex = indices[0];  // smallest index seen this cluster
    int maxIndex = minIndex;    // largest index seen this cluster
    int nextMin = 0;            // expected smallest index for this cluster
    int cp = 0;                 // character position
    int cx = 0;                 // character index (logical)
    int gp = 0;                 // glyph position
    int gx = 0;                 // glyph index (visual)
    int gxlimit = numGlyphs;    // limit of gx, when we reach this we're done
    int pdelta = numvals;       // delta for incrementing positions
    int xdelta = 1;             // delta for incrementing indices

    boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
    if (!ltr) {
        minIndex = indices[numGlyphs - 1];
        maxIndex = minIndex;
        nextMin  = 0; // still logical
        cp = glyphinfo.length - numvals;
        cx = 0; // still logical
        gp = glyphinfo.length - numvals;
        gx = numGlyphs - 1;
        gxlimit = -1;
        pdelta = -numvals;
        xdelta = -1;
    }

    /*
    // to support vertical, use 'ixxxx' indices and swap horiz and vertical components
    if (source.isVertical()) {
        iposx = posy;
        iposy = posx;
        iadvx = advy;
        iadvy = advx;
        ivisx = visy;
        ivisy = visx;
        ivish = visw;
        ivisw = vish;
    } else {
        // use standard values
    }
    */

    // use intermediates to reduce array access when we need to
    float cposl = 0, cposr = 0, cvisl = 0, cvist = 0, cvisr = 0, cvisb = 0;
    float baseline = 0;

    // record if we have to copy data even when no cluster
    boolean mustCopy = false;

    while (gx != gxlimit) {
        // start of new cluster
        boolean haveCopy = false;
        int clusterExtraGlyphs = 0;

        minIndex = indices[gx];
        maxIndex = minIndex;

        // advance to next glyph
        gx += xdelta;
        gp += pdelta;

 /*
        while (gx != gxlimit && (glyphinfo[gp + advx] == 0 ||
                           minIndex != nextMin || indices[gx] <= maxIndex)) {
  */
        while (gx != gxlimit &&
               ((glyphinfo[gp + advx] == 0) ||
               (minIndex != nextMin) ||
               (indices[gx] <= maxIndex) ||
               (maxIndex - minIndex > clusterExtraGlyphs))) {
            // initialize base data first time through, using base glyph
            if (!haveCopy) {
                int gps = gp - pdelta;

                cposl = glyphinfo[gps + posx];
                cposr = cposl + glyphinfo[gps + advx];
                cvisl = glyphinfo[gps + visx];
                cvist = glyphinfo[gps + visy];
                cvisr = cvisl + glyphinfo[gps + visw];
                cvisb = cvist + glyphinfo[gps + vish];

                haveCopy = true;
            }

            // have an extra glyph in this cluster
            ++clusterExtraGlyphs;

            // adjust advance only if new glyph has non-zero advance
            float radvx = glyphinfo[gp + advx];
            if (radvx != 0) {
                float rposx = glyphinfo[gp + posx];
                cposl = Math.min(cposl, rposx);
                cposr = Math.max(cposr, rposx + radvx);
            }

            // adjust visible bounds only if new glyph has non-empty bounds
            float rvisw = glyphinfo[gp + visw];
            if (rvisw != 0) {
                float rvisx = glyphinfo[gp + visx];
                float rvisy = glyphinfo[gp + visy];
                cvisl = Math.min(cvisl, rvisx);
                cvist = Math.min(cvist, rvisy);
                cvisr = Math.max(cvisr, rvisx + rvisw);
                cvisb = Math.max(cvisb, rvisy + glyphinfo[gp + vish]);
            }

            // adjust min, max index
            minIndex = Math.min(minIndex, indices[gx]);
            maxIndex = Math.max(maxIndex, indices[gx]);

            // get ready to examine next glyph
            gx += xdelta;
            gp += pdelta;
        }
        // done with cluster, gx and gp are set for next glyph

        if (DEBUG) {
            System.out.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
        }

        nextMin = maxIndex + 1;

        // do common character adjustments
        glyphinfo[cp + posy] = baseline;
        glyphinfo[cp + advy] = 0;

        if (haveCopy) {
            // save adjustments to the base character
            glyphinfo[cp + posx] = cposl;
            glyphinfo[cp + advx] = cposr - cposl;
            glyphinfo[cp + visx] = cvisl;
            glyphinfo[cp + visy] = cvist;
            glyphinfo[cp + visw] = cvisr - cvisl;
            glyphinfo[cp + vish] = cvisb - cvist;

            // compare number of chars read with number of glyphs read.
            // if more glyphs than chars, set mustCopy to true, as we'll always have
            // to copy the data from here on out.
            if (maxIndex - minIndex < clusterExtraGlyphs) {
                mustCopy = true;
            }

            // Fix the characters that follow the base character.
            // New values are all the same.  Note we fix the number of characters
            // we saw, not the number of glyphs we saw.
            if (minIndex < maxIndex) {
                if (!ltr) {
                    // if rtl, characters to left of base, else to right.  reuse cposr.
                    cposr = cposl;
                }
                cvisr -= cvisl; // reuse, convert to deltas.
                cvisb -= cvist;

                int iMinIndex = minIndex, icp = cp / 8;

                while (minIndex < maxIndex) {
                    ++minIndex;
                    cx += xdelta;
                    cp += pdelta;

                    if (cp < 0 || cp >= glyphinfo.length) {
                        if (DEBUG) System.out.println("minIndex = " + iMinIndex + ", maxIndex = " + maxIndex + ", cp = " + icp);
                    }

                    glyphinfo[cp + posx] = cposr;
                    glyphinfo[cp + posy] = baseline;
                    glyphinfo[cp + advx] = 0;
                    glyphinfo[cp + advy] = 0;
                    glyphinfo[cp + visx] = cvisl;
                    glyphinfo[cp + visy] = cvist;
                    glyphinfo[cp + visw] = cvisr;
                    glyphinfo[cp + vish] = cvisb;
                }
            }

            // no longer using this copy
            haveCopy = false;
        } else if (mustCopy) {
            // out of synch, so we have to copy all the time now
            int gpr = gp - pdelta;

            glyphinfo[cp + posx] = glyphinfo[gpr + posx];
            glyphinfo[cp + advx] = glyphinfo[gpr + advx];
            glyphinfo[cp + visx] = glyphinfo[gpr + visx];
            glyphinfo[cp + visy] = glyphinfo[gpr + visy];
            glyphinfo[cp + visw] = glyphinfo[gpr + visw];
            glyphinfo[cp + vish] = glyphinfo[gpr + vish];
        }
        // else glyphinfo is already at the correct character position, and is unchanged, so just leave it

        // reset for new cluster
        cp += pdelta;
        cx += xdelta;
    }

    if (mustCopy && !ltr) {
        // data written to wrong end of array, need to shift down

        cp -= pdelta; // undo last increment, get start of valid character data in array
        System.arraycopy(glyphinfo, cp, glyphinfo, 0, glyphinfo.length - cp);
    }

    if (DEBUG) {
      char[] chars = source.getChars();
      int start = source.getStart();
      int length = source.getLength();
      System.out.println("char info for " + length + " characters");
      for(int i = 0; i < length * numvals;) {
        System.out.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
                           " x: " + glyphinfo[i++] +
                           " y: " + glyphinfo[i++] +
                           " xa: " + glyphinfo[i++] +
                           " ya: " + glyphinfo[i++] +
                           " l: " + glyphinfo[i++] +
                           " t: " + glyphinfo[i++] +
                           " w: " + glyphinfo[i++] +
                           " h: " + glyphinfo[i++]);
      }
    }

    return glyphinfo;
  }

  /**
   * Map logical character index to visual character index.
   * <p>
   * This ignores hindi reordering.  @see createCharinfo
   */
  protected int l2v(int index) {
    return (source.getLayoutFlags() & 0x1) == 0 ? index : source.getLength() - 1 - index;
  }

  /**
   * Map visual character index to logical character index.
   * <p>
   * This ignores hindi reordering.  @see createCharinfo
   */
  protected int v2l(int index) {
    return (source.getLayoutFlags() & 0x1) == 0 ? index : source.getLength() - 1 - index;
  }

  public TextLineComponent getSubset(int start, int limit, int dir) {
    return new ExtendedTextSourceLabel(source.getSubSource(start, limit-start, dir), decorator);
  }

  public String toString() {
    if (true) {
        return source.toString(source.WITHOUT_CONTEXT);
    }
    StringBuffer buf = new StringBuffer();
    buf.append(super.toString());
    buf.append("[source:");
    buf.append(source.toString(source.WITHOUT_CONTEXT));
    buf.append(", lb:");
    buf.append(lb);
    buf.append(", ab:");
    buf.append(ab);
    buf.append(", vb:");
    buf.append(vb);
    buf.append(", gv:");
    buf.append(gv);
    buf.append(", ci: ");
    if (charinfo == null) {
      buf.append("null");
    } else {
      buf.append(charinfo[0]);
      for (int i = 1; i < charinfo.length;) {
        buf.append(i % numvals == 0 ? "; " : ", ");
        buf.append(charinfo[i]);
      }
    }
    buf.append("]");

    return buf.toString();
  }

  //public static ExtendedTextLabel create(TextSource source) {
  //  return new ExtendedTextSourceLabel(source);
  //}

  public int getNumJustificationInfos() {
    return getGV().getNumGlyphs();
  }


  public void getJustificationInfos(GlyphJustificationInfo[] infos, int infoStart, int charStart, int charLimit) {
    // This simple implementation only uses spaces for justification.
    // Since regular characters aren't justified, we don't need to deal with
    // special infos for combining marks or ligature substitution glyphs.
    // added character justification for kanjii only 2/22/98

    StandardGlyphVector gv = getGV();

    float[] charinfo = getCharinfo();

    float size = gv.getFont().getSize2D();

    GlyphJustificationInfo nullInfo =
      new GlyphJustificationInfo(0,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0);

    GlyphJustificationInfo spaceInfo =
      new GlyphJustificationInfo(size,
                                 true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, size,
                                 true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, size / 4f);

    GlyphJustificationInfo kanjiInfo =
      new GlyphJustificationInfo(size,
                                 true, GlyphJustificationInfo.PRIORITY_INTERCHAR, size, size,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0);

    char[] chars = source.getChars();
    int offset = source.getStart();

    // assume data is 1-1 and either all rtl or all ltr, for now

    int numGlyphs = gv.getNumGlyphs();
    int minGlyph = 0;
    int maxGlyph = numGlyphs;
    boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
    if (charStart != 0 || charLimit != source.getLength()) {
      if (ltr) {
        minGlyph = charStart;
        maxGlyph = charLimit;
      } else {
        minGlyph = numGlyphs - charLimit;
        maxGlyph = numGlyphs - charStart;
      }
    }

    for (int i = 0; i < numGlyphs; ++i) {
      GlyphJustificationInfo info = null;
      if (i >= minGlyph && i < maxGlyph) {
        if (charinfo[i * numvals + advx] == 0) { // combining marks don't justify
          info = nullInfo;
        } else {
          int ci = v2l(i); // 1-1 assumption again
          char c = chars[offset + ci];
          if (Character.isWhitespace(c)) {
            info = spaceInfo;
            // CJK, Hangul, CJK Compatibility areas
          } else if (c >= 0x4e00 &&
                     (c < 0xa000) ||
                     (c >= 0xac00 && c < 0xd7b0) ||
                     (c >= 0xf900 && c < 0xfb00)) {
            info = kanjiInfo;
          } else {
            info = nullInfo;
          }
        }
      }
      infos[infoStart + i] = info;
    }
  }

  public TextLineComponent applyJustificationDeltas(float[] deltas, int deltaStart, boolean[] flags) {

    // when we justify, we need to adjust the charinfo since spaces
    // change their advances.  preserve the existing charinfo.

    float[] newCharinfo = (float[])getCharinfo().clone();

    // we only push spaces, so never need to rejustify
    flags[0] = false;

    // preserve the existing gv.

    StandardGlyphVector newgv = (StandardGlyphVector)getGV().clone();
    float[] newPositions = newgv.getGlyphPositions(null);
    int numGlyphs = newgv.getNumGlyphs();

    /*
    System.out.println("oldgv: " + getGV() + ", newgv: " + newgv);
    System.out.println("newpositions: " + newPositions);
    for (int i = 0; i < newPositions.length; i += 2) {
      System.out.println("[" + (i/2) + "] " + newPositions[i] + ", " + newPositions[i+1]);
    }

    System.out.println("deltas: " + deltas + " start: " + deltaStart);
    for (int i = deltaStart; i < deltaStart + numGlyphs; i += 2) {
      System.out.println("[" + (i/2) + "] " + deltas[i] + ", " + deltas[i+1]);
    }
    */

    char[] chars = source.getChars();
    int offset = source.getStart();

    // accumulate the deltas to adjust positions and advances.
    // handle whitespace by modifying advance,
    // handle everything else by modifying position before and after

    float deltaPos = 0;
    for (int i = 0; i < numGlyphs; ++i) {
      if (Character.isWhitespace(chars[offset + v2l(i)])) {
        newPositions[i*2] += deltaPos;

        float deltaAdv = deltas[deltaStart + i*2] + deltas[deltaStart + i*2 + 1];

        newCharinfo[i * numvals + posx] += deltaPos;
        newCharinfo[i * numvals + visx] += deltaPos;
        newCharinfo[i * numvals + advx] += deltaAdv;

        deltaPos += deltaAdv;
      } else {
        deltaPos += deltas[deltaStart + i*2];

        newPositions[i*2] += deltaPos;
        newCharinfo[i * numvals + posx] += deltaPos;
        newCharinfo[i * numvals + visx] += deltaPos;

        deltaPos += deltas[deltaStart + i*2 + 1];
      }
    }
    newPositions[numGlyphs * 2] += deltaPos;

    newgv.setGlyphPositions(newPositions);

    /*
    newPositions = newgv.getGlyphPositions(null);
    System.out.println(">> newpositions: " + newPositions);
    for (int i = 0; i < newPositions.length; i += 2) {
      System.out.println("[" + (i/2) + "] " + newPositions[i] + ", " + newPositions[i+1]);
    }
    */

    ExtendedTextSourceLabel result = new ExtendedTextSourceLabel(source, decorator);
    result.gv = newgv;
    result.charinfo = newCharinfo;

    return result;
  }
}
