Version 7 of font measure

Updated 2010-10-24 10:30:00 by dkf
font measure font ?-displayof window? text

Measures the amount of space the string text would use in the given font when displayed in window. font is a font description; see FONT DESCRIPTIONS below. If the window argument is omitted, it defaults to the main window. 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". If the string contains newlines or tabs, those characters are not expanded or treated specially when measuring the string.

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]