Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java AWT: Is Font a lightweight object?

How expensive is it to create a Font object when I use Java's AWT? Should I cache Font whenever practical, or is it simply a lightweight reference to the heavyweight font the AWT already caches internally?

like image 717
Tony the Pony Avatar asked May 23 '11 20:05

Tony the Pony


People also ask

What is font awt Java?

In Java, Font is a class that belongs to the java. awt package. It implements the Serializable interface. FontUIResource is the direct known subclass of the Java Font class.

What is font in Java?

The Font class represents fonts, which are used to render text in a visible way. A font provides the information needed to map sequences of characters to sequences of glyphs and to render sequences of glyphs on Graphics and Component objects.

Which are the constant values defined in font class of awt?

Constants. There are four styles for displaying fonts in Java: plain, bold, italic, and bold italic. The BOLD constant represents a boldface font. The ITALIC constant represents an italic font.

Which font styles can be set using font class?

The Font class defines three static style identifiers: PLAIN , BOLD , and ITALIC . You can use these values on all fonts.


1 Answers

If you look at the source code for Font (This is OpenJDK), the constructors with name, style, size are obviously lightweight:

public Font(String name, int style, int size) {
    this.name = (name != null) ? name : "Default";
    this.style = (style & ~0x03) == 0 ? style : 0;
    this.size = size;
    this.pointSize = size;
}

However, the constructor which takes a file and fontformat is:

private Font(File fontFile, int fontFormat,
             boolean isCopy, CreatedFontTracker tracker)
    throws FontFormatException {
    this.createdFont = true;
    /* Font2D instances created by this method track their font file
     * so that when the Font2D is GC'd it can also remove the file.
     */
    this.font2DHandle =
        FontManager.createFont2D(fontFile, fontFormat,
                                 isCopy, tracker).handle;
    this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
    this.style = Font.PLAIN;
    this.size = 1;
    this.pointSize = 1f;
}

which is obviously heavyweight (specifically the FontManager.createFont2D(...) part. This constructor is used only by Font.createFont().

Overall, if you're using a font that's in your system, you're fine, just creating it and referring it to by name. If you're providing your own font (ie: from a TrueType file) you may be better off caching it. (That said, IIRC, there is a way to simply load a file into AWT's cache so you can simply refer to it by name.)

Digging further into the source, all of the functions such as getFamily(), getFontName(), getNumGlyphs(), first call getFont2D() which is essentially:

private Font2D getFont2D() {
    // snip
    if (font2DHandle == null) {
        font2DHandle =
            FontManager.findFont2D(name, style,
                                   FontManager.LOGICAL_FALLBACK).handle;
    }
    /* Do not cache the de-referenced font2D. It must be explicitly
     * de-referenced to pick up a valid font in the event that the
     * original one is marked invalid
     */
    return font2DHandle.font2D;
}

so, that shows that each font is definitely lightweight, and it pulls necessary info from the FontManager which is in charge of caching the font.

like image 68
Reverend Gonzo Avatar answered Sep 27 '22 20:09

Reverend Gonzo