diff --git a/sys/src/libdraw/font.c b/sys/src/libdraw/font.c index 5cda3f25d..4eaeb9e8d 100644 --- a/sys/src/libdraw/font.c +++ b/sys/src/libdraw/font.c @@ -10,7 +10,7 @@ static int freeup(Font*); int cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **subfontname) { - int i, th, sh, h, ld, w, rw, wid, nc; + int i, th, sh, h, w, rw, wid, nc; char *sp; Rune r, *rp, vr; ulong a; @@ -81,12 +81,9 @@ cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **s if(c->age == f->age) /* flush pending string output */ break; - ld = loadchar(f, r, c, h, i, subfontname); - if(ld <= 0){ - if(ld == 0) - continue; + if(loadchar(f, r, c, h, i, subfontname) <= 0) break; - } + c = &f->cache[h]; /* may have reallocated f->cache */ Found: diff --git a/sys/src/libdraw/string.c b/sys/src/libdraw/string.c index 70e7a2797..62e3c3b1a 100644 --- a/sys/src/libdraw/string.c +++ b/sys/src/libdraw/string.c @@ -58,13 +58,12 @@ runestringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int Point _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, int len, Rectangle clipr, Image *bg, Point bgp, Drawop op) { - int m, n, wid, max; + int m, n, wid, max, try; ushort cbuf[Max], *c, *ec; uchar *b; char *subfontname; char **sptr; - Rune **rptr; - Font *def; + Rune **rptr, rune; Subfont *sf; if(s == nil){ @@ -78,63 +77,76 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i }else rptr = &r; sf = nil; - while((*s || *r) && len){ + try = 0; + while((*s || *r) && len > 0){ max = Max; if(len < max) max = len; - n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname); - if(n > 0){ - _setdrawop(dst->display, op); - - m = 47+2*n; - if(bg) - m += 4+2*4; - b = bufimage(dst->display, m); - if(b == 0){ - fprint(2, "string: %r\n"); - break; - } - if(bg) - b[0] = 'x'; - else - b[0] = 's'; - BPLONG(b+1, dst->id); - BPLONG(b+5, src->id); - BPLONG(b+9, f->cacheimage->id); - BPLONG(b+13, pt.x); - BPLONG(b+17, pt.y+f->ascent); - BPLONG(b+21, clipr.min.x); - BPLONG(b+25, clipr.min.y); - BPLONG(b+29, clipr.max.x); - BPLONG(b+33, clipr.max.y); - BPLONG(b+37, sp.x); - BPLONG(b+41, sp.y); - BPSHORT(b+45, n); - b += 47; - if(bg){ - BPLONG(b, bg->id); - BPLONG(b+4, bgp.x); - BPLONG(b+8, bgp.y); - b += 12; - } - ec = &cbuf[n]; - for(c=cbuf; cdisplay, subfontname)) == 0){ - def = f->display ? f->display->defaultfont : nil; - if(def && f!=def) - f = def; - else + if((n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ + if(subfontname){ + if(++try > 10) break; + Nextfont: + freesubfont(sf); + if((sf=_getsubfont(f->display, subfontname)) != nil) + continue; + if(f->display->defaultfont == nil || f->display->defaultfont == f) + break; + f = f->display->defaultfont; + continue; } + if(*r) + r++; + else + s += chartorune(&rune, s); + len--; + continue; } + try = 0; + + _setdrawop(dst->display, op); + + m = 47+2*n; + if(bg) + m += 4+2*4; + b = bufimage(dst->display, m); + if(b == 0){ + fprint(2, "string: %r\n"); + break; + } + if(bg) + b[0] = 'x'; + else + b[0] = 's'; + BPLONG(b+1, dst->id); + BPLONG(b+5, src->id); + BPLONG(b+9, f->cacheimage->id); + BPLONG(b+13, pt.x); + BPLONG(b+17, pt.y+f->ascent); + BPLONG(b+21, clipr.min.x); + BPLONG(b+25, clipr.min.y); + BPLONG(b+29, clipr.max.x); + BPLONG(b+33, clipr.max.y); + BPLONG(b+37, sp.x); + BPLONG(b+41, sp.y); + BPSHORT(b+45, n); + b += 47; + if(bg){ + BPLONG(b, bg->id); + BPLONG(b+4, bgp.x); + BPLONG(b+8, bgp.y); + b += 12; + } + ec = &cbuf[n]; + for(c=cbuf; c0 && (*s || *r)){ + try = 0; + while((*s || *r) && len > 0){ max = Max; if(len < max) max = len; - n = 0; - while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ - if(++n > 10){ - if(*r) - rune = *r; - else - chartorune(&rune, s); - if(f->name != nil) - name = f->name; - else - name = "unnamed font"; - fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); - return twid; - } + if((n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ if(subfontname){ + if(++try > 10) + break; + Nextfont: freesubfont(sf); - if((sf=_getsubfont(f->display, subfontname)) == 0){ - def = f->display->defaultfont; - if(def && f!=def) - f = def; - else - break; - } + if((sf=_getsubfont(f->display, subfontname)) != nil) + continue; + if(f->display == nil || f->display->defaultfont == nil || f->display->defaultfont == f) + break; + f = f->display->defaultfont; + continue; } + if(*r) + r++; + else + s += chartorune(&rune, s); + len--; + continue; } + try = 0; agefont(f); twid += wid; - len -= l; + len -= n; + + if(subfontname) + goto Nextfont; } freesubfont(sf); return twid;