Version 7 of Practical Guide to Choosing Fonts

Updated 2002-07-15 21:40:19

Most Tk programs don't require specific fonts, whether for typefaces, typesizes, or whatever. For many apps, the most important criteria is good-looking and readable fonts. However, Tk provides no way of specifying the quality of a font.

Alas, the platform-neutral fonts don't solve the problem - sometimes they just look bad and a platform-specific choices is much better, so I'll have to put in a switch for the different platforms. For example:

   switch $tcl_platform(platform) "unix" {
      set font times-roman-10
   } "macintosh" {
      set font {-size 9}
   } "windows" {
      set font {-family {MS Sans Serif} -size 7}
   }

I find myself struggling with this frequently. Everytime I need to modify the font from the defaults, I have to play guessing games, trying out various font specifications and seeing what Tk will give me.

And then I have to repeat it on the different platforms (UNIX, Win, Mac) and maybe several variations to make sure it's not some non-standard font that might not exist on another computer of the same type. Even then, I've no guarantees that my little world of computers covers the universe to which my software could be run on.

With that in mind, I'd like to build some tables of fonts that are "good".

I'm thinking of several orthogonal attributes, with things like "size" and "serif-vs-non-serif" and "style (casual, typewriter, formal)".

Here's an initial proposal for sizes without regard to those other attributes:

  • barely readable / teeny
  • uncomfortably small
  • distinctively smaller than "comfortable"
  • comfortable
  • distinctively bigger than "comfortable"
  • screamingly larger

Don't immediately snap at me that "oh, those terms are so vague", or "what's comfortable on one platform (or screen) will be uncomfortable or bad on another". The fonts don't have to be the same across platforms. In fact, they assuredly *won't* be the same. That's the point of this work.

In practise, there are three main styles of font:

Serif
Times, Palatino, Bookman, and many many others. Most web-browsers default to using a serif font for displaying web pages. If you can stand the use of variable width text, this is the best choice for large bodies of text.

http://www.cs.man.ac.uk/~fellowsd/tcl/wikipix/serif.gif

Sans-Serif
Helvetica, Arial, and many others. Tk and many other widget sets usually default to using a sans-serif font (though this is usually configurable.) This group of fonts is often used in printed matter for headings and headlines.

http://www.cs.man.ac.uk/~fellowsd/tcl/wikipix/sans.gif

Monospace
Courier is the most common example of this type of font. These kinds of fonts look like typewriter output, and all the characters are the same width (so a row of 10 'M' characters is the same width as a row of 10 'i' characters.) These fonts are nothing like as easy to read as ordinary text, and so should normally be used sparingly in GUIs outside of user-editable fields and text that is explicitly intended to represent typed input or program source.

http://www.cs.man.ac.uk/~fellowsd/tcl/wikipix/mono.gif

Of course, there are also fonts that do not fit into this neat pattern (e.g. Symbol, Zapf Chancery, Zapf Dingbats, Marlett, etc.) but you mostly don't use those without good reason due to a lack of normal characters(!) or a very low general readability.

NOTE: Before editing this table, TRY OUT THE FONTS you are recommending on all the platforms you are recommending them for. The names of fonts sometimes SEEM like they ought to be right but sometimes they simply suck. That's why this table has to be built by hand in the first place.


UNIX

               mono          serif          sans-serif
 teeny         5x8           times-roman-10
 small
 comfortable   {Courier -12} {Times -14}    {Helvetica 10}
 big                                        {avantgarde 10}
 screaming     {Courier 48}

For balanced text using the Times/Helvetica/Courier set of fonts, you will need to use Courier set as being about 2 points smaller than the other two. I don't know why this is necessary, but without it the monospaced text looks far too large in comparison. - DKF

A lot of this choice on X, however depends on just how an X Server has been set up. A Times 10 may not seem small on a 17" or 19" monitor, where 100dpi fonts preceed 75dpi fonts in the font path. With xfstt, xtt, and other TrueType fontservers growing in use, and native TrueType becoming part of XFree86 X11R6.4, it becomes all the more crucial that fonts be easily user selectable. Bruce Gingery


Windows

               mono           serif         sans-serif
 teeny
 small                                      {{MS Sans Serif} 7}
 comfortable   {Courier 12}   {Times 12}    {{MS Sans Serif} 8}
 big                                        {Helvetica 10}
 screaming

Macintosh

               mono           serif         sans-serif
 teeny                        {-size 9}
 small 
 comfortable   {Courier 12}   {Times 12}
 big                                        {Helvetica 10}
 screaming

UNDER NO CIRCUMSTANCES SHOULD YOU USE MORE THAN ONE SERIF FONT, MORE THAN ONE SANS-SERIF FONT, OR MORE THAN ONE MONOSPACE FONT ON A SCREEN AT A TIME. Everyone has seen the "There are 400 different fonts in this DTP package and I am going to use every one of them!!!" type of document from time to time, and they suck so much you can use them to lift heavy steel panels. A few fonts used effectively is always better - the end product looks better and more professional, and it is easier to use too.


