> > But I still see the > prompt getting incorrectly cut off and the ellipsis still don't get > rendered in case of font change.
I see, you mean in the edge case that there is a font change, but there is not enough space to add a single utf8 character for that font. You can just move the ellipsis rendering if statement outside of the if (utf8strlen) { block. On Tue, Mar 22, 2022 at 6:54 AM NRK <n...@disroot.org> wrote: > On Mon, Mar 21, 2022 at 10:35:21PM +0100, Stein Gunnar Bakkeby wrote: > > you make some interesting points. I am curious as to what your queueing > > approach would look like. > > > > I played around some more simplifying the ellipsis drawing and removing > buf > > as you suggested. > > This would solve all of the aforementioned problems as far as I can tell, > > but it can result in a partly drawn > > emoji for example when the ellipsis cuts it off (which I think is a fair > > tradeoff). > > Hi, > > Tried out your last patch, it's simpler indeed. But I still see the > prompt getting incorrectly cut off and the ellipsis still don't get > rendered in case of font change. > > The queue patch solves the above problems, but as I've said it's quite > messy. I was planning to move everything over to the queue so that we > won't need to special case anything during string drawing. > > But after looking at your current patch, I've scraped that idea. It's > simpler to just draw on top of the problem cases, overwriting them > instead. > > The following diff fixes pretty much every problem for me. The > performance is better and I don't notice any problems with truncating. > Let me know if there's still some edge case unhandled. > > - NRK > > diff --git a/drw.c b/drw.c > index 4cdbcbe..8595a69 100644 > --- a/drw.c > +++ b/drw.c > @@ -251,12 +251,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, > unsigned int h, int filled, int > int > drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned > int lpad, const char *text, int invert) > { > - char buf[1024]; > - int ty; > - unsigned int ew; > + int ty, ellipsis_x = 0; > + unsigned int tmpw, ew, ellipsis_w, ellipsis_len; > XftDraw *d = NULL; > Fnt *usedfont, *curfont, *nextfont; > - size_t i, len; > int utf8strlen, utf8charlen, render = x || y || w || h; > long utf8codepoint = 0; > const char *utf8str; > @@ -264,7 +262,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, > unsigned int h, unsigned int lp > FcPattern *fcpattern; > FcPattern *match; > XftResult result; > - int charexists = 0; > + int charexists = 0, overflow = 0; > > if (!drw || (render && !drw->scheme) || !text || !drw->fonts) > return 0; > @@ -282,8 +280,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, > unsigned int h, unsigned int lp > } > > usedfont = drw->fonts; > + drw_font_getexts(usedfont, "...", 3, &ellipsis_w, NULL); > while (1) { > - utf8strlen = 0; > + ew = ellipsis_len = utf8strlen = 0; > utf8str = text; > nextfont = NULL; > while (*text) { > @@ -291,9 +290,19 @@ drw_text(Drw *drw, int x, int y, unsigned int w, > unsigned int h, unsigned int lp > for (curfont = drw->fonts; curfont; curfont = > curfont->next) { > charexists = charexists || > XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); > if (charexists) { > - if (curfont == usedfont) { > + drw_font_getexts(curfont, text, > utf8charlen, &tmpw, NULL); > + if (ew + ellipsis_w <= w) { > + ellipsis_x = x + ew; > + ellipsis_len = utf8strlen; > + } > + > + if (ew > w) { > + overflow = 1; > + utf8strlen = ellipsis_len; > + } else if (curfont == usedfont) { > utf8strlen += utf8charlen; > text += utf8charlen; > + ew += tmpw; > } else { > nextfont = curfont; > } > @@ -301,36 +310,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, > unsigned int h, unsigned int lp > } > } > > - if (!charexists || nextfont) > + if (overflow || !charexists || nextfont) > break; > else > charexists = 0; > } > > if (utf8strlen) { > - drw_font_getexts(usedfont, utf8str, utf8strlen, > &ew, NULL); > - /* shorten text if necessary */ > - for (len = MIN(utf8strlen, sizeof(buf) - 1); len > && ew > w; len--) > - drw_font_getexts(usedfont, utf8str, len, > &ew, NULL); > - > - if (len) { > - memcpy(buf, utf8str, len); > - buf[len] = '\0'; > - if (len < utf8strlen) > - for (i = len; i && i > len - 3; > buf[--i] = '.') > - ; /* NOP */ > - > - if (render) { > - ty = y + (h - usedfont->h) / 2 + > usedfont->xfont->ascent; > - XftDrawStringUtf8(d, > &drw->scheme[invert ? ColBg : ColFg], > - usedfont->xfont, > x, ty, (XftChar8 *)buf, len); > - } > - x += ew; > - w -= ew; > + if (render) { > + ty = y + (h - usedfont->h) / 2 + > usedfont->xfont->ascent; > + XftDrawStringUtf8(d, &drw->scheme[invert ? > ColBg : ColFg], > + usedfont->xfont, x, ty, > (XftChar8 *)utf8str, utf8strlen); > } > + x += ew; > + w -= ew; > } > + if (render && overflow) > + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, > "...", invert); > > - if (!*text) { > + if (overflow || !*text) { > break; > } else if (nextfont) { > charexists = 0; > > >