1 /* xscreensaver, Copyright (c) 2014 Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* Compatibility layer using XDrawString, XDrawString16() or Xutf8DrawString().
13 This layer is used by X11 systems without Xft, and by MacOS / iOS.
23 # include "resources.h"
27 extern const char *progname;
41 XftFontOpenXlfd (Display *dpy, int screen, _Xconst char *xlfd)
43 XftFont *ff = (XftFont *) calloc (1, sizeof(*ff));
45 if (!dpy || !xlfd) abort();
47 ff->xfont = XLoadQueryFont (dpy, xlfd);
54 ff->name = strdup (xlfd);
55 ff->ascent = ff->xfont->ascent;
56 ff->descent = ff->xfont->descent;
57 ff->height = ff->ascent + ff->descent;
59 # ifdef HAVE_XUTF8DRAWSTRING
61 char **missing_charset_list_return;
62 int missing_charset_count_return;
63 char *def_string_return;
65 char *ss = (char *) malloc (strlen(xlfd) + 10);
68 ff->fontset = XCreateFontSet (dpy, ss,
69 &missing_charset_list_return,
70 &missing_charset_count_return,
76 for (i = 0; i < missing_charset_count_return; i++)
77 fprintf (stderr, "%s: missing charset: %s\n",
78 ss, missing_charset_list_return[i]);
82 /* Apparently this is not to be freed. */
83 /* if (def_string_return) XFree (def_string_return); */
85 if (missing_charset_list_return)
86 XFreeStringList (missing_charset_list_return);
97 XftFontClose (Display *dpy, XftFont *font)
99 if (!dpy || !font) abort();
101 XFreeFont (dpy, font->xfont);
102 # ifdef HAVE_XUTF8DRAWSTRING
103 XFreeFontSet (dpy, font->fontset);
110 XftColorAllocName (Display *dpy,
111 _Xconst Visual *visual,
117 if (!dpy || !visual || !name || !result) abort();
119 if (! XParseColor (dpy, cmap, name, &color))
121 fprintf (stderr, "%s: can't parse color %s", progname, name);
124 else if (! XAllocColor (dpy, cmap, &color))
126 fprintf (stderr, "%s: couldn't allocate color %s", progname, name);
132 color2.red = color.red;
133 color2.green = color.green;
134 color2.blue = color.blue;
135 color2.alpha = 0xFFFF;
136 XftColorAllocValue (dpy, visual, cmap, &color2, result);
137 result->pixel = color.pixel;
144 maskbase (unsigned long m)
160 masklen (unsigned long m)
163 y = (m >> 1) & 033333333333;
164 y = m - y - ((y >>1) & 033333333333);
165 return (short) (((y + (y >> 3)) & 030707070707) % 077);
170 XftColorAllocValue (Display *dpy,
171 _Xconst Visual *visual,
173 _Xconst XRenderColor *color,
176 if (!dpy || !visual || !color || !result) abort();
177 if (visual->class == TrueColor)
179 int red_shift, red_len;
180 int green_shift, green_len;
181 int blue_shift, blue_len;
183 red_shift = maskbase (visual->red_mask);
184 red_len = masklen (visual->red_mask);
185 green_shift = maskbase (visual->green_mask);
186 green_len = masklen (visual->green_mask);
187 blue_shift = maskbase (visual->blue_mask);
188 blue_len = masklen (visual->blue_mask);
189 result->pixel = (((color->red >> (16 - red_len)) << red_shift) |
190 ((color->green >> (16 - green_len)) << green_shift) |
191 ((color->blue >> (16 - blue_len)) << blue_shift));
193 result->pixel |= BlackPixel(dpy, 0); /* alpha */
199 xcolor.red = color->red;
200 xcolor.green = color->green;
201 xcolor.blue = color->blue;
202 if (!XAllocColor (dpy, cmap, &xcolor))
204 result->pixel = xcolor.pixel;
206 result->color.red = color->red;
207 result->color.green = color->green;
208 result->color.blue = color->blue;
209 result->color.alpha = color->alpha;
215 XftColorFree (Display *dpy,
220 if (!dpy || !visual || !color) abort();
221 if (visual->class != TrueColor)
222 XFreeColors (dpy, cmap, &color->pixel, 1, 0);
227 XftDrawCreate (Display *dpy,
232 XftDraw *dd = (XftDraw *) calloc (1, sizeof(*dd));
233 if (!dpy || !drawable || !visual) abort();
237 dd->drawable = drawable;
239 dd->colormap = colormap;
240 dd->gc = XCreateGC (dpy, drawable, 0, 0);
246 XftDrawDestroy (XftDraw *draw)
249 XFreeGC (draw->dpy, draw->gc);
255 XftTextExtentsUtf8 (Display *dpy,
257 _Xconst FcChar8 *string,
261 int direction, ascent, descent;
265 char *s2 = (char *) malloc (len + 1);
267 if (!dpy || !font || !string || !extents || !s2) abort();
269 strncpy (s2, (char *) string, len);
271 s16 = utf8_to_XChar2b (s2, &s16_len);
273 XTextExtents16 (font->xfont, s16, s16_len,
274 &direction, &ascent, &descent, &overall);
277 extents->x = -overall.lbearing;
278 extents->y = overall.ascent;
279 extents->xOff = overall.width;
281 extents->width = overall.rbearing - overall.lbearing;
282 extents->height = overall.ascent + overall.descent;
287 XftDrawStringUtf8 (XftDraw *draw,
288 _Xconst XftColor *color,
292 _Xconst FcChar8 *string,
295 if (!draw || !color || !font || !string) abort();
297 if (color->pixel != draw->pixel)
299 XSetForeground (draw->dpy, draw->gc, color->pixel);
300 draw->pixel = color->pixel;
302 if (font->xfont->fid != draw->fid)
304 XSetFont (draw->dpy, draw->gc, font->xfont->fid);
305 draw->fid = font->xfont->fid;
308 # ifdef HAVE_XUTF8DRAWSTRING
309 /* If we have Xutf8DrawString, use it instead of XDrawString16 because
310 there is some chance it will handle characters of more than 16 bits
311 (beyond the Basic Multilingual Plane).
314 /* #### I guess I don't really understand how FontSet works, because this
315 seems to just truncate the text at the first non-ASCII character.
316 The XDrawString16() path works, however.
318 Xutf8DrawString (draw->dpy, draw->drawable, font->fontset, draw->gc, x, y,
319 (const char *) string, len);
323 char *s2 = (char *) malloc (len + 1);
325 strncpy (s2, (char *) string, len);
327 s16 = utf8_to_XChar2b (s2, &s16_len);
329 XDrawString16 (draw->dpy, draw->drawable, draw->gc, x, y, s16, s16_len);
337 const int Wempty_translation_unit_is_a_dumb_warning = 0;
339 #endif /* HAVE_XFT */