/* GlyphView.java -- A view to render styled text
   Copyright (C) 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text;

import gnu.classpath.SystemProperties;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;

import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.text.Position.Bias;

/**
 * Renders a run of styled text. This {@link View} subclass paints the
 * characters of the <code>Element</code> it is responsible for using
 * the style information from that <code>Element</code>.
 *
 * @author Roman Kennke (roman@kennke.org)
 */
public class GlyphView extends View implements TabableView, Cloneable
{

  /**
   * An abstract base implementation for a glyph painter for
   * <code>GlyphView</code>.
   */
  public abstract static class GlyphPainter
  {
    /**
     * Creates a new <code>GlyphPainer</code>.
     */
    public GlyphPainter()
    {
      // Nothing to do here.
    }

    /**
     * Returns the ascent of the font that is used by this glyph painter.
     *
     * @param v the glyph view
     *
     * @return the ascent of the font that is used by this glyph painter
     */
    public abstract float getAscent(GlyphView v);

    /**
     * Returns the descent of the font that is used by this glyph painter.
     *
     * @param v the glyph view
     *
     * @return the descent of the font that is used by this glyph painter
     */
    public abstract float getDescent(GlyphView v);

    /**
     * Returns the full height of the rendered text.
     *
     * @return the full height of the rendered text
     */
    public abstract float getHeight(GlyphView view);

    /**
     * Determines the model offset, so that the text between <code>p0</code>
     * and this offset fits within the span starting at <code>x</code> with
     * the length of <code>len</code>. 
     *
     * @param v the glyph view
     * @param p0 the starting offset in the model
     * @param x the start location in the view
     * @param len the length of the span in the view
     */
    public abstract int getBoundedPosition(GlyphView v, int p0, float x,
                                           float len);

    /**
     * Paints the glyphs.
     *
     * @param view the glyph view to paint
     * @param g the graphics context to use for painting
     * @param a the allocation of the glyph view
     * @param p0 the start position (in the model) from which to paint
     * @param p1 the end position (in the model) to which to paint
     */
    public abstract void paint(GlyphView view, Graphics g, Shape a, int p0,
                               int p1);

    /**
     * Maps a position in the document into the coordinate space of the View.
     * The output rectangle usually reflects the font height but has a width
     * of zero.
     *
     * @param view the glyph view
     * @param pos the position of the character in the model
     * @param a the area that is occupied by the view
     * @param b either {@link Position.Bias#Forward} or
     *        {@link Position.Bias#Backward} depending on the preferred
     *        direction bias. If <code>null</code> this defaults to
     *        <code>Position.Bias.Forward</code>
     *
     * @return a rectangle that gives the location of the document position
     *         inside the view coordinate space
     *
     * @throws BadLocationException if <code>pos</code> is invalid
     * @throws IllegalArgumentException if b is not one of the above listed
     *         valid values
     */
    public abstract Shape modelToView(GlyphView view, int pos, Position.Bias b,
                                      Shape a)
      throws BadLocationException;

    /**
     * Maps a visual position into a document location.
     *
     * @param v the glyph view
     * @param x the X coordinate of the visual position
     * @param y the Y coordinate of the visual position
     * @param a the allocated region
     * @param biasRet filled with the bias of the model location on method exit
     *
     * @return the model location that represents the specified view location
     */
    public abstract int viewToModel(GlyphView v, float x, float y, Shape a,
                                    Position.Bias[] biasRet);

    /**
     * Determine the span of the glyphs from location <code>p0</code> to
     * location <code>p1</code>. If <code>te</code> is not <code>null</code>,
     * then TABs are expanded using this <code>TabExpander</code>.
     * The parameter <code>x</code> is the location at which the view is
     * located (this is important when using TAB expansion).
     *
     * @param view the glyph view
     * @param p0 the starting location in the document model
     * @param p1 the end location in the document model
     * @param te the tab expander to use
     * @param x the location at which the view is located
     *
     * @return the span of the glyphs from location <code>p0</code> to
     *         location <code>p1</code>, possibly using TAB expansion
     */
    public abstract float getSpan(GlyphView view, int p0, int p1,
                                  TabExpander te, float x);


