free subfonts correctly

This commit is contained in:
rsc 2005-07-13 03:57:24 +00:00
parent 3b634dc7e4
commit b2f9ee0de5
3 changed files with 32 additions and 6 deletions

View file

@ -65,6 +65,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
char **sptr; char **sptr;
Rune **rptr; Rune **rptr;
Font *def; Font *def;
Subfont *sf;
if(s == nil){ if(s == nil){
s = ""; s = "";
@ -76,6 +77,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
rptr = nil; rptr = nil;
}else }else
rptr = &r; rptr = &r;
sf = nil;
while((*s || *r) && len){ while((*s || *r) && len){
max = Max; max = Max;
if(len < max) if(len < max)
@ -124,13 +126,18 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
len -= n; len -= n;
} }
if(subfontname){ if(subfontname){
if(_getsubfont(f->display, subfontname) == 0){ freesubfont(sf);
def = f->display->defaultfont; if((sf=_getsubfont(f->display, subfontname)) == 0){
def = f->display ? f->display->defaultfont : nil;
if(def && f!=def) if(def && f!=def)
f = def; f = def;
else else
break; break;
} }
/*
* must not free sf until cachechars has found it in the cache
* and picked up its own reference.
*/
} }
} }
return pt; return pt;

View file

@ -13,6 +13,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len)
Rune rune, **rptr; Rune rune, **rptr;
char *subfontname, **sptr; char *subfontname, **sptr;
Font *def; Font *def;
Subfont *sf;
if(s == nil){ if(s == nil){
s = ""; s = "";
@ -30,6 +31,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len)
if(len < max) if(len < max)
max = len; max = len;
n = 0; n = 0;
sf = nil;
while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){
if(++n > 10){ if(++n > 10){
if(*r) if(*r)
@ -40,19 +42,26 @@ _stringnwidth(Font *f, char *s, Rune *r, int len)
name = f->name; name = f->name;
else else
name = "unnamed font"; name = "unnamed font";
freesubfont(sf);
fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name);
return twid; return twid;
} }
if(subfontname){ if(subfontname){
if(_getsubfont(f->display, subfontname) == 0){ freesubfont(sf);
def = f->display->defaultfont; if((sf=_getsubfont(f->display, subfontname)) == 0){
def = f->display ? f->display->defaultfont : nil;
if(def && f!=def) if(def && f!=def)
f = def; f = def;
else else
break; break;
} }
/*
* must not free sf until cachechars has found it in the cache
* and picked up its own reference.
*/
} }
} }
freesubfont(sf);
agefont(f); agefont(f);
twid += wid; twid += wid;
len -= l; len -= l;

View file

@ -5,13 +5,14 @@
Subfont* Subfont*
allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i) allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i)
{ {
Subfont *f; Subfont *f, *cf;
assert(height != 0 /* allocsubfont */); assert(height != 0 /* allocsubfont */);
f = malloc(sizeof(Subfont)); f = malloc(sizeof(Subfont));
if(f == 0) if(f == 0)
return 0; return 0;
fprint(2, "allocsubfont %p\n", f);
f->n = n; f->n = n;
f->height = height; f->height = height;
f->ascent = ascent; f->ascent = ascent;
@ -19,9 +20,18 @@ allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i
f->bits = i; f->bits = i;
f->ref = 1; f->ref = 1;
if(name){ 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); f->name = strdup(name);
if(lookupsubfont(i->display, name) == 0) if((cf=lookupsubfont(i->display, name)) == 0)
installsubfont(name, f); installsubfont(name, f);
else
freesubfont(cf); /* drop ref we just picked up */
}else }else
f->name = 0; f->name = 0;
return f; return f;