/* GNUGlyphVector.java -- The GNU implementation of GlyphVector.
   Copyright (C) 2006 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 gnu.java.awt.font;

import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphVector;

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


/**
 * The GNU implementation of the abstract GlyphVector class, which
 * uses the services provided by a FontDelegate for its functionality.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public class GNUGlyphVector
  extends GlyphVector
{
  private FontDelegate fontDelegate;
  private Font font;
  private FontRenderContext renderContext;
  private int[] glyphs;
  private float fontSize;
  private AffineTransform transform;
  private boolean valid;


  /**
   * The position of each glyph. The horizontal position of the
   * <code>i</code>-th glyph is at <code>pos[i * 2]</code>, its
   * vertical position at <code>pos[i * 2 + 1]</code>. The total
   * advance width of the entire vector is stored at
   * <code>pos[numGlyphs]</code>, the total advance height at
   * <code>pos[numGlyphs + 1]</code>.
   */
  private float[] pos;


  private AffineTransform[] transforms;
  private int layoutFlags;


  /**
   * Constructs a new GNUGlyphVector.
   *
   * @param fontDelegate the FontDelegate that creates this vector.
   *
   * @param font the Font that this GlyphVector will return for {@link
   * #getFont()}. That object is also used to determine the point
   * size, which affects the affine transformation used by the font
   * scaler.
   *
   * @param renderContext an object with parameters for font
   * rendering, such as whether anti-aliasing is enabled.
   *
   * @param glyphs the glyphs in this vector.
   */
  public GNUGlyphVector(FontDelegate fontDelegate,
                        Font font,
                        FontRenderContext renderContext,
                        int[] glyphs)
  {
    this.fontDelegate = fontDelegate;
    this.font = font;
    this.renderContext = renderContext;
    this.glyphs = glyphs;
    
    fontSize = font.getSize2D();
    transform = font.getTransform(); // returns a modifiable copy
    //transform.concatenate(renderContext.getTransform());
  }



  /**
   * Returns the font of the glyphs in this GlyphVector.
   */
  public Font getFont()
  {
    return font;
  }


  /**
   * Returns the FontRenderContext that is used to calculate the
   * extent and position of the glyphs.
   */
  public FontRenderContext getFontRenderContext()
  {
    return renderContext;
  }


  /**
   * Moves each glyph in the vector to its default position.
   */
  public void performDefaultLayout()
  {
    float x, y, advanceWidth, advanceHeight;
    int i, p;
    AffineTransform tx;
    Point2D.Float advance = new Point2D.Float();

    pos = new float[(glyphs.length + 1) * 2];
    x = y = 0.0f;
    p = 0;
    for (i = p = 0; i < glyphs.length; i++)
    {
      p += 2;
      
      if ((transforms == null) || (tx = transforms[i]) == null)
        tx = this.transform;
      else
      {
        tx = new AffineTransform(tx);
        tx.concatenate(this.transform);
      }
      
      fontDelegate.getAdvance(glyphs[i], fontSize, tx,
                              renderContext.isAntiAliased(),
                              renderContext.usesFractionalMetrics(),
                              /* horizontal */ true,
                              advance);
      pos[p] = x += advance.x;
      pos[p + 1] = y += advance.y;
    }
    valid = true;
  }


  /**
   * Determines the number of glyphs in this GlyphVector.
   */
  public int getNumGlyphs()
  {
    return glyphs.length;
  }


  /**
   * Determines the glyph number by index in this vector.
   * Glyph numbers are specific to each font, so two fonts
   * will likely assign different numbers to the same glyph.
   *
   * @param glyphIndex the index of the glyph whose glyph number is to
   * be retrieved.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code>
   * is not in the range <code[0 .. getNumGlyphs() - 1]</code>.
   */
  public int getGlyphCode(int glyphIndex)
  {
    /* The exception is thrown automatically if the index is out
     * of the valid bounds.
     */
    return glyphs[glyphIndex];
  }


  /**
   * Returns a slice of this GlyphVector.
   *
   * @param firstGlyphIndex the index of the first glyph in the
   * returned slice.
   *
   * @param numEntries the size of the returned slice.
   *
   * @param outCodes a pre-allocated array for storing the slice,
   * or <code>null</code> to cause allocation of a new array.
   *
   * @return a slice of this GlyphVector. If <code>outCodes</code>
   * is <code>null</code>, the slice will be stored into a freshly
   * allocated array; otherwise, the result will be stored into
   * <code>outCodes</code>.
   */
  public int[] getGlyphCodes(int firstGlyphIndex,
                             int numEntries,
                             int[] outCodes)
  {
    if (numEntries < 0)
      throw new IllegalArgumentException();
    if (outCodes == null)
      outCodes = new int[numEntries];
    System.arraycopy(glyphs, firstGlyphIndex, outCodes, 0, numEntries);
    return outCodes;
  }


  public Rectangle2D getLogicalBounds()
  {
    float ascent, descent;

    validate();

    return new Rectangle2D.Float(0, 0,
                                 pos[pos.length - 2],
                                 getAscent() - getDescent());
  }


  public Rectangle2D getVisualBounds()
  {
    validate();

    // FIXME: Not yet implemented.
    return getLogicalBounds();
  }


  /**
   * Returns the shape of this GlyphVector.
   */
  public Shape getOutline()
  {
    validate();
    return getOutline(0.0f, 0.0f);
  }


  /**
   * Returns the shape of this GlyphVector, translated to the
   * specified position.
   *
   * @param x the horizontal position for rendering this vector.
   * @param y the vertical position for rendering this vector.
   */
  public Shape getOutline(float x, float y)
  {
    validate();

    GeneralPath outline = new GeneralPath();
    int len = glyphs.length;
    for (int i = 0; i < len; i++)
      {
        GeneralPath p = new GeneralPath(getGlyphOutline(i));
        outline.append(p, false);
      }
    AffineTransform t = new AffineTransform();
    t.translate(x, y);
    outline.transform(t);
    return outline;
  }


  /**
   * Determines the shape of the specified glyph.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs()]</code>.
   */
  public Shape getGlyphOutline(int glyphIndex)
  {
    AffineTransform tx, glyphTx;
    GeneralPath path;

    validate();

    if ((transforms != null)
        && ((glyphTx = transforms[glyphIndex]) != null))
    {
      tx =  new AffineTransform(transform);
      tx.concatenate(glyphTx);
    }
    else
      tx = transform;

    path = fontDelegate.getGlyphOutline(glyphs[glyphIndex], fontSize, tx,
                                        renderContext.isAntiAliased(),
                                        renderContext.usesFractionalMetrics());

    tx = new AffineTransform();
    tx.translate(pos[glyphIndex * 2], pos[glyphIndex * 2 + 1]);
    path.transform(tx);
    return path;
  }


  /**
   * Determines the position of the specified glyph, or the
   * total advance width and height of the vector.
   *
   * @param glyphIndex the index of the glyph in question.
   * If this value equals <code>getNumGlyphs()</code>, the
   * position <i>after</i> the last glyph will be returned,
   * which is the total advance width and height of the vector.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs()]</code>.
   */
  public Point2D getGlyphPosition(int glyphIndex)
  {
    validate();
    return new Point2D.Float(pos[glyphIndex * 2],
                             pos[glyphIndex * 2 + 1]);
  }


  /**
   * Moves the specified glyph to a new position, or changes the
   * advance width and height of the entire glyph vector.
   *
   * <p>Note that the position of an individual glyph may also
   * affected by its affine transformation.
   *
   * @param glyphIndex the index of the moved glyph. If
   * <code>glyphIndex</code> equals the total number of glyphs in this
   * vector, the advance width and height of the vector is changed.
   *
   * @param position the new position of the glyph.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs()]</code>.
   */
  public void setGlyphPosition(int glyphIndex, Point2D position)
  {
    validate();
    pos[glyphIndex * 2] = (float) position.getX();
    pos[glyphIndex * 2 + 1] = (float) position.getY();
  }


  /**
   * Returns the affine transformation that is applied to the
   * glyph at the specified index.
   *
   * @param glyphIndex the index of the glyph whose transformation
   * is to be retrieved.
   *
   * @return an affine transformation, or <code>null</code>
   * for the identity transformation.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
   */
  public AffineTransform getGlyphTransform(int glyphIndex)
  {
    if (transforms == null)
      return null;
    else
      return transforms[glyphIndex];
  }


  /**
   * Applies an affine transformation to the glyph at the specified
   * index.
   *
   * @param glyphIndex the index of the glyph to which the
   * transformation is applied.
   *
   * @param transform the affine transformation for the glyph, or
   * <code>null</code> for an identity transformation.
   */
  public void setGlyphTransform(int glyphIndex,
                                AffineTransform transform)
  {
    if (transforms == null)
      transforms = new AffineTransform[glyphs.length];
    transforms[glyphIndex] = transform;

    /* If the GlyphVector has only a transform for a single glyph, and
     * the caller clears its transform, the FLAG_HAS_TRANSFORMS bit
     * should be cleared in layoutFlags.  However, this would require
     * that we keep track of the number of transformed glyphs, or that
     * we count them when a transform is cleared. This would
     * complicate the code quite a bit. Note that the only drawback of
     * wrongly setting FLAG_HAS_TRANSFORMS is that a slower code path
     * might be taken for rendering the vector. Right now, we never
     * really look at the flag, so it does not make any difference.
     */
    if (transform != null)
      layoutFlags |= FLAG_HAS_TRANSFORMS;
    valid = false;
  }


  /**
   * Returns flags that can be used for optimizing the rendering
   * of this GlyphVector.
   *
   * @return a bit mask with the applicable flags set.
   *
   * @since 1.4
   *
   * @see GlyphVector#FLAG_HAS_POSITION_ADJUSTMENTS
   * @see GlyphVector#FLAG_HAS_TRANSFORMS
   * @see GlyphVector#FLAG_RUN_RTL
   * @see GlyphVector#FLAG_COMPLEX_GLYPHS
   * @see GlyphVector#FLAG_MASK
   */
  public int getLayoutFlags()
  {
    return layoutFlags;
  }
  
  
  /**
   * Returns the positions of a range of glyphs in this vector.
   * 
   * @param firstGlyphIndex the index of the first glyph whose
   * position is retrieved.
   *
   * @param numGlyphs the number of glyphs whose positions
   * are retrieved.
   *
   * @param outPositions an array for storing the results
   * (the length must be at least twice <code>numGlyphs</code>),
   * or <code>null</code> for freshly allocating an array.
   *
   * @return an array with the glyph positions. The horizontal
   * position of the <code>i</code>-th glyph is at index <code>2 *
   * i</code>, the vertical position at index <code>2 * i + 1</code>.
   *
   * @throws IllegalArgumentException if <code>numGlyphs</code>
   * is less than zero.
   *
   * @throws IndexOutOfBoundsException if either
   * <code>firstGlyphIndex</code> or <code>(firstGlyphIndex +
   * numGlyphs)</code> is not in the range <code>[0 .. getNumGlyphs() -
   * 1]</code>.
   */
  public float[] getGlyphPositions(int firstGlyphIndex,
                                   int numGlyphs,
                                   float[] outPositions)
  {
    if (numGlyphs < 0)
      throw new IllegalArgumentException();

    validate();
    if (outPositions == null)
      outPositions = new float[numGlyphs * 2];

    System.arraycopy(/*src */ pos, /* srcStart */ firstGlyphIndex * 2,
                     /* dest */ outPositions, /* destStart */ 0,
                     /* length */ numGlyphs * 2);
    return outPositions;
  }

  
  private float getAscent()
  {
    return fontDelegate.getAscent(fontSize, transform,
                                  renderContext.isAntiAliased(),
                                  renderContext.usesFractionalMetrics(),
                                  /* horizontal */ true);
  }


  private float getDescent()
  {
    return fontDelegate.getDescent(fontSize, transform,
                                   renderContext.isAntiAliased(),
                                   renderContext.usesFractionalMetrics(),
                                   /* horizontal */ true);    
  }


  public Shape getGlyphLogicalBounds(int glyphIndex)
  {
    float x, y, ascent;

    validate();
    ascent = getAscent();
    x = pos[glyphIndex * 2];
    y = pos[glyphIndex * 2 + 1];

    return new Rectangle2D.Float(x, y - ascent,
                                 pos[(glyphIndex + 1) * 2] - x,
                                 ascent - getDescent());
  }


  public Shape getGlyphVisualBounds(int glyphIndex)
  {
    return getGlyphOutline(glyphIndex).getBounds2D();
  }


  /**
   * Determines the metrics of the glyph at the specified index.
   *
   * @param glyphIndex the index of the glyph whose metrics is to be
   * retrieved.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
   */
  public GlyphMetrics getGlyphMetrics(int glyphIndex)
  {
    // FIXME: Not yet implemented.
    throw new UnsupportedOperationException();
  }


  /**
   * Determines the justification information for the glyph at the
   * specified index.
   *
   * @param glyphIndex the index of the glyph whose justification
   * information is to be retrieved.
   *
   * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
   * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
   */
  public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex)
  {
    // FIXME: Not yet implemented.
    throw new UnsupportedOperationException();
  }


  /**
   * Determines whether another GlyphVector is for the same font and
   * rendering context, uses the same glyphs and positions them to the
   * same location.
   *
   * @param other the GlyphVector to compare with.
   *
   * @return <code>true</code> if the two vectors are equal,
   * <code>false</code> otherwise.
   */
  public boolean equals(GlyphVector other)
  {
    GNUGlyphVector o;
    if (!(other instanceof GNUGlyphVector))
      return false;

    o = (GNUGlyphVector) other;
    if ((this.font != o.font)
        || (this.fontDelegate != o.fontDelegate)
        || (this.renderContext != o.renderContext)
        || (this.glyphs.length != o.glyphs.length))
      return false;

    for (int i = 0; i < glyphs.length; i++)
      if (this.glyphs[i] != o.glyphs[i])
        return false;

    validate();
    o.validate();
    for (int i = 0; i < pos.length; i++)
      if (this.pos[i] != o.pos[i])
        return false;

    return true;
  }

  private void validate()
  {
    if (!valid)
      performDefaultLayout();
  }
}