    /**
     * Returns the model location that should be used to place a caret when
     * moving the caret through the document.
     *
     * @param v the glyph view
     * @param pos the current model location
     * @param b the bias for <code>p</code>
     * @param a the allocated region for the glyph view
     * @param direction the direction from the current position; Must be one of
     *        {@link SwingConstants#EAST}, {@link SwingConstants#WEST},
     *        {@link SwingConstants#NORTH} or {@link SwingConstants#SOUTH}
     * @param biasRet filled with the bias of the resulting location when method
     *        returns
     *
     * @return the location within the document that should be used to place the
     *         caret when moving the caret around the document
     *
     * @throws BadLocationException if <code>pos</code> is an invalid model
     *         location
     * @throws IllegalArgumentException if <code>d</code> is invalid
     */
    public int getNextVisualPositionFrom(GlyphView v, int pos, Position.Bias b,
                                         Shape a, int direction,
                                         Position.Bias[] biasRet)
      throws BadLocationException

    {
      int result = pos;
      switch (direction)
      {
        case SwingConstants.EAST:
          result = pos + 1;
          break;
        case SwingConstants.WEST:
          result = pos - 1;
          break;
        case SwingConstants.NORTH:
        case SwingConstants.SOUTH:
        default:
          // This should be handled in enclosing view, since the glyph view
          // does not layout vertically.
          break;
      }
      return result;
    }

    /**
     * Returns a painter that can be used to render the specified glyph view.
     * If this glyph painter is stateful, then it should return a new instance.
     * However, if this painter is stateless it should return itself. The
     * default behaviour is to return itself.
     *
     * @param v the glyph view for which to create a painter
     * @param p0 the start offset of the rendered area
     * @param p1 the end offset of the rendered area
     *
     * @return a painter that can be used to render the specified glyph view
     */
    public GlyphPainter getPainter(GlyphView v, int p0, int p1)
    {
      return this;
    }
  }

  /**
   * A GlyphPainter implementation based on TextLayout. This should give
   * better performance in Java2D environments.
   */
  private static class J2DGlyphPainter
    extends GlyphPainter
  {

    /**
     * The text layout.
     */
    TextLayout textLayout;

    /**
     * Creates a new J2DGlyphPainter.
     *
     * @param str the string
     * @param font the font
     * @param frc the font render context
     */
    J2DGlyphPainter(String str, Font font, FontRenderContext frc)
    {
      textLayout = new TextLayout(str, font, frc);
    }

    /**
     * Returns null so that GlyphView.checkPainter() creates a new instance.
     */
    public GlyphPainter getPainter(GlyphView v, int p0, int p1)
    {
      return null;
    }

    /**
     * Delegates to the text layout.
     */
    public float getAscent(GlyphView v)
    {
      return textLayout.getAscent();
    }

    /**
     * Delegates to the text layout.
     */
    public int getBoundedPosition(GlyphView v, int p0, float x, float len)
    {
      int pos;
      TextHitInfo hit = textLayout.hitTestChar(len, 0);
      if (hit.getCharIndex() == -1 && ! textLayout.isLeftToRight())
        pos = v.getEndOffset();
      else
        {
          pos = hit.isLeadingEdge() ? hit.getInsertionIndex()
                                    : hit.getInsertionIndex() - 1;
          pos += v.getStartOffset();
        }
      return pos;
    }

    /**
     * Delegates to the text layout.
     */
    public float getDescent(GlyphView v)
    {
      return textLayout.getDescent();
    }

    /**
     * Delegates to the text layout.
     */
    public float getHeight(GlyphView view)
    {
      return textLayout.getAscent() + textLayout.getDescent()
             + textLayout.getLeading();
    }

    /**
     * Delegates to the text layout.
     */
    public float getSpan(GlyphView v, int p0, int p1, TabExpander te, float x)
    {
      float span;
      if (p0 == v.getStartOffset() && p1 == v.getEndOffset())
        span = textLayout.getAdvance();
      else
        {
          int start = v.getStartOffset();
          int i0 = p0 - start;
          int i1 = p1 - start;
          TextHitInfo hit0 = TextHitInfo.afterOffset(i0);
          TextHitInfo hit1 = TextHitInfo.afterOffset(i1);
          float x0 = textLayout.getCaretInfo(hit0)[0];
          float x1 = textLayout.getCaretInfo(hit1)[0];
          span = Math.abs(x1 - x0);
        }
      return span;
    }

    /**
     * Delegates to the text layout.
     */
    public Shape modelToView(GlyphView v, int pos, Bias b, Shape a)
      throws BadLocationException
    {
      int offs = pos - v.getStartOffset();
      // Create copy here to protect original shape.
      Rectangle2D bounds = a.getBounds2D();
      TextHitInfo hit =
        b == Position.Bias.Forward ? TextHitInfo.afterOffset(offs)
                                   : TextHitInfo.beforeOffset(offs);
      float[] loc = textLayout.getCaretInfo(hit);
      bounds.setRect(bounds.getX() + loc[0], bounds.getY(), 1,
                     bounds.getHeight());
      return bounds;
    }

    /**
     * Delegates to the text layout.
     */
    public void paint(GlyphView view, Graphics g, Shape a, int p0, int p1)
    {
      // Can't paint this with plain graphics.
      if (g instanceof Graphics2D)
        {
          Graphics2D g2d = (Graphics2D) g;
          Rectangle2D b = a instanceof Rectangle2D ? (Rectangle2D) a
                                                   : a.getBounds2D();
          float x = (float) b.getX();
          float y = (float) b.getY() + textLayout.getAscent()
                    + textLayout.getLeading();
          // TODO: Try if clipping makes things faster for narrow views.
          textLayout.draw(g2d, x, y);
        }
    }

    /**
     * Delegates to the text layout.
     */
    public int viewToModel(GlyphView v, float x, float y, Shape a,
                           Bias[] biasRet)
    {
      Rectangle2D bounds = a instanceof Rectangle2D ? (Rectangle2D) a
                                                    : a.getBounds2D();
      TextHitInfo hit = textLayout.hitTestChar(x - (float) bounds.getX(), 0);
      int pos = hit.getInsertionIndex();
      biasRet[0] = hit.isLeadingEdge() ? Position.Bias.Forward
                                       : Position.Bias.Backward;
      return pos + v.getStartOffset();
    }
    
  }

