/* Font.java -- Font object
   Copyright (C) 1999, 2002, 2004, 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.awt;

import gnu.java.awt.ClasspathToolkit;
import gnu.java.awt.peer.ClasspathFontPeer;

import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.peer.FontPeer;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * This class represents a windowing system font.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy (warrenl@cygnus.com)
 * @author Graydon Hoare (graydon@redhat.com)
 */
public class Font implements Serializable
{

/*
 * Static Variables
 */

/**
  * Constant indicating a "plain" font.
  */
public static final int PLAIN = 0;

/**
  * Constant indicating a "bold" font.
  */
public static final int BOLD = 1;

/**
  * Constant indicating an "italic" font.
  */
public static final int ITALIC = 2;

/**
 * Constant indicating the baseline mode characteristic of Roman.
 */
public static final int ROMAN_BASELINE = 0;

/**
 * Constant indicating the baseline mode characteristic of Chinese.
 */
public static final int CENTER_BASELINE = 1;

/**
 * Constant indicating the baseline mode characteristic of Devanigri.
 */
public static final int HANGING_BASELINE = 2;  


  /**
   * Indicates to <code>createFont</code> that the supplied font data
   * is in TrueType format.
   *
   * <p><em>Specification Note:</em> The Sun JavaDoc for J2SE 1.4 does
   * not indicate whether this value also subsumes OpenType. OpenType
   * is essentially the same format as TrueType, but allows to define
   * glyph shapes in the same way as PostScript, using cubic bezier
   * curves.
   *
   * @since 1.3
   */
  public static final int TRUETYPE_FONT = 0;


  /**
   * A flag for <code>layoutGlyphVector</code>, indicating that the
   * orientation of a text run is from left to right.
   *
   * @since 1.4
   */
  public static final int LAYOUT_LEFT_TO_RIGHT = 0;


  /**
   * A flag for <code>layoutGlyphVector</code>, indicating that the
   * orientation of a text run is from right to left.
   *
   * @since 1.4
   */
  public static final int LAYOUT_RIGHT_TO_LEFT = 1;


  /**
   * A flag for <code>layoutGlyphVector</code>, indicating that the
   * text does not contain valid characters before the
   * <code>start</code> position.  If this flag is set,
   * <code>layoutGlyphVector</code> does not examine the text before
   * <code>start</code>, even if this would be necessary to select the
   * correct glyphs (e.g., for Arabic text).
   *
   * @since 1.4
   */
  public static final int LAYOUT_NO_START_CONTEXT = 2;


  /**
   * A flag for <code>layoutGlyphVector</code>, indicating that the
   * text does not contain valid characters after the
   * <code>limit</code> position.  If this flag is set,
   * <code>layoutGlyphVector</code> does not examine the text after
   * <code>limit</code>, even if this would be necessary to select the
   * correct glyphs (e.g., for Arabic text).
   *
   * @since 1.4
   */
  public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;

  /**
   * The logical name of this font.
   *
   * @since 1.0
   */
  protected String name;

  /**
   * The size of this font in pixels.
   *
   * @since 1.0
   */
  protected int size;

  /**
   * The style of this font -- PLAIN, BOLD, ITALIC or BOLD+ITALIC.
   *
   * @since 1.0
   */
  protected int style;

// Serialization constant
private static final long serialVersionUID = -4206021311591459213L;


  // The ClasspathToolkit-provided peer which implements this font
  private ClasspathFontPeer peer;

/*************************************************************************/

/*
 * Static Methods
 */

/**
  * Creates a <code>Font</code> object from the specified string, which
  * is in one of the following formats:
  * <p>
  * <ul>
  * <li>fontname-style-pointsize
  * <li>fontname-style
  * <li>fontname-pointsize
  * <li>fontname
  * </ul>
  * <p>
  * The style should be one of BOLD, ITALIC, or BOLDITALIC.  The default
  * style if none is specified is PLAIN.  The default size if none
  * is specified is 12.
  */
  public static Font decode (String fontspec)
{
  String name = null;
  int style = PLAIN;
  int size = 12;

  StringTokenizer st = new StringTokenizer(fontspec, "-");
  while (st.hasMoreTokens())
    {
      String token = st.nextToken();
      if (name == null)
        {
          name = token;
          continue;
        }

      if (token.toUpperCase().equals("BOLD"))
        {
          style = BOLD;
          continue;
        }
      if (token.toUpperCase().equals("ITALIC"))
        {
          style = ITALIC;
          continue;
        }
      if (token.toUpperCase().equals("BOLDITALIC"))
        {
            style = BOLD | ITALIC;
          continue;
        }

      int tokenval = 0;
      try
        {
          tokenval = Integer.parseInt(token);
        }
      catch(NumberFormatException e)
        {
	  // Ignored.
	}

      if (tokenval != 0)
        size = tokenval;
    }

    HashMap attrs = new HashMap();
    ClasspathFontPeer.copyStyleToAttrs (style, attrs);
    ClasspathFontPeer.copySizeToAttrs (size, attrs);

    return getFontFromToolkit (name, attrs);
}

