sites

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