  /**
   * The default <code>GlyphPainter</code> used in <code>GlyphView</code>.
   */
  static class DefaultGlyphPainter extends GlyphPainter
  {
    FontMetrics fontMetrics;

    /**
     * Returns the full height of the rendered text.
     *
     * @return the full height of the rendered text
     */
    public float getHeight(GlyphView view)
    {
      updateFontMetrics(view);
      float height = fontMetrics.getHeight();
      return height;
    }
    
    /**
     * Paints the glyphs.
     *
     * @param view the glyph view to paint
     * @param g the graphics context to use for painting
     * @param a the allocation of the glyph view
     * @param p0 the start position (in the model) from which to paint
     * @param p1 the end position (in the model) to which to paint
     */
    public void paint(GlyphView view, Graphics g, Shape a, int p0,
                      int p1)
    {
      updateFontMetrics(view);
      Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
      TabExpander tabEx = view.getTabExpander();
      Segment txt = view.getText(p0, p1);

      // Find out the X location at which we have to paint.
      int x = r.x;
      int p = view.getStartOffset();
      if (p != p0)
        {
          int width = Utilities.getTabbedTextWidth(txt, fontMetrics,x, tabEx,
                                                   p);
          x += width;
        }
      // Find out Y location.
      int y = r.y + fontMetrics.getHeight() - fontMetrics.getDescent();

      // Render the thing.
      g.setFont(fontMetrics.getFont());
      Utilities.drawTabbedText(txt, x, y, g, tabEx, p0);

    }

    /**
     * Maps a position in the document into the coordinate space of the View.
     * The output rectangle usually reflects the font height but has a width
     * of zero.
     *
     * @param view the glyph view
     * @param pos the position of the character in the model
     * @param a the area that is occupied by the view
     * @param b either {@link Position.Bias#Forward} or
     *        {@link Position.Bias#Backward} depending on the preferred
     *        direction bias. If <code>null</code> this defaults to
     *        <code>Position.Bias.Forward</code>
     *
     * @return a rectangle that gives the location of the document position
     *         inside the view coordinate space
     *
     * @throws BadLocationException if <code>pos</code> is invalid
     * @throws IllegalArgumentException if b is not one of the above listed
     *         valid values
     */
    public Shape modelToView(GlyphView view, int pos, Position.Bias b,
                             Shape a)
      throws BadLocationException
    {
      updateFontMetrics(view);
      Element el = view.getElement();
      Segment txt = view.getText(el.getStartOffset(), pos);
      Rectangle bounds = a instanceof Rectangle ? (Rectangle) a
                                                : a.getBounds();
      TabExpander expander = view.getTabExpander();
      int width = Utilities.getTabbedTextWidth(txt, fontMetrics, bounds.x,
                                               expander,
                                               view.getStartOffset());
      int height = fontMetrics.getHeight();
      Rectangle result = new Rectangle(bounds.x + width, bounds.y,
                                       0, height);
      return result;
    }

