ref: 368477b5658d7c0a00b3261b212f97fd7deb4218
dir: /test.h/
static void
printusage(Otfile *f)
{
f->print(f->aux, "usage: %s [-i GLYPH_ID] [-p PPEM [-g PIXELS] [-m ... -[-H GLYPH_ID]]] font.otf\n", argv0);
f->print(f->aux, " -i: specifies a single glyph id\n");
f->print(f->aux, " -p: draw (of size in pixels per em) and write the image to stdout\n");
f->print(f->aux, " -g: gap (in pixels) to add to every border of a glyph\n");
f->print(f->aux, " -m: print out glyph ids or render them all as a map (with -p)\n");
f->print(f->aux, " -H: highlight a specific glyph in the map by its ID\n");
f->print(f->aux, "Specifying -m more than once adds guide lines\n");
f->print(f->aux, "Specifying -m more than twice makes empty pixels filled out\n");
}
static int gap, gind = -1, map, ppem, highlight = -1;
static int
dumpmap(Otfile *f, GlyfImage *im, int n)
{
int x, y, i, j, t, maxh, prebase, postbase, d, border;
int gap, total, mid, npix, bw, bh, lines, fill;
u8int *b;
total = 0;
maxh = 0;
gap = 1;
lines = map > 1;
fill = map > 2;
for(i = 0; i < n; i++){
if(im[i].b == nil)
continue;
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;
npix *= 2;
bh *= 2;
npix += bw*gap;
if((b = malloc(npix*3)) == nil)
return -1;
memset(b, 0xff, npix*3);
y = gap;
for(i = 0; i < n;){
prebase = postbase = 0;
for(x = 0, j = i; j < n; j++){
if(im[j].b == nil)
continue;
x += im[j].w + gap;
if(x > bw)
break;
if(prebase < im[j].h+im[j].baseline)
prebase = im[j].h+im[j].baseline;
if(im[j].baseline < 0 && postbase < -im[j].baseline)
postbase = -im[j].baseline;
}
maxh = prebase + postbase;
if(j == i || y+maxh > bh)
break;
for(x = 0; i < j; i++){
if(im[i].b == nil)
continue;
u8int *lt = b + ((y + prebase - (im[i].h+im[i].baseline))*bw + x)*3;
x += im[i].w + gap;
for(d = 0; d < im[i].h; d++, lt += bw*3){
for(t = 0; t < im[i].w; t++){
u8int r, g, b;
r = g = b = im[i].b[d*im[i].w + t];
border = d == 0 || t == 0 || t == im[i].w-1 || d == im[i].h-1;
if((lines || highlight == i) && g == 0xff && (d == im[i].h+im[i].baseline)){
g = 0;
b = 0;
}else if((lines || highlight == i) && g == 0xff && (fill || border)){
if(fill && !border){
r = 0xff;
g = 0x80;
b = 0xff;
}else if(border){
r = 0;
b = 0;
}
}
if(r != 0xff || g != 0xff || b != 0xff){
lt[t*3+0] = b;
lt[t*3+1] = g;
lt[t*3+2] = r;
}
}
}
}
y += maxh + gap;
}
f->print(f->aux, "%11s %11d %11d %11d %11d ", "r8g8b8", 0, 0, bw, y);
f->write(f->aux, b, bw*y*3);
free(b);
return 0;
}
static int
process(Otfile *in, Otfile *out)
{
GlyfImage *im;
int i, n;
Glyf *g;
Otf *o;
if((o = otfopen(in)) == nil)
return -1;
n = otfglyfnum(o);
if(gind >= n){
werrstr("out of range (max %d)", n-1);
goto glypherr;
}
if(map && gind < 0){
im = ppem > 0 ? calloc(n, sizeof(*im)) : nil;
for(i = 0; i < n; i++){
if((g = otfglyf(o, i)) == nil){
gind = i;
glypherr:
werrstr("glyph %d: %r", gind);
return -1;
}
if(ppem > 0 && g->numberOfContours != 0){
if(otfdrawglyf(o, g, ppem, gap, im+i) != 0)
goto glypherr;
}else if(ppem <= 0){
out->print(out->aux, "%d (%s):\n", i,
g->simple ? "simple" : (g->component ? "component" : "empty"));
print_Glyf(out, indentΔ, o, g);
}
free(g);
}
if(ppem > 0){
if(dumpmap(out, im, n) != 0)
return -1;
for(i = 0; i < n; i++)
free(im[i].b);
free(im);
}
}else if(gind < 0){
otfprint(o, out, indentΔ);
}else{
if((g = otfglyf(o, gind)) == nil){
goto glypherr;
}else if(ppem > 0){
GlyfImage im;
if(otfdrawglyf(o, g, ppem, gap, &im) != 0)
goto glypherr;
if(dumpmap(out, &im, 1) != 0)
return -1;
free(im.b);
}else{
out->print(out->aux, "\n%d:\n", gind);
print_Glyf(out, indentΔ, o, g);
}
}
otfclose(o);
return 0;
}
#define parseoptions() \
ARGBEGIN{ \
case 'g': \
gap = strtol(EARGF(usage(&out)), nil, 0); \
break; \
case 'H': \
highlight = strtol(EARGF(usage(&out)), nil, 0); \
break; \
case 'i': \
gind = strtol(EARGF(usage(&out)), nil, 0); \
break; \
case 'm': \
map++; \
break; \
case 'p': \
ppem = strtol(EARGF(usage(&out)), nil, 0); \
break; \
default: \
usage(&out); \
}ARGEND \
if(argc != 1) \
usage(&out);