  /* These methods delegate to the toolkit. */

  protected static ClasspathToolkit tk ()
  {
    return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
  }

  /* Every factory method in Font should eventually call this. */
  protected static Font getFontFromToolkit (String name, Map attribs)
  {
    return tk ().getFont (name, attribs);
  }

  /* Every Font constructor should eventually call this. */
  protected static ClasspathFontPeer getPeerFromToolkit (String name, Map attrs)
  {
    return tk ().getClasspathFontPeer (name, attrs);
  }


/*************************************************************************/

/**
  * Returns a <code>Font</code> object from the passed property name.
  *
  * @param propname The name of the system property.
  * @param defval Value to use if the property is not found.
  *
  * @return The requested font, or <code>default</code> if the property 
  * not exist or is malformed.
  */
  public static Font getFont (String propname, Font defval)
{
  String propval = System.getProperty(propname);
  if (propval != null)
      return decode (propval);
    return defval;
}

/*************************************************************************/

/**
  * Returns a <code>Font</code> object from the passed property name.
  *
  * @param propname The name of the system property.
  *
  * @return The requested font, or <code>null</code> if the property 
  * not exist or is malformed.
  */
  public static Font getFont (String propname)
{
    return getFont (propname, (Font)null);
}

/*************************************************************************/

/*
 * Constructors
 */

/**
  * Initializes a new instance of <code>Font</code> with the specified
  * attributes.
  *
  * @param name The name of the font.
  * @param style The font style.
  * @param size The font point size.
  */

  public Font (String name, int style, int size)
  {
    HashMap attrs = new HashMap();
    ClasspathFontPeer.copyStyleToAttrs (style, attrs);
    ClasspathFontPeer.copySizeToAttrs (size, attrs);
    this.peer = getPeerFromToolkit (name, attrs);
  }

  public Font (Map attrs)
  {
    this(null, attrs);
  }

  /* This extra constructor is here to permit ClasspathToolkit and to build
     a font with a "logical name" as well as attrs.  */
  public Font (String name, Map attrs)
  {
    // If attrs is null, setting it to an empty HashMap will give this
    // Font default attributes.
    if (attrs == null)
      attrs = new HashMap();
    this.peer = getPeerFromToolkit (name, attrs);
  }

/*************************************************************************/

/*
 * Instance Methods
 */

/**
   * Returns the logical name of the font.  A logical name is the name the
   * font was constructed with. It may be the name of a logical font (one
   * of 6 required names in all java environments) or it may be a face
   * name.
  *
  * @return The logical name of the font.
  *
  * @see getFamily()
  * @see getFontName()
  */
  public String getName ()
{
    return peer.getName (this);
}

/*************************************************************************/

/**
  * Returns the style of the font.
  * 
  * @return The font style.
  */
  public int getSize ()
{
    return (int) peer.getSize (this);
}

