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