Version 0 of font measure

Updated 2003-03-04 18:07:09

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]