    /**
     * Determine the span of the glyphs from location <code>p0</code> to
     * location <code>p1</code>. If <code>te</code> is not <code>null</code>,
     * then TABs are expanded using this <code>TabExpander</code>.
     * The parameter <code>x</code> is the location at which the view is
     * located (this is important when using TAB expansion).
     *
     * @param view the glyph view
     * @param p0 the starting location in the document model
     * @param p1 the end location in the document model
     * @param te the tab expander to use
     * @param x the location at which the view is located
     *
     * @return the span of the glyphs from location <code>p0</code> to
     *         location <code>p1</code>, possibly using TAB expansion
     */
    public float getSpan(GlyphView view, int p0, int p1,
                         TabExpander te, float x)
    {
      updateFontMetrics(view);
      Segment txt = view.getText(p0, p1);
      int span = Utilities.getTabbedTextWidth(txt, fontMetrics, (int) x, te,
                                              p0);
      return span;
    }

    /**
     * Returns the ascent of the text run that is rendered by this
     * <code>GlyphPainter</code>.
     *
     * @param v the glyph view
     *
     * @return the ascent of the text run that is rendered by this
     *         <code>GlyphPainter</code>
     *
     * @see FontMetrics#getAscent()
     */
    public float getAscent(GlyphView v)
    {
      updateFontMetrics(v);
      return fontMetrics.getAscent();
    }

    /**
     * Returns the descent of the text run that is rendered by this
     * <code>GlyphPainter</code>.
     *
     * @param v the glyph view
     *
     * @return the descent of the text run that is rendered by this
     *         <code>GlyphPainter</code>
     *
     * @see FontMetrics#getDescent()
     */
    public float getDescent(GlyphView v)
    {
      updateFontMetrics(v);
      return fontMetrics.getDescent();
    }

    /**
     * Determines the model offset, so that the text between <code>p0</code>
     * and this offset fits within the span starting at <code>x</code> with
     * the length of <code>len</code>. 
     *
     * @param v the glyph view
     * @param p0 the starting offset in the model
     * @param x the start location in the view
     * @param len the length of the span in the view
     */
    public int getBoundedPosition(GlyphView v, int p0, float x, float len)
    {
      updateFontMetrics(v);
      TabExpander te = v.getTabExpander();
      Segment txt = v.getText(p0, v.getEndOffset());
      int pos = Utilities.getTabbedTextOffset(txt, fontMetrics, (int) x,
                                              (int) (x + len), te, p0, false);
      return pos + p0;
    }

    /**
     * Maps a visual position into a document location.
     *
     * @param v the glyph view
     * @param x the X coordinate of the visual position
     * @param y the Y coordinate of the visual position
     * @param a the allocated region
     * @param biasRet filled with the bias of the model location on method exit
     *
     * @return the model location that represents the specified view location
     */
    public int viewToModel(GlyphView v, float x, float y, Shape a,
                           Bias[] biasRet)
    {
      Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
      int p0 = v.getStartOffset();
      int p1 = v.getEndOffset();
      TabExpander te = v.getTabExpander();
      Segment s = v.getText(p0, p1);
      int offset = Utilities.getTabbedTextOffset(s, fontMetrics, r.x, (int) x,
                                                 te, p0);
      int ret = p0 + offset;
      if (ret == p1)
        ret--;
      biasRet[0] = Position.Bias.Forward;
      return ret;
    }

    private void updateFontMetrics(GlyphView v)
    {
      Font font = v.getFont();
      if (fontMetrics == null || ! font.equals(fontMetrics.getFont()))
        {
          Container c = v.getContainer();
          FontMetrics fm;
          if (c != null)
            fm = c.getFontMetrics(font);
          else
            fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
          fontMetrics = fm;
        }
    }
  }

  /**
   * The GlyphPainer used for painting the glyphs.
   */
  GlyphPainter glyphPainter;

  /**
   * The start offset within the document for this view.
   */
  private int offset;

  /**
   * The end offset within the document for this view.
   */
  private int length;

  /**
   * The x location against which the tab expansion is done.
   */
  private float tabX;

  /**
   * The tab expander that is used in this view.
   */
  private TabExpander tabExpander;

  /**
   * Creates a new <code>GlyphView</code> for the given <code>Element</code>.
   *
   * @param element the element that is rendered by this GlyphView
   */
  public GlyphView(Element element)
  {
    super(element);
    offset = 0;
    length = 0;
  }

  /**
   * Returns the <code>GlyphPainter</code> that is used by this
   * <code>GlyphView</code>. If no <code>GlyphPainer</code> has been installed
   * <code>null</code> is returned.
   *
   * @return the glyph painter that is used by this
   *         glyph view or <code>null</code> if no glyph painter has been
   *         installed
   */
  public GlyphPainter getGlyphPainter()
  {
    return glyphPainter;
  }

