1 /*
   2  * Copyright (c) 1997, 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  * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
  28  * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
  29  *
  30  * The original version of this source code and documentation is
  31  * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
  32  * of IBM. These materials are provided under terms of a License
  33  * Agreement between Taligent and Sun. This technology is protected
  34  * by multiple US and International patents.
  35  *
  36  * This notice and attribution to Taligent may not be removed.
  37  * Taligent is a registered trademark of Taligent, Inc.
  38  *
  39  */
  40 
  41 package java.awt.font;
  42 
  43 import java.awt.geom.Rectangle2D;
  44 
  45 /**
  46  * The <code>GlyphMetrics</code> class represents information for a
  47  * single glyph.   A glyph is the visual representation of one or more
  48  * characters.  Many different glyphs can be used to represent a single
  49  * character or combination of characters.  <code>GlyphMetrics</code>
  50  * instances are produced by {@link java.awt.Font Font} and are applicable
  51  * to a specific glyph in a particular <code>Font</code>.
  52  * <p>
  53  * Glyphs are either STANDARD, LIGATURE, COMBINING, or COMPONENT.
  54  * <ul>
  55  * <li>STANDARD glyphs are commonly used to represent single characters.
  56  * <li>LIGATURE glyphs are used to represent sequences of characters.
  57  * <li>COMPONENT glyphs in a {@link GlyphVector} do not correspond to a
  58  * particular character in a text model. Instead, COMPONENT glyphs are
  59  * added for typographical reasons, such as Arabic justification.
  60  * <li>COMBINING glyphs embellish STANDARD or LIGATURE glyphs, such
  61  * as accent marks.  Carets do not appear before COMBINING glyphs.
  62  * </ul>
  63  * <p>
  64  * Other metrics available through <code>GlyphMetrics</code> are the
  65  * components of the advance, the visual bounds, and the left and right
  66  * side bearings.
  67  * <p>
  68  * Glyphs for a rotated font, or obtained from a <code>GlyphVector</code>
  69  * which has applied a rotation to the glyph, can have advances that
  70  * contain both X and Y components.  Usually the advance only has one
  71  * component.
  72  * <p>
  73  * The advance of a glyph is the distance from the glyph's origin to the
  74  * origin of the next glyph along the baseline, which is either vertical
  75  * or horizontal.  Note that, in a <code>GlyphVector</code>,
  76  * the distance from a glyph to its following glyph might not be the
  77  * glyph's advance, because of kerning or other positioning adjustments.
  78  * <p>
  79  * The bounds is the smallest rectangle that completely contains the
  80  * outline of the glyph.  The bounds rectangle is relative to the
  81  * glyph's origin.  The left-side bearing is the distance from the glyph
  82  * origin to the left of its bounds rectangle. If the left-side bearing is
  83  * negative, part of the glyph is drawn to the left of its origin.  The
  84  * right-side bearing is the distance from the right side of the bounds
  85  * rectangle to the next glyph origin (the origin plus the advance).  If
  86  * negative, part of the glyph is drawn to the right of the next glyph's
  87  * origin.  Note that the bounds does not necessarily enclose all the pixels
  88  * affected when rendering the glyph, because of rasterization and pixel
  89  * adjustment effects.
  90  * <p>
  91  * Although instances of <code>GlyphMetrics</code> can be directly
  92  * constructed, they are almost always obtained from a
  93  * <code>GlyphVector</code>.  Once constructed, <code>GlyphMetrics</code>
  94  * objects are immutable.
  95  * <p>
  96  * <strong>Example</strong>:<p>
  97  * Querying a <code>Font</code> for glyph information
  98  * <blockquote><pre>
  99  * Font font = ...;
 100  * int glyphIndex = ...;
 101  * GlyphMetrics metrics = GlyphVector.getGlyphMetrics(glyphIndex);
 102  * int isStandard = metrics.isStandard();
 103  * float glyphAdvance = metrics.getAdvance();
 104  * </pre></blockquote>
 105  * @see java.awt.Font
 106  * @see GlyphVector
 107  */
 108 
 109 public final class GlyphMetrics {
 110     /**
 111      * Indicates whether the metrics are for a horizontal or vertical baseline.
 112      */
 113     private boolean horizontal;
 114 
 115     /**
 116      * The x-component of the advance.
 117      */
 118     private float advanceX;
 119 
 120     /**
 121      * The y-component of the advance.
 122      */
 123     private float advanceY;
 124 
 125     /**
 126      * The bounds of the associated glyph.
 127      */
 128     private Rectangle2D.Float bounds;
 129 
 130     /**
 131      * Additional information about the glyph encoded as a byte.
 132      */
 133     private byte glyphType;
 134 
 135     /**
 136      * Indicates a glyph that represents a single standard
 137      * character.
 138      */
 139     public static final byte STANDARD = 0;
 140 
 141     /**
 142      * Indicates a glyph that represents multiple characters
 143      * as a ligature, for example 'fi' or 'ffi'.  It is followed by
 144      * filler glyphs for the remaining characters. Filler and combining
 145      * glyphs can be intermixed to control positioning of accent marks
 146      * on the logically preceding ligature.
 147      */
 148     public static final byte LIGATURE = 1;
 149 
 150     /**
 151      * Indicates a glyph that represents a combining character,
 152      * such as an umlaut.  There is no caret position between this glyph
 153      * and the preceding glyph.
 154      */
 155     public static final byte COMBINING = 2;
 156 
 157     /**
 158      * Indicates a glyph with no corresponding character in the
 159      * backing store.  The glyph is associated with the character
 160      * represented by the logically preceding non-component glyph.  This
 161      * is used for kashida justification or other visual modifications to
 162      * existing glyphs.  There is no caret position between this glyph
 163      * and the preceding glyph.
 164      */
 165     public static final byte COMPONENT = 3;
 166 
 167     /**
 168      * Indicates a glyph with no visual representation. It can
 169      * be added to the other code values to indicate an invisible glyph.
 170      */
 171     public static final byte WHITESPACE = 4;
 172 
 173     /**
 174      * Constructs a <code>GlyphMetrics</code> object.
 175      * @param advance the advance width of the glyph
 176      * @param bounds the black box bounds of the glyph
 177      * @param glyphType the type of the glyph
 178      */
 179     public GlyphMetrics(float advance, Rectangle2D bounds, byte glyphType) {
 180         this.horizontal = true;
 181         this.advanceX = advance;
 182         this.advanceY = 0;
 183         this.bounds = new Rectangle2D.Float();
 184         this.bounds.setRect(bounds);
 185         this.glyphType = glyphType;
 186     }
 187 
 188     /**
 189      * Constructs a <code>GlyphMetrics</code> object.
 190      * @param horizontal if true, metrics are for a horizontal baseline,
 191      *   otherwise they are for a vertical baseline
 192      * @param advanceX the X-component of the glyph's advance
 193      * @param advanceY the Y-component of the glyph's advance
 194      * @param bounds the visual bounds of the glyph
 195      * @param glyphType the type of the glyph
 196      * @since 1.4
 197      */
 198     public GlyphMetrics(boolean horizontal, float advanceX, float advanceY,
 199                         Rectangle2D bounds, byte glyphType) {
 200 
 201         this.horizontal = horizontal;
 202         this.advanceX = advanceX;
 203         this.advanceY = advanceY;
 204         this.bounds = new Rectangle2D.Float();
 205         this.bounds.setRect(bounds);
 206         this.glyphType = glyphType;
 207     }
 208 
 209     /**
 210      * Returns the advance of the glyph along the baseline (either
 211      * horizontal or vertical).
 212      * @return the advance of the glyph
 213      */
 214     public float getAdvance() {
 215         return horizontal ? advanceX : advanceY;
 216     }
 217 
 218     /**
 219      * Returns the x-component of the advance of the glyph.
 220      * @return the x-component of the advance of the glyph
 221      * @since 1.4
 222      */
 223     public float getAdvanceX() {
 224         return advanceX;
 225     }
 226 
 227     /**
 228      * Returns the y-component of the advance of the glyph.
 229      * @return the y-component of the advance of the glyph
 230      * @since 1.4
 231      */
 232     public float getAdvanceY() {
 233         return advanceY;
 234     }
 235 
 236     /**
 237      * Returns the bounds of the glyph. This is the bounding box of the glyph outline.
 238      * Because of rasterization and pixel alignment effects, it does not necessarily
 239      * enclose the pixels that are affected when rendering the glyph.
 240      * @return a {@link Rectangle2D} that is the bounds of the glyph.
 241      */
 242     public Rectangle2D getBounds2D() {
 243         return new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height);
 244     }
 245 
 246     /**
 247      * Returns the left (top) side bearing of the glyph.
 248      * <p>
 249      * This is the distance from 0,&nbsp;0 to the left (top) of the glyph
 250      * bounds.  If the bounds of the glyph is to the left of (above) the
 251      * origin, the LSB is negative.
 252      * @return the left side bearing of the glyph.
 253      */
 254     public float getLSB() {
 255         return horizontal ? bounds.x : bounds.y;
 256     }
 257 
 258     /**
 259      * Returns the right (bottom) side bearing of the glyph.
 260      * <p>
 261      * This is the distance from the right (bottom) of the glyph bounds to
 262      * the advance. If the bounds of the glyph is to the right of (below)
 263      * the advance, the RSB is negative.
 264      * @return the right side bearing of the glyph.
 265      */
 266     public float getRSB() {
 267         return horizontal ?
 268             advanceX - bounds.x - bounds.width :
 269             advanceY - bounds.y - bounds.height;
 270     }
 271 
 272     /**
 273      * Returns the raw glyph type code.
 274      * @return the raw glyph type code.
 275      */
 276     public int getType() {
 277         return glyphType;
 278     }
 279 
 280     /**
 281      * Returns <code>true</code> if this is a standard glyph.
 282      * @return <code>true</code> if this is a standard glyph;
 283      *          <code>false</code> otherwise.
 284      */
 285     public boolean isStandard() {
 286         return (glyphType & 0x3) == STANDARD;
 287     }
 288 
 289     /**
 290      * Returns <code>true</code> if this is a ligature glyph.
 291      * @return <code>true</code> if this is a ligature glyph;
 292      *          <code>false</code> otherwise.
 293      */
 294     public boolean isLigature() {
 295         return (glyphType & 0x3) == LIGATURE;
 296     }
 297 
 298     /**
 299      * Returns <code>true</code> if this is a combining glyph.
 300      * @return <code>true</code> if this is a combining glyph;
 301      *          <code>false</code> otherwise.
 302      */
 303     public boolean isCombining() {
 304         return (glyphType & 0x3) == COMBINING;
 305     }
 306 
 307     /**
 308      * Returns <code>true</code> if this is a component glyph.
 309      * @return <code>true</code> if this is a component glyph;
 310      *          <code>false</code> otherwise.
 311      */
 312     public boolean isComponent() {
 313         return (glyphType & 0x3) == COMPONENT;
 314     }
 315 
 316     /**
 317      * Returns <code>true</code> if this is a whitespace glyph.
 318      * @return <code>true</code> if this is a whitespace glyph;
 319      *          <code>false</code> otherwise.
 320      */
 321     public boolean isWhitespace() {
 322         return (glyphType & 0x4) == WHITESPACE;
 323     }
 324 }
--- EOF ---