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} 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}
50  * instances are produced by {@link java.awt.Font Font} and are applicable
51  * to a specific glyph in a particular {@code Font}.
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} 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}
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},
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} can be directly
92  * constructed, they are almost always obtained from a
93  * {@code GlyphVector}.  Once constructed, {@code GlyphMetrics}
94  * objects are immutable.
95  * <p>
96  * <strong>Example</strong>:<p>
97  * Querying a {@code Font} 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} 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      */
GlyphMetrics(float advance, Rectangle2D bounds, byte glyphType)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} 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      */
GlyphMetrics(boolean horizontal, float advanceX, float advanceY, Rectangle2D bounds, byte glyphType)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      */
getAdvance()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      */
getAdvanceX()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      */
getAdvanceY()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      */
getBounds2D()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      */
getLSB()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      */
getRSB()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      */
getType()276     public int getType() {
277         return glyphType;
278     }
279 
280     /**
281      * Returns {@code true} if this is a standard glyph.
282      * @return {@code true} if this is a standard glyph;
283      *          {@code false} otherwise.
284      */
isStandard()285     public boolean isStandard() {
286         return (glyphType & 0x3) == STANDARD;
287     }
288 
289     /**
290      * Returns {@code true} if this is a ligature glyph.
291      * @return {@code true} if this is a ligature glyph;
292      *          {@code false} otherwise.
293      */
isLigature()294     public boolean isLigature() {
295         return (glyphType & 0x3) == LIGATURE;
296     }
297 
298     /**
299      * Returns {@code true} if this is a combining glyph.
300      * @return {@code true} if this is a combining glyph;
301      *          {@code false} otherwise.
302      */
isCombining()303     public boolean isCombining() {
304         return (glyphType & 0x3) == COMBINING;
305     }
306 
307     /**
308      * Returns {@code true} if this is a component glyph.
309      * @return {@code true} if this is a component glyph;
310      *          {@code false} otherwise.
311      */
isComponent()312     public boolean isComponent() {
313         return (glyphType & 0x3) == COMPONENT;
314     }
315 
316     /**
317      * Returns {@code true} if this is a whitespace glyph.
318      * @return {@code true} if this is a whitespace glyph;
319      *          {@code false} otherwise.
320      */
isWhitespace()321     public boolean isWhitespace() {
322         return (glyphType & 0x4) == WHITESPACE;
323     }
324 }
325