Tk has a rather clever method of font substitution;
however, it doesn't work well with Type 1 fonts on
WinXP.
The trouble seems to be in tkWinFont.c, in the function
LoadFontRanges(). It uses GetFontData() from the
Win32 API, but the platform SDK states "If an application
attempts to use this function to retrieve information for
a non-TrueType font, an error occurs."
I wrote a little program (source available on request) to
try this out, and indeed
n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof
(cmapTable));
returns GDI_ERROR with a Type 1 font selected into
hdc. (I cut-and-pasted this from tkWinFont.c, along
with what I thought was enough of the preceding code
to declare the tables and whatnot.) Perhaps this isn't
saying much, since even for TrueType fonts I get
GDI_ERROR. Maybe using
hdc = CreateCompatibleDC(NULL);
to create a device context isn't the right way; maybe I
need to write a "real" Windows program with WinMain
and a HWND so I can get a real HDC instead of plain
main. But we will assume the docs to be true, so that
Type 1 fonts return GDI_ERROR.
So, I check
if (GetTextCharset(hdc) == ANSI_CHARSET)
as tkWinFont.c does, and this comes up true for every
font I throw in, Type 1 or TrueType. The code in
LoadFontRanges() would then declare that the character
range for the font is 0x00 to 0xff, which means that for
a Type 1 font any character outside of that range will
be substituted for, as is the case.
Now, WinXP (and Win2K) has a function
GetFontUnicodeRanges() that accurately reports what
glyphs are available in a Type 1 font. It also works for
TrueType fonts. I propose that this function be used in
tkWinFont.c instead of GetFontData() for those ports of
Tk to versions of Windows that support it. TextOut()
works with Type 1 fonts (from personal experience), so I
would assume GetTextExtentPoint32() would also,
meaning that very little of the rest of tkWinFont.c would
have to be touched.
I suppose I should submit a patch. Why don't I?
1) I've never submitted a patch before.
2) I don't know the protocol for patching something to
work on only some versions of Windows.
Logged In: YES
user_id=72656
The Tk TkWinGetPlatformId() function gives you the info you
need (VER_PLATFORM_WIN32_*) for version. Patches should be
in diff -u format against the cvs head or core-8-4-branch
head, or the closest version you can get to that.
Logged In: YES
user_id=616899
I don't think it will be this easy. In other words, I don't think
we can just add a conditional based on TkWinGetPlatformId().
GetFontUnicodeRanges() is declared, along with the two
structs it needs, in WinGdi.h. But these declarations are
included only if _WIN32_WINNT is defined to be at least
0x0500.
And even if we just put the declarations in by hand, like those
right before LoadFontRanges() in tkWinFont.c,
GetFontUnicodeRanges() isn't stubbed in OSs besides
Win2K/WinXP, so there will be linker issues. I'm not sure what
the best approach is in this case.
I did write a little XSUB for Perl/Tk that solves the problem --
it takes a previously created Type1 font and replaces the
appropriate entries in the FontFamily struct of the SubFont in
question -- so I'm fairly certain GetFontUnicodeRanges() is
the way to go.
Logged In: YES
user_id=72656
Check out the patch I made at
https://sourceforge.net/tracker/?func=detail&aid=892194&group_id=12997&atid=312997
as an example of how you can easily handle Win2K/XP only
features (in that case, it's toplevel transparency and
SetLayeredWindowAttributes). We don't need to worry about
the compilation phase - we need to just make sure we check
at runtime before using it.