Tkinter: Text widget and fixed-width fonts

jepler at unpythonic.net jepler at unpythonic.net
Tue May 28 21:45:43 EDT 2002


On Wed, May 29, 2002 at 12:34:41AM +0000, Hans Nowak wrote:
> 
> Howdy y'all,
> 
> I wanted to use the Tkinter Text widget to display text in a fixed
> width font, assuming that lines with an equal number of characters
> would also have equal length. E.g. a line of "." * 40 should have
> the same length as "M" * 40. While this works for "regular"
> characters, it doesn't seem to work for special characters (possibly
> ASCII >= 128).

This is probably deep tk stuff.  It's very likely that this problem will
exist when running an equivalent program under wish:

    text .t -font [font create -family FixedSys -size 8]
    set line1 "[string repeat "\374" 80]\n"
    set line2 "[string repeat "W" 80]\n"
    set line3 "[string repeat "." 80]\n"
    .t insert end "$line1$line2$line3"

    pack .t

Behind the scenes, Tk does all sorts of magic to provide all Unicode
characters in every font.  It does this by attempting to find characters in
other fonts when necessary.  This fallback process is different on Windows
and Unix (and probably different still on Mac, but I've never read that
code).  The last steps in this process try to use fonts returned from
'TkFontGetGlobalClass()' and then "[t]ry all face names available in the
whole system until we find one that can be used."  The action of "try"ing
boils down into the CanUseCallback() function, which doesn't seem to take
into account whether the font is fixed or not.

So my guess is that you don't actually have that character in any of the
normal (correct, fixed-width) fallback fonts, but one does show up in a
non-fixed font which is reached in one of these "last gasps" steps.  (Using
unicode characters chosen at random can show a similar problem on my Linux
system)

You might be interested in this note on fonts and encodings from the Tcl/Tk
people:
    The process of identifying suitable fonts is complex, and Tk's
    algorithms don't always find a font even if one is actually installed
    on the system.  Therefore, for best results, you should try to
    select as a widget's master font one that is capable of handling the
    characters you expect to display.  For example, "Times" is likely
    to be a poor choice if you know that you need to display Japanese
    or Arabic characters in a widget.

    If you work with text in a variety of character sets, you
    may need to search out fonts to represent them. Markus Kuhn
    has developed a free 6x13 font that supports essentially
    all the Unicode characters that can be displayed in a 6x13
    glyph. This does not include Japanese, Chinese, and other Asian
    languages, but it does cover many others. The font is available at
    http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html. His site also contains
    many useful links to other sources of fonts and font information.
	(excerpt from http://www.tcl.tk/doc/howto/i18n.html#tk)

Of course, even once you've found a font which displays all european fonts
with characters of one width, then you'll run into Japanese
characters--

    The strlen function does not have to be replaced where the result is
    used as a byte count, for example to allocate a suitably sized buffer
    for a string. The second most common use of strlen is to predict,
    how many columns the cursor of the terminal will advance if a string
    is printed out.  With UTF-8, a character count will also not be
    satisfactory to predict column width, because ideographic characters
    (Chinese, Japanese, Korean) will occupy two column positions. To
    determine the width of a string on the terminal screen, it is
    necessary to decode the UTF-8 sequence and then use the wcwidth
    function to test the display width of each character.
	(excerpt from http://www.cl.cam.ac.uk/~mgk25/unicode.html)

I didn't find anything directly addressing this issue.  Like I said, this
is some sort of deep Tk issue.  If you can, take the bug report there ..
dunno if you'll find an answer, though.

Jeff





More information about the Python-list mailing list