/* FontDelegate.java -- Interface implemented by all font delegates.
   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.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.text.CharacterIterator;
import java.util.Locale;


/**
 * The interface that all font delegate objects implement,
 * irrespective of where they get their information from.
 *
 * <p><b>Thread Safety:</b> All classes that implement the
 * <code>FontDelegate</code> interface must allow calling these
 * methods from multiple concurrent threads. The delegates are
 * responsible for performing the necessary synchronization.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public interface FontDelegate
{
  /**
   * Returns the full name of this font face in the specified
   * locale, for example <i>&#x201c;Univers Light&#x201d;</i>.
   *
   * @param locale the locale for which to localize the name.
   *
   * @return the face name.
   */
  public String getFullName(Locale locale);
  
  
  /**
   * Returns the name of the family to which this font face belongs,
   * for example <i>&#x201c;Univers&#x201d;</i>.
   *
   * @param locale the locale for which to localize the name.
   *
   * @return the family name.
   */
  public String getFamilyName(Locale locale);


  /**
   * Returns the name of this font face inside the family, for example
   * <i>&#x201c;Light&#x201d;</i>.
   *
   * @param locale the locale for which to localize the name.
   *
   * @return the name of the face inside its family.
   */
  public String getSubFamilyName(Locale locale);
  
  
  /**
   * Returns the PostScript name of this font face, for example
   * <i>&#x201c;Helvetica-Bold&#x201d;</i>.
   *
   * @return the PostScript name, or <code>null</code> if the font
   * does not provide a PostScript name.
   */
  public String getPostScriptName();


  /**
   * Returns the number of glyphs in this font face.
   */
  public int getNumGlyphs();
  
  
  /**
   * Returns the index of the glyph which gets displayed if the font
   * cannot map a Unicode code point to a glyph. Many fonts show this
   * glyph as an empty box.
   */
  public int getMissingGlyphCode();
  

  /**
   * Creates a GlyphVector by mapping each character in a
   * CharacterIterator to the corresponding glyph.
   *
   * <p>The mapping takes only the font&#x2019;s <code>cmap</code>
   * tables into consideration. No other operations (such as glyph
   * re-ordering, composition, or ligature substitution) are
   * performed. This means that the resulting GlyphVector will not be
   * correct for text in languages that have complex
   * character-to-glyph mappings, such as Arabic, Hebrew, Hindi, or
   * Thai.
   *
   * @param font the font object that the created GlyphVector
   * will return when it gets asked for its font. This argument is
   * needed because the public API works with java.awt.Font,
   * not with some private delegate like OpenTypeFont.
   *
   * @param frc the font rendering parameters that are used for
   * measuring glyphs. The exact placement of text slightly depends on
   * device-specific characteristics, for instance the device
   * resolution or anti-aliasing. For this reason, any measurements
   * 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>.
   *
   * @param ci a CharacterIterator for iterating over the
   * characters to be displayed.
   */
  public GlyphVector createGlyphVector(Font font,
                                       FontRenderContext frc,
                                       CharacterIterator ci);


  /**
   * Determines the advance width and height for a glyph.
   *
   * @param glyphIndex the glyph whose advance width is to be
   * determined.
   *
   * @param pointSize the point size of the font.
   *
   * @param transform a transform that is applied in addition to
   * scaling to the specified point size. This is often used for
   * scaling according to the device resolution. Those who lack any
   * aesthetic sense may also use the transform to slant or stretch
   * glyphs.
   *
   * @param antialias <code>true</code> for anti-aliased rendering,
   * <code>false</code> for normal rendering. For hinted fonts,
   * this parameter may indeed affect the result.
   *
   * @param fractionalMetrics <code>true</code> for fractional metrics,
   * <code>false</code> for rounding the result to a pixel boundary.
   *
   * @param horizontal <code>true</code> for horizontal line layout,
   * <code>false</code> for vertical line layout.
   *
   * @param advance a point whose <code>x</code> and <code>y</code>
   * fields will hold the advance in each direction. It is well
   * possible that both values are non-zero, for example for rotated
   * text or for Urdu fonts.
   */
  public void getAdvance(int glyphIndex,
                         float pointSize,
                         AffineTransform transform,
                         boolean antialias,
                         boolean fractionalMetrics,
                         boolean horizontal,
                         Point2D advance);
  

  /**
   * Returns the shape of a glyph.
   *
   * @param glyphIndex the glyph whose advance width is to be
   * determined.
   *
   * @param pointSize the point size of the font.
   *
   * @param transform a transform that is applied in addition to
   * scaling to the specified point size. This is often used for
   * scaling according to the device resolution. Those who lack any
   * aesthetic sense may also use the transform to slant or stretch
   * glyphs.
   *
   * @param antialias <code>true</code> for anti-aliased rendering,
   * <code>false</code> for normal rendering. For hinted fonts, this
   * parameter may indeed affect the result.
   *
   * @param fractionalMetrics <code>true</code> for fractional
   * metrics, <code>false</code> for rounding the result to a pixel
   * boundary.
   *
   * @return the scaled and grid-fitted outline of the specified
   * glyph, or <code>null</code> for bitmap fonts.
   */
  public GeneralPath getGlyphOutline(int glyphIndex,
                                     float pointSize,
                                     AffineTransform transform,
                                     boolean antialias,
                                     boolean fractionalMetrics);


  /**
   * Returns a name for the specified glyph. This is useful for
   * generating PostScript or PDF files that embed some glyphs of a
   * font.
   *
   * <p><b>Names are not unique:</b> Under some rare circumstances,
   * the same name can be returned for different glyphs. It is
   * therefore recommended that printer drivers check whether the same
   * name has already been returned for antoher glyph, and make the
   * name unique by adding the string ".alt" followed by the glyph
   * index.</p>
   *
   * <p>This situation would occur for an OpenType or TrueType font
   * that has a <code>post</code> table of format 3 and provides a
   * mapping from glyph IDs to Unicode sequences through a
   * <code>Zapf</code> table. If the same sequence of Unicode
   * codepoints leads to different glyphs (depending on contextual
   * position, for example, or on typographic sophistication level),
   * the same name would get synthesized for those glyphs.
   *
   * @param glyphIndex the glyph whose name the caller wants to
   * retrieve.
   */
  public String getGlyphName(int glyphIndex);


  /**
   * Determines the distance between the base line and the highest
   * ascender.
   *
   * @param pointSize the point size of the font.
   *
   * @param transform a transform that is applied in addition to
   * scaling to the specified point size. This is often used for
   * scaling according to the device resolution. Those who lack any
   * aesthetic sense may also use the transform to slant or stretch
   * glyphs.
   *
   * @param antialiased <code>true</code> for anti-aliased rendering,
   * <code>false</code> for normal rendering. For hinted fonts,
   * this parameter may indeed affect the result.
   *
   * @param fractionalMetrics <code>true</code> for fractional metrics,
   * <code>false</code> for rounding the result to a pixel boundary.
   *
   * @param horizontal <code>true</code> for horizontal line layout,
   * <code>false</code> for vertical line layout.
   *
   * @return the ascent, which usually is a positive number.
   */
  public float getAscent(float pointSize,
                         AffineTransform transform,
                         boolean antialiased,
                         boolean fractionalMetrics,
                         boolean horizontal);


  /**
   * Determines the distance between the base line and the lowest
   * descender.
   *
   * @param pointSize the point size of the font.
   *
   * @param transform a transform that is applied in addition to
   * scaling to the specified point size. This is often used for
   * scaling according to the device resolution. Those who lack any
   * aesthetic sense may also use the transform to slant or stretch
   * glyphs.
   *
   * @param antialiased <code>true</code> for anti-aliased rendering,
   * <code>false</code> for normal rendering. For hinted fonts,
   * this parameter may indeed affect the result.
   *
   * @param fractionalMetrics <code>true</code> for fractional metrics,
   * <code>false</code> for rounding the result to a pixel boundary.
   *
   * @param horizontal <code>true</code> for horizontal line layout,
   * <code>false</code> for vertical line layout.
   *
   * @return the descent, which usually is a nagative number.
   */
  public float getDescent(float pointSize,
                          AffineTransform transform,
                          boolean antialiased,
                          boolean fractionalMetrics,
                          boolean horizontal);
}
