Version 4 of font measure

Updated 2003-03-04 18:09:28

MGS Following a message posted by James Bonfield on The comp.lang.tcl newsgroup regarding the slowness of the 'font measure' command for 'unused' fonts, I had a couple of ideas.

The 'font measure' command does not expand newlines or tabs (it appears to treat each as a double-space), so it doesn't give a true indication of how wide a label (for example) would be using the specified font and text.

 proc font:width {font text {w .}} {

   puts "  measure   = \[[font measure $font -displayof $w $text]\]"

   set max 0
   foreach line [split $text \n] {
     set width [font measure $font -displayof $w $line]
     if { $width > $max } { set max $width }

   puts "  max width = \[$max\]"
   return $max


The font man page says: "The return value is the total width in pixels of text, not including the extra pixels used by highly exagerrated characters such as cursive 'f'." So the only real way to find the required width (and height) of a string is to put it into a label and get the size of the label:

 proc font:reqwidth {font text {w ""}} {

   for {set i 1} {[winfo exists $w.label-$i]} {incr i} {}
   set l $w.label-$i
   label $l -bd 0 -padx 0 -pady 0 -highlightthickness 0 \
     -font $font \
     -text $text
   set width  [winfo reqwidth  $l]
   set height [winfo reqheight $l]
   puts "  reqwidth  = \[$width\]"
   puts "  reqheight = \[$height\]"
   destroy $l
   return $width


 # demo code
 set font [font create -family courier -size 10]
 set text "new\t\nline"
 font:width $font $text
 font:reqwidth $font $text

gives the output:

 measure   = [99]
 max width = [45]
 reqwidth  = [72]
 reqheight = [30]