src/share/classes/java/awt/Font.java

Print this page
rev 1379 : [mq]: fontmanager.patch


  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.awt.font.FontRenderContext;
  29 import java.awt.font.GlyphVector;
  30 import java.awt.font.LineMetrics;
  31 import java.awt.font.TextAttribute;
  32 import java.awt.font.TextLayout;
  33 import java.awt.font.TransformAttribute;
  34 import java.awt.geom.AffineTransform;
  35 import java.awt.geom.Point2D;
  36 import java.awt.geom.Rectangle2D;
  37 import java.awt.peer.FontPeer;
  38 import java.io.*;
  39 import java.lang.ref.SoftReference;
  40 import java.security.AccessController;
  41 import java.security.PrivilegedExceptionAction;
  42 import java.text.AttributedCharacterIterator.Attribute;
  43 import java.text.CharacterIterator;
  44 import java.text.StringCharacterIterator;
  45 import java.util.HashMap;
  46 import java.util.Hashtable;
  47 import java.util.Locale;
  48 import java.util.Map;
  49 import sun.font.StandardGlyphVector;
  50 import sun.java2d.FontSupport;
  51 
  52 import sun.font.AttributeMap;
  53 import sun.font.AttributeValues;
  54 import sun.font.EAttribute;
  55 import sun.font.CompositeFont;
  56 import sun.font.CreatedFontTracker;
  57 import sun.font.Font2D;
  58 import sun.font.Font2DHandle;

  59 import sun.font.FontManager;


  60 import sun.font.GlyphLayout;
  61 import sun.font.FontLineMetrics;
  62 import sun.font.CoreMetrics;
  63 
  64 import static sun.font.EAttribute.*;
  65 
  66 /**
  67  * The <code>Font</code> class represents fonts, which are used to
  68  * render text in a visible way.
  69  * A font provides the information needed to map sequences of
  70  * <em>characters</em> to sequences of <em>glyphs</em>
  71  * and to render sequences of glyphs on <code>Graphics</code> and
  72  * <code>Component</code> objects.
  73  *
  74  * <h4>Characters and Glyphs</h4>
  75  *
  76  * A <em>character</em> is a symbol that represents an item such as a letter,
  77  * a digit, or punctuation in an abstract way. For example, <code>'g'</code>,
  78  * <font size=-1>LATIN SMALL LETTER G</font>, is a character.
  79  * <p>


 206  * java.awt.font.TextAttribute#FONT} for more information.</p>
 207  *
 208  * <p>Several attributes will cause additional rendering overhead
 209  * and potentially invoke layout.  If a <code>Font</code> has such
 210  * attributes, the <code>{@link #hasLayoutAttributes()}</code> method
 211  * will return true.</p>
 212  *
 213  * <p>Note: Font rotations can cause text baselines to be rotated.  In
 214  * order to account for this (rare) possibility, font APIs are
 215  * specified to return metrics and take parameters 'in
 216  * baseline-relative coordinates'.  This maps the 'x' coordinate to
 217  * the advance along the baseline, (positive x is forward along the
 218  * baseline), and the 'y' coordinate to a distance along the
 219  * perpendicular to the baseline at 'x' (positive y is 90 degrees
 220  * clockwise from the baseline vector).  APIs for which this is
 221  * especially important are called out as having 'baseline-relative
 222  * coordinates.'
 223  */
 224 public class Font implements java.io.Serializable
 225 {


















 226     static {
 227         /* ensure that the necessary native libraries are loaded */
 228         Toolkit.loadLibraries();
 229         initIDs();

 230     }
 231 
 232     /**
 233      * This is now only used during serialization.  Typically
 234      * it is null.
 235      *
 236      * @serial
 237      * @see #getAttributes()
 238      */
 239     private Hashtable fRequestedAttributes;
 240 
 241     /*
 242      * Constants to be used for logical font family names.
 243      */
 244 
 245     /**
 246      * A String constant for the canonical family name of the
 247      * logical font "Dialog". It is useful in Font construction
 248      * to provide compile-time verification of the name.
 249      * @since 1.6


 447         if (values == null) {
 448             AttributeValues valuesTmp = new AttributeValues();
 449             valuesTmp.setFamily(name);
 450             valuesTmp.setSize(pointSize); // expects the float value.
 451 
 452             if ((style & BOLD) != 0) {
 453                 valuesTmp.setWeight(2); // WEIGHT_BOLD
 454             }
 455 
 456             if ((style & ITALIC) != 0) {
 457                 valuesTmp.setPosture(.2f); // POSTURE_OBLIQUE
 458             }
 459             valuesTmp.defineAll(PRIMARY_MASK); // for streaming compatibility
 460             values = valuesTmp;
 461         }
 462 
 463         return values;
 464     }
 465 
 466     private Font2D getFont2D() {
 467         if (FontManager.usingPerAppContextComposites &&

 468             font2DHandle != null &&
 469             font2DHandle.font2D instanceof CompositeFont &&
 470             ((CompositeFont)(font2DHandle.font2D)).isStdComposite()) {
 471             return FontManager.findFont2D(name, style,
 472                                           FontManager.LOGICAL_FALLBACK);
 473         } else if (font2DHandle == null) {
 474             font2DHandle =
 475                 FontManager.findFont2D(name, style,
 476                                        FontManager.LOGICAL_FALLBACK).handle;
 477         }
 478         /* Do not cache the de-referenced font2D. It must be explicitly
 479          * de-referenced to pick up a valid font in the event that the
 480          * original one is marked invalid
 481          */
 482         return font2DHandle.font2D;
 483     }
 484 
 485     /**
 486      * Creates a new <code>Font</code> from the specified name, style and
 487      * point size.
 488      * <p>
 489      * The font name can be a font face name or a font family name.
 490      * It is used together with the style to find an appropriate font face.
 491      * When a font family name is specified, the style argument is used to
 492      * select the most appropriate face from the family. When a font face
 493      * name is specified, the face's style and the style argument are
 494      * merged to locate the best matching font from the same family.
 495      * For example if face name "Arial Bold" is specified with style


 553         this.pointSize = sizePts;
 554     }
 555 
 556     /* This constructor is used by deriveFont when attributes is null */
 557     private Font(String name, int style, float sizePts,
 558                  boolean created, Font2DHandle handle) {
 559         this(name, style, sizePts);
 560         this.createdFont = created;
 561         /* Fonts created from a stream will use the same font2D instance
 562          * as the parent.
 563          * One exception is that if the derived font is requested to be
 564          * in a different style, then also check if its a CompositeFont
 565          * and if so build a new CompositeFont from components of that style.
 566          * CompositeFonts can only be marked as "created" if they are used
 567          * to add fall backs to a physical font. And non-composites are
 568          * always from "Font.createFont()" and shouldn't get this treatment.
 569          */
 570         if (created) {
 571             if (handle.font2D instanceof CompositeFont &&
 572                 handle.font2D.getStyle() != style) {
 573                 this.font2DHandle =
 574                     FontManager.getNewComposite(null, style, handle);
 575             } else {
 576                 this.font2DHandle = handle;
 577             }
 578         }
 579     }
 580 
 581     /* used to implement Font.createFont */
 582     private Font(File fontFile, int fontFormat,
 583                  boolean isCopy, CreatedFontTracker tracker)
 584         throws FontFormatException {
 585         this.createdFont = true;
 586         /* Font2D instances created by this method track their font file
 587          * so that when the Font2D is GC'd it can also remove the file.
 588          */
 589         this.font2DHandle =
 590             FontManager.createFont2D(fontFile, fontFormat,
 591                                      isCopy, tracker).handle;
 592         this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
 593         this.style = Font.PLAIN;
 594         this.size = 1;
 595         this.pointSize = 1f;
 596     }
 597 
 598     /* This constructor is used when one font is derived from another.
 599      * Fonts created from a stream will use the same font2D instance as the
 600      * parent. They can be distinguished because the "created" argument
 601      * will be "true". Since there is no way to recreate these fonts they
 602      * need to have the handle to the underlying font2D passed in.
 603      * "created" is also true when a special composite is referenced by the
 604      * handle for essentially the same reasons.
 605      * But when deriving a font in these cases two particular attributes
 606      * need special attention: family/face and style.
 607      * The "composites" in these cases need to be recreated with optimal
 608      * fonts for the new values of family and style.
 609      * For fonts created with createFont() these are treated differently.
 610      * JDK can often synthesise a different style (bold from plain
 611      * for example). For fonts created with "createFont" this is a reasonable


 623 
 624         this.createdFont = created;
 625         if (created) {
 626             this.font2DHandle = handle;
 627 
 628             String newName = null;
 629             if (oldName != null) {
 630                 newName = values.getFamily();
 631                 if (oldName.equals(newName)) newName = null;
 632             }
 633             int newStyle = 0;
 634             if (oldStyle == -1) {
 635                 newStyle = -1;
 636             } else {
 637                 if (values.getWeight() >= 2f)   newStyle  = BOLD;
 638                 if (values.getPosture() >= .2f) newStyle |= ITALIC;
 639                 if (oldStyle == newStyle)       newStyle  = -1;
 640             }
 641             if (handle.font2D instanceof CompositeFont) {
 642                 if (newStyle != -1 || newName != null) {

 643                     this.font2DHandle =
 644                         FontManager.getNewComposite(newName, newStyle, handle);
 645                 }
 646             } else if (newName != null) {
 647                 this.createdFont = false;
 648                 this.font2DHandle = null;
 649             }
 650         }
 651         initFromValues(values);
 652     }
 653 
 654     /**
 655      * Creates a new <code>Font</code> with the specified attributes.
 656      * Only keys defined in {@link java.awt.font.TextAttribute TextAttribute}
 657      * are recognized.  In addition the FONT attribute is
 658      *  not recognized by this constructor
 659      * (see {@link #getAvailableAttributes}). Only attributes that have
 660      * values of valid types will affect the new <code>Font</code>.
 661      * <p>
 662      * If <code>attributes</code> is <code>null</code>, a new
 663      * <code>Font</code> is initialized with default values.
 664      * @see java.awt.font.TextAttribute


 835      * @param fontStream an <code>InputStream</code> object representing the
 836      * input data for the font.
 837      * @return a new <code>Font</code> created with the specified font type.
 838      * @throws IllegalArgumentException if <code>fontFormat</code> is not
 839      *     <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>.
 840      * @throws FontFormatException if the <code>fontStream</code> data does
 841      *     not contain the required font tables for the specified format.
 842      * @throws IOException if the <code>fontStream</code>
 843      *     cannot be completely read.
 844      * @see GraphicsEnvironment#registerFont(Font)
 845      * @since 1.3
 846      */
 847     public static Font createFont(int fontFormat, InputStream fontStream)
 848         throws java.awt.FontFormatException, java.io.IOException {
 849 
 850         if (fontFormat != Font.TRUETYPE_FONT &&
 851             fontFormat != Font.TYPE1_FONT) {
 852             throw new IllegalArgumentException ("font format not recognized");
 853         }
 854         boolean copiedFontData = false;
 855 
 856         try {
 857             final File tFile = AccessController.doPrivileged(
 858                 new PrivilegedExceptionAction<File>() {
 859                     public File run() throws IOException {
 860                         return File.createTempFile("+~JF", ".tmp", null);
 861                     }
 862                 }
 863             );
 864 
 865             int totalSize = 0;
 866             CreatedFontTracker tracker = null;
 867             try {
 868                 final OutputStream outStream =
 869                     AccessController.doPrivileged(
 870                         new PrivilegedExceptionAction<OutputStream>() {
 871                             public OutputStream run() throws IOException {
 872                                 return new FileOutputStream(tFile);
 873                             }
 874                         }
 875                     );


2303                                     int beginIndex, int limit,
2304                                        FontRenderContext frc) {
2305         if (beginIndex < 0) {
2306             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2307         }
2308         if (limit > chars.length) {
2309             throw new IndexOutOfBoundsException("limit: " + limit);
2310         }
2311         if (beginIndex > limit) {
2312             throw new IndexOutOfBoundsException("range length: " +
2313                                                 (limit - beginIndex));
2314         }
2315 
2316         // this code should be in textlayout
2317         // quick check for simple text, assume GV ok to use if simple
2318 
2319         boolean simple = values == null ||
2320             (values.getKerning() == 0 && values.getLigatures() == 0 &&
2321               values.getBaselineTransform() == null);
2322         if (simple) {
2323             simple = !FontManager.isComplexText(chars, beginIndex, limit);
2324         }
2325 
2326         if (simple) {
2327             GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
2328                                                      limit - beginIndex, frc);
2329             return gv.getLogicalBounds();
2330         } else {
2331             // need char array constructor on textlayout
2332             String str = new String(chars, beginIndex, limit - beginIndex);
2333             TextLayout tl = new TextLayout(str, this, frc);
2334             return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
2335                                          tl.getAscent() + tl.getDescent() +
2336                                          tl.getLeading());
2337         }
2338     }
2339 
2340    /**
2341      * Returns the logical bounds of the characters indexed in the
2342      * specified {@link CharacterIterator} in the
2343      * specified <code>FontRenderContext</code>.  The logical bounds




  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.awt.font.FontRenderContext;
  29 import java.awt.font.GlyphVector;
  30 import java.awt.font.LineMetrics;
  31 import java.awt.font.TextAttribute;
  32 import java.awt.font.TextLayout;

  33 import java.awt.geom.AffineTransform;
  34 import java.awt.geom.Point2D;
  35 import java.awt.geom.Rectangle2D;
  36 import java.awt.peer.FontPeer;
  37 import java.io.*;
  38 import java.lang.ref.SoftReference;
  39 import java.security.AccessController;
  40 import java.security.PrivilegedExceptionAction;
  41 import java.text.AttributedCharacterIterator.Attribute;
  42 import java.text.CharacterIterator;
  43 import java.text.StringCharacterIterator;

  44 import java.util.Hashtable;
  45 import java.util.Locale;
  46 import java.util.Map;
  47 import sun.font.StandardGlyphVector;

  48 
  49 import sun.font.AttributeMap;
  50 import sun.font.AttributeValues;

  51 import sun.font.CompositeFont;
  52 import sun.font.CreatedFontTracker;
  53 import sun.font.Font2D;
  54 import sun.font.Font2DHandle;
  55 import sun.font.FontAccess;
  56 import sun.font.FontManager;
  57 import sun.font.FontManagerFactory;
  58 import sun.font.FontUtilities;
  59 import sun.font.GlyphLayout;
  60 import sun.font.FontLineMetrics;
  61 import sun.font.CoreMetrics;
  62 
  63 import static sun.font.EAttribute.*;
  64 
  65 /**
  66  * The <code>Font</code> class represents fonts, which are used to
  67  * render text in a visible way.
  68  * A font provides the information needed to map sequences of
  69  * <em>characters</em> to sequences of <em>glyphs</em>
  70  * and to render sequences of glyphs on <code>Graphics</code> and
  71  * <code>Component</code> objects.
  72  *
  73  * <h4>Characters and Glyphs</h4>
  74  *
  75  * A <em>character</em> is a symbol that represents an item such as a letter,
  76  * a digit, or punctuation in an abstract way. For example, <code>'g'</code>,
  77  * <font size=-1>LATIN SMALL LETTER G</font>, is a character.
  78  * <p>


 205  * java.awt.font.TextAttribute#FONT} for more information.</p>
 206  *
 207  * <p>Several attributes will cause additional rendering overhead
 208  * and potentially invoke layout.  If a <code>Font</code> has such
 209  * attributes, the <code>{@link #hasLayoutAttributes()}</code> method
 210  * will return true.</p>
 211  *
 212  * <p>Note: Font rotations can cause text baselines to be rotated.  In
 213  * order to account for this (rare) possibility, font APIs are
 214  * specified to return metrics and take parameters 'in
 215  * baseline-relative coordinates'.  This maps the 'x' coordinate to
 216  * the advance along the baseline, (positive x is forward along the
 217  * baseline), and the 'y' coordinate to a distance along the
 218  * perpendicular to the baseline at 'x' (positive y is 90 degrees
 219  * clockwise from the baseline vector).  APIs for which this is
 220  * especially important are called out as having 'baseline-relative
 221  * coordinates.'
 222  */
 223 public class Font implements java.io.Serializable
 224 {
 225     private static class FontAccessImpl extends FontAccess {
 226         public Font2D getFont2D(Font font) {
 227             return font.getFont2D();
 228         }
 229 
 230         public void setFont2D(Font font, Font2DHandle handle) {
 231             font.font2DHandle = handle;
 232         }
 233 
 234         public void setCreatedFont(Font font) {
 235             font.createdFont = true;
 236         }
 237 
 238         public boolean isCreatedFont(Font font) {
 239             return font.createdFont;
 240         }
 241     }
 242 
 243     static {
 244         /* ensure that the necessary native libraries are loaded */
 245         Toolkit.loadLibraries();
 246         initIDs();
 247         FontAccess.setFontAccess(new FontAccessImpl());
 248     }
 249 
 250     /**
 251      * This is now only used during serialization.  Typically
 252      * it is null.
 253      *
 254      * @serial
 255      * @see #getAttributes()
 256      */
 257     private Hashtable fRequestedAttributes;
 258 
 259     /*
 260      * Constants to be used for logical font family names.
 261      */
 262 
 263     /**
 264      * A String constant for the canonical family name of the
 265      * logical font "Dialog". It is useful in Font construction
 266      * to provide compile-time verification of the name.
 267      * @since 1.6


 465         if (values == null) {
 466             AttributeValues valuesTmp = new AttributeValues();
 467             valuesTmp.setFamily(name);
 468             valuesTmp.setSize(pointSize); // expects the float value.
 469 
 470             if ((style & BOLD) != 0) {
 471                 valuesTmp.setWeight(2); // WEIGHT_BOLD
 472             }
 473 
 474             if ((style & ITALIC) != 0) {
 475                 valuesTmp.setPosture(.2f); // POSTURE_OBLIQUE
 476             }
 477             valuesTmp.defineAll(PRIMARY_MASK); // for streaming compatibility
 478             values = valuesTmp;
 479         }
 480 
 481         return values;
 482     }
 483 
 484     private Font2D getFont2D() {
 485         FontManager fm = FontManagerFactory.getInstance();
 486         if (fm.usingPerAppContextComposites() &&
 487             font2DHandle != null &&
 488             font2DHandle.font2D instanceof CompositeFont &&
 489             ((CompositeFont)(font2DHandle.font2D)).isStdComposite()) {
 490             return fm.findFont2D(name, style,
 491                                           FontManager.LOGICAL_FALLBACK);
 492         } else if (font2DHandle == null) {
 493             font2DHandle =
 494                 fm.findFont2D(name, style,
 495                               FontManager.LOGICAL_FALLBACK).handle;
 496         }
 497         /* Do not cache the de-referenced font2D. It must be explicitly
 498          * de-referenced to pick up a valid font in the event that the
 499          * original one is marked invalid
 500          */
 501         return font2DHandle.font2D;
 502     }
 503 
 504     /**
 505      * Creates a new <code>Font</code> from the specified name, style and
 506      * point size.
 507      * <p>
 508      * The font name can be a font face name or a font family name.
 509      * It is used together with the style to find an appropriate font face.
 510      * When a font family name is specified, the style argument is used to
 511      * select the most appropriate face from the family. When a font face
 512      * name is specified, the face's style and the style argument are
 513      * merged to locate the best matching font from the same family.
 514      * For example if face name "Arial Bold" is specified with style


 572         this.pointSize = sizePts;
 573     }
 574 
 575     /* This constructor is used by deriveFont when attributes is null */
 576     private Font(String name, int style, float sizePts,
 577                  boolean created, Font2DHandle handle) {
 578         this(name, style, sizePts);
 579         this.createdFont = created;
 580         /* Fonts created from a stream will use the same font2D instance
 581          * as the parent.
 582          * One exception is that if the derived font is requested to be
 583          * in a different style, then also check if its a CompositeFont
 584          * and if so build a new CompositeFont from components of that style.
 585          * CompositeFonts can only be marked as "created" if they are used
 586          * to add fall backs to a physical font. And non-composites are
 587          * always from "Font.createFont()" and shouldn't get this treatment.
 588          */
 589         if (created) {
 590             if (handle.font2D instanceof CompositeFont &&
 591                 handle.font2D.getStyle() != style) {
 592                 FontManager fm = FontManagerFactory.getInstance();
 593                 this.font2DHandle = fm.getNewComposite(null, style, handle);
 594             } else {
 595                 this.font2DHandle = handle;
 596             }
 597         }
 598     }
 599 
 600     /* used to implement Font.createFont */
 601     private Font(File fontFile, int fontFormat,
 602                  boolean isCopy, CreatedFontTracker tracker)
 603         throws FontFormatException {
 604         this.createdFont = true;
 605         /* Font2D instances created by this method track their font file
 606          * so that when the Font2D is GC'd it can also remove the file.
 607          */
 608         FontManager fm = FontManagerFactory.getInstance();
 609         this.font2DHandle = fm.createFont2D(fontFile, fontFormat, isCopy,
 610                                             tracker).handle;
 611         this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
 612         this.style = Font.PLAIN;
 613         this.size = 1;
 614         this.pointSize = 1f;
 615     }
 616 
 617     /* This constructor is used when one font is derived from another.
 618      * Fonts created from a stream will use the same font2D instance as the
 619      * parent. They can be distinguished because the "created" argument
 620      * will be "true". Since there is no way to recreate these fonts they
 621      * need to have the handle to the underlying font2D passed in.
 622      * "created" is also true when a special composite is referenced by the
 623      * handle for essentially the same reasons.
 624      * But when deriving a font in these cases two particular attributes
 625      * need special attention: family/face and style.
 626      * The "composites" in these cases need to be recreated with optimal
 627      * fonts for the new values of family and style.
 628      * For fonts created with createFont() these are treated differently.
 629      * JDK can often synthesise a different style (bold from plain
 630      * for example). For fonts created with "createFont" this is a reasonable


 642 
 643         this.createdFont = created;
 644         if (created) {
 645             this.font2DHandle = handle;
 646 
 647             String newName = null;
 648             if (oldName != null) {
 649                 newName = values.getFamily();
 650                 if (oldName.equals(newName)) newName = null;
 651             }
 652             int newStyle = 0;
 653             if (oldStyle == -1) {
 654                 newStyle = -1;
 655             } else {
 656                 if (values.getWeight() >= 2f)   newStyle  = BOLD;
 657                 if (values.getPosture() >= .2f) newStyle |= ITALIC;
 658                 if (oldStyle == newStyle)       newStyle  = -1;
 659             }
 660             if (handle.font2D instanceof CompositeFont) {
 661                 if (newStyle != -1 || newName != null) {
 662                     FontManager fm = FontManagerFactory.getInstance();
 663                     this.font2DHandle =
 664                         fm.getNewComposite(newName, newStyle, handle);
 665                 }
 666             } else if (newName != null) {
 667                 this.createdFont = false;
 668                 this.font2DHandle = null;
 669             }
 670         }
 671         initFromValues(values);
 672     }
 673 
 674     /**
 675      * Creates a new <code>Font</code> with the specified attributes.
 676      * Only keys defined in {@link java.awt.font.TextAttribute TextAttribute}
 677      * are recognized.  In addition the FONT attribute is
 678      *  not recognized by this constructor
 679      * (see {@link #getAvailableAttributes}). Only attributes that have
 680      * values of valid types will affect the new <code>Font</code>.
 681      * <p>
 682      * If <code>attributes</code> is <code>null</code>, a new
 683      * <code>Font</code> is initialized with default values.
 684      * @see java.awt.font.TextAttribute


 855      * @param fontStream an <code>InputStream</code> object representing the
 856      * input data for the font.
 857      * @return a new <code>Font</code> created with the specified font type.
 858      * @throws IllegalArgumentException if <code>fontFormat</code> is not
 859      *     <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>.
 860      * @throws FontFormatException if the <code>fontStream</code> data does
 861      *     not contain the required font tables for the specified format.
 862      * @throws IOException if the <code>fontStream</code>
 863      *     cannot be completely read.
 864      * @see GraphicsEnvironment#registerFont(Font)
 865      * @since 1.3
 866      */
 867     public static Font createFont(int fontFormat, InputStream fontStream)
 868         throws java.awt.FontFormatException, java.io.IOException {
 869 
 870         if (fontFormat != Font.TRUETYPE_FONT &&
 871             fontFormat != Font.TYPE1_FONT) {
 872             throw new IllegalArgumentException ("font format not recognized");
 873         }
 874         boolean copiedFontData = false;

 875         try {
 876             final File tFile = AccessController.doPrivileged(
 877                 new PrivilegedExceptionAction<File>() {
 878                     public File run() throws IOException {
 879                         return File.createTempFile("+~JF", ".tmp", null);
 880                     }
 881                 }
 882             );
 883 
 884             int totalSize = 0;
 885             CreatedFontTracker tracker = null;
 886             try {
 887                 final OutputStream outStream =
 888                     AccessController.doPrivileged(
 889                         new PrivilegedExceptionAction<OutputStream>() {
 890                             public OutputStream run() throws IOException {
 891                                 return new FileOutputStream(tFile);
 892                             }
 893                         }
 894                     );


2322                                     int beginIndex, int limit,
2323                                        FontRenderContext frc) {
2324         if (beginIndex < 0) {
2325             throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
2326         }
2327         if (limit > chars.length) {
2328             throw new IndexOutOfBoundsException("limit: " + limit);
2329         }
2330         if (beginIndex > limit) {
2331             throw new IndexOutOfBoundsException("range length: " +
2332                                                 (limit - beginIndex));
2333         }
2334 
2335         // this code should be in textlayout
2336         // quick check for simple text, assume GV ok to use if simple
2337 
2338         boolean simple = values == null ||
2339             (values.getKerning() == 0 && values.getLigatures() == 0 &&
2340               values.getBaselineTransform() == null);
2341         if (simple) {
2342             simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
2343         }
2344 
2345         if (simple) {
2346             GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
2347                                                      limit - beginIndex, frc);
2348             return gv.getLogicalBounds();
2349         } else {
2350             // need char array constructor on textlayout
2351             String str = new String(chars, beginIndex, limit - beginIndex);
2352             TextLayout tl = new TextLayout(str, this, frc);
2353             return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
2354                                          tl.getAscent() + tl.getDescent() +
2355                                          tl.getLeading());
2356         }
2357     }
2358 
2359    /**
2360      * Returns the logical bounds of the characters indexed in the
2361      * specified {@link CharacterIterator} in the
2362      * specified <code>FontRenderContext</code>.  The logical bounds