dwm-pango-20230520-e81f17d.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-pango-20230520-e81f17d.diff (22140B)
       ---
            1 From 47099f4e65801269e7ec69bfd1f3c209b63da882 Mon Sep 17 00:00:00 2001
            2 From: Khalid Bin Walid <kbwalid26@gmail.com>
            3 Date: Sat, 20 May 2023 20:38:49 +0900
            4 Subject: [PATCH 1/2] apply dwm-pango patch
            5 
            6 ---
            7  config.def.h |   2 +-
            8  config.mk    |   4 +-
            9  drw.c        | 325 ++++++++++++++-------------------------------------
           10  drw.h        |  19 ++-
           11  dwm.c        |  28 ++---
           12  util.h       |   4 +
           13  6 files changed, 117 insertions(+), 265 deletions(-)
           14 
           15 diff --git a/config.def.h b/config.def.h
           16 index 9efa774..ef0e1b8 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 ba64d3d..96c25af 100644
           30 --- a/config.mk
           31 +++ b/config.mk
           32 @@ -22,8 +22,8 @@ FREETYPEINC = /usr/include/freetype2
           33  #MANPREFIX = ${PREFIX}/man
           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_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           43 diff --git a/drw.c b/drw.c
           44 index a58a2b4..d7ebfd8 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 @@ -95,50 +45,41 @@ drw_free(Drw *drw)
          113  {
          114          XFreePixmap(drw->dpy, drw->drawable);
          115          XFreeGC(drw->dpy, drw->gc);
          116 -        drw_fontset_free(drw->fonts);
          117 +        drw_font_free(drw->font);
          118          free(drw);
          119  }
          120  
          121  /* This function is an implementation detail. Library users should use
          122 - * drw_fontset_create instead.
          123 + * drw_font_create instead.
          124   */
          125  static Fnt *
          126 -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
          127 +xfont_create(Drw *drw, const char *fontname)
          128  {
          129          Fnt *font;
          130 -        XftFont *xfont = NULL;
          131 -        FcPattern *pattern = NULL;
          132 -
          133 -        if (fontname) {
          134 -                /* Using the pattern found at font->xfont->pattern does not yield the
          135 -                 * same substitution results as using the pattern returned by
          136 -                 * FcNameParse; using the latter results in the desired fallback
          137 -                 * behaviour whereas the former just results in missing-character
          138 -                 * rectangles being drawn, at least with some fonts. */
          139 -                if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
          140 -                        fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
          141 -                        return NULL;
          142 -                }
          143 -                if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
          144 -                        fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
          145 -                        XftFontClose(drw->dpy, xfont);
          146 -                        return NULL;
          147 -                }
          148 -        } else if (fontpattern) {
          149 -                if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
          150 -                        fprintf(stderr, "error, cannot load font from pattern.\n");
          151 -                        return NULL;
          152 -                }
          153 -        } else {
          154 +        PangoFontMap *fontmap;
          155 +        PangoContext *context;
          156 +        PangoFontDescription *desc;
          157 +        PangoFontMetrics *metrics;
          158 +
          159 +        if (!fontname) {
          160                  die("no font specified.");
          161          }
          162  
          163          font = ecalloc(1, sizeof(Fnt));
          164 -        font->xfont = xfont;
          165 -        font->pattern = pattern;
          166 -        font->h = xfont->ascent + xfont->descent;
          167          font->dpy = drw->dpy;
          168  
          169 +        fontmap = pango_xft_get_font_map(drw->dpy, drw->screen);
          170 +        context = pango_font_map_create_context(fontmap);
          171 +        desc = pango_font_description_from_string(fontname);
          172 +        font->layout = pango_layout_new(context);
          173 +        pango_layout_set_font_description(font->layout, desc);
          174 +
          175 +        metrics = pango_context_get_metrics(context, desc, NULL);
          176 +        font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE;
          177 +
          178 +        pango_font_metrics_unref(metrics);
          179 +        g_object_unref(context);
          180 +
          181          return font;
          182  }
          183  
          184 @@ -147,35 +88,28 @@ xfont_free(Fnt *font)
          185  {
          186          if (!font)
          187                  return;
          188 -        if (font->pattern)
          189 -                FcPatternDestroy(font->pattern);
          190 -        XftFontClose(font->dpy, font->xfont);
          191 +        if (font->layout)
          192 +                g_object_unref(font->layout);
          193          free(font);
          194  }
          195  
          196  Fnt*
          197 -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
          198 +drw_font_create(Drw* drw, const char font[])
          199  {
          200 -        Fnt *cur, *ret = NULL;
          201 -        size_t i;
          202 +        Fnt *fnt = NULL;
          203  
          204 -        if (!drw || !fonts)
          205 +        if (!drw || !font)
          206                  return NULL;
          207  
          208 -        for (i = 1; i <= fontcount; i++) {
          209 -                if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
          210 -                        cur->next = ret;
          211 -                        ret = cur;
          212 -                }
          213 -        }
          214 -        return (drw->fonts = ret);
          215 +        fnt = xfont_create(drw, font);
          216 +
          217 +        return (drw->font = fnt);
          218  }
          219  
          220  void
          221 -drw_fontset_free(Fnt *font)
          222 +drw_font_free(Fnt *font)
          223  {
          224          if (font) {
          225 -                drw_fontset_free(font->next);
          226                  xfont_free(font);
          227          }
          228  }
          229 @@ -187,8 +121,8 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
          230                  return;
          231  
          232          if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
          233 -                               DefaultColormap(drw->dpy, drw->screen),
          234 -                               clrname, dest))
          235 +                                                   DefaultColormap(drw->dpy, drw->screen),
          236 +                                                   clrname, dest))
          237                  die("error, cannot allocate color '%s'", clrname);
          238  }
          239  
          240 @@ -209,13 +143,6 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
          241          return ret;
          242  }
          243  
          244 -void
          245 -drw_setfontset(Drw *drw, Fnt *set)
          246 -{
          247 -        if (drw)
          248 -                drw->fonts = set;
          249 -}
          250 -
          251  void
          252  drw_setscheme(Drw *drw, Clr *scm)
          253  {
          254 @@ -236,26 +163,16 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
          255  }
          256  
          257  int
          258 -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
          259 +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup)
          260  {
          261 -        int i, ty, ellipsis_x = 0;
          262 -        unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
          263 +        char buf[1024];
          264 +        int i, ty, th;
          265 +        unsigned int ew, eh;
          266          XftDraw *d = NULL;
          267 -        Fnt *usedfont, *curfont, *nextfont;
          268 -        int utf8strlen, utf8charlen, render = x || y || w || h;
          269 -        long utf8codepoint = 0;
          270 -        const char *utf8str;
          271 -        FcCharSet *fccharset;
          272 -        FcPattern *fcpattern;
          273 -        FcPattern *match;
          274 -        XftResult result;
          275 -        int charexists = 0, overflow = 0;
          276 -        /* keep track of a couple codepoints for which we have no match. */
          277 -        enum { nomatches_len = 64 };
          278 -        static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
          279 -        static unsigned int ellipsis_width = 0;
          280 -
          281 -        if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
          282 +        size_t len;
          283 +        int render = x || y || w || h;
          284 +
          285 +        if (!drw || (render && !drw->scheme) || !text || !drw->font)
          286                  return 0;
          287  
          288          if (!render) {
          289 @@ -264,120 +181,47 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
          290                  XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
          291                  XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
          292                  d = XftDrawCreate(drw->dpy, drw->drawable,
          293 -                                  DefaultVisual(drw->dpy, drw->screen),
          294 -                                  DefaultColormap(drw->dpy, drw->screen));
          295 +                                                  DefaultVisual(drw->dpy, drw->screen),
          296 +                                                  DefaultColormap(drw->dpy, drw->screen));
          297                  x += lpad;
          298                  w -= lpad;
          299          }
          300  
          301 -        usedfont = drw->fonts;
          302 -        if (!ellipsis_width && render)
          303 -                ellipsis_width = drw_fontset_getwidth(drw, "...");
          304 -        while (1) {
          305 -                ew = ellipsis_len = utf8strlen = 0;
          306 -                utf8str = text;
          307 -                nextfont = NULL;
          308 -                while (*text) {
          309 -                        utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
          310 -                        for (curfont = drw->fonts; curfont; curfont = curfont->next) {
          311 -                                charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
          312 -                                if (charexists) {
          313 -                                        drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
          314 -                                        if (ew + ellipsis_width <= w) {
          315 -                                                /* keep track where the ellipsis still fits */
          316 -                                                ellipsis_x = x + ew;
          317 -                                                ellipsis_w = w - ew;
          318 -                                                ellipsis_len = utf8strlen;
          319 -                                        }
          320 -
          321 -                                        if (ew + tmpw > w) {
          322 -                                                overflow = 1;
          323 -                                                /* called from drw_fontset_getwidth_clamp():
          324 -                                                 * it wants the width AFTER the overflow
          325 -                                                 */
          326 -                                                if (!render)
          327 -                                                        x += tmpw;
          328 -                                                else
          329 -                                                        utf8strlen = ellipsis_len;
          330 -                                        } else if (curfont == usedfont) {
          331 -                                                utf8strlen += utf8charlen;
          332 -                                                text += utf8charlen;
          333 -                                                ew += tmpw;
          334 -                                        } else {
          335 -                                                nextfont = curfont;
          336 -                                        }
          337 -                                        break;
          338 -                                }
          339 -                        }
          340 +        len = strlen(text);
          341  
          342 -                        if (overflow || !charexists || nextfont)
          343 -                                break;
          344 -                        else
          345 -                                charexists = 0;
          346 +        if (len) {
          347 +                drw_font_getexts(drw->font, text, len, &ew, &eh, markup);
          348 +                th = eh;
          349 +                /* shorten text if necessary */
          350 +                for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) {
          351 +                        drw_font_getexts(drw->font, text, len, &ew, &eh, markup);
          352 +                        if (eh > th)
          353 +                                th = eh;
          354                  }
          355  
          356 -                if (utf8strlen) {
          357 +                if (len) {
          358 +                        memcpy(buf, text, len);
          359 +                        buf[len] = '\0';
          360 +                        if (len < strlen(text))
          361 +                                for (i = len; i && i > len - 3; buf[--i] = '.')
          362 +                                        ; /* NOP */
          363 +
          364                          if (render) {
          365 -                                ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
          366 -                                XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
          367 -                                                  usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
          368 +                                ty = y + (h - th) / 2;
          369 +                                if(markup)
          370 +                                        pango_layout_set_markup(drw->font->layout, buf, len);
          371 +                                else
          372 +                                        pango_layout_set_text(drw->font->layout, buf, len);
          373 +                                pango_xft_render_layout(d, &drw->scheme[invert ? ColBg : ColFg],
          374 +                                        drw->font->layout, x * PANGO_SCALE, ty * PANGO_SCALE);
          375 +                                if(markup) /* clear markup attributes */
          376 +                                        pango_layout_set_attributes(drw->font->layout, NULL);
          377                          }
          378                          x += ew;
          379                          w -= ew;
          380                  }
          381 -                if (render && overflow)
          382 -                        drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
          383 -
          384 -                if (!*text || overflow) {
          385 -                        break;
          386 -                } else if (nextfont) {
          387 -                        charexists = 0;
          388 -                        usedfont = nextfont;
          389 -                } else {
          390 -                        /* Regardless of whether or not a fallback font is found, the
          391 -                         * character must be drawn. */
          392 -                        charexists = 1;
          393 -
          394 -                        for (i = 0; i < nomatches_len; ++i) {
          395 -                                /* avoid calling XftFontMatch if we know we won't find a match */
          396 -                                if (utf8codepoint == nomatches.codepoint[i])
          397 -                                        goto no_match;
          398 -                        }
          399 -
          400 -                        fccharset = FcCharSetCreate();
          401 -                        FcCharSetAddChar(fccharset, utf8codepoint);
          402 -
          403 -                        if (!drw->fonts->pattern) {
          404 -                                /* Refer to the comment in xfont_create for more information. */
          405 -                                die("the first font in the cache must be loaded from a font string.");
          406 -                        }
          407 -
          408 -                        fcpattern = FcPatternDuplicate(drw->fonts->pattern);
          409 -                        FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
          410 -                        FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
          411 -
          412 -                        FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
          413 -                        FcDefaultSubstitute(fcpattern);
          414 -                        match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
          415 -
          416 -                        FcCharSetDestroy(fccharset);
          417 -                        FcPatternDestroy(fcpattern);
          418 -
          419 -                        if (match) {
          420 -                                usedfont = xfont_create(drw, NULL, match);
          421 -                                if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
          422 -                                        for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
          423 -                                                ; /* NOP */
          424 -                                        curfont->next = usedfont;
          425 -                                } else {
          426 -                                        xfont_free(usedfont);
          427 -                                        nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
          428 -no_match:
          429 -                                        usedfont = drw->fonts;
          430 -                                }
          431 -                        }
          432 -                }
          433          }
          434 +
          435          if (d)
          436                  XftDrawDestroy(d);
          437  
          438 @@ -395,35 +239,40 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
          439  }
          440  
          441  unsigned int
          442 -drw_fontset_getwidth(Drw *drw, const char *text)
          443 +drw_font_getwidth(Drw *drw, const char *text, Bool markup)
          444  {
          445 -        if (!drw || !drw->fonts || !text)
          446 +        if (!drw || !drw->font || !text)
          447                  return 0;
          448 -        return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
          449 +        return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup);
          450  }
          451  
          452  unsigned int
          453 -drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
          454 +drw_font_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup)
          455  {
          456          unsigned int tmp = 0;
          457 -        if (drw && drw->fonts && text && n)
          458 -                tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
          459 +        if (drw && drw->font && text && n)
          460 +                tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, markup);
          461          return MIN(n, tmp);
          462  }
          463  
          464  void
          465 -drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
          466 +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup)
          467  {
          468 -        XGlyphInfo ext;
          469 -
          470          if (!font || !text)
          471                  return;
          472  
          473 -        XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
          474 +        PangoRectangle r;
          475 +        if(markup)
          476 +                pango_layout_set_markup(font->layout, text, len);
          477 +        else
          478 +                pango_layout_set_text(font->layout, text, len);
          479 +        pango_layout_get_extents(font->layout, 0, &r);
          480 +        if(markup) /* clear markup attributes */
          481 +                pango_layout_set_attributes(font->layout, NULL);
          482          if (w)
          483 -                *w = ext.xOff;
          484 +                *w = r.width / PANGO_SCALE;
          485          if (h)
          486 -                *h = font->h;
          487 +                *h = r.height / PANGO_SCALE;
          488  }
          489  
          490  Cur *
          491 diff --git a/drw.h b/drw.h
          492 index 6471431..9487c72 100644
          493 --- a/drw.h
          494 +++ b/drw.h
          495 @@ -7,9 +7,7 @@ typedef struct {
          496  typedef struct Fnt {
          497          Display *dpy;
          498          unsigned int h;
          499 -        XftFont *xfont;
          500 -        FcPattern *pattern;
          501 -        struct Fnt *next;
          502 +        PangoLayout *layout;
          503  } Fnt;
          504  
          505  enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
          506 @@ -23,7 +21,7 @@ typedef struct {
          507          Drawable drawable;
          508          GC gc;
          509          Clr *scheme;
          510 -        Fnt *fonts;
          511 +        Fnt *font;
          512  } Drw;
          513  
          514  /* Drawable abstraction */
          515 @@ -32,11 +30,11 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h);
          516  void drw_free(Drw *drw);
          517  
          518  /* Fnt abstraction */
          519 -Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
          520 -void drw_fontset_free(Fnt* set);
          521 -unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
          522 -unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
          523 -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
          524 +Fnt *drw_font_create(Drw* drw, const char font[]);
          525 +void drw_font_free(Fnt* set);
          526 +unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup);
          527 +unsigned int drw_font_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup);
          528 +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
          529  
          530  /* Colorscheme abstraction */
          531  void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
          532 @@ -47,12 +45,11 @@ Cur *drw_cur_create(Drw *drw, int shape);
          533  void drw_cur_free(Drw *drw, Cur *cursor);
          534  
          535  /* Drawing context manipulation */
          536 -void drw_setfontset(Drw *drw, Fnt *set);
          537  void drw_setscheme(Drw *drw, Clr *scm);
          538  
          539  /* Drawing functions */
          540  void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
          541 -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
          542 +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);
          543  
          544  /* Map functions */
          545  void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
          546 diff --git a/dwm.c b/dwm.c
          547 index f1d86b2..e535d73 100644
          548 --- a/dwm.c
          549 +++ b/dwm.c
          550 @@ -40,6 +40,7 @@
          551  #include <X11/extensions/Xinerama.h>
          552  #endif /* XINERAMA */
          553  #include <X11/Xft/Xft.h>
          554 +#include <pango/pango.h>
          555  
          556  #include "drw.h"
          557  #include "util.h"
          558 @@ -55,7 +56,8 @@
          559  #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
          560  #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
          561  #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
          562 -#define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
          563 +#define TEXTW(X)                (drw_font_getwidth(drw, (X), False) + lrpad)
          564 +#define TEXTWM(X)               (drw_font_getwidth(drw, (X), True) + lrpad)
          565  
          566  /* enums */
          567  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
          568 @@ -236,7 +238,7 @@ static void zoom(const Arg *arg);
          569  
          570  /* variables */
          571  static const char broken[] = "broken";
          572 -static char stext[256];
          573 +static char stext[512];
          574  static int screen;
          575  static int sw, sh;           /* X display screen geometry width, height */
          576  static int bh;               /* bar height */
          577 @@ -441,7 +443,7 @@ buttonpress(XEvent *e)
          578                          arg.ui = 1 << i;
          579                  } else if (ev->x < x + TEXTW(selmon->ltsymbol))
          580                          click = ClkLtSymbol;
          581 -                else if (ev->x > selmon->ww - (int)TEXTW(stext))
          582 +                else if (ev->x > selmon->ww - (int)TEXTWM(stext))
          583                          click = ClkStatusText;
          584                  else
          585                          click = ClkWinTitle;
          586 @@ -699,8 +701,8 @@ void
          587  drawbar(Monitor *m)
          588  {
          589          int x, w, tw = 0;
          590 -        int boxs = drw->fonts->h / 9;
          591 -        int boxw = drw->fonts->h / 6 + 2;
          592 +        int boxs = drw->font->h / 9;
          593 +        int boxw = drw->font->h / 6 + 2;
          594          unsigned int i, occ = 0, urg = 0;
          595          Client *c;
          596  
          597 @@ -710,8 +712,8 @@ drawbar(Monitor *m)
          598          /* draw status first so it can be overdrawn by tags later */
          599          if (m == selmon) { /* status is only drawn on selected monitor */
          600                  drw_setscheme(drw, scheme[SchemeNorm]);
          601 -                tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
          602 -                drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
          603 +                tw = TEXTWM(stext) - lrpad + 2; /* 2px right padding */
          604 +                drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0, True);
          605          }
          606  
          607          for (c = m->clients; c; c = c->next) {
          608 @@ -723,7 +725,7 @@ drawbar(Monitor *m)
          609          for (i = 0; i < LENGTH(tags); i++) {
          610                  w = TEXTW(tags[i]);
          611                  drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
          612 -                drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
          613 +                drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i, False);
          614                  if (occ & 1 << i)
          615                          drw_rect(drw, x + boxs, boxs, boxw, boxw,
          616                                  m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
          617 @@ -732,12 +734,12 @@ drawbar(Monitor *m)
          618          }
          619          w = TEXTW(m->ltsymbol);
          620          drw_setscheme(drw, scheme[SchemeNorm]);
          621 -        x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
          622 +        x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0, False);
          623  
          624          if ((w = m->ww - tw - x) > bh) {
          625                  if (m->sel) {
          626                          drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
          627 -                        drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
          628 +                        drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0, False);
          629                          if (m->sel->isfloating)
          630                                  drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
          631                  } else {
          632 @@ -1559,10 +1561,10 @@ setup(void)
          633          sh = DisplayHeight(dpy, screen);
          634          root = RootWindow(dpy, screen);
          635          drw = drw_create(dpy, screen, root, sw, sh);
          636 -        if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
          637 +        if (!drw_font_create(drw, font))
          638                  die("no fonts could be loaded.");
          639 -        lrpad = drw->fonts->h;
          640 -        bh = drw->fonts->h + 2;
          641 +        lrpad = drw->font->h;
          642 +        bh = drw->font->h + 2;
          643          updategeom();
          644          /* init atoms */
          645          utf8string = XInternAtom(dpy, "UTF8_STRING", False);
          646 diff --git a/util.h b/util.h
          647 index f633b51..531ab25 100644
          648 --- a/util.h
          649 +++ b/util.h
          650 @@ -1,7 +1,11 @@
          651  /* See LICENSE file for copyright and license details. */
          652  
          653 +#ifndef MAX
          654  #define MAX(A, B)               ((A) > (B) ? (A) : (B))
          655 +#endif
          656 +#ifndef MIN
          657  #define MIN(A, B)               ((A) < (B) ? (A) : (B))
          658 +#endif
          659  #define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B))
          660  
          661  void die(const char *fmt, ...);
          662 -- 
          663 2.40.1
          664 
          665 
          666 From f54ad36bfe201c64f2f7b82c38c01e08a98fb485 Mon Sep 17 00:00:00 2001
          667 From: Khalid Bin Walid <kbwalid26@gmail.com>
          668 Date: Sat, 20 May 2023 20:54:22 +0900
          669 Subject: [PATCH 2/2] revert unintentional space to tab conversion
          670 
          671 ---
          672  drw.c | 8 ++++----
          673  1 file changed, 4 insertions(+), 4 deletions(-)
          674 
          675 diff --git a/drw.c b/drw.c
          676 index d7ebfd8..908bb89 100644
          677 --- a/drw.c
          678 +++ b/drw.c
          679 @@ -121,8 +121,8 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
          680                  return;
          681  
          682          if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
          683 -                                                   DefaultColormap(drw->dpy, drw->screen),
          684 -                                                   clrname, dest))
          685 +                           DefaultColormap(drw->dpy, drw->screen),
          686 +                           clrname, dest))
          687                  die("error, cannot allocate color '%s'", clrname);
          688  }
          689  
          690 @@ -181,8 +181,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
          691                  XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
          692                  XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
          693                  d = XftDrawCreate(drw->dpy, drw->drawable,
          694 -                                                  DefaultVisual(drw->dpy, drw->screen),
          695 -                                                  DefaultColormap(drw->dpy, drw->screen));
          696 +                          DefaultVisual(drw->dpy, drw->screen),
          697 +                          DefaultColormap(drw->dpy, drw->screen));
          698                  x += lpad;
          699                  w -= lpad;
          700          }
          701 -- 
          702 2.40.1
          703