diff options
author | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
commit | d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 (patch) | |
tree | cbddf8e50f35a9c6e878a5bfe3c6d625d99e12ba /utils/font-retry.c | |
download | xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.gz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.xz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.zip |
Original 5.40
Diffstat (limited to 'utils/font-retry.c')
-rw-r--r-- | utils/font-retry.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/utils/font-retry.c b/utils/font-retry.c new file mode 100644 index 0000000..c3e91a0 --- /dev/null +++ b/utils/font-retry.c @@ -0,0 +1,189 @@ +/* xscreensaver, Copyright (c) 2018 by Jamie Zawinski <jwz@jwz.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +/* Like XLoadQueryFont, but if it fails, it tries some heuristics to + load something close. + */ + +#define _GNU_SOURCE + +#include "utils.h" +#include "visual.h" +#include "xft.h" +#include "font-retry.h" + +extern const char *progname; + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + +static void * +load_font_retry_1 (Display *dpy, int screen, const char *xlfd, Bool xft_p) +{ + +# ifdef USE_XFT +# define LOADFONT() (xft_p \ + ? (void *) XftFontOpenXlfd (dpy, screen, xlfd) \ + : (void *) XLoadQueryFont (dpy, xlfd)) +# else +# define LOADFONT() ((void *) XLoadQueryFont (dpy, xlfd)) +# endif + + void *f = LOADFONT(); + +# ifndef USE_XFT + if (xft_p) abort(); +# endif + +# ifdef HAVE_JWXYZ + return f; +# else /* !HAVE_JWXYZ */ + if (f) + return f; + else + { + Bool bold_p = (!!strcasestr (xlfd, "-bold-")); + Bool italic_p = (!!strcasestr (xlfd, "-i-") || + !!strcasestr (xlfd, "-o-")); + Bool fixed_p = (!!strcasestr (xlfd, "courier") || + !!strcasestr (xlfd, "-ocr") || + !!strcasestr (xlfd, "-m-") || + !!strcasestr (xlfd, "-c-")); + int size = 0; + + if (!strcmp (xlfd, "vga")) /* BSOD uses this: it has no XLFD name. */ + fixed_p = True, size = 120; + + /* Look for the first number in the string like "-180-" */ + if (! size) + { + const char *s; + for (s = xlfd; *s; s++) + if (s[0] == '-' && s[1] >= '0' && s[1] <= '9') + { + int i = s[1] - '0'; + const char *s2 = s+2; + while (*s2 >= '0' && *s2 <= '9') + { + i = i * 10 + *s2 - '0'; + s2++; + } + if (*s2 != '-') continue; /* Number ends with dash */ + if (i < 60 || i >= 2000) continue; /* In range 6pt - 200pt */ + if (i % 10) continue; /* Multiple of 10 */ + + size = i; + break; + } + } + + if (! size) + { + fprintf (stderr, "%s: unloadable, unparsable font: \"%s\"\n", + progname, xlfd); + xlfd = "fixed"; + return LOADFONT(); + } + else + { + const char *fixed[] = { "courier", + "courier new", + "courier 10 pitch", + "lucidatypewriter", + "american typewriter", + "fixed", + "ocr a std", + "*" }; + const char *variable[] = { "helvetica", + "arial", + "bitstream vera sans", + "gill sans", + "times", + "times new roman", + "new century schoolbook", + "utopia", + "palatino", + "lucida", + "bitstream charter", + "*" }; + const char *charsets[] = { "iso10646-1", "iso8859-1", "*-*" }; + const char *weights[] = { "bold", "medium" }; + const char *slants[] = { "o", "i", "r" }; + const char *spacings[] = { "m", "c", "p" }; + int a, b, c, d, e, g; + char buf[1024]; + + for (a = 0; a < countof(charsets); a++) + for (b = (bold_p ? 0 : 1); b < countof(weights); b++) + for (c = (italic_p ? 0 : 2); c < countof(slants); c++) + for (d = 0; + d < (fixed_p ? countof(fixed) : countof(variable)); + d++) + for (g = size; g >= 60; g -= 10) + for (e = (fixed_p ? 0 : 2); e < countof(spacings); e++) + { + sprintf (buf, + "-%s-%s-%s-%s-%s-%s-%s-%d-%s-%s-%s-%s-%s", + "*", /* foundry */ + (fixed_p ? fixed[d] : variable[d]), + weights[b], + slants[c], + "*", /* set width */ + "*", /* add style */ + "*", /* pixel size */ + g, /* point size */ + "*", /* x resolution */ + "*", /* y resolution */ + spacings[e], + "*", /* average width */ + charsets[a]); + /* fprintf(stderr, "%s: trying %s\n", progname, buf);*/ + f = LOADFONT(); + if (f) + { + /* fprintf (stderr, + "%s: substituted \"%s\" for \"%s\"\n", + progname, buf, xlfd); */ + return f; + } + } + + fprintf (stderr, "%s: unable to find any alternatives to \"%s\"\n", + progname, xlfd); + xlfd = "fixed"; + return LOADFONT(); + } + } +# endif /* !HAVE_JWXYZ */ +} + +XFontStruct * +load_font_retry (Display *dpy, const char *xlfd) +{ + return (XFontStruct *) load_font_retry_1 (dpy, 0, xlfd, 0); +} + +#ifdef USE_XFT +XftFont * +load_xft_font_retry (Display *dpy, int screen, const char *xlfd) +{ + return (XftFont *) load_font_retry_1 (dpy, screen, xlfd, 1); +} + +#elif defined(HAVE_JWXYZ) + +XftFont * +load_xft_font_retry (Display *dpy, int screen, const char *xlfd) +{ + return XftFontOpenXlfd (dpy, screen, xlfd); +} + +#endif /* !HAVE_JWXYZ */ |