Re: font selection, particularly for the Identify and About windows
"Greg A. Woods" <[email protected]> Tue, 05 Nov 2024 11:15:55 -0800
| Newsgroups | gmane.comp.window-managers.ctwm |
|---|---|
| Organization | Planix, Inc. |
| Message-ID | <[email protected]> |
--pgp-sign-Multipart_Tue_Nov__5_11:15:44_2024-1 Content-Type: text/plain; charset=US-ASCII So, I've found the problem. After comparing code with the latest version of good old twm original, I finally spotted where things were going wrong. CTWM is handling fonts very incorrectly! The first big problem is the broken hack of tacking ",*" onto the end of every font specification in some lame attempt to try to turn broken XLFD font specifications into "working" FontSets. This is WRONG. It is a very unstable and problematic hack. It is _NOT_ what modern twm does. The result is entirely dependent on whatever fonts are installed and how the X server's font path is configured. NEVER EVER do this! When CTWM was first changed to create FontSets it should have been documented as using FontSets, and this hack should never have been used at all, even for the built-in fonts! All you end up with is the first random font in your font list -- I ended up with a fixed 75dpi bitmap font and I was trying to display it on 218dpi and 331dpi monitors! Users should be free create their on full fontSets, and to add whatever wildcard fonts to the end of the fontSet specs if desired, but in reality with iso10646-1 fonts widely available these days it is rare to ever need more than just one font in a fontSet. The next big problem is that any attempt to use a font alias, e.g. the "misc" font.alias entries like "fixed" or "variable" is probably not ever going to work with FontSets. While I don't think the code or any built-in font or configuration was still using said aliases, the documentation was. The attached patches fix the first problem, and also should fix the built-in fonts to use scalable fonts, in iso10646-1, so that they will work correctly on high-resolution monitors, and to use generic enough font families to work on a much wider variety of default X11 installs. (I've tested with XQuartz (on macos), Debian, NetBSD, and FreeBSD.) I also added some warning messages, taken from the current twm, that might help people see what might be wrong with their hand-crafted fontSet specifications, especially with the broken-in-modern-times en_US-UTF-8/XLC_LOCALE database still shipped with libX11. (That's another story!) There may be some artificial "height" adjustment that might still be causing line spacing, e.g. especially in menus, to be a little too much, but I haven't looked into that yet. I left some other hacks in to keep the diff small and readable, including some memory minor leaks (but I fixed one memory leak!). The documentation also needs some serious fixing in related areas, specifically to tell people these are indeed in fact fontSets, and that they should consider setting "*international:true" in their resources and switching everything to fontSets, and that when specifying scalable fonts for a monitor that has a different apparent DPI than the original font was designed for they must explicitly specify the actual/apparent resolution in the XLFD spec, and NEVER EVER use pixel sized fonts -- that MUST be set to '0' for scaling to work. The DefaultFont itself should also be configurable -- or maybe instead a special new font variable should be created for about and identify windows, though the whole concept of a "default font" when there are built-in defaults for all fonts is kinda questionable. A better set of fixes might be to ditch XLFD entirely and move to Xft. (then users only need to set the DPI once globally in a resource) -- Greg A. Woods <[email protected]> Kelowna, BC +1 250 762-7675 RoboHack <[email protected]> Planix, Inc. <[email protected]> Avoncote Farms <[email protected]> diff --git a/ctwm_main.c b/ctwm_main.c index 0a0aefb4..90d42ef2 100644 --- a/ctwm_main.c +++ b/ctwm_main.c @@ -1328,10 +1328,31 @@ InitScreenInfo(int scrnum, Window croot, int crootx, int crooty, scr->workSpaceMgr.icon_name = "WorkSpaceManager Icon"; - // Setup default fonts in case the config file doesn't -#define DEFAULT_NICE_FONT "-*-helvetica-bold-r-normal-*-*-120-*" -#define DEFAULT_FAST_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-*" -#define SETFONT(fld, var) (scr->fld##Font.basename = DEFAULT_##var##_FONT) + /* from xdpyinfo.c: + * there are 2.54 centimeters to an inch; so there are 25.4 millimeters. + * + * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) + * = N pixels / (M inch / 25.4) + * = N * 25.4 pixels / M inch + */ + scr->xres = (int) (((((double) DisplayWidth(dpy, scr->screen)) * 25.4) / + ((double) DisplayWidthMM(dpy, scr->screen))) + 0.5); + scr->yres = (int) (((((double) DisplayHeight(dpy, scr->screen)) * 25.4) / + ((double) DisplayHeightMM(dpy, scr->screen))) + 0.5); + + // Setup default fontSets in case the config file doesn't + // + // Use iso10646-1 because that's why we're here! + // + // "bitstream charter" is the only proportional, scalable, iso10646-1 + // font common to most modern X11 platforms (especially GNU/Linux!) + // + // "courier*" must have the star(*) because it may need to match either + // "courier" or "courier 10 pitch", depending on which is available. + // +#define DEFAULT_NICE_FONT "-*-bitstream charter-medium-r-normal--0-100-%d-%d-p-*-iso10646-1" +#define DEFAULT_FAST_FONT "-*-courier*-medium-r-normal--0-100-%d-%d-m-*-iso10646-1" +#define SETFONT(fld, var) asprintf(&scr->fld##Font.basename, DEFAULT_##var##_FONT, scr->xres, scr->yres) SETFONT(TitleBar, NICE); SETFONT(Menu, NICE); @@ -1339,8 +1360,9 @@ InitScreenInfo(int scrnum, Window croot, int crootx, int crooty, SETFONT(Size, FAST); SETFONT(IconManager, NICE); SETFONT(Default, FAST); - scr->workSpaceMgr.windowFont.basename = - "-adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1"; + asprintf(&scr->workSpaceMgr.windowFont.basename, + "-*-courier*-medium-r-normal--0-75-%d-%d-m-*-iso10646-1", // FAST, but smaller + scr->xres, scr->yres); #undef SETFONT #undef DEFAULT_FAST_FONT diff --git a/parse_be.c b/parse_be.c index e84e865f..6ccaea3e 100644 --- a/parse_be.c +++ b/parse_be.c @@ -970,6 +970,10 @@ do_string_keyword(int keyword, char *s) } case kws_IconFont: + // see the comment in ctwm_main.c just before the call + // to CreateFonts() as to why are these all wrapped in + // !HaveFonts XXX it still maybe doesn't make sense here + // though.... if(!Scr->HaveFonts) { Scr->IconFont.basename = s; } diff --git a/screen.h b/screen.h index de281e48..81603eb8 100644 --- a/screen.h +++ b/screen.h @@ -142,6 +142,9 @@ struct ScreenInfo { /// @} #endif + int xres; ///< horizontal DPI + int yres; ///< vertical DPI + int MaxWindowWidth; ///< Largest window width to allow int MaxWindowHeight; ///< Largest window height to allow diff --git a/system.ctwmrc b/system.ctwmrc index f23b68d5..cc5325cf 100644 --- a/system.ctwmrc +++ b/system.ctwmrc @@ -10,11 +10,8 @@ # any windows and to use meta-keys. # -TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" -ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" -MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" -IconFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" -IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*" +# n.b. the default fonts are scalable fonts with the correct resolution + ShowWorkSpaceManager # start with workspace manager up UseThreeDMenus UseThreeDTitles diff --git a/util.c b/util.c index 3cc91503..991c92dd 100644 --- a/util.c +++ b/util.c @@ -338,15 +338,19 @@ GetFont(MyFont *font) XFreeFontSet(dpy, font->font_set); } - asprintf(&basename2, "%s,*", font->basename); + /* xxx eliminate the VERY bad ",*" hack but keep the asprintf() for now */ + asprintf(&basename2, "%s", font->basename); if((font->font_set = XCreateFontSet(dpy, basename2, &missing_charset_list_return, &missing_charset_count_return, &def_string_return)) == NULL) { - fprintf(stderr, "Failed to get fontset %s\n", basename2); + fprintf(stderr, "Failed to get fontset \"%s\"\n", basename2); if(Scr->DefaultFont.basename) { deffontname = Scr->DefaultFont.basename; } + free(basename2); + asprintf(&basename2, "%s", deffontname); + fprintf(stderr, "trying default fontset \"%s\"\n", basename2); if((font->font_set = XCreateFontSet(dpy, deffontname, &missing_charset_list_return, &missing_charset_count_return, @@ -356,7 +360,16 @@ GetFont(MyFont *font) exit(1); } } - free(basename2); + if (missing_charset_count_return) { + fprintf(stderr, "%d charsets are missing from fontset \"%s\"\n", + missing_charset_count_return, basename2); + for (i = 0; i < missing_charset_count_return; i++) { + fprintf(stderr, "font for charset %s is lacking.\n", + missing_charset_list_return[i]); + } + XFreeStringList(missing_charset_list_return); + } + font_extents = XExtentsOfFontSet(font->font_set); fnum = XFontsOfFontSet(font->font_set, &xfonts, &font_names); @@ -373,6 +386,12 @@ GetFont(MyFont *font) font->avg_height = 0; font->avg_fheight = 0.0; font->avg_count = 0; + if(CLarg.PrintErrorMessages) { /* xxx overload, but kinda like old twm */ + fprintf(stderr, "created fontset with %d fonts (%d missing) for \"%s\"\n", + fnum, missing_charset_count_return, + basename2); + } + free(basename2); } --pgp-sign-Multipart_Tue_Nov__5_11:15:44_2024-1 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit Content-Description: OpenPGP Digital Signature -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQRuK6dmwVAucmRxuh9mfXG3eL/0fwUCZypu5gAKCRBmfXG3eL/0 f4mzAJ9XZphq5NcKMbcZfASOiLtiQ6v0PgCg9HM8pqaeFgqbYS4hoQ3jAGTYmPw= =iaCc -----END PGP SIGNATURE----- --pgp-sign-Multipart_Tue_Nov__5_11:15:44_2024-1--