ref: 5877598b3b65ae59ec9d1447e222af4b1e848911
dir: /plan9/test.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "otf.h" static void dumpmap(Biobuf *out, GlyfImage *im, int n) { #define gap 1 int total, mid, npix, bw, bh, x, y, i, maxh, d; u8int *b; total = 0; maxh = 0; for(i = 0; i < n; i++){ if(maxh < im[i].h) maxh = im[i].h; total += im[i].w; } mid = total / n; npix = (mid+gap)*(maxh+gap)*n; bh = sqrt(npix); bw = npix/bh; bh *= 1.5; npix *= 1.5; npix += bw*gap; if((b = malloc(npix)) == nil) sysfatal("no memory"); memset(b, 0xff, npix); x = y = gap; for(i = 0; i < n; i++){ if((bw-x) < im[i].w+gap){ y += maxh + gap; x = gap; } if((bh-y) < maxh+gap) continue; for(d = 0; d < im[i].h; d++) memcpy(b + (maxh - im[i].h + y + im[i].baseline + d)*bw + x, im[i].b + d*im[i].w, im[i].w); x += im[i].w + gap; } Bprint(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+maxh*2+gap); Bwrite(out, b, bw*(y+maxh*2+gap)); free(b); } static int otfseek(void *aux, int off, int whence) { return Bseek(aux, off, whence); } static int otfread(void *aux, void *dst, int sz) { return Bread(aux, dst, sz); } static void usage(void) { fprint(2, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-p PPM] font.otf ...\n", argv0); fprint(2, " -g: specifies a single glyph id\n"); fprint(2, " -G: print out glyph ids, only ones that can be drawn atm (no compound yet)\n"); fprint(2, " -p: draw (of size in pixels per em) and write the image to stdout\n"); exits("usage"); } void main(int argc, char **argv) { int i, gi, G, ppem; Otfile in, out; Otf *o; gi = -1; G = 0; ppem = 0; ARGBEGIN{ case 'g': gi = strtol(EARGF(usage()), nil, 0); break; case 'G': G++; break; case 'p': ppem = strtol(EARGF(usage()), nil, 0); break; default: usage(); }ARGEND in.seek = otfseek; in.read = otfread; out.print = (void*)Bprint; out.aux = Bfdopen(1, OWRITE); for(i = 0; i < argc; i++){ if((in.aux = Bopen(argv[i], OREAD)) == nil || (o = otfopen(&in)) == nil){ fprint(2, "%r\n"); continue; } if(ppem <= 0) Bprint(out.aux, "%s\n", argv[i]); if(G && gi < 0){ int i, n = otfglyfnum(o); GlyfImage *im = ppem > 0 ? calloc(n, sizeof(*im)) : nil; for(i = 0; i < n; i++){ Glyf *g = otfglyf(o, i); if(g == nil) sysfatal("glyf %d: %r", i); if(ppem > 0 && g->numberOfContours != 0){ if(otfdrawglyf(o, g, ppem, &im[i]) != 0) sysfatal("glyf %d: %r", i); }else if(ppem <= 0){ Bprint(out.aux, "%d (%s):\n", i, g->simple ? "simple" : (g->component ? "component" : "empty")); print_Glyf(&out, indentΔ, o, g); } free(g); } if(ppem > 0){ dumpmap(out.aux, im, n); for(i = 0; i < n; i++) free(im[i].b); free(im); }else{ fprint(2, "\n"); } }else if(gi < 0){ otfprint(o, &out, indentΔ); }else{ int n = otfglyfnum(o); if(gi >= n) sysfatal("glyph %d out of range, max %d", gi, n-1); Glyf *g = otfglyf(o, gi); if(g == nil){ fprint(2, "%d: %r\n", gi); }else if(ppem > 0){ GlyfImage im; if(otfdrawglyf(o, g, ppem, &im) != 0) sysfatal("%r"); fprint(1, "%11s %11d %11d %11d %11d ", "k8", 0, 0, im.w, im.h); write(1, im.b, im.w*im.h); free(im.b); }else{ Bprint(out.aux, "\n%d:\n", gi); print_Glyf(&out, indentΔ, o, g); } } otfclose(o); Bterm(in.aux); } Bterm(out.aux); exits(nil); }