tfree subfonts correctly - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
commit b2f9ee0de55f3c59c83f479d12cfe8c894935bd7
parent 3b634dc7e4ab32a6854c8ec93107b2750bf906e8
Author: rsc 
Date:   Wed, 13 Jul 2005 03:57:24 +0000

free subfonts correctly

Diffstat:
  M src/libdraw/string.c                |      11 +++++++++--
  M src/libdraw/stringwidth.c           |      13 +++++++++++--
  M src/libdraw/subfont.c               |      14 ++++++++++++--

3 files changed, 32 insertions(+), 6 deletions(-)
---
diff --git a/src/libdraw/string.c b/src/libdraw/string.c
t@@ -65,6 +65,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
         char **sptr;
         Rune **rptr;
         Font *def;
+        Subfont *sf;
 
         if(s == nil){
                 s = "";
t@@ -76,6 +77,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
                 rptr = nil;
         }else
                 rptr = &r;
+        sf = nil;
         while((*s || *r) && len){
                 max = Max;
                 if(len < max)
t@@ -124,13 +126,18 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
                         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;
diff --git a/src/libdraw/stringwidth.c b/src/libdraw/stringwidth.c
t@@ -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 = "";
t@@ -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)
t@@ -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;
diff --git a/src/libdraw/subfont.c b/src/libdraw/subfont.c
t@@ -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;
t@@ -19,9 +20,18 @@ allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i
         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;