1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17/**
18 * @author Ilya S. Okomin
19 * @version $Revision$
20 */
21
22package java.awt.font;
23
24import java.awt.geom.Rectangle2D;
25
26/**
27 * The GlyphMetrics class provides information about the size and shape of a
28 * single glyph. Each glyph has information to specify whether its baseline is
29 * horizontal or vertical as well as information on how it interacts with other
30 * characters in a text, given as one of the following types: STANDARD,
31 * LIGATURE, COMBINING, or COMPONENT.
32 *
33 * @since Android 1.0
34 */
35public final class GlyphMetrics {
36
37    // advance width of the glyph character cell
38    /**
39     * The advance x.
40     */
41    private float advanceX;
42
43    // advance height of the glyph character cell
44    /**
45     * The advance y.
46     */
47    private float advanceY;
48
49    // flag if the glyph horizontal
50    /**
51     * The horizontal.
52     */
53    private boolean horizontal;
54
55    // glyph type code
56    /**
57     * The glyph type.
58     */
59    private byte glyphType;
60
61    // bounding box for outline of the glyph
62    /**
63     * The bounds.
64     */
65    private Rectangle2D.Float bounds;
66
67    /**
68     * The Constant STANDARD indicates a glyph that represents a single
69     * character.
70     */
71    public static final byte STANDARD = 0;
72
73    /**
74     * The Constant LIGATURE indicates a glyph that represents multiple
75     * characters as a ligature.
76     */
77    public static final byte LIGATURE = 1;
78
79    /**
80     * The Constant COMBINING indicates a glyph which has no caret position
81     * between glyphs (for example umlaut).
82     */
83    public static final byte COMBINING = 2;
84
85    /**
86     * The Constant COMPONENT indicates a glyph with no corresponding character
87     * in the backing store.
88     */
89    public static final byte COMPONENT = 3;
90
91    /**
92     * The Constant WHITESPACE indicates a glyph without visual representation.
93     */
94    public static final byte WHITESPACE = 4;
95
96    /**
97     * Instantiates a new GlyphMetrics object with the specified parameters.
98     *
99     * @param horizontal
100     *            specifies if metrics are for a horizontal baseline (true
101     *            value), or a vertical baseline (false value).
102     * @param advanceX
103     *            the X component of the glyph's advance.
104     * @param advanceY
105     *            the Y component of the glyph's advance.
106     * @param bounds
107     *            the glyph's bounds.
108     * @param glyphType
109     *            the glyph's type.
110     */
111    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, Rectangle2D bounds,
112            byte glyphType) {
113        this.horizontal = horizontal;
114        this.advanceX = advanceX;
115        this.advanceY = advanceY;
116
117        this.bounds = new Rectangle2D.Float();
118        this.bounds.setRect(bounds);
119
120        this.glyphType = glyphType;
121    }
122
123    /**
124     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
125     *
126     * @param advanceX
127     *            the X component of the glyph's advance.
128     * @param bounds
129     *            the glyph's bounds.
130     * @param glyphType
131     *            the glyph's type.
132     */
133    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
134        this.advanceX = advanceX;
135        this.advanceY = 0;
136
137        this.horizontal = true;
138
139        this.bounds = new Rectangle2D.Float();
140        this.bounds.setRect(bounds);
141
142        this.glyphType = glyphType;
143    }
144
145    /**
146     * Gets the glyph's bounds.
147     *
148     * @return glyph's bounds.
149     */
150    public Rectangle2D getBounds2D() {
151        return (Rectangle2D.Float)this.bounds.clone();
152    }
153
154    /**
155     * Checks if this glyph is whitespace or not.
156     *
157     * @return true, if this glyph is whitespace, false otherwise.
158     */
159    public boolean isWhitespace() {
160        return ((this.glyphType & 4) == WHITESPACE);
161    }
162
163    /**
164     * Checks if this glyph is standard or not.
165     *
166     * @return true, if this glyph is standard, false otherwise.
167     */
168    public boolean isStandard() {
169        return ((this.glyphType & 3) == STANDARD);
170    }
171
172    /**
173     * Checks if this glyph is ligature or not.
174     *
175     * @return true, if this glyph is ligature, false otherwise.
176     */
177    public boolean isLigature() {
178        return ((this.glyphType & 3) == LIGATURE);
179    }
180
181    /**
182     * Checks if this glyph is component or not.
183     *
184     * @return true, if this glyph is component, false otherwise.
185     */
186    public boolean isComponent() {
187        return ((this.glyphType & 3) == COMPONENT);
188    }
189
190    /**
191     * Checks if this glyph is combining or not.
192     *
193     * @return true, if this glyph is combining, false otherwise.
194     */
195    public boolean isCombining() {
196        return ((this.glyphType & 3) == COMBINING);
197    }
198
199    /**
200     * Gets the glyph's type.
201     *
202     * @return the glyph's type.
203     */
204    public int getType() {
205        return this.glyphType;
206    }
207
208    /**
209     * Gets the distance from the right (for horizontal) or bottom (for
210     * vertical) of the glyph bounds to the advance.
211     *
212     * @return the distance from the right (for horizontal) or bottom (for
213     *         vertical) of the glyph bounds to the advance.
214     */
215    public float getRSB() {
216        if (this.horizontal) {
217            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
218        }
219        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
220    }
221
222    /**
223     * Gets the distance from 0, 0 to the left (for horizontal) or top (for
224     * vertical) of the glyph bounds.
225     *
226     * @return the distance from 0, 0 to the left (for horizontal) or top (for
227     *         vertical) of the glyph bounds.
228     */
229    public float getLSB() {
230        if (this.horizontal) {
231            return this.bounds.x;
232        }
233        return this.bounds.y;
234    }
235
236    /**
237     * Gets the Y component of the glyph's advance.
238     *
239     * @return the Y component of the glyph's advance.
240     */
241    public float getAdvanceY() {
242        return this.advanceY;
243    }
244
245    /**
246     * Gets the X component of the glyph's advance.
247     *
248     * @return the X component of the glyph's advance.
249     */
250    public float getAdvanceX() {
251        return this.advanceX;
252    }
253
254    /**
255     * Gets the glyph's advance along the baseline.
256     *
257     * @return the glyph's advance.
258     */
259    public float getAdvance() {
260        if (this.horizontal) {
261            return this.advanceX;
262        }
263        return this.advanceY;
264    }
265
266}
267