  /**
   * Sets the {@link GlyphPainter} to be used for this <code>GlyphView</code>.
   *
   * @param painter the glyph painter to be used for this glyph view
   */
  public void setGlyphPainter(GlyphPainter painter)
  {
    glyphPainter = painter;
  }

  /**
   * Checks if a <code>GlyphPainer</code> is installed. If this is not the
   * case, a default painter is installed.
   */
  protected void checkPainter()
  {
    if (glyphPainter == null)
      {
        if ("true".equals(
                 SystemProperties.getProperty("gnu.javax.swing.noGraphics2D")))
          {
            glyphPainter = new DefaultGlyphPainter();
          }
        else
          {
            Segment s = getText(getStartOffset(), getEndOffset());
            glyphPainter = new J2DGlyphPainter(s.toString(), getFont(),
                                               new FontRenderContext(null,
                                                                     false,
                                                                     false));
          }
      }
  }

  /**
   * Renders the <code>Element</code> that is associated with this
   * <code>View</code>.
   *
   * @param g the <code>Graphics</code> context to render to
   * @param a the allocated region for the <code>Element</code>
   */
  public void paint(Graphics g, Shape a)
  {
    checkPainter();
    int p0 = getStartOffset();
    int p1 = getEndOffset();

    Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
    Container c = getContainer();

    Color fg = getForeground();
    JTextComponent tc = null;
    if (c instanceof JTextComponent)
      {
        tc = (JTextComponent) c;
        if (! tc.isEnabled())
          fg = tc.getDisabledTextColor();
      }
    Color bg = getBackground();
    if (bg != null)
      {
        g.setColor(bg);
        g.fillRect(r.x, r.y, r.width, r.height);
      }

    
    // Paint layered highlights if there are any.
    if (tc != null)
      {
        Highlighter h = tc.getHighlighter();
        if (h instanceof LayeredHighlighter)
          {
            LayeredHighlighter lh = (LayeredHighlighter) h;
            lh.paintLayeredHighlights(g, p0, p1, a, tc, this);
          }
      }

    g.setColor(fg);
    glyphPainter.paint(this, g, a, p0, p1);
    boolean underline = isUnderline();
    boolean striked = isStrikeThrough();
    if (underline || striked)
      {
        View parent = getParent();
        // X coordinate.
        if (parent != null && parent.getEndOffset() == p1)
          {
            // Strip whitespace.
            Segment s = getText(p0, p1);
            while (s.count > 0 && Character.isWhitespace(s.array[s.count - 1]))
              {
                p1--;
                s.count--;
              }
          }
        int x0 = r.x;
        int p = getStartOffset();
        TabExpander tabEx = getTabExpander();
        if (p != p0)
          x0 += (int) glyphPainter.getSpan(this, p, p0, tabEx, x0);
        int x1 = x0 + (int) glyphPainter.getSpan(this, p0, p1, tabEx, x0);
        // Y coordinate.
        int y = r.y + r.height - (int) glyphPainter.getDescent(this);
        if (underline)
          {
            int yTmp = y;
            yTmp += 1;
            g.drawLine(x0, yTmp, x1, yTmp);
          }
        if (striked)
          {
            int yTmp = y;
            yTmp -= (int) glyphPainter.getAscent(this);
            g.drawLine(x0, yTmp, x1, yTmp);
          }
      }
  }


  /**
   * Returns the preferred span of the content managed by this
   * <code>View</code> along the specified <code>axis</code>.
   *
   * @param axis the axis
   *
   * @return the preferred span of this <code>View</code>.
   */
  public float getPreferredSpan(int axis)
  {
    float span = 0;
    checkPainter();
    GlyphPainter painter = getGlyphPainter();
    switch (axis)
      {
      case X_AXIS:
        TabExpander tabEx = null;
        View parent = getParent();
        if (parent instanceof TabExpander)
          tabEx = (TabExpander) parent;
        span = painter.getSpan(this, getStartOffset(), getEndOffset(),
                               tabEx, 0.F);
        break;
      case Y_AXIS:
        span = painter.getHeight(this);
        if (isSuperscript())
          span += span / 3;
        break;
      default:
        throw new IllegalArgumentException("Illegal axis");
      }
    return span;
  }

