X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=utils%2Fxft.c;fp=utils%2Fxft.c;h=0b9b7ae5b6a2c52ada2c92094553db09255e4903;hp=690586d4cc9754d9147cbbe197ca1e15fbcf004f;hb=d1ae2829ff0fd2a96c16a0c8c5420efaa47d7b30;hpb=7edd66e6bd3209013ee059819747b10b5835635b diff --git a/utils/xft.c b/utils/xft.c index 690586d4..0b9b7ae5 100644 --- a/utils/xft.c +++ b/utils/xft.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 2014 Jamie Zawinski +/* xscreensaver, Copyright (c) 2014-2015 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -58,11 +58,28 @@ XftFontOpenXlfd (Display *dpy, int screen, _Xconst char *xlfd) # ifdef HAVE_XUTF8DRAWSTRING { + unsigned i; + + // In the event of -*-random-* (under JWXYZ), get the actual XLFD, + // otherwise we'll get another random font that doesn't match ff->xfont. + char *xlfd_resolved = NULL; + char **missing_charset_list_return; int missing_charset_count_return; char *def_string_return; - char *ss = (char *) malloc (strlen(xlfd) + 10); + char *ss; + + for (i = 0; i != ff->xfont->n_properties; ++i) { + if (ff->xfont->properties[i].name == XA_FONT) { + xlfd_resolved = XGetAtomName (dpy, ff->xfont->properties[i].card32); + if (xlfd_resolved) + xlfd = xlfd_resolved; + break; + } + } + + ss = (char *) malloc (strlen(xlfd) + 10); strcpy (ss, xlfd); strcat (ss, ",*"); ff->fontset = XCreateFontSet (dpy, ss, @@ -86,6 +103,7 @@ XftFontOpenXlfd (Display *dpy, int screen, _Xconst char *xlfd) XFreeStringList (missing_charset_list_return); free (ss); + free (xlfd_resolved); } # endif @@ -258,28 +276,34 @@ XftTextExtentsUtf8 (Display *dpy, int len, XGlyphInfo *extents) { - int direction, ascent, descent; XCharStruct overall; - XChar2b *s16; - int s16_len = 0; - char *s2 = (char *) malloc (len + 1); - - if (!dpy || !font || !string || !extents || !s2) abort(); - - strncpy (s2, (char *) string, len); - s2[len] = 0; - s16 = utf8_to_XChar2b (s2, &s16_len); - free (s2); - XTextExtents16 (font->xfont, s16, s16_len, - &direction, &ascent, &descent, &overall); - free (s16); - - extents->x = -overall.lbearing; - extents->y = overall.ascent; - extents->xOff = overall.width; - extents->yOff = 0; - extents->width = overall.rbearing - overall.lbearing; - extents->height = overall.ascent + overall.descent; + + if (!dpy || !font || !string || !extents) abort(); + +# ifdef HAVE_XUTF8DRAWSTRING + { + XRectangle ink; + int advancement = + Xutf8TextExtents (font->fontset, (const char *) string, len, &ink, 0); + XmbRectangle_to_XCharStruct (ink, overall, advancement); + } +# else /* !HAVE_XUTF8DRAWSTRING */ + { + char *s2 = (char *) malloc (len + 1); + int direction, ascent, descent; + XChar2b *s16; + int s16_len = 0; + strncpy (s2, (char *) string, len); + s2[len] = 0; + s16 = utf8_to_XChar2b (s2, &s16_len); + XTextExtents16 (font->xfont, s16, s16_len, + &direction, &ascent, &descent, &overall); + free (s2); + free (s16); + } +# endif /* !HAVE_XUTF8DRAWSTRING */ + + XCharStruct_to_XGlyphInfo (overall, *extents); } @@ -311,9 +335,14 @@ XftDrawStringUtf8 (XftDraw *draw, (beyond the Basic Multilingual Plane). */ - /* #### I guess I don't really understand how FontSet works, because this - seems to just truncate the text at the first non-ASCII character. - The XDrawString16() path works, however. + /* #### I guess I don't really understand how FontSet works, because when + using the real X11 implementation of Xutf8DrawString, this seems + to just truncate the text at the first non-ASCII character. + + The XDrawString16() path works, however, at the expense of losing + everything above Basic Multilingual. However, that path is only + taken on X11 systems that are old enough to not have libXft, + which means that the chance of Unicode working was already slim. */ Xutf8DrawString (draw->dpy, draw->drawable, font->fontset, draw->gc, x, y, (const char *) string, len);