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