>
> 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;
>
>
>

Reply via email to