sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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