  /**
   * Maps a position in the document into the coordinate space of the View.
   * The output rectangle usually reflects the font height but has a width
   * of zero.
   *
   * @param pos the position of the character in the model
   * @param a the area that is occupied by the view
   * @param b either {@link Position.Bias#Forward} or
   *        {@link Position.Bias#Backward} depending on the preferred
   *        direction bias. If <code>null</code> this defaults to
   *        <code>Position.Bias.Forward</code>
   *
   * @return a rectangle that gives the location of the document position
   *         inside the view coordinate space
   *
   * @throws BadLocationException if <code>pos</code> is invalid
   * @throws IllegalArgumentException if b is not one of the above listed
   *         valid values
   */
  public Shape modelToView(int pos, Shape a, Position.Bias b)
    throws BadLocationException
  {
    GlyphPainter p = getGlyphPainter();
    return p.modelToView(this, pos, b, a);
  }

  /**
   * Maps coordinates from the <code>View</code>'s space into a position
   * in the document model.
   *
   * @param x the x coordinate in the view space
   * @param y the y coordinate in the view space
   * @param a the allocation of this <code>View</code>
   * @param b the bias to use
   *
   * @return the position in the document that corresponds to the screen
   *         coordinates <code>x, y</code>
   */
  public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
  {
    checkPainter();
    GlyphPainter painter = getGlyphPainter();
    return painter.viewToModel(this, x, y, a, b);
  }

  /**
   * Return the {@link TabExpander} to use.
   *
   * @return the {@link TabExpander} to use
   */
  public TabExpander getTabExpander()
  {
    return tabExpander;
  }

  /**
   * Returns the preferred span of this view for tab expansion.
   *
   * @param x the location of the view
   * @param te the tab expander to use
   *
   * @return the preferred span of this view for tab expansion
   */
  public float getTabbedSpan(float x, TabExpander te)
  {
    checkPainter();
    TabExpander old = tabExpander;
    tabExpander = te;
    if (tabExpander != old)
      {
        // Changing the tab expander will lead to a relayout in the X_AXIS.
        preferenceChanged(null, true, false);
      }
    tabX = x;
    return getGlyphPainter().getSpan(this, getStartOffset(),
                                     getEndOffset(), tabExpander, x);
  }

  /**
   * Returns the span of a portion of the view. This is used in TAB expansion
   * for fragments that don't contain TABs.
   *
   * @param p0 the start index
   * @param p1 the end index
   *
   * @return the span of the specified portion of the view
   */
  public float getPartialSpan(int p0, int p1)
  {
    checkPainter();
    return glyphPainter.getSpan(this, p0, p1, tabExpander, tabX);
  }

  /**
   * Returns the start offset in the document model of the portion
   * of text that this view is responsible for.
   *
   * @return the start offset in the document model of the portion
   *         of text that this view is responsible for
   */
  public int getStartOffset()
  {
    Element el = getElement();
    int offs = el.getStartOffset();
    if (length > 0)
      offs += offset;
    return offs;
  }

  /**
   * Returns the end offset in the document model of the portion
   * of text that this view is responsible for.
   *
   * @return the end offset in the document model of the portion
   *         of text that this view is responsible for
   */
  public int getEndOffset()
  {
    Element el = getElement();
    int offs;
    if (length > 0)
      offs = el.getStartOffset() + offset + length;
    else
      offs = el.getEndOffset();
    return offs;
  }

  private Segment cached = new Segment();

  /**
   * Returns the text segment that this view is responsible for.
   *
   * @param p0 the start index in the document model
   * @param p1 the end index in the document model
   *
   * @return the text segment that this view is responsible for
   */
  public Segment getText(int p0, int p1)
  {
    try
      {
        getDocument().getText(p0, p1 - p0, cached);
      }
    catch (BadLocationException ex)
      {
	AssertionError ae;
        ae = new AssertionError("BadLocationException should not be "
				+ "thrown here. p0 = " + p0 + ", p1 = " + p1);
	ae.initCause(ex);
	throw ae;
      }

    return cached;
  }

  /**
   * Returns the font for the text run for which this <code>GlyphView</code>
   * is responsible.
   *
   * @return the font for the text run for which this <code>GlyphView</code>
   *         is responsible
   */
  public Font getFont()
  {
    Document doc = getDocument();
    Font font = null;
    if (doc instanceof StyledDocument)
      {
        StyledDocument styledDoc = (StyledDocument) doc;
        font = styledDoc.getFont(getAttributes());
      }
    else
      {
        Container c = getContainer();
        if (c != null)
          font = c.getFont();
      }
    return font;
  }

