Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TIP #64: Improvements to Windows Font Handling

7 views
Skip to first unread message

Chris Nelson

unread,
Sep 28, 2001, 10:21:01 AM9/28/01
to

TIP #64: IMPROVEMENTS TO WINDOWS FONT HANDLING
================================================
Version: $Revision: 1.1 $
Author: Chris Nelson <ch...@pinebush.com>
State: Draft
Type: Project
Tcl-Version: 8.4
Vote: Pending
Created: Thursday, 27 September 2001
URL: http://purl.org/tcl/tip/64.html
WebEdit: http://purl.org/tcl/tip/edit/64
Post-History:

-------------------------------------------------------------------------

ABSTRACT
==========

This TIP improves handling of native fonts in Tk under Microsoft
Windows making Tk applications more aesthetic and more consistent with
users' expectations of Windows applications.

BACKGROUND
============

Tk 8.4 includes platform-specific system font names which relate to
configurable aspects of the native system.

* On UNIX, this includes all X font names (e.g. as listed by
_xlsfonts_).

* On Macintosh, this includes _system_ and _application_.

* On Microsoft Windows, this includes _system_, _systemfixed_,
_ansi_, _ansifixed_, _device_, and _oemfixed_.

Through v8.4a2, Tk used 8pt MS Sans Serif as the default font for
widgets. While this was almost OK, it fails in two respects:

* Users can change the font used for various Windows desktop
features so MS Sans Serif may not be the correct font for, for
example, menus.

* Windows 2000 and Windows XP use Tahoma, not MS Sans Serif as
their default font.

SourceForge patch #461442 (Make Tk use the default Windows font) -
<URL:https://sourceforge.net/tracker/index.php?func=detail&aid=461442&group_id=12997&atid=312997>
- attempts to address Tk's deficiency by adding a _windefault_ font
based on the Message font configured for the Windows desktop. This
appears to be wrong.

This TIP attempts to fix the default Tk font the right way as well as
giving Tk programmers access to the rest of the fonts configure for the
Windows desktop.

THE DEFAULT GUI FONT
======================

The Win API call _GetStockObject()_ accesses brushes, pens, and fonts
which are pre-configured on the system. The available fonts are:

1. ANSI_FIXED_FONT

2. ANSI_VAR_FONT

3. DEVICE_DEFAULT_FONT

4. DEFAULT_GUI_FONT

5. OEM_FIXED_FONT

6. SYSTEM_FIXED_FONT

7. SYSTEM_FONT

The _TkStateMap systemMap_ in _tkWinFont.c_ listed all but one of
these, DEFAULT_GUI_FONT. As it turns out, this is the most important as
it is the one that Windows uses as it's default font (for example, in
Control Panel Applets).

I propose to add DEFAULT_GUI_FONT to the _systemMap_ with a font name
of _defaultgui_ and to change CTL_FONT in _tkWinDefault.h_ from _{MS
Sans Serif} 8_ to _defaultgui_. This will require a change in
documentation to list the new system font name but is otherwise simple
and painless. Furthermore, it makes Tk GUIs look right on W2k.

A reference implementation for this is available in patch 461442
(referenced above).

ACCESS TO DESKTOP FONTS
=========================

The original implementation of _windefault_ as a new font, accessed the
message font from the NONCLIENTMETRICS structure. While this is not, in
fact, the correct default GUI font, it is an important system font, as
are the others on the NONCLIENTMETRICS structure. The structure lists:

* Caption (title bar) font

* Small Caption (palette title bar) font

* Menu font

* Tooltip (and status bar) font

* Message box font

The Windows Desktop Properties also include a font for icon labels on
the desktop. This font is accesses with _SystemParametersInfo()_.

I propose to add 6 desktop fonts as system fonts on Windows. The names
would be derived from their Desktop Properties entries: _dtIcon_,
_dtTitleBar_, _dtMenu_, _dtMessageBox_, _dtPaletteTitle_, _dtToolTip_.
The "dt" prefix associates the fonts with the desktop properties. (Can
or should font names have internal capital letters?)

We might also add synonyms which relate to the structure field names
and/or customary use of the font. I'd propose adding _dtCaption_ as
equivalent to _dtTitleBar_, _dtSmallCaption_ as equivalent to
_dtPaletteTitle_, and _dtStatus_ as equivalent to _dtToolTip_.

