17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier static int fontresize(Font*, int, int, int);
67dd7cddfSDavid du Colombier static int freeup(Font*);
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier #define PJW 0 /* use NUL==pjw for invisible characters */
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier int
cachechars(Font * f,char ** ss,Rune ** rr,ushort * cp,int max,int * wp,char ** subfontname)117dd7cddfSDavid du Colombier cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **subfontname)
127dd7cddfSDavid du Colombier {
137dd7cddfSDavid du Colombier int i, th, sh, h, ld, w, rw, wid, nc;
147dd7cddfSDavid du Colombier char *sp;
157dd7cddfSDavid du Colombier Rune r, *rp, vr;
167dd7cddfSDavid du Colombier ulong a;
177dd7cddfSDavid du Colombier Cacheinfo *c, *tc, *ec;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier if(ss){
207dd7cddfSDavid du Colombier sp = *ss;
217dd7cddfSDavid du Colombier rp = L"";
227dd7cddfSDavid du Colombier }else{
237dd7cddfSDavid du Colombier sp = "";
247dd7cddfSDavid du Colombier rp = *rr;
257dd7cddfSDavid du Colombier }
267dd7cddfSDavid du Colombier wid = 0;
277dd7cddfSDavid du Colombier *subfontname = 0;
28ac1798d1SDavid du Colombier for(i=0; i<max && (*sp || *rp); sp+=w, rp+=rw){
297dd7cddfSDavid du Colombier if(ss){
307dd7cddfSDavid du Colombier r = *(uchar*)sp;
317dd7cddfSDavid du Colombier if(r < Runeself)
327dd7cddfSDavid du Colombier w = 1;
337dd7cddfSDavid du Colombier else{
347dd7cddfSDavid du Colombier w = chartorune(&vr, sp);
357dd7cddfSDavid du Colombier r = vr;
367dd7cddfSDavid du Colombier }
377dd7cddfSDavid du Colombier rw = 0;
387dd7cddfSDavid du Colombier }else{
397dd7cddfSDavid du Colombier r = *rp;
407dd7cddfSDavid du Colombier w = 0;
417dd7cddfSDavid du Colombier rw = 1;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier sh = (17 * (uint)r) & (f->ncache-NFLOOK-1);
457dd7cddfSDavid du Colombier c = &f->cache[sh];
467dd7cddfSDavid du Colombier ec = c+NFLOOK;
477dd7cddfSDavid du Colombier h = sh;
487dd7cddfSDavid du Colombier while(c < ec){
497dd7cddfSDavid du Colombier if(c->value==r && c->age)
507dd7cddfSDavid du Colombier goto Found;
517dd7cddfSDavid du Colombier c++;
527dd7cddfSDavid du Colombier h++;
537dd7cddfSDavid du Colombier }
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier /*
567dd7cddfSDavid du Colombier * Not found; toss out oldest entry
577dd7cddfSDavid du Colombier */
587dd7cddfSDavid du Colombier a = ~0;
597dd7cddfSDavid du Colombier th = sh;
607dd7cddfSDavid du Colombier tc = &f->cache[th];
617dd7cddfSDavid du Colombier while(tc < ec){
627dd7cddfSDavid du Colombier if(tc->age < a){
637dd7cddfSDavid du Colombier a = tc->age;
647dd7cddfSDavid du Colombier h = th;
657dd7cddfSDavid du Colombier c = tc;
667dd7cddfSDavid du Colombier }
677dd7cddfSDavid du Colombier tc++;
687dd7cddfSDavid du Colombier th++;
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier if(a && (f->age-a)<500){ /* kicking out too recent; resize */
727dd7cddfSDavid du Colombier nc = 2*(f->ncache-NFLOOK) + NFLOOK;
737dd7cddfSDavid du Colombier if(nc <= MAXFCACHE){
747dd7cddfSDavid du Colombier if(i == 0)
757dd7cddfSDavid du Colombier fontresize(f, f->width, nc, f->maxdepth);
767dd7cddfSDavid du Colombier /* else flush first; retry will resize */
777dd7cddfSDavid du Colombier break;
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier if(c->age == f->age) /* flush pending string output */
827dd7cddfSDavid du Colombier break;
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier ld = loadchar(f, r, c, h, i, subfontname);
857dd7cddfSDavid du Colombier if(ld <= 0){
867dd7cddfSDavid du Colombier if(ld == 0)
877dd7cddfSDavid du Colombier continue;
887dd7cddfSDavid du Colombier break;
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier c = &f->cache[h]; /* may have reallocated f->cache */
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier Found:
937dd7cddfSDavid du Colombier wid += c->width;
947dd7cddfSDavid du Colombier c->age = f->age;
957dd7cddfSDavid du Colombier cp[i] = h;
967dd7cddfSDavid du Colombier i++;
977dd7cddfSDavid du Colombier }
987dd7cddfSDavid du Colombier if(ss)
997dd7cddfSDavid du Colombier *ss = sp;
1007dd7cddfSDavid du Colombier else
1017dd7cddfSDavid du Colombier *rr = rp;
1027dd7cddfSDavid du Colombier *wp = wid;
1037dd7cddfSDavid du Colombier return i;
1047dd7cddfSDavid du Colombier }
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier void
agefont(Font * f)1077dd7cddfSDavid du Colombier agefont(Font *f)
1087dd7cddfSDavid du Colombier {
1097dd7cddfSDavid du Colombier Cacheinfo *c, *ec;
1107dd7cddfSDavid du Colombier Cachesubf *s, *es;
1117dd7cddfSDavid du Colombier
1127dd7cddfSDavid du Colombier f->age++;
1137dd7cddfSDavid du Colombier if(f->age == 65536){
1147dd7cddfSDavid du Colombier /*
1157dd7cddfSDavid du Colombier * Renormalize ages
1167dd7cddfSDavid du Colombier */
1177dd7cddfSDavid du Colombier c = f->cache;
1187dd7cddfSDavid du Colombier ec = c+f->ncache;
1197dd7cddfSDavid du Colombier while(c < ec){
1207dd7cddfSDavid du Colombier if(c->age){
1217dd7cddfSDavid du Colombier c->age >>= 2;
1227dd7cddfSDavid du Colombier c->age++;
1237dd7cddfSDavid du Colombier }
1247dd7cddfSDavid du Colombier c++;
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier s = f->subf;
1277dd7cddfSDavid du Colombier es = s+f->nsubf;
1287dd7cddfSDavid du Colombier while(s < es){
1297dd7cddfSDavid du Colombier if(s->age){
1307dd7cddfSDavid du Colombier if(s->age<SUBFAGE && s->cf->name != nil){
1317dd7cddfSDavid du Colombier /* clean up */
132*6bbfed0dSDavid du Colombier if(display &&
133*6bbfed0dSDavid du Colombier s->f != display->defaultsubfont)
1347dd7cddfSDavid du Colombier freesubfont(s->f);
1357dd7cddfSDavid du Colombier s->cf = nil;
1367dd7cddfSDavid du Colombier s->f = nil;
1377dd7cddfSDavid du Colombier s->age = 0;
1387dd7cddfSDavid du Colombier }else{
1397dd7cddfSDavid du Colombier s->age >>= 2;
1407dd7cddfSDavid du Colombier s->age++;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier s++;
1447dd7cddfSDavid du Colombier }
1457dd7cddfSDavid du Colombier f->age = (65536>>2) + 1;
1467dd7cddfSDavid du Colombier }
1477dd7cddfSDavid du Colombier }
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier static Subfont*
cf2subfont(Cachefont * cf,Font * f)1507dd7cddfSDavid du Colombier cf2subfont(Cachefont *cf, Font *f)
1517dd7cddfSDavid du Colombier {
1529a747e4fSDavid du Colombier int depth;
1537dd7cddfSDavid du Colombier char *name;
1547dd7cddfSDavid du Colombier Subfont *sf;
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier name = cf->subfontname;
1577dd7cddfSDavid du Colombier if(name == nil){
1582df1634fSDavid du Colombier if(f->display && f->display->screenimage)
1599a747e4fSDavid du Colombier depth = f->display->screenimage->depth;
1602df1634fSDavid du Colombier else
161b8661318SDavid du Colombier depth = 8;
1629a747e4fSDavid du Colombier name = subfontname(cf->name, f->name, depth);
1637dd7cddfSDavid du Colombier if(name == nil)
1647dd7cddfSDavid du Colombier return nil;
1657dd7cddfSDavid du Colombier cf->subfontname = name;
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier sf = lookupsubfont(f->display, name);
1687dd7cddfSDavid du Colombier return sf;
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier /* return 1 if load succeeded, 0 if failed, -1 if must retry */
1727dd7cddfSDavid du Colombier int
loadchar(Font * f,Rune r,Cacheinfo * c,int h,int noflush,char ** subfontname)1737dd7cddfSDavid du Colombier loadchar(Font *f, Rune r, Cacheinfo *c, int h, int noflush, char **subfontname)
1747dd7cddfSDavid du Colombier {
1757dd7cddfSDavid du Colombier int i, oi, wid, top, bottom;
1767dd7cddfSDavid du Colombier Rune pic;
1777dd7cddfSDavid du Colombier Fontchar *fi;
1787dd7cddfSDavid du Colombier Cachefont *cf;
1797dd7cddfSDavid du Colombier Cachesubf *subf, *of;
1807dd7cddfSDavid du Colombier uchar *b;
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier pic = r;
1837dd7cddfSDavid du Colombier Again:
1847dd7cddfSDavid du Colombier for(i=0; i<f->nsub; i++){
1857dd7cddfSDavid du Colombier cf = f->sub[i];
1867dd7cddfSDavid du Colombier if(cf->min<=pic && pic<=cf->max)
1877dd7cddfSDavid du Colombier goto Found;
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier TryPJW:
1907dd7cddfSDavid du Colombier if(pic != PJW){
1917dd7cddfSDavid du Colombier pic = PJW;
1927dd7cddfSDavid du Colombier goto Again;
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier return 0;
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier Found:
1977dd7cddfSDavid du Colombier /*
1987dd7cddfSDavid du Colombier * Choose exact or oldest
1997dd7cddfSDavid du Colombier */
2007dd7cddfSDavid du Colombier oi = 0;
2017dd7cddfSDavid du Colombier subf = &f->subf[0];
2027dd7cddfSDavid du Colombier for(i=0; i<f->nsubf; i++){
2037dd7cddfSDavid du Colombier if(cf == subf->cf)
2047dd7cddfSDavid du Colombier goto Found2;
2057dd7cddfSDavid du Colombier if(subf->age < f->subf[oi].age)
2067dd7cddfSDavid du Colombier oi = i;
2077dd7cddfSDavid du Colombier subf++;
2087dd7cddfSDavid du Colombier }
2097dd7cddfSDavid du Colombier subf = &f->subf[oi];
2107dd7cddfSDavid du Colombier
2117dd7cddfSDavid du Colombier if(subf->f){
2127dd7cddfSDavid du Colombier if(f->age-subf->age>SUBFAGE || f->nsubf>MAXSUBF){
2137dd7cddfSDavid du Colombier Toss:
2147dd7cddfSDavid du Colombier /* ancient data; toss */
2157dd7cddfSDavid du Colombier freesubfont(subf->f);
2167dd7cddfSDavid du Colombier subf->cf = nil;
2177dd7cddfSDavid du Colombier subf->f = nil;
2187dd7cddfSDavid du Colombier subf->age = 0;
2197dd7cddfSDavid du Colombier }else{ /* too recent; grow instead */
2207dd7cddfSDavid du Colombier of = f->subf;
2217dd7cddfSDavid du Colombier f->subf = malloc((f->nsubf+DSUBF)*sizeof *subf);
2227dd7cddfSDavid du Colombier if(f->subf == nil){
2237dd7cddfSDavid du Colombier f->subf = of;
2247dd7cddfSDavid du Colombier goto Toss;
2257dd7cddfSDavid du Colombier }
2267dd7cddfSDavid du Colombier memmove(f->subf, of, (f->nsubf+DSUBF)*sizeof *subf);
2277dd7cddfSDavid du Colombier memset(f->subf+f->nsubf, 0, DSUBF*sizeof *subf);
2287dd7cddfSDavid du Colombier subf = &f->subf[f->nsubf];
2297dd7cddfSDavid du Colombier f->nsubf += DSUBF;
2307dd7cddfSDavid du Colombier free(of);
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier subf->age = 0;
2347dd7cddfSDavid du Colombier subf->cf = nil;
2357dd7cddfSDavid du Colombier subf->f = cf2subfont(cf, f);
2367dd7cddfSDavid du Colombier if(subf->f == nil){
23780ee5cbfSDavid du Colombier if(cf->subfontname == nil)
23880ee5cbfSDavid du Colombier goto TryPJW;
2397dd7cddfSDavid du Colombier *subfontname = cf->subfontname;
2407dd7cddfSDavid du Colombier return -1;
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier subf->cf = cf;
244b8661318SDavid du Colombier if(subf->f->ascent > f->ascent && f->display){
2457dd7cddfSDavid du Colombier /* should print something? this is a mistake in the font file */
2467dd7cddfSDavid du Colombier /* must prevent c->top from going negative when loading cache */
2477dd7cddfSDavid du Colombier Image *b;
2487dd7cddfSDavid du Colombier int d, t;
2497dd7cddfSDavid du Colombier d = subf->f->ascent - f->ascent;
2507dd7cddfSDavid du Colombier b = subf->f->bits;
2517dd7cddfSDavid du Colombier draw(b, b->r, b, nil, addpt(b->r.min, Pt(0, d)));
2527dd7cddfSDavid du Colombier draw(b, Rect(b->r.min.x, b->r.max.y-d, b->r.max.x, b->r.max.y), f->display->black, nil, b->r.min);
2537dd7cddfSDavid du Colombier for(i=0; i<subf->f->n; i++){
2547dd7cddfSDavid du Colombier t = subf->f->info[i].top-d;
2557dd7cddfSDavid du Colombier if(t < 0)
2567dd7cddfSDavid du Colombier t = 0;
2577dd7cddfSDavid du Colombier subf->f->info[i].top = t;
2587dd7cddfSDavid du Colombier t = subf->f->info[i].bottom-d;
2597dd7cddfSDavid du Colombier if(t < 0)
2607dd7cddfSDavid du Colombier t = 0;
2617dd7cddfSDavid du Colombier subf->f->info[i].bottom = t;
2627dd7cddfSDavid du Colombier }
2637dd7cddfSDavid du Colombier subf->f->ascent = f->ascent;
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier
2667dd7cddfSDavid du Colombier Found2:
2677dd7cddfSDavid du Colombier subf->age = f->age;
2687dd7cddfSDavid du Colombier
2691517f4bcSDavid du Colombier /* possible overflow here, but works out okay */
2707dd7cddfSDavid du Colombier pic += cf->offset;
2711517f4bcSDavid du Colombier pic -= cf->min;
2721517f4bcSDavid du Colombier if(pic >= subf->f->n)
2737dd7cddfSDavid du Colombier goto TryPJW;
2741517f4bcSDavid du Colombier fi = &subf->f->info[pic];
2757dd7cddfSDavid du Colombier if(fi->width == 0)
2767dd7cddfSDavid du Colombier goto TryPJW;
2777dd7cddfSDavid du Colombier wid = (fi+1)->x - fi->x;
2787dd7cddfSDavid du Colombier if(f->width < wid || f->width == 0 || f->maxdepth < subf->f->bits->depth){
2797dd7cddfSDavid du Colombier /*
2807dd7cddfSDavid du Colombier * Flush, free, reload (easier than reformatting f->b)
2817dd7cddfSDavid du Colombier */
2827dd7cddfSDavid du Colombier if(noflush)
2837dd7cddfSDavid du Colombier return -1;
2847dd7cddfSDavid du Colombier if(f->width < wid)
2857dd7cddfSDavid du Colombier f->width = wid;
2867dd7cddfSDavid du Colombier if(f->maxdepth < subf->f->bits->depth)
2877dd7cddfSDavid du Colombier f->maxdepth = subf->f->bits->depth;
2887dd7cddfSDavid du Colombier i = fontresize(f, f->width, f->ncache, f->maxdepth);
2897dd7cddfSDavid du Colombier if(i <= 0)
2907dd7cddfSDavid du Colombier return i;
2917dd7cddfSDavid du Colombier /* c is still valid as didn't reallocate f->cache */
2927dd7cddfSDavid du Colombier }
2937dd7cddfSDavid du Colombier c->value = r;
2947dd7cddfSDavid du Colombier top = fi->top + (f->ascent-subf->f->ascent);
2957dd7cddfSDavid du Colombier bottom = fi->bottom + (f->ascent-subf->f->ascent);
2967dd7cddfSDavid du Colombier c->width = fi->width;
2977dd7cddfSDavid du Colombier c->x = h*f->width;
2987dd7cddfSDavid du Colombier c->left = fi->left;
299b8661318SDavid du Colombier if(f->display == nil)
300b8661318SDavid du Colombier return 1;
3017dd7cddfSDavid du Colombier flushimage(f->display, 0); /* flush any pending errors */
3027dd7cddfSDavid du Colombier b = bufimage(f->display, 37);
3037dd7cddfSDavid du Colombier if(b == 0)
3047dd7cddfSDavid du Colombier return 0;
3057dd7cddfSDavid du Colombier b[0] = 'l';
3067dd7cddfSDavid du Colombier BPLONG(b+1, f->cacheimage->id);
3077dd7cddfSDavid du Colombier BPLONG(b+5, subf->f->bits->id);
3087dd7cddfSDavid du Colombier BPSHORT(b+9, c-f->cache);
3097dd7cddfSDavid du Colombier BPLONG(b+11, c->x);
3107dd7cddfSDavid du Colombier BPLONG(b+15, top);
3117dd7cddfSDavid du Colombier BPLONG(b+19, c->x+((fi+1)->x-fi->x));
3127dd7cddfSDavid du Colombier BPLONG(b+23, bottom);
3137dd7cddfSDavid du Colombier BPLONG(b+27, fi->x);
3147dd7cddfSDavid du Colombier BPLONG(b+31, fi->top);
3157dd7cddfSDavid du Colombier b[35] = fi->left;
3167dd7cddfSDavid du Colombier b[36] = fi->width;
3177dd7cddfSDavid du Colombier return 1;
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier
3207dd7cddfSDavid du Colombier /* release all subfonts, return number freed */
3217dd7cddfSDavid du Colombier static
3227dd7cddfSDavid du Colombier int
freeup(Font * f)3237dd7cddfSDavid du Colombier freeup(Font *f)
3247dd7cddfSDavid du Colombier {
3257dd7cddfSDavid du Colombier Cachesubf *s, *es;
3267dd7cddfSDavid du Colombier int nf;
3277dd7cddfSDavid du Colombier
3287dd7cddfSDavid du Colombier if(f->sub[0]->name == nil) /* font from mkfont; don't free */
3297dd7cddfSDavid du Colombier return 0;
3307dd7cddfSDavid du Colombier s = f->subf;
3317dd7cddfSDavid du Colombier es = s+f->nsubf;
3327dd7cddfSDavid du Colombier nf = 0;
3337dd7cddfSDavid du Colombier while(s < es){
3347dd7cddfSDavid du Colombier if(s->age){
3357dd7cddfSDavid du Colombier freesubfont(s->f);
3367dd7cddfSDavid du Colombier s->cf = nil;
3377dd7cddfSDavid du Colombier s->f = nil;
3387dd7cddfSDavid du Colombier s->age = 0;
3397dd7cddfSDavid du Colombier nf++;
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier s++;
3427dd7cddfSDavid du Colombier }
3437dd7cddfSDavid du Colombier return nf;
3447dd7cddfSDavid du Colombier }
3457dd7cddfSDavid du Colombier
3467dd7cddfSDavid du Colombier /* return whether resize succeeded && f->cache is unchanged */
3477dd7cddfSDavid du Colombier static int
fontresize(Font * f,int wid,int ncache,int depth)3487dd7cddfSDavid du Colombier fontresize(Font *f, int wid, int ncache, int depth)
3497dd7cddfSDavid du Colombier {
3507dd7cddfSDavid du Colombier Cacheinfo *i;
3517dd7cddfSDavid du Colombier int ret;
3527dd7cddfSDavid du Colombier Image *new;
3537dd7cddfSDavid du Colombier uchar *b;
3547dd7cddfSDavid du Colombier Display *d;
3557dd7cddfSDavid du Colombier
3567dd7cddfSDavid du Colombier ret = 0;
3577dd7cddfSDavid du Colombier if(depth <= 0)
3587dd7cddfSDavid du Colombier depth = 1;
3594af5a9a1SDavid du Colombier if(wid <= 0)
3604af5a9a1SDavid du Colombier wid = 1;
3617dd7cddfSDavid du Colombier
362b8661318SDavid du Colombier d = f->display;
363b8661318SDavid du Colombier if(d == nil)
364b8661318SDavid du Colombier goto Nodisplay;
365b8661318SDavid du Colombier
3667dd7cddfSDavid du Colombier new = allocimage(d, Rect(0, 0, ncache*wid, f->height), CHAN1(CGrey, depth), 0, 0);
3677dd7cddfSDavid du Colombier if(new == nil){
3689a747e4fSDavid du Colombier fprint(2, "font cache resize failed: %r\n");
3697dd7cddfSDavid du Colombier abort();
3707dd7cddfSDavid du Colombier goto Return;
3717dd7cddfSDavid du Colombier }
3727dd7cddfSDavid du Colombier flushimage(d, 0); /* flush any pending errors */
3737dd7cddfSDavid du Colombier b = bufimage(d, 1+4+4+1);
3747dd7cddfSDavid du Colombier if(b == 0){
3757dd7cddfSDavid du Colombier freeimage(new);
3767dd7cddfSDavid du Colombier goto Return;
3777dd7cddfSDavid du Colombier }
3787dd7cddfSDavid du Colombier b[0] = 'i';
3797dd7cddfSDavid du Colombier BPLONG(b+1, new->id);
3807dd7cddfSDavid du Colombier BPLONG(b+5, ncache);
3817dd7cddfSDavid du Colombier b[9] = f->ascent;
3827dd7cddfSDavid du Colombier if(flushimage(d, 0) < 0){
3839a747e4fSDavid du Colombier fprint(2, "resize: init failed: %r\n");
3847dd7cddfSDavid du Colombier freeimage(new);
3857dd7cddfSDavid du Colombier goto Return;
3867dd7cddfSDavid du Colombier }
3877dd7cddfSDavid du Colombier freeimage(f->cacheimage);
3887dd7cddfSDavid du Colombier f->cacheimage = new;
389b8661318SDavid du Colombier Nodisplay:
3907dd7cddfSDavid du Colombier f->width = wid;
3917dd7cddfSDavid du Colombier f->maxdepth = depth;
3927dd7cddfSDavid du Colombier ret = 1;
3937dd7cddfSDavid du Colombier if(f->ncache != ncache){
3947dd7cddfSDavid du Colombier i = malloc(ncache*sizeof f->cache[0]);
3957dd7cddfSDavid du Colombier if(i != nil){
3967dd7cddfSDavid du Colombier ret = 0;
3977dd7cddfSDavid du Colombier free(f->cache);
3987dd7cddfSDavid du Colombier f->ncache = ncache;
3997dd7cddfSDavid du Colombier f->cache = i;
4007dd7cddfSDavid du Colombier }
4017dd7cddfSDavid du Colombier /* else just wipe the cache clean and things will be ok */
4027dd7cddfSDavid du Colombier }
4037dd7cddfSDavid du Colombier Return:
4047dd7cddfSDavid du Colombier memset(f->cache, 0, f->ncache*sizeof f->cache[0]);
4057dd7cddfSDavid du Colombier return ret;
4067dd7cddfSDavid du Colombier }
407