Created by (in order of appearance): DL, DKF

KBK: [L1 ] adds:

The combinations,

                  Courier   10/12/15/18
                  Times     10/12/15/18
              and Helvetica 10/12/15/18

are available and generally attractive on all the platforms, with a single caveat: The scaling must be set correctly for the screen. Some platforms do this gracefully, and some don't. When I do a big app, I generally use the 'tk scaling' command at the start, and have a separate panel where the user can customize the scaling value. If you adjust the scaling, and never use pixel-based font metrics (negative sizes), you'll be a much happier camper. //Kevin


Here is a cute script written by Kevin Kenny for helping compute the scaling factor that 'tk scaling' needs. - DL

 # Determine screen width and height, screen diagonal, and screen aspect.
 # Phi is the angle that the screen diagonal makes with the horizontal,
 # assuming square pixels.

 set screenwd [winfo screenwidth .]
 set screenht [winfo screenheight .]

 set screendiag [expr {sqrt ($screenwd*$screenwd + $screenht*$screenht)}]

 set cos_phi [expr {1.0 * $screenwd / $screendiag}]
 set sin_phi [expr {1.0 * $screenht / $screendiag}]

 # Make a canvas to display the ruler

 set winwd [expr 0.8*$screenwd]
 set winht [expr 0.8*$screenht]

 grid [canvas .c -width $winwd -height $winht] -columnspan 2

 # Compute ruler length, start, and end.  Draw the ruler.

 set rlen_nominal [expr {0.8 * $screendiag - 150}]
 set rlen [expr {50 * int($rlen_nominal / 50)}]

 set x0 [expr {($winwd - $rlen * $cos_phi) / 2}]
 set y0 [expr {($winht - $rlen * $sin_phi) / 2}]

 set xend [expr {$x0 + $rlen * $cos_phi}]
 set yend [expr {$y0 + $rlen * $sin_phi}]

 .c create line $x0 $y0 $xend $yend

 # Draw ticks on the ruler, and label the major ticks.

 for {set p 0} {$p < $rlen+12} {incr p 50} {
    set h0 [expr {$x0 + $p * $cos_phi}]
    set k0 [expr {$y0 + $p * $sin_phi}]
    set h1 [expr {$h0 + 20.0 * $sin_phi}]
    set k1 [expr {$k0 - 20.0 * $cos_phi}]
    .c create line $h0 $k0 $h1 $k1
    .c create text $h1 $k1 -anchor sw -text $p
 }
 for {set p 0} {$p < $rlen+5} {incr p 10} {
    if {$p % 50} {
        set h0 [expr {$x0 + $p * $cos_phi}]
        set k0 [expr {$y0 + $p * $sin_phi}]
        set h1 [expr {$h0 + 10.0 * $sin_phi}]
        set k1 [expr {$k0 - 10.0 * $cos_phi}]
        .c create line $h0 $k0 $h1 $k1
    }
 }
 for {set p 5} {$p < $rlen+2} {incr p 10} {
    set h0 [expr {$x0 + $p * $cos_phi}]
    set k0 [expr {$y0 + $p * $sin_phi}]
    set h1 [expr {$h0 + 5.0 * $sin_phi}]
    set k1 [expr {$k0 - 5.0 * $cos_phi}]
    .c create line $h0 $k0 $h1 $k1
 }

 # Make a handy-dandy calculator for resolution.

 grid [label .l1 -text "Pixels:"] [entry .e1 -textvariable pixels] -sticky w
 grid [label .l2 -text "Inches:"] [entry .e2 -textvariable inches] -sticky w
 grid [label .l3 -text "Pixels/inch"] \
        [entry .e3 -state disabled -textvariable ppi] -sticky w
 grid [label .l4 -text "Pixels/point (tk scaling factor)"] \
        [entry .e4 -state disabled -textvariable ppp] -sticky w
 grid columnconfigure . 1 -weight 100

 trace variable pixels w update_ppi
 trace variable inches w update_ppi

 proc update_ppi args {
    uplevel #0 {
        catch {
            set ppi [expr {1.0 * $pixels / $inches}]
            set ppp [expr {$pixels / ($inches * 72.0)}]
        }
    }
 }

LV: How about some advice on how to select good Unicode related fonts on Unix? In particular good quality Kanji fonts.

DKF: Can't help here. I wouldn't know a good Kanji font if it jumped up and bit me (other than by looking at whether it is a stroked or a bitmapped font; the former are usually better, particularly at large sizes. The usual X rasterizer isn't very good at handling small fonts though, which is where bitmapped fonts tend to come into their own.)

DNK: Two I've seen suggested are both TrueType fonts: Microsoft's "Arial Unicode" and the Bitstream Cyberbit font. [L2 ] describes how to set these up and make them work; following the recommended procedures makes them display beautifully, except that I can't coax any non-Latin-1 characters out of them no matter what I do. Your mileage will hopefully vary.


Category Porting