diff --git a/OSX/xscreensaver.xcodeproj/project.xcworkspace/xcuserdata/jwz.xcuserdatad/UserInterfaceState.xcuserstate b/OSX/xscreensaver.xcodeproj/project.xcworkspace/xcuserdata/jwz.xcuserdatad/UserInterfaceState.xcuserstate
index 42d085cb..33fed937 100644
Binary files a/OSX/xscreensaver.xcodeproj/project.xcworkspace/xcuserdata/jwz.xcuserdatad/UserInterfaceState.xcuserstate and b/OSX/xscreensaver.xcodeproj/project.xcworkspace/xcuserdata/jwz.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/driver/dialog.c b/driver/dialog.c
index 984449d5..3f68548b 100644
--- a/driver/dialog.c
+++ b/driver/dialog.c
@@ -638,7 +638,7 @@ get_font (window_state *ws, const char *name)
resource_keys (ws, &name, &rclass);
s = get_string_resource (ws->dpy, (char *) name, (char *) rclass);
if (!s || !*s)
- s = "Helvetica Bold 14";
+ s = "sans-serif 14";
f = load_xft_font_retry (ws->dpy, DefaultScreen(ws->dpy), s);
if (!f) abort();
return f;
diff --git a/driver/windows.c b/driver/windows.c
index 0aaabb4e..c9cdf9d2 100644
--- a/driver/windows.c
+++ b/driver/windows.c
@@ -900,7 +900,7 @@ screenhack_obituary (saver_screen_info *ssi,
fn = get_string_resource (si->dpy, "errorFont", "Font");
cn = get_string_resource (si->dpy, "errorColor", "Color");
- if (!fn || !*fn) fn = strdup ("Courier Bold 16");
+ if (!fn || !*fn) fn = strdup ("monospace bold 16");
if (!cn || !*cn) cn = strdup ("#FF0000");
font = load_xft_font_retry (si->dpy, screen_number (ssi->screen), fn);
diff --git a/hacks/apollonian.c b/hacks/apollonian.c
index 7ce7c69a..782b41c3 100644
--- a/hacks/apollonian.c
+++ b/hacks/apollonian.c
@@ -67,7 +67,7 @@ static const char sccsid[] = "@(#)apollonian.c 5.02 2001/07/01 xlockmore";
"*count: 64 \n" \
"*cycles: 20 \n" \
"*ncolors: 64 \n" \
- "*font: Helvetica Bold 10\n" \
+ "*font: sans-serif bold 10\n" \
"*fpsTop: true \n" \
"*fpsSolid: true \n" \
"*ignoreRotation: True" \
diff --git a/hacks/fluidballs.c b/hacks/fluidballs.c
index 4b1faa16..c42632ad 100644
--- a/hacks/fluidballs.c
+++ b/hacks/fluidballs.c
@@ -350,7 +350,7 @@ fluidballs_init (Display *dpy, Window window)
{
char *fontname = get_string_resource (dpy, "fpsFont", "Font");
char *s;
- if (!fontname) fontname = "Courier bold 18";
+ if (!fontname) fontname = "monospace bold 18";
state->font =
load_xft_font_retry (dpy, screen_number (state->xgwa.screen),
fontname);
diff --git a/hacks/fps.c b/hacks/fps.c
index 8dca6dc2..c62b8675 100644
--- a/hacks/fps.c
+++ b/hacks/fps.c
@@ -45,7 +45,7 @@ fps_init (Display *dpy, Window window)
XGetWindowAttributes (dpy, window, &xgwa);
if (!font)
- font = "Courier Bold 18"; /* also texfont.c */
+ font = "monospace bold 18"; /* also texfont.c */
f = load_xft_font_retry (dpy, screen_number (xgwa.screen), font);
if (!f) abort();
diff --git a/hacks/glx/carousel.c b/hacks/glx/carousel.c
index 112d400e..ec207a4a 100644
--- a/hacks/glx/carousel.c
+++ b/hacks/glx/carousel.c
@@ -12,8 +12,9 @@
* Created: 21-Feb-2005
*/
-#define DEF_FONT "OCR A Std 48, Lucida Console 48, Monaco 48, Courier 48"
-#define DEF_TITLE_FONT "Helvetica Bold 48"
+#define DEF_FONT \
+ "OCR A Std 48, Lucida Console 48, Monaco 48, Courier 48, monospace 48"
+#define DEF_TITLE_FONT "sans-serif bold 48"
#define DEFAULTS "*count: 7 \n" \
"*delay: 10000 \n" \
diff --git a/hacks/glx/circuit.c b/hacks/glx/circuit.c
index 4f837129..00e88c86 100644
--- a/hacks/glx/circuit.c
+++ b/hacks/glx/circuit.c
@@ -33,7 +33,7 @@
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*suppressRotationAnimation: True\n" \
- "*componentFont: Courier Bold 12" \
+ "*componentFont: monospace bold 12" \
# define release_circuit 0
# define circuit_handle_event xlockmore_no_events
diff --git a/hacks/glx/dymaxionmap.c b/hacks/glx/dymaxionmap.c
index 74ee91fb..1527daa6 100644
--- a/hacks/glx/dymaxionmap.c
+++ b/hacks/glx/dymaxionmap.c
@@ -14,7 +14,7 @@
* other special, indirect and consequential damages.
*/
-#define LABEL_FONT "Helvetica Bold 24"
+#define LABEL_FONT "sans-serif bold 24"
#ifdef STANDALONE
#define DEFAULTS "*delay: 20000 \n" \
diff --git a/hacks/glx/engine.c b/hacks/glx/engine.c
index 0048de3f..cdc68f93 100644
--- a/hacks/glx/engine.c
+++ b/hacks/glx/engine.c
@@ -25,7 +25,7 @@
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*suppressRotationAnimation: True\n" \
- "*titleFont: Helvetica 18\n" \
+ "*titleFont: sans-serif 18\n" \
# define release_engine 0
# include "xlockmore.h" /* from the xscreensaver distribution */
diff --git a/hacks/glx/esper.c b/hacks/glx/esper.c
index ebffd891..bbc0aa6c 100644
--- a/hacks/glx/esper.c
+++ b/hacks/glx/esper.c
@@ -126,7 +126,8 @@
/* Use a small point size to keep it nice and grainy. */
-#define TITLE_FONT "OCR A Std 10, Lucida Console 10, Monaco 10, Courier 10"
+#define TITLE_FONT \
+ "OCR A Std 10, Lucida Console 10, Monaco 10, Courier 10, monospace 10"
#define DEFAULTS "*delay: 20000 \n" \
"*wireframe: False \n" \
diff --git a/hacks/glx/fliptext.c b/hacks/glx/fliptext.c
index f370e566..84f43dae 100644
--- a/hacks/glx/fliptext.c
+++ b/hacks/glx/fliptext.c
@@ -10,7 +10,7 @@
* implied warranty.
*/
-#define DEF_FONT "Utopia Bold 72, Helvetica Bold 72"
+#define DEF_FONT "sans-serif bold 72"
#define DEF_COLOR "#00CCFF"
#define DEFAULTS "*delay: 10000 \n" \
diff --git a/hacks/glx/geodesicgears.c b/hacks/glx/geodesicgears.c
index 4b6dd5b2..146b835f 100644
--- a/hacks/glx/geodesicgears.c
+++ b/hacks/glx/geodesicgears.c
@@ -18,7 +18,7 @@
"*showFPS: False \n" \
"*texFontCacheSize: 100 \n" \
"*suppressRotationAnimation: True\n" \
- "*font: Helvetica 16\n" \
+ "*font: sans-serif 16\n" \
# define release_geodesic 0
diff --git a/hacks/glx/gibson.c b/hacks/glx/gibson.c
index fa2c7a6c..e90d8d25 100644
--- a/hacks/glx/gibson.c
+++ b/hacks/glx/gibson.c
@@ -14,7 +14,7 @@
* edge-lit etched perspex, each about four feet tall.
*/
-#define TOWER_FONT "Helvetica Bold 48"
+#define TOWER_FONT "sans-serif bold 48"
#define DEFAULTS "*delay: 20000 \n" \
"*groundColor: #8A2BE2" "\n" \
diff --git a/hacks/glx/glslideshow.c b/hacks/glx/glslideshow.c
index ea700a53..88055e34 100644
--- a/hacks/glx/glslideshow.c
+++ b/hacks/glx/glslideshow.c
@@ -53,7 +53,7 @@
"*showFPS: False \n" \
"*fpsSolid: True \n" \
"*useSHM: True \n" \
- "*titleFont: Helvetica 18\n" \
+ "*titleFont: sans-serif 18\n" \
"*desktopGrabber: xscreensaver-getimage -no-desktop %s\n" \
"*grabDesktopImages: False \n" \
"*chooseRandomImages: True \n"
diff --git a/hacks/glx/glsnake.c b/hacks/glx/glsnake.c
index 1b9eb3fe..d7e133e7 100644
--- a/hacks/glx/glsnake.c
+++ b/hacks/glx/glsnake.c
@@ -135,7 +135,7 @@ static GLfloat angvel;
"*count: 30 \n" \
"*showFPS: False \n" \
"*suppressRotationAnimation: True\n" \
- "*labelfont: Helvetica 18\n" \
+ "*labelfont: sans-serif 18\n" \
#include "xlockmore.h"
diff --git a/hacks/glx/jigsaw.c b/hacks/glx/jigsaw.c
index 1ba39a7d..206c3468 100644
--- a/hacks/glx/jigsaw.c
+++ b/hacks/glx/jigsaw.c
@@ -48,7 +48,7 @@
#define DEF_WOBBLE "True"
#define DEF_DEBUG "False"
-#define DEF_FONT "Helvetica Bold 24"
+#define DEF_FONT "sans-serif bold 24"
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*font: " DEF_FONT"\n" \
diff --git a/hacks/glx/juggler3d.c b/hacks/glx/juggler3d.c
index d7c74a96..31228be8 100644
--- a/hacks/glx/juggler3d.c
+++ b/hacks/glx/juggler3d.c
@@ -131,7 +131,7 @@
"*count: 200 \n" \
"*cycles: 1000 \n" \
"*ncolors: 32 \n" \
- "*titleFont: Helvetica Bold 18\n" \
+ "*titleFont: sans-serif bold 18\n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
diff --git a/hacks/glx/molecule.c b/hacks/glx/molecule.c
index 7006c7a6..c173c6b3 100644
--- a/hacks/glx/molecule.c
+++ b/hacks/glx/molecule.c
@@ -27,8 +27,8 @@
#define DEFAULTS "*delay: 10000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*atomFont: Helvetica 24\n" \
- "*titleFont: helvetica 18\n" \
+ "*atomFont: sans-serif 24\n" \
+ "*titleFont: sans-serif 18\n" \
"*noLabelThreshold: 150 \n" \
"*wireframeThreshold: 150 \n" \
"*suppressRotationAnimation: True\n" \
diff --git a/hacks/glx/photopile.c b/hacks/glx/photopile.c
index 4634aa2f..78e34b54 100644
--- a/hacks/glx/photopile.c
+++ b/hacks/glx/photopile.c
@@ -11,7 +11,8 @@
* implied warranty.
*/
-#define DEF_FONT "OCR A Std 18, Lucida Console 18, Monaco 18, Courier 18"
+#define DEF_FONT \
+ "OCR A Std 18, Lucida Console 18, Monaco 18, Courier 18, monospace 18"
#define DEFAULTS "*count: 7 \n" \
"*delay: 10000 \n" \
diff --git a/hacks/glx/pinion.c b/hacks/glx/pinion.c
index d1536e48..343600f1 100644
--- a/hacks/glx/pinion.c
+++ b/hacks/glx/pinion.c
@@ -12,9 +12,9 @@
#define DEFAULTS "*delay: 15000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*titleFont: Helvetica 18\n" \
- "*titleFont2: Helvetica 12\n" \
- "*titleFont3: Helvetica 8\n" \
+ "*titleFont: sans-serif 18\n" \
+ "*titleFont2: sans-serif 12\n" \
+ "*titleFont3: sans-serif 8\n" \
# define release_pinion 0
diff --git a/hacks/glx/polyhedra-gl.c b/hacks/glx/polyhedra-gl.c
index 107743a0..d433d7aa 100644
--- a/hacks/glx/polyhedra-gl.c
+++ b/hacks/glx/polyhedra-gl.c
@@ -18,9 +18,9 @@
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*titleFont: Helvetica 14\n" \
- "*titleFont2: Helvetica 10\n" \
- "*titleFont3: Helvetica 8\n" \
+ "*titleFont: sans-serif 14\n" \
+ "*titleFont2: sans-serif 10\n" \
+ "*titleFont3: sans-serif 8\n" \
"*suppressRotationAnimation: True\n" \
diff --git a/hacks/glx/sonar.c b/hacks/glx/sonar.c
index 029d0e87..5b1df315 100644
--- a/hacks/glx/sonar.c
+++ b/hacks/glx/sonar.c
@@ -51,7 +51,7 @@
* - plot IM contacts or Facebook friends and their last-activity times.
*/
-#define DEF_FONT "Courier Bold 48"
+#define DEF_FONT "monospace bold 48"
#define DEF_SPEED "1.0"
#define DEF_SWEEP_SIZE "0.3"
#define DEF_FONT_SIZE "12"
diff --git a/hacks/glx/spheremonics.c b/hacks/glx/spheremonics.c
index f342d880..13eed8ae 100644
--- a/hacks/glx/spheremonics.c
+++ b/hacks/glx/spheremonics.c
@@ -63,8 +63,8 @@
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*labelfont: sans-serif 18\n" \
"*suppressRotationAnimation: True\n" \
- "*labelfont: Helvetica Medium 18\n" \
# define release_spheremonics 0
diff --git a/hacks/glx/splitflap.c b/hacks/glx/splitflap.c
index 254bd45b..0706cc8b 100644
--- a/hacks/glx/splitflap.c
+++ b/hacks/glx/splitflap.c
@@ -11,7 +11,7 @@
* Draws a split-flap text display.
*/
-#define FLAP_FONT "Helvetica Bold 144"
+#define FLAP_FONT "sans-serif bold 144"
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
diff --git a/hacks/glx/starwars.c b/hacks/glx/starwars.c
index 39a1471b..fbdf39d4 100644
--- a/hacks/glx/starwars.c
+++ b/hacks/glx/starwars.c
@@ -73,7 +73,7 @@
#define DEF_FADE "True"
#define DEF_TEXTURES "True"
#define DEF_DEBUG "False"
-#define DEF_FONT "Utopia Bold 36, Helvetica 36"
+#define DEF_FONT "sans-serif 36"
#define TAB_WIDTH 8
diff --git a/hacks/glx/tangram.c b/hacks/glx/tangram.c
index 7a2f61d6..c7e36577 100644
--- a/hacks/glx/tangram.c
+++ b/hacks/glx/tangram.c
@@ -16,11 +16,11 @@
*/
-#define DEFAULTS "*delay: 10000 \n" \
- "*wireframe: False \n" \
- "*titleFont: Helvetica 18\n" \
- "*titleFont2: Helvetica 12\n" \
- "*titleFont3: Helvetica 8\n" \
+#define DEFAULTS "*delay: 10000 \n" \
+ "*wireframe: False \n" \
+ "*titleFont: sans-serif 18\n" \
+ "*titleFont2: sans-serif 12\n" \
+ "*titleFont3: sans-serif 8\n" \
# define release_tangram 0
diff --git a/hacks/glx/texfont.c b/hacks/glx/texfont.c
index ac9b4d85..d5951dcc 100644
--- a/hacks/glx/texfont.c
+++ b/hacks/glx/texfont.c
@@ -314,9 +314,9 @@ load_texture_font (Display *dpy, char *res)
{
int screen = DefaultScreen (dpy);
char *font = get_string_resource (dpy, res, "Font");
- const char *def1 = "Helvetica 18";
- const char *def2 = "Helvetica 14";
- const char *def3 = "fixed";
+ const char *def1 = "sans-serif 18";
+ const char *def2 = "sans-serif 14";
+ const char *def3 = "monospace";
XftFont *f = 0;
texture_font_data *data;
int cache_size = get_integer_resource (dpy, "texFontCacheSize", "Integer");
@@ -329,7 +329,7 @@ load_texture_font (Display *dpy, char *res)
if (!res || !*res) abort();
if (!strcmp (res, "fpsFont")) { /* Kludge. */
- def1 = "Courier Bold 18"; /* also fps.c */
+ def1 = "monospace bold 18"; /* also fps.c */
cache_size = 0; /* No need for a cache on FPS: already throttled. */
}
diff --git a/hacks/glx/unicrud.c b/hacks/glx/unicrud.c
index 50f0312d..9cd8d484 100644
--- a/hacks/glx/unicrud.c
+++ b/hacks/glx/unicrud.c
@@ -9,11 +9,11 @@
* implied warranty.
*/
-#define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
+#define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n" \
+ "*titleFont: sans-serif bold 18\n" \
+ "*font: sans-serif bold 300\n" \
"*suppressRotationAnimation: True\n" \
- "*titleFont: Helvetica Bold 18\n" \
- "*font: Helvetica Bold 300\n" \
# define release_unicrud 0
diff --git a/hacks/glx/winduprobot.c b/hacks/glx/winduprobot.c
index 97aa3692..237352d2 100644
--- a/hacks/glx/winduprobot.c
+++ b/hacks/glx/winduprobot.c
@@ -39,7 +39,7 @@
* https://www.youtube.com/watch?v=EZF4ZAAy49g
*/
-#define LABEL_FONT "Helvetica Bold 24"
+#define LABEL_FONT "sans-serif bold 24"
#define DEFAULTS "*delay: 20000 \n" \
"*count: 25 \n" \
diff --git a/hacks/noseguy.c b/hacks/noseguy.c
index 7c48574a..e5e2b0be 100644
--- a/hacks/noseguy.c
+++ b/hacks/noseguy.c
@@ -561,7 +561,7 @@ static const char *noseguy_defaults [] = {
"*fpsSolid: true",
"*program: xscreensaver-text",
"*usePty: False",
- ".font: Helvetica 14",
+ ".font: sans-serif 14",
0
};
diff --git a/hacks/penetrate.c b/hacks/penetrate.c
index d2b7bf92..85c1c08b 100644
--- a/hacks/penetrate.c
+++ b/hacks/penetrate.c
@@ -368,8 +368,8 @@ penetrate_init (Display *dpy, Window window)
{
struct state *st = (struct state *) calloc (1, sizeof(*st));
int i;
- const char *levelfont = "Courier 38";
- const char *scorefont = "Helvetica 18";
+ const char *levelfont = "monospace 38";
+ const char *scorefont = "sans-serif 18";
XGCValues gcv;
XWindowAttributes xgwa;
char *s;
diff --git a/jwxyz/jwxyz-cocoa.m b/jwxyz/jwxyz-cocoa.m
index ff3eeb42..f5bc551f 100644
--- a/jwxyz/jwxyz-cocoa.m
+++ b/jwxyz/jwxyz-cocoa.m
@@ -330,7 +330,7 @@
font_mask |= NSBoldFontMask;
if (MATCH(@"Italic") || MATCH(@"Oblique"))
font_mask |= NSItalicFontMask;
- if (MATCH(@"Courier"))
+ if (MATCH(@"Courier") || MATCH(@"monospace") || MATCH(@"fixed"))
font_mask |= NSFixedPitchFontMask;
}
diff --git a/jwxyz/jwxyz-common.c b/jwxyz/jwxyz-common.c
index d7fd17e3..0b170f67 100644
--- a/jwxyz/jwxyz-common.c
+++ b/jwxyz/jwxyz-common.c
@@ -1168,7 +1168,7 @@ try_xlfd_font (Display *dpy, const char *name, Font fid)
// This used to substitute Georgia for Times. Now it doesn't.
if (CMP ("random")) {
rand = True;
- } else if (CMP ("fixed")) {
+ } else if (CMP ("fixed") || CMP ("monospace")) {
require |= JWXYZ_STYLE_MONOSPACE;
family_name = "Courier";
family_name_size = strlen(family_name);
diff --git a/utils/font-retry.c b/utils/font-retry.c
index 4fcf69a0..31229691 100644
--- a/utils/font-retry.c
+++ b/utils/font-retry.c
@@ -95,10 +95,12 @@ font_name_to_xlfd (const char *font_name)
if (name[0] == '-' || name[0] == '*')
return name; /* Already an XLFD */
- /* Downcase ASCII */
+ /* Downcase ASCII; dash to space */
for (s = name; *s; s++)
if (*s >= 'A' && *s <= 'Z')
*s += 'a'-'A';
+ else if (*s == '-')
+ *s = ' ';
/* "Family NN" or "Family-NN" */
s = strrchr (name, ' ');
@@ -142,6 +144,13 @@ font_name_to_xlfd (const char *font_name)
Courier, since Xft special-cases that one, but it happens with any other
fixed width font that is not similarly privileged.
+ Even worse: when Xft substitutes fonts, it makes no attempt to return fonts
+ that are capable of displaying the language of the current locale. For
+ example: if your locale is set to Japanese and you request "Helvetica", Xft
+ silently substitutes "Nimbus Sans" -- a font which is not capable of
+ displaying Japanese characters. If instead you requested "asdfasdfghjkl",
+ you get "Noto Sans CJK JP", which does work. So that's just spectacular.
+
Since there does not appear to be a way to ask Xft whether a particular
font exists, we load the font and then check to see if the name we got
is the name we requested.
@@ -165,6 +174,23 @@ font_name_to_xlfd (const char *font_name)
Xft source is here:
https://opensource.apple.com/source/X11ForMacOSXSource/X11ForMacOSXSource-1.0/xc/lib/Xft1/
+
+ Courier, Helvetica and the other historical PostScript font names seem to
+ be special-cased in /etc/fonts/conf.d/ in the files 30-metric-aliases.conf,
+ 45-latin.conf and/or 60-latin.conf, which uses an idiosyncratic scripting
+ language implemented as XML! Some incomplete documentation on that baroque
+ mess is here:
+ https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
+
+ The Xft configuration files seem to special-case the names "monospace",
+ "serif" and "sans-serif" as generic fallback fonts.
+
+ However, "sans-serif" is problematic because it does not survive the trip
+ through XftXlfdParse and XftFontOpenPattern -- XLFD font families cannot
+ include hyphens. So we have no choice but to turn it into "sans serif",
+ which is *not* special-cased by the Xft config files.
+
+ In summary, everything is terrible, and it's a wonder anything works at all.
*/
static Bool
xlfd_substituted_p (XftFont *f, const char *xlfd)
@@ -391,6 +417,9 @@ xft_selftest (Display *dpy, int screen)
"Helvetica-48:style=Bold Italic",
"Liberation Mono-48:style=Bold Italic",
"Liberation Sans-48:style=Bold Italic",
+ "-*-sans serif-bold-o-*-*-*-480-*-*-m-*-*-*",
+ "-*-sans-serif-bold-o-*-*-*-480-*-*-m-*-*-*",
+ "-*-sans\\-serif-bold-o-*-*-*-480-*-*-m-*-*-*",
};
const char *tests2[] = { "Helvetica 10",
@@ -403,6 +432,9 @@ xft_selftest (Display *dpy, int screen)
"Times New Roman-Oblique Italic Bold 10",
"Times-20:style=Bold",
"Times-Oblique-20:style=Bold",
+ "sans serif-20:style=Bold",
+ "sans-serif-20:style=Bold",
+ "sans\\-serif-20:style=Bold",
};
fprintf (stderr, "\n");