Source for java.awt.Font

   1: /* Font.java -- Font object
   2:    Copyright (C) 1999, 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt;
  40: 
  41: import gnu.java.awt.ClasspathToolkit;
  42: import gnu.java.awt.peer.ClasspathFontPeer;
  43: 
  44: import java.awt.font.FontRenderContext;
  45: import java.awt.font.GlyphVector;
  46: import java.awt.font.LineMetrics;
  47: import java.awt.font.TextLayout;
  48: import java.awt.geom.AffineTransform;
  49: import java.awt.geom.Rectangle2D;
  50: import java.awt.peer.FontPeer;
  51: import java.io.IOException;
  52: import java.io.InputStream;
  53: import java.io.Serializable;
  54: import java.text.AttributedCharacterIterator;
  55: import java.text.CharacterIterator;
  56: import java.text.StringCharacterIterator;
  57: import java.util.HashMap;
  58: import java.util.Locale;
  59: import java.util.Map;
  60: import java.util.StringTokenizer;
  61: 
  62: /**
  63:  * This class represents a windowing system font.
  64:  *
  65:  * @author Aaron M. Renn (arenn@urbanophile.com)
  66:  * @author Warren Levy (warrenl@cygnus.com)
  67:  * @author Graydon Hoare (graydon@redhat.com)
  68:  */
  69: public class Font implements Serializable
  70: {
  71: 
  72: /*
  73:  * Static Variables
  74:  */
  75: 
  76: /**
  77:   * Constant indicating a "plain" font.
  78:   */
  79: public static final int PLAIN = 0;
  80: 
  81: /**
  82:   * Constant indicating a "bold" font.
  83:   */
  84: public static final int BOLD = 1;
  85: 
  86: /**
  87:   * Constant indicating an "italic" font.
  88:   */
  89: public static final int ITALIC = 2;
  90: 
  91: /**
  92:  * Constant indicating the baseline mode characteristic of Roman.
  93:  */
  94: public static final int ROMAN_BASELINE = 0;
  95: 
  96: /**
  97:  * Constant indicating the baseline mode characteristic of Chinese.
  98:  */
  99: public static final int CENTER_BASELINE = 1;
 100: 
 101: /**
 102:  * Constant indicating the baseline mode characteristic of Devanigri.
 103:  */
 104: public static final int HANGING_BASELINE = 2;  
 105: 
 106: 
 107:   /**
 108:    * Indicates to <code>createFont</code> that the supplied font data
 109:    * is in TrueType format.
 110:    *
 111:    * <p><em>Specification Note:</em> The Sun JavaDoc for J2SE 1.4 does
 112:    * not indicate whether this value also subsumes OpenType. OpenType
 113:    * is essentially the same format as TrueType, but allows to define
 114:    * glyph shapes in the same way as PostScript, using cubic bezier
 115:    * curves.
 116:    *
 117:    * @since 1.3
 118:    */
 119:   public static final int TRUETYPE_FONT = 0;
 120: 
 121: 
 122:   /**
 123:    * A flag for <code>layoutGlyphVector</code>, indicating that the
 124:    * orientation of a text run is from left to right.
 125:    *
 126:    * @since 1.4
 127:    */
 128:   public static final int LAYOUT_LEFT_TO_RIGHT = 0;
 129: 
 130: 
 131:   /**
 132:    * A flag for <code>layoutGlyphVector</code>, indicating that the
 133:    * orientation of a text run is from right to left.
 134:    *
 135:    * @since 1.4
 136:    */
 137:   public static final int LAYOUT_RIGHT_TO_LEFT = 1;
 138: 
 139: 
 140:   /**
 141:    * A flag for <code>layoutGlyphVector</code>, indicating that the
 142:    * text does not contain valid characters before the
 143:    * <code>start</code> position.  If this flag is set,
 144:    * <code>layoutGlyphVector</code> does not examine the text before
 145:    * <code>start</code>, even if this would be necessary to select the
 146:    * correct glyphs (e.g., for Arabic text).
 147:    *
 148:    * @since 1.4
 149:    */
 150:   public static final int LAYOUT_NO_START_CONTEXT = 2;
 151: 
 152: 
 153:   /**
 154:    * A flag for <code>layoutGlyphVector</code>, indicating that the
 155:    * text does not contain valid characters after the
 156:    * <code>limit</code> position.  If this flag is set,
 157:    * <code>layoutGlyphVector</code> does not examine the text after
 158:    * <code>limit</code>, even if this would be necessary to select the
 159:    * correct glyphs (e.g., for Arabic text).
 160:    *
 161:    * @since 1.4
 162:    */
 163:   public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
 164: 
 165:   /**
 166:    * The logical name of this font.
 167:    *
 168:    * @since 1.0
 169:    */
 170:   protected String name;
 171: 
 172:   /**
 173:    * The size of this font in pixels.
 174:    *
 175:    * @since 1.0
 176:    */
 177:   protected int size;
 178: 
 179:   /**
 180:    * The style of this font -- PLAIN, BOLD, ITALIC or BOLD+ITALIC.
 181:    *
 182:    * @since 1.0
 183:    */
 184:   protected int style;
 185: 
 186: // Serialization constant
 187: private static final long serialVersionUID = -4206021311591459213L;
 188: 
 189: 
 190:   // The ClasspathToolkit-provided peer which implements this font
 191:   private ClasspathFontPeer peer;
 192: 
 193: /*************************************************************************/
 194: 
 195: /*
 196:  * Static Methods
 197:  */
 198: 
 199: /**
 200:   * Creates a <code>Font</code> object from the specified string, which
 201:   * is in one of the following formats:
 202:   * <p>
 203:   * <ul>
 204:   * <li>fontname-style-pointsize
 205:   * <li>fontname-style
 206:   * <li>fontname-pointsize
 207:   * <li>fontname
 208:   * </ul>
 209:   * <p>
 210:   * The style should be one of BOLD, ITALIC, or BOLDITALIC.  The default
 211:   * style if none is specified is PLAIN.  The default size if none
 212:   * is specified is 12.
 213:   * 
 214:   * @param fontspec  a string specifying the required font (<code>null</code> 
 215:   *                  permitted, interpreted as 'Dialog-PLAIN-12').
 216:   * 
 217:   * @return A font.
 218:   */
 219:   public static Font decode (String fontspec)
 220: {
 221:   if (fontspec == null) 
 222:     fontspec = "Dialog-PLAIN-12";
 223:   String name = null;
 224:   int style = PLAIN;
 225:   int size = 12;
 226: 
 227:   StringTokenizer st = new StringTokenizer(fontspec, "- ");
 228:   while (st.hasMoreTokens())
 229:     {
 230:       String token = st.nextToken();
 231:       if (name == null)
 232:         {
 233:           name = token;
 234:           continue;
 235:         }
 236: 
 237:       if (token.toUpperCase().equals("BOLD"))
 238:         {
 239:           style = BOLD;
 240:           continue;
 241:         }
 242:       if (token.toUpperCase().equals("ITALIC"))
 243:         {
 244:           style = ITALIC;
 245:           continue;
 246:         }
 247:       if (token.toUpperCase().equals("BOLDITALIC"))
 248:         {
 249:             style = BOLD | ITALIC;
 250:           continue;
 251:         }
 252: 
 253:       int tokenval = 0;
 254:       try
 255:         {
 256:           tokenval = Integer.parseInt(token);
 257:         }
 258:       catch(NumberFormatException e)
 259:         {
 260:       // Ignored.
 261:     }
 262: 
 263:       if (tokenval != 0)
 264:         size = tokenval;
 265:     }
 266: 
 267:     HashMap attrs = new HashMap();
 268:     ClasspathFontPeer.copyStyleToAttrs (style, attrs);
 269:     ClasspathFontPeer.copySizeToAttrs (size, attrs);
 270: 
 271:     return getFontFromToolkit (name, attrs);
 272: }
 273: 
 274:   /* These methods delegate to the toolkit. */
 275: 
 276:   protected static ClasspathToolkit tk ()
 277:   {
 278:     return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
 279:   }
 280: 
 281:   /* Every factory method in Font should eventually call this. */
 282:   protected static Font getFontFromToolkit (String name, Map attribs)
 283:   {
 284:     return tk ().getFont (name, attribs);
 285:   }
 286: 
 287:   /* Every Font constructor should eventually call this. */
 288:   protected static ClasspathFontPeer getPeerFromToolkit (String name, Map attrs)
 289:   {
 290:     return tk ().getClasspathFontPeer (name, attrs);
 291:   }
 292: 
 293: 
 294: /*************************************************************************/
 295: 
 296: /**
 297:   * Returns a <code>Font</code> object from the passed property name.
 298:   *
 299:   * @param propname The name of the system property.
 300:   * @param defval Value to use if the property is not found.
 301:   *
 302:   * @return The requested font, or <code>default</code> if the property 
 303:   * not exist or is malformed.
 304:   */
 305:   public static Font getFont (String propname, Font defval)
 306: {
 307:   String propval = System.getProperty(propname);
 308:   if (propval != null)
 309:       return decode (propval);
 310:     return defval;
 311: }
 312: 
 313: /*************************************************************************/
 314: 
 315: /**
 316:   * Returns a <code>Font</code> object from the passed property name.
 317:   *
 318:   * @param propname The name of the system property.
 319:   *
 320:   * @return The requested font, or <code>null</code> if the property 
 321:   * not exist or is malformed.
 322:   */
 323:   public static Font getFont (String propname)
 324: {
 325:     return getFont (propname, (Font)null);
 326: }
 327: 
 328: /*************************************************************************/
 329: 
 330: /*
 331:  * Constructors
 332:  */
 333: 
 334: /**
 335:   * Initializes a new instance of <code>Font</code> with the specified
 336:   * attributes.
 337:   *
 338:   * @param name The name of the font.
 339:   * @param style The font style.
 340:   * @param size The font point size.
 341:   */
 342: 
 343:   public Font (String name, int style, int size)
 344:   {
 345:     HashMap attrs = new HashMap();
 346:     ClasspathFontPeer.copyStyleToAttrs (style, attrs);
 347:     ClasspathFontPeer.copySizeToAttrs (size, attrs);
 348:     this.peer = getPeerFromToolkit (name, attrs);
 349:   }
 350: 
 351:   public Font (Map attrs)
 352:   {
 353:     this(null, attrs);
 354:   }
 355: 
 356:   /* This extra constructor is here to permit ClasspathToolkit and to
 357:      build a font with a "logical name" as well as attrs.
 358:      ClasspathToolkit.getFont(String,Map) uses reflection to call this
 359:      package-private constructor. */
 360:   Font (String name, Map attrs)
 361:   {
 362:     // If attrs is null, setting it to an empty HashMap will give this
 363:     // Font default attributes.
 364:     if (attrs == null)
 365:       attrs = new HashMap();
 366:     this.peer = getPeerFromToolkit (name, attrs);
 367:   }
 368: 
 369: /*************************************************************************/
 370: 
 371: /*
 372:  * Instance Methods
 373:  */
 374: 
 375: /**
 376:    * Returns the logical name of the font.  A logical name is the name the
 377:    * font was constructed with. It may be the name of a logical font (one
 378:    * of 6 required names in all java environments) or it may be a face
 379:    * name.
 380:   *
 381:   * @return The logical name of the font.
 382:   *
 383:   * @see #getFamily()
 384:   * @see #getFontName()
 385:   */
 386:   public String getName ()
 387: {
 388:     return peer.getName (this);
 389: }
 390: 
 391: /*************************************************************************/
 392: 
 393: /**
 394:   * Returns the style of the font.
 395:   * 
 396:   * @return The font style.
 397:   */
 398:   public int getSize ()
 399: {
 400:     return (int) peer.getSize (this);
 401: }
 402: 
 403:   public float getSize2D ()
 404: {
 405:     return peer.getSize (this);
 406: }
 407: 
 408: /*************************************************************************/
 409: 
 410: /**
 411:   * Tests whether or not this is a plain font.  This will be true if
 412:   * and only if neither the bold nor the italics style is set.
 413:   *
 414:   * @return <code>true</code> if this is a plain font, <code>false</code>
 415:   * otherwise.
 416:   */
 417:   public boolean isPlain ()
 418: {
 419:     return peer.isPlain (this); 
 420: }
 421: 
 422: /*************************************************************************/
 423: 
 424: /**
 425:   * Tests whether or not this font is bold.
 426:   *
 427:   * @return <code>true</code> if this font is bold, <code>false</code>
 428:   * otherwise.
 429:   */
 430:   public boolean isBold ()
 431: {
 432:     return peer.isBold (this);
 433: }
 434: 
 435: /*************************************************************************/
 436: 
 437: /**
 438:   * Tests whether or not this font is italic.
 439:   *
 440:   * @return <code>true</code> if this font is italic, <code>false</code>
 441:   * otherwise.
 442:   */
 443:   public boolean isItalic ()
 444: {
 445:     return peer.isItalic (this);
 446: }
 447: 
 448: /*************************************************************************/
 449: 
 450: /**
 451:    * Returns the family name of this font. A family name describes a design
 452:    * or "brand name" (such as Helvetica or Palatino). It is less specific
 453:    * than a font face name (such as Helvetica Bold).
 454:   *
 455:   * @return A string containing the font family name.
 456:   *
 457:   * @since 1.2
 458:   *
 459:   * @see #getName()
 460:   * @see #getFontName()
 461:   * @see GraphicsEnvironment#getAvailableFontFamilyNames()
 462:   */
 463:   public String getFamily ()
 464: {
 465:     return peer.getFamily (this);
 466: }
 467: 
 468: /**
 469:   * Returns integer code representing the sum of style flags of this font, a
 470:   * combination of either {@link #PLAIN}, {@link #BOLD}, or {@link #ITALIC}.
 471:   *
 472:   * @return code representing the style of this font.
 473:   *
 474:   * @see #isPlain()
 475:   * @see #isBold()
 476:   * @see #isItalic()
 477:   */
 478:   public int getStyle ()
 479: {
 480:     return peer.getStyle (this);
 481: }
 482: 
 483: /**
 484:   * Checks if specified character maps to a glyph in this font.
 485:   *
 486:   * @param c The character to check.
 487:   *
 488:   * @return Whether the character has a corresponding glyph in this font.
 489:   *
 490:   * @since 1.2
 491:   */
 492:   public boolean canDisplay (char c)
 493: {
 494:     return peer.canDisplay (this, c);    
 495: }
 496: 
 497: /**
 498:   * Checks how much of a given string can be mapped to glyphs in 
 499:   * this font.
 500:   *
 501:   * @param s The string to check.
 502:   *
 503:   * @return The index of the first character in <code>s</code> which cannot
 504:   * be converted to a glyph by this font, or <code>-1</code> if all
 505:   * characters can be mapped to glyphs.
 506:   *
 507:   * @since 1.2
 508:   */
 509:   public int canDisplayUpTo (String s)
 510: {
 511:     return peer.canDisplayUpTo (this, new StringCharacterIterator (s), 
 512:                                 0, s.length () - 1);
 513: }
 514: 
 515: /**
 516:   * Checks how much of a given sequence of text can be mapped to glyphs in
 517:   * this font.
 518:   *
 519:   * @param text Array containing the text to check.
 520:   * @param start Position of first character to check in <code>text</code>.
 521:   * @param limit Position of last character to check in <code>text</code>.
 522:   *
 523:   * @return The index of the first character in the indicated range which
 524:   * cannot be converted to a glyph by this font, or <code>-1</code> if all
 525:   * characters can be mapped to glyphs.
 526:   *
 527:   * @since 1.2
 528:   *
 529:   * @throws IndexOutOfBoundsException if the range [start, limit] is
 530:   * invalid in <code>text</code>.
 531:   */
 532:   public int canDisplayUpTo (char[] text, int start, int limit)
 533: {
 534:     return peer.canDisplayUpTo 
 535:       (this, new StringCharacterIterator (new String (text)), start, limit);
 536: }
 537: 
 538: /**
 539:   * Checks how much of a given sequence of text can be mapped to glyphs in
 540:   * this font.
 541:   *
 542:   * @param i Iterator over the text to check.
 543:   * @param start Position of first character to check in <code>i</code>.
 544:   * @param limit Position of last character to check in <code>i</code>.
 545:   *
 546:   * @return The index of the first character in the indicated range which
 547:   * cannot be converted to a glyph by this font, or <code>-1</code> if all
 548:   * characters can be mapped to glyphs.
 549:   *
 550:   * @since 1.2
 551:   *
 552:   * @throws IndexOutOfBoundsException if the range [start, limit] is
 553:   * invalid in <code>i</code>.
 554:   */
 555:   public int canDisplayUpTo (CharacterIterator i, int start, int limit)
 556: {
 557:     return peer.canDisplayUpTo (this, i, start, limit);    
 558: }
 559: 
 560: /**
 561:   * Creates a new font with point size 1 and {@link #PLAIN} style,
 562:   * reading font data from the provided input stream. The resulting font
 563:   * can have further fonts derived from it using its
 564:   * <code>deriveFont</code> method.
 565:   *
 566:   * @param fontFormat Integer code indicating the format the font data is
 567:   * in.Currently this can only be {@link #TRUETYPE_FONT}.
 568:   * @param is {@link InputStream} from which font data will be read. This
 569:   * stream is not closed after font data is extracted.
 570:   *
 571:   * @return A new {@link Font} of the format indicated.
 572:   *
 573:   * @throws IllegalArgumentException if <code>fontType</code> is not
 574:   * recognized.
 575:   * @throws FontFormatException if data in InputStream is not of format
 576:   * indicated.
 577:   * @throws IOException if insufficient data is present on InputStream.
 578:   *
 579:   * @since 1.3
 580:   */
 581:   public static Font createFont (int fontFormat, InputStream is) 
 582:   throws FontFormatException, IOException
 583: {
 584:     return tk().createFont (fontFormat, is);
 585: }
 586: 
 587: /**
 588:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 589:   * {@link GlyphVector} with a mapped glyph for each input character. This
 590:   * sort of mapping is often sufficient for some scripts such as Roman, but
 591:   * is inappropriate for scripts with special shaping or contextual layout
 592:   * requirements such as Arabic, Indic, Hebrew or Thai.
 593:   *
 594:   * @param ctx The rendering context used for precise glyph placement.
 595:   * @param str The string to convert to Glyphs.
 596:   *
 597:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 598:   * through the font's cmap table.
 599:   *
 600:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 601:   */
 602:   public GlyphVector createGlyphVector (FontRenderContext ctx, String str)
 603: {
 604:     return peer.createGlyphVector (this, ctx, new StringCharacterIterator (str));
 605: }
 606: 
 607: /**
 608:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 609:   * {@link GlyphVector} with a mapped glyph for each input character. This
 610:   * sort of mapping is often sufficient for some scripts such as Roman, but
 611:   * is inappropriate for scripts with special shaping or contextual layout
 612:   * requirements such as Arabic, Indic, Hebrew or Thai.
 613:   *
 614:   * @param ctx The rendering context used for precise glyph placement.
 615:   * @param i Iterator over the text to convert to glyphs.
 616:   *
 617:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 618:   * through the font's cmap table.
 619:   *
 620:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 621:   */
 622:   public GlyphVector createGlyphVector (FontRenderContext ctx, CharacterIterator i)
 623: {
 624:     return peer.createGlyphVector (this, ctx, i);
 625: }
 626: 
 627: /**
 628:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 629:   * {@link GlyphVector} with a mapped glyph for each input character. This
 630:   * sort of mapping is often sufficient for some scripts such as Roman, but
 631:   * is inappropriate for scripts with special shaping or contextual layout
 632:   * requirements such as Arabic, Indic, Hebrew or Thai.
 633:   *
 634:   * @param ctx The rendering context used for precise glyph placement.
 635:   * @param chars Array of characters to convert to glyphs.
 636:   *
 637:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 638:   * through the font's cmap table.
 639:   *
 640:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 641:   */
 642:   public GlyphVector createGlyphVector (FontRenderContext ctx, char[] chars)
 643: {
 644:     return peer.createGlyphVector 
 645:       (this, ctx, new StringCharacterIterator (new String (chars)));
 646: }
 647: 
 648: /**
 649:   * Extracts a sequence of glyphs from a font, returning a new {@link
 650:   * GlyphVector} with a mapped glyph for each input glyph code. 
 651:   *
 652:   * @param ctx The rendering context used for precise glyph placement.
 653:   * @param glyphCodes Array of characters to convert to glyphs.
 654:   *
 655:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 656:   * through the font's cmap table.
 657:   *
 658:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 659:   *
 660:   * @specnote This method is documented to perform character-to-glyph
 661:   * conversions, in the Sun documentation, but its second parameter name is
 662:   * "glyphCodes" and it is not clear to me why it would exist if its
 663:   * purpose was to transport character codes inside integers. I assume it
 664:   * is mis-documented in the Sun documentation.
 665:   */
 666: 
 667:   public GlyphVector createGlyphVector (FontRenderContext ctx, int[] glyphCodes)
 668: {
 669:     return peer.createGlyphVector (this, ctx, glyphCodes);
 670: }
 671: 
 672: /**
 673:   * Produces a new {@link Font} based on the current font, adjusted to a
 674:   * new size and style.
 675:   *
 676:   * @param style The style of the newly created font.
 677:   * @param size The size of the newly created font.
 678:   *
 679:   * @return A clone of the current font, with the specified size and style.
 680:   *
 681:   * @since 1.2
 682:   */
 683:   public Font deriveFont (int style, float size)
 684: {
 685:     return peer.deriveFont (this, style, size);
 686: }
 687: 
 688: /**
 689:   * Produces a new {@link Font} based on the current font, adjusted to a
 690:   * new size.
 691:   *
 692:   * @param size The size of the newly created font.
 693:   *
 694:   * @return A clone of the current font, with the specified size.
 695:   *
 696:   * @since 1.2
 697:   */
 698:   public Font deriveFont (float size)
 699: {
 700:     return peer.deriveFont (this, size);
 701: }
 702: 
 703: /**
 704:   * Produces a new {@link Font} based on the current font, adjusted to a
 705:   * new style.
 706:   *
 707:   * @param style The style of the newly created font.
 708:   *
 709:   * @return A clone of the current font, with the specified style.
 710:   *
 711:   * @since 1.2
 712:   */
 713:   public Font deriveFont (int style)
 714: {
 715:     return peer.deriveFont (this, style);
 716: }
 717: 
 718: /**
 719:   * Produces a new {@link Font} based on the current font, adjusted to a
 720:   * new style and subjected to a new affine transformation.
 721:   *
 722:   * @param style The style of the newly created font.
 723:   * @param a The transformation to apply.
 724:   *
 725:   * @return A clone of the current font, with the specified style and
 726:   * transform.
 727:   *
 728:   * @throws IllegalArgumentException If transformation is
 729:   * <code>null</code>.
 730:   *
 731:   * @since 1.2
 732:   */
 733:   public Font deriveFont (int style, AffineTransform a)
 734: {
 735:     if (a == null)
 736:       throw new IllegalArgumentException ("Affine transformation is null");
 737: 
 738:     return peer.deriveFont (this, style, a);
 739: }
 740: 
 741: /**
 742:   * Produces a new {@link Font} based on the current font, subjected
 743:   * to a new affine transformation.
 744:   *
 745:   * @param a The transformation to apply.
 746:   *
 747:   * @return A clone of the current font, with the specified transform.
 748:   *
 749:   * @throws IllegalArgumentException If transformation is
 750:   * <code>null</code>.
 751:   *
 752:   * @since 1.2
 753:   */
 754:   public Font deriveFont (AffineTransform a)
 755: {
 756:     if (a == null)
 757:       throw new IllegalArgumentException ("Affine transformation is null");
 758: 
 759:     return peer.deriveFont (this, a);
 760: }
 761: 
 762: /**
 763:   * Produces a new {@link Font} based on the current font, adjusted to a
 764:   * new set of attributes.
 765:   *
 766:   * @param attributes Attributes of the newly created font.
 767:   *
 768:   * @return A clone of the current font, with the specified attributes.
 769:   *
 770:   * @since 1.2
 771:   */
 772:   public Font deriveFont (Map attributes)
 773: {
 774:     return peer.deriveFont (this, attributes);
 775: }
 776: 
 777: /**
 778:   * Returns a map of chracter attributes which this font currently has set.
 779:   *
 780:   * @return A map of chracter attributes which this font currently has set.
 781:   *
 782:   * @see #getAvailableAttributes()
 783:   * @see java.text.AttributedCharacterIterator.Attribute
 784:   * @see java.awt.font.TextAttribute
 785:   */
 786:   public Map getAttributes ()
 787: {
 788:     return peer.getAttributes (this);
 789: }
 790: 
 791: /**
 792:   * Returns an array of chracter attribute keys which this font understands. 
 793:   *
 794:   * @return An array of chracter attribute keys which this font understands.
 795:   *
 796:   * @see #getAttributes()
 797:   * @see java.text.AttributedCharacterIterator.Attribute
 798:   * @see java.awt.font.TextAttribute
 799:   */
 800:   public AttributedCharacterIterator.Attribute[] getAvailableAttributes()
 801: {
 802:     return peer.getAvailableAttributes (this);
 803: }
 804: 
 805: /**
 806:   * Returns a baseline code (one of {@link #ROMAN_BASELINE}, {@link
 807:   * #CENTER_BASELINE} or {@link #HANGING_BASELINE}) indicating which baseline
 808:   * this font will measure baseline offsets for, when presenting glyph
 809:   * metrics for a given character.
 810:   *
 811:   * Baseline offsets describe the position of a glyph relative to an
 812:   * invisible line drawn under, through the center of, or over a line of
 813:   * rendered text, respectively. Different scripts use different baseline
 814:   * modes, so clients should not assume all baseline offsets in a glyph
 815:   * vector are from a common baseline.
 816:   *
 817:   * @param c The character code to select a baseline mode for.
 818:   *
 819:   * @return The baseline mode which would be used in a glyph associated
 820:   * with the provided character.
 821:   *
 822:   * @since 1.2
 823:   *
 824:   * @see LineMetrics#getBaselineOffsets()
 825:   */
 826:   public byte getBaselineFor (char c)
 827: {
 828:     return peer.getBaselineFor (this, c);
 829: }
 830: 
 831: /**
 832:   * Returns the family name of this font. A family name describes a
 833:   * typographic style (such as Helvetica or Palatino). It is more specific
 834:   * than a logical font name (such as Sans Serif) but less specific than a
 835:   * font face name (such as Helvetica Bold).
 836:   *
 837:   * @param lc The locale in which to describe the name of the font family.
 838:   *
 839:   * @return A string containing the font family name, localized for the
 840:   * provided locale.
 841:   *
 842:   * @since 1.2
 843:   *
 844:   * @see #getName()
 845:   * @see #getFontName()
 846:   * @see GraphicsEnvironment#getAvailableFontFamilyNames()
 847:   * @see Locale
 848:   */
 849:   public String getFamily (Locale lc)
 850: {
 851:     return peer.getFamily (this, lc); 
 852: }
 853: 
 854: /**
 855:   * Returns a font appropriate for the given attribute set.
 856:   *
 857:   * @param attributes The attributes required for the new font.
 858:   *
 859:   * @return A new Font with the given attributes.
 860:   *
 861:   * @since 1.2
 862:   *
 863:   * @see java.awt.font.TextAttribute  
 864:   */
 865:   public static Font getFont (Map attributes)
 866: {
 867:     return getFontFromToolkit (null, attributes);
 868: }
 869: 
 870: /**
 871:   * Returns the font face name of the font.  A font face name describes a
 872:   * specific variant of a font family (such as Helvetica Bold). It is more
 873:   * specific than both a font family name (such as Helvetica) and a logical
 874:   * font name (such as Sans Serif).
 875:   *
 876:   * @return The font face name of the font.
 877:   *
 878:   * @since 1.2
 879:   *
 880:   * @see #getName()
 881:   * @see #getFamily()
 882:   */
 883:   public String getFontName ()
 884: {
 885:     return peer.getFontName (this);
 886: }
 887: 
 888: /**
 889:   * Returns the font face name of the font.  A font face name describes a
 890:   * specific variant of a font family (such as Helvetica Bold). It is more
 891:    * specific than both a font family name (such as Helvetica).
 892:   *
 893:   * @param lc The locale in which to describe the name of the font face.
 894:   *
 895:   * @return A string containing the font face name, localized for the
 896:   * provided locale.
 897:   *
 898:   * @since 1.2
 899:   *
 900:   * @see #getName()
 901:   * @see #getFamily()
 902:   */
 903:   public String getFontName (Locale lc)
 904: {
 905:     return peer.getFontName (this, lc);
 906: }
 907: 
 908: /**
 909:   * Returns the italic angle of this font, a measurement of its slant when
 910:   * style is {@link #ITALIC}. The precise meaning is the inverse slope of a
 911:   * caret line which "best measures" the font's italic posture.
 912:   *
 913:   * @return The italic angle.
 914:   *
 915:   * @see java.awt.font.TextAttribute#POSTURE
 916:   */
 917:   public float getItalicAngle ()
 918: {
 919:     return peer.getItalicAngle (this);
 920: }
 921: 
 922: /**
 923:   * Returns a {@link LineMetrics} object constructed with the specified
 924:   * text and {@link FontRenderContext}. 
 925:   *
 926:   * @param text The string to calculate metrics from.
 927:   * @param begin Index of first character in <code>text</code> to measure.
 928:   * @param limit Index of last character in <code>text</code> to measure.
 929:   * @param rc Context for calculating precise glyph placement and hints.
 930:   *
 931:   * @return A new {@link LineMetrics} object.
 932:   *
 933:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 934:   * invalid in <code>text</code>.
 935:   */
 936:   public LineMetrics getLineMetrics(String text, int begin, 
 937:                                     int limit, FontRenderContext rc)
 938: {
 939:     return peer.getLineMetrics (this, new StringCharacterIterator (text), 
 940:                                 begin, limit, rc);
 941: }
 942: 
 943: /**
 944:   * Returns a {@link LineMetrics} object constructed with the specified
 945:   * text and {@link FontRenderContext}. 
 946:   *
 947:   * @param chars The string to calculate metrics from.
 948:   * @param begin Index of first character in <code>text</code> to measure.
 949:   * @param limit Index of last character in <code>text</code> to measure.
 950:   * @param rc Context for calculating precise glyph placement and hints.
 951:   *
 952:   * @return A new {@link LineMetrics} object.
 953:   *
 954:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 955:   * invalid in <code>chars</code>.
 956:   */
 957:   public LineMetrics getLineMetrics(char[] chars, int begin, 
 958:                                     int limit, FontRenderContext rc)
 959: {
 960:     return peer.getLineMetrics (this, new StringCharacterIterator (new String(chars)), 
 961:                                 begin, limit, rc);
 962: }
 963: 
 964: /**
 965:   * Returns a {@link LineMetrics} object constructed with the specified
 966:   * text and {@link FontRenderContext}. 
 967:   *
 968:   * @param ci The string to calculate metrics from.
 969:   * @param begin Index of first character in <code>text</code> to measure.
 970:   * @param limit Index of last character in <code>text</code> to measure.
 971:   * @param rc Context for calculating precise glyph placement and hints.
 972:   *
 973:   * @return A new {@link LineMetrics} object.
 974:   *
 975:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 976:   * invalid in <code>ci</code>.
 977:   */
 978:   public LineMetrics getLineMetrics (CharacterIterator ci, int begin, 
 979:                                      int limit, FontRenderContext rc)
 980: {
 981:     return peer.getLineMetrics (this, ci, begin, limit, rc);
 982: }
 983: 
 984: /**
 985:   * Returns the maximal bounding box of all the bounding boxes in this
 986:   * font, when the font's bounding boxes are evaluated in a given {@link
 987:   * FontRenderContext}
 988:   *
 989:   * @param rc Context in which to evaluate bounding boxes.
 990:   *
 991:   * @return The maximal bounding box.
 992:   */
 993:   public Rectangle2D getMaxCharBounds (FontRenderContext rc)
 994: {
 995:     return peer.getMaxCharBounds (this, rc);
 996: }
 997: 
 998: /**
 999:   * Returns the glyph code this font uses to represent missing glyphs. This
1000:   * code will be present in glyph vectors when the font was unable to
1001:   * locate a glyph to represent a particular character code.
1002:   *
1003:   * @return The missing glyph code.
1004:   *
1005:   * @since 1.2
1006:   */
1007:   public int getMissingGlyphCode ()
1008: {
1009:     return peer.getMissingGlyphCode (this);
1010: }
1011: 
1012: /**
1013:   * Returns the overall number of glyphs in this font. This number is one
1014:   * more than the greatest glyph code used in any glyph vectors this font
1015:   * produces. In other words, glyph codes are taken from the range
1016:   * <code>[ 0, getNumGlyphs() - 1 ]</code>.
1017:   *
1018:   * @return The number of glyphs in this font.
1019:   * 
1020:   * @since 1.2
1021:   */
1022:   public int getNumGlyphs ()
1023: {
1024:     return peer.getMissingGlyphCode (this);
1025: }
1026: 
1027: /**
1028:   * Returns the PostScript Name of this font.   
1029:   *
1030:   * @return The PostScript Name of this font.
1031:   *
1032:   * @since 1.2
1033:   *
1034:   * @see #getName()
1035:   * @see #getFamily()
1036:   * @see #getFontName()
1037:   */
1038:   public String getPSName ()
1039: {
1040:     return peer.getPostScriptName (this);
1041: }
1042: 
1043: /**
1044:   * Returns the logical bounds of the specified string when rendered with this
1045:   * font in the specified {@link FontRenderContext}. This box will include the
1046:   * glyph origin, ascent, advance, height, and leading, but may not include all
1047:   * diacritics or accents. To get the complete visual bounding box of all the
1048:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of 
1049:   * {@link TextLayout}.
1050:   *
1051:   * @param str The string to measure.
1052:   * @param frc The context in which to make the precise glyph measurements.
1053:   * 
1054:   * @return A bounding box covering the logical bounds of the specified text.
1055:   *
1056:   * @see #createGlyphVector(FontRenderContext, String)
1057:   */
1058:   public Rectangle2D getStringBounds (String str, FontRenderContext frc)
1059: {
1060:     return getStringBounds (str, 0, str.length () - 1, frc);
1061: }
1062: 
1063: /**
1064:   * Returns the logical bounds of the specified string when rendered with this
1065:   * font in the specified {@link FontRenderContext}. This box will include the
1066:   * glyph origin, ascent, advance, height, and leading, but may not include all
1067:   * diacritics or accents. To get the complete visual bounding box of all the
1068:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1069:   * {@link TextLayout}.
1070:   *
1071:   * @param str The string to measure.
1072:   * @param begin Index of the first character in <code>str</code> to measure.
1073:   * @param limit Index of the last character in <code>str</code> to measure.
1074:   * @param frc The context in which to make the precise glyph measurements.
1075:   * 
1076:   * @return A bounding box covering the logical bounds of the specified text.
1077:   *
1078:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1079:   * invalid in <code>str</code>.
1080:   *
1081:   * @since 1.2
1082:   *
1083:   * @see #createGlyphVector(FontRenderContext, String)
1084:   */
1085:   public Rectangle2D getStringBounds (String str, int begin, 
1086:                                       int limit, FontRenderContext frc)
1087: {
1088:     return peer.getStringBounds (this, new StringCharacterIterator(str), begin, limit, frc);
1089: }
1090: 
1091: /**
1092:   * Returns the logical bounds of the specified string when rendered with this
1093:   * font in the specified {@link FontRenderContext}. This box will include the
1094:   * glyph origin, ascent, advance, height, and leading, but may not include all
1095:   * diacritics or accents. To get the complete visual bounding box of all the
1096:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1097:   * {@link TextLayout}.
1098:   *
1099:   * @param ci The text to measure.
1100:   * @param begin Index of the first character in <code>ci</code> to measure.
1101:   * @param limit Index of the last character in <code>ci</code> to measure.
1102:   * @param frc The context in which to make the precise glyph measurements.
1103:   * 
1104:   * @return A bounding box covering the logical bounds of the specified text.
1105:   *
1106:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1107:   * invalid in <code>ci</code>.
1108:   *
1109:   * @since 1.2
1110:   *
1111:   * @see #createGlyphVector(FontRenderContext, CharacterIterator)
1112:   */
1113:   public Rectangle2D getStringBounds (CharacterIterator ci, int begin, 
1114:                                       int limit, FontRenderContext frc)
1115: {
1116:     return peer.getStringBounds (this, ci, begin, limit, frc);
1117: }
1118: 
1119: /**
1120:   * Returns the logical bounds of the specified string when rendered with this
1121:   * font in the specified {@link FontRenderContext}. This box will include the
1122:   * glyph origin, ascent, advance, height, and leading, but may not include all
1123:   * diacritics or accents. To get the complete visual bounding box of all the
1124:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1125:   * {@link TextLayout}.
1126:   *
1127:   * @param chars The text to measure.
1128:   * @param begin Index of the first character in <code>ci</code> to measure.
1129:   * @param limit Index of the last character in <code>ci</code> to measure.
1130:   * @param frc The context in which to make the precise glyph measurements.
1131:   * 
1132:   * @return A bounding box covering the logical bounds of the specified text.
1133:   *
1134:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1135:   * invalid in <code>chars</code>.
1136:   *
1137:   * @since 1.2
1138:   *
1139:   * @see #createGlyphVector(FontRenderContext, char[])
1140:   */
1141:   public Rectangle2D getStringBounds (char[] chars, int begin, 
1142:                                       int limit, FontRenderContext frc)
1143: {
1144:     return peer.getStringBounds (this, new StringCharacterIterator (new String (chars)), 
1145:                                  begin, limit, frc);
1146: }
1147: 
1148: /**
1149:   * Returns a copy of the affine transformation this font is currently
1150:   * subject to, if any.
1151:   *
1152:   * @return The current transformation.
1153:  */
1154:   public AffineTransform getTransform ()
1155: {
1156:     return peer.getTransform (this);
1157: }
1158: 
1159: /**
1160:   * Indicates whether this font's line metrics are uniform. A font may be
1161:   * composed of several "subfonts", each covering a different code range,
1162:   * and each with their own line metrics. A font with no subfonts, or
1163:   * subfonts with identical line metrics, is said to have "uniform" line
1164:   * metrics.
1165:   *
1166:   * @return Whether this font has uniform line metrics.
1167:   *
1168:   * @see LineMetrics
1169:   * @see #getLineMetrics(String, FontRenderContext)
1170:   */
1171:   public boolean hasUniformLineMetrics ()
1172: {
1173:     return peer.hasUniformLineMetrics (this);
1174: }
1175: 
1176: /**
1177:   * Indicates whether this font is subject to a non-identity affine
1178:   * transformation.
1179:   *
1180:   * @return <code>true</code> iff the font has a non-identity affine
1181:   * transformation applied to it.
1182:   */
1183:   public boolean isTransformed ()
1184: {
1185:     return peer.isTransformed (this);
1186: }
1187: 
1188: /**
1189:   * Produces a glyph vector representing a full layout fo the specified
1190:   * text in this font. Full layouts may include complex shaping and
1191:   * reordering operations, for scripts such as Arabic or Hindi.
1192:   *
1193:   * Bidirectional (bidi) layout is not performed in this method; text
1194:   * should have its bidi direction specified with one of the flags {@link
1195:   * #LAYOUT_LEFT_TO_RIGHT} or {@link #LAYOUT_RIGHT_TO_LEFT}.
1196:   *
1197:   * Some types of layout (notably Arabic glyph shaping) may examine context
1198:   * characters beyond the bounds of the indicated range, in order to select
1199:   * an appropriate shape. The flags {@link #LAYOUT_NO_START_CONTEXT} and
1200:   * {@link #LAYOUT_NO_LIMIT_CONTEXT} can be provided to prevent these extra
1201:   * context areas from being examined, for instance if they contain invalid
1202:   * characters.
1203:   *
1204:   * @param frc Context in which to perform the layout.
1205:   * @param chars Text to perform layout on.
1206:   * @param start Index of first character to perform layout on.
1207:   * @param limit Index of last character to perform layout on.
1208:   * @param flags Combination of flags controlling layout.
1209:   *
1210:   * @return A new {@link GlyphVector} representing the specified text.
1211:   *
1212:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1213:   * invalid in <code>chars</code>. 
1214:   */
1215:   public GlyphVector layoutGlyphVector (FontRenderContext frc, 
1216:                                         char[] chars, int start, 
1217:                                         int limit, int flags)
1218: {
1219:     return peer.layoutGlyphVector (this, frc, chars, start, limit, flags);
1220: }
1221: 
1222: 
1223: /**
1224:   * Returns a native peer object for this font.
1225:   *
1226:   * @return A native peer object for this font.
1227:   *
1228:   * @deprecated
1229:   */
1230:   public FontPeer getPeer ()
1231: {
1232:     return peer;
1233: }
1234: 
1235: 
1236: /**
1237:   * Returns a hash value for this font.
1238:   * 
1239:   * @return A hash for this font.
1240:   */
1241:   public int hashCode()
1242: {
1243:     return this.toString().hashCode();
1244: }
1245: 
1246: 
1247: /**
1248:   * Tests whether or not the specified object is equal to this font.  This
1249:   * will be true if and only if:
1250:   * <P>
1251:   * <ul>
1252:   * <li>The object is not <code>null</code>.
1253:   * <li>The object is an instance of <code>Font</code>.
1254:   * <li>The object has the same names, style, size, and transform as this object.
1255:   * </ul>
1256:   *
1257:   * @return <code>true</code> if the specified object is equal to this
1258:   * object, <code>false</code> otherwise.
1259:   */
1260: public boolean
1261: equals(Object obj)
1262: {
1263:   if (obj == null)
1264:     return(false);
1265: 
1266:   if (!(obj instanceof Font))
1267:     return(false);
1268: 
1269:   Font f = (Font)obj;
1270: 
1271:   return (f.getName ().equals (this.getName ()) &&
1272:           f.getFamily ().equals (this.getFamily ()) &&
1273:           f.getFontName ().equals (this.getFontName ()) &&
1274:           f.getTransform ().equals (this.getTransform ()) &&
1275:           f.getSize() == this.getSize() &&
1276:           f.getStyle() == this.getStyle());
1277: } 
1278: 
1279: /*************************************************************************/
1280: 
1281: /**
1282:   * Returns a string representation of this font.
1283:   *
1284:   * @return A string representation of this font.
1285:   */
1286: public String
1287: toString()
1288: {
1289:   String styleString = "";
1290: 
1291:   switch (getStyle ())
1292:     {
1293:     case 0:
1294:       styleString = "plain";
1295:       break;
1296:     case 1:
1297:       styleString = "bold";
1298:       break;
1299:     case 2:
1300:       styleString = "italic";
1301:       break;
1302:     default:
1303:       styleString = "unknown";
1304:     }
1305: 
1306:   return getClass ().getName () 
1307:     + "[family=" + getFamily ()
1308:     + ",name=" + getFontName ()
1309:     + ",style=" + styleString
1310:     + ",size=" + getSize () + "]";
1311: }
1312: 
1313: 
1314:   /**
1315:    * Determines the line metrics for a run of text.
1316:    *
1317:    * @param str the text run to be measured.
1318:    *
1319:    * @param frc the font rendering parameters that are used for the
1320:    *        measurement. The exact placement and size of text slightly
1321:    *        depends on device-specific characteristics, for instance
1322:    *        the device resolution or anti-aliasing.  For this reason,
1323:    *        the returned measurement will only be accurate if the
1324:    *        passed <code>FontRenderContext</code> correctly reflects
1325:    *        the relevant parameters. Hence, <code>frc</code> should be
1326:    *        obtained from the same <code>Graphics2D</code> that will
1327:    *        be used for drawing, and any rendering hints should be set
1328:    *        to the desired values before obtaining <code>frc</code>.
1329:    *
1330:    * @see java.awt.Graphics2D#getFontRenderContext()
1331:    */
1332:   public LineMetrics getLineMetrics(String str, FontRenderContext frc)
1333:   {
1334:     return getLineMetrics (str, 0, str.length () - 1, frc);
1335:   }
1336: 
1337: } // class Font