1 /*
   2  * Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.awt.Graphics2D;
  29 import java.awt.font.FontRenderContext;
  30 import java.awt.font.LineMetrics;
  31 import java.awt.geom.Rectangle2D;
  32 import java.nio.charset.Charset;
  33 import java.nio.charset.StandardCharsets;
  34 import java.text.CharacterIterator;
  35 
  36 /**
  37  * The <code>FontMetrics</code> class defines a font metrics object, which
  38  * encapsulates information about the rendering of a particular font on a
  39  * particular screen.
  40  * <p>
  41  * <b>Note to subclassers</b>: Since many of these methods form closed,
  42  * mutually recursive loops, you must take care that you implement
  43  * at least one of the methods in each such loop to prevent
  44  * infinite recursion when your subclass is used.
  45  * In particular, the following is the minimal suggested set of methods
  46  * to override in order to ensure correctness and prevent infinite
  47  * recursion (though other subsets are equally feasible):
  48  * <ul>
  49  * <li>{@link #getAscent()}
  50  * <li>{@link #getLeading()}
  51  * <li>{@link #getMaxAdvance()}
  52  * <li>{@link #charWidth(char)}
  53  * <li>{@link #charsWidth(char[], int, int)}
  54  * </ul>
  55  * <p>
  56  * <img src="doc-files/FontMetrics-1.gif" alt="The letter 'p' showing its 'reference point'" border=15 align
  57  * ALIGN=right HSPACE=10 VSPACE=7>
  58  * Note that the implementations of these methods are
  59  * inefficient, so they are usually overridden with more efficient
  60  * toolkit-specific implementations.
  61  * <p>
  62  * When an application asks to place a character at the position
  63  * (<i>x</i>,&nbsp;<i>y</i>), the character is placed so that its
  64  * reference point (shown as the dot in the accompanying image) is
  65  * put at that position. The reference point specifies a horizontal
  66  * line called the <i>baseline</i> of the character. In normal
  67  * printing, the baselines of characters should align.
  68  * <p>
  69  * In addition, every character in a font has an <i>ascent</i>, a
  70  * <i>descent</i>, and an <i>advance width</i>. The ascent is the
  71  * amount by which the character ascends above the baseline. The
  72  * descent is the amount by which the character descends below the
  73  * baseline. The advance width indicates the position at which AWT
  74  * should place the next character.
  75  * <p>
  76  * An array of characters or a string can also have an ascent, a
  77  * descent, and an advance width. The ascent of the array is the
  78  * maximum ascent of any character in the array. The descent is the
  79  * maximum descent of any character in the array. The advance width
  80  * is the sum of the advance widths of each of the characters in the
  81  * character array.  The advance of a <code>String</code> is the
  82  * distance along the baseline of the <code>String</code>.  This
  83  * distance is the width that should be used for centering or
  84  * right-aligning the <code>String</code>.
  85  * <p>Note that the advance of a <code>String</code> is not necessarily
  86  * the sum of the advances of its characters measured in isolation
  87  * because the width of a character can vary depending on its context.
  88  * For example, in Arabic text, the shape of a character can change
  89  * in order to connect to other characters.  Also, in some scripts,
  90  * certain character sequences can be represented by a single shape,
  91  * called a <em>ligature</em>.  Measuring characters individually does
  92  * not account for these transformations.
  93  * <p>Font metrics are baseline-relative, meaning that they are
  94  * generally independent of the rotation applied to the font (modulo
  95  * possible grid hinting effects).  See {@link java.awt.Font Font}.
  96  *
  97  * @author      Jim Graham
  98  * @see         java.awt.Font
  99  * @since       JDK1.0
 100  */
 101 public abstract class FontMetrics implements java.io.Serializable {
 102 
 103     static {
 104         /* ensure that the necessary native libraries are loaded */
 105         Toolkit.loadLibraries();
 106         if (!GraphicsEnvironment.isHeadless()) {
 107             initIDs();
 108         }
 109     }
 110 
 111     private static final FontRenderContext
 112         DEFAULT_FRC = new FontRenderContext(null, false, false);
 113 
 114     /**
 115      * The actual {@link Font} from which the font metrics are
 116      * created.
 117      * This cannot be null.
 118      *
 119      * @serial
 120      * @see #getFont()
 121      */
 122     protected Font font;
 123 
 124     /*
 125      * JDK 1.1 serialVersionUID
 126      */
 127     private static final long serialVersionUID = 1681126225205050147L;
 128 
 129     /**
 130      * Creates a new <code>FontMetrics</code> object for finding out
 131      * height and width information about the specified <code>Font</code>
 132      * and specific character glyphs in that <code>Font</code>.
 133      * @param     font the <code>Font</code>
 134      * @see       java.awt.Font
 135      */
 136     protected FontMetrics(Font font) {
 137         this.font = font;
 138     }
 139 
 140     /**
 141      * Gets the <code>Font</code> described by this
 142      * <code>FontMetrics</code> object.
 143      * @return    the <code>Font</code> described by this
 144      * <code>FontMetrics</code> object.
 145      */
 146     public Font getFont() {
 147         return font;
 148     }
 149 
 150     /**
 151      * Gets the <code>FontRenderContext</code> used by this
 152      * <code>FontMetrics</code> object to measure text.
 153      * <p>
 154      * Note that methods in this class which take a <code>Graphics</code>
 155      * parameter measure text using the <code>FontRenderContext</code>
 156      * of that <code>Graphics</code> object, and not this
 157      * <code>FontRenderContext</code>
 158      * @return    the <code>FontRenderContext</code> used by this
 159      * <code>FontMetrics</code> object.
 160      * @since 1.6
 161      */
 162     public FontRenderContext getFontRenderContext() {
 163         return DEFAULT_FRC;
 164     }
 165 
 166     /**
 167      * Determines the <em>standard leading</em> of the
 168      * <code>Font</code> described by this <code>FontMetrics</code>
 169      * object.  The standard leading, or
 170      * interline spacing, is the logical amount of space to be reserved
 171      * between the descent of one line of text and the ascent of the next
 172      * line. The height metric is calculated to include this extra space.
 173      * @return    the standard leading of the <code>Font</code>.
 174      * @see   #getHeight()
 175      * @see   #getAscent()
 176      * @see   #getDescent()
 177      */
 178     public int getLeading() {
 179         return 0;
 180     }
 181 
 182     /**
 183      * Determines the <em>font ascent</em> of the <code>Font</code>
 184      * described by this <code>FontMetrics</code> object. The font ascent
 185      * is the distance from the font's baseline to the top of most
 186      * alphanumeric characters. Some characters in the <code>Font</code>
 187      * might extend above the font ascent line.
 188      * @return     the font ascent of the <code>Font</code>.
 189      * @see        #getMaxAscent()
 190      */
 191     public int getAscent() {
 192         return font.getSize();
 193     }
 194 
 195     /**
 196      * Determines the <em>font descent</em> of the <code>Font</code>
 197      * described by this
 198      * <code>FontMetrics</code> object. The font descent is the distance
 199      * from the font's baseline to the bottom of most alphanumeric
 200      * characters with descenders. Some characters in the
 201      * <code>Font</code> might extend
 202      * below the font descent line.
 203      * @return     the font descent of the <code>Font</code>.
 204      * @see        #getMaxDescent()
 205      */
 206     public int getDescent() {
 207         return 0;
 208     }
 209 
 210     /**
 211      * Gets the standard height of a line of text in this font.  This
 212      * is the distance between the baseline of adjacent lines of text.
 213      * It is the sum of the leading + ascent + descent. Due to rounding
 214      * this may not be the same as getAscent() + getDescent() + getLeading().
 215      * There is no guarantee that lines of text spaced at this distance are
 216      * disjoint; such lines may overlap if some characters overshoot
 217      * either the standard ascent or the standard descent metric.
 218      * @return    the standard height of the font.
 219      * @see       #getLeading()
 220      * @see       #getAscent()
 221      * @see       #getDescent()
 222      */
 223     public int getHeight() {
 224         return getLeading() + getAscent() + getDescent();
 225     }
 226 
 227     /**
 228      * Determines the maximum ascent of the <code>Font</code>
 229      * described by this <code>FontMetrics</code> object.  No character
 230      * extends further above the font's baseline than this height.
 231      * @return    the maximum ascent of any character in the
 232      * <code>Font</code>.
 233      * @see       #getAscent()
 234      */
 235     public int getMaxAscent() {
 236         return getAscent();
 237     }
 238 
 239     /**
 240      * Determines the maximum descent of the <code>Font</code>
 241      * described by this <code>FontMetrics</code> object.  No character
 242      * extends further below the font's baseline than this height.
 243      * @return    the maximum descent of any character in the
 244      * <code>Font</code>.
 245      * @see       #getDescent()
 246      */
 247     public int getMaxDescent() {
 248         return getDescent();
 249     }
 250 
 251     /**
 252      * For backward compatibility only.
 253      * @return    the maximum descent of any character in the
 254      * <code>Font</code>.
 255      * @see #getMaxDescent()
 256      * @deprecated As of JDK version 1.1.1,
 257      * replaced by <code>getMaxDescent()</code>.
 258      */
 259     @Deprecated
 260     public int getMaxDecent() {
 261         return getMaxDescent();
 262     }
 263 
 264     /**
 265      * Gets the maximum advance width of any character in this
 266      * <code>Font</code>.  The advance is the
 267      * distance from the leftmost point to the rightmost point on the
 268      * string's baseline.  The advance of a <code>String</code> is
 269      * not necessarily the sum of the advances of its characters.
 270      * @return    the maximum advance width of any character
 271      *            in the <code>Font</code>, or <code>-1</code> if the
 272      *            maximum advance width is not known.
 273      */
 274     public int getMaxAdvance() {
 275         return -1;
 276     }
 277 
 278     /**
 279      * Returns the advance width of the specified character in this
 280      * <code>Font</code>.  The advance is the
 281      * distance from the leftmost point to the rightmost point on the
 282      * character's baseline.  Note that the advance of a
 283      * <code>String</code> is not necessarily the sum of the advances
 284      * of its characters.
 285      *
 286      * <p>This method doesn't validate the specified character to be a
 287      * valid Unicode code point. The caller must validate the
 288      * character value using {@link
 289      * java.lang.Character#isValidCodePoint(int)
 290      * Character.isValidCodePoint} if necessary.
 291      *
 292      * @param codePoint the character (Unicode code point) to be measured
 293      * @return    the advance width of the specified character
 294      *            in the <code>Font</code> described by this
 295      *            <code>FontMetrics</code> object.
 296      * @see   #charsWidth(char[], int, int)
 297      * @see   #stringWidth(String)
 298      */
 299     public int charWidth(int codePoint) {
 300         if (!Character.isValidCodePoint(codePoint)) {
 301             codePoint = 0xffff; // substitute missing glyph width
 302         }
 303 
 304         if (codePoint < 256) {
 305             return getWidths()[codePoint];
 306         } else {
 307             char[] buffer = new char[2];
 308             int len = Character.toChars(codePoint, buffer, 0);
 309             return charsWidth(buffer, 0, len);
 310         }
 311     }
 312 
 313     /**
 314      * Returns the advance width of the specified character in this
 315      * <code>Font</code>.  The advance is the
 316      * distance from the leftmost point to the rightmost point on the
 317      * character's baseline.  Note that the advance of a
 318      * <code>String</code> is not necessarily the sum of the advances
 319      * of its characters.
 320      *
 321      * <p><b>Note:</b> This method cannot handle <a
 322      * href="../lang/Character.html#supplementary"> supplementary
 323      * characters</a>. To support all Unicode characters, including
 324      * supplementary characters, use the {@link #charWidth(int)} method.
 325      *
 326      * @param ch the character to be measured
 327      * @return     the advance width of the specified character
 328      *                  in the <code>Font</code> described by this
 329      *                  <code>FontMetrics</code> object.
 330      * @see        #charsWidth(char[], int, int)
 331      * @see        #stringWidth(String)
 332      */
 333     public int charWidth(char ch) {
 334         if (ch < 256) {
 335             return getWidths()[ch];
 336         }
 337         char data[] = {ch};
 338         return charsWidth(data, 0, 1);
 339     }
 340 
 341     /**
 342      * Returns the total advance width for showing the specified
 343      * <code>String</code> in this <code>Font</code>.  The advance
 344      * is the distance from the leftmost point to the rightmost point
 345      * on the string's baseline.
 346      * <p>
 347      * Note that the advance of a <code>String</code> is
 348      * not necessarily the sum of the advances of its characters.
 349      * @param str the <code>String</code> to be measured
 350      * @return    the advance width of the specified <code>String</code>
 351      *                  in the <code>Font</code> described by this
 352      *                  <code>FontMetrics</code>.
 353      * @throws NullPointerException if str is null.
 354      * @see       #bytesWidth(byte[], int, int)
 355      * @see       #charsWidth(char[], int, int)
 356      * @see       #getStringBounds(String, Graphics)
 357      */
 358     public int stringWidth(String str) {
 359         int len = str.length();
 360         char data[] = new char[len];
 361         str.getChars(0, len, data, 0);
 362         return charsWidth(data, 0, len);
 363     }
 364 
 365     /**
 366      * Returns the total advance width for showing the specified array
 367      * of characters in this <code>Font</code>.  The advance is the
 368      * distance from the leftmost point to the rightmost point on the
 369      * string's baseline.  The advance of a <code>String</code>
 370      * is not necessarily the sum of the advances of its characters.
 371      * This is equivalent to measuring a <code>String</code> of the
 372      * characters in the specified range.
 373      * @param data the array of characters to be measured
 374      * @param off the start offset of the characters in the array
 375      * @param len the number of characters to be measured from the array
 376      * @return    the advance width of the subarray of the specified
 377      *               <code>char</code> array in the font described by
 378      *               this <code>FontMetrics</code> object.
 379      * @throws    NullPointerException if <code>data</code> is null.
 380      * @throws    IndexOutOfBoundsException if the <code>off</code>
 381      *            and <code>len</code> arguments index characters outside
 382      *            the bounds of the <code>data</code> array.
 383      * @see       #charWidth(int)
 384      * @see       #charWidth(char)
 385      * @see       #bytesWidth(byte[], int, int)
 386      * @see       #stringWidth(String)
 387      */
 388     public int charsWidth(char data[], int off, int len) {
 389         return stringWidth(new String(data, off, len));
 390     }
 391 
 392     /**
 393      * Returns the total advance width for showing the specified array
 394      * of bytes in this <code>Font</code>.  The advance is the
 395      * distance from the leftmost point to the rightmost point on the
 396      * string's baseline.  The advance of a <code>String</code>
 397      * is not necessarily the sum of the advances of its characters.
 398      * This is equivalent to measuring a <code>String</code> of the
 399      * characters in the specified range.
 400      * @param data the array of bytes to be measured
 401      * @param off the start offset of the bytes in the array
 402      * @param len the number of bytes to be measured from the array
 403      * @return    the advance width of the subarray of the specified
 404      *               <code>byte</code> array in the <code>Font</code>
 405      *                  described by
 406      *               this <code>FontMetrics</code> object.
 407      * @throws    NullPointerException if <code>data</code> is null.
 408      * @throws    IndexOutOfBoundsException if the <code>off</code>
 409      *            and <code>len</code> arguments index bytes outside
 410      *            the bounds of the <code>data</code> array.
 411      * @see       #charsWidth(char[], int, int)
 412      * @see       #stringWidth(String)
 413      */
 414     public int bytesWidth(byte data[], int off, int len) {
 415         return stringWidth(new String(data, off, len, StandardCharsets.ISO_8859_1));
 416     }
 417 
 418     /**
 419      * Gets the advance widths of the first 256 characters in the
 420      * <code>Font</code>.  The advance is the
 421      * distance from the leftmost point to the rightmost point on the
 422      * character's baseline.  Note that the advance of a
 423      * <code>String</code> is not necessarily the sum of the advances
 424      * of its characters.
 425      * @return    an array storing the advance widths of the
 426      *                 characters in the <code>Font</code>
 427      *                 described by this <code>FontMetrics</code> object.
 428      */
 429     public int[] getWidths() {
 430         int widths[] = new int[256];
 431         for (char ch = 0 ; ch < 256 ; ch++) {
 432             widths[ch] = charWidth(ch);
 433         }
 434         return widths;
 435     }
 436 
 437     /**
 438      * Checks to see if the <code>Font</code> has uniform line metrics.  A
 439      * composite font may consist of several different fonts to cover
 440      * various character sets.  In such cases, the
 441      * <code>FontLineMetrics</code> objects are not uniform.
 442      * Different fonts may have a different ascent, descent, metrics and
 443      * so on.  This information is sometimes necessary for line
 444      * measuring and line breaking.
 445      * @return <code>true</code> if the font has uniform line metrics;
 446      * <code>false</code> otherwise.
 447      * @see java.awt.Font#hasUniformLineMetrics()
 448      */
 449     public boolean hasUniformLineMetrics() {
 450         return font.hasUniformLineMetrics();
 451     }
 452 
 453     /**
 454      * Returns the {@link LineMetrics} object for the specified
 455      * <code>String</code> in the specified {@link Graphics} context.
 456      * @param str the specified <code>String</code>
 457      * @param context the specified <code>Graphics</code> context
 458      * @return a <code>LineMetrics</code> object created with the
 459      * specified <code>String</code> and <code>Graphics</code> context.
 460      * @see java.awt.Font#getLineMetrics(String, FontRenderContext)
 461      */
 462     public LineMetrics getLineMetrics( String str, Graphics context) {
 463         return font.getLineMetrics(str, myFRC(context));
 464     }
 465 
 466     /**
 467      * Returns the {@link LineMetrics} object for the specified
 468      * <code>String</code> in the specified {@link Graphics} context.
 469      * @param str the specified <code>String</code>
 470      * @param beginIndex the initial offset of <code>str</code>
 471      * @param limit the end offset of <code>str</code>
 472      * @param context the specified <code>Graphics</code> context
 473      * @return a <code>LineMetrics</code> object created with the
 474      * specified <code>String</code> and <code>Graphics</code> context.
 475      * @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext)
 476      */
 477     public LineMetrics getLineMetrics( String str,
 478                                             int beginIndex, int limit,
 479                                             Graphics context) {
 480         return font.getLineMetrics(str, beginIndex, limit, myFRC(context));
 481     }
 482 
 483     /**
 484      * Returns the {@link LineMetrics} object for the specified
 485      * character array in the specified {@link Graphics} context.
 486      * @param chars the specified character array
 487      * @param beginIndex the initial offset of <code>chars</code>
 488      * @param limit the end offset of <code>chars</code>
 489      * @param context the specified <code>Graphics</code> context
 490      * @return a <code>LineMetrics</code> object created with the
 491      * specified character array and <code>Graphics</code> context.
 492      * @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext)
 493      */
 494     public LineMetrics getLineMetrics(char [] chars,
 495                                             int beginIndex, int limit,
 496                                             Graphics context) {
 497         return font.getLineMetrics(
 498                                 chars, beginIndex, limit, myFRC(context));
 499     }
 500 
 501     /**
 502      * Returns the {@link LineMetrics} object for the specified
 503      * {@link CharacterIterator} in the specified {@link Graphics}
 504      * context.
 505      * @param ci the specified <code>CharacterIterator</code>
 506      * @param beginIndex the initial offset in <code>ci</code>
 507      * @param limit the end index of <code>ci</code>
 508      * @param context the specified <code>Graphics</code> context
 509      * @return a <code>LineMetrics</code> object created with the
 510      * specified arguments.
 511      * @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, FontRenderContext)
 512      */
 513     public LineMetrics getLineMetrics(CharacterIterator ci,
 514                                             int beginIndex, int limit,
 515                                             Graphics context) {
 516         return font.getLineMetrics(ci, beginIndex, limit, myFRC(context));
 517     }
 518 
 519     /**
 520      * Returns the bounds of the specified <code>String</code> in the
 521      * specified <code>Graphics</code> context.  The bounds is used
 522      * to layout the <code>String</code>.
 523      * <p>Note: The returned bounds is in baseline-relative coordinates
 524      * (see {@link java.awt.FontMetrics class notes}).
 525      * @param str the specified <code>String</code>
 526      * @param context the specified <code>Graphics</code> context
 527      * @return a {@link Rectangle2D} that is the bounding box of the
 528      * specified <code>String</code> in the specified
 529      * <code>Graphics</code> context.
 530      * @see java.awt.Font#getStringBounds(String, FontRenderContext)
 531      */
 532     public Rectangle2D getStringBounds( String str, Graphics context) {
 533         return font.getStringBounds(str, myFRC(context));
 534     }
 535 
 536     /**
 537      * Returns the bounds of the specified <code>String</code> in the
 538      * specified <code>Graphics</code> context.  The bounds is used
 539      * to layout the <code>String</code>.
 540      * <p>Note: The returned bounds is in baseline-relative coordinates
 541      * (see {@link java.awt.FontMetrics class notes}).
 542      * @param str the specified <code>String</code>
 543      * @param beginIndex the offset of the beginning of <code>str</code>
 544      * @param limit the end offset of <code>str</code>
 545      * @param context the specified <code>Graphics</code> context
 546      * @return a <code>Rectangle2D</code> that is the bounding box of the
 547      * specified <code>String</code> in the specified
 548      * <code>Graphics</code> context.
 549      * @see java.awt.Font#getStringBounds(String, int, int, FontRenderContext)
 550      */
 551     public Rectangle2D getStringBounds( String str,
 552                                         int beginIndex, int limit,
 553                                         Graphics context) {
 554         return font.getStringBounds(str, beginIndex, limit,
 555                                         myFRC(context));
 556     }
 557 
 558    /**
 559      * Returns the bounds of the specified array of characters
 560      * in the specified <code>Graphics</code> context.
 561      * The bounds is used to layout the <code>String</code>
 562      * created with the specified array of characters,
 563      * <code>beginIndex</code> and <code>limit</code>.
 564      * <p>Note: The returned bounds is in baseline-relative coordinates
 565      * (see {@link java.awt.FontMetrics class notes}).
 566      * @param chars an array of characters
 567      * @param beginIndex the initial offset of the array of
 568      * characters
 569      * @param limit the end offset of the array of characters
 570      * @param context the specified <code>Graphics</code> context
 571      * @return a <code>Rectangle2D</code> that is the bounding box of the
 572      * specified character array in the specified
 573      * <code>Graphics</code> context.
 574      * @see java.awt.Font#getStringBounds(char[], int, int, FontRenderContext)
 575      */
 576     public Rectangle2D getStringBounds( char [] chars,
 577                                         int beginIndex, int limit,
 578                                         Graphics context) {
 579         return font.getStringBounds(chars, beginIndex, limit,
 580                                         myFRC(context));
 581     }
 582 
 583    /**
 584      * Returns the bounds of the characters indexed in the specified
 585      * <code>CharacterIterator</code> in the
 586      * specified <code>Graphics</code> context.
 587      * <p>Note: The returned bounds is in baseline-relative coordinates
 588      * (see {@link java.awt.FontMetrics class notes}).
 589      * @param ci the specified <code>CharacterIterator</code>
 590      * @param beginIndex the initial offset in <code>ci</code>
 591      * @param limit the end index of <code>ci</code>
 592      * @param context the specified <code>Graphics</code> context
 593      * @return a <code>Rectangle2D</code> that is the bounding box of the
 594      * characters indexed in the specified <code>CharacterIterator</code>
 595      * in the specified <code>Graphics</code> context.
 596      * @see java.awt.Font#getStringBounds(CharacterIterator, int, int, FontRenderContext)
 597      */
 598     public Rectangle2D getStringBounds(CharacterIterator ci,
 599                                         int beginIndex, int limit,
 600                                         Graphics context) {
 601         return font.getStringBounds(ci, beginIndex, limit,
 602                                         myFRC(context));
 603     }
 604 
 605     /**
 606      * Returns the bounds for the character with the maximum bounds
 607      * in the specified <code>Graphics</code> context.
 608      * @param context the specified <code>Graphics</code> context
 609      * @return a <code>Rectangle2D</code> that is the
 610      * bounding box for the character with the maximum bounds.
 611      * @see java.awt.Font#getMaxCharBounds(FontRenderContext)
 612      */
 613     public Rectangle2D getMaxCharBounds(Graphics context) {
 614         return font.getMaxCharBounds(myFRC(context));
 615     }
 616 
 617     private FontRenderContext myFRC(Graphics context) {
 618         if (context instanceof Graphics2D) {
 619             return ((Graphics2D)context).getFontRenderContext();
 620         }
 621         return DEFAULT_FRC;
 622     }
 623 
 624 
 625     /**
 626      * Returns a representation of this <code>FontMetrics</code>
 627      * object's values as a <code>String</code>.
 628      * @return    a <code>String</code> representation of this
 629      * <code>FontMetrics</code> object.
 630      * @since     JDK1.0.
 631      */
 632     public String toString() {
 633         return getClass().getName() +
 634             "[font=" + getFont() +
 635             "ascent=" + getAscent() +
 636             ", descent=" + getDescent() +
 637             ", height=" + getHeight() + "]";
 638     }
 639 
 640     /**
 641      * Initialize JNI field and method IDs
 642      */
 643     private static native void initIDs();
 644 }