#include #include #include #include #include #include #include "common.h" enum { Fmtk1, Fmtk8, }; static char *sfmt[] = { [Fmtk1] = "k1", [Fmtk8] = "k8", }; int savesubfont(uint8_t *pix, int w, int h, int ascent, int scale, Fontchar *cs, int nc, char *path) { int f, sz, i, fmt, pixsz, x, y; uint8_t *b, *p, t; Fontchar *c; if(h < 1){ fprintf(stderr, "%s: zero height subfont\n", path); return -1; } for(y = h-1; y > 0; y--){ for(x = 0; x < w; x++){ if(pix[y*w + x] != 0) break; } if(x < w) break; } h = y+1; if(scale > 1){ b = p = malloc(w*scale*h*scale); for(y = 0; y < h; y++){ for(x = 0; x < w; x++){ for(i = 0; i < scale; i++) *p++ = pix[y*w + x]; } for(i = 0; i < scale-1; i++){ memmove(p, p-w*scale, w*scale); p += w*scale; } } pix = b; w *= scale; h *= scale; ascent *= scale; } pixsz = w*h; fmt = Fmtk8; for(i = 0; i < pixsz && (pix[i] == 0x00 || pix[i] == 0xff); i++); if(i == pixsz){ pixsz = 0; fmt = Fmtk1; p = pix; for(y = 0; y < h; y++){ b = pix + y*w; for(x = 0; x < w; x += 8){ t = 0; for(i = 0; i < 8; i++){ t <<= 1; if(x+i < w) t |= (*b++ & 1); } *p++ = t; pixsz++; } } } b = NULL; sz = 6*(nc+1); if((f = open(path, O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0644)) < 0 || dprintf(f, "%11s %11d %11d %11d %11d ", sfmt[fmt], 0, 0, w, h) < 0 || write(f, pix, pixsz) != pixsz || dprintf(f, "%11d %11d %11d ", nc, h, ascent) < 0 || (b = p = malloc(sz)) == NULL) goto err; for(i = 0; i < nc; i++){ c = cs+i; *p++ = (c->x * scale) >> 0; *p++ = (c->x * scale) >> 8; *p++ = c->top * scale; *p++ = c->bottom * scale; *p++ = c->left * scale; *p++ = c->width * scale; } *p++ = w; *p++ = w >> 8; *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; if(write(f, b, sz) != sz) goto err; free(b); if(scale > 1) free(pix); close(f); return 0; err: perror(path); if(f >= 0) close(f); free(b); if(scale > 1) free(pix); return -1; }