/* 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., 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 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.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.peer.FontPeer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
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
{

  /**
   * 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;
  
  /**
   * Indicates to <code>createFont</code> that the supplied font data
   * is in Type1 format.
   * 
   * @since 1.5
   */
  public static final int TYPE1_FONT = 1;

  /**
   * 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;

  /**
   * @since 1.6
   */
  public static final String DIALOG = "Dialog";

  /**
   * @since 1.6
   */
  public static final String DIALOG_INPUT = "DialogInput";

  /**
   * @since 1.6
   */
  public static final String MONOSPACED = "Monospaced";

  /**
   * @since 1.6
   */
  public static final String SANS_SERIF = "SansSerif";

  /**
   * @since 1.6
   */
  public static final String SERIF = "Serif";

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

  /**
   * The size of this font in points, rounded.
   *
   * @since 1.0
   */
  protected int size;

  /**
   * The size of this font in points.
   *
   * @since 1.0
   */
  protected float pointSize;

  /**
   * 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 transient ClasspathFontPeer peer;

  /**
   * The cached hashcode. A value of 0 (default initialized) means that the
   * hashcode is not computed yet.
   */
  private transient int hashCode;

  /**
   * 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.
   * 
   * @param fontspec  a string specifying the required font (<code>null</code> 
   *                  permitted, interpreted as 'Dialog-PLAIN-12').
   * 
   * @return A font.
   */
  public static Font decode(String fontspec)
  {
    if (fontspec == null) 
      fontspec = "Dialog-PLAIN-12";
    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. */

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

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

  /* Every Font constructor should eventually call this. */
  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);
  }

  protected Font(Font font)
  {
    this(font.getName(), font.getAttributes());
  }

  /**
   * 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);
    this.size = size;
    this.pointSize = (float) size;
    if (name != null)
      this.name = name;
    else
      this.name = peer.getName(this);
  }

  public Font(Map<? extends AttributedCharacterIterator.Attribute, ?> 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.
   ClasspathToolkit.getFont(String,Map) uses reflection to call this
   package-private constructor. */
  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();
    peer = getPeerFromToolkit(name, attrs);
    size = (int) peer.getSize(this);
    pointSize = peer.getSize(this);
    if (name != null)
      this.name = name;
    else
      this.name = peer.getName(this);
  }

  /**
   * 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 size of the font, in typographics points (1/72 of an inch),
   * rounded to an integer.
   * 
   * @return The font size
   */
  public int getSize()
  {
    return size;
  }

  /**
   * Returns the size of the font, in typographics points (1/72 of an inch).
   * 
   * @return The font size
   */
  public float getSize2D()
  {
    return pointSize;
  }

  /**
   * 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 canDisplay((int) c);
  }

  public boolean canDisplay(int codePoint)
  {
    return peer.canDisplay(this, codePoint);
  }

  /**
   * 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);
  }

  /**
   * Creates a new font from a File object.
   *
   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
   *
   * @param fontFormat - Integer code indicating the format the font data is
   * in.Currently this can only be {@link #TRUETYPE_FONT}.
   * @param file - a {@link File} from which font data will be read.
   *
   * @return A new {@link Font} of the format indicated.
   *
   * @throws IllegalArgumentException if <code>fontType</code> is not
   * recognized.
   * @throws NullPointerException if <code>file</code> is <code>null</code>.
   * @throws FontFormatException if data in the file is invalid or cannot be read..
   * @throws SecurityException if the caller has no read permission for the file.
   * @throws IOException if the file cannot be read
   *
   * @since 1.5
   */
  public static Font createFont (int fontFormat, File file)
    throws FontFormatException, IOException
  {
    if( file == null )
      throw new NullPointerException("Null file argument");
    return tk().createFont(fontFormat, new FileInputStream( file ));
  }

  /**
   * 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(FontRenderContext, char[], int, int, int)
   */
  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(FontRenderContext, char[], int, int, int)
   */
  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(FontRenderContext, char[], int, int, int)
   */
  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(FontRenderContext, char[], int, int, int)
   *
   * @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<? extends AttributedCharacterIterator.Attribute, ?> 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<TextAttribute, ?> 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 java.awt.font.TextAttribute  
   */
  public static Font getFont(Map<? extends AttributedCharacterIterator.Attribute, ?> 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 java.awt.font.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.getNumGlyphs(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(FontRenderContext, String)
   */
  public Rectangle2D getStringBounds(String str, FontRenderContext frc)
  {
    char[] chars = str.toCharArray();
    return getStringBounds(chars, 0, chars.length, 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(FontRenderContext, String)
   */
  public Rectangle2D getStringBounds(String str, int begin, 
                                     int limit, FontRenderContext frc)
  {
    String sub = str.substring(begin, limit);
    return getStringBounds(sub, 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(FontRenderContext, CharacterIterator)
   */
  public Rectangle2D getStringBounds(CharacterIterator ci, int begin, 
                                     int limit, FontRenderContext frc)
  {
    int start = ci.getBeginIndex();
    int end = ci.getEndIndex();
    char[] chars = new char[limit - start];
    ci.setIndex(start);
    for (int index = 0; index < chars.length; index++)
      {
        chars[index] = ci.current();
        ci.next();
      }
    return getStringBounds(chars, 0, chars.length, 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(FontRenderContext, char[])
   */
  public Rectangle2D getStringBounds(char[] chars, int begin, 
                                     int limit, FontRenderContext frc)
  {
    String str = new String(chars, begin, limit - begin);
    TextLayout layout = new TextLayout(str, this, frc);
    return new Rectangle2D.Float(0, -layout.getAscent(), layout.getAdvance(),
                                layout.getDescent() + layout.getLeading());
  }

  /**
   * 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(String, FontRenderContext)
   */
  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()
  {
    // We cache the hashcode. This makes sense, because the font wouldn't
    // change the relevant properties.
    if (hashCode == 0)
      {
        hashCode = getName().hashCode() ^ getTransform().hashCode() ^ getSize()
                   ^ getStyle();
        // In the rare case when the above yields 0, we set this to some other
        // value to avoid recomputing over and over again. This is still
        // conform to the specification of hashCode().
        if (hashCode == 0)
          {
            hashCode = -1;
          }
      }
    return 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);
  }

  public boolean hasLayoutAttributes()
  {
    // TODO: Implement properly.
    return false;
  }

  /**
   * Reads the normal fields from the stream and then constructs the
   * peer from the style and size through getPeerFromToolkit().
   */
  private void readObject(ObjectInputStream ois)
    throws IOException, ClassNotFoundException
  {
    ois.defaultReadObject();

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

  }
}
