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