A reference implementation for this is available in Patch #461442
(referenced above) albeit with different font names.

DYNAMIC FONTS
===============

Many Windows applications respond on-the-fly to changes in the desktop
fonts. Tk responds to changes in Tk fonts via [font configure]. I
propose that Tk respond to the WM_SETTINGCHANGE message from Windows to
propagate changes to the desktop fonts enumerated above as it
propagates changes to Tk fonts when they are reconfigured. I have yet
to prototype these changes.

COPYRIGHT
===========

This document has been placed in the public domain.

-------------------------------------------------------------------------

TIP AutoGenerator - written by Donal K. Fellows

[[Send Tcl/Tk announcements to tcl-an...@mitchell.org
Send administrivia to tcl-announ...@mitchell.org
Announcements archived at http://groups.yahoo.com/group/tcl_announce/
The primary Tcl/Tk archive is ftp://ftp.neosoft.com/pub/tcl/ ]]

Chris Nelson

unread,
Sep 28, 2001, 12:59:38 PM9/28/01
to
Chris Nelson wrote:
> ...

> DYNAMIC FONTS
> ===============
>
> Many Windows applications respond on-the-fly to changes in the desktop
> fonts. Tk responds to changes in Tk fonts via [font configure]. I
> propose that Tk respond to the WM_SETTINGCHANGE message from Windows to
> propagate changes to the desktop fonts enumerated above as it
> propagates changes to Tk fonts when they are reconfigured. I have yet
> to prototype these changes.
> ...

I'm trying to work on this part. In tkWinX.c, I've added to
Tk_TranslateWinEvent:

case WM_SETTINGCHANGE: {
OutputDebugString("Got WM_SETTINGCHANGE");
if (wParam == SPI_SETICONTITLELOGFONT
|| wParam == SPI_SETNONCLIENTMETRICS) {
/* User may have changed system fonts. Update Tk */
OutputDebugString("Got a font-related message");
}
break;

But I'm not seeing the debug strings. Am I poking in the wrong place to
add this handler?

Chris
--
Rens-se-LEER is a county. RENS-se-ler is a city. R-P-I is a school!

Chris Nelson

unread,
Oct 2, 2001, 3:13:45 PM10/2/01
to

<SIGH> My system wasn't unloading the Tk dll so my changes weren't
having an effect. I'm farther along now; though, I fear, not close to a
solution.

Chris
--
Never doubt that a small group of thoughtful, concerned citizens
can change the world. Indeed, it's the only thing that ever has.
--Margaret Mead

Chris Nelson

unread,
Oct 2, 2001, 3:41:18 PM10/2/01
to
Chris Nelson wrote:
> ...

> DYNAMIC FONTS
> ===============
>
> Many Windows applications respond on-the-fly to changes in the desktop
> fonts. Tk responds to changes in Tk fonts via [font configure]. I
> propose that Tk respond to the WM_SETTINGCHANGE message from Windows to
> propagate changes to the desktop fonts enumerated above as it
> propagates changes to Tk fonts when they are reconfigured. I have yet
> to prototype these changes.

I'm making progress. I've added to tk\win\tkWinWm.c a clause like:

case WM_SETTINGCHANGE: {
OutputDebugString("Got WM_SETTINGCHANGE\n");


if (wParam == SPI_SETICONTITLELOGFONT
|| wParam == SPI_SETNONCLIENTMETRICS) {
/* User may have changed system fonts. Update Tk */

TkWindow *winPtr = GetTopLevel(hwnd);
Tk_UpdateFonts((ClientData)winPtr);
result = 0;
goto done;
}
break;
}

Where Tk_UpdateFonts() is a new function in generic\tkFont.c:

void Tk_UpdateFonts(clientData)
ClientData clientData; /* Toplevel window to work in */
{
TkWindow *winPtr;

winPtr = (TkWindow *)clientData;

if (fontUpdatePending == 0) {
fontUpdatePending = 1;
Tcl_DoWhenIdle(RecomputeWidgets, (ClientData)winPtr);
}
}

I've put some tracing in RecomputeWidgets() and it does traverse the
widget hierarchy and redraw everything. But it uses the existing system
fonts. What do I need to do to invalidate the system fonts and get
TkpGetNativeFont to be called again?

0 new messages