  /**
   * Returns the foreground color which should be used to paint the text.
   * This is fetched from the associated element's text attributes using
   * {@link StyleConstants#getForeground}.
   *
   * @return the foreground color which should be used to paint the text
   */
  public Color getForeground()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    return StyleConstants.getForeground(atts);
  }

  /**
   * Returns the background color which should be used to paint the text.
   * This is fetched from the associated element's text attributes using
   * {@link StyleConstants#getBackground}.
   *
   * @return the background color which should be used to paint the text
   */
  public Color getBackground()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    // We cannot use StyleConstants.getBackground() here, because that returns
    // BLACK as default (when background == null). What we need is the
    // background setting of the text component instead, which is what we get
    // when background == null anyway.
    return (Color) atts.getAttribute(StyleConstants.Background);
  }

  /**
   * Determines whether the text should be rendered strike-through or not. This
   * is determined using the method
   * {@link StyleConstants#isStrikeThrough(AttributeSet)} on the element of
   * this view.
   *
   * @return whether the text should be rendered strike-through or not
   */
  public boolean isStrikeThrough()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    return StyleConstants.isStrikeThrough(atts);
  }

  /**
   * Determines whether the text should be rendered as subscript or not. This
   * is determined using the method
   * {@link StyleConstants#isSubscript(AttributeSet)} on the element of
   * this view.
   *
   * @return whether the text should be rendered as subscript or not
   */
  public boolean isSubscript()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    return StyleConstants.isSubscript(atts);
  }

  /**
   * Determines whether the text should be rendered as superscript or not. This
   * is determined using the method
   * {@link StyleConstants#isSuperscript(AttributeSet)} on the element of
   * this view.
   *
   * @return whether the text should be rendered as superscript or not
   */
  public boolean isSuperscript()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    return StyleConstants.isSuperscript(atts);
  }

  /**
   * Determines whether the text should be rendered as underlined or not. This
   * is determined using the method
   * {@link StyleConstants#isUnderline(AttributeSet)} on the element of
   * this view.
   *
   * @return whether the text should be rendered as underlined or not
   */
  public boolean isUnderline()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    return StyleConstants.isUnderline(atts);
  }

  /**
   * Creates and returns a shallow clone of this GlyphView. This is used by
   * the {@link #createFragment} and {@link #breakView} methods.
   *
   * @return a shallow clone of this GlyphView
   */
  protected final Object clone()
  {
    try
      {
        return super.clone();
      }
    catch (CloneNotSupportedException ex)
      {
        AssertionError err = new AssertionError("CloneNotSupportedException "
                                                + "must not be thrown here");
        err.initCause(ex);
        throw err;
      }
  }

  /**
   * Tries to break the view near the specified view span <code>len</code>.
   * The glyph view can only be broken in the X direction. For Y direction it
   * returns itself.
   *
   * @param axis the axis for breaking, may be {@link View#X_AXIS} or
   *        {@link View#Y_AXIS}
   * @param p0 the model location where the fragment should start
   * @param pos the view position along the axis where the fragment starts
   * @param len the desired length of the fragment view
   *
   * @return the fragment view, or <code>this</code> if breaking was not
   *         possible
   */
  public View breakView(int axis, int p0, float pos, float len)
  {
    View brokenView = this;
    if (axis == X_AXIS)
      {
        checkPainter();
        int end = glyphPainter.getBoundedPosition(this, p0, pos, len);
        int breakLoc = getBreakLocation(p0, end);
        if (breakLoc != -1)
          end = breakLoc;
        if (p0 != getStartOffset() || end != getEndOffset())
          {
            brokenView = createFragment(p0, end);
            if (brokenView instanceof GlyphView)
              ((GlyphView) brokenView).tabX = pos;
          }
      }
    return brokenView;
  }

  /**
   * Determines how well the specified view location is suitable for inserting
   * a line break. If <code>axis</code> is <code>View.Y_AXIS</code>, then
   * this method forwards to the superclass, if <code>axis</code> is
   * <code>View.X_AXIS</code> then this method returns
   * {@link View#ExcellentBreakWeight} if there is a suitable break location
   * (usually whitespace) within the specified view span, or
   * {@link View#GoodBreakWeight} if not.
   *
   * @param axis the axis along which the break weight is requested
   * @param pos the starting view location
   * @param len the length of the span at which the view should be broken
   *
   * @return the break weight
   */
  public int getBreakWeight(int axis, float pos, float len)
  {
    int weight;
    if (axis == Y_AXIS)
      weight = super.getBreakWeight(axis, pos, len);
    else
      {
        checkPainter();
        int start = getStartOffset();
        int end = glyphPainter.getBoundedPosition(this, start, pos, len);
        if (end == 0)
          weight = BadBreakWeight;
        else
          {
            if (getBreakLocation(start, end) != -1)
              weight = ExcellentBreakWeight;
            else
              weight = GoodBreakWeight;
          }
      }
    return weight;
  }

  private int getBreakLocation(int start, int end)
  {
    int loc = -1;
    Segment s = getText(start, end);
    for (char c = s.last(); c != Segment.DONE && loc == -1; c = s.previous())
      {
        if (Character.isWhitespace(c))
          {
            loc = s.getIndex() - s.getBeginIndex() + 1 + start;
          }
      }
    return loc;
  }

  /**
   * Receives notification that some text attributes have changed within the
   * text fragment that this view is responsible for. This calls
   * {@link View#preferenceChanged(View, boolean, boolean)} on the parent for
   * both width and height.
   *
   * @param e the document event describing the change; not used here
   * @param a the view allocation on screen; not used here
   * @param vf the view factory; not used here
   */
  public void changedUpdate(DocumentEvent e, Shape a, ViewFactory vf)
  {
    preferenceChanged(null, true, true);
  }

  /**
   * Receives notification that some text has been inserted within the
   * text fragment that this view is responsible for. This calls
   * {@link View#preferenceChanged(View, boolean, boolean)} for the
   * direction in which the glyphs are rendered.
   *
   * @param e the document event describing the change; not used here
   * @param a the view allocation on screen; not used here
   * @param vf the view factory; not used here
   */
  public void insertUpdate(DocumentEvent e, Shape a, ViewFactory vf)
  {
    preferenceChanged(null, true, false);
  }

  /**
   * Receives notification that some text has been removed within the
   * text fragment that this view is responsible for. This calls
   * {@link View#preferenceChanged(View, boolean, boolean)} on the parent for
   * width.
   *
   * @param e the document event describing the change; not used here
   * @param a the view allocation on screen; not used here
   * @param vf the view factory; not used here
   */
  public void removeUpdate(DocumentEvent e, Shape a, ViewFactory vf)
  {
    preferenceChanged(null, true, false);
  }

  /**
   * Creates a fragment view of this view that starts at <code>p0</code> and
   * ends at <code>p1</code>.
   *
   * @param p0 the start location for the fragment view
   * @param p1 the end location for the fragment view
   *
   * @return the fragment view
   */
  public View createFragment(int p0, int p1)
  {
    checkPainter();
    Element el = getElement();
    GlyphView fragment = (GlyphView) clone();
    fragment.offset = p0 - el.getStartOffset();
    fragment.length = p1 - p0;
    fragment.glyphPainter = glyphPainter.getPainter(fragment, p0, p1);
    return fragment;
  }

  /**
   * Returns the alignment of this view along the specified axis. For the Y
   * axis this is <code>(height - descent) / height</code> for the used font,
   * so that it is aligned along the baseline.
   * For the X axis the superclass is called.
   */
  public float getAlignment(int axis)
  {
    checkPainter();
    float align;
    if (axis == Y_AXIS)
      {
        GlyphPainter painter = getGlyphPainter();
        float height = painter.getHeight(this);
        float descent = painter.getDescent(this);
        float ascent = painter.getAscent(this);
        if (isSuperscript())
          align = 1.0F;
        else if (isSubscript())
          align = height > 0 ? (height - (descent + (ascent / 2))) / height
                             : 0;
        else
          align = height > 0 ? (height - descent) / height : 0;
      }
    else
      align = super.getAlignment(axis);

    return align;
  }

  /**
   * Returns the model location that should be used to place a caret when
   * moving the caret through the document.
   *
   * @param pos the current model location
   * @param bias the bias for <code>p</code>
   * @param a the allocated region for the glyph view
   * @param direction the direction from the current position; Must be one of
   *        {@link SwingConstants#EAST}, {@link SwingConstants#WEST},
   *        {@link SwingConstants#NORTH} or {@link SwingConstants#SOUTH}
   * @param biasRet filled with the bias of the resulting location when method
   *        returns
   *
   * @return the location within the document that should be used to place the
   *         caret when moving the caret around the document
   *
   * @throws BadLocationException if <code>pos</code> is an invalid model
   *         location
   * @throws IllegalArgumentException if <code>d</code> is invalid
   */
  public int getNextVisualPositionFrom(int pos, Position.Bias bias, Shape a,
                                       int direction, Position.Bias[] biasRet)
    throws BadLocationException
  {
    checkPainter();
    GlyphPainter painter = getGlyphPainter();
    return painter.getNextVisualPositionFrom(this, pos, bias, a, direction,
                                             biasRet);
  }
}
