1 50 51 package org.openlaszlo.iv.flash.api.text; 52 53 import org.openlaszlo.iv.flash.parser.Parser; 54 import org.openlaszlo.iv.flash.util.*; 55 import org.openlaszlo.iv.flash.cache.*; 56 import org.openlaszlo.iv.flash.api.*; 57 import org.openlaszlo.iv.flash.api.shape.*; 58 import java.io.*; 59 import java.awt.geom.Rectangle2D ; 60 61 202 public final class Font { 203 204 public static final int HAS_LAYOUT = 0x0080; 205 public static final int SHIFT_JIS = 0x0040; 206 public static final int UNICODE = 0x0020; 207 public static final int ANSI = 0x0010; 208 public static final int WIDE_OFFSETS = 0x0008; 209 public static final int WIDE_CODES = 0x0004; 210 public static final int ITALIC = 0x0002; 211 public static final int BOLD = 0x0001; 212 213 public int flags; public String fontName; public String fontKey; public boolean cached = false; public byte[] fileBuffer; public int[] glyphOffsets; private BareShape[] glyphs; public int[] codeTable; public int blankPos = 0; public int[] advanceTable; public int ascent; public int descent; public int leading; public int[] kernLeftCodes; public int[] kernRightCodes; public int[] kernAdjustment; public byte[] boundsBuffer; public int boundsOffset; public int boundsLength; private Rectangle2D [] bounds; 236 public Font() { 237 init( null ); 238 } 239 240 246 public static Font createDummyFont( String fontName ) { 247 Font f = new Font(); 248 f.init( fontName ); 249 return f; 250 } 251 252 private void init( String fontName ) { 253 flags = HAS_LAYOUT | ANSI; 254 fontName = fontName; 255 codeTable = new int[] { ' ' }; 256 advanceTable = new int[] { 0 }; 257 kernRightCodes = kernAdjustment = kernLeftCodes = new int[] { 0 }; 258 fileBuffer = new byte[0]; 259 glyphOffsets = new int[] { 0, 0 }; 260 } 261 262 271 public int getGlyphTableSize() { 272 return glyphOffsets.length; 273 } 274 275 280 public int getNumGlyph() { 281 return glyphOffsets.length-1; 282 } 283 284 290 public int getIndex( int ch ) { 291 try { 292 int idx = ch-' '+blankPos; 293 if( codeTable[idx] == ch ) return idx; 294 } catch( ArrayIndexOutOfBoundsException e ) {} 295 296 for( int i=0; i<codeTable.length; i++ ) { 297 if( ch == codeTable[i] ) return i; 298 } 299 return -1; 300 } 301 302 307 public String getFontName() { 308 return fontName; 309 } 310 311 317 public int getAdvanceValue( int idx ) { 318 try { 319 return advanceTable[idx]; 320 } catch( Exception e ) { 321 return 0; 322 } 323 } 324 325 326 335 public int getKerning( int ch_left, int ch_right ) { 336 for( int i=0; i<kernLeftCodes.length; i++ ) { 337 if( ch_left == kernLeftCodes[i] && ch_right == kernRightCodes[i] ) { 338 return kernAdjustment[i]; 339 } 340 } 341 return 0; 342 } 343 344 351 public BareShape[] getGlyphs() { 352 if( glyphs == null ) { 353 Parser p = new Parser(); 354 glyphs = new BareShape[ getNumGlyph() ]; 355 for( int i=0; i<glyphs.length; i++ ) { 356 p.init(fileBuffer, glyphOffsets[i], fileBuffer.length); 357 glyphs[i] = BareShape.parseBareShape(p); 358 } 359 } 360 return glyphs; 361 } 362 363 368 public Rectangle2D [] getGlyphBounds() { 369 if( bounds == null && boundsBuffer != null ) { 370 Parser p = new Parser(); 371 bounds = new Rectangle2D [ getNumGlyph() ]; 372 p.init(boundsBuffer, boundsOffset, boundsBuffer.length); 373 for( int i=0; i<bounds.length; i++ ) { 374 bounds[i] = p.getRect(); 375 } 376 } 377 return bounds; 378 } 379 380 388 public boolean isLargeThan( Font f ) { 389 if( getNumGlyph() > f.getNumGlyph() ) return true; 390 if( getNumGlyph() < f.getNumGlyph() ) return false; 391 392 if( (f.flags&Font.HAS_LAYOUT) != 0 && (flags&Font.HAS_LAYOUT) == 0 ) return false; 393 if( (flags&Font.HAS_LAYOUT) != 0 && (f.flags&Font.HAS_LAYOUT) == 0 ) return true; 394 395 return getFontSize() > f.getFontSize(); 396 } 397 398 405 public int getFontSize() { 406 int size = fileBuffer.length; 407 if( codeTable != null ) size += codeTable.length*4; 408 if( advanceTable != null ) size += advanceTable.length*4; 409 if( kernLeftCodes != null ) size += kernLeftCodes.length*4; 410 if( kernRightCodes != null ) size += kernRightCodes.length*4; 411 if( kernAdjustment != null ) size += kernAdjustment.length*4; 412 if( boundsBuffer != null && boundsBuffer != fileBuffer ) size += boundsBuffer.length; 413 return size; 414 } 415 416 public void printContent( PrintStream out, String indent, int id ) { 417 out.println( indent+"Font: id="+id+", fontName="+fontName+", flags="+Util.w2h(flags)+", nGlyph="+(glyphOffsets.length-1) ); 418 426 out.print( indent+" CodeTable:" ); 427 for( int i=0; i<codeTable.length; i++ ) { 428 if( (i%10) == 0 ) { 429 out.println(); out.print( indent+" " ); 430 } 431 if( (flags&WIDE_CODES) != 0 ) { 432 out.print( Util.b2h(i)+"["+Util.toPrint( (char)codeTable[i] )+"(0x"+Util.w2h(codeTable[i])+")] " ); 433 } else { 434 out.print( Util.b2h(i)+"["+Util.toPrint( (char)codeTable[i] )+"(0x"+Util.b2h(codeTable[i])+")] " ); 435 } 436 } 437 out.println(); 438 if( (flags&HAS_LAYOUT) != 0 ) { 439 out.println( indent+" hasLayout: ascent="+ascent+", descent="+descent+", leading="+leading ); 440 441 out.println( indent+" bounds: " ); 442 Rectangle2D [] bounds = getGlyphBounds(); 443 for( int i=0; i<bounds.length; i++ ) { 444 out.println( indent+" index="+i+", rect: "+bounds[i].toString() ); 445 } 446 out.print( indent+" AdvanceTable:" ); 447 for( int i=0; i<advanceTable.length; i++ ) { 448 if( (i%10) == 0 ) { 449 out.println(); out.print( indent+" " ); 450 } 451 out.print( Util.b2h(i)+"["+advanceTable[i]+"] " ); 452 } 453 out.println(); 454 out.println( indent+" KerningTable:" ); 455 for( int i=0; i<kernLeftCodes.length; i++ ) { 456 int lc = kernLeftCodes[i]; 457 int rc = kernRightCodes[i]; 458 int ad = kernAdjustment[i]; 459 if( (flags&WIDE_CODES) != 0 ) { 460 out.println( indent+" "+"["+Util.toPrint((char)lc)+"(0x"+Util.w2h(lc)+")] --> ["+Util.toPrint((char)rc)+"(0x"+Util.w2h(rc)+")] = "+ad ); 461 } else { 462 out.println( indent+" "+"["+Util.toPrint((char)lc)+"(0x"+Util.b2h(lc)+")] --> ["+Util.toPrint((char)rc)+"(0x"+Util.b2h(rc)+")] = "+ad ); 463 } 464 } 465 } 466 } 467 468 473 public void copyTo( Font font ) { 474 font.flags = flags; 475 font.fontName = fontName; 476 font.fontKey = fontKey; 477 font.fileBuffer = fileBuffer; 478 font.glyphOffsets = glyphOffsets; 479 font.glyphs = glyphs; 480 font.codeTable = codeTable; 481 font.blankPos = blankPos; 482 font.advanceTable = advanceTable; 483 font.boundsBuffer = boundsBuffer; 484 font.boundsOffset = boundsOffset; 485 font.boundsLength = boundsLength; 486 font.bounds = bounds; 487 font.ascent = ascent; 488 font.descent = descent; 489 font.leading = leading; 490 font.kernLeftCodes = kernLeftCodes; 491 font.kernRightCodes = kernRightCodes; 492 font.kernAdjustment = kernAdjustment; 493 506 } 507 508 } 509 | Popular Tags |