dwm-pango-20201020-519f869.diff (22470B)
1 From 986b03fee484ecc98c0913ee3678318bc8c29d65 Mon Sep 17 00:00:00 2001 2 From: Marius Iacob <themariusus@gmail.com> 3 Date: Mon, 11 May 2020 12:17:20 +0300 4 Subject: [PATCH 1/4] pango support 5 6 --- 7 config.def.h | 2 +- 8 config.mk | 4 +- 9 drw.c | 303 +++++++++++++-------------------------------------- 10 drw.h | 17 ++- 11 dwm.c | 28 ++--- 12 util.h | 4 + 13 6 files changed, 106 insertions(+), 252 deletions(-) 14 15 diff --git a/config.def.h b/config.def.h 16 index 1c0b587..d201ae6 100644 17 --- a/config.def.h 18 +++ b/config.def.h 19 @@ -5,7 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ 20 static const unsigned int snap = 32; /* snap pixel */ 21 static const int showbar = 1; /* 0 means no bar */ 22 static const int topbar = 1; /* 0 means bottom bar */ 23 -static const char *fonts[] = { "monospace:size=10" }; 24 +static const char font[] = "monospace 10"; 25 static const char dmenufont[] = "monospace:size=10"; 26 static const char col_gray1[] = "#222222"; 27 static const char col_gray2[] = "#444444"; 28 diff --git a/config.mk b/config.mk 29 index 7084c33..b5c7e12 100644 30 --- a/config.mk 31 +++ b/config.mk 32 @@ -21,8 +21,8 @@ FREETYPEINC = /usr/include/freetype2 33 #FREETYPEINC = ${X11INC}/freetype2 34 35 # includes and libs 36 -INCS = -I${X11INC} -I${FREETYPEINC} 37 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} 38 +INCS = -I${X11INC} -I${FREETYPEINC} `pkg-config --cflags xft pango pangoxft` 39 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} `pkg-config --libs xft pango pangoxft` 40 41 # flags 42 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 43 diff --git a/drw.c b/drw.c 44 index 8fd1ca4..6d1b64e 100644 45 --- a/drw.c 46 +++ b/drw.c 47 @@ -4,62 +4,12 @@ 48 #include <string.h> 49 #include <X11/Xlib.h> 50 #include <X11/Xft/Xft.h> 51 +#include <pango/pango.h> 52 +#include <pango/pangoxft.h> 53 54 #include "drw.h" 55 #include "util.h" 56 57 -#define UTF_INVALID 0xFFFD 58 -#define UTF_SIZ 4 59 - 60 -static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; 61 -static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; 62 -static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; 63 -static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; 64 - 65 -static long 66 -utf8decodebyte(const char c, size_t *i) 67 -{ 68 - for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) 69 - if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) 70 - return (unsigned char)c & ~utfmask[*i]; 71 - return 0; 72 -} 73 - 74 -static size_t 75 -utf8validate(long *u, size_t i) 76 -{ 77 - if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) 78 - *u = UTF_INVALID; 79 - for (i = 1; *u > utfmax[i]; ++i) 80 - ; 81 - return i; 82 -} 83 - 84 -static size_t 85 -utf8decode(const char *c, long *u, size_t clen) 86 -{ 87 - size_t i, j, len, type; 88 - long udecoded; 89 - 90 - *u = UTF_INVALID; 91 - if (!clen) 92 - return 0; 93 - udecoded = utf8decodebyte(c[0], &len); 94 - if (!BETWEEN(len, 1, UTF_SIZ)) 95 - return 1; 96 - for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { 97 - udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); 98 - if (type) 99 - return j; 100 - } 101 - if (j < len) 102 - return 0; 103 - *u = udecoded; 104 - utf8validate(u, len); 105 - 106 - return len; 107 -} 108 - 109 Drw * 110 drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) 111 { 112 @@ -99,58 +49,37 @@ drw_free(Drw *drw) 113 } 114 115 /* This function is an implementation detail. Library users should use 116 - * drw_fontset_create instead. 117 + * drw_font_create instead. 118 */ 119 static Fnt * 120 -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) 121 +xfont_create(Drw *drw, const char *fontname) 122 { 123 Fnt *font; 124 - XftFont *xfont = NULL; 125 - FcPattern *pattern = NULL; 126 - 127 - if (fontname) { 128 - /* Using the pattern found at font->xfont->pattern does not yield the 129 - * same substitution results as using the pattern returned by 130 - * FcNameParse; using the latter results in the desired fallback 131 - * behaviour whereas the former just results in missing-character 132 - * rectangles being drawn, at least with some fonts. */ 133 - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { 134 - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); 135 - return NULL; 136 - } 137 - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { 138 - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); 139 - XftFontClose(drw->dpy, xfont); 140 - return NULL; 141 - } 142 - } else if (fontpattern) { 143 - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { 144 - fprintf(stderr, "error, cannot load font from pattern.\n"); 145 - return NULL; 146 - } 147 - } else { 148 - die("no font specified."); 149 - } 150 + PangoFontMap *fontmap; 151 + PangoContext *context; 152 + PangoFontDescription *desc; 153 + PangoFontMetrics *metrics; 154 155 - /* Do not allow using color fonts. This is a workaround for a BadLength 156 - * error from Xft with color glyphs. Modelled on the Xterm workaround. See 157 - * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 158 - * https://lists.suckless.org/dev/1701/30932.html 159 - * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 160 - * and lots more all over the internet. 161 - */ 162 - FcBool iscol; 163 - if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { 164 - XftFontClose(drw->dpy, xfont); 165 - return NULL; 166 + 167 + if (!fontname) { 168 + die("no font specified."); 169 } 170 171 font = ecalloc(1, sizeof(Fnt)); 172 - font->xfont = xfont; 173 - font->pattern = pattern; 174 - font->h = xfont->ascent + xfont->descent; 175 font->dpy = drw->dpy; 176 177 + fontmap = pango_xft_get_font_map(drw->dpy, drw->screen); 178 + context = pango_font_map_create_context(fontmap); 179 + desc = pango_font_description_from_string(fontname); 180 + font->layout = pango_layout_new(context); 181 + pango_layout_set_font_description(font->layout, desc); 182 + 183 + metrics = pango_context_get_metrics(context, desc, pango_language_from_string ("en-us")); 184 + font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE; 185 + 186 + pango_font_metrics_unref(metrics); 187 + g_object_unref(context); 188 + 189 return font; 190 } 191 192 @@ -159,35 +88,28 @@ xfont_free(Fnt *font) 193 { 194 if (!font) 195 return; 196 - if (font->pattern) 197 - FcPatternDestroy(font->pattern); 198 - XftFontClose(font->dpy, font->xfont); 199 + if (font->layout) 200 + g_object_unref(font->layout); 201 free(font); 202 } 203 204 Fnt* 205 -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) 206 +drw_font_create(Drw* drw, const char font[]) 207 { 208 - Fnt *cur, *ret = NULL; 209 - size_t i; 210 + Fnt *fnt = NULL; 211 212 - if (!drw || !fonts) 213 + if (!drw || !font) 214 return NULL; 215 216 - for (i = 1; i <= fontcount; i++) { 217 - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { 218 - cur->next = ret; 219 - ret = cur; 220 - } 221 - } 222 - return (drw->fonts = ret); 223 + fnt = xfont_create(drw, font); 224 + 225 + return (drw->font = fnt); 226 } 227 228 void 229 -drw_fontset_free(Fnt *font) 230 +drw_font_free(Fnt *font) 231 { 232 if (font) { 233 - drw_fontset_free(font->next); 234 xfont_free(font); 235 } 236 } 237 @@ -221,13 +143,6 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) 238 return ret; 239 } 240 241 -void 242 -drw_setfontset(Drw *drw, Fnt *set) 243 -{ 244 - if (drw) 245 - drw->fonts = set; 246 -} 247 - 248 void 249 drw_setscheme(Drw *drw, Clr *scm) 250 { 251 @@ -248,24 +163,16 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int 252 } 253 254 int 255 -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) 256 +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup) 257 { 258 char buf[1024]; 259 int ty; 260 unsigned int ew; 261 XftDraw *d = NULL; 262 - Fnt *usedfont, *curfont, *nextfont; 263 size_t i, len; 264 - int utf8strlen, utf8charlen, render = x || y || w || h; 265 - long utf8codepoint = 0; 266 - const char *utf8str; 267 - FcCharSet *fccharset; 268 - FcPattern *fcpattern; 269 - FcPattern *match; 270 - XftResult result; 271 - int charexists = 0; 272 - 273 - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) 274 + int render = x || y || w || h; 275 + 276 + if (!drw || (render && !drw->scheme) || !text || !drw->font) 277 return 0; 278 279 if (!render) { 280 @@ -280,98 +187,37 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp 281 w -= lpad; 282 } 283 284 - usedfont = drw->fonts; 285 - while (1) { 286 - utf8strlen = 0; 287 - utf8str = text; 288 - nextfont = NULL; 289 - while (*text) { 290 - utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); 291 - for (curfont = drw->fonts; curfont; curfont = curfont->next) { 292 - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); 293 - if (charexists) { 294 - if (curfont == usedfont) { 295 - utf8strlen += utf8charlen; 296 - text += utf8charlen; 297 - } else { 298 - nextfont = curfont; 299 - } 300 - break; 301 - } 302 - } 303 - 304 - if (!charexists || nextfont) 305 - break; 306 - else 307 - charexists = 0; 308 - } 309 - 310 - if (utf8strlen) { 311 - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); 312 - /* shorten text if necessary */ 313 - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) 314 - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); 315 - 316 - if (len) { 317 - memcpy(buf, utf8str, len); 318 - buf[len] = '\0'; 319 - if (len < utf8strlen) 320 - for (i = len; i && i > len - 3; buf[--i] = '.') 321 - ; /* NOP */ 322 - 323 - if (render) { 324 - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; 325 - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], 326 - usedfont->xfont, x, ty, (XftChar8 *)buf, len); 327 - } 328 - x += ew; 329 - w -= ew; 330 - } 331 - } 332 - 333 - if (!*text) { 334 - break; 335 - } else if (nextfont) { 336 - charexists = 0; 337 - usedfont = nextfont; 338 - } else { 339 - /* Regardless of whether or not a fallback font is found, the 340 - * character must be drawn. */ 341 - charexists = 1; 342 - 343 - fccharset = FcCharSetCreate(); 344 - FcCharSetAddChar(fccharset, utf8codepoint); 345 - 346 - if (!drw->fonts->pattern) { 347 - /* Refer to the comment in xfont_create for more information. */ 348 - die("the first font in the cache must be loaded from a font string."); 349 - } 350 - 351 - fcpattern = FcPatternDuplicate(drw->fonts->pattern); 352 - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); 353 - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); 354 - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); 355 - 356 - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); 357 - FcDefaultSubstitute(fcpattern); 358 - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); 359 - 360 - FcCharSetDestroy(fccharset); 361 - FcPatternDestroy(fcpattern); 362 - 363 - if (match) { 364 - usedfont = xfont_create(drw, NULL, match); 365 - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { 366 - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) 367 - ; /* NOP */ 368 - curfont->next = usedfont; 369 - } else { 370 - xfont_free(usedfont); 371 - usedfont = drw->fonts; 372 - } 373 + len = strlen(text); 374 + 375 + if (len) { 376 + drw_font_getexts(drw->font, text, len, &ew, NULL, markup); 377 + /* shorten text if necessary */ 378 + for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) 379 + drw_font_getexts(drw->font, text, len, &ew, NULL, markup); 380 + 381 + if (len) { 382 + memcpy(buf, text, len); 383 + buf[len] = '\0'; 384 + if (len < strlen(text)) 385 + for (i = len; i && i > len - 3; buf[--i] = '.') 386 + ; /* NOP */ 387 + 388 + if (render) { 389 + ty = y + (h - drw->font->h) / 2; 390 + if(markup) 391 + pango_layout_set_markup(drw->font->layout, buf, len); 392 + else 393 + pango_layout_set_text(drw->font->layout, buf, len); 394 + pango_xft_render_layout(d, &drw->scheme[invert ? ColBg : ColFg], 395 + drw->font->layout, x * PANGO_SCALE, ty * PANGO_SCALE); 396 + if(markup) /* clear markup attributes */ 397 + pango_layout_set_attributes(drw->font->layout, NULL); 398 } 399 + x += ew; 400 + w -= ew; 401 } 402 } 403 + 404 if (d) 405 XftDrawDestroy(d); 406 407 @@ -389,24 +235,29 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) 408 } 409 410 unsigned int 411 -drw_fontset_getwidth(Drw *drw, const char *text) 412 +drw_font_getwidth(Drw *drw, const char *text, Bool markup) 413 { 414 - if (!drw || !drw->fonts || !text) 415 + if (!drw || !drw->font || !text) 416 return 0; 417 - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); 418 + return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup); 419 } 420 421 void 422 -drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) 423 +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup) 424 { 425 - XGlyphInfo ext; 426 - 427 if (!font || !text) 428 return; 429 430 - XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); 431 + PangoRectangle r; 432 + if(markup) 433 + pango_layout_set_markup(font->layout, text, len); 434 + else 435 + pango_layout_set_text(font->layout, text, len); 436 + pango_layout_get_extents(font->layout, 0, &r); 437 + if(markup) /* clear markup attributes */ 438 + pango_layout_set_attributes(font->layout, NULL); 439 if (w) 440 - *w = ext.xOff; 441 + *w = r.width / PANGO_SCALE; 442 if (h) 443 *h = font->h; 444 } 445 diff --git a/drw.h b/drw.h 446 index 4bcd5ad..3d3a906 100644 447 --- a/drw.h 448 +++ b/drw.h 449 @@ -7,9 +7,7 @@ typedef struct { 450 typedef struct Fnt { 451 Display *dpy; 452 unsigned int h; 453 - XftFont *xfont; 454 - FcPattern *pattern; 455 - struct Fnt *next; 456 + PangoLayout *layout; 457 } Fnt; 458 459 enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ 460 @@ -23,7 +21,7 @@ typedef struct { 461 Drawable drawable; 462 GC gc; 463 Clr *scheme; 464 - Fnt *fonts; 465 + Fnt *font; 466 } Drw; 467 468 /* Drawable abstraction */ 469 @@ -32,10 +30,10 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h); 470 void drw_free(Drw *drw); 471 472 /* Fnt abstraction */ 473 -Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); 474 -void drw_fontset_free(Fnt* set); 475 -unsigned int drw_fontset_getwidth(Drw *drw, const char *text); 476 -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); 477 +Fnt *drw_font_create(Drw* drw, const char font[]); 478 +void drw_font_free(Fnt* set); 479 +unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup); 480 +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup); 481 482 /* Colorscheme abstraction */ 483 void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); 484 @@ -46,12 +44,11 @@ Cur *drw_cur_create(Drw *drw, int shape); 485 void drw_cur_free(Drw *drw, Cur *cursor); 486 487 /* Drawing context manipulation */ 488 -void drw_setfontset(Drw *drw, Fnt *set); 489 void drw_setscheme(Drw *drw, Clr *scm); 490 491 /* Drawing functions */ 492 void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); 493 -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); 494 +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup); 495 496 /* Map functions */ 497 void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); 498 diff --git a/dwm.c b/dwm.c 499 index 9fd0286..cc180c4 100644 500 --- a/dwm.c 501 +++ b/dwm.c 502 @@ -40,6 +40,7 @@ 503 #include <X11/extensions/Xinerama.h> 504 #endif /* XINERAMA */ 505 #include <X11/Xft/Xft.h> 506 +#include <pango/pango.h> 507 508 #include "drw.h" 509 #include "util.h" 510 @@ -55,7 +56,8 @@ 511 #define WIDTH(X) ((X)->w + 2 * (X)->bw) 512 #define HEIGHT(X) ((X)->h + 2 * (X)->bw) 513 #define TAGMASK ((1 << LENGTH(tags)) - 1) 514 -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) 515 +#define TEXTW(X) (drw_font_getwidth(drw, (X), False) + lrpad) 516 +#define TEXTWM(X) (drw_font_getwidth(drw, (X), True) + lrpad) 517 518 /* enums */ 519 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 520 @@ -237,7 +239,7 @@ static void zoom(const Arg *arg); 521 522 /* variables */ 523 static const char broken[] = "broken"; 524 -static char stext[256]; 525 +static char stext[512]; 526 static int screen; 527 static int sw, sh; /* X display screen geometry width, height */ 528 static int bh, blw = 0; /* bar geometry */ 529 @@ -440,7 +442,7 @@ buttonpress(XEvent *e) 530 arg.ui = 1 << i; 531 } else if (ev->x < x + blw) 532 click = ClkLtSymbol; 533 - else if (ev->x > selmon->ww - TEXTW(stext)) 534 + else if (ev->x > selmon->ww - TEXTWM(stext)) 535 click = ClkStatusText; 536 else 537 click = ClkWinTitle; 538 @@ -697,16 +699,16 @@ void 539 drawbar(Monitor *m) 540 { 541 int x, w, tw = 0; 542 - int boxs = drw->fonts->h / 9; 543 - int boxw = drw->fonts->h / 6 + 2; 544 + int boxs = drw->font->h / 9; 545 + int boxw = drw->font->h / 6 + 2; 546 unsigned int i, occ = 0, urg = 0; 547 Client *c; 548 549 /* draw status first so it can be overdrawn by tags later */ 550 if (m == selmon) { /* status is only drawn on selected monitor */ 551 drw_setscheme(drw, scheme[SchemeNorm]); 552 - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 553 - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); 554 + tw = TEXTWM(stext) - lrpad + 2; /* 2px right padding */ 555 + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0, True); 556 } 557 558 for (c = m->clients; c; c = c->next) { 559 @@ -718,7 +720,7 @@ drawbar(Monitor *m) 560 for (i = 0; i < LENGTH(tags); i++) { 561 w = TEXTW(tags[i]); 562 drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 563 - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); 564 + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i, False); 565 if (occ & 1 << i) 566 drw_rect(drw, x + boxs, boxs, boxw, boxw, 567 m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 568 @@ -727,12 +729,12 @@ drawbar(Monitor *m) 569 } 570 w = blw = TEXTW(m->ltsymbol); 571 drw_setscheme(drw, scheme[SchemeNorm]); 572 - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); 573 + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0, False); 574 575 if ((w = m->ww - tw - x) > bh) { 576 if (m->sel) { 577 drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 578 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); 579 + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0, False); 580 if (m->sel->isfloating) 581 drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); 582 } else { 583 @@ -1543,10 +1545,10 @@ setup(void) 584 sh = DisplayHeight(dpy, screen); 585 root = RootWindow(dpy, screen); 586 drw = drw_create(dpy, screen, root, sw, sh); 587 - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) 588 + if (!drw_font_create(drw, font)) 589 die("no fonts could be loaded."); 590 - lrpad = drw->fonts->h; 591 - bh = drw->fonts->h + 2; 592 + lrpad = drw->font->h; 593 + bh = drw->font->h + 2; 594 updategeom(); 595 /* init atoms */ 596 utf8string = XInternAtom(dpy, "UTF8_STRING", False); 597 diff --git a/util.h b/util.h 598 index f633b51..531ab25 100644 599 --- a/util.h 600 +++ b/util.h 601 @@ -1,7 +1,11 @@ 602 /* See LICENSE file for copyright and license details. */ 603 604 +#ifndef MAX 605 #define MAX(A, B) ((A) > (B) ? (A) : (B)) 606 +#endif 607 +#ifndef MIN 608 #define MIN(A, B) ((A) < (B) ? (A) : (B)) 609 +#endif 610 #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) 611 612 void die(const char *fmt, ...); 613 -- 614 2.28.0 615 616 617 From 62b46168970345a67cce6afb7bddb3c4eddbde8c Mon Sep 17 00:00:00 2001 618 From: Marius Iacob <themariusus@gmail.com> 619 Date: Wed, 20 May 2020 17:04:34 +0300 620 Subject: [PATCH 2/4] removed some blank lines 621 622 --- 623 drw.c | 1 - 624 dwm.c | 1 - 625 2 files changed, 2 deletions(-) 626 627 diff --git a/drw.c b/drw.c 628 index 6d1b64e..30543f2 100644 629 --- a/drw.c 630 +++ b/drw.c 631 @@ -60,7 +60,6 @@ xfont_create(Drw *drw, const char *fontname) 632 PangoFontDescription *desc; 633 PangoFontMetrics *metrics; 634 635 - 636 if (!fontname) { 637 die("no font specified."); 638 } 639 diff --git a/dwm.c b/dwm.c 640 index cc180c4..d63ebb4 100644 641 --- a/dwm.c 642 +++ b/dwm.c 643 @@ -1599,7 +1599,6 @@ setup(void) 644 focus(NULL); 645 } 646 647 - 648 void 649 seturgent(Client *c, int urg) 650 { 651 -- 652 2.28.0 653 654 655 From 1d3a8696e884317c7eab0cc47c2a2e4fca1d1685 Mon Sep 17 00:00:00 2001 656 From: Marius Iacob <themariusus@gmail.com> 657 Date: Wed, 22 Jul 2020 09:48:32 +0300 658 Subject: [PATCH 3/4] Fixed patch after update 659 660 --- 661 drw.c | 2 +- 662 1 file changed, 1 insertion(+), 1 deletion(-) 663 664 diff --git a/drw.c b/drw.c 665 index b834cef..34bda61 100644 666 --- a/drw.c 667 +++ b/drw.c 668 @@ -45,7 +45,7 @@ drw_free(Drw *drw) 669 { 670 XFreePixmap(drw->dpy, drw->drawable); 671 XFreeGC(drw->dpy, drw->gc); 672 - drw_fontset_free(drw->fonts); 673 + drw_font_free(drw->font); 674 free(drw); 675 } 676 677 -- 678 2.28.0 679 680 681 From 63d0a5e4a8fb109c5a032e76d5e2410fa792e45f Mon Sep 17 00:00:00 2001 682 From: Marius Iacob <themariusus@gmail.com> 683 Date: Tue, 20 Oct 2020 21:06:48 +0300 684 Subject: [PATCH 4/4] font rendering fixes 685 686 removed hardcoded locale, should use system defined in env vars 687 688 get height of text on a case by case basis, helps with CJK fonts 689 --- 690 drw.c | 20 ++++++++++++-------- 691 1 file changed, 12 insertions(+), 8 deletions(-) 692 693 diff --git a/drw.c b/drw.c 694 index 34bda61..1795a13 100644 695 --- a/drw.c 696 +++ b/drw.c 697 @@ -74,7 +74,7 @@ xfont_create(Drw *drw, const char *fontname) 698 font->layout = pango_layout_new(context); 699 pango_layout_set_font_description(font->layout, desc); 700 701 - metrics = pango_context_get_metrics(context, desc, pango_language_from_string ("en-us")); 702 + metrics = pango_context_get_metrics(context, desc, NULL); 703 font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE; 704 705 pango_font_metrics_unref(metrics); 706 @@ -166,8 +166,8 @@ int 707 drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup) 708 { 709 char buf[1024]; 710 - int ty; 711 - unsigned int ew; 712 + int ty, th; 713 + unsigned int ew, eh; 714 XftDraw *d = NULL; 715 size_t i, len; 716 int render = x || y || w || h; 717 @@ -190,10 +190,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp 718 len = strlen(text); 719 720 if (len) { 721 - drw_font_getexts(drw->font, text, len, &ew, NULL, markup); 722 + drw_font_getexts(drw->font, text, len, &ew, &eh, markup); 723 + th = eh; 724 /* shorten text if necessary */ 725 - for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) 726 - drw_font_getexts(drw->font, text, len, &ew, NULL, markup); 727 + for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) { 728 + drw_font_getexts(drw->font, text, len, &ew, &eh, markup); 729 + if (eh > th) 730 + th = eh; 731 + } 732 733 if (len) { 734 memcpy(buf, text, len); 735 @@ -203,7 +207,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp 736 ; /* NOP */ 737 738 if (render) { 739 - ty = y + (h - drw->font->h) / 2; 740 + ty = y + (h - th) / 2; 741 if(markup) 742 pango_layout_set_markup(drw->font->layout, buf, len); 743 else 744 @@ -259,7 +263,7 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, 745 if (w) 746 *w = r.width / PANGO_SCALE; 747 if (h) 748 - *h = font->h; 749 + *h = r.height / PANGO_SCALE; 750 } 751 752 Cur * 753 -- 754 2.28.0 755