Introduction to named fonts
If you've ever written a commercial app, or any app that you share with others, you've probably been asked "how can I change the fonts?" Maybe you have a finely crafted set of fonts custom tailored to your design or maybe you rely on the defaults provided by tk, but no matter what you provide some user will want to change it.
One of the more unique features of Tk is support for something called named fonts, part of the standard tk font command [1]. This article briefly describes how and why you should use named fonts. In addition, example code is given for adding the ability to dynamically change the fonts at runtime with a simple binding.
What is a named font?
What is a named font? A named font can be thought of as an alias for a complete font description. You create a named font with the font create command. Once created, you can use the named font anywhere you would normally use a standard font specification. That's all there is to it.
The following example illustrates how to create and use a named font:
font create customFont -family Helvetica -size 14 -slant italic label .label -text "A label with a named font" -font customFont pack .label
Changing the font at runtime
The advantage to using named fonts is that when the font is changed, all widgets that use the font automatically get updated. To see the effect, start an intereactive Wish shell and enter the code from the above examples.
The main window should look something like this:

Changing the font is as simple as calling the font configure command, giving it the name of the font and any new attributes:
font configure customFont -slant roman -weight bold
If you run the above command in your interactive shell the window should now look like this:

Growing and shrinking fonts
Once you start using named fonts it becomes easy to provide a mechanism to let the user grow or shrink the fonts. For example, you might want to bind Control-plus to increase the font and Control-minus to decrease it. Or, you may want a menubar View menu item for "Bigger Fonts" and "Smaller Fonts". The following example shows one way to accomplish that task:
proc bump_fonts {incr} {
set size [font configure customFont -size]
catch {
incr size $incr
# keep font sizes sane...
if {$size >== 8 && $size <== 32} {
font configure customFont -size $size
}
}
}
# Control-plus actually requires the user to press Control-Shift-equals;
# using Control-equal is a convenience to make it a bit easier on the user
bind all <Control-plus> [list bump_fonts +2]
bind all <Control-equal> [list bump_fonts +2]
bind all <Control-minus> [list bump_fonts -2]
Of course, you can have multiple named fonts within an application and bump_fonts could iterate over each font to change them all at the same time. For example, my apps often have several fonts such as normalFont, boldFont, italicFont, etc.
Using a named font as the default font
You can use named fonts by supplying the name of the font for every widget that has a font. This can be tedious. An arguably better solution is to use the built-in option database [2] features of Tk. The following example shows how to use a named font for all widgets:
option add *font customFont
Putting it all together
The following example creates an application with a single text widget and a menubar, and uses three different named fonts:
proc main {} {
font create defaultFont -family Helvetica -size 12
font create boldFont -family Helvetica -size 12 -weight bold
font create italicFont -family Helvetica -size 12 -slant italic
option add *font defaultFont
menu .mb
menu .mb.file
menu .mb.view
.mb.file add command -label "Exit" -command exit
.mb.view add command -label "Bigger Fonts" \
-accelerator "Control-plus" -command [list bump_fonts +2]
.mb.view add command -label "Smaller Fonts" \
-accelerator "Control-minus" -command [list bump_fonts -2]
.mb add cascade -label File -menu .mb.file
.mb add cascade -label View -menu .mb.view
. configure -menu .mb
text .t -wrap word -width 20 -height 5
pack .t
.t tag configure normal -font defaultFont
.t tag configure bold -font boldFont
.t tag configure italics -font italicFont
bind all <Control-plus> [list bump_fonts +2]
bind all <Control-equal> [list bump_fonts +2]
bind all <Control-minus> [list bump_fonts -2]
.t insert end "Normal\n" "normal" "Bold\n" bold "Italics\n" italics
}
proc bump_fonts {incr} {
foreach font {defaultFont boldFont italicFont} {
catch {
set size [font configure $font -size]
incr size $incr
if {$size >= 8 && $size <= 32} {
font configure $font -size $size
}
}
}
}
main

Limitations
One limitation of named fonts is that you can't directly copy a font. You can use the output of tk's font actual command to get the attributes of a font and assign them to another font. Doing so, however, doesn't yield perfect results. For example, most unix systems have a bitmapped font alias named "6x13". As of tk 8.5 there doesn't seem to be any way to create a named font that is exactly that font. For example, with the following code it seems like the two labels should be identical but they are not:
eval font create myFont [font actual "6x13"] label .l1 -text "ABCabc123 this is 6x13" -font 6x13 -anchor w label .l2 -text "ABCabc123 this is myFont" -font myFont -anchor w pack .l1 .l2 -side top -fill x
If you try this on a non-X11 system the widgets may look the same; on most flavors of unix they will look slightly different:

Summary
As long as you don't need to use one of the X11 bitmapped fonts, named fonts provide a lot of flexibility. By creating a handful of named fonts at startup it becomes easy to build in the ability for the user to reconfigure fonts on the fly without having to manually re-apply font definitions to every widget. In addition, if you need to make font adjustments for specific platforms you can do so all in one place without having to track down dozens of font references in your code.
Get in the habit of always using named fonts and you'll have fewer font related problems as your code matures.
References
- Font man page, http://www.tcl.tk/man/tcl8.4/TkCmd/font.htm
- Option man page, http://www.tcl.tk/man/tcl8.4/TkCmd/option.htm
Further Reading
- Introduction to Fonts: http://wiki.tcl.tk/5997
- How does one change the font in the wish widgets: http://wiki.tcl.tk/470
- Practical Guide to Choosing Fonts: http://wiki.tcl.tk/451
- Donal Fellows' guide to the option database:
http://people.man.ac.uk/~zzcgudf/tcl/option-tutorial.html