  public float getSize2D ()
{
    return peer.getSize (this);
}

/*************************************************************************/

/**
  * Tests whether or not this is a plain font.  This will be true if
  * and only if neither the bold nor the italics style is set.
  *
  * @return <code>true</code> if this is a plain font, <code>false</code>
  * otherwise.
  */
  public boolean isPlain ()
{
    return peer.isPlain (this); 
}

/*************************************************************************/

/**
  * Tests whether or not this font is bold.
  *
  * @return <code>true</code> if this font is bold, <code>false</code>
  * otherwise.
  */
  public boolean isBold ()
{
    return peer.isBold (this);
}

/*************************************************************************/

/**
  * Tests whether or not this font is italic.
  *
  * @return <code>true</code> if this font is italic, <code>false</code>
  * otherwise.
  */
  public boolean isItalic ()
{
    return peer.isItalic (this);
}

/*************************************************************************/

/**
   * Returns the family name of this font. A family name describes a design
   * or "brand name" (such as Helvetica or Palatino). It is less specific
   * than a font face name (such as Helvetica Bold).
  *
  * @return A string containing the font family name.
  *
  * @since 1.2
  *
  * @see getName()
  * @see getFontName()
  * @see GraphicsEnvironment.getAvailableFontFamilyNames()
  */
  public String getFamily ()
{
    return peer.getFamily (this);
}

/**
  * Returns integer code representing the sum of style flags of this font, a
  * combination of either {@link PLAIN}, {@link BOLD}, or {@link ITALIC}.
  *
  * @return code representing the style of this font.
  *
  * @see isPlain()
  * @see isBold()
  * @see isItalic()
  */
  public int getStyle ()
{
    return peer.getStyle (this);
}

/**
  * Checks if specified character maps to a glyph in this font.
  *
  * @param c The character to check.
  *
  * @return Whether the character has a corresponding glyph in this font.
  *
  * @since 1.2
  */
  public boolean canDisplay (char c)
{
    return peer.canDisplay (this, c);    
}

/**
  * Checks how much of a given string can be mapped to glyphs in 
  * this font.
  *
  * @param s The string to check.
  *
  * @return The index of the first character in <code>s</code> which cannot
  * be converted to a glyph by this font, or <code>-1</code> if all
  * characters can be mapped to glyphs.
  *
  * @since 1.2
  */
  public int canDisplayUpTo (String s)
{
    return peer.canDisplayUpTo (this, new StringCharacterIterator (s), 
                                0, s.length () - 1);
}

/**
  * Checks how much of a given sequence of text can be mapped to glyphs in
  * this font.
  *
  * @param text Array containing the text to check.
  * @param start Position of first character to check in <code>text</code>.
  * @param limit Position of last character to check in <code>text</code>.
  *
  * @return The index of the first character in the indicated range which
  * cannot be converted to a glyph by this font, or <code>-1</code> if all
  * characters can be mapped to glyphs.
  *
  * @since 1.2
  *
  * @throws IndexOutOfBoundsException if the range [start, limit] is
  * invalid in <code>text</code>.
  */
  public int canDisplayUpTo (char[] text, int start, int limit)
{
    return peer.canDisplayUpTo 
      (this, new StringCharacterIterator (new String (text)), start, limit);
}

/**
  * Checks how much of a given sequence of text can be mapped to glyphs in
  * this font.
  *
  * @param i Iterator over the text to check.
  * @param start Position of first character to check in <code>i</code>.
  * @param limit Position of last character to check in <code>i</code>.
  *
  * @return The index of the first character in the indicated range which
  * cannot be converted to a glyph by this font, or <code>-1</code> if all
  * characters can be mapped to glyphs.
  *
  * @since 1.2
  *
  * @throws IndexOutOfBoundsException if the range [start, limit] is
  * invalid in <code>i</code>.
  */
  public int canDisplayUpTo (CharacterIterator i, int start, int limit)
{
    return peer.canDisplayUpTo (this, i, start, limit);    
}

/**
  * Creates a new font with point size 1 and {@link PLAIN} style,
  * reading font data from the provided input stream. The resulting font
  * can have further fonts derived from it using its
  * <code>deriveFont</code> method.
  *
  * @param fontFormat Integer code indicating the format the font data is
  * in.Currently this can only be {@link TRUETYPE_FONT}.
  * @param is {@link InputStream} from which font data will be read. This
  * stream is not closed after font data is extracted.
  *
  * @return A new {@link Font} of the format indicated.
  *
  * @throws IllegalArgumentException if <code>fontType</code> is not
  * recognized.
  * @throws FontFormatException if data in InputStream is not of format
  * indicated.
  * @throws IOException if insufficient data is present on InputStream.
  *
  * @since 1.3
  */
  public static Font createFont (int fontFormat, InputStream is) 
  throws FontFormatException, IOException
{
    return tk().createFont (fontFormat, is);
}

/**
  * Maps characters to glyphs in a one-to-one relationship, returning a new
  * {@link GlyphVector} with a mapped glyph for each input character. This
  * sort of mapping is often sufficient for some scripts such as Roman, but
  * is inappropriate for scripts with special shaping or contextual layout
  * requirements such as Arabic, Indic, Hebrew or Thai.
  *
  * @param ctx The rendering context used for precise glyph placement.
  * @param str The string to convert to Glyphs.
  *
  * @return A new {@link GlyphVector} containing glyphs mapped from str,
  * through the font's cmap table.
  *
  * @see layoutGlyphVector()
  */
  public GlyphVector createGlyphVector (FontRenderContext ctx, String str)
{
    return peer.createGlyphVector (this, ctx, new StringCharacterIterator (str));
}

/**
  * Maps characters to glyphs in a one-to-one relationship, returning a new
  * {@link GlyphVector} with a mapped glyph for each input character. This
  * sort of mapping is often sufficient for some scripts such as Roman, but
  * is inappropriate for scripts with special shaping or contextual layout
  * requirements such as Arabic, Indic, Hebrew or Thai.
  *
  * @param ctx The rendering context used for precise glyph placement.
  * @param i Iterator over the text to convert to glyphs.
  *
  * @return A new {@link GlyphVector} containing glyphs mapped from str,
  * through the font's cmap table.
  *
  * @see layoutGlyphVector()
  */
  public GlyphVector createGlyphVector (FontRenderContext ctx, CharacterIterator i)
{
    return peer.createGlyphVector (this, ctx, i);
}

/**
  * Maps characters to glyphs in a one-to-one relationship, returning a new
  * {@link GlyphVector} with a mapped glyph for each input character. This
  * sort of mapping is often sufficient for some scripts such as Roman, but
  * is inappropriate for scripts with special shaping or contextual layout
  * requirements such as Arabic, Indic, Hebrew or Thai.
  *
  * @param ctx The rendering context used for precise glyph placement.
  * @param chars Array of characters to convert to glyphs.
  *
  * @return A new {@link GlyphVector} containing glyphs mapped from str,
  * through the font's cmap table.
  *
  * @see layoutGlyphVector()
  */
  public GlyphVector createGlyphVector (FontRenderContext ctx, char[] chars)
{
    return peer.createGlyphVector 
      (this, ctx, new StringCharacterIterator (new String (chars)));
}

/**
  * Extracts a sequence of glyphs from a font, returning a new {@link
  * GlyphVector} with a mapped glyph for each input glyph code. 
  *
  * @param ctx The rendering context used for precise glyph placement.
  * @param glyphCodes Array of characters to convert to glyphs.
  *
  * @return A new {@link GlyphVector} containing glyphs mapped from str,
  * through the font's cmap table.
  *
  * @see layoutGlyphVector()
  *
  * @specnote This method is documented to perform character-to-glyph
  * conversions, in the Sun documentation, but its second parameter name is
  * "glyphCodes" and it is not clear to me why it would exist if its
  * purpose was to transport character codes inside integers. I assume it
  * is mis-documented in the Sun documentation.
  */

