stringwidth(2) was leaking subfonts. Reference: /n/atom/patch/applied2013/strwidthleak Date: Fri Nov 29 04:40:06 CET 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/libdraw/init.acid6 Thu Jan 1 00:00:00 1970 +++ /sys/src/libdraw/init.acid6 Fri Nov 29 04:39:41 2013 @@ -0,0 +1,741 @@ +sizeof_1_ = 8; +aggr _1_ +{ + 'U' 0 lo; + 'U' 4 hi; +}; + +defn +_1_(addr) { + complex _1_ addr; + print(" lo ", addr.lo, "\n"); + print(" hi ", addr.hi, "\n"); +}; + +sizeofFPdbleword = 8; +aggr FPdbleword +{ + 'F' 0 x; + { + 'U' 0 lo; + 'U' 4 hi; + }; +}; + +defn +FPdbleword(addr) { + complex FPdbleword addr; + print(" x ", addr.x, "\n"); + print("_1_ {\n"); + _1_(addr+0); + print("}\n"); +}; + +UTFmax = 4; +Runesync = 128; +Runeself = 128; +Runeerror = 65533; +Runemax = 1114111; +sizeofFmt = 48; +aggr Fmt +{ + 'b' 0 runes; + 'X' 4 start; + 'X' 8 to; + 'X' 12 stop; + 'X' 16 flush; + 'X' 20 farg; + 'D' 24 nfmt; + 'X' 28 args; + 'D' 32 r; + 'D' 36 width; + 'D' 40 prec; + 'U' 44 flags; +}; + +defn +Fmt(addr) { + complex Fmt addr; + print(" runes ", addr.runes, "\n"); + print(" start ", addr.start\X, "\n"); + print(" to ", addr.to\X, "\n"); + print(" stop ", addr.stop\X, "\n"); + print(" flush ", addr.flush\X, "\n"); + print(" farg ", addr.farg\X, "\n"); + print(" nfmt ", addr.nfmt, "\n"); + print(" args ", addr.args\X, "\n"); + print(" r ", addr.r, "\n"); + print(" width ", addr.width, "\n"); + print(" prec ", addr.prec, "\n"); + print(" flags ", addr.flags, "\n"); +}; + +FmtWidth = 1; +FmtLeft = 2; +FmtPrec = 4; +FmtSharp = 8; +FmtSpace = 16; +FmtSign = 32; +FmtZero = 64; +FmtUnsigned = 128; +FmtShort = 256; +FmtLong = 512; +FmtVLong = 1024; +FmtComma = 2048; +FmtByte = 4096; +FmtFlag = 8192; +sizeofTm = 40; +aggr Tm +{ + 'D' 0 sec; + 'D' 4 min; + 'D' 8 hour; + 'D' 12 mday; + 'D' 16 mon; + 'D' 20 year; + 'D' 24 wday; + 'D' 28 yday; + 'a' 32 zone; + 'D' 36 tzoff; +}; + +defn +Tm(addr) { + complex Tm addr; + print(" sec ", addr.sec, "\n"); + print(" min ", addr.min, "\n"); + print(" hour ", addr.hour, "\n"); + print(" mday ", addr.mday, "\n"); + print(" mon ", addr.mon, "\n"); + print(" year ", addr.year, "\n"); + print(" wday ", addr.wday, "\n"); + print(" yday ", addr.yday, "\n"); + print(" zone ", addr.zone, "\n"); + print(" tzoff ", addr.tzoff, "\n"); +}; + +PNPROC = 1; +PNGROUP = 2; +Profoff = 0; +Profuser = 1; +Profkernel = 2; +Proftime = 3; +Profsample = 4; +sizeofLock = 4; +aggr Lock +{ + 'D' 0 val; +}; + +defn +Lock(addr) { + complex Lock addr; + print(" val ", addr.val, "\n"); +}; + +sizeofQLp = 12; +aggr QLp +{ + 'D' 0 inuse; + 'A' QLp 4 next; + 'C' 8 state; +}; + +defn +QLp(addr) { + complex QLp addr; + print(" inuse ", addr.inuse, "\n"); + print(" next ", addr.next\X, "\n"); + print(" state ", addr.state, "\n"); +}; + +sizeofQLock = 16; +aggr QLock +{ + Lock 0 lock; + 'D' 4 locked; + 'A' QLp 8 $head; + 'A' QLp 12 $tail; +}; + +defn +QLock(addr) { + complex QLock addr; + print("Lock lock {\n"); + Lock(addr.lock); + print("}\n"); + print(" locked ", addr.locked, "\n"); + print(" $head ", addr.$head\X, "\n"); + print(" $tail ", addr.$tail\X, "\n"); +}; + +sizeofRWLock = 20; +aggr RWLock +{ + Lock 0 lock; + 'D' 4 readers; + 'D' 8 writer; + 'A' QLp 12 $head; + 'A' QLp 16 $tail; +}; + +defn +RWLock(addr) { + complex RWLock addr; + print("Lock lock {\n"); + Lock(addr.lock); + print("}\n"); + print(" readers ", addr.readers, "\n"); + print(" writer ", addr.writer, "\n"); + print(" $head ", addr.$head\X, "\n"); + print(" $tail ", addr.$tail\X, "\n"); +}; + +sizeofRendez = 12; +aggr Rendez +{ + 'A' QLock 0 l; + 'A' QLp 4 $head; + 'A' QLp 8 $tail; +}; + +defn +Rendez(addr) { + complex Rendez addr; + print(" l ", addr.l\X, "\n"); + print(" $head ", addr.$head\X, "\n"); + print(" $tail ", addr.$tail\X, "\n"); +}; + +sizeofNetConnInfo = 36; +aggr NetConnInfo +{ + 'X' 0 dir; + 'X' 4 root; + 'X' 8 spec; + 'X' 12 lsys; + 'X' 16 lserv; + 'X' 20 rsys; + 'X' 24 rserv; + 'X' 28 laddr; + 'X' 32 raddr; +}; + +defn +NetConnInfo(addr) { + complex NetConnInfo addr; + print(" dir ", addr.dir\X, "\n"); + print(" root ", addr.root\X, "\n"); + print(" spec ", addr.spec\X, "\n"); + print(" lsys ", addr.lsys\X, "\n"); + print(" lserv ", addr.lserv\X, "\n"); + print(" rsys ", addr.rsys\X, "\n"); + print(" rserv ", addr.rserv\X, "\n"); + print(" laddr ", addr.laddr\X, "\n"); + print(" raddr ", addr.raddr\X, "\n"); +}; + +RFNAMEG = 1; +RFENVG = 2; +RFFDG = 4; +RFNOTEG = 8; +RFPROC = 16; +RFMEM = 32; +RFNOWAIT = 64; +RFCNAMEG = 1024; +RFCENVG = 2048; +RFCFDG = 4096; +RFREND = 8192; +RFNOMNT = 16384; +sizeofQid = 16; +aggr Qid +{ + 'W' 0 path; + 'U' 8 vers; + 'b' 12 type; +}; + +defn +Qid(addr) { + complex Qid addr; + print(" path ", addr.path, "\n"); + print(" vers ", addr.vers, "\n"); + print(" type ", addr.type, "\n"); +}; + +sizeofDir = 60; +aggr Dir +{ + 'u' 0 type; + 'U' 4 dev; + Qid 8 qid; + 'U' 24 mode; + 'U' 28 atime; + 'U' 32 mtime; + 'V' 36 length; + 'X' 44 name; + 'X' 48 uid; + 'X' 52 gid; + 'X' 56 muid; +}; + +defn +Dir(addr) { + complex Dir addr; + print(" type ", addr.type, "\n"); + print(" dev ", addr.dev, "\n"); + print("Qid qid {\n"); + Qid(addr.qid); + print("}\n"); + print(" mode ", addr.mode, "\n"); + print(" atime ", addr.atime, "\n"); + print(" mtime ", addr.mtime, "\n"); + print(" length ", addr.length, "\n"); + print(" name ", addr.name\X, "\n"); + print(" uid ", addr.uid\X, "\n"); + print(" gid ", addr.gid\X, "\n"); + print(" muid ", addr.muid\X, "\n"); +}; + +sizeofWaitmsg = 20; +aggr Waitmsg +{ + 'D' 0 pid; + 'a' 4 time; + 'X' 16 msg; +}; + +defn +Waitmsg(addr) { + complex Waitmsg addr; + print(" pid ", addr.pid, "\n"); + print(" time ", addr.time, "\n"); + print(" msg ", addr.msg\X, "\n"); +}; + +sizeofIOchunk = 8; +aggr IOchunk +{ + 'X' 0 addr; + 'U' 4 len; +}; + +defn +IOchunk(addr) { + complex IOchunk addr; + print(" addr ", addr.addr\X, "\n"); + print(" len ", addr.len, "\n"); +}; + +DOpaque = 4294967295; +DTransparent = 0; +DBlack = 255; +DWhite = 4294967295; +DRed = 4278190335; +DGreen = 16711935; +DBlue = 65535; +DCyan = 16777215; +DMagenta = 4278255615; +DYellow = 4294902015; +DPaleyellow = 4294945535; +DDarkyellow = 4008615679; +DDarkgreen = 1149781247; +DPalegreen = 2868882175; +DMedgreen = 2295105791; +DDarkblue = 22015; +DPalebluegreen = 2868903935; +DPaleblue = 48127; +DBluegreen = 8947967; +DGreygreen = 1437248255; +DPalegreygreen = 2666458879; +DYellowgreen = 2576960767; +DMedblue = 39423; +DGreyblue = 6142975; +DPalegreyblue = 1234427391; +DPurpleblue = 2290666751; +DNotacolor = 4294967040; +DNofill = 4294967040; +Displaybufsize = 8000; +ICOSSCALE = 1024; +Borderwidth = 4; +Refbackup = 0; +Refnone = 1; +Refmesg = 2; +Endsquare = 0; +Enddisc = 1; +Endarrow = 2; +Endmask = 31; +Clear = 0; +SinD = 8; +DinS = 4; +SoutD = 2; +DoutS = 1; +S = 10; +SoverD = 11; +SatopD = 9; +SxorD = 3; +D = 5; +DoverS = 7; +DatopS = 6; +DxorS = 3; +Ncomp = 12; +CRed = 0; +CGreen = 1; +CBlue = 2; +CGrey = 3; +CAlpha = 4; +CMap = 5; +CIgnore = 6; +NChan = 7; +GREY1 = 49; +GREY2 = 50; +GREY4 = 52; +GREY8 = 56; +CMAP8 = 88; +RGB15 = 1627723045; +RGB16 = 333349; +RGB24 = 530472; +RGBA32 = 135800904; +ARGB32 = 1208490024; +XRGB32 = 1745360936; +BGR24 = 2627592; +ABGR32 = 1210587144; +XBGR32 = 1747458056; +sizeofPoint = 8; +aggr Point +{ + 'D' 0 x; + 'D' 4 y; +}; + +defn +Point(addr) { + complex Point addr; + print(" x ", addr.x, "\n"); + print(" y ", addr.y, "\n"); +}; + +sizeofRectangle = 16; +aggr Rectangle +{ + Point 0 min; + Point 8 max; +}; + +defn +Rectangle(addr) { + complex Rectangle addr; + print("Point min {\n"); + Point(addr.min); + print("}\n"); + print("Point max {\n"); + Point(addr.max); + print("}\n"); +}; + +sizeofScreen = 16; +aggr Screen +{ + 'X' 0 display; + 'D' 4 id; + 'X' 8 image; + 'X' 12 fill; +}; + +defn +Screen(addr) { + complex Screen addr; + print(" display ", addr.display\X, "\n"); + print(" id ", addr.id, "\n"); + print(" image ", addr.image\X, "\n"); + print(" fill ", addr.fill\X, "\n"); +}; + +sizeofDisplay = 176; +aggr Display +{ + QLock 0 qlock; + 'D' 16 locking; + 'D' 20 dirno; + 'D' 24 fd; + 'D' 28 reffd; + 'D' 32 ctlfd; + 'D' 36 imageid; + 'D' 40 $local; + 'X' 44 error; + 'X' 48 devdir; + 'X' 52 windir; + 'a' 56 oldlabel; + 'U' 120 dataqid; + 'X' 124 white; + 'X' 128 black; + 'X' 132 opaque; + 'X' 136 transparent; + 'X' 140 image; + 'X' 144 buf; + 'D' 148 bufsize; + 'X' 152 bufp; + 'X' 156 defaultfont; + 'X' 160 defaultsubfont; + 'X' 164 windows; + 'X' 168 screenimage; + 'D' 172 _isnewdisplay; +}; + +defn +Display(addr) { + complex Display addr; + print("QLock qlock {\n"); + QLock(addr.qlock); + print("}\n"); + print(" locking ", addr.locking, "\n"); + print(" dirno ", addr.dirno, "\n"); + print(" fd ", addr.fd, "\n"); + print(" reffd ", addr.reffd, "\n"); + print(" ctlfd ", addr.ctlfd, "\n"); + print(" imageid ", addr.imageid, "\n"); + print(" $local ", addr.$local, "\n"); + print(" error ", addr.error\X, "\n"); + print(" devdir ", addr.devdir\X, "\n"); + print(" windir ", addr.windir\X, "\n"); + print(" oldlabel ", addr.oldlabel, "\n"); + print(" dataqid ", addr.dataqid, "\n"); + print(" white ", addr.white\X, "\n"); + print(" black ", addr.black\X, "\n"); + print(" opaque ", addr.opaque\X, "\n"); + print(" transparent ", addr.transparent\X, "\n"); + print(" image ", addr.image\X, "\n"); + print(" buf ", addr.buf\X, "\n"); + print(" bufsize ", addr.bufsize, "\n"); + print(" bufp ", addr.bufp\X, "\n"); + print(" defaultfont ", addr.defaultfont\X, "\n"); + print(" defaultsubfont ", addr.defaultsubfont\X, "\n"); + print(" windows ", addr.windows\X, "\n"); + print(" screenimage ", addr.screenimage\X, "\n"); + print(" _isnewdisplay ", addr._isnewdisplay, "\n"); +}; + +sizeofImage = 60; +aggr Image +{ + 'A' Display 0 display; + 'D' 4 id; + Rectangle 8 r; + Rectangle 24 clipr; + 'D' 40 depth; + 'U' 44 chan; + 'D' 48 repl; + 'A' Screen 52 screen; + 'A' Image 56 next; +}; + +defn +Image(addr) { + complex Image addr; + print(" display ", addr.display\X, "\n"); + print(" id ", addr.id, "\n"); + print("Rectangle r {\n"); + Rectangle(addr.r); + print("}\n"); + print("Rectangle clipr {\n"); + Rectangle(addr.clipr); + print("}\n"); + print(" depth ", addr.depth, "\n"); + print(" chan ", addr.chan, "\n"); + print(" repl ", addr.repl, "\n"); + print(" screen ", addr.screen\X, "\n"); + print(" next ", addr.next\X, "\n"); +}; + +sizeofRGB = 12; +aggr RGB +{ + 'U' 0 red; + 'U' 4 green; + 'U' 8 blue; +}; + +defn +RGB(addr) { + complex RGB addr; + print(" red ", addr.red, "\n"); + print(" green ", addr.green, "\n"); + print(" blue ", addr.blue, "\n"); +}; + +sizeofFontchar = 8; +aggr Fontchar +{ + 'D' 0 x; + 'b' 4 top; + 'b' 5 bottom; + 'C' 6 left; + 'b' 7 width; +}; + +defn +Fontchar(addr) { + complex Fontchar addr; + print(" x ", addr.x, "\n"); + print(" top ", addr.top, "\n"); + print(" bottom ", addr.bottom, "\n"); + print(" left ", addr.left, "\n"); + print(" width ", addr.width, "\n"); +}; + +sizeofSubfont = 20; +aggr Subfont +{ + 'X' 0 name; + 'd' 4 n; + 'b' 6 height; + 'C' 7 ascent; + 'A' Fontchar 8 info; + 'A' Image 12 bits; + 'D' 16 ref; +}; + +defn +Subfont(addr) { + complex Subfont addr; + print(" name ", addr.name\X, "\n"); + print(" n ", addr.n, "\n"); + print(" height ", addr.height, "\n"); + print(" ascent ", addr.ascent, "\n"); + print(" info ", addr.info\X, "\n"); + print(" bits ", addr.bits\X, "\n"); + print(" ref ", addr.ref, "\n"); +}; + +LOG2NFCACHE = 6; +NFCACHE = 64; +NFLOOK = 5; +NFSUBF = 2; +MAXFCACHE = 1029; +MAXSUBF = 50; +DSUBF = 4; +SUBFAGE = 10000; +CACHEAGE = 10000; +sizeofCachefont = 20; +aggr Cachefont +{ + 'U' 0 min; + 'U' 4 max; + 'D' 8 offset; + 'X' 12 name; + 'X' 16 subfontname; +}; + +defn +Cachefont(addr) { + complex Cachefont addr; + print(" min ", addr.min, "\n"); + print(" max ", addr.max, "\n"); + print(" offset ", addr.offset, "\n"); + print(" name ", addr.name\X, "\n"); + print(" subfontname ", addr.subfontname\X, "\n"); +}; + +sizeofCacheinfo = 12; +aggr Cacheinfo +{ + 'u' 0 x; + 'b' 2 width; + 'C' 3 left; + 'U' 4 value; + 'u' 8 age; +}; + +defn +Cacheinfo(addr) { + complex Cacheinfo addr; + print(" x ", addr.x, "\n"); + print(" width ", addr.width, "\n"); + print(" left ", addr.left, "\n"); + print(" value ", addr.value, "\n"); + print(" age ", addr.age, "\n"); +}; + +sizeofCachesubf = 12; +aggr Cachesubf +{ + 'U' 0 age; + 'A' Cachefont 4 cf; + 'A' Subfont 8 f; +}; + +defn +Cachesubf(addr) { + complex Cachesubf addr; + print(" age ", addr.age, "\n"); + print(" cf ", addr.cf\X, "\n"); + print(" f ", addr.f\X, "\n"); +}; + +sizeofFont = 48; +aggr Font +{ + 'X' 0 name; + 'A' Display 4 display; + 'd' 8 height; + 'd' 10 ascent; + 'd' 12 width; + 'd' 14 nsub; + 'U' 16 age; + 'D' 20 maxdepth; + 'D' 24 ncache; + 'D' 28 nsubf; + 'A' Cacheinfo 32 cache; + 'A' Cachesubf 36 subf; + 'A' Cachefont 40 sub; + 'A' Image 44 cacheimage; +}; + +defn +Font(addr) { + complex Font addr; + print(" name ", addr.name\X, "\n"); + print(" display ", addr.display\X, "\n"); + print(" height ", addr.height, "\n"); + print(" ascent ", addr.ascent, "\n"); + print(" width ", addr.width, "\n"); + print(" nsub ", addr.nsub, "\n"); + print(" age ", addr.age, "\n"); + print(" maxdepth ", addr.maxdepth, "\n"); + print(" ncache ", addr.ncache, "\n"); + print(" nsubf ", addr.nsubf, "\n"); + print(" cache ", addr.cache\X, "\n"); + print(" subf ", addr.subf\X, "\n"); + print(" sub ", addr.sub\X, "\n"); + print(" cacheimage ", addr.cacheimage\X, "\n"); +}; + +complex Point ZP; +complex Rectangle ZR; +complex Display display; +complex Font font; +complex Image screen; +complex Screen _screen; +complex Display display; +complex Font font; +complex Image screen; +complex Screen _screen; +complex Display drawshutdown:d; +complex Subfont geninitdraw:df; +complex Display gengetwindow:d; +complex Image gengetwindow:winp; +complex Screen gengetwindow:scrp; +complex Image gengetwindow:image; +complex Rectangle gengetwindow:r; +complex Display getwindow:d; +complex Display initdisplay:disp; +complex Dir initdisplay:dir; +complex Image initdisplay:image; +complex Display closedisplay:disp; +complex Display _closedisplay:disp; +complex Display lockdisplay:disp; +complex Display unlockdisplay:disp; +complex Display drawerror:d; +complex Display doflush:d; +complex Display flushimage:d; +complex Display bufimage:d; --- /sys/src/libdraw/stringwidth.c Fri Nov 29 04:39:41 2013 +++ /sys/src/libdraw/stringwidth.c Fri Nov 29 04:39:41 2013 @@ -12,6 +12,7 @@ Rune rune, **rptr; char *subfontname, **sptr; Font *def; + Subfont *sf; if(s == nil){ s = ""; @@ -23,6 +24,7 @@ rptr = nil; }else rptr = &r; + sf = nil; twid = 0; while(len>0 && (*s || *r)){ max = Max; @@ -43,7 +45,8 @@ return twid; } if(subfontname){ - if(_getsubfont(f->display, subfontname) == 0){ + freesubfont(sf); + if((sf=_getsubfont(f->display, subfontname)) == 0){ def = f->display->defaultfont; if(def && f!=def) f = def; @@ -56,6 +59,7 @@ twid += wid; len -= l; } + freesubfont(sf); return twid; }