1 /* FontMetrics.java -- Information about about a fonts display characteristics 2 Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.awt; 40 41 import java.awt.font.FontRenderContext; 42 import java.awt.font.LineMetrics; 43 import java.awt.geom.Rectangle2D; 44 import java.text.CharacterIterator; 45 46 // FIXME: I leave many methods basically unimplemented. This 47 // should be reviewed. 48 49 /** 50 * This class returns information about the display characteristics of 51 * a font. It is abstract, and concrete subclasses should implement at 52 * least the following methods: 53 * 54 * <ul> 55 * <li>getAscent()</li> 56 * <li>getDescent()</li> 57 * <li>getLeading()</li> 58 * <li>getMaxAdvance()</li> 59 * <li>charWidth(char)</li> 60 * <li>charsWidth(char[], int, int)</li> 61 * </ul> 62 * 63 * @author Aaron M. Renn (arenn@urbanophile.com) 64 */ 65 public abstract class FontMetrics implements java.io.Serializable 66 { 67 // Serialization constant. 68 private static final long serialVersionUID = 1681126225205050147L; 69 70 /** 71 * This is the font for which metrics will be returned. 72 */ 73 protected Font font; 74 75 /** 76 * Initializes a new instance of <code>FontMetrics</code> for the 77 * specified font. 78 * 79 * @param font The font to return metric information for. 80 */ FontMetrics(Font font)81 protected FontMetrics(Font font) 82 { 83 this.font = font; 84 } 85 86 /** 87 * Returns the font that this object is creating metric information fo. 88 * 89 * @return The font for this object. 90 */ getFont()91 public Font getFont() 92 { 93 return font; 94 } 95 96 /** 97 * Returns the leading, or spacing between lines, for this font. 98 * 99 * @return The font leading. 100 */ getLeading()101 public int getLeading() 102 { 103 return 0; 104 } 105 106 /** 107 * Returns the ascent of the font, which is the distance from the base 108 * to the top of the majority of characters in the set. Some characters 109 * can exceed this value however. 110 * 111 * @return The font ascent. 112 */ getAscent()113 public int getAscent() 114 { 115 return 1; 116 } 117 118 /** 119 * Returns the descent of the font, which is the distance from the base 120 * to the bottom of the majority of characters in the set. Some characters 121 * can exceed this value however. 122 * 123 * @return The font descent. 124 */ getDescent()125 public int getDescent() 126 { 127 return 1; 128 } 129 130 /** 131 * Returns the height of a line in this font. This will be the sum 132 * of the leading, the ascent, and the descent. 133 * 134 * @return The height of the font. 135 */ getHeight()136 public int getHeight() 137 { 138 return getAscent() + getDescent() + getLeading(); 139 } 140 141 /** 142 * Returns the maximum ascent value. This is the maximum distance any 143 * character in the font rised above the baseline. 144 * 145 * @return The maximum ascent for this font. 146 */ getMaxAscent()147 public int getMaxAscent() 148 { 149 return getAscent(); 150 } 151 152 /** 153 * Returns the maximum descent value. This is the maximum distance any 154 * character in the font extends below the baseline. 155 * 156 * @return The maximum descent for this font. 157 */ getMaxDescent()158 public int getMaxDescent() 159 { 160 return getMaxDecent(); 161 } 162 163 /** 164 * Returns the maximum descent value. This is the maximum distance any 165 * character in the font extends below the baseline. 166 * 167 * @return The maximum descent for this font. 168 * 169 * @deprecated This method is deprecated in favor of 170 * <code>getMaxDescent()</code>. 171 */ getMaxDecent()172 public int getMaxDecent() 173 { 174 return getDescent(); 175 } 176 177 /** 178 * Returns the width of the widest character in the font. 179 * 180 * @return The width of the widest character in the font. 181 */ getMaxAdvance()182 public int getMaxAdvance() 183 { 184 return -1; 185 } 186 187 /** 188 * Returns the width of the specified character. 189 * 190 * @param ch The character to return the width of. 191 * 192 * @return The width of the specified character. 193 */ charWidth(int ch)194 public int charWidth(int ch) 195 { 196 char[] chars = Character.toChars(ch); 197 return charsWidth(chars, 0, chars.length); 198 } 199 200 /** 201 * Returns the width of the specified character. 202 * 203 * @param ch The character to return the width of. 204 * 205 * @return The width of the specified character. 206 */ charWidth(char ch)207 public int charWidth(char ch) 208 { 209 return 1; 210 } 211 212 /** 213 * Returns the total width of the specified string 214 * 215 * @param str The string to return the width of. 216 * 217 * @return The width of the string. 218 */ stringWidth(String str)219 public int stringWidth(String str) 220 { 221 char[] buf = new char[str.length()]; 222 str.getChars(0, str.length(), buf, 0); 223 224 return charsWidth(buf, 0, buf.length); 225 } 226 227 /** 228 * Returns the total width of the specified character array. 229 * 230 * @param buf The character array containing the data. 231 * @param offset The offset into the array to start calculating from. 232 * @param len The total number of bytes to process. 233 * 234 * @return The width of the requested characters. 235 */ charsWidth(char[] buf, int offset, int len)236 public int charsWidth(char[] buf, int offset, int len) 237 { 238 int total_width = 0; 239 int endOffset = offset + len; 240 for (int i = offset; i < endOffset; i++) 241 total_width += charWidth(buf[i]); 242 return total_width; 243 } 244 245 /** 246 * Returns the total width of the specified byte array. 247 * 248 * @param buf The byte array containing the data. 249 * @param offset The offset into the array to start calculating from. 250 * @param len The total number of bytes to process. 251 * 252 * @return The width of the requested characters. 253 */ bytesWidth(byte[] buf, int offset, int len)254 public int bytesWidth(byte[] buf, int offset, int len) 255 { 256 int total_width = 0; 257 for (int i = offset; i < len; i++) 258 total_width = charWidth((char) buf[i]); 259 260 return total_width; 261 } 262 263 /** 264 * Returns the widths of the first 256 characters in the font. 265 * 266 * @return The widths of the first 256 characters in the font. 267 */ getWidths()268 public int[] getWidths() 269 { 270 int[] result = new int[256]; 271 for (char i = 0; i < 256; i++) 272 result[i] = charWidth(i); 273 return result; 274 } 275 276 /** 277 * Returns a string representation of this object. 278 * 279 * @return A string representation of this object. 280 */ toString()281 public String toString() 282 { 283 return (this.getClass() + "[font=" + font + ",ascent=" + getAscent() 284 + ",descent=" + getDescent() + ",height=" + getHeight() + "]"); 285 } 286 287 // Generic FontRenderContext used when getLineMetrics is called with a 288 // plain Graphics object. 289 private static final FontRenderContext gRC = new FontRenderContext(null, 290 false, 291 false); 292 293 /** 294 * Returns a {@link LineMetrics} object constructed with the 295 * specified text and the {@link FontRenderContext} of the Graphics 296 * object when it is an instance of Graphics2D or a generic 297 * FontRenderContext with a null transform, not anti-aliased and not 298 * using fractional metrics. 299 * 300 * @param text The string to calculate metrics from. 301 * @param g The Graphics object that will be used. 302 * 303 * @return A new {@link LineMetrics} object. 304 */ getLineMetrics(String text, Graphics g)305 public LineMetrics getLineMetrics(String text, Graphics g) 306 { 307 return getLineMetrics(text, 0, text.length(), g); 308 } 309 310 /** 311 * Returns a {@link LineMetrics} object constructed with the 312 * specified text and the {@link FontRenderContext} of the Graphics 313 * object when it is an instance of Graphics2D or a generic 314 * FontRenderContext with a null transform, not anti-aliased and not 315 * using fractional metrics. 316 * 317 * @param text The string to calculate metrics from. 318 * @param begin Index of first character in <code>text</code> to measure. 319 * @param limit Index of last character in <code>text</code> to measure. 320 * @param g The Graphics object that will be used. 321 * 322 * @return A new {@link LineMetrics} object. 323 * 324 * @throws IndexOutOfBoundsException if the range [begin, limit] is 325 * invalid in <code>text</code>. 326 */ getLineMetrics(String text, int begin, int limit, Graphics g)327 public LineMetrics getLineMetrics(String text, int begin, int limit, 328 Graphics g) 329 { 330 FontRenderContext rc; 331 if (g instanceof Graphics2D) 332 rc = ((Graphics2D) g).getFontRenderContext(); 333 else 334 rc = gRC; 335 return font.getLineMetrics(text, begin, limit, rc); 336 } 337 338 /** 339 * Returns a {@link LineMetrics} object constructed with the 340 * specified text and the {@link FontRenderContext} of the Graphics 341 * object when it is an instance of Graphics2D or a generic 342 * FontRenderContext with a null transform, not anti-aliased and not 343 * using fractional metrics. 344 * 345 * @param chars The string to calculate metrics from. 346 * @param begin Index of first character in <code>text</code> to measure. 347 * @param limit Index of last character in <code>text</code> to measure. 348 * @param g The Graphics object that will be used. 349 * 350 * @return A new {@link LineMetrics} object. 351 * 352 * @throws IndexOutOfBoundsException if the range [begin, limit] is 353 * invalid in <code>text</code>. 354 */ getLineMetrics(char[] chars, int begin, int limit, Graphics g)355 public LineMetrics getLineMetrics(char[] chars, int begin, int limit, 356 Graphics g) 357 { 358 FontRenderContext rc; 359 if (g instanceof Graphics2D) 360 rc = ((Graphics2D) g).getFontRenderContext(); 361 else 362 rc = gRC; 363 return font.getLineMetrics(chars, begin, limit, rc); 364 } 365 366 /** 367 * Returns the bounds of the largest character in a Graphics context. 368 * @param context the Graphics context object. 369 * @return a <code>Rectangle2D</code> representing the bounds 370 */ getMaxCharBounds(Graphics context)371 public Rectangle2D getMaxCharBounds(Graphics context) 372 { 373 if( context instanceof Graphics2D ) 374 return font.getMaxCharBounds(((Graphics2D)context).getFontRenderContext()); 375 return font.getMaxCharBounds( gRC ); 376 } 377 378 /** 379 * Returns a {@link LineMetrics} object constructed with the 380 * specified text and the {@link FontRenderContext} of the Graphics 381 * object when it is an instance of Graphics2D or a generic 382 * FontRenderContext with a null transform, not anti-aliased and not 383 * using fractional metrics. 384 * 385 * @param ci An iterator over the string to calculate metrics from. 386 * @param begin Index of first character in <code>text</code> to measure. 387 * @param limit Index of last character in <code>text</code> to measure. 388 * @param g The Graphics object that will be used. 389 * 390 * @return A new {@link LineMetrics} object. 391 * 392 * @throws IndexOutOfBoundsException if the range [begin, limit] is 393 * invalid in <code>text</code>. 394 */ getLineMetrics(CharacterIterator ci, int begin, int limit, Graphics g)395 public LineMetrics getLineMetrics(CharacterIterator ci, int begin, 396 int limit, Graphics g) 397 { 398 FontRenderContext rc; 399 if (g instanceof Graphics2D) 400 rc = ((Graphics2D) g).getFontRenderContext(); 401 else 402 rc = gRC; 403 return font.getLineMetrics(ci, begin, limit, rc); 404 } 405 getStringBounds(String str, Graphics context)406 public Rectangle2D getStringBounds(String str, Graphics context) 407 { 408 return font.getStringBounds(str, getFontRenderContext(context)); 409 } 410 getStringBounds(String str, int beginIndex, int limit, Graphics context)411 public Rectangle2D getStringBounds(String str, int beginIndex, int limit, 412 Graphics context) 413 { 414 return font.getStringBounds(str, beginIndex, limit, 415 getFontRenderContext(context)); 416 } 417 getStringBounds(char[] chars, int beginIndex, int limit, Graphics context)418 public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit, 419 Graphics context) 420 { 421 return font.getStringBounds(chars, beginIndex, limit, 422 getFontRenderContext(context)); 423 } 424 getStringBounds(CharacterIterator ci, int beginIndex, int limit, Graphics context)425 public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex, 426 int limit, Graphics context) 427 { 428 return font.getStringBounds(ci, beginIndex, limit, 429 getFontRenderContext(context)); 430 } 431 getFontRenderContext(Graphics context)432 private FontRenderContext getFontRenderContext(Graphics context) 433 { 434 if (context instanceof Graphics2D) 435 return ((Graphics2D) context).getFontRenderContext(); 436 437 return gRC; 438 } 439 440 /** 441 * Returns if the font has uniform line metrics. 442 * @see Font#hasUniformLineMetrics() 443 */ hasUniformLineMetrics()444 public boolean hasUniformLineMetrics() 445 { 446 return font.hasUniformLineMetrics(); 447 } 448 } 449