commit b2f9ee0de55f3c59c83f479d12cfe8c894935bd7 from: rsc date: Wed Jul 13 03:57:24 2005 UTC free subfonts correctly commit - 3b634dc7e4ab32a6854c8ec93107b2750bf906e8 commit + b2f9ee0de55f3c59c83f479d12cfe8c894935bd7 blob - 4dfb27faa5d15e00ce525ac8c9dc2947f42aab14 blob + 4e876c170b7def9e2a15ee33da7558ae41b78a48 --- src/libdraw/string.c +++ src/libdraw/string.c @@ -65,6 +65,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Fo char **sptr; Rune **rptr; Font *def; + Subfont *sf; if(s == nil){ s = ""; @@ -76,6 +77,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Fo rptr = nil; }else rptr = &r; + sf = nil; while((*s || *r) && len){ max = Max; if(len < max) @@ -124,13 +126,18 @@ _string(Image *dst, Point pt, Image *src, Point sp, Fo len -= n; } if(subfontname){ - if(_getsubfont(f->display, subfontname) == 0){ - def = f->display->defaultfont; + freesubfont(sf); + if((sf=_getsubfont(f->display, subfontname)) == 0){ + def = f->display ? f->display->defaultfont : nil; if(def && f!=def) f = def; else break; } + /* + * must not free sf until cachechars has found it in the cache + * and picked up its own reference. + */ } } return pt; blob - 8d8c6d081a1be0219ccf6c1136b574b1fa869259 blob + 522fbc0115d07609314b5133b5ef1adf11eddbb7 --- src/libdraw/stringwidth.c +++ src/libdraw/stringwidth.c @@ -13,6 +13,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len) Rune rune, **rptr; char *subfontname, **sptr; Font *def; + Subfont *sf; if(s == nil){ s = ""; @@ -30,6 +31,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len) if(len < max) max = len; n = 0; + sf = nil; while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ if(++n > 10){ if(*r) @@ -40,19 +42,26 @@ _stringnwidth(Font *f, char *s, Rune *r, int len) name = f->name; else name = "unnamed font"; + freesubfont(sf); fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); return twid; } if(subfontname){ - if(_getsubfont(f->display, subfontname) == 0){ - def = f->display->defaultfont; + freesubfont(sf); + if((sf=_getsubfont(f->display, subfontname)) == 0){ + def = f->display ? f->display->defaultfont : nil; if(def && f!=def) f = def; else break; } + /* + * must not free sf until cachechars has found it in the cache + * and picked up its own reference. + */ } } + freesubfont(sf); agefont(f); twid += wid; len -= l; blob - 61838b0548190d1e622ea654e7a5acc9c9cc3acb blob + 085afba31bb0b2162bba1a7b7f8a5558515e4eb1 --- src/libdraw/subfont.c +++ src/libdraw/subfont.c @@ -5,13 +5,14 @@ Subfont* allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i) { - Subfont *f; + Subfont *f, *cf; assert(height != 0 /* allocsubfont */); f = malloc(sizeof(Subfont)); if(f == 0) return 0; +fprint(2, "allocsubfont %p\n", f); f->n = n; f->height = height; f->ascent = ascent; @@ -19,9 +20,18 @@ allocsubfont(char *name, int n, int height, int ascent f->bits = i; f->ref = 1; if(name){ + /* + * if already caching this subfont, leave older + * (and hopefully more widely used) copy in cache. + * this case should not happen -- we got called + * because cachechars needed this subfont and it + * wasn't in the cache. + */ f->name = strdup(name); - if(lookupsubfont(i->display, name) == 0) + if((cf=lookupsubfont(i->display, name)) == 0) installsubfont(name, f); + else + freesubfont(cf); /* drop ref we just picked up */ }else f->name = 0; return f;