1 /*
   2  * Copyright (c) 1998, 2020, 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 /*
  27  * @author Charlton Innovations, Inc.
  28  */
  29 
  30 package java.awt.font;
  31 
  32 import java.awt.Graphics2D;
  33 import java.awt.Font;
  34 import java.awt.Polygon;        // remind - need a floating point version
  35 import java.awt.Rectangle;
  36 import java.awt.geom.Point2D;
  37 import java.awt.geom.Rectangle2D;
  38 import java.awt.geom.AffineTransform;
  39 import java.awt.Shape;
  40 import java.awt.font.GlyphMetrics;
  41 import java.awt.font.GlyphJustificationInfo;
  42 
  43 /**
  44  * A {@code GlyphVector} object is a collection of glyphs
  45  * containing geometric information for the placement of each glyph
  46  * in a transformed coordinate space which corresponds to the
  47  * device on which the {@code GlyphVector} is ultimately
  48  * displayed.
  49  * <p>
  50  * The {@code GlyphVector} does not attempt any interpretation of
  51  * the sequence of glyphs it contains.  Relationships between adjacent
  52  * glyphs in sequence are solely used to determine the placement of
  53  * the glyphs in the visual coordinate space.
  54  * <p>
  55  * Instances of {@code GlyphVector} are created by a {@link Font}.
  56  * <p>
  57  * In a text processing application that can cache intermediate
  58  * representations of text, creation and subsequent caching of a
  59  * {@code GlyphVector} for use during rendering is the fastest
  60  * method to present the visual representation of characters to a user.
  61  * <p>
  62  * A {@code GlyphVector} is associated with exactly one
  63  * {@code Font}, and can provide data useful only in relation to
  64  * this {@code Font}.  In addition, metrics obtained from a
  65  * {@code GlyphVector} are not generally geometrically scalable
  66  * since the pixelization and spacing are dependent on grid-fitting
  67  * algorithms within a {@code Font}.  To facilitate accurate
  68  * measurement of a {@code GlyphVector} and its component
  69  * glyphs, you must specify a scaling transform, anti-alias mode, and
  70  * fractional metrics mode when creating the {@code GlyphVector}.
  71  * These characteristics can be derived from the destination device.
  72  * <p>
  73  * For each glyph in the {@code GlyphVector}, you can obtain:
  74  * <ul>
  75  * <li>the position of the glyph
  76  * <li>the transform associated with the glyph
  77  * <li>the metrics of the glyph in the context of the
  78  *   {@code GlyphVector}.  The metrics of the glyph may be
  79  *   different under different transforms, application specified
  80  *   rendering hints, and the specific instance of the glyph within
  81  *   the {@code GlyphVector}.
  82  * </ul>
  83  * <p>
  84  * Altering the data used to create the {@code GlyphVector} does not
  85  * alter the state of the {@code GlyphVector}.
  86  * <p>
  87  * Methods are provided to adjust the positions of the glyphs
  88  * within the {@code GlyphVector}.  These methods are most
  89  * appropriate for applications that are performing justification
  90  * operations for the presentation of the glyphs.
  91  * <p>
  92  * Methods are provided to transform individual glyphs within the
  93  * {@code GlyphVector}.  These methods are primarily useful for
  94  * special effects.
  95  * <p>
  96  * Methods are provided to return both the visual, logical, and pixel bounds
  97  * of the entire {@code GlyphVector} or of individual glyphs within
  98  * the {@code GlyphVector}.
  99  * <p>
 100  * Methods are provided to return a {@link Shape} for the
 101  * {@code GlyphVector}, and for individual glyphs within the
 102  * {@code GlyphVector}.
 103  * @see Font
 104  * @see GlyphMetrics
 105  * @see TextLayout
 106  * @author Charlton Innovations, Inc.
 107  */
 108 
 109 public abstract class GlyphVector implements Cloneable {
 110 
 111     /**
 112      * Constructor for subclasses to call.
 113      */
 114     public GlyphVector() {}
 115 
 116     //
 117     // methods associated with creation-time state
 118     //
 119 
 120     /**
 121      * Returns the {@code Font} associated with this
 122      * {@code GlyphVector}.
 123      * @return {@code Font} used to create this
 124      * {@code GlyphVector}.
 125      * @see Font
 126      */
 127     public abstract Font getFont();
 128 
 129     /**
 130      * Returns the {@link FontRenderContext} associated with this
 131      * {@code GlyphVector}.
 132      * @return {@code FontRenderContext} used to create this
 133      * {@code GlyphVector}.
 134      * @see FontRenderContext
 135      * @see Font
 136      */
 137     public abstract FontRenderContext getFontRenderContext();
 138 
 139     //
 140     // methods associated with the GlyphVector as a whole
 141     //
 142 
 143     /**
 144      * Assigns default positions to each glyph in this
 145      * {@code GlyphVector}. This can destroy information
 146      * generated during initial layout of this {@code GlyphVector}.
 147      */
 148     public abstract void performDefaultLayout();
 149 
 150     /**
 151      * Returns the number of glyphs in this {@code GlyphVector}.
 152      * @return number of glyphs in this {@code GlyphVector}.
 153      */
 154     public abstract int getNumGlyphs();
 155 
 156     /**
 157      * Returns the glyphcode of the specified glyph.
 158      * This return value is meaningless to anything other
 159      * than the {@code Font} object that created this
 160      * {@code GlyphVector}.
 161      * @param glyphIndex the index into this {@code GlyphVector}
 162      * that corresponds to the glyph from which to retrieve the
 163      * glyphcode.
 164      * @return the glyphcode of the glyph at the specified
 165      * {@code glyphIndex}.
 166      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 167      * is less than 0 or greater than or equal to the
 168      * number of glyphs in this {@code GlyphVector}
 169      */
 170     public abstract int getGlyphCode(int glyphIndex);
 171 
 172     /**
 173      * Returns an array of glyphcodes for the specified glyphs.
 174      * The contents of this return value are meaningless to anything other
 175      * than the {@code Font} used to create this
 176      * {@code GlyphVector}.  This method is used
 177      * for convenience and performance when processing glyphcodes.
 178      * If no array is passed in, a new array is created.
 179      * @param beginGlyphIndex the index into this
 180      *   {@code GlyphVector} at which to start retrieving glyphcodes
 181      * @param numEntries the number of glyphcodes to retrieve
 182      * @param codeReturn the array that receives the glyphcodes and is
 183      *   then returned
 184      * @return an array of glyphcodes for the specified glyphs.
 185      * @throws IllegalArgumentException if {@code numEntries} is
 186      *   less than 0
 187      * @throws IndexOutOfBoundsException if {@code beginGlyphIndex}
 188      *   is less than 0
 189      * @throws IndexOutOfBoundsException if the sum of
 190      *   {@code beginGlyphIndex} and {@code numEntries} is
 191      *   greater than the number of glyphs in this
 192      *   {@code GlyphVector}
 193      */
 194     public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
 195                                         int[] codeReturn);
 196 
 197     /**
 198      * Returns the character index of the specified glyph.
 199      * The character index is the index of the first logical
 200      * character represented by the glyph.  The default
 201      * implementation assumes a one-to-one, left-to-right mapping
 202      * of glyphs to characters.
 203      * @param glyphIndex the index of the glyph
 204      * @return the index of the first character represented by the glyph
 205      * @since 1.4
 206      */
 207     public int getGlyphCharIndex(int glyphIndex) {
 208         return glyphIndex;
 209     }
 210 
 211     /**
 212      * Returns the character indices of the specified glyphs.
 213      * The character index is the index of the first logical
 214      * character represented by the glyph.  Indices are returned
 215      * in glyph order.  The default implementation invokes
 216      * getGlyphCharIndex for each glyph, and subclassers will probably
 217      * want to override this implementation for performance reasons.
 218      * Use this method for convenience and performance
 219      * in processing of glyphcodes. If no array is passed in,
 220      * a new array is created.
 221      * @param beginGlyphIndex the index of the first glyph
 222      * @param numEntries the number of glyph indices
 223      * @param codeReturn the array into which to return the character indices
 224      * @return an array of character indices, one per glyph.
 225      * @since 1.4
 226      */
 227     public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries,
 228                                      int[] codeReturn) {
 229         if (codeReturn == null) {
 230             codeReturn = new int[numEntries];
 231         }
 232         for (int i = 0, j = beginGlyphIndex; i < numEntries; ++i, ++j) {
 233             codeReturn[i] = getGlyphCharIndex(j);
 234         }
 235         return codeReturn;
 236      }
 237 
 238     /**
 239      * Returns the logical bounds of this {@code GlyphVector}.
 240      * This method is used when positioning this {@code GlyphVector}
 241      * in relation to visually adjacent {@code GlyphVector} objects.
 242      * @return a {@link Rectangle2D} that is the logical bounds of this
 243      * {@code GlyphVector}.
 244      */
 245     public abstract Rectangle2D getLogicalBounds();
 246 
 247     /**
 248      * Returns the visual bounds of this {@code GlyphVector}
 249      * The visual bounds is the bounding box of the outline of this
 250      * {@code GlyphVector}.  Because of rasterization and
 251      * alignment of pixels, it is possible that this box does not
 252      * enclose all pixels affected by rendering this {@code GlyphVector}.
 253      * @return a {@code Rectangle2D} that is the bounding box
 254      * of this {@code GlyphVector}.
 255      */
 256     public abstract Rectangle2D getVisualBounds();
 257 
 258     /**
 259      * Returns the pixel bounds of this {@code GlyphVector} when
 260      * rendered in a graphics with the given
 261      * {@code FontRenderContext} at the given location.  The
 262      * renderFRC need not be the same as the
 263      * {@code FontRenderContext} of this
 264      * {@code GlyphVector}, and can be null.  If it is null, the
 265      * {@code FontRenderContext} of this {@code GlyphVector}
 266      * is used.  The default implementation returns the visual bounds,
 267      * offset to x, y and rounded out to the next integer value (i.e. returns an
 268      * integer rectangle which encloses the visual bounds) and
 269      * ignores the FRC.  Subclassers should override this method.
 270      * @param renderFRC the {@code FontRenderContext} of the {@code Graphics}.
 271      * @param x the x-coordinate at which to render this {@code GlyphVector}.
 272      * @param y the y-coordinate at which to render this {@code GlyphVector}.
 273      * @return a {@code Rectangle} bounding the pixels that would be affected.
 274      * @since 1.4
 275      */
 276     public Rectangle getPixelBounds(FontRenderContext renderFRC, float x, float y) {
 277                 Rectangle2D rect = getVisualBounds();
 278                 int l = (int)Math.floor(rect.getX() + x);
 279                 int t = (int)Math.floor(rect.getY() + y);
 280                 int r = (int)Math.ceil(rect.getMaxX() + x);
 281                 int b = (int)Math.ceil(rect.getMaxY() + y);
 282                 return new Rectangle(l, t, r - l, b - t);
 283         }
 284 
 285 
 286     /**
 287      * Returns a {@code Shape} whose interior corresponds to the
 288      * visual representation of this {@code GlyphVector}.
 289      * @return a {@code Shape} that is the outline of this
 290      * {@code GlyphVector}.
 291      */
 292     public abstract Shape getOutline();
 293 
 294     /**
 295      * Returns a {@code Shape} whose interior corresponds to the
 296      * visual representation of this {@code GlyphVector} when
 297      * rendered at x,&nbsp;y.
 298      * @param x the X coordinate of this {@code GlyphVector}.
 299      * @param y the Y coordinate of this {@code GlyphVector}.
 300      * @return a {@code Shape} that is the outline of this
 301      *   {@code GlyphVector} when rendered at the specified
 302      *   coordinates.
 303      */
 304     public abstract Shape getOutline(float x, float y);
 305 
 306     /**
 307      * Returns a {@code Shape} whose interior corresponds to the
 308      * visual representation of the specified glyph
 309      * within this {@code GlyphVector}.
 310      * The outline returned by this method is positioned around the
 311      * origin of each individual glyph.
 312      * @param glyphIndex the index into this {@code GlyphVector}
 313      * @return a {@code Shape} that is the outline of the glyph
 314      *   at the specified {@code glyphIndex} of this
 315      *   {@code GlyphVector}.
 316      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 317      *   is less than 0 or greater than or equal to the number
 318      *   of glyphs in this {@code GlyphVector}
 319      */
 320     public abstract Shape getGlyphOutline(int glyphIndex);
 321 
 322     /**
 323      * Returns a {@code Shape} whose interior corresponds to the
 324      * visual representation of the specified glyph
 325      * within this {@code GlyphVector}, offset to x,&nbsp;y.
 326      * The outline returned by this method is positioned around the
 327      * origin of each individual glyph.
 328      * @param glyphIndex the index into this {@code GlyphVector}
 329      * @param x the X coordinate of the location of this {@code GlyphVector}
 330      * @param y the Y coordinate of the location of this {@code GlyphVector}
 331      * @return a {@code Shape} that is the outline of the glyph
 332      *   at the specified {@code glyphIndex} of this
 333      *   {@code GlyphVector} when rendered at the specified
 334      *   coordinates.
 335      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 336      *   is less than 0 or greater than or equal to the number
 337      *   of glyphs in this {@code GlyphVector}
 338      * @since 1.4
 339      */
 340     public Shape getGlyphOutline(int glyphIndex, float x, float y) {
 341         Shape s = getGlyphOutline(glyphIndex);
 342         AffineTransform at = AffineTransform.getTranslateInstance(x,y);
 343         return at.createTransformedShape(s);
 344         }
 345 
 346     /**
 347      * Returns the position of the specified glyph relative to the
 348      * origin of this {@code GlyphVector}.
 349      * If {@code glyphIndex} equals the number of glyphs in
 350      * this {@code GlyphVector}, this method returns the position after
 351      * the last glyph. This position is used to define the advance of
 352      * the entire {@code GlyphVector}.
 353      * @param glyphIndex the index into this {@code GlyphVector}
 354      * @return a {@link Point2D} object that is the position of the glyph
 355      *   at the specified {@code glyphIndex}.
 356      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 357      *   is less than 0 or greater than the number of glyphs
 358      *   in this {@code GlyphVector}
 359      * @see #setGlyphPosition
 360      */
 361     public abstract Point2D getGlyphPosition(int glyphIndex);
 362 
 363     /**
 364      * Sets the position of the specified glyph within this
 365      * {@code GlyphVector}.
 366      * If {@code glyphIndex} equals the number of glyphs in
 367      * this {@code GlyphVector}, this method sets the position after
 368      * the last glyph. This position is used to define the advance of
 369      * the entire {@code GlyphVector}.
 370      * @param glyphIndex the index into this {@code GlyphVector}
 371      * @param newPos the {@code Point2D} at which to position the
 372      *   glyph at the specified {@code glyphIndex}
 373      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 374      *   is less than 0 or greater than the number of glyphs
 375      *   in this {@code GlyphVector}
 376      * @see #getGlyphPosition
 377      */
 378     public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
 379 
 380     /**
 381      * Returns the transform of the specified glyph within this
 382      * {@code GlyphVector}.  The transform is relative to the
 383      * glyph position.  If no special transform has been applied,
 384      * {@code null} can be returned.  A null return indicates
 385      * an identity transform.
 386      * @param glyphIndex the index into this {@code GlyphVector}
 387      * @return an {@link AffineTransform} that is the transform of
 388      *   the glyph at the specified {@code glyphIndex}.
 389      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 390      *   is less than 0 or greater than or equal to the number
 391      *   of glyphs in this {@code GlyphVector}
 392      * @see #setGlyphTransform
 393      */
 394     public abstract AffineTransform getGlyphTransform(int glyphIndex);
 395 
 396     /**
 397      * Sets the transform of the specified glyph within this
 398      * {@code GlyphVector}.  The transform is relative to the glyph
 399      * position.  A {@code null} argument for {@code newTX}
 400      * indicates that no special transform is applied for the specified
 401      * glyph.
 402      * This method can be used to rotate, mirror, translate and scale the
 403      * glyph.  Adding a transform can result in significant performance changes.
 404      * @param glyphIndex the index into this {@code GlyphVector}
 405      * @param newTX the new transform of the glyph at {@code glyphIndex}
 406      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 407      *   is less than 0 or greater than or equal to the number
 408      *   of glyphs in this {@code GlyphVector}
 409      * @see #getGlyphTransform
 410      */
 411     public abstract void setGlyphTransform(int glyphIndex, AffineTransform newTX);
 412 
 413     /**
 414      * Returns flags describing the global state of the GlyphVector.
 415      * Flags not described below are reserved.  The default
 416      * implementation returns 0 (meaning false) for the position adjustments,
 417      * transforms, rtl, and complex flags.
 418      * Subclassers should override this method, and make sure
 419      * it correctly describes the GlyphVector and corresponds
 420      * to the results of related calls.
 421      * @return an int containing the flags describing the state
 422      * @see #FLAG_HAS_POSITION_ADJUSTMENTS
 423      * @see #FLAG_HAS_TRANSFORMS
 424      * @see #FLAG_RUN_RTL
 425      * @see #FLAG_COMPLEX_GLYPHS
 426      * @see #FLAG_MASK
 427      * @since 1.4
 428      */
 429     public int getLayoutFlags() {
 430                 return 0;
 431         }
 432 
 433     /**
 434      * A flag used with getLayoutFlags that indicates that this {@code GlyphVector} has
 435      * per-glyph transforms.
 436      * @since 1.4
 437      */
 438     public static final int FLAG_HAS_TRANSFORMS = 1;
 439 
 440     /**
 441      * A flag used with getLayoutFlags that indicates that this {@code GlyphVector} has
 442      * position adjustments.  When this is true, the glyph positions don't match the
 443      * accumulated default advances of the glyphs (for example, if kerning has been done).
 444      * @since 1.4
 445      */
 446     public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
 447 
 448     /**
 449      * A flag used with getLayoutFlags that indicates that this {@code GlyphVector} has
 450      * a right-to-left run direction.  This refers to the glyph-to-char mapping and does
 451      * not imply that the visual locations of the glyphs are necessarily in this order,
 452      * although generally they will be.
 453      * @since 1.4
 454      */
 455     public static final int FLAG_RUN_RTL = 4;
 456 
 457     /**
 458      * A flag used with getLayoutFlags that indicates that this {@code GlyphVector} has
 459      * a complex glyph-to-char mapping (one that does not map glyphs to chars one-to-one in
 460      * strictly ascending or descending order matching the run direction).
 461      * @since 1.4
 462      */
 463     public static final int FLAG_COMPLEX_GLYPHS = 8;
 464 
 465     /**
 466      * A mask for supported flags from getLayoutFlags.  Only bits covered by the mask
 467      * should be tested.
 468      * @since 1.4
 469      */
 470     public static final int FLAG_MASK =
 471         FLAG_HAS_TRANSFORMS |
 472         FLAG_HAS_POSITION_ADJUSTMENTS |
 473         FLAG_RUN_RTL |
 474         FLAG_COMPLEX_GLYPHS;
 475 
 476     /**
 477      * Returns an array of glyph positions for the specified glyphs.
 478      * This method is used for convenience and performance when
 479      * processing glyph positions.
 480      * If no array is passed in, a new array is created.
 481      * Even numbered array entries beginning with position zero are the X
 482      * coordinates of the glyph numbered {@code beginGlyphIndex + position/2}.
 483      * Odd numbered array entries beginning with position one are the Y
 484      * coordinates of the glyph numbered {@code beginGlyphIndex + (position-1)/2}.
 485      * If {@code beginGlyphIndex} equals the number of glyphs in
 486      * this {@code GlyphVector}, this method gets the position after
 487      * the last glyph and this position is used to define the advance of
 488      * the entire {@code GlyphVector}.
 489      * @param beginGlyphIndex the index at which to begin retrieving
 490      *   glyph positions
 491      * @param numEntries the number of glyphs to retrieve
 492      * @param positionReturn the array that receives the glyph positions
 493      *   and is then returned.
 494      * @return an array of glyph positions specified by
 495      *  {@code beginGlyphIndex} and {@code numEntries}.
 496      * @throws IllegalArgumentException if {@code numEntries} is
 497      *   less than 0
 498      * @throws IndexOutOfBoundsException if {@code beginGlyphIndex}
 499      *   is less than 0
 500      * @throws IndexOutOfBoundsException if the sum of
 501      *   {@code beginGlyphIndex} and {@code numEntries}
 502      *   is greater than the number of glyphs in this
 503      *   {@code GlyphVector} plus one
 504      */
 505     public abstract float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
 506                                               float[] positionReturn);
 507 
 508     /**
 509      * Returns the logical bounds of the specified glyph within this
 510      * {@code GlyphVector}.
 511      * These logical bounds have a total of four edges, with two edges
 512      * parallel to the baseline under the glyph's transform and the other two
 513      * edges are shared with adjacent glyphs if they are present.  This
 514      * method is useful for hit-testing of the specified glyph,
 515      * positioning of a caret at the leading or trailing edge of a glyph,
 516      * and for drawing a highlight region around the specified glyph.
 517      * @param glyphIndex the index into this {@code GlyphVector}
 518      *   that corresponds to the glyph from which to retrieve its logical
 519      *   bounds
 520      * @return  a {@code Shape} that is the logical bounds of the
 521      *   glyph at the specified {@code glyphIndex}.
 522      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 523      *   is less than 0 or greater than or equal to the number
 524      *   of glyphs in this {@code GlyphVector}
 525      * @see #getGlyphVisualBounds
 526      */
 527     public abstract Shape getGlyphLogicalBounds(int glyphIndex);
 528 
 529     /**
 530      * Returns the visual bounds of the specified glyph within the
 531      * {@code GlyphVector}.
 532      * The bounds returned by this method is positioned around the
 533      * origin of each individual glyph.
 534      * @param glyphIndex the index into this {@code GlyphVector}
 535      *   that corresponds to the glyph from which to retrieve its visual
 536      *   bounds
 537      * @return a {@code Shape} that is the visual bounds of the
 538      *   glyph at the specified {@code glyphIndex}.
 539      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 540      *   is less than 0 or greater than or equal to the number
 541      *   of glyphs in this {@code GlyphVector}
 542      * @see #getGlyphLogicalBounds
 543      */
 544     public abstract Shape getGlyphVisualBounds(int glyphIndex);
 545 
 546     /**
 547      * Returns the pixel bounds of the glyph at index when this
 548      * {@code GlyphVector} is rendered in a {@code Graphics} with the
 549      * given {@code FontRenderContext} at the given location. The
 550      * renderFRC need not be the same as the
 551      * {@code FontRenderContext} of this
 552      * {@code GlyphVector}, and can be null.  If it is null, the
 553      * {@code FontRenderContext} of this {@code GlyphVector}
 554      * is used.  The default implementation returns the visual bounds of the glyph,
 555      * offset to x, y and rounded out to the next integer value, and
 556      * ignores the FRC.  Subclassers should override this method.
 557      * @param index the index of the glyph.
 558      * @param renderFRC the {@code FontRenderContext} of the {@code Graphics}.
 559      * @param x the X position at which to render this {@code GlyphVector}.
 560      * @param y the Y position at which to render this {@code GlyphVector}.
 561      * @return a {@code Rectangle} bounding the pixels that would be affected.
 562      * @since 1.4
 563      */
 564     public Rectangle getGlyphPixelBounds(int index, FontRenderContext renderFRC, float x, float y) {
 565                 Rectangle2D rect = getGlyphVisualBounds(index).getBounds2D();
 566                 int l = (int)Math.floor(rect.getX() + x);
 567                 int t = (int)Math.floor(rect.getY() + y);
 568                 int r = (int)Math.ceil(rect.getMaxX() + x);
 569                 int b = (int)Math.ceil(rect.getMaxY() + y);
 570                 return new Rectangle(l, t, r - l, b - t);
 571         }
 572 
 573     /**
 574      * Returns the metrics of the glyph at the specified index into
 575      * this {@code GlyphVector}.
 576      * @param glyphIndex the index into this {@code GlyphVector}
 577      *   that corresponds to the glyph from which to retrieve its metrics
 578      * @return a {@link GlyphMetrics} object that represents the
 579      *   metrics of the glyph at the specified {@code glyphIndex}
 580      *   into this {@code GlyphVector}.
 581      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 582      *   is less than 0 or greater than or equal to the number
 583      *   of glyphs in this {@code GlyphVector}
 584      */
 585     public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
 586 
 587     /**
 588      * Returns the justification information for the glyph at
 589      * the specified index into this {@code GlyphVector}.
 590      * @param glyphIndex the index into this {@code GlyphVector}
 591      *   that corresponds to the glyph from which to retrieve its
 592      *   justification properties
 593      * @return a {@link GlyphJustificationInfo} object that
 594      *   represents the justification properties of the glyph at the
 595      *   specified {@code glyphIndex} into this
 596      *   {@code GlyphVector}.
 597      * @throws IndexOutOfBoundsException if {@code glyphIndex}
 598      *   is less than 0 or greater than or equal to the number
 599      *   of glyphs in this {@code GlyphVector}
 600      */
 601     public abstract GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex);
 602 
 603     //
 604     // general utility methods
 605     //
 606 
 607     /**
 608      * Tests if the specified {@code GlyphVector} exactly
 609      * equals this {@code GlyphVector}.
 610      * @param set the specified {@code GlyphVector} to test
 611      * @return {@code true} if the specified
 612      *   {@code GlyphVector} equals this {@code GlyphVector};
 613      *   {@code false} otherwise.
 614      */
 615     public abstract boolean equals(GlyphVector set);
 616 }