- /*
- * @(#)GlyphMetrics.java 1.40 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- /*
- * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
- *
- * The original version of this source code and documentation is
- * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
- * of IBM. These materials are provided under terms of a License
- * Agreement between Taligent and Sun. This technology is protected
- * by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- *
- */
-
- package java.awt.font;
-
- import java.awt.geom.Rectangle2D;
-
- /**
- * The <code>GlyphMetrics</code> class represents infomation for a
- * single glyph. A glyph is the visual representation of one or more
- * characters. Many different glyphs can be used to represent a single
- * character or combination of characters. <code>GlyphMetrics</code>
- * instances are produced by {@link java.awt.Font Font} and are applicable
- * to a specific glyph in a particular <code>Font</code>.
- * <p>
- * Glyphs are either STANDARD, LIGATURE, COMBINING, or COMPONENT.
- * <ul>
- * <li>STANDARD glyphs are commonly used to represent single characters.
- * <li>LIGATURE glyphs are used to represent sequences of characters.
- * <li>COMPONENT glyphs in a {@link GlyphVector} do not correspond to a
- * particular character in a text model. Instead, COMPONENT glyphs are
- * added for typographical reasons, such as Arabic justification.
- * <li>COMBINING glyphs embellish STANDARD or LIGATURE glyphs, such
- * as accent marks. Carets do not appear before COMBINING glyphs.
- * </ul>
- * <p>
- * Other metrics available through <code>GlyphMetrics</code> are the
- * components of the advance, the visual bounds, and the left and right
- * side bearings.
- * <p>
- * Glyphs for a rotated font, or obtained from a <code>GlyphVector</code>
- * which has applied a rotation to the glyph, can have advances that
- * contain both X and Y components. Usually the advance only has one
- * component.
- * <p>
- * The advance of a glyph is the distance from the glyph's origin to the
- * origin of the next glyph along the baseline, which is either vertical
- * or horizontal. Note that, in a <code>GlyphVector</code>,
- * the distance from a glyph to its following glyph might not be the
- * glyph's advance, because of kerning or other positioning adjustments.
- * <p>
- * The bounds is the smallest rectangle that completely contains the
- * outline of the glyph. The bounds rectangle is relative to the
- * glyph's origin. The left-side bearing is the distance from the glyph
- * origin to the left of its bounds rectangle. If the left-side bearing is
- * negative, part of the glyph is drawn to the left of its origin. The
- * right-side bearing is the distance from the right side of the bounds
- * rectangle to the next glyph origin (the origin plus the advance). If
- * negative, part of the glyph is drawn to the right of the next glyph's
- * origin. Note that the bounds does not necessarily enclose all the pixels
- * affected when rendering the glyph, because of rasterization and pixel
- * adjustment effects.
- * <p>
- * Although instances of <code>GlyphMetrics</code> can be directly
- * constructed, they are almost always obtained from a
- * <code>GlyphVector</code>. Once constructed, <code>GlyphMetrics</code>
- * objects are immutable.
- * <p>
- * <strong>Example</strong>:<p>
- * Querying a <code>Font</code> for glyph information
- * <blockquote><pre>
- * Font font = ...;
- * int glyphIndex = ...;
- * GlyphMetrics metrics = GlyphVector.getGlyphMetrics(glyphIndex);
- * int isStandard = metrics.isStandard();
- * float glyphAdvance = metrics.getAdvance();
- * </pre></blockquote>
- * @see java.awt.Font
- * @see GlyphVector
- */
-
- public final class GlyphMetrics {
- /**
- * Indicates whether the metrics are for a horizontal or vertical baseline.
- */
- private boolean horizontal;
-
- /**
- * The x-component of the advance.
- */
- private float advanceX;
-
- /**
- * The y-component of the advance.
- */
- private float advanceY;
-
- /**
- * The bounds of the associated glyph.
- */
- private Rectangle2D.Float bounds;
-
- /**
- * Additional information about the glyph encoded as a byte.
- */
- private byte glyphType;
-
- /**
- * Indicates a glyph that represents a single standard
- * character.
- */
- public static final byte STANDARD = 0;
-
- /**
- * Indicates a glyph that represents multiple characters
- * as a ligature, for example 'fi' or 'ffi'. It is followed by
- * filler glyphs for the remaining characters. Filler and combining
- * glyphs can be intermixed to control positioning of accent marks
- * on the logically preceeding ligature.
- */
- public static final byte LIGATURE = 1;
-
- /**
- * Indicates a glyph that represents a combining character,
- * such as an umlaut. There is no caret position between this glyph
- * and the preceeding glyph.
- */
- public static final byte COMBINING = 2;
-
- /**
- * Indicates a glyph with no corresponding character in the
- * backing store. The glyph is associated with the character
- * represented by the logicaly preceeding non-component glyph. This
- * is used for kashida justification or other visual modifications to
- * existing glyphs. There is no caret position between this glyph
- * and the preceeding glyph.
- */
- public static final byte COMPONENT = 3;
-
- /**
- * Indicates a glyph with no visual representation. It can
- * be added to the other code values to indicate an invisible glyph.
- */
- public static final byte WHITESPACE = 4;
-
- /**
- * Constructs a <code>GlyphMetrics</code> object.
- * @param advance the advance width of the glyph
- * @param bounds the black box bounds of the glyph
- * @param glyphType the type of the glyph
- */
- public GlyphMetrics(float advance, Rectangle2D bounds, byte glyphType) {
- this.horizontal = true;
- this.advanceX = advance;
- this.advanceY = 0;
- this.bounds = new Rectangle2D.Float();
- this.bounds.setRect(bounds);
- this.glyphType = glyphType;
- }
-
- /**
- * Constructs a <code>GlyphMetrics</code> object.
- * @param horizontal if true, metrics are for a horizontal baseline,
- * otherwise they are for a vertical baseline
- * @param advanceX the X-component of the glyph's advance
- * @param advanceY the Y-component of the glyph's advance
- * @param bounds the visual bounds of the glyph
- * @param glyphType the type of the glyph
- */
- public GlyphMetrics(boolean horizontal, float advanceX, float advanceY,
- Rectangle2D bounds, byte glyphType) {
-
- this.horizontal = horizontal;
- this.advanceX = advanceX;
- this.advanceY = advanceY;
- this.bounds = new Rectangle2D.Float();
- this.bounds.setRect(bounds);
- this.glyphType = glyphType;
- }
-
- /**
- * Returns the advance of the glyph along the baseline (either
- * horizontal or vertical).
- * @return the advance of the glyph
- */
- public float getAdvance() {
- return horizontal ? advanceX : advanceY;
- }
-
- /**
- * Returns the x-component of the advance of the glyph.
- * @return the x-component of the advance of the glyph
- */
- public float getAdvanceX() {
- return advanceX;
- }
-
- /**
- * Returns the y-component of the advance of the glyph.
- * @return the y-component of the advance of the glyph
- */
- public float getAdvanceY() {
- return advanceY;
- }
-
- /**
- * Returns the bounds of the glyph. This is the bounding box of the glyph outline.
- * Because of rasterization and pixel alignment effects, it does not necessarily
- * enclose the pixels that are affected when rendering the glyph.
- * @return a {@link Rectangle2D} that is the bounds of the glyph.
- */
- public Rectangle2D getBounds2D() {
- return new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height);
- }
-
- /**
- * Returns the left (top) side bearing of the glyph.
- * <p>
- * This is the distance from 0, 0 to the left (top) of the glyph
- * bounds. If the bounds of the glyph is to the left of (above) the
- * origin, the LSB is negative.
- * @return the left side bearing of the glyph.
- */
- public float getLSB() {
- return horizontal ? bounds.x : bounds.y;
- }
-
- /**
- * Returns the right (bottom) side bearing of the glyph.
- * <p>
- * This is the distance from the right (bottom) of the glyph bounds to
- * the advance. If the bounds of the glyph is to the right of (below)
- * the advance, the RSB is negative.
- * @return the right side bearing of the glyph.
- */
- public float getRSB() {
- return horizontal ?
- advanceX - bounds.x - bounds.width :
- advanceY - bounds.y - bounds.height;
- }
-
- /**
- * Returns the raw glyph type code.
- * @return the raw glyph type code.
- */
- public int getType() {
- return glyphType;
- }
-
- /**
- * Returns <code>true</code> if this is a standard glyph.
- * @return <code>true</code> if this is a standard glyph;
- * <code>false</code> otherwise.
- */
- public boolean isStandard() {
- return (glyphType & 0x3) == STANDARD;
- }
-
- /**
- * Returns <code>true</code> if this is a ligature glyph.
- * @return <code>true</code> if this is a ligature glyph;
- * <code>false</code> otherwise.
- */
- public boolean isLigature() {
- return (glyphType & 0x3) == LIGATURE;
- }
-
- /**
- * Returns <code>true</code> if this is a combining glyph.
- * @return <code>true</code> if this is a combining glyph;
- * <code>false</code> otherwise.
- */
- public boolean isCombining() {
- return (glyphType & 0x3) == COMBINING;
- }
-
- /**
- * Returns <code>true</code> if this is a component glyph.
- * @return <code>true</code> if this is a component glyph;
- * <code>false</code> otherwise.
- */
- public boolean isComponent() {
- return (glyphType & 0x3) == COMPONENT;
- }
-
- /**
- * Returns <code>true</code> if this is a whitespace glyph.
- * @return <code>true</code> if this is a whitespace glyph;
- * <code>false</code> otherwise.
- */
- public boolean isWhitespace() {
- return (glyphType & 0x4) == WHITESPACE;
- }
- }
-