  public GlyphVector createGlyphVector (FontRenderContext ctx, int[] glyphCodes)
{
    return peer.createGlyphVector (this, ctx, glyphCodes);
}

/**
  * Produces a new {@link Font} based on the current font, adjusted to a
  * new size and style.
  *
  * @param style The style of the newly created font.
  * @param size The size of the newly created font.
  *
  * @return A clone of the current font, with the specified size and style.
  *
  * @since 1.2
  */
  public Font deriveFont (int style, float size)
{
    return peer.deriveFont (this, style, size);
}

/**
  * Produces a new {@link Font} based on the current font, adjusted to a
  * new size.
  *
  * @param size The size of the newly created font.
  *
  * @return A clone of the current font, with the specified size.
  *
  * @since 1.2
  */
  public Font deriveFont (float size)
{
    return peer.deriveFont (this, size);
}

/**
  * Produces a new {@link Font} based on the current font, adjusted to a
  * new style.
  *
  * @param style The style of the newly created font.
  *
  * @return A clone of the current font, with the specified style.
  *
  * @since 1.2
  */
  public Font deriveFont (int style)
{
    return peer.deriveFont (this, style);
}

/**
  * Produces a new {@link Font} based on the current font, adjusted to a
  * new style and subjected to a new affine transformation.
  *
  * @param style The style of the newly created font.
  * @param a The transformation to apply.
  *
  * @return A clone of the current font, with the specified style and
  * transform.
  *
  * @throws IllegalArgumentException If transformation is
  * <code>null</code>.
  *
  * @since 1.2
  */
  public Font deriveFont (int style, AffineTransform a)
{
    if (a == null)
      throw new IllegalArgumentException ("Affine transformation is null");

    return peer.deriveFont (this, style, a);
}

/**
  * Produces a new {@link Font} based on the current font, subjected
  * to a new affine transformation.
  *
  * @param a The transformation to apply.
  *
  * @return A clone of the current font, with the specified transform.
  *
  * @throws IllegalArgumentException If transformation is
  * <code>null</code>.
  *
  * @since 1.2
  */
  public Font deriveFont (AffineTransform a)
{
    if (a == null)
      throw new IllegalArgumentException ("Affine transformation is null");

    return peer.deriveFont (this, a);
}

/**
  * Produces a new {@link Font} based on the current font, adjusted to a
  * new set of attributes.
  *
  * @param attributes Attributes of the newly created font.
  *
  * @return A clone of the current font, with the specified attributes.
  *
  * @since 1.2
  */
  public Font deriveFont (Map attributes)
{
    return peer.deriveFont (this, attributes);
}

/**
  * Returns a map of chracter attributes which this font currently has set.
  *
  * @return A map of chracter attributes which this font currently has set.
  *
  * @see getAvailableAttributes()
  * @see java.text.AttributedCharacterIterator.Attribute
  * @see java.awt.font.TextAttribute
  */
  public Map getAttributes ()
{
    return peer.getAttributes (this);
}

/**
  * Returns an array of chracter attribute keys which this font understands. 
  *
  * @return An array of chracter attribute keys which this font understands.
  *
  * @see getAttributes()
  * @see java.text.AttributedCharacterIterator.Attribute
  * @see java.awt.font.TextAttribute
  */
  public AttributedCharacterIterator.Attribute[] getAvailableAttributes()
{
    return peer.getAvailableAttributes (this);
}

/**
  * Returns a baseline code (one of {@link ROMAN_BASELINE}, {@link
  * CENTER_BASELINE} or {@link HANGING_BASELINE}) indicating which baseline
  * this font will measure baseline offsets for, when presenting glyph
  * metrics for a given character.
  *
  * Baseline offsets describe the position of a glyph relative to an
  * invisible line drawn under, through the center of, or over a line of
  * rendered text, respectively. Different scripts use different baseline
  * modes, so clients should not assume all baseline offsets in a glyph
  * vector are from a common baseline.
  *
  * @param c The character code to select a baseline mode for.
  *
  * @return The baseline mode which would be used in a glyph associated
  * with the provided character.
  *
  * @since 1.2
  *
  * @see LineMetrics.getBaselineOffsets()
  */
  public byte getBaselineFor (char c)
{
    return peer.getBaselineFor (this, c);
}

/**
  * Returns the family name of this font. A family name describes a
  * typographic style (such as Helvetica or Palatino). It is more specific
  * than a logical font name (such as Sans Serif) but less specific than a
  * font face name (such as Helvetica Bold).
  *
  * @param lc The locale in which to describe the name of the font family.
  *
  * @return A string containing the font family name, localized for the
  * provided locale.
  *
  * @since 1.2
  *
  * @see getName()
  * @see getFontName()
  * @see GraphicsEnvironment.getAvailableFontFamilyNames()
  * @see Locale
  */
  public String getFamily (Locale lc)
{
    return peer.getFamily (this, lc); 
}

/**
  * Returns a font appropriate for the given attribute set.
  *
  * @param attributes The attributes required for the new font.
  *
  * @return A new Font with the given attributes.
  *
  * @since 1.2
  *
  * @see TextAttribure  
  */
  public static Font getFont (Map attributes)
{
    return getFontFromToolkit (null, attributes);
}

/**
  * Returns the font face name of the font.  A font face name describes a
  * specific variant of a font family (such as Helvetica Bold). It is more
  * specific than both a font family name (such as Helvetica) and a logical
  * font name (such as Sans Serif).
  *
  * @return The font face name of the font.
  *
  * @since 1.2
  *
  * @see getName()
  * @see getFamily()
  */
  public String getFontName ()
{
    return peer.getFontName (this);
}

/**
  * Returns the font face name of the font.  A font face name describes a
  * specific variant of a font family (such as Helvetica Bold). It is more
   * specific than both a font family name (such as Helvetica).
  *
  * @param lc The locale in which to describe the name of the font face.
  *
  * @return A string containing the font face name, localized for the
  * provided locale.
  *
  * @since 1.2
  *
  * @see getName()
  * @see getFamily()
  */
  public String getFontName (Locale lc)
{
    return peer.getFontName (this, lc);
}

/**
  * Returns the italic angle of this font, a measurement of its slant when
  * style is {@link ITALIC}. The precise meaning is the inverse slope of a
  * caret line which "best measures" the font's italic posture.
  *
  * @return The italic angle.
  *
  * @see TextAttribute.POSTURE
  */
  public float getItalicAngle ()
{
    return peer.getItalicAngle (this);
}

/**
  * Returns a {@link LineMetrics} object constructed with the specified
  * text and {@link FontRenderContext}. 
  *
  * @param text The string to calculate metrics from.
  * @param begin Index of first character in <code>text</code> to measure.
  * @param limit Index of last character in <code>text</code> to measure.
  * @param rc Context for calculating precise glyph placement and hints.
  *
  * @return A new {@link LineMetrics} object.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>text</code>.
  */
  public LineMetrics getLineMetrics(String text, int begin, 
                                    int limit, FontRenderContext rc)
{
    return peer.getLineMetrics (this, new StringCharacterIterator (text), 
                                begin, limit, rc);
}

/**
  * Returns a {@link LineMetrics} object constructed with the specified
  * text and {@link FontRenderContext}. 
  *
  * @param chars The string to calculate metrics from.
  * @param begin Index of first character in <code>text</code> to measure.
  * @param limit Index of last character in <code>text</code> to measure.
  * @param rc Context for calculating precise glyph placement and hints.
  *
  * @return A new {@link LineMetrics} object.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>chars</code>.
  */
  public LineMetrics getLineMetrics(char[] chars, int begin, 
                                    int limit, FontRenderContext rc)
{
    return peer.getLineMetrics (this, new StringCharacterIterator (new String(chars)), 
                                begin, limit, rc);
}

/**
  * Returns a {@link LineMetrics} object constructed with the specified
  * text and {@link FontRenderContext}. 
  *
  * @param ci The string to calculate metrics from.
  * @param begin Index of first character in <code>text</code> to measure.
  * @param limit Index of last character in <code>text</code> to measure.
  * @param rc Context for calculating precise glyph placement and hints.
  *
  * @return A new {@link LineMetrics} object.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>ci</code>.
  */
  public LineMetrics getLineMetrics (CharacterIterator ci, int begin, 
                                     int limit, FontRenderContext rc)
{
    return peer.getLineMetrics (this, ci, begin, limit, rc);
}

/**
  * Returns the maximal bounding box of all the bounding boxes in this
  * font, when the font's bounding boxes are evaluated in a given {@link
  * FontRenderContext}
  *
  * @param rc Context in which to evaluate bounding boxes.
  *
  * @return The maximal bounding box.
  */
  public Rectangle2D getMaxCharBounds (FontRenderContext rc)
{
    return peer.getMaxCharBounds (this, rc);
}

/**
  * Returns the glyph code this font uses to represent missing glyphs. This
  * code will be present in glyph vectors when the font was unable to
  * locate a glyph to represent a particular character code.
  *
  * @return The missing glyph code.
  *
  * @since 1.2
  */
  public int getMissingGlyphCode ()
{
    return peer.getMissingGlyphCode (this);
}

/**
  * Returns the overall number of glyphs in this font. This number is one
  * more than the greatest glyph code used in any glyph vectors this font
  * produces. In other words, glyph codes are taken from the range
  * <code>[ 0, getNumGlyphs() - 1 ]</code>.
  *
  * @return The number of glyphs in this font.
  * 
  * @since 1.2
  */
  public int getNumGlyphs ()
{
    return peer.getMissingGlyphCode (this);
}

/**
  * Returns the PostScript Name of this font.   
  *
  * @return The PostScript Name of this font.
  *
  * @since 1.2
  *
  * @see getName()
  * @see getFamily()
  * @see getFontName()
  */
  public String getPSName ()
{
    return peer.getPostScriptName (this);
}

/**
  * Returns the logical bounds of the specified string when rendered with this
  * font in the specified {@link FontRenderContext}. This box will include the
  * glyph origin, ascent, advance, height, and leading, but may not include all
  * diacritics or accents. To get the complete visual bounding box of all the
  * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
  * {@link TextLayout}.
  *
  * @param str The string to measure.
  * @param frc The context in which to make the precise glyph measurements.
  * 
  * @return A bounding box covering the logical bounds of the specified text.
  *
  * @see createGlyphVector()
  */
  public Rectangle2D getStringBounds (String str, FontRenderContext frc)
{
    return getStringBounds (str, 0, str.length () - 1, frc);
}

/**
  * Returns the logical bounds of the specified string when rendered with this
  * font in the specified {@link FontRenderContext}. This box will include the
  * glyph origin, ascent, advance, height, and leading, but may not include all
  * diacritics or accents. To get the complete visual bounding box of all the
  * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
  * {@link TextLayout}.
  *
  * @param str The string to measure.
  * @param begin Index of the first character in <code>str</code> to measure.
  * @param limit Index of the last character in <code>str</code> to measure.
  * @param frc The context in which to make the precise glyph measurements.
  * 
  * @return A bounding box covering the logical bounds of the specified text.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>str</code>.
  *
  * @since 1.2
  *
  * @see createGlyphVector()
  */
  public Rectangle2D getStringBounds (String str, int begin, 
                                      int limit, FontRenderContext frc)
{
    return peer.getStringBounds (this, new StringCharacterIterator(str), begin, limit, frc);
}

/**
  * Returns the logical bounds of the specified string when rendered with this
  * font in the specified {@link FontRenderContext}. This box will include the
  * glyph origin, ascent, advance, height, and leading, but may not include all
  * diacritics or accents. To get the complete visual bounding box of all the
  * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
  * {@link TextLayout}.
  *
  * @param ci The text to measure.
  * @param begin Index of the first character in <code>ci</code> to measure.
  * @param limit Index of the last character in <code>ci</code> to measure.
  * @param frc The context in which to make the precise glyph measurements.
  * 
  * @return A bounding box covering the logical bounds of the specified text.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>ci</code>.
  *
  * @since 1.2
  *
  * @see createGlyphVector()
  */
  public Rectangle2D getStringBounds (CharacterIterator ci, int begin, 
                                      int limit, FontRenderContext frc)
{
    return peer.getStringBounds (this, ci, begin, limit, frc);
}

/**
  * Returns the logical bounds of the specified string when rendered with this
  * font in the specified {@link FontRenderContext}. This box will include the
  * glyph origin, ascent, advance, height, and leading, but may not include all
  * diacritics or accents. To get the complete visual bounding box of all the
  * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
  * {@link TextLayout}.
  *
  * @param chars The text to measure.
  * @param begin Index of the first character in <code>ci</code> to measure.
  * @param limit Index of the last character in <code>ci</code> to measure.
  * @param frc The context in which to make the precise glyph measurements.
  * 
  * @return A bounding box covering the logical bounds of the specified text.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>chars</code>.
  *
  * @since 1.2
  *
  * @see createGlyphVector()
  */
  public Rectangle2D getStringBounds (char[] chars, int begin, 
                                      int limit, FontRenderContext frc)
{
    return peer.getStringBounds (this, new StringCharacterIterator (new String (chars)), 
                                 begin, limit, frc);
}

/**
  * Returns a copy of the affine transformation this font is currently
  * subject to, if any.
  *
  * @return The current transformation.
 */
  public AffineTransform getTransform ()
{
    return peer.getTransform (this);
}

/**
  * Indicates whether this font's line metrics are uniform. A font may be
  * composed of several "subfonts", each covering a different code range,
  * and each with their own line metrics. A font with no subfonts, or
  * subfonts with identical line metrics, is said to have "uniform" line
  * metrics.
  *
  * @return Whether this font has uniform line metrics.
  *
  * @see LineMetrics
  * @see getLineMetrics()
  */
  public boolean hasUniformLineMetrics ()
{
    return peer.hasUniformLineMetrics (this);
}

/**
  * Indicates whether this font is subject to a non-identity affine
  * transformation.
  *
  * @return <code>true</code> iff the font has a non-identity affine
  * transformation applied to it.
  */
  public boolean isTransformed ()
{
    return peer.isTransformed (this);
}

/**
  * Produces a glyph vector representing a full layout fo the specified
  * text in this font. Full layouts may include complex shaping and
  * reordering operations, for scripts such as Arabic or Hindi.
  *
  * Bidirectional (bidi) layout is not performed in this method; text
  * should have its bidi direction specified with one of the flags {@link
  * LAYOUT_LEFT_TO_RIGHT} or {@link LAYOUT_RIGHT_TO_LEFT}.
  *
  * Some types of layout (notably Arabic glyph shaping) may examine context
  * characters beyond the bounds of the indicated range, in order to select
  * an appropriate shape. The flags {@link LAYOUT_NO_START_CONTEXT} and
  * {@link LAYOUT_NO_LIMIT_CONTEXT} can be provided to prevent these extra
  * context areas from being examined, for instance if they contain invalid
  * characters.
  *
  * @param frc Context in which to perform the layout.
  * @param chars Text to perform layout on.
  * @param start Index of first character to perform layout on.
  * @param limit Index of last character to perform layout on.
  * @param flags Combination of flags controlling layout.
  *
  * @return A new {@link GlyphVector} representing the specified text.
  *
  * @throws IndexOutOfBoundsException if the range [begin, limit] is
  * invalid in <code>chars</code>. 
  */
  public GlyphVector layoutGlyphVector (FontRenderContext frc, 
                                        char[] chars, int start, 
                                        int limit, int flags)
{
    return peer.layoutGlyphVector (this, frc, chars, start, limit, flags);
}


/**
  * Returns a native peer object for this font.
  *
  * @return A native peer object for this font.
  *
  * @deprecated
  */
  public FontPeer getPeer ()
{
    return peer;
}


/**
  * Returns a hash value for this font.
  * 
  * @return A hash for this font.
  */
  public int hashCode()
{
    return this.toString().hashCode();
}


/**
  * Tests whether or not the specified object is equal to this font.  This
  * will be true if and only if:
  * <P>
  * <ul>
  * <li>The object is not <code>null</code>.
  * <li>The object is an instance of <code>Font</code>.
  * <li>The object has the same names, style, size, and transform as this object.
  * </ul>
  *
  * @return <code>true</code> if the specified object is equal to this
  * object, <code>false</code> otherwise.
  */
public boolean
equals(Object obj)
{
  if (obj == null)
    return(false);

  if (!(obj instanceof Font))
    return(false);

  Font f = (Font)obj;

  return (f.getName ().equals (this.getName ()) &&
          f.getFamily ().equals (this.getFamily ()) &&
          f.getFontName ().equals (this.getFontName ()) &&
          f.getTransform ().equals (this.getTransform ()) &&
          f.getSize() == this.getSize() &&
          f.getStyle() == this.getStyle());
} 

/*************************************************************************/

/**
  * Returns a string representation of this font.
  *
  * @return A string representation of this font.
  */
public String
toString()
{
  String styleString = "";

  switch (getStyle ())
    {
    case 0:
      styleString = "plain";
      break;
    case 1:
      styleString = "bold";
      break;
    case 2:
      styleString = "italic";
      break;
    default:
      styleString = "unknown";
    }

  return getClass ().getName () 
    + "[family=" + getFamily ()
    + ",name=" + getFontName ()
    + ",style=" + styleString
    + ",size=" + getSize () + "]";
}


  /**
   * Determines the line metrics for a run of text.
   *
   * @param str the text run to be measured.
   *
   * @param frc the font rendering parameters that are used for the
   *        measurement. The exact placement and size of text slightly
   *        depends on device-specific characteristics, for instance
   *        the device resolution or anti-aliasing.  For this reason,
   *        the returned measurement will only be accurate if the
   *        passed <code>FontRenderContext</code> correctly reflects
   *        the relevant parameters. Hence, <code>frc</code> should be
   *        obtained from the same <code>Graphics2D</code> that will
   *        be used for drawing, and any rendering hints should be set
   *        to the desired values before obtaining <code>frc</code>.
   *
   * @see java.awt.Graphics2D#getFontRenderContext()
   */
  public LineMetrics getLineMetrics(String str, FontRenderContext frc)
  {
    return getLineMetrics (str, 0, str.length () - 1, frc);
  }

} // class Font 

