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?
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.
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.
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.
The Font class defines three static style identifiers: PLAIN , BOLD , and ITALIC . You can use these values on all fonts.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With