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