C—
Fonts
This appendix describes how to use the new methods in Tk8.0 to create and maintain fonts. In Tk4, you could only pass a font string to -font option. You can still pass a font string in Tk8.0, but you can also use some methods to create your own named fonts and perform operations on them. First I'll go over the simple way to use a font string, which works in both versions. Then we'll get into the more complicated methods available with Tk8.0.
The Font String
When there is a -font option for a widget, you need to pass a string that indicates which font to use. There are several ways to specify a font string:
• Specify the name of a font with the fontCreate method (fontCreate is explained later in this chapter in "Font Methods").
• Use a string that describes the font and follows a predefined format (see Appendix B, Operating System Differences); for example, "Times 12 Normal."
• Use the name of a font that can be interpreted by the graphics display (typically a Unix system running X Windows). These strings usually have asterisks in them and are very hard for humans to comprehend.
To specify a font in a string, you first have to know which fonts are available on your system.
Determining Available Fonts
In Unix, you must specify fonts by using a long, drawn-out syntax with a lot of asterisks that represent families, size, type, and so on. In the X Window System, you can get a list of Unix fonts by running the command
xlsfonts > font_file
The file named font_file will now contain a huge list of fonts that you can use on your system. Be careful when picking fonts from this huge list. If you are going to be running your application from more than one system, the font you pick might not be available on all systems.
If you use Microsoft Windows, you'll have a different way of seeing what fonts are available. Click on the Start menu and select Settings (r) Control Panel. Once the Control Panel appears, double-click Fonts and a window similar to the one shown in Figure C-1 appears.
0335-01.gif
Figure C-1.
The Fonts from a Windows 95 System
My system has most of the standard fonts and a few that I've downloaded over the Internet, such as augie and Bard. If I want to use these fonts I have to know how to specify them. If you double-click on a font name, another window appears and displays detailed information about the font (see Figure C-2).
The information about the font includes how much space it takes up on the hard drive (64K in this case), what version it is, and its name. It also lists the available sizes. The Arial font starts at 12 points and goes up to 72 points. To use the -font option to specify this font for a widget (for instance, a button), you need to know the name of the font (Arial), the size, and the type (normal, bold, or italic). With these
0336-01.gif
Figure C-2.
The Arial font details
three pieces of information, you can build a font string: "Arial 24 normal".* That's all there is to it. To create a button with this font, use the -font option:
$mw->Button(-text => "Exit", -command => sub { exit },
            -font => "Arial 24 normal")->pack();
Figure C-3 shows a button with the default font, and one with a larger font.
0336-02.gif
Figure C-3.
A default size font button and one with Arial 24
If the name of the font has spaces in it such as Times New Roman, you still build the string the same way:
-font => "Times New Roman 12 normal"
* You might also see a font specified with curly braces around the name and the style of the font (e.g., "{Arial} 12 {normal}"). The curly braces are not required
You might see an error on the console when using this type of font specification:
SplitString 'Times New Roman 12 normal' at script line 7
You can ignore these errors, and as far as I know, there is no easy way to get rid of them. Hopefully, later versions of the Tk module will deal more gracefully with this (initial tests with Tk 8.0 show that this error no longer appears).
I don't recommend changing the font for the text on any of the standard widgets because you'll have to worry about whether the font is available. The only place you might absolutely have to change font is in the text widget, and then only if you are actually going to format the text.
One more thing: There is a Tk::Fonts module available, but it doesn't work correctly under Microsoft Windows (95 or NT). If you are using X Windows, you should play around with the Tk::Font a bit; it does have some useful features.
Font Methods
The following methods are available only with the newest version of Perl/Tk, which contains Tk8.0.
Create
The fontCreate method creates a new font.
$name = $widget->fontCreate();
$name = $widget->fontCreate(fontname);
You can either specify a font name or one will be generated in the format "fontX" where X is a number. You can specify options for the font:
$name = $widget->fontCreate(-size => 12);
$name = $widget->fontCreate(fontname, -size => 12);
The options you can use to create a font are as follows:
-family => name
The family name can be
"courier", "times", or "helvetica". If you specify one of these, the closest match on your system will be used. You can also specify the name of a font that is specific to your machine (for example, "Moon Runes"), but it might not show up on other systems.
-size => amount
The amount specified for the font size indicates how big you want the font to be. If the amount is positive, the font will be sized in points. If the amount is negative, the font will be sized by using the absolute value of the amount in pixels.
-weight => "normal" | "bold"
The -weight option determines the thickness of the font.
-slant => "roman" | "italic"
The slant of the font is how far it tips over to one side. By default, "roman" means that the font is upright. Specifying "italic" as the value for -slant will tilt the font to the right slightly.
-underline => 0 | 1
If you want the characters to be underlined, specify 1 for the -underline option.
-overstrike => 0 | 1
A line is drawn through the text when -overstrike has a value of 1.
Configuring
You can change the options associated with a font by using the fontConfigure method. This method works just like a configure method does on any widget:
%optionsNvalues = $widget->fontConfigure(fontname);
$value = $widget->fontConfigure(fontname, -size);
$widget->fontConfigure(fontname, -size => 24); # Change size to 24
You can use the same options with fontCreate and fontConfigure
Actual Information
If a specified font size is not available on the user's system, the system substitutes another font size, or even a different font altogether. You can find out which font is actually displayed by using the fontActual method. To get a list of all options and their values, call fontActual with just a font name:
%vals = $widget->fontActual (fontname);
To get the actual value for just one option:
$value = $widget->fontActual(fontname, -size);
Again, all the options used in fontCreate can be used with fontActual
Deleting
To delete one or more fonts, use the fontDelete method:
$widget->fontDelete(fontname);
$widget->fontDelete(font1, font2);
If the font is currently being used by a widget, it will not actually be deleted until the widget isn't using it anymore. If you re-create a font by using fontCreate with the name of the original font, the widgets that use the original font will use the new font information.
Text Size
You can find out how much space a text string that uses a particular font would take by calling fontMeasure:
$pixels = $widget->fontMeasure(fontname, textstring);
The value returned into $pixels is only an estimate because characters such as "\t" or "\n" aren't expanded before the measurement is taken.
Font Metrics
Metrics are details about a font: the ascent, descent, space between lines, and whether or not the font is proportional. You can use the fontMetrics method to get this information about a named font. Calling fontMetrics with only a font name gives you all the metrics and their values for that font:
%values = $widget->fontMetrics(fontname);
You can also find out the value of a specific metric by passing it in as an option:
$value = $widget->fontMetrics("fontname", -ascent);
Note that you cannot change a font's metrics. They are calculated when the font is created
The valid metric options are as follows:
-ascent
Measures the highest part of the font above the baseline. Amount returned is in pixels.
-descent
Measures the lowest part of the font below the baseline. Amount returned is in pixels.
-linespace
Measures the distance between two lines of text that use the same font. Amount returned is in pixels.
-fixed
Returns 1 if the font is a fixed width font (all characters take up the same amount of space, such as in Courier). Returns 0 if the font is proportional (each character takes up a different amount of space based on how fat or skinny it is; the letter "I" takes up less space than "M").
Families & Names
To find out all the font families that exist on a particular $widget's display, call fontFamilies:
@families = $widget->fontFamilies();
To determine the names of all the fonts that are defined, call fontName:
@names = $widget->fontNames();