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, 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