dwm-pango-20201020-519f869.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       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