< prev index next >

src/java.desktop/share/classes/java/awt/Font.java

Print this page




  48 import sun.awt.ComponentFactory;
  49 import sun.font.StandardGlyphVector;
  50 
  51 import sun.font.AttributeMap;
  52 import sun.font.AttributeValues;
  53 import sun.font.CompositeFont;
  54 import sun.font.CreatedFontTracker;
  55 import sun.font.Font2D;
  56 import sun.font.Font2DHandle;
  57 import sun.font.FontAccess;
  58 import sun.font.FontManager;
  59 import sun.font.FontManagerFactory;
  60 import sun.font.FontUtilities;
  61 import sun.font.GlyphLayout;
  62 import sun.font.FontLineMetrics;
  63 import sun.font.CoreMetrics;
  64 
  65 import static sun.font.EAttribute.*;
  66 
  67 /**
  68  * The <code>Font</code> class represents fonts, which are used to
  69  * render text in a visible way.
  70  * A font provides the information needed to map sequences of
  71  * <em>characters</em> to sequences of <em>glyphs</em>
  72  * and to render sequences of glyphs on <code>Graphics</code> and
  73  * <code>Component</code> objects.
  74  *
  75  * <h3>Characters and Glyphs</h3>
  76  *
  77  * A <em>character</em> is a symbol that represents an item such as a letter,
  78  * a digit, or punctuation in an abstract way. For example, <code>'g'</code>,
  79  * LATIN SMALL LETTER G, is a character.
  80  * <p>
  81  * A <em>glyph</em> is a shape used to render a character or a sequence of
  82  * characters. In simple writing systems, such as Latin, typically one glyph
  83  * represents one character. In general, however, characters and glyphs do not
  84  * have one-to-one correspondence. For example, the character '&aacute;'
  85  * LATIN SMALL LETTER A WITH ACUTE, can be represented by
  86  * two glyphs: one for 'a' and one for '&acute;'. On the other hand, the
  87  * two-character string "fi" can be represented by a single glyph, an
  88  * "fi" ligature. In complex writing systems, such as Arabic or the South
  89  * and South-East Asian writing systems, the relationship between characters
  90  * and glyphs can be more complicated and involve context-dependent selection
  91  * of glyphs as well as glyph reordering.
  92  *
  93  * A font encapsulates the collection of glyphs needed to render a selected set
  94  * of characters as well as the tables needed to map sequences of characters to
  95  * corresponding sequences of glyphs.
  96  *
  97  * <h3>Physical and Logical Fonts</h3>
  98  *


 118  * Serif, SansSerif, Monospaced, Dialog, and DialogInput.
 119  * These logical fonts are not actual font libraries. Instead, the logical
 120  * font names are mapped to physical fonts by the Java runtime environment.
 121  * The mapping is implementation and usually locale dependent, so the look
 122  * and the metrics provided by them vary.
 123  * Typically, each logical font name maps to several physical fonts in order to
 124  * cover a large range of characters.
 125  * <p>
 126  * Peered AWT components, such as {@link Label Label} and
 127  * {@link TextField TextField}, can only use logical fonts.
 128  * <p>
 129  * For a discussion of the relative advantages and disadvantages of using
 130  * physical or logical fonts, see the
 131  * <a href="https://docs.oracle.com/javase/tutorial/2d/text/fonts.html#advantages-and-disadvantages">
 132  *    Physical and Logical Fonts</a>
 133  * in <a href="https://docs.oracle.com/javase/tutorial/index.html">The Java Tutorials</a>
 134  * document.
 135  *
 136  * <h3>Font Faces and Names</h3>
 137  *
 138  * A <code>Font</code>
 139  * can have many faces, such as heavy, medium, oblique, gothic and
 140  * regular. All of these faces have similar typographic design.
 141  * <p>
 142  * There are three different names that you can get from a
 143  * <code>Font</code> object.  The <em>logical font name</em> is simply the
 144  * name that was used to construct the font.
 145  * The <em>font face name</em>, or just <em>font name</em> for
 146  * short, is the name of a particular font face, like Helvetica Bold. The
 147  * <em>family name</em> is the name of the font family that determines the
 148  * typographic design across several faces, like Helvetica.
 149  * <p>
 150  * The <code>Font</code> class represents an instance of a font face from
 151  * a collection of  font faces that are present in the system resources
 152  * of the host system.  As examples, Arial Bold and Courier Bold Italic
 153  * are font faces.  There can be several <code>Font</code> objects
 154  * associated with a font face, each differing in size, style, transform
 155  * and font features.
 156  * <p>
 157  * The {@link GraphicsEnvironment#getAllFonts() getAllFonts} method
 158  * of the <code>GraphicsEnvironment</code> class returns an
 159  * array of all font faces available in the system. These font faces are
 160  * returned as <code>Font</code> objects with a size of 1, identity
 161  * transform and default font features. These
 162  * base fonts can then be used to derive new <code>Font</code> objects
 163  * with varying sizes, styles, transforms and font features via the
 164  * <code>deriveFont</code> methods in this class.
 165  *
 166  * <h3>Font and TextAttribute</h3>
 167  *
 168  * <p><code>Font</code> supports most
 169  * <code>TextAttribute</code>s.  This makes some operations, such as
 170  * rendering underlined text, convenient since it is not
 171  * necessary to explicitly construct a <code>TextLayout</code> object.
 172  * Attributes can be set on a Font by constructing or deriving it
 173  * using a <code>Map</code> of <code>TextAttribute</code> values.
 174  *
 175  * <p>The values of some <code>TextAttributes</code> are not
 176  * serializable, and therefore attempting to serialize an instance of
 177  * <code>Font</code> that has such values will not serialize them.
 178  * This means a Font deserialized from such a stream will not compare
 179  * equal to the original Font that contained the non-serializable
 180  * attributes.  This should very rarely pose a problem
 181  * since these attributes are typically used only in special
 182  * circumstances and are unlikely to be serialized.
 183  *
 184  * <ul>
 185  * <li><code>FOREGROUND</code> and <code>BACKGROUND</code> use
 186  * <code>Paint</code> values. The subclass <code>Color</code> is
 187  * serializable, while <code>GradientPaint</code> and
 188  * <code>TexturePaint</code> are not.</li>
 189  * <li><code>CHAR_REPLACEMENT</code> uses
 190  * <code>GraphicAttribute</code> values.  The subclasses
 191  * <code>ShapeGraphicAttribute</code> and
 192  * <code>ImageGraphicAttribute</code> are not serializable.</li>
 193  * <li><code>INPUT_METHOD_HIGHLIGHT</code> uses
 194  * <code>InputMethodHighlight</code> values, which are
 195  * not serializable.  See {@link java.awt.im.InputMethodHighlight}.</li>
 196  * </ul>
 197  *
 198  * <p>Clients who create custom subclasses of <code>Paint</code> and
 199  * <code>GraphicAttribute</code> can make them serializable and
 200  * avoid this problem.  Clients who use input method highlights can
 201  * convert these to the platform-specific attributes for that
 202  * highlight on the current platform and set them on the Font as
 203  * a workaround.
 204  *
 205  * <p>The <code>Map</code>-based constructor and
 206  * <code>deriveFont</code> APIs ignore the FONT attribute, and it is
 207  * not retained by the Font; the static {@link #getFont} method should
 208  * be used if the FONT attribute might be present.  See {@link
 209  * java.awt.font.TextAttribute#FONT} for more information.</p>
 210  *
 211  * <p>Several attributes will cause additional rendering overhead
 212  * and potentially invoke layout.  If a <code>Font</code> has such
 213  * attributes, the <code>{@link #hasLayoutAttributes()}</code> method
 214  * will return true.</p>
 215  *
 216  * <p>Note: Font rotations can cause text baselines to be rotated.  In
 217  * order to account for this (rare) possibility, font APIs are
 218  * specified to return metrics and take parameters 'in
 219  * baseline-relative coordinates'.  This maps the 'x' coordinate to
 220  * the advance along the baseline, (positive x is forward along the
 221  * baseline), and the 'y' coordinate to a distance along the
 222  * perpendicular to the baseline at 'x' (positive y is 90 degrees
 223  * clockwise from the baseline vector).  APIs for which this is
 224  * especially important are called out as having 'baseline-relative
 225  * coordinates.'
 226  */
 227 public class Font implements java.io.Serializable
 228 {
 229     private static class FontAccessImpl extends FontAccess {
 230         public Font2D getFont2D(Font font) {
 231             return font.getFont2D();
 232         }


 353      * Used to specify a TrueType font resource to the
 354      * {@link #createFont} method.
 355      * The TrueType format was extended to become the OpenType
 356      * format, which adds support for fonts with Postscript outlines,
 357      * this tag therefore references these fonts, as well as those
 358      * with TrueType outlines.
 359      * @since 1.3
 360      */
 361 
 362     public static final int TRUETYPE_FONT = 0;
 363 
 364     /**
 365      * Identify a font resource of type TYPE1.
 366      * Used to specify a Type1 font resource to the
 367      * {@link #createFont} method.
 368      * @since 1.5
 369      */
 370     public static final int TYPE1_FONT = 1;
 371 
 372     /**
 373      * The logical name of this <code>Font</code>, as passed to the
 374      * constructor.
 375      * @since 1.0
 376      *
 377      * @serial
 378      * @see #getName
 379      */
 380     protected String name;
 381 
 382     /**
 383      * The style of this <code>Font</code>, as passed to the constructor.
 384      * This style can be PLAIN, BOLD, ITALIC, or BOLD+ITALIC.
 385      * @since 1.0
 386      *
 387      * @serial
 388      * @see #getStyle()
 389      */
 390     protected int style;
 391 
 392     /**
 393      * The point size of this <code>Font</code>, rounded to integer.
 394      * @since 1.0
 395      *
 396      * @serial
 397      * @see #getSize()
 398      */
 399     protected int size;
 400 
 401     /**
 402      * The point size of this <code>Font</code> in <code>float</code>.
 403      *
 404      * @serial
 405      * @see #getSize()
 406      * @see #getSize2D()
 407      */
 408     protected float pointSize;
 409 
 410     /**
 411      * The platform specific font information.
 412      */
 413     private transient FontPeer peer;
 414     private transient long pData;       // native JDK1.1 font pointer
 415     private transient Font2DHandle font2DHandle;
 416 
 417     private transient AttributeValues values;
 418     private transient boolean hasLayoutAttributes;
 419 
 420     /*
 421      * If the origin of a Font is a created font then this attribute
 422      * must be set on all derived fonts too.


 491         FontManager fm = FontManagerFactory.getInstance();
 492         if (fm.usingPerAppContextComposites() &&
 493             font2DHandle != null &&
 494             font2DHandle.font2D instanceof CompositeFont &&
 495             ((CompositeFont)(font2DHandle.font2D)).isStdComposite()) {
 496             return fm.findFont2D(name, style,
 497                                           FontManager.LOGICAL_FALLBACK);
 498         } else if (font2DHandle == null) {
 499             font2DHandle =
 500                 fm.findFont2D(name, style,
 501                               FontManager.LOGICAL_FALLBACK).handle;
 502         }
 503         /* Do not cache the de-referenced font2D. It must be explicitly
 504          * de-referenced to pick up a valid font in the event that the
 505          * original one is marked invalid
 506          */
 507         return font2DHandle.font2D;
 508     }
 509 
 510     /**
 511      * Creates a new <code>Font</code> from the specified name, style and
 512      * point size.
 513      * <p>
 514      * The font name can be a font face name or a font family name.
 515      * It is used together with the style to find an appropriate font face.
 516      * When a font family name is specified, the style argument is used to
 517      * select the most appropriate face from the family. When a font face
 518      * name is specified, the face's style and the style argument are
 519      * merged to locate the best matching font from the same family.
 520      * For example if face name "Arial Bold" is specified with style
 521      * <code>Font.ITALIC</code>, the font system looks for a face in the
 522      * "Arial" family that is bold and italic, and may associate the font
 523      * instance with the physical font face "Arial Bold Italic".
 524      * The style argument is merged with the specified face's style, not
 525      * added or subtracted.
 526      * This means, specifying a bold face and a bold style does not
 527      * double-embolden the font, and specifying a bold face and a plain
 528      * style does not lighten the font.
 529      * <p>
 530      * If no face for the requested style can be found, the font system
 531      * may apply algorithmic styling to achieve the desired style.
 532      * For example, if <code>ITALIC</code> is requested, but no italic
 533      * face is available, glyphs from the plain face may be algorithmically
 534      * obliqued (slanted).
 535      * <p>
 536      * Font name lookup is case insensitive, using the case folding
 537      * rules of the US locale.
 538      * <p>
 539      * If the <code>name</code> parameter represents something other than a
 540      * logical font, i.e. is interpreted as a physical font face or family, and
 541      * this cannot be mapped by the implementation to a physical font or a
 542      * compatible alternative, then the font system will map the Font
 543      * instance to "Dialog", such that for example, the family as reported
 544      * by {@link #getFamily() getFamily} will be "Dialog".
 545      *
 546      * @param name the font name.  This can be a font face name or a font
 547      * family name, and may represent either a logical font or a physical
 548      * font found in this {@code GraphicsEnvironment}.
 549      * The family names for logical fonts are: Dialog, DialogInput,
 550      * Monospaced, Serif, or SansSerif. Pre-defined String constants exist
 551      * for all of these names, for example, {@code DIALOG}. If {@code name} is
 552      * {@code null}, the <em>logical font name</em> of the new
 553      * {@code Font} as returned by {@code getName()} is set to
 554      * the name "Default".
 555      * @param style the style constant for the {@code Font}
 556      * The style argument is an integer bitmask that may
 557      * be {@code PLAIN}, or a bitwise union of {@code BOLD} and/or
 558      * {@code ITALIC} (for example, {@code ITALIC} or {@code BOLD|ITALIC}).
 559      * If the style argument does not conform to one of the expected


 660             } else {
 661                 if (values.getWeight() >= 2f)   newStyle  = BOLD;
 662                 if (values.getPosture() >= .2f) newStyle |= ITALIC;
 663                 if (oldStyle == newStyle)       newStyle  = -1;
 664             }
 665             if (handle.font2D instanceof CompositeFont) {
 666                 if (newStyle != -1 || newName != null) {
 667                     FontManager fm = FontManagerFactory.getInstance();
 668                     this.font2DHandle =
 669                         fm.getNewComposite(newName, newStyle, handle);
 670                 }
 671             } else if (newName != null) {
 672                 this.createdFont = false;
 673                 this.font2DHandle = null;
 674             }
 675         }
 676         initFromValues(values);
 677     }
 678 
 679     /**
 680      * Creates a new <code>Font</code> with the specified attributes.
 681      * Only keys defined in {@link java.awt.font.TextAttribute TextAttribute}
 682      * are recognized.  In addition the FONT attribute is
 683      *  not recognized by this constructor
 684      * (see {@link #getAvailableAttributes}). Only attributes that have
 685      * values of valid types will affect the new <code>Font</code>.
 686      * <p>
 687      * If <code>attributes</code> is <code>null</code>, a new
 688      * <code>Font</code> is initialized with default values.
 689      * @see java.awt.font.TextAttribute
 690      * @param attributes the attributes to assign to the new
 691      *          <code>Font</code>, or <code>null</code>
 692      */
 693     public Font(Map<? extends Attribute, ?> attributes) {
 694         initFromValues(AttributeValues.fromMap(attributes, RECOGNIZED_MASK));
 695     }
 696 
 697     /**
 698      * Creates a new <code>Font</code> from the specified <code>font</code>.
 699      * This constructor is intended for use by subclasses.
 700      * @param font from which to create this <code>Font</code>.
 701      * @throws NullPointerException if <code>font</code> is null
 702      * @since 1.6
 703      */
 704     protected Font(Font font) {
 705         if (font.values != null) {
 706             initFromValues(font.getAttributeValues().clone());
 707         } else {
 708             this.name = font.name;
 709             this.style = font.style;
 710             this.size = font.size;
 711             this.pointSize = font.pointSize;
 712         }
 713         this.font2DHandle = font.font2DHandle;
 714         this.createdFont = font.createdFont;
 715     }
 716 
 717     /**
 718      * Font recognizes all attributes except FONT.
 719      */
 720     private static final int RECOGNIZED_MASK = AttributeValues.MASK_ALL
 721         & ~AttributeValues.getMask(EFONT);


 748             AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH);
 749 
 750     /**
 751      * Initialize the standard Font fields from the values object.
 752      */
 753     private void initFromValues(AttributeValues values) {
 754         this.values = values;
 755         values.defineAll(PRIMARY_MASK); // for 1.5 streaming compatibility
 756 
 757         this.name = values.getFamily();
 758         this.pointSize = values.getSize();
 759         this.size = (int)(values.getSize() + 0.5);
 760         if (values.getWeight() >= 2f) this.style |= BOLD; // not == 2f
 761         if (values.getPosture() >= .2f) this.style |= ITALIC; // not  == .2f
 762 
 763         this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
 764         this.hasLayoutAttributes =  values.anyNonDefault(LAYOUT_MASK);
 765     }
 766 
 767     /**
 768      * Returns a <code>Font</code> appropriate to the attributes.
 769      * If <code>attributes</code>contains a <code>FONT</code> attribute
 770      * with a valid <code>Font</code> as its value, it will be
 771      * merged with any remaining attributes.  See
 772      * {@link java.awt.font.TextAttribute#FONT} for more
 773      * information.
 774      *
 775      * @param attributes the attributes to assign to the new
 776      *          <code>Font</code>
 777      * @return a new <code>Font</code> created with the specified
 778      *          attributes
 779      * @throws NullPointerException if <code>attributes</code> is null.
 780      * @since 1.2
 781      * @see java.awt.font.TextAttribute
 782      */
 783     public static Font getFont(Map<? extends Attribute, ?> attributes) {
 784         // optimize for two cases:
 785         // 1) FONT attribute, and nothing else
 786         // 2) attributes, but no FONT
 787 
 788         // avoid turning the attributemap into a regular map for no reason
 789         if (attributes instanceof AttributeMap &&
 790             ((AttributeMap)attributes).getValues() != null) {
 791             AttributeValues values = ((AttributeMap)attributes).getValues();
 792             if (values.isNonDefault(EFONT)) {
 793                 Font font = values.getFont();
 794                 if (!values.anyDefined(SECONDARY_MASK)) {
 795                     return font;
 796                 }
 797                 // merge
 798                 values = font.getAttributeValues().clone();
 799                 values.merge(attributes, SECONDARY_MASK);


 825      */
 826     private static boolean hasTempPermission() {
 827 
 828         if (System.getSecurityManager() == null) {
 829             return true;
 830         }
 831         File f = null;
 832         boolean hasPerm = false;
 833         try {
 834             f = Files.createTempFile("+~JT", ".tmp").toFile();
 835             f.delete();
 836             f = null;
 837             hasPerm = true;
 838         } catch (Throwable t) {
 839             /* inc. any kind of SecurityException */
 840         }
 841         return hasPerm;
 842     }
 843 
 844     /**
 845      * Returns a new <code>Font</code> using the specified font type
 846      * and input data.  The new <code>Font</code> is
 847      * created with a point size of 1 and style {@link #PLAIN PLAIN}.
 848      * This base font can then be used with the <code>deriveFont</code>
 849      * methods in this class to derive new <code>Font</code> objects with
 850      * varying sizes, styles, transforms and font features.  This
 851      * method does not close the {@link InputStream}.
 852      * <p>
 853      * To make the <code>Font</code> available to Font constructors the
 854      * returned <code>Font</code> must be registered in the
 855      * <code>GraphicsEnvironment</code> by calling
 856      * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
 857      * @param fontFormat the type of the <code>Font</code>, which is
 858      * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is specified.
 859      * or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is specified.
 860      * @param fontStream an <code>InputStream</code> object representing the
 861      * input data for the font.
 862      * @return a new <code>Font</code> created with the specified font type.
 863      * @throws IllegalArgumentException if <code>fontFormat</code> is not
 864      *     <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>.
 865      * @throws FontFormatException if the <code>fontStream</code> data does
 866      *     not contain the required font tables for the specified format.
 867      * @throws IOException if the <code>fontStream</code>
 868      *     cannot be completely read.
 869      * @see GraphicsEnvironment#registerFont(Font)
 870      * @since 1.3
 871      */
 872     public static Font createFont(int fontFormat, InputStream fontStream)
 873         throws java.awt.FontFormatException, java.io.IOException {
 874 
 875         if (hasTempPermission()) {
 876             return createFont0(fontFormat, fontStream, null);
 877         }
 878 
 879         // Otherwise, be extra conscious of pending temp file creation and
 880         // resourcefully handle the temp file resources, among other things.
 881         CreatedFontTracker tracker = CreatedFontTracker.getTracker();
 882         boolean acquired = false;
 883         try {
 884             acquired = tracker.acquirePermit();
 885             if (!acquired) {
 886                 throw new IOException("Timed out waiting for resources.");
 887             }


 984                         }
 985                     );
 986                 }
 987             }
 988         } catch (Throwable t) {
 989             if (t instanceof FontFormatException) {
 990                 throw (FontFormatException)t;
 991             }
 992             if (t instanceof IOException) {
 993                 throw (IOException)t;
 994             }
 995             Throwable cause = t.getCause();
 996             if (cause instanceof FontFormatException) {
 997                 throw (FontFormatException)cause;
 998             }
 999             throw new IOException("Problem reading font data.");
1000         }
1001     }
1002 
1003     /**
1004      * Returns a new <code>Font</code> using the specified font type
1005      * and the specified font file.  The new <code>Font</code> is
1006      * created with a point size of 1 and style {@link #PLAIN PLAIN}.
1007      * This base font can then be used with the <code>deriveFont</code>
1008      * methods in this class to derive new <code>Font</code> objects with
1009      * varying sizes, styles, transforms and font features.
1010      * @param fontFormat the type of the <code>Font</code>, which is
1011      * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is
1012      * specified or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is
1013      * specified.
1014      * So long as the returned font, or its derived fonts are referenced
1015      * the implementation may continue to access <code>fontFile</code>
1016      * to retrieve font data. Thus the results are undefined if the file
1017      * is changed, or becomes inaccessible.
1018      * <p>
1019      * To make the <code>Font</code> available to Font constructors the
1020      * returned <code>Font</code> must be registered in the
1021      * <code>GraphicsEnvironment</code> by calling
1022      * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
1023      * @param fontFile a <code>File</code> object representing the
1024      * input data for the font.
1025      * @return a new <code>Font</code> created with the specified font type.
1026      * @throws IllegalArgumentException if <code>fontFormat</code> is not
1027      *     <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>.
1028      * @throws NullPointerException if <code>fontFile</code> is null.
1029      * @throws IOException if the <code>fontFile</code> cannot be read.
1030      * @throws FontFormatException if <code>fontFile</code> does
1031      *     not contain the required font tables for the specified format.
1032      * @throws SecurityException if the executing code does not have
1033      * permission to read from the file.
1034      * @see GraphicsEnvironment#registerFont(Font)
1035      * @since 1.5
1036      */
1037     public static Font createFont(int fontFormat, File fontFile)
1038         throws java.awt.FontFormatException, java.io.IOException {
1039 
1040         fontFile = new File(fontFile.getPath());
1041 
1042         if (fontFormat != Font.TRUETYPE_FONT &&
1043             fontFormat != Font.TYPE1_FONT) {
1044             throw new IllegalArgumentException ("font format not recognized");
1045         }
1046         SecurityManager sm = System.getSecurityManager();
1047         if (sm != null) {
1048             FilePermission filePermission =
1049                 new FilePermission(fontFile.getPath(), "read");
1050             sm.checkPermission(filePermission);
1051         }
1052         if (!fontFile.canRead()) {
1053             throw new IOException("Can't read " + fontFile);
1054         }
1055         return new Font(fontFile, fontFormat, false, null);
1056     }
1057 
1058     /**
1059      * Returns a copy of the transform associated with this
1060      * <code>Font</code>.  This transform is not necessarily the one
1061      * used to construct the font.  If the font has algorithmic
1062      * superscripting or width adjustment, this will be incorporated
1063      * into the returned <code>AffineTransform</code>.
1064      * <p>
1065      * Typically, fonts will not be transformed.  Clients generally
1066      * should call {@link #isTransformed} first, and only call this
1067      * method if <code>isTransformed</code> returns true.
1068      *
1069      * @return an {@link AffineTransform} object representing the
1070      *          transform attribute of this <code>Font</code> object.
1071      */
1072     public AffineTransform getTransform() {
1073         /* The most common case is the identity transform.  Most callers
1074          * should call isTransformed() first, to decide if they need to
1075          * get the transform, but some may not.  Here we check to see
1076          * if we have a nonidentity transform, and only do the work to
1077          * fetch and/or compute it if so, otherwise we return a new
1078          * identity transform.
1079          *
1080          * Note that the transform is _not_ necessarily the same as
1081          * the transform passed in as an Attribute in a Map, as the
1082          * transform returned will also reflect the effects of WIDTH and
1083          * SUPERSCRIPT attributes.  Clients who want the actual transform
1084          * need to call getRequestedAttributes.
1085          */
1086         if (nonIdentityTx) {
1087             AttributeValues values = getAttributeValues();
1088 
1089             AffineTransform at = values.isNonDefault(ETRANSFORM)
1090                 ? new AffineTransform(values.getTransform())


1146     // x (1 - r) = r^0 - r^(n+1)
1147     // x = (r^0 - r^(n+1)) / (1 - r)
1148     // x = (1 - r^(n+1)) / (1 - r)
1149 
1150     // scale ratio is 2/3
1151     // trans = 1/2 of ascent * x
1152     // assume ascent is 3/4 of point size
1153 
1154     private static final float[] ssinfo = {
1155         0.0f,
1156         0.375f,
1157         0.625f,
1158         0.7916667f,
1159         0.9027778f,
1160         0.9768519f,
1161         1.0262346f,
1162         1.0591564f,
1163     };
1164 
1165     /**
1166      * Returns the family name of this <code>Font</code>.
1167      *
1168      * <p>The family name of a font is font specific. Two fonts such as
1169      * Helvetica Italic and Helvetica Bold have the same family name,
1170      * <i>Helvetica</i>, whereas their font face names are
1171      * <i>Helvetica Bold</i> and <i>Helvetica Italic</i>. The list of
1172      * available family names may be obtained by using the
1173      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1174      *
1175      * <p>Use <code>getName</code> to get the logical name of the font.
1176      * Use <code>getFontName</code> to get the font face name of the font.
1177      * @return a <code>String</code> that is the family name of this
1178      *          <code>Font</code>.
1179      *
1180      * @see #getName
1181      * @see #getFontName
1182      * @since 1.1
1183      */
1184     public String getFamily() {
1185         return getFamily_NoClientCode();
1186     }
1187     // NOTE: This method is called by privileged threads.
1188     //       We implement this functionality in a package-private
1189     //       method to insure that it cannot be overridden by client
1190     //       subclasses.
1191     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1192     final String getFamily_NoClientCode() {
1193         return getFamily(Locale.getDefault());
1194     }
1195 
1196     /**
1197      * Returns the family name of this <code>Font</code>, localized for
1198      * the specified locale.
1199      *
1200      * <p>The family name of a font is font specific. Two fonts such as
1201      * Helvetica Italic and Helvetica Bold have the same family name,
1202      * <i>Helvetica</i>, whereas their font face names are
1203      * <i>Helvetica Bold</i> and <i>Helvetica Italic</i>. The list of
1204      * available family names may be obtained by using the
1205      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1206      *
1207      * <p>Use <code>getFontName</code> to get the font face name of the font.
1208      * @param l locale for which to get the family name
1209      * @return a <code>String</code> representing the family name of the
1210      *          font, localized for the specified locale.
1211      * @see #getFontName
1212      * @see java.util.Locale
1213      * @since 1.2
1214      */
1215     public String getFamily(Locale l) {
1216         if (l == null) {
1217             throw new NullPointerException("null locale doesn't mean default");
1218         }
1219         return getFont2D().getFamilyName(l);
1220     }
1221 
1222     /**
1223      * Returns the postscript name of this <code>Font</code>.
1224      * Use <code>getFamily</code> to get the family name of the font.
1225      * Use <code>getFontName</code> to get the font face name of the font.
1226      * @return a <code>String</code> representing the postscript name of
1227      *          this <code>Font</code>.
1228      * @since 1.2
1229      */
1230     public String getPSName() {
1231         return getFont2D().getPostscriptName();
1232     }
1233 
1234     /**
1235      * Returns the logical name of this <code>Font</code>.
1236      * Use <code>getFamily</code> to get the family name of the font.
1237      * Use <code>getFontName</code> to get the font face name of the font.
1238      * @return a <code>String</code> representing the logical name of
1239      *          this <code>Font</code>.
1240      * @see #getFamily
1241      * @see #getFontName
1242      * @since 1.0
1243      */
1244     public String getName() {
1245         return name;
1246     }
1247 
1248     /**
1249      * Returns the font face name of this <code>Font</code>.  For example,
1250      * Helvetica Bold could be returned as a font face name.
1251      * Use <code>getFamily</code> to get the family name of the font.
1252      * Use <code>getName</code> to get the logical name of the font.
1253      * @return a <code>String</code> representing the font face name of
1254      *          this <code>Font</code>.
1255      * @see #getFamily
1256      * @see #getName
1257      * @since 1.2
1258      */
1259     public String getFontName() {
1260       return getFontName(Locale.getDefault());
1261     }
1262 
1263     /**
1264      * Returns the font face name of the <code>Font</code>, localized
1265      * for the specified locale. For example, Helvetica Fett could be
1266      * returned as the font face name.
1267      * Use <code>getFamily</code> to get the family name of the font.
1268      * @param l a locale for which to get the font face name
1269      * @return a <code>String</code> representing the font face name,
1270      *          localized for the specified locale.
1271      * @see #getFamily
1272      * @see java.util.Locale
1273      */
1274     public String getFontName(Locale l) {
1275         if (l == null) {
1276             throw new NullPointerException("null locale doesn't mean default");
1277         }
1278         return getFont2D().getFontName(l);
1279     }
1280 
1281     /**
1282      * Returns the style of this <code>Font</code>.  The style can be
1283      * PLAIN, BOLD, ITALIC, or BOLD+ITALIC.
1284      * @return the style of this <code>Font</code>
1285      * @see #isPlain
1286      * @see #isBold
1287      * @see #isItalic
1288      * @since 1.0
1289      */
1290     public int getStyle() {
1291         return style;
1292     }
1293 
1294     /**
1295      * Returns the point size of this <code>Font</code>, rounded to
1296      * an integer.
1297      * Most users are familiar with the idea of using <i>point size</i> to
1298      * specify the size of glyphs in a font. This point size defines a
1299      * measurement between the baseline of one line to the baseline of the
1300      * following line in a single spaced text document. The point size is
1301      * based on <i>typographic points</i>, approximately 1/72 of an inch.
1302      * <p>
1303      * The Java(tm)2D API adopts the convention that one point is
1304      * equivalent to one unit in user coordinates.  When using a
1305      * normalized transform for converting user space coordinates to
1306      * device space coordinates 72 user
1307      * space units equal 1 inch in device space.  In this case one point
1308      * is 1/72 of an inch.
1309      * @return the point size of this <code>Font</code> in 1/72 of an
1310      *          inch units.
1311      * @see #getSize2D
1312      * @see GraphicsConfiguration#getDefaultTransform
1313      * @see GraphicsConfiguration#getNormalizingTransform
1314      * @since 1.0
1315      */
1316     public int getSize() {
1317         return size;
1318     }
1319 
1320     /**
1321      * Returns the point size of this <code>Font</code> in
1322      * <code>float</code> value.
1323      * @return the point size of this <code>Font</code> as a
1324      * <code>float</code> value.
1325      * @see #getSize
1326      * @since 1.2
1327      */
1328     public float getSize2D() {
1329         return pointSize;
1330     }
1331 
1332     /**
1333      * Indicates whether or not this <code>Font</code> object's style is
1334      * PLAIN.
1335      * @return    <code>true</code> if this <code>Font</code> has a
1336      *            PLAIN style;
1337      *            <code>false</code> otherwise.
1338      * @see       java.awt.Font#getStyle
1339      * @since     1.0
1340      */
1341     public boolean isPlain() {
1342         return style == 0;
1343     }
1344 
1345     /**
1346      * Indicates whether or not this <code>Font</code> object's style is
1347      * BOLD.
1348      * @return    <code>true</code> if this <code>Font</code> object's
1349      *            style is BOLD;
1350      *            <code>false</code> otherwise.
1351      * @see       java.awt.Font#getStyle
1352      * @since     1.0
1353      */
1354     public boolean isBold() {
1355         return (style & BOLD) != 0;
1356     }
1357 
1358     /**
1359      * Indicates whether or not this <code>Font</code> object's style is
1360      * ITALIC.
1361      * @return    <code>true</code> if this <code>Font</code> object's
1362      *            style is ITALIC;
1363      *            <code>false</code> otherwise.
1364      * @see       java.awt.Font#getStyle
1365      * @since     1.0
1366      */
1367     public boolean isItalic() {
1368         return (style & ITALIC) != 0;
1369     }
1370 
1371     /**
1372      * Indicates whether or not this <code>Font</code> object has a
1373      * transform that affects its size in addition to the Size
1374      * attribute.
1375      * @return  <code>true</code> if this <code>Font</code> object
1376      *          has a non-identity AffineTransform attribute.
1377      *          <code>false</code> otherwise.
1378      * @see     java.awt.Font#getTransform
1379      * @since   1.4
1380      */
1381     public boolean isTransformed() {
1382         return nonIdentityTx;
1383     }
1384 
1385     /**
1386      * Return true if this Font contains attributes that require extra
1387      * layout processing.
1388      * @return true if the font has layout attributes
1389      * @since 1.6
1390      */
1391     public boolean hasLayoutAttributes() {
1392         return hasLayoutAttributes;
1393     }
1394 
1395     /**
1396      * Returns a <code>Font</code> object from the system properties list.
1397      * <code>nm</code> is treated as the name of a system property to be
1398      * obtained.  The <code>String</code> value of this property is then
1399      * interpreted as a <code>Font</code> object according to the
1400      * specification of <code>Font.decode(String)</code>
1401      * If the specified property is not found, or the executing code does
1402      * not have permission to read the property, null is returned instead.
1403      *
1404      * @param nm the property name
1405      * @return a <code>Font</code> object that the property name
1406      *          describes, or null if no such property exists.
1407      * @throws NullPointerException if nm is null.
1408      * @since 1.2
1409      * @see #decode(String)
1410      */
1411     public static Font getFont(String nm) {
1412         return getFont(nm, null);
1413     }
1414 
1415     /**
1416      * Returns the <code>Font</code> that the <code>str</code>
1417      * argument describes.
1418      * To ensure that this method returns the desired Font,
1419      * format the <code>str</code> parameter in
1420      * one of these ways
1421      *
1422      * <ul>
1423      * <li><em>fontname-style-pointsize</em>
1424      * <li><em>fontname-pointsize</em>
1425      * <li><em>fontname-style</em>
1426      * <li><em>fontname</em>
1427      * <li><em>fontname style pointsize</em>
1428      * <li><em>fontname pointsize</em>
1429      * <li><em>fontname style</em>
1430      * <li><em>fontname</em>
1431      * </ul>
1432      * in which <i>style</i> is one of the four
1433      * case-insensitive strings:
1434      * <code>"PLAIN"</code>, <code>"BOLD"</code>, <code>"BOLDITALIC"</code>, or
1435      * <code>"ITALIC"</code>, and pointsize is a positive decimal integer
1436      * representation of the point size.
1437      * For example, if you want a font that is Arial, bold, with
1438      * a point size of 18, you would call this method with:
1439      * "Arial-BOLD-18".
1440      * This is equivalent to calling the Font constructor :
1441      * <code>new Font("Arial", Font.BOLD, 18);</code>
1442      * and the values are interpreted as specified by that constructor.
1443      * <p>
1444      * A valid trailing decimal field is always interpreted as the pointsize.
1445      * Therefore a fontname containing a trailing decimal value should not
1446      * be used in the fontname only form.
1447      * <p>
1448      * If a style name field is not one of the valid style strings, it is
1449      * interpreted as part of the font name, and the default style is used.
1450      * <p>
1451      * Only one of ' ' or '-' may be used to separate fields in the input.
1452      * The identified separator is the one closest to the end of the string
1453      * which separates a valid pointsize, or a valid style name from
1454      * the rest of the string.
1455      * Null (empty) pointsize and style fields are treated
1456      * as valid fields with the default value for that field.
1457      *<p>
1458      * Some font names may include the separator characters ' ' or '-'.
1459      * If <code>str</code> is not formed with 3 components, e.g. such that
1460      * <code>style</code> or <code>pointsize</code> fields are not present in
1461      * <code>str</code>, and <code>fontname</code> also contains a
1462      * character determined to be the separator character
1463      * then these characters where they appear as intended to be part of
1464      * <code>fontname</code> may instead be interpreted as separators
1465      * so the font name may not be properly recognised.
1466      *
1467      * <p>
1468      * The default size is 12 and the default style is PLAIN.
1469      * If <code>str</code> does not specify a valid size, the returned
1470      * <code>Font</code> has a size of 12.  If <code>str</code> does not
1471      * specify a valid style, the returned Font has a style of PLAIN.
1472      * If you do not specify a valid font name in
1473      * the <code>str</code> argument, this method will return
1474      * a font with the family name "Dialog".
1475      * To determine what font family names are available on
1476      * your system, use the
1477      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1478      * If <code>str</code> is <code>null</code>, a new <code>Font</code>
1479      * is returned with the family name "Dialog", a size of 12 and a
1480      * PLAIN style.
1481      * @param str the name of the font, or <code>null</code>
1482      * @return the <code>Font</code> object that <code>str</code>
1483      *          describes, or a new default <code>Font</code> if
1484      *          <code>str</code> is <code>null</code>.
1485      * @see #getFamily
1486      * @since 1.1
1487      */
1488     public static Font decode(String str) {
1489         String fontName = str;
1490         String styleName = "";
1491         int fontSize = 12;
1492         int fontStyle = Font.PLAIN;
1493 
1494         if (str == null) {
1495             return new Font(DIALOG, fontStyle, fontSize);
1496         }
1497 
1498         int lastHyphen = str.lastIndexOf('-');
1499         int lastSpace = str.lastIndexOf(' ');
1500         char sepChar = (lastHyphen > lastSpace) ? '-' : ' ';
1501         int sizeIndex = str.lastIndexOf(sepChar);
1502         int styleIndex = str.lastIndexOf(sepChar, sizeIndex-1);
1503         int strlen = str.length();
1504 


1542             }
1543             fontName = str.substring(0, styleIndex);
1544 
1545         } else {
1546             int fontEnd = strlen;
1547             if (styleIndex > 0) {
1548                 fontEnd = styleIndex;
1549             } else if (sizeIndex > 0) {
1550                 fontEnd = sizeIndex;
1551             }
1552             if (fontEnd > 0 && str.charAt(fontEnd-1) == sepChar) {
1553                 fontEnd--;
1554             }
1555             fontName = str.substring(0, fontEnd);
1556         }
1557 
1558         return new Font(fontName, fontStyle, fontSize);
1559     }
1560 
1561     /**
1562      * Gets the specified <code>Font</code> from the system properties
1563      * list.  As in the <code>getProperty</code> method of
1564      * <code>System</code>, the first
1565      * argument is treated as the name of a system property to be
1566      * obtained.  The <code>String</code> value of this property is then
1567      * interpreted as a <code>Font</code> object.
1568      * <p>
1569      * The property value should be one of the forms accepted by
1570      * <code>Font.decode(String)</code>
1571      * If the specified property is not found, or the executing code does not
1572      * have permission to read the property, the <code>font</code>
1573      * argument is returned instead.
1574      * @param nm the case-insensitive property name
1575      * @param font a default <code>Font</code> to return if property
1576      *          <code>nm</code> is not defined
1577      * @return    the <code>Font</code> value of the property.
1578      * @throws NullPointerException if nm is null.
1579      * @see #decode(String)
1580      */
1581     public static Font getFont(String nm, Font font) {
1582         String str = null;
1583         try {
1584             str =System.getProperty(nm);
1585         } catch(SecurityException e) {
1586         }
1587         if (str == null) {
1588             return font;
1589         }
1590         return decode ( str );
1591     }
1592 
1593     transient int hash;
1594     /**
1595      * Returns a hashcode for this <code>Font</code>.
1596      * @return     a hashcode value for this <code>Font</code>.
1597      * @since      1.0
1598      */
1599     public int hashCode() {
1600         if (hash == 0) {
1601             hash = name.hashCode() ^ style ^ size;
1602             /* It is possible many fonts differ only in transform.
1603              * So include the transform in the hash calculation.
1604              * nonIdentityTx is set whenever there is a transform in
1605              * 'values'. The tests for null are required because it can
1606              * also be set for other reasons.
1607              */
1608             if (nonIdentityTx &&
1609                 values != null && values.getTransform() != null) {
1610                 hash ^= values.getTransform().hashCode();
1611             }
1612         }
1613         return hash;
1614     }
1615 
1616     /**
1617      * Compares this <code>Font</code> object to the specified
1618      * <code>Object</code>.
1619      * @param obj the <code>Object</code> to compare
1620      * @return <code>true</code> if the objects are the same
1621      *          or if the argument is a <code>Font</code> object
1622      *          describing the same font as this object;
1623      *          <code>false</code> otherwise.
1624      * @since 1.0
1625      */
1626     public boolean equals(Object obj) {
1627         if (obj == this) {
1628             return true;
1629         }
1630 
1631         if (obj != null) {
1632             try {
1633                 Font font = (Font)obj;
1634                 if (size == font.size &&
1635                     style == font.style &&
1636                     nonIdentityTx == font.nonIdentityTx &&
1637                     hasLayoutAttributes == font.hasLayoutAttributes &&
1638                     pointSize == font.pointSize &&
1639                     name.equals(font.name)) {
1640 
1641                     /* 'values' is usually initialized lazily, except when
1642                      * the font is constructed from a Map, or derived using
1643                      * a Map or other values. So if only one font has


1645                      * the other instance and compare.
1646                      */
1647                     if (values == null) {
1648                         if (font.values == null) {
1649                             return true;
1650                         } else {
1651                             return getAttributeValues().equals(font.values);
1652                         }
1653                     } else {
1654                         return values.equals(font.getAttributeValues());
1655                     }
1656                 }
1657             }
1658             catch (ClassCastException e) {
1659             }
1660         }
1661         return false;
1662     }
1663 
1664     /**
1665      * Converts this <code>Font</code> object to a <code>String</code>
1666      * representation.
1667      * @return     a <code>String</code> representation of this
1668      *          <code>Font</code> object.
1669      * @since      1.0
1670      */
1671     // NOTE: This method may be called by privileged threads.
1672     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1673     public String toString() {
1674         String  strStyle;
1675 
1676         if (isBold()) {
1677             strStyle = isItalic() ? "bolditalic" : "bold";
1678         } else {
1679             strStyle = isItalic() ? "italic" : "plain";
1680         }
1681 
1682         return getClass().getName() + "[family=" + getFamily() + ",name=" + name + ",style=" +
1683             strStyle + ",size=" + size + "]";
1684     } // toString()
1685 
1686 
1687     /** Serialization support.  A <code>readObject</code>
1688      *  method is necessary because the constructor creates
1689      *  the font's peer, and we can't serialize the peer.
1690      *  Similarly the computed font "family" may be different
1691      *  at <code>readObject</code> time than at
1692      *  <code>writeObject</code> time.  An integer version is
1693      *  written so that future versions of this class will be
1694      *  able to recognize serialized output from this one.
1695      */
1696     /**
1697      * The <code>Font</code> Serializable Data Form.
1698      *
1699      * @serial
1700      */
1701     private int fontSerializedDataVersion = 1;
1702 
1703     /**
1704      * Writes default serializable fields to a stream.
1705      *
1706      * @param s the <code>ObjectOutputStream</code> to write
1707      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1708      * @see #readObject(java.io.ObjectInputStream)
1709      */
1710     private void writeObject(java.io.ObjectOutputStream s)
1711       throws java.lang.ClassNotFoundException,
1712              java.io.IOException
1713     {
1714         if (values != null) {
1715           synchronized(values) {
1716             // transient
1717             fRequestedAttributes = values.toSerializableHashtable();
1718             s.defaultWriteObject();
1719             fRequestedAttributes = null;
1720           }
1721         } else {
1722           s.defaultWriteObject();
1723         }
1724     }
1725 
1726     /**
1727      * Reads the <code>ObjectInputStream</code>.
1728      * Unrecognized keys or values will be ignored.
1729      *
1730      * @param s the <code>ObjectInputStream</code> to read
1731      * @serial
1732      * @see #writeObject(java.io.ObjectOutputStream)
1733      */
1734     private void readObject(java.io.ObjectInputStream s)
1735       throws java.lang.ClassNotFoundException,
1736              java.io.IOException
1737     {
1738         s.defaultReadObject();
1739         if (pointSize == 0) {
1740             pointSize = (float)size;
1741         }
1742 
1743         // Handle fRequestedAttributes.
1744         // in 1.5, we always streamed out the font values plus
1745         // TRANSFORM, SUPERSCRIPT, and WIDTH, regardless of whether the
1746         // values were default or not.  In 1.6 we only stream out
1747         // defined values.  So, 1.6 streams in from a 1.5 stream,
1748         // it check each of these values and 'undefines' it if the
1749         // value is the default.
1750 
1751         if (fRequestedAttributes != null) {
1752             values = getAttributeValues(); // init
1753             AttributeValues extras =
1754                 AttributeValues.fromSerializableHashtable(fRequestedAttributes);
1755             if (!AttributeValues.is16Hashtable(fRequestedAttributes)) {
1756                 extras.unsetDefault(); // if legacy stream, undefine these
1757             }
1758             values = getAttributeValues().merge(extras);
1759             this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
1760             this.hasLayoutAttributes =  values.anyNonDefault(LAYOUT_MASK);
1761 
1762             fRequestedAttributes = null; // don't need it any more
1763         }
1764     }
1765 
1766     /**
1767      * Returns the number of glyphs in this <code>Font</code>. Glyph codes
1768      * for this <code>Font</code> range from 0 to
1769      * <code>getNumGlyphs()</code> - 1.
1770      * @return the number of glyphs in this <code>Font</code>.
1771      * @since 1.2
1772      */
1773     public int getNumGlyphs() {
1774         return  getFont2D().getNumGlyphs();
1775     }
1776 
1777     /**
1778      * Returns the glyphCode which is used when this <code>Font</code>
1779      * does not have a glyph for a specified unicode code point.
1780      * @return the glyphCode of this <code>Font</code>.
1781      * @since 1.2
1782      */
1783     public int getMissingGlyphCode() {
1784         return getFont2D().getMissingGlyphCode();
1785     }
1786 
1787     /**
1788      * Returns the baseline appropriate for displaying this character.
1789      * <p>
1790      * Large fonts can support different writing systems, and each system can
1791      * use a different baseline.
1792      * The character argument determines the writing system to use. Clients
1793      * should not assume all characters use the same baseline.
1794      *
1795      * @param c a character used to identify the writing system
1796      * @return the baseline appropriate for the specified character.
1797      * @see LineMetrics#getBaselineOffsets
1798      * @see #ROMAN_BASELINE
1799      * @see #CENTER_BASELINE
1800      * @see #HANGING_BASELINE
1801      * @since 1.2
1802      */
1803     public byte getBaselineFor(char c) {
1804         return getFont2D().getBaselineFor(c);
1805     }
1806 
1807     /**
1808      * Returns a map of font attributes available in this
1809      * <code>Font</code>.  Attributes include things like ligatures and
1810      * glyph substitution.
1811      * @return the attributes map of this <code>Font</code>.
1812      */
1813     public Map<TextAttribute,?> getAttributes(){
1814         return new AttributeMap(getAttributeValues());
1815     }
1816 
1817     /**
1818      * Returns the keys of all the attributes supported by this
1819      * <code>Font</code>.  These attributes can be used to derive other
1820      * fonts.
1821      * @return an array containing the keys of all the attributes
1822      *          supported by this <code>Font</code>.
1823      * @since 1.2
1824      */
1825     public Attribute[] getAvailableAttributes() {
1826         // FONT is not supported by Font
1827 
1828         Attribute attributes[] = {
1829             TextAttribute.FAMILY,
1830             TextAttribute.WEIGHT,
1831             TextAttribute.WIDTH,
1832             TextAttribute.POSTURE,
1833             TextAttribute.SIZE,
1834             TextAttribute.TRANSFORM,
1835             TextAttribute.SUPERSCRIPT,
1836             TextAttribute.CHAR_REPLACEMENT,
1837             TextAttribute.FOREGROUND,
1838             TextAttribute.BACKGROUND,
1839             TextAttribute.UNDERLINE,
1840             TextAttribute.STRIKETHROUGH,
1841             TextAttribute.RUN_DIRECTION,
1842             TextAttribute.BIDI_EMBEDDING,
1843             TextAttribute.JUSTIFICATION,
1844             TextAttribute.INPUT_METHOD_HIGHLIGHT,
1845             TextAttribute.INPUT_METHOD_UNDERLINE,
1846             TextAttribute.SWAP_COLORS,
1847             TextAttribute.NUMERIC_SHAPING,
1848             TextAttribute.KERNING,
1849             TextAttribute.LIGATURES,
1850             TextAttribute.TRACKING,
1851         };
1852 
1853         return attributes;
1854     }
1855 
1856     /**
1857      * Creates a new <code>Font</code> object by replicating this
1858      * <code>Font</code> object and applying a new style and size.
1859      * @param style the style for the new <code>Font</code>
1860      * @param size the size for the new <code>Font</code>
1861      * @return a new <code>Font</code> object.
1862      * @since 1.2
1863      */
1864     public Font deriveFont(int style, float size){
1865         if (values == null) {
1866             return new Font(name, style, size, createdFont, font2DHandle);
1867         }
1868         AttributeValues newValues = getAttributeValues().clone();
1869         int oldStyle = (this.style != style) ? this.style : -1;
1870         applyStyle(style, newValues);
1871         newValues.setSize(size);
1872         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1873     }
1874 
1875     /**
1876      * Creates a new <code>Font</code> object by replicating this
1877      * <code>Font</code> object and applying a new style and transform.
1878      * @param style the style for the new <code>Font</code>
1879      * @param trans the <code>AffineTransform</code> associated with the
1880      * new <code>Font</code>
1881      * @return a new <code>Font</code> object.
1882      * @throws IllegalArgumentException if <code>trans</code> is
1883      *         <code>null</code>
1884      * @since 1.2
1885      */
1886     public Font deriveFont(int style, AffineTransform trans){
1887         AttributeValues newValues = getAttributeValues().clone();
1888         int oldStyle = (this.style != style) ? this.style : -1;
1889         applyStyle(style, newValues);
1890         applyTransform(trans, newValues);
1891         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1892     }
1893 
1894     /**
1895      * Creates a new <code>Font</code> object by replicating the current
1896      * <code>Font</code> object and applying a new size to it.
1897      * @param size the size for the new <code>Font</code>.
1898      * @return a new <code>Font</code> object.
1899      * @since 1.2
1900      */
1901     public Font deriveFont(float size){
1902         if (values == null) {
1903             return new Font(name, style, size, createdFont, font2DHandle);
1904         }
1905         AttributeValues newValues = getAttributeValues().clone();
1906         newValues.setSize(size);
1907         return new Font(newValues, null, -1, createdFont, font2DHandle);
1908     }
1909 
1910     /**
1911      * Creates a new <code>Font</code> object by replicating the current
1912      * <code>Font</code> object and applying a new transform to it.
1913      * @param trans the <code>AffineTransform</code> associated with the
1914      * new <code>Font</code>
1915      * @return a new <code>Font</code> object.
1916      * @throws IllegalArgumentException if <code>trans</code> is
1917      *         <code>null</code>
1918      * @since 1.2
1919      */
1920     public Font deriveFont(AffineTransform trans){
1921         AttributeValues newValues = getAttributeValues().clone();
1922         applyTransform(trans, newValues);
1923         return new Font(newValues, null, -1, createdFont, font2DHandle);
1924     }
1925 
1926     /**
1927      * Creates a new <code>Font</code> object by replicating the current
1928      * <code>Font</code> object and applying a new style to it.
1929      * @param style the style for the new <code>Font</code>
1930      * @return a new <code>Font</code> object.
1931      * @since 1.2
1932      */
1933     public Font deriveFont(int style){
1934         if (values == null) {
1935            return new Font(name, style, size, createdFont, font2DHandle);
1936         }
1937         AttributeValues newValues = getAttributeValues().clone();
1938         int oldStyle = (this.style != style) ? this.style : -1;
1939         applyStyle(style, newValues);
1940         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1941     }
1942 
1943     /**
1944      * Creates a new <code>Font</code> object by replicating the current
1945      * <code>Font</code> object and applying a new set of font attributes
1946      * to it.
1947      *
1948      * @param attributes a map of attributes enabled for the new
1949      * <code>Font</code>
1950      * @return a new <code>Font</code> object.
1951      * @since 1.2
1952      */
1953     public Font deriveFont(Map<? extends Attribute, ?> attributes) {
1954         if (attributes == null) {
1955             return this;
1956         }
1957         AttributeValues newValues = getAttributeValues().clone();
1958         newValues.merge(attributes, RECOGNIZED_MASK);
1959 
1960         return new Font(newValues, name, style, createdFont, font2DHandle);
1961     }
1962 
1963     /**
1964      * Checks if this <code>Font</code> has a glyph for the specified
1965      * character.
1966      *
1967      * <p> <b>Note:</b> This method cannot handle <a
1968      * href="../../java/lang/Character.html#supplementary"> supplementary
1969      * characters</a>. To support all Unicode characters, including
1970      * supplementary characters, use the {@link #canDisplay(int)}
1971      * method or <code>canDisplayUpTo</code> methods.
1972      *
1973      * @param c the character for which a glyph is needed
1974      * @return <code>true</code> if this <code>Font</code> has a glyph for this
1975      *          character; <code>false</code> otherwise.
1976      * @since 1.2
1977      */
1978     public boolean canDisplay(char c){
1979         return getFont2D().canDisplay(c);
1980     }
1981 
1982     /**
1983      * Checks if this <code>Font</code> has a glyph for the specified
1984      * character.
1985      *
1986      * @param codePoint the character (Unicode code point) for which a glyph
1987      *        is needed.
1988      * @return <code>true</code> if this <code>Font</code> has a glyph for the
1989      *          character; <code>false</code> otherwise.
1990      * @throws IllegalArgumentException if the code point is not a valid Unicode
1991      *          code point.
1992      * @see Character#isValidCodePoint(int)
1993      * @since 1.5
1994      */
1995     public boolean canDisplay(int codePoint) {
1996         if (!Character.isValidCodePoint(codePoint)) {
1997             throw new IllegalArgumentException("invalid code point: " +
1998                                                Integer.toHexString(codePoint));
1999         }
2000         return getFont2D().canDisplay(codePoint);
2001     }
2002 
2003     /**
2004      * Indicates whether or not this <code>Font</code> can display a
2005      * specified <code>String</code>.  For strings with Unicode encoding,
2006      * it is important to know if a particular font can display the
2007      * string. This method returns an offset into the <code>String</code>
2008      * <code>str</code> which is the first character this
2009      * <code>Font</code> cannot display without using the missing glyph
2010      * code. If the <code>Font</code> can display all characters, -1 is
2011      * returned.
2012      * @param str a <code>String</code> object
2013      * @return an offset into <code>str</code> that points
2014      *          to the first character in <code>str</code> that this
2015      *          <code>Font</code> cannot display; or <code>-1</code> if
2016      *          this <code>Font</code> can display all characters in
2017      *          <code>str</code>.
2018      * @since 1.2
2019      */
2020     public int canDisplayUpTo(String str) {
2021         Font2D font2d = getFont2D();
2022         int len = str.length();
2023         for (int i = 0; i < len; i++) {
2024             char c = str.charAt(i);
2025             if (font2d.canDisplay(c)) {
2026                 continue;
2027             }
2028             if (!Character.isHighSurrogate(c)) {
2029                 return i;
2030             }
2031             if (!font2d.canDisplay(str.codePointAt(i))) {
2032                 return i;
2033             }
2034             i++;
2035         }
2036         return -1;
2037     }
2038 
2039     /**
2040      * Indicates whether or not this <code>Font</code> can display
2041      * the characters in the specified <code>text</code>
2042      * starting at <code>start</code> and ending at
2043      * <code>limit</code>.  This method is a convenience overload.
2044      * @param text the specified array of <code>char</code> values
2045      * @param start the specified starting offset (in
2046      *              <code>char</code>s) into the specified array of
2047      *              <code>char</code> values
2048      * @param limit the specified ending offset (in
2049      *              <code>char</code>s) into the specified array of
2050      *              <code>char</code> values
2051      * @return an offset into <code>text</code> that points
2052      *          to the first character in <code>text</code> that this
2053      *          <code>Font</code> cannot display; or <code>-1</code> if
2054      *          this <code>Font</code> can display all characters in
2055      *          <code>text</code>.
2056      * @since 1.2
2057      */
2058     public int canDisplayUpTo(char[] text, int start, int limit) {
2059         Font2D font2d = getFont2D();
2060         for (int i = start; i < limit; i++) {
2061             char c = text[i];
2062             if (font2d.canDisplay(c)) {
2063                 continue;
2064             }
2065             if (!Character.isHighSurrogate(c)) {
2066                 return i;
2067             }
2068             if (!font2d.canDisplay(Character.codePointAt(text, i, limit))) {
2069                 return i;
2070             }
2071             i++;
2072         }
2073         return -1;
2074     }
2075 
2076     /**
2077      * Indicates whether or not this <code>Font</code> can display the
2078      * text specified by the <code>iter</code> starting at
2079      * <code>start</code> and ending at <code>limit</code>.
2080      *
2081      * @param iter  a {@link CharacterIterator} object
2082      * @param start the specified starting offset into the specified
2083      *              <code>CharacterIterator</code>.
2084      * @param limit the specified ending offset into the specified
2085      *              <code>CharacterIterator</code>.
2086      * @return an offset into <code>iter</code> that points
2087      *          to the first character in <code>iter</code> that this
2088      *          <code>Font</code> cannot display; or <code>-1</code> if
2089      *          this <code>Font</code> can display all characters in
2090      *          <code>iter</code>.
2091      * @since 1.2
2092      */
2093     public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
2094         Font2D font2d = getFont2D();
2095         char c = iter.setIndex(start);
2096         for (int i = start; i < limit; i++, c = iter.next()) {
2097             if (font2d.canDisplay(c)) {
2098                 continue;
2099             }
2100             if (!Character.isHighSurrogate(c)) {
2101                 return i;
2102             }
2103             char c2 = iter.next();
2104             // c2 could be CharacterIterator.DONE which is not a low surrogate.
2105             if (!Character.isLowSurrogate(c2)) {
2106                 return i;
2107             }
2108             if (!font2d.canDisplay(Character.toCodePoint(c, c2))) {
2109                 return i;
2110             }
2111             i++;
2112         }
2113         return -1;
2114     }
2115 
2116     /**
2117      * Returns the italic angle of this <code>Font</code>.  The italic angle
2118      * is the inverse slope of the caret which best matches the posture of this
2119      * <code>Font</code>.
2120      * @see TextAttribute#POSTURE
2121      * @return the angle of the ITALIC style of this <code>Font</code>.
2122      */
2123     public float getItalicAngle() {
2124         return getItalicAngle(null);
2125     }
2126 
2127     /* The FRC hints don't affect the value of the italic angle but
2128      * we need to pass them in to look up a strike.
2129      * If we can pass in ones already being used it can prevent an extra
2130      * strike from being allocated. Note that since italic angle is
2131      * a property of the font, the font transform is needed not the
2132      * device transform. Finally, this is private but the only caller of this
2133      * in the JDK - and the only likely caller - is in this same class.
2134      */
2135     private float getItalicAngle(FontRenderContext frc) {
2136         Object aa, fm;
2137         if (frc == null) {
2138             aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
2139             fm = RenderingHints.VALUE_FRACTIONALMETRICS_OFF;
2140         } else {
2141             aa = frc.getAntiAliasingHint();
2142             fm = frc.getFractionalMetricsHint();
2143         }
2144         return getFont2D().getItalicAngle(this, identityTx, aa, fm);
2145     }
2146 
2147     /**
2148      * Checks whether or not this <code>Font</code> has uniform
2149      * line metrics.  A logical <code>Font</code> might be a
2150      * composite font, which means that it is composed of different
2151      * physical fonts to cover different code ranges.  Each of these
2152      * fonts might have different <code>LineMetrics</code>.  If the
2153      * logical <code>Font</code> is a single
2154      * font then the metrics would be uniform.
2155      * @return <code>true</code> if this <code>Font</code> has
2156      * uniform line metrics; <code>false</code> otherwise.
2157      */
2158     public boolean hasUniformLineMetrics() {
2159         return false;   // REMIND always safe, but prevents caller optimize
2160     }
2161 
2162     private transient SoftReference<FontLineMetrics> flmref;
2163     private FontLineMetrics defaultLineMetrics(FontRenderContext frc) {
2164         FontLineMetrics flm = null;
2165         if (flmref == null
2166             || (flm = flmref.get()) == null
2167             || !flm.frc.equals(frc)) {
2168 
2169             /* The device transform in the frc is not used in obtaining line
2170              * metrics, although it probably should be: REMIND find why not?
2171              * The font transform is used but its applied in getFontMetrics, so
2172              * just pass identity here
2173              */
2174             float [] metrics = new float[8];
2175             getFont2D().getFontMetrics(this, identityTx,
2176                                        frc.getAntiAliasingHint(),


2218                 }
2219             }
2220             strikethroughOffset += ssOffset;
2221             underlineOffset += ssOffset;
2222 
2223             CoreMetrics cm = new CoreMetrics(ascent, descent, leading, height,
2224                                              baselineIndex, baselineOffsets,
2225                                              strikethroughOffset, strikethroughThickness,
2226                                              underlineOffset, underlineThickness,
2227                                              ssOffset, italicAngle);
2228 
2229             flm = new FontLineMetrics(0, cm, frc);
2230             flmref = new SoftReference<FontLineMetrics>(flm);
2231         }
2232 
2233         return (FontLineMetrics)flm.clone();
2234     }
2235 
2236     /**
2237      * Returns a {@link LineMetrics} object created with the specified
2238      * <code>String</code> and {@link FontRenderContext}.
2239      * @param str the specified <code>String</code>
2240      * @param frc the specified <code>FontRenderContext</code>
2241      * @return a <code>LineMetrics</code> object created with the
2242      * specified <code>String</code> and {@link FontRenderContext}.
2243      */
2244     public LineMetrics getLineMetrics( String str, FontRenderContext frc) {
2245         FontLineMetrics flm = defaultLineMetrics(frc);
2246         flm.numchars = str.length();
2247         return flm;
2248     }
2249 
2250     /**
2251      * Returns a <code>LineMetrics</code> object created with the
2252      * specified arguments.
2253      * @param str the specified <code>String</code>
2254      * @param beginIndex the initial offset of <code>str</code>
2255      * @param limit the end offset of <code>str</code>
2256      * @param frc the specified <code>FontRenderContext</code>
2257      * @return a <code>LineMetrics</code> object created with the
2258      * specified arguments.
2259      */
2260     public LineMetrics getLineMetrics( String str,
2261                                     int beginIndex, int limit,
2262                                     FontRenderContext frc) {
2263         FontLineMetrics flm = defaultLineMetrics(frc);
2264         int numChars = limit - beginIndex;
2265         flm.numchars = (numChars < 0)? 0: numChars;
2266         return flm;
2267     }
2268 
2269     /**
2270      * Returns a <code>LineMetrics</code> object created with the
2271      * specified arguments.
2272      * @param chars an array of characters
2273      * @param beginIndex the initial offset of <code>chars</code>
2274      * @param limit the end offset of <code>chars</code>
2275      * @param frc the specified <code>FontRenderContext</code>
2276      * @return a <code>LineMetrics</code> object created with the
2277      * specified arguments.
2278      */
2279     public LineMetrics getLineMetrics(char [] chars,
2280                                     int beginIndex, int limit,
2281                                     FontRenderContext frc) {
2282         FontLineMetrics flm = defaultLineMetrics(frc);
2283         int numChars = limit - beginIndex;
2284         flm.numchars = (numChars < 0)? 0: numChars;
2285         return flm;
2286     }
2287 
2288     /**
2289      * Returns a <code>LineMetrics</code> object created with the
2290      * specified arguments.
2291      * @param ci the specified <code>CharacterIterator</code>
2292      * @param beginIndex the initial offset in <code>ci</code>
2293      * @param limit the end offset of <code>ci</code>
2294      * @param frc the specified <code>FontRenderContext</code>
2295      * @return a <code>LineMetrics</code> object created with the
2296      * specified arguments.
2297      */
2298     public LineMetrics getLineMetrics(CharacterIterator ci,
2299                                     int beginIndex, int limit,
2300                                     FontRenderContext frc) {
2301         FontLineMetrics flm = defaultLineMetrics(frc);
2302         int numChars = limit - beginIndex;
2303         flm.numchars = (numChars < 0)? 0: numChars;
2304         return flm;
2305     }
2306 
2307     /**
2308      * Returns the logical bounds of the specified <code>String</code> in
2309      * the specified <code>FontRenderContext</code>.  The logical bounds
2310      * contains the origin, ascent, advance, and height, which includes
2311      * the leading.  The logical bounds does not always enclose all the
2312      * text.  For example, in some languages and in some fonts, accent
2313      * marks can be positioned above the ascent or below the descent.
2314      * To obtain a visual bounding box, which encloses all the text,
2315      * use the {@link TextLayout#getBounds() getBounds} method of
2316      * <code>TextLayout</code>.
2317      * <p>Note: The returned bounds is in baseline-relative coordinates
2318      * (see {@link java.awt.Font class notes}).
2319      * @param str the specified <code>String</code>
2320      * @param frc the specified <code>FontRenderContext</code>
2321      * @return a {@link Rectangle2D} that is the bounding box of the
2322      * specified <code>String</code> in the specified
2323      * <code>FontRenderContext</code>.
2324      * @see FontRenderContext
2325      * @see Font#createGlyphVector
2326      * @since 1.2
2327      */
2328     public Rectangle2D getStringBounds( String str, FontRenderContext frc) {
2329         char[] array = str.toCharArray();
2330         return getStringBounds(array, 0, array.length, frc);
2331     }
2332 
2333    /**
2334      * Returns the logical bounds of the specified <code>String</code> in
2335      * the specified <code>FontRenderContext</code>.  The logical bounds
2336      * contains the origin, ascent, advance, and height, which includes
2337      * the leading.  The logical bounds does not always enclose all the
2338      * text.  For example, in some languages and in some fonts, accent
2339      * marks can be positioned above the ascent or below the descent.
2340      * To obtain a visual bounding box, which encloses all the text,
2341      * use the {@link TextLayout#getBounds() getBounds} method of
2342      * <code>TextLayout</code>.
2343      * <p>Note: The returned bounds is in baseline-relative coordinates
2344      * (see {@link java.awt.Font class notes}).
2345      * @param str the specified <code>String</code>
2346      * @param beginIndex the initial offset of <code>str</code>
2347      * @param limit the end offset of <code>str</code>
2348      * @param frc the specified <code>FontRenderContext</code>
2349      * @return a <code>Rectangle2D</code> that is the bounding box of the
2350      * specified <code>String</code> in the specified
2351      * <code>FontRenderContext</code>.
2352      * @throws IndexOutOfBoundsException if <code>beginIndex</code> is
2353      *         less than zero, or <code>limit</code> is greater than the
2354      *         length of <code>str</code>, or <code>beginIndex</code>
2355      *         is greater than <code>limit</code>.
2356      * @see FontRenderContext
2357      * @see Font#createGlyphVector
2358      * @since 1.2
2359      */
2360     public Rectangle2D getStringBounds( String str,
2361                                     int beginIndex, int limit,
2362                                         FontRenderContext frc) {
2363         String substr = str.substring(beginIndex, limit);
2364         return getStringBounds(substr, frc);
2365     }
2366 
2367    /**
2368      * Returns the logical bounds of the specified array of characters
2369      * in the specified <code>FontRenderContext</code>.  The logical
2370      * bounds contains the origin, ascent, advance, and height, which
2371      * includes the leading.  The logical bounds does not always enclose
2372      * all the text.  For example, in some languages and in some fonts,
2373      * accent marks can be positioned above the ascent or below the
2374      * descent.  To obtain a visual bounding box, which encloses all the
2375      * text, use the {@link TextLayout#getBounds() getBounds} method of
2376      * <code>TextLayout</code>.
2377      * <p>Note: The returned bounds is in baseline-relative coordinates
2378      * (see {@link java.awt.Font class notes}).
2379      * @param chars an array of characters
2380      * @param beginIndex the initial offset in the array of
2381      * characters
2382      * @param limit the end offset in the array of characters
2383      * @param frc the specified <code>FontRenderContext</code>
2384      * @return a <code>Rectangle2D</code> that is the bounding box of the
2385      * specified array of characters in the specified
2386      * <code>FontRenderContext</code>.
2387      * @throws IndexOutOfBoundsException if <code>beginIndex</code> is
2388      *         less than zero, or <code>limit</code> is greater than the
2389      *         length of <code>chars</code>, or <code>beginIndex</code>
2390      *         is greater than <code>limit</code>.
2391      * @see FontRenderContext
2392      * @see Font#createGlyphVector
2393      * @since 1.2
2394      */
2395     public Rectangle2D getStringBounds(char [] chars,
2396                                     int beginIndex, int limit,
2397                                        FontRenderContext frc) {
2398         if (beginIndex < 0) {
2399             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2400         }
2401         if (limit > chars.length) {
2402             throw new IndexOutOfBoundsException("limit: " + limit);
2403         }
2404         if (beginIndex > limit) {
2405             throw new IndexOutOfBoundsException("range length: " +
2406                                                 (limit - beginIndex));
2407         }
2408 
2409         // this code should be in textlayout
2410         // quick check for simple text, assume GV ok to use if simple


2416             simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
2417         }
2418 
2419         if (simple) {
2420             GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
2421                                                      limit - beginIndex, frc);
2422             return gv.getLogicalBounds();
2423         } else {
2424             // need char array constructor on textlayout
2425             String str = new String(chars, beginIndex, limit - beginIndex);
2426             TextLayout tl = new TextLayout(str, this, frc);
2427             return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
2428                                          tl.getAscent() + tl.getDescent() +
2429                                          tl.getLeading());
2430         }
2431     }
2432 
2433    /**
2434      * Returns the logical bounds of the characters indexed in the
2435      * specified {@link CharacterIterator} in the
2436      * specified <code>FontRenderContext</code>.  The logical bounds
2437      * contains the origin, ascent, advance, and height, which includes
2438      * the leading.  The logical bounds does not always enclose all the
2439      * text.  For example, in some languages and in some fonts, accent
2440      * marks can be positioned above the ascent or below the descent.
2441      * To obtain a visual bounding box, which encloses all the text,
2442      * use the {@link TextLayout#getBounds() getBounds} method of
2443      * <code>TextLayout</code>.
2444      * <p>Note: The returned bounds is in baseline-relative coordinates
2445      * (see {@link java.awt.Font class notes}).
2446      * @param ci the specified <code>CharacterIterator</code>
2447      * @param beginIndex the initial offset in <code>ci</code>
2448      * @param limit the end offset in <code>ci</code>
2449      * @param frc the specified <code>FontRenderContext</code>
2450      * @return a <code>Rectangle2D</code> that is the bounding box of the
2451      * characters indexed in the specified <code>CharacterIterator</code>
2452      * in the specified <code>FontRenderContext</code>.
2453      * @see FontRenderContext
2454      * @see Font#createGlyphVector
2455      * @since 1.2
2456      * @throws IndexOutOfBoundsException if <code>beginIndex</code> is
2457      *         less than the start index of <code>ci</code>, or
2458      *         <code>limit</code> is greater than the end index of
2459      *         <code>ci</code>, or <code>beginIndex</code> is greater
2460      *         than <code>limit</code>
2461      */
2462     public Rectangle2D getStringBounds(CharacterIterator ci,
2463                                     int beginIndex, int limit,
2464                                        FontRenderContext frc) {
2465         int start = ci.getBeginIndex();
2466         int end = ci.getEndIndex();
2467 
2468         if (beginIndex < start) {
2469             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2470         }
2471         if (limit > end) {
2472             throw new IndexOutOfBoundsException("limit: " + limit);
2473         }
2474         if (beginIndex > limit) {
2475             throw new IndexOutOfBoundsException("range length: " +
2476                                                 (limit - beginIndex));
2477         }
2478 
2479         char[]  arr = new char[limit - beginIndex];
2480 
2481         ci.setIndex(beginIndex);
2482         for(int idx = 0; idx < arr.length; idx++) {
2483             arr[idx] = ci.current();
2484             ci.next();
2485         }
2486 
2487         return getStringBounds(arr,0,arr.length,frc);
2488     }
2489 
2490     /**
2491      * Returns the bounds for the character with the maximum
2492      * bounds as defined in the specified <code>FontRenderContext</code>.
2493      * <p>Note: The returned bounds is in baseline-relative coordinates
2494      * (see {@link java.awt.Font class notes}).
2495      * @param frc the specified <code>FontRenderContext</code>
2496      * @return a <code>Rectangle2D</code> that is the bounding box
2497      * for the character with the maximum bounds.
2498      */
2499     public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
2500         float [] metrics = new float[4];
2501 
2502         getFont2D().getFontMetrics(this, frc, metrics);
2503 
2504         return new Rectangle2D.Float(0, -metrics[0],
2505                                 metrics[3],
2506                                 metrics[0] + metrics[1] + metrics[2]);
2507     }
2508 
2509     /**
2510      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2511      * mapping characters to glyphs one-to-one based on the
2512      * Unicode cmap in this <code>Font</code>.  This method does no other
2513      * processing besides the mapping of glyphs to characters.  This
2514      * means that this method is not useful for some scripts, such
2515      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2516      * shaping, or ligature substitution.
2517      * @param frc the specified <code>FontRenderContext</code>
2518      * @param str the specified <code>String</code>
2519      * @return a new <code>GlyphVector</code> created with the
2520      * specified <code>String</code> and the specified
2521      * <code>FontRenderContext</code>.
2522      */
2523     public GlyphVector createGlyphVector(FontRenderContext frc, String str)
2524     {
2525         return (GlyphVector)new StandardGlyphVector(this, str, frc);
2526     }
2527 
2528     /**
2529      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2530      * mapping characters to glyphs one-to-one based on the
2531      * Unicode cmap in this <code>Font</code>.  This method does no other
2532      * processing besides the mapping of glyphs to characters.  This
2533      * means that this method is not useful for some scripts, such
2534      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2535      * shaping, or ligature substitution.
2536      * @param frc the specified <code>FontRenderContext</code>
2537      * @param chars the specified array of characters
2538      * @return a new <code>GlyphVector</code> created with the
2539      * specified array of characters and the specified
2540      * <code>FontRenderContext</code>.
2541      */
2542     public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars)
2543     {
2544         return (GlyphVector)new StandardGlyphVector(this, chars, frc);
2545     }
2546 
2547     /**
2548      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2549      * mapping the specified characters to glyphs one-to-one based on the
2550      * Unicode cmap in this <code>Font</code>.  This method does no other
2551      * processing besides the mapping of glyphs to characters.  This
2552      * means that this method is not useful for some scripts, such
2553      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2554      * shaping, or ligature substitution.
2555      * @param frc the specified <code>FontRenderContext</code>
2556      * @param ci the specified <code>CharacterIterator</code>
2557      * @return a new <code>GlyphVector</code> created with the
2558      * specified <code>CharacterIterator</code> and the specified
2559      * <code>FontRenderContext</code>.
2560      */
2561     public GlyphVector createGlyphVector(   FontRenderContext frc,
2562                                             CharacterIterator ci)
2563     {
2564         return (GlyphVector)new StandardGlyphVector(this, ci, frc);
2565     }
2566 
2567     /**
2568      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2569      * mapping characters to glyphs one-to-one based on the
2570      * Unicode cmap in this <code>Font</code>.  This method does no other
2571      * processing besides the mapping of glyphs to characters.  This
2572      * means that this method is not useful for some scripts, such
2573      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2574      * shaping, or ligature substitution.
2575      * @param frc the specified <code>FontRenderContext</code>
2576      * @param glyphCodes the specified integer array
2577      * @return a new <code>GlyphVector</code> created with the
2578      * specified integer array and the specified
2579      * <code>FontRenderContext</code>.
2580      */
2581     public GlyphVector createGlyphVector(   FontRenderContext frc,
2582                                             int [] glyphCodes)
2583     {
2584         return (GlyphVector)new StandardGlyphVector(this, glyphCodes, frc);
2585     }
2586 
2587     /**
2588      * Returns a new <code>GlyphVector</code> object, performing full
2589      * layout of the text if possible.  Full layout is required for
2590      * complex text, such as Arabic or Hindi.  Support for different
2591      * scripts depends on the font and implementation.
2592      * <p>
2593      * Layout requires bidi analysis, as performed by
2594      * <code>Bidi</code>, and should only be performed on text that
2595      * has a uniform direction.  The direction is indicated in the
2596      * flags parameter,by using LAYOUT_RIGHT_TO_LEFT to indicate a
2597      * right-to-left (Arabic and Hebrew) run direction, or
2598      * LAYOUT_LEFT_TO_RIGHT to indicate a left-to-right (English)
2599      * run direction.
2600      * <p>
2601      * In addition, some operations, such as Arabic shaping, require
2602      * context, so that the characters at the start and limit can have
2603      * the proper shapes.  Sometimes the data in the buffer outside
2604      * the provided range does not have valid data.  The values
2605      * LAYOUT_NO_START_CONTEXT and LAYOUT_NO_LIMIT_CONTEXT can be
2606      * added to the flags parameter to indicate that the text before
2607      * start, or after limit, respectively, should not be examined
2608      * for context.
2609      * <p>
2610      * All other values for the flags parameter are reserved.
2611      *
2612      * @param frc the specified <code>FontRenderContext</code>
2613      * @param text the text to layout
2614      * @param start the start of the text to use for the <code>GlyphVector</code>
2615      * @param limit the limit of the text to use for the <code>GlyphVector</code>
2616      * @param flags control flags as described above
2617      * @return a new <code>GlyphVector</code> representing the text between
2618      * start and limit, with glyphs chosen and positioned so as to best represent
2619      * the text
2620      * @throws ArrayIndexOutOfBoundsException if start or limit is
2621      * out of bounds
2622      * @see java.text.Bidi
2623      * @see #LAYOUT_LEFT_TO_RIGHT
2624      * @see #LAYOUT_RIGHT_TO_LEFT
2625      * @see #LAYOUT_NO_START_CONTEXT
2626      * @see #LAYOUT_NO_LIMIT_CONTEXT
2627      * @since 1.4
2628      */
2629     public GlyphVector layoutGlyphVector(FontRenderContext frc,
2630                                          char[] text,
2631                                          int start,
2632                                          int limit,
2633                                          int flags) {
2634 
2635         GlyphLayout gl = GlyphLayout.get(null); // !!! no custom layout engines
2636         StandardGlyphVector gv = gl.layout(this, frc, text,
2637                                            start, limit-start, flags, null);




  48 import sun.awt.ComponentFactory;
  49 import sun.font.StandardGlyphVector;
  50 
  51 import sun.font.AttributeMap;
  52 import sun.font.AttributeValues;
  53 import sun.font.CompositeFont;
  54 import sun.font.CreatedFontTracker;
  55 import sun.font.Font2D;
  56 import sun.font.Font2DHandle;
  57 import sun.font.FontAccess;
  58 import sun.font.FontManager;
  59 import sun.font.FontManagerFactory;
  60 import sun.font.FontUtilities;
  61 import sun.font.GlyphLayout;
  62 import sun.font.FontLineMetrics;
  63 import sun.font.CoreMetrics;
  64 
  65 import static sun.font.EAttribute.*;
  66 
  67 /**
  68  * The {@code Font} class represents fonts, which are used to
  69  * render text in a visible way.
  70  * A font provides the information needed to map sequences of
  71  * <em>characters</em> to sequences of <em>glyphs</em>
  72  * and to render sequences of glyphs on {@code Graphics} and
  73  * {@code Component} objects.
  74  *
  75  * <h3>Characters and Glyphs</h3>
  76  *
  77  * A <em>character</em> is a symbol that represents an item such as a letter,
  78  * a digit, or punctuation in an abstract way. For example, {@code 'g'},
  79  * LATIN SMALL LETTER G, is a character.
  80  * <p>
  81  * A <em>glyph</em> is a shape used to render a character or a sequence of
  82  * characters. In simple writing systems, such as Latin, typically one glyph
  83  * represents one character. In general, however, characters and glyphs do not
  84  * have one-to-one correspondence. For example, the character '&aacute;'
  85  * LATIN SMALL LETTER A WITH ACUTE, can be represented by
  86  * two glyphs: one for 'a' and one for '&acute;'. On the other hand, the
  87  * two-character string "fi" can be represented by a single glyph, an
  88  * "fi" ligature. In complex writing systems, such as Arabic or the South
  89  * and South-East Asian writing systems, the relationship between characters
  90  * and glyphs can be more complicated and involve context-dependent selection
  91  * of glyphs as well as glyph reordering.
  92  *
  93  * A font encapsulates the collection of glyphs needed to render a selected set
  94  * of characters as well as the tables needed to map sequences of characters to
  95  * corresponding sequences of glyphs.
  96  *
  97  * <h3>Physical and Logical Fonts</h3>
  98  *


 118  * Serif, SansSerif, Monospaced, Dialog, and DialogInput.
 119  * These logical fonts are not actual font libraries. Instead, the logical
 120  * font names are mapped to physical fonts by the Java runtime environment.
 121  * The mapping is implementation and usually locale dependent, so the look
 122  * and the metrics provided by them vary.
 123  * Typically, each logical font name maps to several physical fonts in order to
 124  * cover a large range of characters.
 125  * <p>
 126  * Peered AWT components, such as {@link Label Label} and
 127  * {@link TextField TextField}, can only use logical fonts.
 128  * <p>
 129  * For a discussion of the relative advantages and disadvantages of using
 130  * physical or logical fonts, see the
 131  * <a href="https://docs.oracle.com/javase/tutorial/2d/text/fonts.html#advantages-and-disadvantages">
 132  *    Physical and Logical Fonts</a>
 133  * in <a href="https://docs.oracle.com/javase/tutorial/index.html">The Java Tutorials</a>
 134  * document.
 135  *
 136  * <h3>Font Faces and Names</h3>
 137  *
 138  * A {@code Font}
 139  * can have many faces, such as heavy, medium, oblique, gothic and
 140  * regular. All of these faces have similar typographic design.
 141  * <p>
 142  * There are three different names that you can get from a
 143  * {@code Font} object.  The <em>logical font name</em> is simply the
 144  * name that was used to construct the font.
 145  * The <em>font face name</em>, or just <em>font name</em> for
 146  * short, is the name of a particular font face, like Helvetica Bold. The
 147  * <em>family name</em> is the name of the font family that determines the
 148  * typographic design across several faces, like Helvetica.
 149  * <p>
 150  * The {@code Font} class represents an instance of a font face from
 151  * a collection of  font faces that are present in the system resources
 152  * of the host system.  As examples, Arial Bold and Courier Bold Italic
 153  * are font faces.  There can be several {@code Font} objects
 154  * associated with a font face, each differing in size, style, transform
 155  * and font features.
 156  * <p>
 157  * The {@link GraphicsEnvironment#getAllFonts() getAllFonts} method
 158  * of the {@code GraphicsEnvironment} class returns an
 159  * array of all font faces available in the system. These font faces are
 160  * returned as {@code Font} objects with a size of 1, identity
 161  * transform and default font features. These
 162  * base fonts can then be used to derive new {@code Font} objects
 163  * with varying sizes, styles, transforms and font features via the
 164  * {@code deriveFont} methods in this class.
 165  *
 166  * <h3>Font and TextAttribute</h3>
 167  *
 168  * <p>{@code Font} supports most
 169  * {@code TextAttribute}s.  This makes some operations, such as
 170  * rendering underlined text, convenient since it is not
 171  * necessary to explicitly construct a {@code TextLayout} object.
 172  * Attributes can be set on a Font by constructing or deriving it
 173  * using a {@code Map} of {@code TextAttribute} values.
 174  *
 175  * <p>The values of some {@code TextAttributes} are not
 176  * serializable, and therefore attempting to serialize an instance of
 177  * {@code Font} that has such values will not serialize them.
 178  * This means a Font deserialized from such a stream will not compare
 179  * equal to the original Font that contained the non-serializable
 180  * attributes.  This should very rarely pose a problem
 181  * since these attributes are typically used only in special
 182  * circumstances and are unlikely to be serialized.
 183  *
 184  * <ul>
 185  * <li>{@code FOREGROUND} and {@code BACKGROUND} use
 186  * {@code Paint} values. The subclass {@code Color} is
 187  * serializable, while {@code GradientPaint} and
 188  * {@code TexturePaint} are not.</li>
 189  * <li>{@code CHAR_REPLACEMENT} uses
 190  * {@code GraphicAttribute} values.  The subclasses
 191  * {@code ShapeGraphicAttribute} and
 192  * {@code ImageGraphicAttribute} are not serializable.</li>
 193  * <li>{@code INPUT_METHOD_HIGHLIGHT} uses
 194  * {@code InputMethodHighlight} values, which are
 195  * not serializable.  See {@link java.awt.im.InputMethodHighlight}.</li>
 196  * </ul>
 197  *
 198  * <p>Clients who create custom subclasses of {@code Paint} and
 199  * {@code GraphicAttribute} can make them serializable and
 200  * avoid this problem.  Clients who use input method highlights can
 201  * convert these to the platform-specific attributes for that
 202  * highlight on the current platform and set them on the Font as
 203  * a workaround.
 204  *
 205  * <p>The {@code Map}-based constructor and
 206  * {@code deriveFont} APIs ignore the FONT attribute, and it is
 207  * not retained by the Font; the static {@link #getFont} method should
 208  * be used if the FONT attribute might be present.  See {@link
 209  * java.awt.font.TextAttribute#FONT} for more information.</p>
 210  *
 211  * <p>Several attributes will cause additional rendering overhead
 212  * and potentially invoke layout.  If a {@code Font} has such
 213  * attributes, the <code>{@link #hasLayoutAttributes()}</code> method
 214  * will return true.</p>
 215  *
 216  * <p>Note: Font rotations can cause text baselines to be rotated.  In
 217  * order to account for this (rare) possibility, font APIs are
 218  * specified to return metrics and take parameters 'in
 219  * baseline-relative coordinates'.  This maps the 'x' coordinate to
 220  * the advance along the baseline, (positive x is forward along the
 221  * baseline), and the 'y' coordinate to a distance along the
 222  * perpendicular to the baseline at 'x' (positive y is 90 degrees
 223  * clockwise from the baseline vector).  APIs for which this is
 224  * especially important are called out as having 'baseline-relative
 225  * coordinates.'
 226  */
 227 public class Font implements java.io.Serializable
 228 {
 229     private static class FontAccessImpl extends FontAccess {
 230         public Font2D getFont2D(Font font) {
 231             return font.getFont2D();
 232         }


 353      * Used to specify a TrueType font resource to the
 354      * {@link #createFont} method.
 355      * The TrueType format was extended to become the OpenType
 356      * format, which adds support for fonts with Postscript outlines,
 357      * this tag therefore references these fonts, as well as those
 358      * with TrueType outlines.
 359      * @since 1.3
 360      */
 361 
 362     public static final int TRUETYPE_FONT = 0;
 363 
 364     /**
 365      * Identify a font resource of type TYPE1.
 366      * Used to specify a Type1 font resource to the
 367      * {@link #createFont} method.
 368      * @since 1.5
 369      */
 370     public static final int TYPE1_FONT = 1;
 371 
 372     /**
 373      * The logical name of this {@code Font}, as passed to the
 374      * constructor.
 375      * @since 1.0
 376      *
 377      * @serial
 378      * @see #getName
 379      */
 380     protected String name;
 381 
 382     /**
 383      * The style of this {@code Font}, as passed to the constructor.
 384      * This style can be PLAIN, BOLD, ITALIC, or BOLD+ITALIC.
 385      * @since 1.0
 386      *
 387      * @serial
 388      * @see #getStyle()
 389      */
 390     protected int style;
 391 
 392     /**
 393      * The point size of this {@code Font}, rounded to integer.
 394      * @since 1.0
 395      *
 396      * @serial
 397      * @see #getSize()
 398      */
 399     protected int size;
 400 
 401     /**
 402      * The point size of this {@code Font} in {@code float}.
 403      *
 404      * @serial
 405      * @see #getSize()
 406      * @see #getSize2D()
 407      */
 408     protected float pointSize;
 409 
 410     /**
 411      * The platform specific font information.
 412      */
 413     private transient FontPeer peer;
 414     private transient long pData;       // native JDK1.1 font pointer
 415     private transient Font2DHandle font2DHandle;
 416 
 417     private transient AttributeValues values;
 418     private transient boolean hasLayoutAttributes;
 419 
 420     /*
 421      * If the origin of a Font is a created font then this attribute
 422      * must be set on all derived fonts too.


 491         FontManager fm = FontManagerFactory.getInstance();
 492         if (fm.usingPerAppContextComposites() &&
 493             font2DHandle != null &&
 494             font2DHandle.font2D instanceof CompositeFont &&
 495             ((CompositeFont)(font2DHandle.font2D)).isStdComposite()) {
 496             return fm.findFont2D(name, style,
 497                                           FontManager.LOGICAL_FALLBACK);
 498         } else if (font2DHandle == null) {
 499             font2DHandle =
 500                 fm.findFont2D(name, style,
 501                               FontManager.LOGICAL_FALLBACK).handle;
 502         }
 503         /* Do not cache the de-referenced font2D. It must be explicitly
 504          * de-referenced to pick up a valid font in the event that the
 505          * original one is marked invalid
 506          */
 507         return font2DHandle.font2D;
 508     }
 509 
 510     /**
 511      * Creates a new {@code Font} from the specified name, style and
 512      * point size.
 513      * <p>
 514      * The font name can be a font face name or a font family name.
 515      * It is used together with the style to find an appropriate font face.
 516      * When a font family name is specified, the style argument is used to
 517      * select the most appropriate face from the family. When a font face
 518      * name is specified, the face's style and the style argument are
 519      * merged to locate the best matching font from the same family.
 520      * For example if face name "Arial Bold" is specified with style
 521      * {@code Font.ITALIC}, the font system looks for a face in the
 522      * "Arial" family that is bold and italic, and may associate the font
 523      * instance with the physical font face "Arial Bold Italic".
 524      * The style argument is merged with the specified face's style, not
 525      * added or subtracted.
 526      * This means, specifying a bold face and a bold style does not
 527      * double-embolden the font, and specifying a bold face and a plain
 528      * style does not lighten the font.
 529      * <p>
 530      * If no face for the requested style can be found, the font system
 531      * may apply algorithmic styling to achieve the desired style.
 532      * For example, if {@code ITALIC} is requested, but no italic
 533      * face is available, glyphs from the plain face may be algorithmically
 534      * obliqued (slanted).
 535      * <p>
 536      * Font name lookup is case insensitive, using the case folding
 537      * rules of the US locale.
 538      * <p>
 539      * If the {@code name} parameter represents something other than a
 540      * logical font, i.e. is interpreted as a physical font face or family, and
 541      * this cannot be mapped by the implementation to a physical font or a
 542      * compatible alternative, then the font system will map the Font
 543      * instance to "Dialog", such that for example, the family as reported
 544      * by {@link #getFamily() getFamily} will be "Dialog".
 545      *
 546      * @param name the font name.  This can be a font face name or a font
 547      * family name, and may represent either a logical font or a physical
 548      * font found in this {@code GraphicsEnvironment}.
 549      * The family names for logical fonts are: Dialog, DialogInput,
 550      * Monospaced, Serif, or SansSerif. Pre-defined String constants exist
 551      * for all of these names, for example, {@code DIALOG}. If {@code name} is
 552      * {@code null}, the <em>logical font name</em> of the new
 553      * {@code Font} as returned by {@code getName()} is set to
 554      * the name "Default".
 555      * @param style the style constant for the {@code Font}
 556      * The style argument is an integer bitmask that may
 557      * be {@code PLAIN}, or a bitwise union of {@code BOLD} and/or
 558      * {@code ITALIC} (for example, {@code ITALIC} or {@code BOLD|ITALIC}).
 559      * If the style argument does not conform to one of the expected


 660             } else {
 661                 if (values.getWeight() >= 2f)   newStyle  = BOLD;
 662                 if (values.getPosture() >= .2f) newStyle |= ITALIC;
 663                 if (oldStyle == newStyle)       newStyle  = -1;
 664             }
 665             if (handle.font2D instanceof CompositeFont) {
 666                 if (newStyle != -1 || newName != null) {
 667                     FontManager fm = FontManagerFactory.getInstance();
 668                     this.font2DHandle =
 669                         fm.getNewComposite(newName, newStyle, handle);
 670                 }
 671             } else if (newName != null) {
 672                 this.createdFont = false;
 673                 this.font2DHandle = null;
 674             }
 675         }
 676         initFromValues(values);
 677     }
 678 
 679     /**
 680      * Creates a new {@code Font} with the specified attributes.
 681      * Only keys defined in {@link java.awt.font.TextAttribute TextAttribute}
 682      * are recognized.  In addition the FONT attribute is
 683      *  not recognized by this constructor
 684      * (see {@link #getAvailableAttributes}). Only attributes that have
 685      * values of valid types will affect the new {@code Font}.
 686      * <p>
 687      * If {@code attributes} is {@code null}, a new
 688      * {@code Font} is initialized with default values.
 689      * @see java.awt.font.TextAttribute
 690      * @param attributes the attributes to assign to the new
 691      *          {@code Font}, or {@code null}
 692      */
 693     public Font(Map<? extends Attribute, ?> attributes) {
 694         initFromValues(AttributeValues.fromMap(attributes, RECOGNIZED_MASK));
 695     }
 696 
 697     /**
 698      * Creates a new {@code Font} from the specified {@code font}.
 699      * This constructor is intended for use by subclasses.
 700      * @param font from which to create this {@code Font}.
 701      * @throws NullPointerException if {@code font} is null
 702      * @since 1.6
 703      */
 704     protected Font(Font font) {
 705         if (font.values != null) {
 706             initFromValues(font.getAttributeValues().clone());
 707         } else {
 708             this.name = font.name;
 709             this.style = font.style;
 710             this.size = font.size;
 711             this.pointSize = font.pointSize;
 712         }
 713         this.font2DHandle = font.font2DHandle;
 714         this.createdFont = font.createdFont;
 715     }
 716 
 717     /**
 718      * Font recognizes all attributes except FONT.
 719      */
 720     private static final int RECOGNIZED_MASK = AttributeValues.MASK_ALL
 721         & ~AttributeValues.getMask(EFONT);


 748             AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH);
 749 
 750     /**
 751      * Initialize the standard Font fields from the values object.
 752      */
 753     private void initFromValues(AttributeValues values) {
 754         this.values = values;
 755         values.defineAll(PRIMARY_MASK); // for 1.5 streaming compatibility
 756 
 757         this.name = values.getFamily();
 758         this.pointSize = values.getSize();
 759         this.size = (int)(values.getSize() + 0.5);
 760         if (values.getWeight() >= 2f) this.style |= BOLD; // not == 2f
 761         if (values.getPosture() >= .2f) this.style |= ITALIC; // not  == .2f
 762 
 763         this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
 764         this.hasLayoutAttributes =  values.anyNonDefault(LAYOUT_MASK);
 765     }
 766 
 767     /**
 768      * Returns a {@code Font} appropriate to the attributes.
 769      * If {@code attributes} contains a {@code FONT} attribute
 770      * with a valid {@code Font} as its value, it will be
 771      * merged with any remaining attributes.  See
 772      * {@link java.awt.font.TextAttribute#FONT} for more
 773      * information.
 774      *
 775      * @param attributes the attributes to assign to the new
 776      *          {@code Font}
 777      * @return a new {@code Font} created with the specified
 778      *          attributes
 779      * @throws NullPointerException if {@code attributes} is null.
 780      * @since 1.2
 781      * @see java.awt.font.TextAttribute
 782      */
 783     public static Font getFont(Map<? extends Attribute, ?> attributes) {
 784         // optimize for two cases:
 785         // 1) FONT attribute, and nothing else
 786         // 2) attributes, but no FONT
 787 
 788         // avoid turning the attributemap into a regular map for no reason
 789         if (attributes instanceof AttributeMap &&
 790             ((AttributeMap)attributes).getValues() != null) {
 791             AttributeValues values = ((AttributeMap)attributes).getValues();
 792             if (values.isNonDefault(EFONT)) {
 793                 Font font = values.getFont();
 794                 if (!values.anyDefined(SECONDARY_MASK)) {
 795                     return font;
 796                 }
 797                 // merge
 798                 values = font.getAttributeValues().clone();
 799                 values.merge(attributes, SECONDARY_MASK);


 825      */
 826     private static boolean hasTempPermission() {
 827 
 828         if (System.getSecurityManager() == null) {
 829             return true;
 830         }
 831         File f = null;
 832         boolean hasPerm = false;
 833         try {
 834             f = Files.createTempFile("+~JT", ".tmp").toFile();
 835             f.delete();
 836             f = null;
 837             hasPerm = true;
 838         } catch (Throwable t) {
 839             /* inc. any kind of SecurityException */
 840         }
 841         return hasPerm;
 842     }
 843 
 844     /**
 845      * Returns a new {@code Font} using the specified font type
 846      * and input data.  The new {@code Font} is
 847      * created with a point size of 1 and style {@link #PLAIN PLAIN}.
 848      * This base font can then be used with the {@code deriveFont}
 849      * methods in this class to derive new {@code Font} objects with
 850      * varying sizes, styles, transforms and font features.  This
 851      * method does not close the {@link InputStream}.
 852      * <p>
 853      * To make the {@code Font} available to Font constructors the
 854      * returned {@code Font} must be registered in the
 855      * {@code GraphicsEnvironment} by calling
 856      * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
 857      * @param fontFormat the type of the {@code Font}, which is
 858      * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is specified.
 859      * or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is specified.
 860      * @param fontStream an {@code InputStream} object representing the
 861      * input data for the font.
 862      * @return a new {@code Font} created with the specified font type.
 863      * @throws IllegalArgumentException if {@code fontFormat} is not
 864      *     {@code TRUETYPE_FONT} or {@code TYPE1_FONT}.
 865      * @throws FontFormatException if the {@code fontStream} data does
 866      *     not contain the required font tables for the specified format.
 867      * @throws IOException if the {@code fontStream}
 868      *     cannot be completely read.
 869      * @see GraphicsEnvironment#registerFont(Font)
 870      * @since 1.3
 871      */
 872     public static Font createFont(int fontFormat, InputStream fontStream)
 873         throws java.awt.FontFormatException, java.io.IOException {
 874 
 875         if (hasTempPermission()) {
 876             return createFont0(fontFormat, fontStream, null);
 877         }
 878 
 879         // Otherwise, be extra conscious of pending temp file creation and
 880         // resourcefully handle the temp file resources, among other things.
 881         CreatedFontTracker tracker = CreatedFontTracker.getTracker();
 882         boolean acquired = false;
 883         try {
 884             acquired = tracker.acquirePermit();
 885             if (!acquired) {
 886                 throw new IOException("Timed out waiting for resources.");
 887             }


 984                         }
 985                     );
 986                 }
 987             }
 988         } catch (Throwable t) {
 989             if (t instanceof FontFormatException) {
 990                 throw (FontFormatException)t;
 991             }
 992             if (t instanceof IOException) {
 993                 throw (IOException)t;
 994             }
 995             Throwable cause = t.getCause();
 996             if (cause instanceof FontFormatException) {
 997                 throw (FontFormatException)cause;
 998             }
 999             throw new IOException("Problem reading font data.");
1000         }
1001     }
1002 
1003     /**
1004      * Returns a new {@code Font} using the specified font type
1005      * and the specified font file.  The new {@code Font} is
1006      * created with a point size of 1 and style {@link #PLAIN PLAIN}.
1007      * This base font can then be used with the {@code deriveFont}
1008      * methods in this class to derive new {@code Font} objects with
1009      * varying sizes, styles, transforms and font features.
1010      * @param fontFormat the type of the {@code Font}, which is
1011      * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is
1012      * specified or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is
1013      * specified.
1014      * So long as the returned font, or its derived fonts are referenced
1015      * the implementation may continue to access {@code fontFile}
1016      * to retrieve font data. Thus the results are undefined if the file
1017      * is changed, or becomes inaccessible.
1018      * <p>
1019      * To make the {@code Font} available to Font constructors the
1020      * returned {@code Font} must be registered in the
1021      * {@code GraphicsEnvironment} by calling
1022      * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
1023      * @param fontFile a {@code File} object representing the
1024      * input data for the font.
1025      * @return a new {@code Font} created with the specified font type.
1026      * @throws IllegalArgumentException if {@code fontFormat} is not
1027      *     {@code TRUETYPE_FONT} or {@code TYPE1_FONT}.
1028      * @throws NullPointerException if {@code fontFile} is null.
1029      * @throws IOException if the {@code fontFile} cannot be read.
1030      * @throws FontFormatException if {@code fontFile} does
1031      *     not contain the required font tables for the specified format.
1032      * @throws SecurityException if the executing code does not have
1033      * permission to read from the file.
1034      * @see GraphicsEnvironment#registerFont(Font)
1035      * @since 1.5
1036      */
1037     public static Font createFont(int fontFormat, File fontFile)
1038         throws java.awt.FontFormatException, java.io.IOException {
1039 
1040         fontFile = new File(fontFile.getPath());
1041 
1042         if (fontFormat != Font.TRUETYPE_FONT &&
1043             fontFormat != Font.TYPE1_FONT) {
1044             throw new IllegalArgumentException ("font format not recognized");
1045         }
1046         SecurityManager sm = System.getSecurityManager();
1047         if (sm != null) {
1048             FilePermission filePermission =
1049                 new FilePermission(fontFile.getPath(), "read");
1050             sm.checkPermission(filePermission);
1051         }
1052         if (!fontFile.canRead()) {
1053             throw new IOException("Can't read " + fontFile);
1054         }
1055         return new Font(fontFile, fontFormat, false, null);
1056     }
1057 
1058     /**
1059      * Returns a copy of the transform associated with this
1060      * {@code Font}.  This transform is not necessarily the one
1061      * used to construct the font.  If the font has algorithmic
1062      * superscripting or width adjustment, this will be incorporated
1063      * into the returned {@code AffineTransform}.
1064      * <p>
1065      * Typically, fonts will not be transformed.  Clients generally
1066      * should call {@link #isTransformed} first, and only call this
1067      * method if {@code isTransformed} returns true.
1068      *
1069      * @return an {@link AffineTransform} object representing the
1070      *          transform attribute of this {@code Font} object.
1071      */
1072     public AffineTransform getTransform() {
1073         /* The most common case is the identity transform.  Most callers
1074          * should call isTransformed() first, to decide if they need to
1075          * get the transform, but some may not.  Here we check to see
1076          * if we have a nonidentity transform, and only do the work to
1077          * fetch and/or compute it if so, otherwise we return a new
1078          * identity transform.
1079          *
1080          * Note that the transform is _not_ necessarily the same as
1081          * the transform passed in as an Attribute in a Map, as the
1082          * transform returned will also reflect the effects of WIDTH and
1083          * SUPERSCRIPT attributes.  Clients who want the actual transform
1084          * need to call getRequestedAttributes.
1085          */
1086         if (nonIdentityTx) {
1087             AttributeValues values = getAttributeValues();
1088 
1089             AffineTransform at = values.isNonDefault(ETRANSFORM)
1090                 ? new AffineTransform(values.getTransform())


1146     // x (1 - r) = r^0 - r^(n+1)
1147     // x = (r^0 - r^(n+1)) / (1 - r)
1148     // x = (1 - r^(n+1)) / (1 - r)
1149 
1150     // scale ratio is 2/3
1151     // trans = 1/2 of ascent * x
1152     // assume ascent is 3/4 of point size
1153 
1154     private static final float[] ssinfo = {
1155         0.0f,
1156         0.375f,
1157         0.625f,
1158         0.7916667f,
1159         0.9027778f,
1160         0.9768519f,
1161         1.0262346f,
1162         1.0591564f,
1163     };
1164 
1165     /**
1166      * Returns the family name of this {@code Font}.
1167      *
1168      * <p>The family name of a font is font specific. Two fonts such as
1169      * Helvetica Italic and Helvetica Bold have the same family name,
1170      * <i>Helvetica</i>, whereas their font face names are
1171      * <i>Helvetica Bold</i> and <i>Helvetica Italic</i>. The list of
1172      * available family names may be obtained by using the
1173      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1174      *
1175      * <p>Use {@code getName} to get the logical name of the font.
1176      * Use {@code getFontName} to get the font face name of the font.
1177      * @return a {@code String} that is the family name of this
1178      *          {@code Font}.
1179      *
1180      * @see #getName
1181      * @see #getFontName
1182      * @since 1.1
1183      */
1184     public String getFamily() {
1185         return getFamily_NoClientCode();
1186     }
1187     // NOTE: This method is called by privileged threads.
1188     //       We implement this functionality in a package-private
1189     //       method to insure that it cannot be overridden by client
1190     //       subclasses.
1191     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1192     final String getFamily_NoClientCode() {
1193         return getFamily(Locale.getDefault());
1194     }
1195 
1196     /**
1197      * Returns the family name of this {@code Font}, localized for
1198      * the specified locale.
1199      *
1200      * <p>The family name of a font is font specific. Two fonts such as
1201      * Helvetica Italic and Helvetica Bold have the same family name,
1202      * <i>Helvetica</i>, whereas their font face names are
1203      * <i>Helvetica Bold</i> and <i>Helvetica Italic</i>. The list of
1204      * available family names may be obtained by using the
1205      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1206      *
1207      * <p>Use {@code getFontName} to get the font face name of the font.
1208      * @param l locale for which to get the family name
1209      * @return a {@code String} representing the family name of the
1210      *          font, localized for the specified locale.
1211      * @see #getFontName
1212      * @see java.util.Locale
1213      * @since 1.2
1214      */
1215     public String getFamily(Locale l) {
1216         if (l == null) {
1217             throw new NullPointerException("null locale doesn't mean default");
1218         }
1219         return getFont2D().getFamilyName(l);
1220     }
1221 
1222     /**
1223      * Returns the postscript name of this {@code Font}.
1224      * Use {@code getFamily} to get the family name of the font.
1225      * Use {@code getFontName} to get the font face name of the font.
1226      * @return a {@code String} representing the postscript name of
1227      *          this {@code Font}.
1228      * @since 1.2
1229      */
1230     public String getPSName() {
1231         return getFont2D().getPostscriptName();
1232     }
1233 
1234     /**
1235      * Returns the logical name of this {@code Font}.
1236      * Use {@code getFamily} to get the family name of the font.
1237      * Use {@code getFontName} to get the font face name of the font.
1238      * @return a {@code String} representing the logical name of
1239      *          this {@code Font}.
1240      * @see #getFamily
1241      * @see #getFontName
1242      * @since 1.0
1243      */
1244     public String getName() {
1245         return name;
1246     }
1247 
1248     /**
1249      * Returns the font face name of this {@code Font}.  For example,
1250      * Helvetica Bold could be returned as a font face name.
1251      * Use {@code getFamily} to get the family name of the font.
1252      * Use {@code getName} to get the logical name of the font.
1253      * @return a {@code String} representing the font face name of
1254      *          this {@code Font}.
1255      * @see #getFamily
1256      * @see #getName
1257      * @since 1.2
1258      */
1259     public String getFontName() {
1260       return getFontName(Locale.getDefault());
1261     }
1262 
1263     /**
1264      * Returns the font face name of the {@code Font}, localized
1265      * for the specified locale. For example, Helvetica Fett could be
1266      * returned as the font face name.
1267      * Use {@code getFamily} to get the family name of the font.
1268      * @param l a locale for which to get the font face name
1269      * @return a {@code String} representing the font face name,
1270      *          localized for the specified locale.
1271      * @see #getFamily
1272      * @see java.util.Locale
1273      */
1274     public String getFontName(Locale l) {
1275         if (l == null) {
1276             throw new NullPointerException("null locale doesn't mean default");
1277         }
1278         return getFont2D().getFontName(l);
1279     }
1280 
1281     /**
1282      * Returns the style of this {@code Font}.  The style can be
1283      * PLAIN, BOLD, ITALIC, or BOLD+ITALIC.
1284      * @return the style of this {@code Font}
1285      * @see #isPlain
1286      * @see #isBold
1287      * @see #isItalic
1288      * @since 1.0
1289      */
1290     public int getStyle() {
1291         return style;
1292     }
1293 
1294     /**
1295      * Returns the point size of this {@code Font}, rounded to
1296      * an integer.
1297      * Most users are familiar with the idea of using <i>point size</i> to
1298      * specify the size of glyphs in a font. This point size defines a
1299      * measurement between the baseline of one line to the baseline of the
1300      * following line in a single spaced text document. The point size is
1301      * based on <i>typographic points</i>, approximately 1/72 of an inch.
1302      * <p>
1303      * The Java(tm)2D API adopts the convention that one point is
1304      * equivalent to one unit in user coordinates.  When using a
1305      * normalized transform for converting user space coordinates to
1306      * device space coordinates 72 user
1307      * space units equal 1 inch in device space.  In this case one point
1308      * is 1/72 of an inch.
1309      * @return the point size of this {@code Font} in 1/72 of an
1310      *          inch units.
1311      * @see #getSize2D
1312      * @see GraphicsConfiguration#getDefaultTransform
1313      * @see GraphicsConfiguration#getNormalizingTransform
1314      * @since 1.0
1315      */
1316     public int getSize() {
1317         return size;
1318     }
1319 
1320     /**
1321      * Returns the point size of this {@code Font} in
1322      * {@code float} value.
1323      * @return the point size of this {@code Font} as a
1324      * {@code float} value.
1325      * @see #getSize
1326      * @since 1.2
1327      */
1328     public float getSize2D() {
1329         return pointSize;
1330     }
1331 
1332     /**
1333      * Indicates whether or not this {@code Font} object's style is
1334      * PLAIN.
1335      * @return    {@code true} if this {@code Font} has a
1336      *            PLAIN style;
1337      *            {@code false} otherwise.
1338      * @see       java.awt.Font#getStyle
1339      * @since     1.0
1340      */
1341     public boolean isPlain() {
1342         return style == 0;
1343     }
1344 
1345     /**
1346      * Indicates whether or not this {@code Font} object's style is
1347      * BOLD.
1348      * @return    {@code true} if this {@code Font} object's
1349      *            style is BOLD;
1350      *            {@code false} otherwise.
1351      * @see       java.awt.Font#getStyle
1352      * @since     1.0
1353      */
1354     public boolean isBold() {
1355         return (style & BOLD) != 0;
1356     }
1357 
1358     /**
1359      * Indicates whether or not this {@code Font} object's style is
1360      * ITALIC.
1361      * @return    {@code true} if this {@code Font} object's
1362      *            style is ITALIC;
1363      *            {@code false} otherwise.
1364      * @see       java.awt.Font#getStyle
1365      * @since     1.0
1366      */
1367     public boolean isItalic() {
1368         return (style & ITALIC) != 0;
1369     }
1370 
1371     /**
1372      * Indicates whether or not this {@code Font} object has a
1373      * transform that affects its size in addition to the Size
1374      * attribute.
1375      * @return  {@code true} if this {@code Font} object
1376      *          has a non-identity AffineTransform attribute.
1377      *          {@code false} otherwise.
1378      * @see     java.awt.Font#getTransform
1379      * @since   1.4
1380      */
1381     public boolean isTransformed() {
1382         return nonIdentityTx;
1383     }
1384 
1385     /**
1386      * Return true if this Font contains attributes that require extra
1387      * layout processing.
1388      * @return true if the font has layout attributes
1389      * @since 1.6
1390      */
1391     public boolean hasLayoutAttributes() {
1392         return hasLayoutAttributes;
1393     }
1394 
1395     /**
1396      * Returns a {@code Font} object from the system properties list.
1397      * {@code nm} is treated as the name of a system property to be
1398      * obtained.  The {@code String} value of this property is then
1399      * interpreted as a {@code Font} object according to the
1400      * specification of {@code Font.decode(String)}
1401      * If the specified property is not found, or the executing code does
1402      * not have permission to read the property, null is returned instead.
1403      *
1404      * @param nm the property name
1405      * @return a {@code Font} object that the property name
1406      *          describes, or null if no such property exists.
1407      * @throws NullPointerException if nm is null.
1408      * @since 1.2
1409      * @see #decode(String)
1410      */
1411     public static Font getFont(String nm) {
1412         return getFont(nm, null);
1413     }
1414 
1415     /**
1416      * Returns the {@code Font} that the {@code str}
1417      * argument describes.
1418      * To ensure that this method returns the desired Font,
1419      * format the {@code str} parameter in
1420      * one of these ways
1421      *
1422      * <ul>
1423      * <li><em>fontname-style-pointsize</em>
1424      * <li><em>fontname-pointsize</em>
1425      * <li><em>fontname-style</em>
1426      * <li><em>fontname</em>
1427      * <li><em>fontname style pointsize</em>
1428      * <li><em>fontname pointsize</em>
1429      * <li><em>fontname style</em>
1430      * <li><em>fontname</em>
1431      * </ul>
1432      * in which <i>style</i> is one of the four
1433      * case-insensitive strings:
1434      * {@code "PLAIN"}, {@code "BOLD"}, {@code "BOLDITALIC"}, or
1435      * {@code "ITALIC"}, and pointsize is a positive decimal integer
1436      * representation of the point size.
1437      * For example, if you want a font that is Arial, bold, with
1438      * a point size of 18, you would call this method with:
1439      * "Arial-BOLD-18".
1440      * This is equivalent to calling the Font constructor :
1441      * {@code new Font("Arial", Font.BOLD, 18);}
1442      * and the values are interpreted as specified by that constructor.
1443      * <p>
1444      * A valid trailing decimal field is always interpreted as the pointsize.
1445      * Therefore a fontname containing a trailing decimal value should not
1446      * be used in the fontname only form.
1447      * <p>
1448      * If a style name field is not one of the valid style strings, it is
1449      * interpreted as part of the font name, and the default style is used.
1450      * <p>
1451      * Only one of ' ' or '-' may be used to separate fields in the input.
1452      * The identified separator is the one closest to the end of the string
1453      * which separates a valid pointsize, or a valid style name from
1454      * the rest of the string.
1455      * Null (empty) pointsize and style fields are treated
1456      * as valid fields with the default value for that field.
1457      *<p>
1458      * Some font names may include the separator characters ' ' or '-'.
1459      * If {@code str} is not formed with 3 components, e.g. such that
1460      * {@code style} or {@code pointsize} fields are not present in
1461      * {@code str}, and {@code fontname} also contains a
1462      * character determined to be the separator character
1463      * then these characters where they appear as intended to be part of
1464      * {@code fontname} may instead be interpreted as separators
1465      * so the font name may not be properly recognised.
1466      *
1467      * <p>
1468      * The default size is 12 and the default style is PLAIN.
1469      * If {@code str} does not specify a valid size, the returned
1470      * {@code Font} has a size of 12.  If {@code str} does not
1471      * specify a valid style, the returned Font has a style of PLAIN.
1472      * If you do not specify a valid font name in
1473      * the {@code str} argument, this method will return
1474      * a font with the family name "Dialog".
1475      * To determine what font family names are available on
1476      * your system, use the
1477      * {@link GraphicsEnvironment#getAvailableFontFamilyNames()} method.
1478      * If {@code str} is {@code null}, a new {@code Font}
1479      * is returned with the family name "Dialog", a size of 12 and a
1480      * PLAIN style.
1481      * @param str the name of the font, or {@code null}
1482      * @return the {@code Font} object that {@code str}
1483      *          describes, or a new default {@code Font} if
1484      *          {@code str} is {@code null}.
1485      * @see #getFamily
1486      * @since 1.1
1487      */
1488     public static Font decode(String str) {
1489         String fontName = str;
1490         String styleName = "";
1491         int fontSize = 12;
1492         int fontStyle = Font.PLAIN;
1493 
1494         if (str == null) {
1495             return new Font(DIALOG, fontStyle, fontSize);
1496         }
1497 
1498         int lastHyphen = str.lastIndexOf('-');
1499         int lastSpace = str.lastIndexOf(' ');
1500         char sepChar = (lastHyphen > lastSpace) ? '-' : ' ';
1501         int sizeIndex = str.lastIndexOf(sepChar);
1502         int styleIndex = str.lastIndexOf(sepChar, sizeIndex-1);
1503         int strlen = str.length();
1504 


1542             }
1543             fontName = str.substring(0, styleIndex);
1544 
1545         } else {
1546             int fontEnd = strlen;
1547             if (styleIndex > 0) {
1548                 fontEnd = styleIndex;
1549             } else if (sizeIndex > 0) {
1550                 fontEnd = sizeIndex;
1551             }
1552             if (fontEnd > 0 && str.charAt(fontEnd-1) == sepChar) {
1553                 fontEnd--;
1554             }
1555             fontName = str.substring(0, fontEnd);
1556         }
1557 
1558         return new Font(fontName, fontStyle, fontSize);
1559     }
1560 
1561     /**
1562      * Gets the specified {@code Font} from the system properties
1563      * list.  As in the {@code getProperty} method of
1564      * {@code System}, the first
1565      * argument is treated as the name of a system property to be
1566      * obtained.  The {@code String} value of this property is then
1567      * interpreted as a {@code Font} object.
1568      * <p>
1569      * The property value should be one of the forms accepted by
1570      * {@code Font.decode(String)}
1571      * If the specified property is not found, or the executing code does not
1572      * have permission to read the property, the {@code font}
1573      * argument is returned instead.
1574      * @param nm the case-insensitive property name
1575      * @param font a default {@code Font} to return if property
1576      *          {@code nm} is not defined
1577      * @return    the {@code Font} value of the property.
1578      * @throws NullPointerException if nm is null.
1579      * @see #decode(String)
1580      */
1581     public static Font getFont(String nm, Font font) {
1582         String str = null;
1583         try {
1584             str =System.getProperty(nm);
1585         } catch(SecurityException e) {
1586         }
1587         if (str == null) {
1588             return font;
1589         }
1590         return decode ( str );
1591     }
1592 
1593     transient int hash;
1594     /**
1595      * Returns a hashcode for this {@code Font}.
1596      * @return     a hashcode value for this {@code Font}.
1597      * @since      1.0
1598      */
1599     public int hashCode() {
1600         if (hash == 0) {
1601             hash = name.hashCode() ^ style ^ size;
1602             /* It is possible many fonts differ only in transform.
1603              * So include the transform in the hash calculation.
1604              * nonIdentityTx is set whenever there is a transform in
1605              * 'values'. The tests for null are required because it can
1606              * also be set for other reasons.
1607              */
1608             if (nonIdentityTx &&
1609                 values != null && values.getTransform() != null) {
1610                 hash ^= values.getTransform().hashCode();
1611             }
1612         }
1613         return hash;
1614     }
1615 
1616     /**
1617      * Compares this {@code Font} object to the specified
1618      * {@code Object}.
1619      * @param obj the {@code Object} to compare
1620      * @return {@code true} if the objects are the same
1621      *          or if the argument is a {@code Font} object
1622      *          describing the same font as this object;
1623      *          {@code false} otherwise.
1624      * @since 1.0
1625      */
1626     public boolean equals(Object obj) {
1627         if (obj == this) {
1628             return true;
1629         }
1630 
1631         if (obj != null) {
1632             try {
1633                 Font font = (Font)obj;
1634                 if (size == font.size &&
1635                     style == font.style &&
1636                     nonIdentityTx == font.nonIdentityTx &&
1637                     hasLayoutAttributes == font.hasLayoutAttributes &&
1638                     pointSize == font.pointSize &&
1639                     name.equals(font.name)) {
1640 
1641                     /* 'values' is usually initialized lazily, except when
1642                      * the font is constructed from a Map, or derived using
1643                      * a Map or other values. So if only one font has


1645                      * the other instance and compare.
1646                      */
1647                     if (values == null) {
1648                         if (font.values == null) {
1649                             return true;
1650                         } else {
1651                             return getAttributeValues().equals(font.values);
1652                         }
1653                     } else {
1654                         return values.equals(font.getAttributeValues());
1655                     }
1656                 }
1657             }
1658             catch (ClassCastException e) {
1659             }
1660         }
1661         return false;
1662     }
1663 
1664     /**
1665      * Converts this {@code Font} object to a {@code String}
1666      * representation.
1667      * @return     a {@code String} representation of this
1668      *          {@code Font} object.
1669      * @since      1.0
1670      */
1671     // NOTE: This method may be called by privileged threads.
1672     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1673     public String toString() {
1674         String  strStyle;
1675 
1676         if (isBold()) {
1677             strStyle = isItalic() ? "bolditalic" : "bold";
1678         } else {
1679             strStyle = isItalic() ? "italic" : "plain";
1680         }
1681 
1682         return getClass().getName() + "[family=" + getFamily() + ",name=" + name + ",style=" +
1683             strStyle + ",size=" + size + "]";
1684     } // toString()
1685 
1686 
1687     /** Serialization support.  A {@code readObject}
1688      *  method is necessary because the constructor creates
1689      *  the font's peer, and we can't serialize the peer.
1690      *  Similarly the computed font "family" may be different
1691      *  at {@code readObject} time than at
1692      *  {@code writeObject} time.  An integer version is
1693      *  written so that future versions of this class will be
1694      *  able to recognize serialized output from this one.
1695      */
1696     /**
1697      * The {@code Font} Serializable Data Form.
1698      *
1699      * @serial
1700      */
1701     private int fontSerializedDataVersion = 1;
1702 
1703     /**
1704      * Writes default serializable fields to a stream.
1705      *
1706      * @param s the {@code ObjectOutputStream} to write
1707      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1708      * @see #readObject(java.io.ObjectInputStream)
1709      */
1710     private void writeObject(java.io.ObjectOutputStream s)
1711       throws java.lang.ClassNotFoundException,
1712              java.io.IOException
1713     {
1714         if (values != null) {
1715           synchronized(values) {
1716             // transient
1717             fRequestedAttributes = values.toSerializableHashtable();
1718             s.defaultWriteObject();
1719             fRequestedAttributes = null;
1720           }
1721         } else {
1722           s.defaultWriteObject();
1723         }
1724     }
1725 
1726     /**
1727      * Reads the {@code ObjectInputStream}.
1728      * Unrecognized keys or values will be ignored.
1729      *
1730      * @param s the {@code ObjectInputStream} to read
1731      * @serial
1732      * @see #writeObject(java.io.ObjectOutputStream)
1733      */
1734     private void readObject(java.io.ObjectInputStream s)
1735       throws java.lang.ClassNotFoundException,
1736              java.io.IOException
1737     {
1738         s.defaultReadObject();
1739         if (pointSize == 0) {
1740             pointSize = (float)size;
1741         }
1742 
1743         // Handle fRequestedAttributes.
1744         // in 1.5, we always streamed out the font values plus
1745         // TRANSFORM, SUPERSCRIPT, and WIDTH, regardless of whether the
1746         // values were default or not.  In 1.6 we only stream out
1747         // defined values.  So, 1.6 streams in from a 1.5 stream,
1748         // it check each of these values and 'undefines' it if the
1749         // value is the default.
1750 
1751         if (fRequestedAttributes != null) {
1752             values = getAttributeValues(); // init
1753             AttributeValues extras =
1754                 AttributeValues.fromSerializableHashtable(fRequestedAttributes);
1755             if (!AttributeValues.is16Hashtable(fRequestedAttributes)) {
1756                 extras.unsetDefault(); // if legacy stream, undefine these
1757             }
1758             values = getAttributeValues().merge(extras);
1759             this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
1760             this.hasLayoutAttributes =  values.anyNonDefault(LAYOUT_MASK);
1761 
1762             fRequestedAttributes = null; // don't need it any more
1763         }
1764     }
1765 
1766     /**
1767      * Returns the number of glyphs in this {@code Font}. Glyph codes
1768      * for this {@code Font} range from 0 to
1769      * {@code getNumGlyphs()} - 1.
1770      * @return the number of glyphs in this {@code Font}.
1771      * @since 1.2
1772      */
1773     public int getNumGlyphs() {
1774         return  getFont2D().getNumGlyphs();
1775     }
1776 
1777     /**
1778      * Returns the glyphCode which is used when this {@code Font}
1779      * does not have a glyph for a specified unicode code point.
1780      * @return the glyphCode of this {@code Font}.
1781      * @since 1.2
1782      */
1783     public int getMissingGlyphCode() {
1784         return getFont2D().getMissingGlyphCode();
1785     }
1786 
1787     /**
1788      * Returns the baseline appropriate for displaying this character.
1789      * <p>
1790      * Large fonts can support different writing systems, and each system can
1791      * use a different baseline.
1792      * The character argument determines the writing system to use. Clients
1793      * should not assume all characters use the same baseline.
1794      *
1795      * @param c a character used to identify the writing system
1796      * @return the baseline appropriate for the specified character.
1797      * @see LineMetrics#getBaselineOffsets
1798      * @see #ROMAN_BASELINE
1799      * @see #CENTER_BASELINE
1800      * @see #HANGING_BASELINE
1801      * @since 1.2
1802      */
1803     public byte getBaselineFor(char c) {
1804         return getFont2D().getBaselineFor(c);
1805     }
1806 
1807     /**
1808      * Returns a map of font attributes available in this
1809      * {@code Font}.  Attributes include things like ligatures and
1810      * glyph substitution.
1811      * @return the attributes map of this {@code Font}.
1812      */
1813     public Map<TextAttribute,?> getAttributes(){
1814         return new AttributeMap(getAttributeValues());
1815     }
1816 
1817     /**
1818      * Returns the keys of all the attributes supported by this
1819      * {@code Font}.  These attributes can be used to derive other
1820      * fonts.
1821      * @return an array containing the keys of all the attributes
1822      *          supported by this {@code Font}.
1823      * @since 1.2
1824      */
1825     public Attribute[] getAvailableAttributes() {
1826         // FONT is not supported by Font
1827 
1828         Attribute attributes[] = {
1829             TextAttribute.FAMILY,
1830             TextAttribute.WEIGHT,
1831             TextAttribute.WIDTH,
1832             TextAttribute.POSTURE,
1833             TextAttribute.SIZE,
1834             TextAttribute.TRANSFORM,
1835             TextAttribute.SUPERSCRIPT,
1836             TextAttribute.CHAR_REPLACEMENT,
1837             TextAttribute.FOREGROUND,
1838             TextAttribute.BACKGROUND,
1839             TextAttribute.UNDERLINE,
1840             TextAttribute.STRIKETHROUGH,
1841             TextAttribute.RUN_DIRECTION,
1842             TextAttribute.BIDI_EMBEDDING,
1843             TextAttribute.JUSTIFICATION,
1844             TextAttribute.INPUT_METHOD_HIGHLIGHT,
1845             TextAttribute.INPUT_METHOD_UNDERLINE,
1846             TextAttribute.SWAP_COLORS,
1847             TextAttribute.NUMERIC_SHAPING,
1848             TextAttribute.KERNING,
1849             TextAttribute.LIGATURES,
1850             TextAttribute.TRACKING,
1851         };
1852 
1853         return attributes;
1854     }
1855 
1856     /**
1857      * Creates a new {@code Font} object by replicating this
1858      * {@code Font} object and applying a new style and size.
1859      * @param style the style for the new {@code Font}
1860      * @param size the size for the new {@code Font}
1861      * @return a new {@code Font} object.
1862      * @since 1.2
1863      */
1864     public Font deriveFont(int style, float size){
1865         if (values == null) {
1866             return new Font(name, style, size, createdFont, font2DHandle);
1867         }
1868         AttributeValues newValues = getAttributeValues().clone();
1869         int oldStyle = (this.style != style) ? this.style : -1;
1870         applyStyle(style, newValues);
1871         newValues.setSize(size);
1872         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1873     }
1874 
1875     /**
1876      * Creates a new {@code Font} object by replicating this
1877      * {@code Font} object and applying a new style and transform.
1878      * @param style the style for the new {@code Font}
1879      * @param trans the {@code AffineTransform} associated with the
1880      * new {@code Font}
1881      * @return a new {@code Font} object.
1882      * @throws IllegalArgumentException if {@code trans} is
1883      *         {@code null}
1884      * @since 1.2
1885      */
1886     public Font deriveFont(int style, AffineTransform trans){
1887         AttributeValues newValues = getAttributeValues().clone();
1888         int oldStyle = (this.style != style) ? this.style : -1;
1889         applyStyle(style, newValues);
1890         applyTransform(trans, newValues);
1891         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1892     }
1893 
1894     /**
1895      * Creates a new {@code Font} object by replicating the current
1896      * {@code Font} object and applying a new size to it.
1897      * @param size the size for the new {@code Font}.
1898      * @return a new {@code Font} object.
1899      * @since 1.2
1900      */
1901     public Font deriveFont(float size){
1902         if (values == null) {
1903             return new Font(name, style, size, createdFont, font2DHandle);
1904         }
1905         AttributeValues newValues = getAttributeValues().clone();
1906         newValues.setSize(size);
1907         return new Font(newValues, null, -1, createdFont, font2DHandle);
1908     }
1909 
1910     /**
1911      * Creates a new {@code Font} object by replicating the current
1912      * {@code Font} object and applying a new transform to it.
1913      * @param trans the {@code AffineTransform} associated with the
1914      * new {@code Font}
1915      * @return a new {@code Font} object.
1916      * @throws IllegalArgumentException if {@code trans} is
1917      *         {@code null}
1918      * @since 1.2
1919      */
1920     public Font deriveFont(AffineTransform trans){
1921         AttributeValues newValues = getAttributeValues().clone();
1922         applyTransform(trans, newValues);
1923         return new Font(newValues, null, -1, createdFont, font2DHandle);
1924     }
1925 
1926     /**
1927      * Creates a new {@code Font} object by replicating the current
1928      * {@code Font} object and applying a new style to it.
1929      * @param style the style for the new {@code Font}
1930      * @return a new {@code Font} object.
1931      * @since 1.2
1932      */
1933     public Font deriveFont(int style){
1934         if (values == null) {
1935            return new Font(name, style, size, createdFont, font2DHandle);
1936         }
1937         AttributeValues newValues = getAttributeValues().clone();
1938         int oldStyle = (this.style != style) ? this.style : -1;
1939         applyStyle(style, newValues);
1940         return new Font(newValues, null, oldStyle, createdFont, font2DHandle);
1941     }
1942 
1943     /**
1944      * Creates a new {@code Font} object by replicating the current
1945      * {@code Font} object and applying a new set of font attributes
1946      * to it.
1947      *
1948      * @param attributes a map of attributes enabled for the new
1949      * {@code Font}
1950      * @return a new {@code Font} object.
1951      * @since 1.2
1952      */
1953     public Font deriveFont(Map<? extends Attribute, ?> attributes) {
1954         if (attributes == null) {
1955             return this;
1956         }
1957         AttributeValues newValues = getAttributeValues().clone();
1958         newValues.merge(attributes, RECOGNIZED_MASK);
1959 
1960         return new Font(newValues, name, style, createdFont, font2DHandle);
1961     }
1962 
1963     /**
1964      * Checks if this {@code Font} has a glyph for the specified
1965      * character.
1966      *
1967      * <p> <b>Note:</b> This method cannot handle <a
1968      * href="../../java/lang/Character.html#supplementary"> supplementary
1969      * characters</a>. To support all Unicode characters, including
1970      * supplementary characters, use the {@link #canDisplay(int)}
1971      * method or {@code canDisplayUpTo} methods.
1972      *
1973      * @param c the character for which a glyph is needed
1974      * @return {@code true} if this {@code Font} has a glyph for this
1975      *          character; {@code false} otherwise.
1976      * @since 1.2
1977      */
1978     public boolean canDisplay(char c){
1979         return getFont2D().canDisplay(c);
1980     }
1981 
1982     /**
1983      * Checks if this {@code Font} has a glyph for the specified
1984      * character.
1985      *
1986      * @param codePoint the character (Unicode code point) for which a glyph
1987      *        is needed.
1988      * @return {@code true} if this {@code Font} has a glyph for the
1989      *          character; {@code false} otherwise.
1990      * @throws IllegalArgumentException if the code point is not a valid Unicode
1991      *          code point.
1992      * @see Character#isValidCodePoint(int)
1993      * @since 1.5
1994      */
1995     public boolean canDisplay(int codePoint) {
1996         if (!Character.isValidCodePoint(codePoint)) {
1997             throw new IllegalArgumentException("invalid code point: " +
1998                                                Integer.toHexString(codePoint));
1999         }
2000         return getFont2D().canDisplay(codePoint);
2001     }
2002 
2003     /**
2004      * Indicates whether or not this {@code Font} can display a
2005      * specified {@code String}.  For strings with Unicode encoding,
2006      * it is important to know if a particular font can display the
2007      * string. This method returns an offset into the {@code String}
2008      * {@code str} which is the first character this
2009      * {@code Font} cannot display without using the missing glyph
2010      * code. If the {@code Font} can display all characters, -1 is
2011      * returned.
2012      * @param str a {@code String} object
2013      * @return an offset into {@code str} that points
2014      *          to the first character in {@code str} that this
2015      *          {@code Font} cannot display; or {@code -1} if
2016      *          this {@code Font} can display all characters in
2017      *          {@code str}.
2018      * @since 1.2
2019      */
2020     public int canDisplayUpTo(String str) {
2021         Font2D font2d = getFont2D();
2022         int len = str.length();
2023         for (int i = 0; i < len; i++) {
2024             char c = str.charAt(i);
2025             if (font2d.canDisplay(c)) {
2026                 continue;
2027             }
2028             if (!Character.isHighSurrogate(c)) {
2029                 return i;
2030             }
2031             if (!font2d.canDisplay(str.codePointAt(i))) {
2032                 return i;
2033             }
2034             i++;
2035         }
2036         return -1;
2037     }
2038 
2039     /**
2040      * Indicates whether or not this {@code Font} can display
2041      * the characters in the specified {@code text}
2042      * starting at {@code start} and ending at
2043      * {@code limit}.  This method is a convenience overload.
2044      * @param text the specified array of {@code char} values
2045      * @param start the specified starting offset (in
2046      *              {@code char}s) into the specified array of
2047      *              {@code char} values
2048      * @param limit the specified ending offset (in
2049      *              {@code char}s) into the specified array of
2050      *              {@code char} values
2051      * @return an offset into {@code text} that points
2052      *          to the first character in {@code text} that this
2053      *          {@code Font} cannot display; or {@code -1} if
2054      *          this {@code Font} can display all characters in
2055      *          {@code text}.
2056      * @since 1.2
2057      */
2058     public int canDisplayUpTo(char[] text, int start, int limit) {
2059         Font2D font2d = getFont2D();
2060         for (int i = start; i < limit; i++) {
2061             char c = text[i];
2062             if (font2d.canDisplay(c)) {
2063                 continue;
2064             }
2065             if (!Character.isHighSurrogate(c)) {
2066                 return i;
2067             }
2068             if (!font2d.canDisplay(Character.codePointAt(text, i, limit))) {
2069                 return i;
2070             }
2071             i++;
2072         }
2073         return -1;
2074     }
2075 
2076     /**
2077      * Indicates whether or not this {@code Font} can display the
2078      * text specified by the {@code iter} starting at
2079      * {@code start} and ending at {@code limit}.
2080      *
2081      * @param iter  a {@link CharacterIterator} object
2082      * @param start the specified starting offset into the specified
2083      *              {@code CharacterIterator}.
2084      * @param limit the specified ending offset into the specified
2085      *              {@code CharacterIterator}.
2086      * @return an offset into {@code iter} that points
2087      *          to the first character in {@code iter} that this
2088      *          {@code Font} cannot display; or {@code -1} if
2089      *          this {@code Font} can display all characters in
2090      *          {@code iter}.
2091      * @since 1.2
2092      */
2093     public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
2094         Font2D font2d = getFont2D();
2095         char c = iter.setIndex(start);
2096         for (int i = start; i < limit; i++, c = iter.next()) {
2097             if (font2d.canDisplay(c)) {
2098                 continue;
2099             }
2100             if (!Character.isHighSurrogate(c)) {
2101                 return i;
2102             }
2103             char c2 = iter.next();
2104             // c2 could be CharacterIterator.DONE which is not a low surrogate.
2105             if (!Character.isLowSurrogate(c2)) {
2106                 return i;
2107             }
2108             if (!font2d.canDisplay(Character.toCodePoint(c, c2))) {
2109                 return i;
2110             }
2111             i++;
2112         }
2113         return -1;
2114     }
2115 
2116     /**
2117      * Returns the italic angle of this {@code Font}.  The italic angle
2118      * is the inverse slope of the caret which best matches the posture of this
2119      * {@code Font}.
2120      * @see TextAttribute#POSTURE
2121      * @return the angle of the ITALIC style of this {@code Font}.
2122      */
2123     public float getItalicAngle() {
2124         return getItalicAngle(null);
2125     }
2126 
2127     /* The FRC hints don't affect the value of the italic angle but
2128      * we need to pass them in to look up a strike.
2129      * If we can pass in ones already being used it can prevent an extra
2130      * strike from being allocated. Note that since italic angle is
2131      * a property of the font, the font transform is needed not the
2132      * device transform. Finally, this is private but the only caller of this
2133      * in the JDK - and the only likely caller - is in this same class.
2134      */
2135     private float getItalicAngle(FontRenderContext frc) {
2136         Object aa, fm;
2137         if (frc == null) {
2138             aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
2139             fm = RenderingHints.VALUE_FRACTIONALMETRICS_OFF;
2140         } else {
2141             aa = frc.getAntiAliasingHint();
2142             fm = frc.getFractionalMetricsHint();
2143         }
2144         return getFont2D().getItalicAngle(this, identityTx, aa, fm);
2145     }
2146 
2147     /**
2148      * Checks whether or not this {@code Font} has uniform
2149      * line metrics.  A logical {@code Font} might be a
2150      * composite font, which means that it is composed of different
2151      * physical fonts to cover different code ranges.  Each of these
2152      * fonts might have different {@code LineMetrics}.  If the
2153      * logical {@code Font} is a single
2154      * font then the metrics would be uniform.
2155      * @return {@code true} if this {@code Font} has
2156      * uniform line metrics; {@code false} otherwise.
2157      */
2158     public boolean hasUniformLineMetrics() {
2159         return false;   // REMIND always safe, but prevents caller optimize
2160     }
2161 
2162     private transient SoftReference<FontLineMetrics> flmref;
2163     private FontLineMetrics defaultLineMetrics(FontRenderContext frc) {
2164         FontLineMetrics flm = null;
2165         if (flmref == null
2166             || (flm = flmref.get()) == null
2167             || !flm.frc.equals(frc)) {
2168 
2169             /* The device transform in the frc is not used in obtaining line
2170              * metrics, although it probably should be: REMIND find why not?
2171              * The font transform is used but its applied in getFontMetrics, so
2172              * just pass identity here
2173              */
2174             float [] metrics = new float[8];
2175             getFont2D().getFontMetrics(this, identityTx,
2176                                        frc.getAntiAliasingHint(),


2218                 }
2219             }
2220             strikethroughOffset += ssOffset;
2221             underlineOffset += ssOffset;
2222 
2223             CoreMetrics cm = new CoreMetrics(ascent, descent, leading, height,
2224                                              baselineIndex, baselineOffsets,
2225                                              strikethroughOffset, strikethroughThickness,
2226                                              underlineOffset, underlineThickness,
2227                                              ssOffset, italicAngle);
2228 
2229             flm = new FontLineMetrics(0, cm, frc);
2230             flmref = new SoftReference<FontLineMetrics>(flm);
2231         }
2232 
2233         return (FontLineMetrics)flm.clone();
2234     }
2235 
2236     /**
2237      * Returns a {@link LineMetrics} object created with the specified
2238      * {@code String} and {@link FontRenderContext}.
2239      * @param str the specified {@code String}
2240      * @param frc the specified {@code FontRenderContext}
2241      * @return a {@code LineMetrics} object created with the
2242      * specified {@code String} and {@link FontRenderContext}.
2243      */
2244     public LineMetrics getLineMetrics( String str, FontRenderContext frc) {
2245         FontLineMetrics flm = defaultLineMetrics(frc);
2246         flm.numchars = str.length();
2247         return flm;
2248     }
2249 
2250     /**
2251      * Returns a {@code LineMetrics} object created with the
2252      * specified arguments.
2253      * @param str the specified {@code String}
2254      * @param beginIndex the initial offset of {@code str}
2255      * @param limit the end offset of {@code str}
2256      * @param frc the specified {@code FontRenderContext}
2257      * @return a {@code LineMetrics} object created with the
2258      * specified arguments.
2259      */
2260     public LineMetrics getLineMetrics( String str,
2261                                     int beginIndex, int limit,
2262                                     FontRenderContext frc) {
2263         FontLineMetrics flm = defaultLineMetrics(frc);
2264         int numChars = limit - beginIndex;
2265         flm.numchars = (numChars < 0)? 0: numChars;
2266         return flm;
2267     }
2268 
2269     /**
2270      * Returns a {@code LineMetrics} object created with the
2271      * specified arguments.
2272      * @param chars an array of characters
2273      * @param beginIndex the initial offset of {@code chars}
2274      * @param limit the end offset of {@code chars}
2275      * @param frc the specified {@code FontRenderContext}
2276      * @return a {@code LineMetrics} object created with the
2277      * specified arguments.
2278      */
2279     public LineMetrics getLineMetrics(char [] chars,
2280                                     int beginIndex, int limit,
2281                                     FontRenderContext frc) {
2282         FontLineMetrics flm = defaultLineMetrics(frc);
2283         int numChars = limit - beginIndex;
2284         flm.numchars = (numChars < 0)? 0: numChars;
2285         return flm;
2286     }
2287 
2288     /**
2289      * Returns a {@code LineMetrics} object created with the
2290      * specified arguments.
2291      * @param ci the specified {@code CharacterIterator}
2292      * @param beginIndex the initial offset in {@code ci}
2293      * @param limit the end offset of {@code ci}
2294      * @param frc the specified {@code FontRenderContext}
2295      * @return a {@code LineMetrics} object created with the
2296      * specified arguments.
2297      */
2298     public LineMetrics getLineMetrics(CharacterIterator ci,
2299                                     int beginIndex, int limit,
2300                                     FontRenderContext frc) {
2301         FontLineMetrics flm = defaultLineMetrics(frc);
2302         int numChars = limit - beginIndex;
2303         flm.numchars = (numChars < 0)? 0: numChars;
2304         return flm;
2305     }
2306 
2307     /**
2308      * Returns the logical bounds of the specified {@code String} in
2309      * the specified {@code FontRenderContext}.  The logical bounds
2310      * contains the origin, ascent, advance, and height, which includes
2311      * the leading.  The logical bounds does not always enclose all the
2312      * text.  For example, in some languages and in some fonts, accent
2313      * marks can be positioned above the ascent or below the descent.
2314      * To obtain a visual bounding box, which encloses all the text,
2315      * use the {@link TextLayout#getBounds() getBounds} method of
2316      * {@code TextLayout}.
2317      * <p>Note: The returned bounds is in baseline-relative coordinates
2318      * (see {@link java.awt.Font class notes}).
2319      * @param str the specified {@code String}
2320      * @param frc the specified {@code FontRenderContext}
2321      * @return a {@link Rectangle2D} that is the bounding box of the
2322      * specified {@code String} in the specified
2323      * {@code FontRenderContext}.
2324      * @see FontRenderContext
2325      * @see Font#createGlyphVector
2326      * @since 1.2
2327      */
2328     public Rectangle2D getStringBounds( String str, FontRenderContext frc) {
2329         char[] array = str.toCharArray();
2330         return getStringBounds(array, 0, array.length, frc);
2331     }
2332 
2333    /**
2334      * Returns the logical bounds of the specified {@code String} in
2335      * the specified {@code FontRenderContext}.  The logical bounds
2336      * contains the origin, ascent, advance, and height, which includes
2337      * the leading.  The logical bounds does not always enclose all the
2338      * text.  For example, in some languages and in some fonts, accent
2339      * marks can be positioned above the ascent or below the descent.
2340      * To obtain a visual bounding box, which encloses all the text,
2341      * use the {@link TextLayout#getBounds() getBounds} method of
2342      * {@code TextLayout}.
2343      * <p>Note: The returned bounds is in baseline-relative coordinates
2344      * (see {@link java.awt.Font class notes}).
2345      * @param str the specified {@code String}
2346      * @param beginIndex the initial offset of {@code str}
2347      * @param limit the end offset of {@code str}
2348      * @param frc the specified {@code FontRenderContext}
2349      * @return a {@code Rectangle2D} that is the bounding box of the
2350      * specified {@code String} in the specified
2351      * {@code FontRenderContext}.
2352      * @throws IndexOutOfBoundsException if {@code beginIndex} is
2353      *         less than zero, or {@code limit} is greater than the
2354      *         length of {@code str}, or {@code beginIndex}
2355      *         is greater than {@code limit}.
2356      * @see FontRenderContext
2357      * @see Font#createGlyphVector
2358      * @since 1.2
2359      */
2360     public Rectangle2D getStringBounds( String str,
2361                                     int beginIndex, int limit,
2362                                         FontRenderContext frc) {
2363         String substr = str.substring(beginIndex, limit);
2364         return getStringBounds(substr, frc);
2365     }
2366 
2367    /**
2368      * Returns the logical bounds of the specified array of characters
2369      * in the specified {@code FontRenderContext}.  The logical
2370      * bounds contains the origin, ascent, advance, and height, which
2371      * includes the leading.  The logical bounds does not always enclose
2372      * all the text.  For example, in some languages and in some fonts,
2373      * accent marks can be positioned above the ascent or below the
2374      * descent.  To obtain a visual bounding box, which encloses all the
2375      * text, use the {@link TextLayout#getBounds() getBounds} method of
2376      * {@code TextLayout}.
2377      * <p>Note: The returned bounds is in baseline-relative coordinates
2378      * (see {@link java.awt.Font class notes}).
2379      * @param chars an array of characters
2380      * @param beginIndex the initial offset in the array of
2381      * characters
2382      * @param limit the end offset in the array of characters
2383      * @param frc the specified {@code FontRenderContext}
2384      * @return a {@code Rectangle2D} that is the bounding box of the
2385      * specified array of characters in the specified
2386      * {@code FontRenderContext}.
2387      * @throws IndexOutOfBoundsException if {@code beginIndex} is
2388      *         less than zero, or {@code limit} is greater than the
2389      *         length of {@code chars}, or {@code beginIndex}
2390      *         is greater than {@code limit}.
2391      * @see FontRenderContext
2392      * @see Font#createGlyphVector
2393      * @since 1.2
2394      */
2395     public Rectangle2D getStringBounds(char [] chars,
2396                                     int beginIndex, int limit,
2397                                        FontRenderContext frc) {
2398         if (beginIndex < 0) {
2399             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2400         }
2401         if (limit > chars.length) {
2402             throw new IndexOutOfBoundsException("limit: " + limit);
2403         }
2404         if (beginIndex > limit) {
2405             throw new IndexOutOfBoundsException("range length: " +
2406                                                 (limit - beginIndex));
2407         }
2408 
2409         // this code should be in textlayout
2410         // quick check for simple text, assume GV ok to use if simple


2416             simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
2417         }
2418 
2419         if (simple) {
2420             GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
2421                                                      limit - beginIndex, frc);
2422             return gv.getLogicalBounds();
2423         } else {
2424             // need char array constructor on textlayout
2425             String str = new String(chars, beginIndex, limit - beginIndex);
2426             TextLayout tl = new TextLayout(str, this, frc);
2427             return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
2428                                          tl.getAscent() + tl.getDescent() +
2429                                          tl.getLeading());
2430         }
2431     }
2432 
2433    /**
2434      * Returns the logical bounds of the characters indexed in the
2435      * specified {@link CharacterIterator} in the
2436      * specified {@code FontRenderContext}.  The logical bounds
2437      * contains the origin, ascent, advance, and height, which includes
2438      * the leading.  The logical bounds does not always enclose all the
2439      * text.  For example, in some languages and in some fonts, accent
2440      * marks can be positioned above the ascent or below the descent.
2441      * To obtain a visual bounding box, which encloses all the text,
2442      * use the {@link TextLayout#getBounds() getBounds} method of
2443      * {@code TextLayout}.
2444      * <p>Note: The returned bounds is in baseline-relative coordinates
2445      * (see {@link java.awt.Font class notes}).
2446      * @param ci the specified {@code CharacterIterator}
2447      * @param beginIndex the initial offset in {@code ci}
2448      * @param limit the end offset in {@code ci}
2449      * @param frc the specified {@code FontRenderContext}
2450      * @return a {@code Rectangle2D} that is the bounding box of the
2451      * characters indexed in the specified {@code CharacterIterator}
2452      * in the specified {@code FontRenderContext}.
2453      * @see FontRenderContext
2454      * @see Font#createGlyphVector
2455      * @since 1.2
2456      * @throws IndexOutOfBoundsException if {@code beginIndex} is
2457      *         less than the start index of {@code ci}, or
2458      *         {@code limit} is greater than the end index of
2459      *         {@code ci}, or {@code beginIndex} is greater
2460      *         than {@code limit}
2461      */
2462     public Rectangle2D getStringBounds(CharacterIterator ci,
2463                                     int beginIndex, int limit,
2464                                        FontRenderContext frc) {
2465         int start = ci.getBeginIndex();
2466         int end = ci.getEndIndex();
2467 
2468         if (beginIndex < start) {
2469             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2470         }
2471         if (limit > end) {
2472             throw new IndexOutOfBoundsException("limit: " + limit);
2473         }
2474         if (beginIndex > limit) {
2475             throw new IndexOutOfBoundsException("range length: " +
2476                                                 (limit - beginIndex));
2477         }
2478 
2479         char[]  arr = new char[limit - beginIndex];
2480 
2481         ci.setIndex(beginIndex);
2482         for(int idx = 0; idx < arr.length; idx++) {
2483             arr[idx] = ci.current();
2484             ci.next();
2485         }
2486 
2487         return getStringBounds(arr,0,arr.length,frc);
2488     }
2489 
2490     /**
2491      * Returns the bounds for the character with the maximum
2492      * bounds as defined in the specified {@code FontRenderContext}.
2493      * <p>Note: The returned bounds is in baseline-relative coordinates
2494      * (see {@link java.awt.Font class notes}).
2495      * @param frc the specified {@code FontRenderContext}
2496      * @return a {@code Rectangle2D} that is the bounding box
2497      * for the character with the maximum bounds.
2498      */
2499     public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
2500         float [] metrics = new float[4];
2501 
2502         getFont2D().getFontMetrics(this, frc, metrics);
2503 
2504         return new Rectangle2D.Float(0, -metrics[0],
2505                                 metrics[3],
2506                                 metrics[0] + metrics[1] + metrics[2]);
2507     }
2508 
2509     /**
2510      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2511      * mapping characters to glyphs one-to-one based on the
2512      * Unicode cmap in this {@code Font}.  This method does no other
2513      * processing besides the mapping of glyphs to characters.  This
2514      * means that this method is not useful for some scripts, such
2515      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2516      * shaping, or ligature substitution.
2517      * @param frc the specified {@code FontRenderContext}
2518      * @param str the specified {@code String}
2519      * @return a new {@code GlyphVector} created with the
2520      * specified {@code String} and the specified
2521      * {@code FontRenderContext}.
2522      */
2523     public GlyphVector createGlyphVector(FontRenderContext frc, String str)
2524     {
2525         return (GlyphVector)new StandardGlyphVector(this, str, frc);
2526     }
2527 
2528     /**
2529      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2530      * mapping characters to glyphs one-to-one based on the
2531      * Unicode cmap in this {@code Font}.  This method does no other
2532      * processing besides the mapping of glyphs to characters.  This
2533      * means that this method is not useful for some scripts, such
2534      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2535      * shaping, or ligature substitution.
2536      * @param frc the specified {@code FontRenderContext}
2537      * @param chars the specified array of characters
2538      * @return a new {@code GlyphVector} created with the
2539      * specified array of characters and the specified
2540      * {@code FontRenderContext}.
2541      */
2542     public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars)
2543     {
2544         return (GlyphVector)new StandardGlyphVector(this, chars, frc);
2545     }
2546 
2547     /**
2548      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2549      * mapping the specified characters to glyphs one-to-one based on the
2550      * Unicode cmap in this {@code Font}.  This method does no other
2551      * processing besides the mapping of glyphs to characters.  This
2552      * means that this method is not useful for some scripts, such
2553      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2554      * shaping, or ligature substitution.
2555      * @param frc the specified {@code FontRenderContext}
2556      * @param ci the specified {@code CharacterIterator}
2557      * @return a new {@code GlyphVector} created with the
2558      * specified {@code CharacterIterator} and the specified
2559      * {@code FontRenderContext}.
2560      */
2561     public GlyphVector createGlyphVector(   FontRenderContext frc,
2562                                             CharacterIterator ci)
2563     {
2564         return (GlyphVector)new StandardGlyphVector(this, ci, frc);
2565     }
2566 
2567     /**
2568      * Creates a {@link java.awt.font.GlyphVector GlyphVector} by
2569      * mapping characters to glyphs one-to-one based on the
2570      * Unicode cmap in this {@code Font}.  This method does no other
2571      * processing besides the mapping of glyphs to characters.  This
2572      * means that this method is not useful for some scripts, such
2573      * as Arabic, Hebrew, Thai, and Indic, that require reordering,
2574      * shaping, or ligature substitution.
2575      * @param frc the specified {@code FontRenderContext}
2576      * @param glyphCodes the specified integer array
2577      * @return a new {@code GlyphVector} created with the
2578      * specified integer array and the specified
2579      * {@code FontRenderContext}.
2580      */
2581     public GlyphVector createGlyphVector(   FontRenderContext frc,
2582                                             int [] glyphCodes)
2583     {
2584         return (GlyphVector)new StandardGlyphVector(this, glyphCodes, frc);
2585     }
2586 
2587     /**
2588      * Returns a new {@code GlyphVector} object, performing full
2589      * layout of the text if possible.  Full layout is required for
2590      * complex text, such as Arabic or Hindi.  Support for different
2591      * scripts depends on the font and implementation.
2592      * <p>
2593      * Layout requires bidi analysis, as performed by
2594      * {@code Bidi}, and should only be performed on text that
2595      * has a uniform direction.  The direction is indicated in the
2596      * flags parameter,by using LAYOUT_RIGHT_TO_LEFT to indicate a
2597      * right-to-left (Arabic and Hebrew) run direction, or
2598      * LAYOUT_LEFT_TO_RIGHT to indicate a left-to-right (English)
2599      * run direction.
2600      * <p>
2601      * In addition, some operations, such as Arabic shaping, require
2602      * context, so that the characters at the start and limit can have
2603      * the proper shapes.  Sometimes the data in the buffer outside
2604      * the provided range does not have valid data.  The values
2605      * LAYOUT_NO_START_CONTEXT and LAYOUT_NO_LIMIT_CONTEXT can be
2606      * added to the flags parameter to indicate that the text before
2607      * start, or after limit, respectively, should not be examined
2608      * for context.
2609      * <p>
2610      * All other values for the flags parameter are reserved.
2611      *
2612      * @param frc the specified {@code FontRenderContext}
2613      * @param text the text to layout
2614      * @param start the start of the text to use for the {@code GlyphVector}
2615      * @param limit the limit of the text to use for the {@code GlyphVector}
2616      * @param flags control flags as described above
2617      * @return a new {@code GlyphVector} representing the text between
2618      * start and limit, with glyphs chosen and positioned so as to best represent
2619      * the text
2620      * @throws ArrayIndexOutOfBoundsException if start or limit is
2621      * out of bounds
2622      * @see java.text.Bidi
2623      * @see #LAYOUT_LEFT_TO_RIGHT
2624      * @see #LAYOUT_RIGHT_TO_LEFT
2625      * @see #LAYOUT_NO_START_CONTEXT
2626      * @see #LAYOUT_NO_LIMIT_CONTEXT
2627      * @since 1.4
2628      */
2629     public GlyphVector layoutGlyphVector(FontRenderContext frc,
2630                                          char[] text,
2631                                          int start,
2632                                          int limit,
2633                                          int flags) {
2634 
2635         GlyphLayout gl = GlyphLayout.get(null); // !!! no custom layout engines
2636         StandardGlyphVector gv = gl.layout(this, frc, text,
2637                                            start, limit-start, flags, null);


< prev index next >