dwm-6.1-xft-with-fallback-font.diff - sites - public wiki contents of suckless.… | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dwm-6.1-xft-with-fallback-font.diff (19598B) | |
--- | |
1 Author: Eric Pruitt, https://github.com/ericpruitt/ | |
2 Description: Xft with fallback font support built on top of the Xft patch | |
3 written by Quentin (http://lists.suckless.org/dev/1311/18279.html). The … | |
4 functions were written by Damian Okrasa for the MIT/X licensed | |
5 (http://opensource.org/licenses/MIT) terminal emulator st | |
6 (http://st.suckless.org/). | |
7 | |
8 With this patch, the "font" variable in config.h is superseded by the "f… | |
9 variable which is a priority-ordered list of fonts that should be used to | |
10 render text. Here's an example "fonts" definition: | |
11 | |
12 static const char *fonts[] = { | |
13 "Sans:size=10.5", | |
14 "VL Gothic:size=10.5", | |
15 "WenQuanYi Micro Hei:size=10.5", | |
16 }; | |
17 | |
18 At least one font must be specified, and a maximum of DRW_FONT_CACHE_SIZ… | |
19 can be used. | |
20 | |
21 diff --git a/config.def.h b/config.def.h | |
22 index 875885b..eaae8f3 100644 | |
23 --- a/config.def.h | |
24 +++ b/config.def.h | |
25 @@ -1,7 +1,12 @@ | |
26 /* See LICENSE file for copyright and license details. */ | |
27 | |
28 /* appearance */ | |
29 -static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-… | |
30 +static const char *fonts[] = { | |
31 + "Sans:size=10.5", | |
32 + "VL Gothic:size=10.5", | |
33 + "WenQuanYi Micro Hei:size=10.5", | |
34 +}; | |
35 +static const char dmenufont[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-… | |
36 static const char normbordercolor[] = "#444444"; | |
37 static const char normbgcolor[] = "#222222"; | |
38 static const char normfgcolor[] = "#bbbbbb"; | |
39 @@ -51,7 +56,7 @@ static const Layout layouts[] = { | |
40 | |
41 /* commands */ | |
42 static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in… | |
43 -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", f… | |
44 +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", d… | |
45 static const char *termcmd[] = { "st", NULL }; | |
46 | |
47 static Key keys[] = { | |
48 diff --git a/config.mk b/config.mk | |
49 index bc3d80e..50b2175 100644 | |
50 --- a/config.mk | |
51 +++ b/config.mk | |
52 @@ -11,12 +11,12 @@ X11INC = /usr/X11R6/include | |
53 X11LIB = /usr/X11R6/lib | |
54 | |
55 # Xinerama, comment if you don't want it | |
56 -XINERAMALIBS = -lXinerama | |
57 -XINERAMAFLAGS = -DXINERAMA | |
58 +#XINERAMALIBS = -lXinerama | |
59 +#XINERAMAFLAGS = -DXINERAMA | |
60 | |
61 # includes and libs | |
62 -INCS = -I${X11INC} | |
63 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} | |
64 +INCS = -I${X11INC} -I/usr/include/freetype2 | |
65 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lfontconfig -lXft | |
66 | |
67 # flags | |
68 CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" $… | |
69 diff --git a/drw.c b/drw.c | |
70 index b130405..36cf992 100644 | |
71 --- a/drw.c | |
72 +++ b/drw.c | |
73 @@ -3,10 +3,59 @@ | |
74 #include <stdlib.h> | |
75 #include <string.h> | |
76 #include <X11/Xlib.h> | |
77 +#include <X11/Xft/Xft.h> | |
78 | |
79 #include "drw.h" | |
80 #include "util.h" | |
81 | |
82 +#define UTF_INVALID 0xFFFD | |
83 +#define UTF_SIZ 4 | |
84 + | |
85 +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0x… | |
86 +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0x… | |
87 +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800,… | |
88 +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF,… | |
89 + | |
90 +static long | |
91 +utf8decodebyte(const char c, size_t *i) { | |
92 + for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | |
93 + if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | |
94 + return (unsigned char)c & ~utfmask[*i]; | |
95 + return 0; | |
96 +} | |
97 + | |
98 +static size_t | |
99 +utf8validate(long *u, size_t i) { | |
100 + if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0x… | |
101 + *u = UTF_INVALID; | |
102 + for(i = 1; *u > utfmax[i]; ++i) | |
103 + ; | |
104 + return i; | |
105 +} | |
106 + | |
107 +static size_t | |
108 +utf8decode(const char *c, long *u, size_t clen) { | |
109 + size_t i, j, len, type; | |
110 + long udecoded; | |
111 + | |
112 + *u = UTF_INVALID; | |
113 + if(!clen) | |
114 + return 0; | |
115 + udecoded = utf8decodebyte(c[0], &len); | |
116 + if(!BETWEEN(len, 1, UTF_SIZ)) | |
117 + return 1; | |
118 + for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { | |
119 + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type… | |
120 + if(type != 0) | |
121 + return j; | |
122 + } | |
123 + if(j < len) | |
124 + return 0; | |
125 + *u = udecoded; | |
126 + utf8validate(u, len); | |
127 + return len; | |
128 +} | |
129 + | |
130 Drw * | |
131 drw_create(Display *dpy, int screen, Window root, unsigned int w, unsig… | |
132 Drw *drw = (Drw *)calloc(1, sizeof(Drw)); | |
133 @@ -19,6 +68,7 @@ drw_create(Display *dpy, int screen, Window root, unsi… | |
134 drw->h = h; | |
135 drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy… | |
136 drw->gc = XCreateGC(dpy, root, 0, NULL); | |
137 + drw->fontcount = 0; | |
138 XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMit… | |
139 return drw; | |
140 } | |
141 @@ -36,56 +86,79 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)… | |
142 | |
143 void | |
144 drw_free(Drw *drw) { | |
145 + size_t i; | |
146 + for (i = 0; i < drw->fontcount; i++) { | |
147 + drw_font_free(drw->fonts[i]); | |
148 + } | |
149 XFreePixmap(drw->dpy, drw->drawable); | |
150 XFreeGC(drw->dpy, drw->gc); | |
151 free(drw); | |
152 } | |
153 | |
154 Fnt * | |
155 -drw_font_create(Display *dpy, const char *fontname) { | |
156 +drw_font_create(Drw *drw, const char *fontname, FcPattern *fontpattern)… | |
157 Fnt *font; | |
158 - char *def, **missing; | |
159 - int n; | |
160 | |
161 - font = (Fnt *)calloc(1, sizeof(Fnt)); | |
162 - if(!font) | |
163 + if (!(fontname || fontpattern)) | |
164 + die("No font specified.\n"); | |
165 + | |
166 + if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) | |
167 return NULL; | |
168 - font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def); | |
169 - if(missing) { | |
170 - while(n--) | |
171 - fprintf(stderr, "drw: missing fontset: %s\n", m… | |
172 - XFreeStringList(missing); | |
173 - } | |
174 - if(font->set) { | |
175 - XFontStruct **xfonts; | |
176 - char **font_names; | |
177 - XExtentsOfFontSet(font->set); | |
178 - n = XFontsOfFontSet(font->set, &xfonts, &font_names); | |
179 - while(n--) { | |
180 - font->ascent = MAX(font->ascent, (*xfonts)->asc… | |
181 - font->descent = MAX(font->descent,(*xfonts)->de… | |
182 - xfonts++; | |
183 + | |
184 + if (fontname) { | |
185 + // Using the pattern found at font->xfont->pattern does… | |
186 + // the same substitution results as using the pattern r… | |
187 + // FcNameParse; using the latter results in the desired… | |
188 + // behaviour whereas the former just results in | |
189 + // missing-character-rectangles being drawn, at least w… | |
190 + if (!(font->xfont = XftFontOpenName(drw->dpy, drw->scre… | |
191 + !(font->pattern = FcNameParse((FcChar8 *) fontname)… | |
192 + if (font->xfont) | |
193 + XftFontClose(font->dpy, font->xfont); | |
194 + fprintf(stderr, "error, cannot load font: '%s'\… | |
195 + } | |
196 + } else if (fontpattern) { | |
197 + if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpa… | |
198 + fprintf(stderr, "error, cannot load font patter… | |
199 + } else { | |
200 + font->pattern = NULL; | |
201 } | |
202 } | |
203 - else { | |
204 - if(!(font->xfont = XLoadQueryFont(dpy, fontname)) | |
205 - && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) | |
206 - die("error, cannot load font: '%s'\n", fontname… | |
207 - font->ascent = font->xfont->ascent; | |
208 - font->descent = font->xfont->descent; | |
209 + | |
210 + if (!font->xfont) { | |
211 + free(font); | |
212 + return NULL; | |
213 } | |
214 + | |
215 + font->ascent = font->xfont->ascent; | |
216 + font->descent = font->xfont->descent; | |
217 font->h = font->ascent + font->descent; | |
218 + font->dpy = drw->dpy; | |
219 return font; | |
220 } | |
221 | |
222 void | |
223 -drw_font_free(Display *dpy, Fnt *font) { | |
224 +drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { | |
225 + size_t i; | |
226 + Fnt *font; | |
227 + for (i = 0; i < fontcount && drw->fontcount < DRW_FONT_CACHE_SI… | |
228 + if ((font = drw_font_create(drw, fonts[i], NULL))) { | |
229 + drw->fonts[drw->fontcount++] = font; | |
230 + } | |
231 + } | |
232 + | |
233 + if (i != fontcount) { | |
234 + die("Font cache exhausted.\n"); | |
235 + } | |
236 +} | |
237 + | |
238 +void | |
239 +drw_font_free(Fnt *font) { | |
240 if(!font) | |
241 return; | |
242 - if(font->set) | |
243 - XFreeFontSet(dpy, font->set); | |
244 - else | |
245 - XFreeFont(dpy, font->xfont); | |
246 + if(font->pattern) | |
247 + FcPatternDestroy(font->pattern); | |
248 + XftFontClose(font->dpy, font->xfont); | |
249 free(font); | |
250 } | |
251 | |
252 @@ -93,7 +166,7 @@ Clr * | |
253 drw_clr_create(Drw *drw, const char *clrname) { | |
254 Clr *clr; | |
255 Colormap cmap; | |
256 - XColor color; | |
257 + Visual *vis; | |
258 | |
259 if(!drw) | |
260 return NULL; | |
261 @@ -101,9 +174,10 @@ drw_clr_create(Drw *drw, const char *clrname) { | |
262 if(!clr) | |
263 return NULL; | |
264 cmap = DefaultColormap(drw->dpy, drw->screen); | |
265 - if(!XAllocNamedColor(drw->dpy, cmap, clrname, &color, &color)) | |
266 + vis = DefaultVisual(drw->dpy, drw->screen); | |
267 + if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) | |
268 die("error, cannot allocate color '%s'\n", clrname); | |
269 - clr->rgb = color.pixel; | |
270 + clr->pix = clr->rgb.pixel; | |
271 return clr; | |
272 } | |
273 | |
274 @@ -114,14 +188,8 @@ drw_clr_free(Clr *clr) { | |
275 } | |
276 | |
277 void | |
278 -drw_setfont(Drw *drw, Fnt *font) { | |
279 - if(drw) | |
280 - drw->font = font; | |
281 -} | |
282 - | |
283 -void | |
284 drw_setscheme(Drw *drw, ClrScheme *scheme) { | |
285 - if(drw && scheme) | |
286 + if(drw && scheme) | |
287 drw->scheme = scheme; | |
288 } | |
289 | |
290 @@ -129,46 +197,158 @@ void | |
291 drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int fi… | |
292 int dx; | |
293 | |
294 - if(!drw || !drw->font || !drw->scheme) | |
295 + if(!drw || !drw->fontcount || !drw->scheme) | |
296 return; | |
297 - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb… | |
298 - dx = (drw->font->ascent + drw->font->descent + 2) / 4; | |
299 + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix… | |
300 + dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; | |
301 if(filled) | |
302 XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y… | |
303 else if(empty) | |
304 XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y… | |
305 } | |
306 | |
307 -void | |
308 +int | |
309 drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const … | |
310 - char buf[256]; | |
311 - int i, tx, ty, th, len, olen; | |
312 + char buf[1024]; | |
313 + int tx, ty, th; | |
314 Extnts tex; | |
315 + Colormap cmap; | |
316 + Visual *vis; | |
317 + XftDraw *d; | |
318 + Fnt *curfont, *nextfont; | |
319 + size_t i, len; | |
320 + int utf8strlen, utf8charlen, render; | |
321 + long utf8codepoint = 0; | |
322 + const char *utf8str; | |
323 + FcCharSet *fccharset; | |
324 + FcPattern *fcpattern; | |
325 + FcPattern *match; | |
326 + XftResult result; | |
327 + int charexists = 0; | |
328 | |
329 - if(!drw || !drw->scheme) | |
330 - return; | |
331 - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->rgb… | |
332 - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
333 - if(!text || !drw->font) | |
334 - return; | |
335 - olen = strlen(text); | |
336 - drw_font_getexts(drw->font, text, olen, &tex); | |
337 - th = drw->font->ascent + drw->font->descent; | |
338 - ty = y + (h / 2) - (th / 2) + drw->font->ascent; | |
339 - tx = x + (h / 2); | |
340 - /* shorten text if necessary */ | |
341 - for(len = MIN(olen, sizeof buf); len && (tex.w > w - tex.h || w… | |
342 - drw_font_getexts(drw->font, text, len, &tex); | |
343 - if(!len) | |
344 - return; | |
345 - memcpy(buf, text, len); | |
346 - if(len < olen) | |
347 - for(i = len; i && i > len - 3; buf[--i] = '.'); | |
348 - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb… | |
349 - if(drw->font->set) | |
350 - XmbDrawString(drw->dpy, drw->drawable, drw->font->set, … | |
351 - else | |
352 - XDrawString(drw->dpy, drw->drawable, drw->gc, tx, ty, b… | |
353 + if (!(render = x || y || w || h)) { | |
354 + w = ~w; | |
355 + } | |
356 + | |
357 + if (!drw || !drw->scheme) { | |
358 + return 0; | |
359 + } else if (render) { | |
360 + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme-… | |
361 + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, … | |
362 + } | |
363 + | |
364 + if (!text || !drw->fontcount) { | |
365 + return 0; | |
366 + } else if (render) { | |
367 + cmap = DefaultColormap(drw->dpy, drw->screen); | |
368 + vis = DefaultVisual(drw->dpy, drw->screen); | |
369 + d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); | |
370 + } | |
371 + | |
372 + curfont = drw->fonts[0]; | |
373 + while (1) { | |
374 + utf8strlen = 0; | |
375 + utf8str = text; | |
376 + nextfont = NULL; | |
377 + while (*text) { | |
378 + utf8charlen = utf8decode(text, &utf8codepoint, … | |
379 + for (i = 0; i < drw->fontcount; i++) { | |
380 + charexists = charexists || XftCharExist… | |
381 + if (charexists) { | |
382 + if (drw->fonts[i] == curfont) { | |
383 + utf8strlen += utf8charl… | |
384 + text += utf8charlen; | |
385 + } else { | |
386 + nextfont = drw->fonts[i… | |
387 + } | |
388 + break; | |
389 + } | |
390 + } | |
391 + | |
392 + if (!charexists || (nextfont && nextfont != cur… | |
393 + break; | |
394 + } else { | |
395 + charexists = 0; | |
396 + } | |
397 + } | |
398 + | |
399 + if (utf8strlen) { | |
400 + drw_font_getexts(curfont, utf8str, utf8strlen, … | |
401 + /* shorten text if necessary */ | |
402 + for(len = MIN(utf8strlen, (sizeof buf) - 1); le… | |
403 + drw_font_getexts(curfont, utf8str, len,… | |
404 + | |
405 + if (len) { | |
406 + memcpy(buf, utf8str, len); | |
407 + buf[len] = '\0'; | |
408 + if(len < utf8strlen) | |
409 + for(i = len; i && i > len - 3; … | |
410 + | |
411 + if (render) { | |
412 + th = curfont->ascent + curfont-… | |
413 + ty = y + (h / 2) - (th / 2) + c… | |
414 + tx = x + (h / 2); | |
415 + XftDrawStringUtf8(d, invert ? &… | |
416 + } | |
417 + | |
418 + x += tex.w; | |
419 + w -= tex.w; | |
420 + } | |
421 + } | |
422 + | |
423 + if (!*text) { | |
424 + break; | |
425 + } else if (nextfont) { | |
426 + charexists = 0; | |
427 + curfont = nextfont; | |
428 + } else { | |
429 + // Regardless of whether or not a fallback font… | |
430 + // character must be drawn. | |
431 + charexists = 1; | |
432 + | |
433 + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { | |
434 + continue; | |
435 + } | |
436 + | |
437 + fccharset = FcCharSetCreate(); | |
438 + FcCharSetAddChar(fccharset, utf8codepoint); | |
439 + | |
440 + if (!drw->fonts[0]->pattern) { | |
441 + // Refer to the comment in drw_font_cre… | |
442 + // information. | |
443 + die("The first font in the cache must b… | |
444 + } | |
445 + | |
446 + fcpattern = FcPatternDuplicate(drw->fonts[0]->p… | |
447 + FcPatternAddCharSet(fcpattern, FC_CHARSET, fcch… | |
448 + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue… | |
449 + | |
450 + FcConfigSubstitute(NULL, fcpattern, FcMatchPatt… | |
451 + FcDefaultSubstitute(fcpattern); | |
452 + match = XftFontMatch(drw->dpy, drw->screen, fcp… | |
453 + | |
454 + FcCharSetDestroy(fccharset); | |
455 + FcPatternDestroy(fcpattern); | |
456 + | |
457 + if (match) { | |
458 + curfont = drw_font_create(drw, NULL, ma… | |
459 + if (curfont && XftCharExists(drw->dpy, … | |
460 + drw->fonts[drw->fontcount++] = … | |
461 + } else { | |
462 + if (curfont) { | |
463 + drw_font_free(curfont); | |
464 + } | |
465 + curfont = drw->fonts[0]; | |
466 + } | |
467 + } | |
468 + } | |
469 + } | |
470 + | |
471 + if (render) { | |
472 + XftDrawDestroy(d); | |
473 + } | |
474 + | |
475 + return x; | |
476 } | |
477 | |
478 void | |
479 @@ -182,19 +362,13 @@ drw_map(Drw *drw, Window win, int x, int y, unsign… | |
480 | |
481 void | |
482 drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts … | |
483 - XRectangle r; | |
484 + XGlyphInfo ext; | |
485 | |
486 if(!font || !text) | |
487 return; | |
488 - if(font->set) { | |
489 - XmbTextExtents(font->set, text, len, NULL, &r); | |
490 - tex->w = r.width; | |
491 - tex->h = r.height; | |
492 - } | |
493 - else { | |
494 - tex->h = font->ascent + font->descent; | |
495 - tex->w = XTextWidth(font->xfont, text, len); | |
496 - } | |
497 + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, le… | |
498 + tex->h = font->h; | |
499 + tex->w = ext.xOff; | |
500 } | |
501 | |
502 unsigned int | |
503 diff --git a/drw.h b/drw.h | |
504 index a5f34e0..02bfefc 100644 | |
505 --- a/drw.h | |
506 +++ b/drw.h | |
507 @@ -1,7 +1,9 @@ | |
508 /* See LICENSE file for copyright and license details. */ | |
509 +#define DRW_FONT_CACHE_SIZE 32 | |
510 | |
511 typedef struct { | |
512 - unsigned long rgb; | |
513 + unsigned long pix; | |
514 + XftColor rgb; | |
515 } Clr; | |
516 | |
517 typedef struct { | |
518 @@ -9,11 +11,12 @@ typedef struct { | |
519 } Cur; | |
520 | |
521 typedef struct { | |
522 + Display *dpy; | |
523 int ascent; | |
524 int descent; | |
525 unsigned int h; | |
526 - XFontSet set; | |
527 - XFontStruct *xfont; | |
528 + XftFont *xfont; | |
529 + FcPattern *pattern; | |
530 } Fnt; | |
531 | |
532 typedef struct { | |
533 @@ -30,7 +33,8 @@ typedef struct { | |
534 Drawable drawable; | |
535 GC gc; | |
536 ClrScheme *scheme; | |
537 - Fnt *font; | |
538 + size_t fontcount; | |
539 + Fnt *fonts[DRW_FONT_CACHE_SIZE]; | |
540 } Drw; | |
541 | |
542 typedef struct { | |
543 @@ -44,8 +48,9 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int… | |
544 void drw_free(Drw *drw); | |
545 | |
546 /* Fnt abstraction */ | |
547 -Fnt *drw_font_create(Display *dpy, const char *fontname); | |
548 -void drw_font_free(Display *dpy, Fnt *font); | |
549 +Fnt *drw_font_create(Drw *drw, const char *fontname, FcPattern *fontpat… | |
550 +void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); | |
551 +void drw_font_free(Fnt *font); | |
552 void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Ex… | |
553 unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsign… | |
554 | |
555 @@ -63,7 +68,7 @@ void drw_setscheme(Drw *drw, ClrScheme *scheme); | |
556 | |
557 /* Drawing functions */ | |
558 void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, i… | |
559 -void drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, c… | |
560 +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, co… | |
561 | |
562 /* Map functions */ | |
563 void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsign… | |
564 diff --git a/dwm.c b/dwm.c | |
565 index f896170..169adcb 100644 | |
566 --- a/dwm.c | |
567 +++ b/dwm.c | |
568 @@ -39,6 +39,7 @@ | |
569 #ifdef XINERAMA | |
570 #include <X11/extensions/Xinerama.h> | |
571 #endif /* XINERAMA */ | |
572 +#include <X11/Xft/Xft.h> | |
573 | |
574 #include "drw.h" | |
575 #include "util.h" | |
576 @@ -54,7 +55,7 @@ | |
577 #define WIDTH(X) ((X)->w + 2 * (X)->bw) | |
578 #define HEIGHT(X) ((X)->h + 2 * (X)->bw) | |
579 #define TAGMASK ((1 << LENGTH(tags)) - 1) | |
580 -#define TEXTW(X) (drw_font_getexts_width(drw->font, X, s… | |
581 +#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + dr… | |
582 | |
583 /* enums */ | |
584 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | |
585 @@ -263,7 +264,6 @@ static Cur *cursor[CurLast]; | |
586 static ClrScheme scheme[SchemeLast]; | |
587 static Display *dpy; | |
588 static Drw *drw; | |
589 -static Fnt *fnt; | |
590 static Monitor *mons, *selmon; | |
591 static Window root; | |
592 | |
593 @@ -474,7 +474,6 @@ cleanup(void) { | |
594 drw_cur_free(drw, cursor[CurNormal]); | |
595 drw_cur_free(drw, cursor[CurResize]); | |
596 drw_cur_free(drw, cursor[CurMove]); | |
597 - drw_font_free(dpy, fnt); | |
598 drw_clr_free(scheme[SchemeNorm].border); | |
599 drw_clr_free(scheme[SchemeNorm].bg); | |
600 drw_clr_free(scheme[SchemeNorm].fg); | |
601 @@ -792,7 +791,7 @@ focus(Client *c) { | |
602 detachstack(c); | |
603 attachstack(c); | |
604 grabbuttons(c, True); | |
605 - XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border-… | |
606 + XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border-… | |
607 setfocus(c); | |
608 } | |
609 else { | |
610 @@ -1040,7 +1039,7 @@ manage(Window w, XWindowAttributes *wa) { | |
611 | |
612 wc.border_width = c->bw; | |
613 XConfigureWindow(dpy, w, CWBorderWidth, &wc); | |
614 - XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->rgb); | |
615 + XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->pix); | |
616 configure(c); /* propagates border_width, if size doesn't chang… | |
617 updatewindowtype(c); | |
618 updatesizehints(c); | |
619 @@ -1505,13 +1504,14 @@ setup(void) { | |
620 | |
621 /* init screen */ | |
622 screen = DefaultScreen(dpy); | |
623 - root = RootWindow(dpy, screen); | |
624 - fnt = drw_font_create(dpy, font); | |
625 sw = DisplayWidth(dpy, screen); | |
626 sh = DisplayHeight(dpy, screen); | |
627 - bh = fnt->h + 2; | |
628 + root = RootWindow(dpy, screen); | |
629 drw = drw_create(dpy, screen, root, sw, sh); | |
630 - drw_setfont(drw, fnt); | |
631 + drw_load_fonts(drw, fonts, LENGTH(fonts)); | |
632 + if (!drw->fontcount) | |
633 + die("No fonts could be loaded.\n"); | |
634 + bh = drw->fonts[0]->h + 2; | |
635 updategeom(); | |
636 /* init atoms */ | |
637 wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | |
638 @@ -1685,7 +1685,7 @@ unfocus(Client *c, Bool setfocus) { | |
639 if(!c) | |
640 return; | |
641 grabbuttons(c, False); | |
642 - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->rgb); | |
643 + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->pix); | |
644 if(setfocus) { | |
645 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentT… | |
646 XDeleteProperty(dpy, root, netatom[NetActiveWindow]); | |
647 diff --git a/util.h b/util.h | |
648 index 033700c..f7ce721 100644 | |
649 --- a/util.h | |
650 +++ b/util.h | |
651 @@ -2,5 +2,6 @@ | |
652 | |
653 #define MAX(A, B) ((A) > (B) ? (A) : (B)) | |
654 #define MIN(A, B) ((A) < (B) ? (A) : (B)) | |
655 +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) | |
656 | |
657 void die(const char *errstr, ...); |