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 build
 357:      a font with a "logical name" as well as attrs.  */
 358:   public Font (String name, Map attrs)
 359:   {
 360:     // If attrs is null, setting it to an empty HashMap will give this
 361:     // Font default attributes.
 362:     if (attrs == null)
 363:       attrs = new HashMap();
 364:     this.peer = getPeerFromToolkit (name, attrs);
 365:   }
 366: 
 367: /*************************************************************************/
 368: 
 369: /*
 370:  * Instance Methods
 371:  */
 372: 
 373: /**
 374:    * Returns the logical name of the font.  A logical name is the name the
 375:    * font was constructed with. It may be the name of a logical font (one
 376:    * of 6 required names in all java environments) or it may be a face
 377:    * name.
 378:   *
 379:   * @return The logical name of the font.
 380:   *
 381:   * @see #getFamily()
 382:   * @see #getFontName()
 383:   */
 384:   public String getName ()
 385: {
 386:     return peer.getName (this);
 387: }
 388: 
 389: /*************************************************************************/
 390: 
 391: /**
 392:   * Returns the style of the font.
 393:   * 
 394:   * @return The font style.
 395:   */
 396:   public int getSize ()
 397: {
 398:     return (int) peer.getSize (this);
 399: }
 400: 
 401:   public float getSize2D ()
 402: {
 403:     return peer.getSize (this);
 404: }
 405: 
 406: /*************************************************************************/
 407: 
 408: /**
 409:   * Tests whether or not this is a plain font.  This will be true if
 410:   * and only if neither the bold nor the italics style is set.
 411:   *
 412:   * @return <code>true</code> if this is a plain font, <code>false</code>
 413:   * otherwise.
 414:   */
 415:   public boolean isPlain ()
 416: {
 417:     return peer.isPlain (this); 
 418: }
 419: 
 420: /*************************************************************************/
 421: 
 422: /**
 423:   * Tests whether or not this font is bold.
 424:   *
 425:   * @return <code>true</code> if this font is bold, <code>false</code>
 426:   * otherwise.
 427:   */
 428:   public boolean isBold ()
 429: {
 430:     return peer.isBold (this);
 431: }
 432: 
 433: /*************************************************************************/
 434: 
 435: /**
 436:   * Tests whether or not this font is italic.
 437:   *
 438:   * @return <code>true</code> if this font is italic, <code>false</code>
 439:   * otherwise.
 440:   */
 441:   public boolean isItalic ()
 442: {
 443:     return peer.isItalic (this);
 444: }
 445: 
 446: /*************************************************************************/
 447: 
 448: /**
 449:    * Returns the family name of this font. A family name describes a design
 450:    * or "brand name" (such as Helvetica or Palatino). It is less specific
 451:    * than a font face name (such as Helvetica Bold).
 452:   *
 453:   * @return A string containing the font family name.
 454:   *
 455:   * @since 1.2
 456:   *
 457:   * @see #getName()
 458:   * @see #getFontName()
 459:   * @see GraphicsEnvironment#getAvailableFontFamilyNames()
 460:   */
 461:   public String getFamily ()
 462: {
 463:     return peer.getFamily (this);
 464: }
 465: 
 466: /**
 467:   * Returns integer code representing the sum of style flags of this font, a
 468:   * combination of either {@link #PLAIN}, {@link #BOLD}, or {@link #ITALIC}.
 469:   *
 470:   * @return code representing the style of this font.
 471:   *
 472:   * @see #isPlain()
 473:   * @see #isBold()
 474:   * @see #isItalic()
 475:   */
 476:   public int getStyle ()
 477: {
 478:     return peer.getStyle (this);
 479: }
 480: 
 481: /**
 482:   * Checks if specified character maps to a glyph in this font.
 483:   *
 484:   * @param c The character to check.
 485:   *
 486:   * @return Whether the character has a corresponding glyph in this font.
 487:   *
 488:   * @since 1.2
 489:   */
 490:   public boolean canDisplay (char c)
 491: {
 492:     return peer.canDisplay (this, c);    
 493: }
 494: 
 495: /**
 496:   * Checks how much of a given string can be mapped to glyphs in 
 497:   * this font.
 498:   *
 499:   * @param s The string to check.
 500:   *
 501:   * @return The index of the first character in <code>s</code> which cannot
 502:   * be converted to a glyph by this font, or <code>-1</code> if all
 503:   * characters can be mapped to glyphs.
 504:   *
 505:   * @since 1.2
 506:   */
 507:   public int canDisplayUpTo (String s)
 508: {
 509:     return peer.canDisplayUpTo (this, new StringCharacterIterator (s), 
 510:                                 0, s.length () - 1);
 511: }
 512: 
 513: /**
 514:   * Checks how much of a given sequence of text can be mapped to glyphs in
 515:   * this font.
 516:   *
 517:   * @param text Array containing the text to check.
 518:   * @param start Position of first character to check in <code>text</code>.
 519:   * @param limit Position of last character to check in <code>text</code>.
 520:   *
 521:   * @return The index of the first character in the indicated range which
 522:   * cannot be converted to a glyph by this font, or <code>-1</code> if all
 523:   * characters can be mapped to glyphs.
 524:   *
 525:   * @since 1.2
 526:   *
 527:   * @throws IndexOutOfBoundsException if the range [start, limit] is
 528:   * invalid in <code>text</code>.
 529:   */
 530:   public int canDisplayUpTo (char[] text, int start, int limit)
 531: {
 532:     return peer.canDisplayUpTo 
 533:       (this, new StringCharacterIterator (new String (text)), start, limit);
 534: }
 535: 
 536: /**
 537:   * Checks how much of a given sequence of text can be mapped to glyphs in
 538:   * this font.
 539:   *
 540:   * @param i Iterator over the text to check.
 541:   * @param start Position of first character to check in <code>i</code>.
 542:   * @param limit Position of last character to check in <code>i</code>.
 543:   *
 544:   * @return The index of the first character in the indicated range which
 545:   * cannot be converted to a glyph by this font, or <code>-1</code> if all
 546:   * characters can be mapped to glyphs.
 547:   *
 548:   * @since 1.2
 549:   *
 550:   * @throws IndexOutOfBoundsException if the range [start, limit] is
 551:   * invalid in <code>i</code>.
 552:   */
 553:   public int canDisplayUpTo (CharacterIterator i, int start, int limit)
 554: {
 555:     return peer.canDisplayUpTo (this, i, start, limit);    
 556: }
 557: 
 558: /**
 559:   * Creates a new font with point size 1 and {@link #PLAIN} style,
 560:   * reading font data from the provided input stream. The resulting font
 561:   * can have further fonts derived from it using its
 562:   * <code>deriveFont</code> method.
 563:   *
 564:   * @param fontFormat Integer code indicating the format the font data is
 565:   * in.Currently this can only be {@link #TRUETYPE_FONT}.
 566:   * @param is {@link InputStream} from which font data will be read. This
 567:   * stream is not closed after font data is extracted.
 568:   *
 569:   * @return A new {@link Font} of the format indicated.
 570:   *
 571:   * @throws IllegalArgumentException if <code>fontType</code> is not
 572:   * recognized.
 573:   * @throws FontFormatException if data in InputStream is not of format
 574:   * indicated.
 575:   * @throws IOException if insufficient data is present on InputStream.
 576:   *
 577:   * @since 1.3
 578:   */
 579:   public static Font createFont (int fontFormat, InputStream is) 
 580:   throws FontFormatException, IOException
 581: {
 582:     return tk().createFont (fontFormat, is);
 583: }
 584: 
 585: /**
 586:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 587:   * {@link GlyphVector} with a mapped glyph for each input character. This
 588:   * sort of mapping is often sufficient for some scripts such as Roman, but
 589:   * is inappropriate for scripts with special shaping or contextual layout
 590:   * requirements such as Arabic, Indic, Hebrew or Thai.
 591:   *
 592:   * @param ctx The rendering context used for precise glyph placement.
 593:   * @param str The string to convert to Glyphs.
 594:   *
 595:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 596:   * through the font's cmap table.
 597:   *
 598:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 599:   */
 600:   public GlyphVector createGlyphVector (FontRenderContext ctx, String str)
 601: {
 602:     return peer.createGlyphVector (this, ctx, new StringCharacterIterator (str));
 603: }
 604: 
 605: /**
 606:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 607:   * {@link GlyphVector} with a mapped glyph for each input character. This
 608:   * sort of mapping is often sufficient for some scripts such as Roman, but
 609:   * is inappropriate for scripts with special shaping or contextual layout
 610:   * requirements such as Arabic, Indic, Hebrew or Thai.
 611:   *
 612:   * @param ctx The rendering context used for precise glyph placement.
 613:   * @param i Iterator over the text to convert to glyphs.
 614:   *
 615:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 616:   * through the font's cmap table.
 617:   *
 618:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 619:   */
 620:   public GlyphVector createGlyphVector (FontRenderContext ctx, CharacterIterator i)
 621: {
 622:     return peer.createGlyphVector (this, ctx, i);
 623: }
 624: 
 625: /**
 626:   * Maps characters to glyphs in a one-to-one relationship, returning a new
 627:   * {@link GlyphVector} with a mapped glyph for each input character. This
 628:   * sort of mapping is often sufficient for some scripts such as Roman, but
 629:   * is inappropriate for scripts with special shaping or contextual layout
 630:   * requirements such as Arabic, Indic, Hebrew or Thai.
 631:   *
 632:   * @param ctx The rendering context used for precise glyph placement.
 633:   * @param chars Array of characters to convert to glyphs.
 634:   *
 635:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 636:   * through the font's cmap table.
 637:   *
 638:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 639:   */
 640:   public GlyphVector createGlyphVector (FontRenderContext ctx, char[] chars)
 641: {
 642:     return peer.createGlyphVector 
 643:       (this, ctx, new StringCharacterIterator (new String (chars)));
 644: }
 645: 
 646: /**
 647:   * Extracts a sequence of glyphs from a font, returning a new {@link
 648:   * GlyphVector} with a mapped glyph for each input glyph code. 
 649:   *
 650:   * @param ctx The rendering context used for precise glyph placement.
 651:   * @param glyphCodes Array of characters to convert to glyphs.
 652:   *
 653:   * @return A new {@link GlyphVector} containing glyphs mapped from str,
 654:   * through the font's cmap table.
 655:   *
 656:   * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
 657:   *
 658:   * @specnote This method is documented to perform character-to-glyph
 659:   * conversions, in the Sun documentation, but its second parameter name is
 660:   * "glyphCodes" and it is not clear to me why it would exist if its
 661:   * purpose was to transport character codes inside integers. I assume it
 662:   * is mis-documented in the Sun documentation.
 663:   */
 664: 
 665:   public GlyphVector createGlyphVector (FontRenderContext ctx, int[] glyphCodes)
 666: {
 667:     return peer.createGlyphVector (this, ctx, glyphCodes);
 668: }
 669: 
 670: /**
 671:   * Produces a new {@link Font} based on the current font, adjusted to a
 672:   * new size and style.
 673:   *
 674:   * @param style The style of the newly created font.
 675:   * @param size The size of the newly created font.
 676:   *
 677:   * @return A clone of the current font, with the specified size and style.
 678:   *
 679:   * @since 1.2
 680:   */
 681:   public Font deriveFont (int style, float size)
 682: {
 683:     return peer.deriveFont (this, style, size);
 684: }
 685: 
 686: /**
 687:   * Produces a new {@link Font} based on the current font, adjusted to a
 688:   * new size.
 689:   *
 690:   * @param size The size of the newly created font.
 691:   *
 692:   * @return A clone of the current font, with the specified size.
 693:   *
 694:   * @since 1.2
 695:   */
 696:   public Font deriveFont (float size)
 697: {
 698:     return peer.deriveFont (this, size);
 699: }
 700: 
 701: /**
 702:   * Produces a new {@link Font} based on the current font, adjusted to a
 703:   * new style.
 704:   *
 705:   * @param style The style of the newly created font.
 706:   *
 707:   * @return A clone of the current font, with the specified style.
 708:   *
 709:   * @since 1.2
 710:   */
 711:   public Font deriveFont (int style)
 712: {
 713:     return peer.deriveFont (this, style);
 714: }
 715: 
 716: /**
 717:   * Produces a new {@link Font} based on the current font, adjusted to a
 718:   * new style and subjected to a new affine transformation.
 719:   *
 720:   * @param style The style of the newly created font.
 721:   * @param a The transformation to apply.
 722:   *
 723:   * @return A clone of the current font, with the specified style and
 724:   * transform.
 725:   *
 726:   * @throws IllegalArgumentException If transformation is
 727:   * <code>null</code>.
 728:   *
 729:   * @since 1.2
 730:   */
 731:   public Font deriveFont (int style, AffineTransform a)
 732: {
 733:     if (a == null)
 734:       throw new IllegalArgumentException ("Affine transformation is null");
 735: 
 736:     return peer.deriveFont (this, style, a);
 737: }
 738: 
 739: /**
 740:   * Produces a new {@link Font} based on the current font, subjected
 741:   * to a new affine transformation.
 742:   *
 743:   * @param a The transformation to apply.
 744:   *
 745:   * @return A clone of the current font, with the specified transform.
 746:   *
 747:   * @throws IllegalArgumentException If transformation is
 748:   * <code>null</code>.
 749:   *
 750:   * @since 1.2
 751:   */
 752:   public Font deriveFont (AffineTransform a)
 753: {
 754:     if (a == null)
 755:       throw new IllegalArgumentException ("Affine transformation is null");
 756: 
 757:     return peer.deriveFont (this, a);
 758: }
 759: 
 760: /**
 761:   * Produces a new {@link Font} based on the current font, adjusted to a
 762:   * new set of attributes.
 763:   *
 764:   * @param attributes Attributes of the newly created font.
 765:   *
 766:   * @return A clone of the current font, with the specified attributes.
 767:   *
 768:   * @since 1.2
 769:   */
 770:   public Font deriveFont (Map attributes)
 771: {
 772:     return peer.deriveFont (this, attributes);
 773: }
 774: 
 775: /**
 776:   * Returns a map of chracter attributes which this font currently has set.
 777:   *
 778:   * @return A map of chracter attributes which this font currently has set.
 779:   *
 780:   * @see #getAvailableAttributes()
 781:   * @see java.text.AttributedCharacterIterator.Attribute
 782:   * @see java.awt.font.TextAttribute
 783:   */
 784:   public Map getAttributes ()
 785: {
 786:     return peer.getAttributes (this);
 787: }
 788: 
 789: /**
 790:   * Returns an array of chracter attribute keys which this font understands. 
 791:   *
 792:   * @return An array of chracter attribute keys which this font understands.
 793:   *
 794:   * @see #getAttributes()
 795:   * @see java.text.AttributedCharacterIterator.Attribute
 796:   * @see java.awt.font.TextAttribute
 797:   */
 798:   public AttributedCharacterIterator.Attribute[] getAvailableAttributes()
 799: {
 800:     return peer.getAvailableAttributes (this);
 801: }
 802: 
 803: /**
 804:   * Returns a baseline code (one of {@link #ROMAN_BASELINE}, {@link
 805:   * #CENTER_BASELINE} or {@link #HANGING_BASELINE}) indicating which baseline
 806:   * this font will measure baseline offsets for, when presenting glyph
 807:   * metrics for a given character.
 808:   *
 809:   * Baseline offsets describe the position of a glyph relative to an
 810:   * invisible line drawn under, through the center of, or over a line of
 811:   * rendered text, respectively. Different scripts use different baseline
 812:   * modes, so clients should not assume all baseline offsets in a glyph
 813:   * vector are from a common baseline.
 814:   *
 815:   * @param c The character code to select a baseline mode for.
 816:   *
 817:   * @return The baseline mode which would be used in a glyph associated
 818:   * with the provided character.
 819:   *
 820:   * @since 1.2
 821:   *
 822:   * @see LineMetrics#getBaselineOffsets()
 823:   */
 824:   public byte getBaselineFor (char c)
 825: {
 826:     return peer.getBaselineFor (this, c);
 827: }
 828: 
 829: /**
 830:   * Returns the family name of this font. A family name describes a
 831:   * typographic style (such as Helvetica or Palatino). It is more specific
 832:   * than a logical font name (such as Sans Serif) but less specific than a
 833:   * font face name (such as Helvetica Bold).
 834:   *
 835:   * @param lc The locale in which to describe the name of the font family.
 836:   *
 837:   * @return A string containing the font family name, localized for the
 838:   * provided locale.
 839:   *
 840:   * @since 1.2
 841:   *
 842:   * @see #getName()
 843:   * @see #getFontName()
 844:   * @see GraphicsEnvironment#getAvailableFontFamilyNames()
 845:   * @see Locale
 846:   */
 847:   public String getFamily (Locale lc)
 848: {
 849:     return peer.getFamily (this, lc); 
 850: }
 851: 
 852: /**
 853:   * Returns a font appropriate for the given attribute set.
 854:   *
 855:   * @param attributes The attributes required for the new font.
 856:   *
 857:   * @return A new Font with the given attributes.
 858:   *
 859:   * @since 1.2
 860:   *
 861:   * @see java.awt.font.TextAttribute  
 862:   */
 863:   public static Font getFont (Map attributes)
 864: {
 865:     return getFontFromToolkit (null, attributes);
 866: }
 867: 
 868: /**
 869:   * Returns the font face name of the font.  A font face name describes a
 870:   * specific variant of a font family (such as Helvetica Bold). It is more
 871:   * specific than both a font family name (such as Helvetica) and a logical
 872:   * font name (such as Sans Serif).
 873:   *
 874:   * @return The font face name of the font.
 875:   *
 876:   * @since 1.2
 877:   *
 878:   * @see #getName()
 879:   * @see #getFamily()
 880:   */
 881:   public String getFontName ()
 882: {
 883:     return peer.getFontName (this);
 884: }
 885: 
 886: /**
 887:   * Returns the font face name of the font.  A font face name describes a
 888:   * specific variant of a font family (such as Helvetica Bold). It is more
 889:    * specific than both a font family name (such as Helvetica).
 890:   *
 891:   * @param lc The locale in which to describe the name of the font face.
 892:   *
 893:   * @return A string containing the font face name, localized for the
 894:   * provided locale.
 895:   *
 896:   * @since 1.2
 897:   *
 898:   * @see #getName()
 899:   * @see #getFamily()
 900:   */
 901:   public String getFontName (Locale lc)
 902: {
 903:     return peer.getFontName (this, lc);
 904: }
 905: 
 906: /**
 907:   * Returns the italic angle of this font, a measurement of its slant when
 908:   * style is {@link #ITALIC}. The precise meaning is the inverse slope of a
 909:   * caret line which "best measures" the font's italic posture.
 910:   *
 911:   * @return The italic angle.
 912:   *
 913:   * @see java.awt.font.TextAttribute#POSTURE
 914:   */
 915:   public float getItalicAngle ()
 916: {
 917:     return peer.getItalicAngle (this);
 918: }
 919: 
 920: /**
 921:   * Returns a {@link LineMetrics} object constructed with the specified
 922:   * text and {@link FontRenderContext}. 
 923:   *
 924:   * @param text The string to calculate metrics from.
 925:   * @param begin Index of first character in <code>text</code> to measure.
 926:   * @param limit Index of last character in <code>text</code> to measure.
 927:   * @param rc Context for calculating precise glyph placement and hints.
 928:   *
 929:   * @return A new {@link LineMetrics} object.
 930:   *
 931:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 932:   * invalid in <code>text</code>.
 933:   */
 934:   public LineMetrics getLineMetrics(String text, int begin, 
 935:                                     int limit, FontRenderContext rc)
 936: {
 937:     return peer.getLineMetrics (this, new StringCharacterIterator (text), 
 938:                                 begin, limit, rc);
 939: }
 940: 
 941: /**
 942:   * Returns a {@link LineMetrics} object constructed with the specified
 943:   * text and {@link FontRenderContext}. 
 944:   *
 945:   * @param chars The string to calculate metrics from.
 946:   * @param begin Index of first character in <code>text</code> to measure.
 947:   * @param limit Index of last character in <code>text</code> to measure.
 948:   * @param rc Context for calculating precise glyph placement and hints.
 949:   *
 950:   * @return A new {@link LineMetrics} object.
 951:   *
 952:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 953:   * invalid in <code>chars</code>.
 954:   */
 955:   public LineMetrics getLineMetrics(char[] chars, int begin, 
 956:                                     int limit, FontRenderContext rc)
 957: {
 958:     return peer.getLineMetrics (this, new StringCharacterIterator (new String(chars)), 
 959:                                 begin, limit, rc);
 960: }
 961: 
 962: /**
 963:   * Returns a {@link LineMetrics} object constructed with the specified
 964:   * text and {@link FontRenderContext}. 
 965:   *
 966:   * @param ci The string to calculate metrics from.
 967:   * @param begin Index of first character in <code>text</code> to measure.
 968:   * @param limit Index of last character in <code>text</code> to measure.
 969:   * @param rc Context for calculating precise glyph placement and hints.
 970:   *
 971:   * @return A new {@link LineMetrics} object.
 972:   *
 973:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
 974:   * invalid in <code>ci</code>.
 975:   */
 976:   public LineMetrics getLineMetrics (CharacterIterator ci, int begin, 
 977:                                      int limit, FontRenderContext rc)
 978: {
 979:     return peer.getLineMetrics (this, ci, begin, limit, rc);
 980: }
 981: 
 982: /**
 983:   * Returns the maximal bounding box of all the bounding boxes in this
 984:   * font, when the font's bounding boxes are evaluated in a given {@link
 985:   * FontRenderContext}
 986:   *
 987:   * @param rc Context in which to evaluate bounding boxes.
 988:   *
 989:   * @return The maximal bounding box.
 990:   */
 991:   public Rectangle2D getMaxCharBounds (FontRenderContext rc)
 992: {
 993:     return peer.getMaxCharBounds (this, rc);
 994: }
 995: 
 996: /**
 997:   * Returns the glyph code this font uses to represent missing glyphs. This
 998:   * code will be present in glyph vectors when the font was unable to
 999:   * locate a glyph to represent a particular character code.
1000:   *
1001:   * @return The missing glyph code.
1002:   *
1003:   * @since 1.2
1004:   */
1005:   public int getMissingGlyphCode ()
1006: {
1007:     return peer.getMissingGlyphCode (this);
1008: }
1009: 
1010: /**
1011:   * Returns the overall number of glyphs in this font. This number is one
1012:   * more than the greatest glyph code used in any glyph vectors this font
1013:   * produces. In other words, glyph codes are taken from the range
1014:   * <code>[ 0, getNumGlyphs() - 1 ]</code>.
1015:   *
1016:   * @return The number of glyphs in this font.
1017:   * 
1018:   * @since 1.2
1019:   */
1020:   public int getNumGlyphs ()
1021: {
1022:     return peer.getMissingGlyphCode (this);
1023: }
1024: 
1025: /**
1026:   * Returns the PostScript Name of this font.   
1027:   *
1028:   * @return The PostScript Name of this font.
1029:   *
1030:   * @since 1.2
1031:   *
1032:   * @see #getName()
1033:   * @see #getFamily()
1034:   * @see #getFontName()
1035:   */
1036:   public String getPSName ()
1037: {
1038:     return peer.getPostScriptName (this);
1039: }
1040: 
1041: /**
1042:   * Returns the logical bounds of the specified string when rendered with this
1043:   * font in the specified {@link FontRenderContext}. This box will include the
1044:   * glyph origin, ascent, advance, height, and leading, but may not include all
1045:   * diacritics or accents. To get the complete visual bounding box of all the
1046:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of 
1047:   * {@link TextLayout}.
1048:   *
1049:   * @param str The string to measure.
1050:   * @param frc The context in which to make the precise glyph measurements.
1051:   * 
1052:   * @return A bounding box covering the logical bounds of the specified text.
1053:   *
1054:   * @see #createGlyphVector(FontRenderContext, String)
1055:   */
1056:   public Rectangle2D getStringBounds (String str, FontRenderContext frc)
1057: {
1058:     return getStringBounds (str, 0, str.length () - 1, frc);
1059: }
1060: 
1061: /**
1062:   * Returns the logical bounds of the specified string when rendered with this
1063:   * font in the specified {@link FontRenderContext}. This box will include the
1064:   * glyph origin, ascent, advance, height, and leading, but may not include all
1065:   * diacritics or accents. To get the complete visual bounding box of all the
1066:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1067:   * {@link TextLayout}.
1068:   *
1069:   * @param str The string to measure.
1070:   * @param begin Index of the first character in <code>str</code> to measure.
1071:   * @param limit Index of the last character in <code>str</code> to measure.
1072:   * @param frc The context in which to make the precise glyph measurements.
1073:   * 
1074:   * @return A bounding box covering the logical bounds of the specified text.
1075:   *
1076:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1077:   * invalid in <code>str</code>.
1078:   *
1079:   * @since 1.2
1080:   *
1081:   * @see #createGlyphVector(FontRenderContext, String)
1082:   */
1083:   public Rectangle2D getStringBounds (String str, int begin, 
1084:                                       int limit, FontRenderContext frc)
1085: {
1086:     return peer.getStringBounds (this, new StringCharacterIterator(str), begin, limit, frc);
1087: }
1088: 
1089: /**
1090:   * Returns the logical bounds of the specified string when rendered with this
1091:   * font in the specified {@link FontRenderContext}. This box will include the
1092:   * glyph origin, ascent, advance, height, and leading, but may not include all
1093:   * diacritics or accents. To get the complete visual bounding box of all the
1094:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1095:   * {@link TextLayout}.
1096:   *
1097:   * @param ci The text to measure.
1098:   * @param begin Index of the first character in <code>ci</code> to measure.
1099:   * @param limit Index of the last character in <code>ci</code> to measure.
1100:   * @param frc The context in which to make the precise glyph measurements.
1101:   * 
1102:   * @return A bounding box covering the logical bounds of the specified text.
1103:   *
1104:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1105:   * invalid in <code>ci</code>.
1106:   *
1107:   * @since 1.2
1108:   *
1109:   * @see #createGlyphVector(FontRenderContext, CharacterIterator)
1110:   */
1111:   public Rectangle2D getStringBounds (CharacterIterator ci, int begin, 
1112:                                       int limit, FontRenderContext frc)
1113: {
1114:     return peer.getStringBounds (this, ci, begin, limit, frc);
1115: }
1116: 
1117: /**
1118:   * Returns the logical bounds of the specified string when rendered with this
1119:   * font in the specified {@link FontRenderContext}. This box will include the
1120:   * glyph origin, ascent, advance, height, and leading, but may not include all
1121:   * diacritics or accents. To get the complete visual bounding box of all the
1122:   * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
1123:   * {@link TextLayout}.
1124:   *
1125:   * @param chars The text to measure.
1126:   * @param begin Index of the first character in <code>ci</code> to measure.
1127:   * @param limit Index of the last character in <code>ci</code> to measure.
1128:   * @param frc The context in which to make the precise glyph measurements.
1129:   * 
1130:   * @return A bounding box covering the logical bounds of the specified text.
1131:   *
1132:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1133:   * invalid in <code>chars</code>.
1134:   *
1135:   * @since 1.2
1136:   *
1137:   * @see #createGlyphVector(FontRenderContext, char[])
1138:   */
1139:   public Rectangle2D getStringBounds (char[] chars, int begin, 
1140:                                       int limit, FontRenderContext frc)
1141: {
1142:     return peer.getStringBounds (this, new StringCharacterIterator (new String (chars)), 
1143:                                  begin, limit, frc);
1144: }
1145: 
1146: /**
1147:   * Returns a copy of the affine transformation this font is currently
1148:   * subject to, if any.
1149:   *
1150:   * @return The current transformation.
1151:  */
1152:   public AffineTransform getTransform ()
1153: {
1154:     return peer.getTransform (this);
1155: }
1156: 
1157: /**
1158:   * Indicates whether this font's line metrics are uniform. A font may be
1159:   * composed of several "subfonts", each covering a different code range,
1160:   * and each with their own line metrics. A font with no subfonts, or
1161:   * subfonts with identical line metrics, is said to have "uniform" line
1162:   * metrics.
1163:   *
1164:   * @return Whether this font has uniform line metrics.
1165:   *
1166:   * @see LineMetrics
1167:   * @see #getLineMetrics(String, FontRenderContext)
1168:   */
1169:   public boolean hasUniformLineMetrics ()
1170: {
1171:     return peer.hasUniformLineMetrics (this);
1172: }
1173: 
1174: /**
1175:   * Indicates whether this font is subject to a non-identity affine
1176:   * transformation.
1177:   *
1178:   * @return <code>true</code> iff the font has a non-identity affine
1179:   * transformation applied to it.
1180:   */
1181:   public boolean isTransformed ()
1182: {
1183:     return peer.isTransformed (this);
1184: }
1185: 
1186: /**
1187:   * Produces a glyph vector representing a full layout fo the specified
1188:   * text in this font. Full layouts may include complex shaping and
1189:   * reordering operations, for scripts such as Arabic or Hindi.
1190:   *
1191:   * Bidirectional (bidi) layout is not performed in this method; text
1192:   * should have its bidi direction specified with one of the flags {@link
1193:   * #LAYOUT_LEFT_TO_RIGHT} or {@link #LAYOUT_RIGHT_TO_LEFT}.
1194:   *
1195:   * Some types of layout (notably Arabic glyph shaping) may examine context
1196:   * characters beyond the bounds of the indicated range, in order to select
1197:   * an appropriate shape. The flags {@link #LAYOUT_NO_START_CONTEXT} and
1198:   * {@link #LAYOUT_NO_LIMIT_CONTEXT} can be provided to prevent these extra
1199:   * context areas from being examined, for instance if they contain invalid
1200:   * characters.
1201:   *
1202:   * @param frc Context in which to perform the layout.
1203:   * @param chars Text to perform layout on.
1204:   * @param start Index of first character to perform layout on.
1205:   * @param limit Index of last character to perform layout on.
1206:   * @param flags Combination of flags controlling layout.
1207:   *
1208:   * @return A new {@link GlyphVector} representing the specified text.
1209:   *
1210:   * @throws IndexOutOfBoundsException if the range [begin, limit] is
1211:   * invalid in <code>chars</code>. 
1212:   */
1213:   public GlyphVector layoutGlyphVector (FontRenderContext frc, 
1214:                                         char[] chars, int start, 
1215:                                         int limit, int flags)
1216: {
1217:     return peer.layoutGlyphVector (this, frc, chars, start, limit, flags);
1218: }
1219: 
1220: 
1221: /**
1222:   * Returns a native peer object for this font.
1223:   *
1224:   * @return A native peer object for this font.
1225:   *
1226:   * @deprecated
1227:   */
1228:   public FontPeer getPeer ()
1229: {
1230:     return peer;
1231: }
1232: 
1233: 
1234: /**
1235:   * Returns a hash value for this font.
1236:   * 
1237:   * @return A hash for this font.
1238:   */
1239:   public int hashCode()
1240: {
1241:     return this.toString().hashCode();
1242: }
1243: 
1244: 
1245: /**
1246:   * Tests whether or not the specified object is equal to this font.  This
1247:   * will be true if and only if:
1248:   * <P>
1249:   * <ul>
1250:   * <li>The object is not <code>null</code>.
1251:   * <li>The object is an instance of <code>Font</code>.
1252:   * <li>The object has the same names, style, size, and transform as this object.
1253:   * </ul>
1254:   *
1255:   * @return <code>true</code> if the specified object is equal to this
1256:   * object, <code>false</code> otherwise.
1257:   */
1258: public boolean
1259: equals(Object obj)
1260: {
1261:   if (obj == null)
1262:     return(false);
1263: 
1264:   if (!(obj instanceof Font))
1265:     return(false);
1266: 
1267:   Font f = (Font)obj;
1268: 
1269:   return (f.getName ().equals (this.getName ()) &&
1270:           f.getFamily ().equals (this.getFamily ()) &&
1271:           f.getFontName ().equals (this.getFontName ()) &&
1272:           f.getTransform ().equals (this.getTransform ()) &&
1273:           f.getSize() == this.getSize() &&
1274:           f.getStyle() == this.getStyle());
1275: } 
1276: 
1277: /*************************************************************************/
1278: 
1279: /**
1280:   * Returns a string representation of this font.
1281:   *
1282:   * @return A string representation of this font.
1283:   */
1284: public String
1285: toString()
1286: {
1287:   String styleString = "";
1288: 
1289:   switch (getStyle ())
1290:     {
1291:     case 0:
1292:       styleString = "plain";
1293:       break;
1294:     case 1:
1295:       styleString = "bold";
1296:       break;
1297:     case 2:
1298:       styleString = "italic";
1299:       break;
1300:     default:
1301:       styleString = "unknown";
1302:     }
1303: 
1304:   return getClass ().getName () 
1305:     + "[family=" + getFamily ()
1306:     + ",name=" + getFontName ()
1307:     + ",style=" + styleString
1308:     + ",size=" + getSize () + "]";
1309: }
1310: 
1311: 
1312:   /**
1313:    * Determines the line metrics for a run of text.
1314:    *
1315:    * @param str the text run to be measured.
1316:    *
1317:    * @param frc the font rendering parameters that are used for the
1318:    *        measurement. The exact placement and size of text slightly
1319:    *        depends on device-specific characteristics, for instance
1320:    *        the device resolution or anti-aliasing.  For this reason,
1321:    *        the returned measurement will only be accurate if the
1322:    *        passed <code>FontRenderContext</code> correctly reflects
1323:    *        the relevant parameters. Hence, <code>frc</code> should be
1324:    *        obtained from the same <code>Graphics2D</code> that will
1325:    *        be used for drawing, and any rendering hints should be set
1326:    *        to the desired values before obtaining <code>frc</code>.
1327:    *
1328:    * @see java.awt.Graphics2D#getFontRenderContext()
1329:    */
1330:   public LineMetrics getLineMetrics(String str, FontRenderContext frc)
1331:   {
1332:     return getLineMetrics (str, 0, str.length () - 1, frc);
1333:   }
1334: 
1335: } // class Font