| 1 7 8 package java.awt; 9 10 import java.awt.font.FontRenderContext ; 11 import java.awt.font.GlyphVector ; 12 import java.awt.font.LineMetrics ; 13 import java.awt.font.TextAttribute ; 14 import java.awt.font.TextLayout ; 15 import java.awt.font.TransformAttribute ; 16 import java.awt.geom.AffineTransform ; 17 import java.awt.geom.Rectangle2D ; 18 import java.awt.peer.FontPeer; 19 import java.io.*; 20 import java.lang.ref.SoftReference ; 21 import java.text.AttributedCharacterIterator.Attribute; 22 import java.text.CharacterIterator ; 23 import java.text.StringCharacterIterator ; 24 import java.util.HashMap ; 25 import java.util.Hashtable ; 26 import java.util.Locale ; 27 import java.util.Map ; 28 import sun.font.StandardGlyphVector; 29 import sun.java2d.FontSupport; 30 31 import sun.font.Font2D; 32 import sun.font.Font2DHandle; 33 import sun.font.FontManager; 34 import sun.font.GlyphLayout; 35 import sun.font.FontLineMetrics; 36 import sun.font.CoreMetrics; 37 38 136 public class Font implements java.io.Serializable  137 { 138 139 static { 140 141 Toolkit.loadLibraries(); 142 initIDs(); 143 } 144 145 152 private Hashtable fRequestedAttributes; 153 154 private static final Map EMPTY_MAP = new Hashtable (5, (float)0.9); 155 private static final TransformAttribute IDENT_TX_ATTRIBUTE = 156 new TransformAttribute (new AffineTransform ()); 157 158 162 163 166 public static final int PLAIN = 0; 167 168 172 public static final int BOLD = 1; 173 174 178 public static final int ITALIC = 2; 179 180 183 public static final int ROMAN_BASELINE = 0; 184 185 189 public static final int CENTER_BASELINE = 1; 190 191 195 public static final int HANGING_BASELINE = 2; 196 197 203 204 public static final int TRUETYPE_FONT = 0; 205 206 212 public static final int TYPE1_FONT = 1; 213 214 222 protected String name; 223 224 232 protected int style; 233 234 241 protected int size; 242 243 250 protected float pointSize; 251 252 255 private transient FontPeer peer; 256 private transient long pData; private transient Font2DHandle font2DHandle; 258 private transient int superscript; 259 private transient float width = 1f; 260 261 265 private transient boolean createdFont = false; 266 267 private transient double[] matrix; 269 private transient boolean nonIdentityTx; 270 271 private static final AffineTransform identityTx = new AffineTransform (); 272 275 private static final long serialVersionUID = -4206021311591459213L; 276 277 283 @Deprecated  284 public FontPeer getPeer(){ 285 return getPeer_NoClientCode(); 286 } 287 final FontPeer getPeer_NoClientCode() { 292 if(peer == null) { 293 Toolkit tk = Toolkit.getDefaultToolkit(); 294 this.peer = tk.getFontPeer(name, style); 295 } 296 return peer; 297 } 298 299 300 private Hashtable getRequestedAttributes() { 301 if (fRequestedAttributes == null) { 302 fRequestedAttributes = new Hashtable (7, (float)0.9); 303 fRequestedAttributes.put(TextAttribute.TRANSFORM, 304 IDENT_TX_ATTRIBUTE); 305 fRequestedAttributes.put(TextAttribute.FAMILY, name); 306 fRequestedAttributes.put(TextAttribute.SIZE, new Float (size)); 307 fRequestedAttributes.put(TextAttribute.WEIGHT, 308 (style & BOLD) != 0 ? 309 TextAttribute.WEIGHT_BOLD : 310 TextAttribute.WEIGHT_REGULAR); 311 fRequestedAttributes.put(TextAttribute.POSTURE, 312 (style & ITALIC) != 0 ? 313 TextAttribute.POSTURE_OBLIQUE : 314 TextAttribute.POSTURE_REGULAR); 315 fRequestedAttributes.put(TextAttribute.SUPERSCRIPT, 316 new Integer (superscript)); 317 fRequestedAttributes.put(TextAttribute.WIDTH, 318 new Float (width)); 319 } 320 return fRequestedAttributes; 321 } 322 323 private void initializeFont(Hashtable attributes) { 324 if (attributes != null) { 325 Object obj = attributes.get(TextAttribute.TRANSFORM); 326 if (obj instanceof TransformAttribute ) { 327 nonIdentityTx = !((TransformAttribute )obj).isIdentity(); 328 } else if (obj instanceof AffineTransform ) { 329 nonIdentityTx = !((AffineTransform )obj).isIdentity(); 330 } 331 332 obj = attributes.get(TextAttribute.SUPERSCRIPT); 333 if (obj instanceof Integer ) { 334 superscript = ((Integer )obj).intValue(); 335 336 nonIdentityTx |= superscript != 0; 338 } 339 340 obj = attributes.get(TextAttribute.WIDTH); 341 if (obj instanceof Integer ) { 342 width = ((Float )obj).floatValue(); 343 344 nonIdentityTx |= width != 1; 346 } 347 } 348 } 349 350 private Font2D getFont2D() { 351 if (FontManager.usingPerAppContextComposites && 352 font2DHandle != null && 353 font2DHandle.font2D instanceof sun.font.CompositeFont && 354 ((sun.font.CompositeFont)(font2DHandle.font2D)).isStdComposite()) { 355 return FontManager.findFont2D(name, style, 356 FontManager.LOGICAL_FALLBACK); 357 } else if (font2DHandle == null) { 358 font2DHandle = 359 FontManager.findFont2D(name, style, 360 FontManager.LOGICAL_FALLBACK).handle; 361 } 362 366 return font2DHandle.font2D; 367 } 368 369 376 private Font2DHandle getFont2DHandleForCreatedFont() { 377 if (font2DHandle != null && createdFont && 378 !(font2DHandle.font2D instanceof sun.font.CompositeFont)) { 379 return font2DHandle; 380 } else { 381 return null; 382 } 383 } 384 385 433 public Font(String name, int style, int size) { 434 this.name = (name != null) ? name : "Default"; 435 this.style = (style & ~0x03) == 0 ? style : 0; 436 this.size = size; 437 this.pointSize = size; 438 } 439 440 private Font(String name, int style, float sizePts) { 441 this.name = (name != null) ? name : "Default"; 442 this.style = (style & ~0x03) == 0 ? style : 0; 443 this.size = (int)(sizePts + 0.5); 444 this.pointSize = sizePts; 445 } 446 447 448 private Font(File fontFile, int fontFormat, boolean isCopy) 449 throws FontFormatException { 450 this.createdFont = true; 451 454 this.font2DHandle = 455 FontManager.createFont2D(fontFile, fontFormat, isCopy).handle; 456 this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault()); 457 this.style = Font.PLAIN; 458 this.size = 1; 459 this.pointSize = 1f; 460 } 461 462 private Font(Map attributes, boolean created, Font2DHandle handle) { 463 this.createdFont = created; 464 467 if (created) { 468 this.font2DHandle = handle; 469 } 470 initFromMap(attributes); 471 } 472 473 482 public Font(Map <? extends Attribute , ?> attributes) { 483 initFromMap(attributes); 484 } 485 486 487 private void initFromMap(Map attributes) { 488 this.name = "Dialog"; 489 this.pointSize = 12; 490 this.size = 12; 491 492 if((attributes != null) && 493 (!attributes.equals(EMPTY_MAP))) 494 { 495 Object obj; 496 fRequestedAttributes = new Hashtable (attributes); 497 if ((obj = attributes.get(TextAttribute.FAMILY)) != null) { 498 this.name = (String )obj; 499 } 500 501 if ((obj = attributes.get(TextAttribute.WEIGHT)) != null) { 502 if(obj.equals(TextAttribute.WEIGHT_BOLD)) { 503 this.style |= BOLD; 504 } 505 } 506 507 if ((obj = attributes.get(TextAttribute.POSTURE)) != null) { 508 if(obj.equals(TextAttribute.POSTURE_OBLIQUE)) { 509 this.style |= ITALIC; 510 } 511 } 512 513 if ((obj = attributes.get(TextAttribute.SIZE)) != null) { 514 this.pointSize = ((Float )obj).floatValue(); 515 this.size = (int)(this.pointSize + 0.5); 516 } 517 518 if ((obj = attributes.get(TextAttribute.TRANSFORM)) != null) { 519 if (obj instanceof TransformAttribute ) { 520 nonIdentityTx = !((TransformAttribute )obj).isIdentity(); 521 } else if (obj instanceof AffineTransform ) { 522 nonIdentityTx = !((AffineTransform )obj).isIdentity(); 523 } 524 } 525 526 if ((obj = attributes.get(TextAttribute.SUPERSCRIPT)) != null) { 527 if (obj instanceof Integer ) { 528 superscript = ((Integer )obj).intValue(); 529 nonIdentityTx |= superscript != 0; 530 } 531 } 532 533 if ((obj = attributes.get(TextAttribute.WIDTH)) != null) { 534 if (obj instanceof Float ) { 535 width = ((Float )obj).floatValue(); 536 nonIdentityTx |= width != 1; 537 } 538 } 539 } 540 } 541 542 552 public static Font getFont(Map <? extends Attribute , ?> attributes) { 553 Font font = (Font )attributes.get(TextAttribute.FONT); 554 if (font != null) { 555 return font; 556 } 557 558 return get(new Key(attributes)); 559 } 560 561 private static SoftReference cacheRef = new SoftReference (new HashMap ()); 562 private static Font get(Key key) { 563 Font f = null; 564 Map cache = (Map )cacheRef.get(); 565 if (cache == null) { 566 cache = new HashMap (); 567 cacheRef = new SoftReference (cache); 568 } else { 569 f = (Font )cache.get(key); 570 } 571 572 if (f == null) { 573 f = new Font (key.attrs); 574 cache.put(key, f); 575 } 576 577 return f; 578 } 579 580 585 private static class Key { 586 String family = "Dialog"; float weight = 1.0f; 588 float posture = 0.0f; 589 float size = 12.0f; 590 int superscript = 0; 591 float width = 1.0f; 592 double[] txdata = null; 594 Map attrs; 595 int hashCode = 0; 596 597 Key(Map map) { 598 attrs = map; 599 600 Object o = map.get(TextAttribute.FAMILY); 601 if (o != null) { 602 family = (String )o; 603 } 604 hashCode = family.hashCode(); 605 606 o = map.get(TextAttribute.WEIGHT); 607 if (o != null && o != TextAttribute.WEIGHT_REGULAR) { 608 float xweight = ((Float )o).floatValue(); 611 if (xweight == TextAttribute.WEIGHT_BOLD.floatValue()) { 612 weight = xweight; 613 hashCode = (hashCode << 3) ^ Float.floatToIntBits(weight); 614 } 615 } 616 617 o = map.get(TextAttribute.POSTURE); 618 if (o != null && o != TextAttribute.POSTURE_REGULAR) { 619 float xposture = ((Float )o).floatValue(); 621 if (xposture == TextAttribute.POSTURE_OBLIQUE.floatValue()) { 622 posture = xposture; 623 hashCode = (hashCode << 3) ^ Float.floatToIntBits(posture); 624 } 625 } 626 627 o = map.get(TextAttribute.SIZE); 628 if (o != null) { 629 size = ((Float )o).floatValue(); 630 if (size != 12.0f) { 631 hashCode = (hashCode << 3) ^ Float.floatToIntBits(size); 632 } 633 } 634 635 o = map.get(TextAttribute.TRANSFORM); 636 if (o != null) { 637 AffineTransform tx = null; 638 if (o instanceof TransformAttribute ) { 639 TransformAttribute ta = (TransformAttribute )o; 640 if (!ta.isIdentity()) { 641 tx = ta.getTransform(); 642 } 643 } else if (o instanceof AffineTransform ) { 644 AffineTransform at = (AffineTransform )o; 645 if (!at.isIdentity()) { 646 tx = at; 647 } 648 } 649 if (tx != null) { 650 txdata = new double[6]; 651 tx.getMatrix(txdata); 652 hashCode = (hashCode << 3) ^ new Double (txdata[0]).hashCode(); 653 } 654 } 655 656 o = map.get(TextAttribute.SUPERSCRIPT); 657 if (o != null) { 658 if (o instanceof Integer ) { 659 superscript = ((Integer )o).intValue(); 660 hashCode = hashCode << 3 ^ superscript; 661 } 662 } 663 664 o = map.get(TextAttribute.WIDTH); 665 if (o != null) { 666 if (o instanceof Float ) { 667 width = ((Float )o).floatValue(); 668 hashCode = hashCode << 3 ^ Float.floatToIntBits(width); 669 } 670 } 671 } 672 673 public int hashCode() { 674 return hashCode; 675 } 676 677 public boolean equals(Object rhs) { 678 Key rhskey = (Key)rhs; 679 if (this.hashCode == rhskey.hashCode && 680 this.size == rhskey.size && 681 this.weight == rhskey.weight && 682 this.posture == rhskey.posture && 683 this.superscript == rhskey.superscript && 684 this.width == rhskey.width && 685 this.family.equals(rhskey.family) && 686 ((this.txdata == null) == (rhskey.txdata == null))) { 687 688 if (this.txdata != null) { 689 for (int i = 0; i < this.txdata.length; ++i) { 690 if (this.txdata[i] != rhskey.txdata[i]) { 691 return false; 692 } 693 } 694 } 695 return true; 696 } 697 return false; 698 } 699 } 700 701 702 724 public static Font createFont(int fontFormat, InputStream fontStream) 725 throws java.awt.FontFormatException , java.io.IOException { 726 727 if (fontFormat != Font.TRUETYPE_FONT && 728 fontFormat != Font.TYPE1_FONT) { 729 throw new IllegalArgumentException ("font format not recognized"); 730 } 731 final InputStream fStream = fontStream; 732 Object ret = java.security.AccessController.doPrivileged( 733 new java.security.PrivilegedAction () { 734 public Object run() { 735 File tFile = null; 736 try { 737 tFile = File.createTempFile("+~JF", ".tmp", null); 738 tFile.deleteOnExit(); 739 BufferedInputStream inStream = 740 new BufferedInputStream(fStream); 741 FileOutputStream outStream = new FileOutputStream(tFile); 742 int bytesRead = 0; 743 int bufSize = 8192; 744 byte [] buf = new byte[bufSize]; 745 while (bytesRead != -1) { 746 bytesRead = inStream.read(buf, 0, bufSize); 747 if (bytesRead != -1) { 748 outStream.write(buf, 0, bytesRead); 749 } 750 } 751 752 outStream.close(); 753 } catch (IOException e) { 754 return e; 755 } 756 return tFile; 757 } 758 }); 759 760 if (ret instanceof File) { 761 return new Font ((File)ret, fontFormat, true); 762 } else if (ret instanceof IOException) { 763 throw (IOException)ret; 764 } else { 765 throw new FontFormatException ("Couldn't access font stream"); 766 } 767 } 768 769 797 public static Font createFont(int fontFormat, File fontFile) 798 throws java.awt.FontFormatException , java.io.IOException { 799 if (fontFormat != Font.TRUETYPE_FONT && 800 fontFormat != Font.TYPE1_FONT) { 801 throw new IllegalArgumentException ("font format not recognized"); 802 } 803 SecurityManager sm = System.getSecurityManager(); 804 if (sm != null) { 805 FilePermission filePermission = 806 new FilePermission(fontFile.getPath(), "read"); 807 sm.checkPermission(filePermission); 808 } 809 if (!fontFile.canRead()) { 810 throw new IOException("Can't read " + fontFile); 811 } 812 return new Font (fontFile, fontFormat, false); 813 } 814 815 821 public AffineTransform getTransform() { 822 835 if (nonIdentityTx) { 836 AffineTransform at = null; 837 Object obj = getRequestedAttributes().get(TextAttribute.TRANSFORM); 838 if (obj != null) { 839 if( obj instanceof TransformAttribute ){ 840 at = ((TransformAttribute )obj).getTransform(); 841 } 842 else { 843 if ( obj instanceof AffineTransform ){ 844 at = new AffineTransform ((AffineTransform )obj); 845 } 846 } 847 } else { 848 at = new AffineTransform (); 849 } 850 851
|