diff options
| -rw-r--r-- | drw.c | 56 |
1 files changed, 28 insertions, 28 deletions
| @@ -251,12 +251,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int | |||
| 251 | int | 251 | int |
| 252 | drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) | 252 | drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) |
| 253 | { | 253 | { |
| 254 | char buf[1024]; | 254 | int ty, ellipsis_x = 0; |
| 255 | int ty; | 255 | unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, ellipsis_width; |
| 256 | unsigned int ew; | ||
| 257 | XftDraw *d = NULL; | 256 | XftDraw *d = NULL; |
| 258 | Fnt *usedfont, *curfont, *nextfont; | 257 | Fnt *usedfont, *curfont, *nextfont; |
| 259 | size_t i, len; | ||
| 260 | int utf8strlen, utf8charlen, render = x || y || w || h; | 258 | int utf8strlen, utf8charlen, render = x || y || w || h; |
| 261 | long utf8codepoint = 0; | 259 | long utf8codepoint = 0; |
| 262 | const char *utf8str; | 260 | const char *utf8str; |
| @@ -264,7 +262,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp | |||
| 264 | FcPattern *fcpattern; | 262 | FcPattern *fcpattern; |
| 265 | FcPattern *match; | 263 | FcPattern *match; |
| 266 | XftResult result; | 264 | XftResult result; |
| 267 | int charexists = 0; | 265 | int charexists = 0, overflow = 0; |
| 268 | 266 | ||
| 269 | if (!drw || (render && !drw->scheme) || !text || !drw->fonts) | 267 | if (!drw || (render && !drw->scheme) || !text || !drw->fonts) |
| 270 | return 0; | 268 | return 0; |
| @@ -282,8 +280,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp | |||
| 282 | } | 280 | } |
| 283 | 281 | ||
| 284 | usedfont = drw->fonts; | 282 | usedfont = drw->fonts; |
| 283 | drw_font_getexts(usedfont, "...", 3, &ellipsis_width, NULL); | ||
| 285 | while (1) { | 284 | while (1) { |
| 286 | utf8strlen = 0; | 285 | ew = ellipsis_len = utf8strlen = 0; |
| 287 | utf8str = text; | 286 | utf8str = text; |
| 288 | nextfont = NULL; | 287 | nextfont = NULL; |
| 289 | while (*text) { | 288 | while (*text) { |
| @@ -291,9 +290,21 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp | |||
| 291 | for (curfont = drw->fonts; curfont; curfont = curfont->next) { | 290 | for (curfont = drw->fonts; curfont; curfont = curfont->next) { |
| 292 | charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); | 291 | charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); |
| 293 | if (charexists) { | 292 | if (charexists) { |
| 294 | if (curfont == usedfont) { | 293 | drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); |
| 294 | if (ew + ellipsis_width <= w) { | ||
| 295 | /* keep track where the ellipsis still fits */ | ||
| 296 | ellipsis_x = x + ew; | ||
| 297 | ellipsis_w = w - ew; | ||
| 298 | ellipsis_len = utf8strlen; | ||
| 299 | } | ||
| 300 | |||
| 301 | if (ew + tmpw > w) { | ||
| 302 | overflow = 1; | ||
| 303 | utf8strlen = ellipsis_len; | ||
| 304 | } else if (curfont == usedfont) { | ||
| 295 | utf8strlen += utf8charlen; | 305 | utf8strlen += utf8charlen; |
| 296 | text += utf8charlen; | 306 | text += utf8charlen; |
| 307 | ew += tmpw; | ||
| 297 | } else { | 308 | } else { |
| 298 | nextfont = curfont; | 309 | nextfont = curfont; |
| 299 | } | 310 | } |
| @@ -301,36 +312,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp | |||
| 301 | } | 312 | } |
| 302 | } | 313 | } |
| 303 | 314 | ||
| 304 | if (!charexists || nextfont) | 315 | if (overflow || !charexists || nextfont) |
| 305 | break; | 316 | break; |
| 306 | else | 317 | else |
| 307 | charexists = 0; | 318 | charexists = 0; |
| 308 | } | 319 | } |
| 309 | 320 | ||
| 310 | if (utf8strlen) { | 321 | if (utf8strlen) { |
| 311 | drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); | 322 | if (render) { |
| 312 | /* shorten text if necessary */ | 323 | ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; |
| 313 | for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) | 324 | XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], |
| 314 | drw_font_getexts(usedfont, utf8str, len, &ew, NULL); | 325 | usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); |
| 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 | } | 326 | } |
| 327 | x += ew; | ||
| 328 | w -= ew; | ||
| 331 | } | 329 | } |
| 330 | if (render && overflow) | ||
| 331 | drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); | ||
| 332 | 332 | ||
| 333 | if (!*text) { | 333 | if (!*text || overflow) { |
| 334 | break; | 334 | break; |
| 335 | } else if (nextfont) { | 335 | } else if (nextfont) { |
| 336 | charexists = 0; | 336 | charexists = 0; |
