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