History

raster: use ppem for scaling

Sigrid Solveig Haflínudóttir committed 2 years ago

Commit def6bc81 parent c623ba38 files · +105 −84Browse files

Unified · Split

8 files
  1. otf.c.in +6 −0
  2. otf.h.in +1 −1
  3. otf.rkt +1 −1
  4. plan9/otf.c +6 −0
  5. plan9/otf.h +2 −1
  6. plan9/test.c +34 −32
  7. rast.c +18 −14
  8. unix/test.c +37 −35
otf.c.in+6−0
@@ -539,6 +539,10 @@ otfglyf(Otf *o, int index) · 538 unmodified lines
539539 werrstr("no memory");
540540 goto err;
541541 }
542+ if(o->td.head == nil){
543+ werrstr("no head table");
544+ goto err;
545+ }
542546 if(o->td.loca == nil){
543547 werrstr("no loca table");
544548 goto err;
@@ -577,6 +581,8 @@ otfglyf(Otf *o, int index) · 32 unmodified lines
577581 if(read_Glyf(o, g) < 0){
578582 free(g);
579583 g = nil;
584+ }else{
585+ g->unitsPerEm = o->td.head->unitsPerEm;
580586 }
581587 otfpoprange(o);
582588 otfpoprange(o);
otf.h.in+1−1
@@ -80,4 +80,4 @@ void otfclose(Otf *o); · 79 unmodified lines
8080 typedef struct Glyf Glyf;
8181 Glyf *otfglyf(Otf *o, int index);
8282 int otfglyfnum(Otf *o);
83−u8int *otfdrawglyf(Glyf *g, int h, int *wo);
83+u8int *otfdrawglyf(Glyf *g, int ppem, int *wo, int *ho);
otf.rkt+1−1
@@ -209,7 +209,7 @@ · 208 unmodified lines
209209 {int16 xMax}
210210 {int16 yMax}
211211 #:extra
212− (list (cons 'field (list (~a "ComponentGlyph *component;") (~a "SimpleGlyph *simple;")))
212+ (list (cons 'field (list (~a "ComponentGlyph *component;") (~a "SimpleGlyph *simple;") (~a "u16int unitsPerEm;")))
213213 (cons 'read
214214 (list (~a "if(v->numberOfContours < 0 && read_ComponentGlyph(o, &v->component, 0) < 0)")
215215 (~a " goto err;")
plan9/otf.c+6−0
@@ -553,6 +553,10 @@ otfglyf(Otf *o, int index) · 552 unmodified lines
553553 werrstr("no memory");
554554 goto err;
555555 }
556+ if(o->td.head == nil){
557+ werrstr("no head table");
558+ goto err;
559+ }
556560 if(o->td.loca == nil){
557561 werrstr("no loca table");
558562 goto err;
@@ -591,6 +595,8 @@ otfglyf(Otf *o, int index) · 32 unmodified lines
591595 if(read_Glyf(o, g) < 0){
592596 free(g);
593597 g = nil;
598+ }else{
599+ g->unitsPerEm = o->td.head->unitsPerEm;
594600 }
595601 otfpoprange(o);
596602 otfpoprange(o);
plan9/otf.h+2−1
@@ -80,7 +80,7 @@ void otfclose(Otf *o); · 79 unmodified lines
8080 typedef struct Glyf Glyf;
8181 Glyf *otfglyf(Otf *o, int index);
8282 int otfglyfnum(Otf *o);
83−u8int *otfdrawglyf(Glyf *g, int h, int *wo);
83+u8int *otfdrawglyf(Glyf *g, int ppem, int *wo, int *ho);
8484
8585 typedef struct SubHeader SubHeader;
8686 typedef struct MapGroup MapGroup;
@@ -451,6 +451,7 @@ struct Glyf { · 364 unmodified lines
451451 s16int yMax;
452452 ComponentGlyph *component;
453453 SimpleGlyph *simple;
454+ u16int unitsPerEm;
454455 };
455456
456457 int read_Glyf(Otf *o, Glyf *v);
plan9/test.c+34−32
@@ -6,38 +6,43 @@ · 5 unmodified lines
66 typedef struct Image Image;
77
88 struct Image {
9+ int h;
910 int w;
1011 u8int *b;
1112 };
1213
1314 static void
14−fit(u8int *b, int bw, int bh, Image *im, int h, int *x, int *y, int gap)
15+fit(u8int *b, int bw, int bh, Image *im, int maxh, int *x, int *y, int gap)
1516 {
1617 int d;
1718
1819 if((bw-*x) < im->w+gap){
19− *y += h + gap;
20+ *y += maxh + gap;
2021 *x = gap;
2122 }
22− if((bh-*y) < h+gap)
23+ if((bh-*y) < maxh+gap)
2324 return;
24− for(d = 0; d < h; d++)
25+ for(d = 0; d < im->h; d++)
2526 memcpy(b + (*y + d)*bw + *x, im->b + d*im->w, im->w);
2627 *x += im->w + gap;
2728 }
2829
2930 static void
30−dumpmap(Biobuf *out, Image *im, int n, int h)
31+dumpmap(Biobuf *out, Image *im, int n)
3132 {
32−#define gap 2
33− int total, mid, npix, bw, bh, x, y, i;
33+#define gap 1
34+ int total, mid, npix, bw, bh, x, y, i, maxh;
3435 u8int *b;
3536
3637 total = 0;
37− for(i = 0; i < n; i++)
38+ maxh = 0;
39+ for(i = 0; i < n; i++){
40+ if(maxh < im[i].h)
41+ maxh = im[i].h;
3842 total += im[i].w;
43+ }
3944 mid = total / n;
40− npix = (mid+gap)*(h+gap)*n;
45+ npix = (mid+gap)*(maxh+gap)*n;
4146 bh = sqrt(npix);
4247 bw = npix/bh;
4348 bh *= 1.5;
@@ -48,9 +53,9 @@ dumpmap(Biobuf *out, Image *im, int n, int h) · 4 unmodified lines
4853 memset(b, 0xff, npix);
4954 x = y = gap;
5055 for(i = 0; i < n; i++)
51− fit(b, bw, bh, im+i, h, &x, &y, gap);
52− Bprint(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+h+gap);
53− Bwrite(out, b, bw*(y+h+gap));
56+ fit(b, bw, bh, im+i, maxh, &x, &y, gap);
57+ Bprint(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+maxh+gap);
58+ Bwrite(out, b, bw*(y+maxh+gap));
5459 free(b);
5560 }
5661
@@ -69,23 +74,23 @@ otfread(void *aux, void *dst, int sz) · 12 unmodified lines
6974 static void
7075 usage(void)
7176 {
72− fprint(2, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-s PX] font.otf ...\n", argv0);
77+ fprint(2, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-p PPM] font.otf ...\n", argv0);
7378 fprint(2, " -g: specifies a single glyph id\n");
7479 fprint(2, " -G: print out glyph ids, only ones that can be drawn atm (no compound yet)\n");
75− fprint(2, " -s: draw (of size PX) and write the image to stdout\n");
80+ fprint(2, " -p: draw (of size in pixels per em) and write the image to stdout\n");
7681 exits("usage");
7782 }
7883
7984 void
8085 main(int argc, char **argv)
8186 {
82− int i, gi, G, h;
87+ int i, gi, G, ppem;
8388 Otfile in, out;
8489 Otf *o;
8590
8691 gi = -1;
8792 G = 0;
88− h = 0;
93+ ppem = 0;
8994 ARGBEGIN{
9095 case 'g':
9196 gi = strtol(EARGF(usage()), nil, 0);
@@ -93,8 +98,8 @@ main(int argc, char **argv) · 1 unmodified line
9398 case 'G':
9499 G++;
95100 break;
96− case 's':
97− h = strtol(EARGF(usage()), nil, 0);
101+ case 'p':
102+ ppem = strtol(EARGF(usage()), nil, 0);
98103 break;
99104 default:
100105 usage();
@@ -110,30 +115,27 @@ main(int argc, char **argv) · 9 unmodified lines
110115 fprint(2, "%r\n");
111116 continue;
112117 }
113− if(h <= 0)
118+ if(ppem <= 0)
114119 Bprint(out.aux, "%s\n", argv[i]);
115120 if(G && gi < 0){
116121 int i, n = otfglyfnum(o);
117− Image *im = h > 0 ? calloc(n, sizeof(*im)) : nil;
122+ Image *im = ppem > 0 ? calloc(n, sizeof(*im)) : nil;
118123 for(i = 0; i < n; i++){
119124 Glyf *g = otfglyf(o, i);
120125 if(g == nil)
121126 sysfatal("%r");
122− if(h > 0 && g->simple != nil && g->numberOfContours > 0){
123− int w;
124− u8int *b = otfdrawglyf(g, h, &w);
125− if(b == nil)
127+ if(ppem > 0 && g->simple != nil && g->numberOfContours > 0){
128+ im[i].b = otfdrawglyf(g, ppem, &im[i].w, &im[i].h);
129+ if(im[i].b == nil)
126130 sysfatal("%r");
127− im[i].w = w;
128− im[i].b = b;
129− }else if(h <= 0){
131+ }else if(ppem <= 0){
130132 Bprint(out.aux, "%d (%s):\n", i, g->simple ? "simple" : "component");
131133 print_Glyf(&out, indentΔ, o, g);
132134 }
133135 free(g);
134136 }
135− if(h > 0){
136− dumpmap(out.aux, im, n, h);
137+ if(ppem > 0){
138+ dumpmap(out.aux, im, n);
137139 for(i = 0; i < n; i++)
138140 free(im[i].b);
139141 free(im);
@@ -149,12 +151,12 @@ main(int argc, char **argv) · 9 unmodified lines
149151 Glyf *g = otfglyf(o, gi);
150152 if(g == nil){
151153 fprint(2, "%d: %r\n", gi);
152− }else if(h > 0){
154+ }else if(ppem > 0){
153155 if(g->component != nil)
154156 fprint(2, "%d: component\n", gi);
155157 else{
156− int w;
157− u8int *b = otfdrawglyf(g, h, &w);
158+ int w, h;
159+ u8int *b = otfdrawglyf(g, ppem, &w, &h);
158160 if(b == nil)
159161 sysfatal("%r");
160162 fprint(1, "%11s %11d %11d %11d %11d ", "k8", 0, 0, w, h);
rast.c+18−14
@@ -57,6 +57,8 @@ struct SegQ { · 56 unmodified lines
5757 */
5858 #define QBZR_PIX_SCALE 4.0
5959
60+#define GAP 0
61+
6062 #define ε 1.0e-10
6163
6264 static int
@@ -450,21 +452,17 @@ qbzr(SegQ *seg, int ns, int dw, int dh, Sval *p) · 387 unmodified lines
450452 }
451453
452454 u8int *
453−otfdrawglyf(Glyf *g, int h, int *wo)
455+otfdrawglyf(Glyf *g, int ppem, int *wo, int *ho)
454456 {
455− int w, i, r, k, npts, npx, ns;
457+ int w, h, i, r, k, npts, npx, ns;
456458 Point *p₀, *p, *prev;
457459 Spt *pts₀, *pts, *e;
458− double scale;
459460 SegQ *s₀, *s;
460461 Sval *fp;
461462 u8int *b;
462463
463− /* FIXME those epsilons and ceil is a rather dumb hack for now */
464− scale = (double)h / (g->yMax - g->yMin) + ε;
465− w = *wo = ceil((g->xMax - g->xMin) * scale + ε);
464+#define scale (double)ppem/g->unitsPerEm
466465
467− npx = w * h;
468466 ns = 0;
469467 s₀ = nil;
470468
@@ -507,16 +505,19 @@ otfdrawglyf(Glyf *g, int h, int *wo) · 36 unmodified lines
507505 s = s₀ + ns;
508506 pts = e;
509507 for(e = pts₀; e <= pts-3; e += 2, s++, ns++){
510− s->v0[0] = (e[0].x - g->xMin) * scale;
511− s->v0[1] = (e[0].y - g->yMin) * scale;
512− s->v1[0] = (e[1].x - g->xMin) * scale;
513− s->v1[1] = (e[1].y - g->yMin) * scale;
514− s->v2[0] = (e[2].x - g->xMin) * scale;
515− s->v2[1] = (e[2].y - g->yMin) * scale;
508+ s->v0[0] = (e[0].x - g->xMin) * scale + GAP;
509+ s->v0[1] = (e[0].y - g->yMin) * scale + GAP;
510+ s->v1[0] = (e[1].x - g->xMin) * scale + GAP;
511+ s->v1[1] = (e[1].y - g->yMin) * scale + GAP;
512+ s->v2[0] = (e[2].x - g->xMin) * scale + GAP;
513+ s->v2[1] = (e[2].y - g->yMin) * scale + GAP;
516514 }
517515 free(pts₀);
518516 }
519517
518+ w = ceil((g->xMax - g->xMin)*scale + 2*GAP);
519+ h = ceil((g->yMax - g->yMin)*scale + 2*GAP);
520+ npx = w*h;
520521 fp = calloc(1, npx*sizeof(*fp));
521522 r = qbzr(s₀, ns, w, h, fp);
522523 free(s₀);
@@ -526,8 +527,11 @@ otfdrawglyf(Glyf *g, int h, int *wo) · 3 unmodified lines
526527 b = (u8int*)fp;
527528 for(i = 0; i < npx; i++)
528529 b[i] = 255 - (fp[i] <= 0 ? 0 : (fp[i] >= QBZR_PIX_SCALE ? 255 : fp[i]/QBZR_PIX_SCALE*255));
529− if((b = realloc(b, npx)) != nil)
530+ if((b = realloc(b, npx)) != nil){
531+ *wo = w;
532+ *ho = h;
530533 fp = nil;
534+ }
531535 }
532536 free(fp);
533537 return b;
unix/test.c+37−35
@@ -9,37 +9,42 @@ typedef struct Image Image; · 8 unmodified lines
99
1010 struct Image {
1111 int w;
12+ int h;
1213 u8int *b;
1314 };
1415
1516 static void
16−fit(u8int *b, int bw, int bh, Image *im, int h, int *x, int *y, int gap)
17+fit(u8int *b, int bw, int bh, Image *im, int maxh, int *x, int *y, int gap)
1718 {
1819 int d;
1920
2021 if((bw-*x) < im->w+gap){
21− *y += h + gap;
22+ *y += maxh + gap;
2223 *x = gap;
2324 }
24− if((bh-*y) < h+gap)
25+ if((bh-*y) < maxh+gap)
2526 return;
26− for(d = 0; d < h; d++)
27+ for(d = 0; d < im->h; d++)
2728 memcpy(b + (*y + d)*bw + *x, im->b + d*im->w, im->w);
2829 *x += im->w + gap;
2930 }
3031
3132 static void
32−dumpmap(FILE *out, Image *im, int n, int h)
33+dumpmap(FILE *out, Image *im, int n)
3334 {
34−#define gap 2
35− int total, mid, npix, bw, bh, x, y, i;
35+#define gap 1
36+ int total, mid, npix, bw, bh, x, y, i, maxh;
3637 u8int *b;
3738
3839 total = 0;
39− for(i = 0; i < n; i++)
40+ maxh = 0;
41+ for(i = 0; i < n; i++){
42+ if(maxh < im[i].h)
43+ maxh = im[i].h;
4044 total += im[i].w;
45+ }
4146 mid = total / n;
42− npix = (mid+gap)*(h+gap)*n;
47+ npix = (mid+gap)*(maxh+gap)*n;
4348 bh = sqrt(npix);
4449 bw = npix/bh;
4550 bh *= 1.5;
@@ -51,9 +56,9 @@ dumpmap(FILE *out, Image *im, int n, int h) · 5 unmodified lines
5156 memset(b, 0xff, npix);
5257 x = y = gap;
5358 for(i = 0; i < n; i++)
54− fit(b, bw, bh, im+i, h, &x, &y, gap);
55− fprintf(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+h+gap);
56− fwrite(b, 1, bw*(y+h+gap), out);
59+ fit(b, bw, bh, im+i, maxh, &x, &y, gap);
60+ fprintf(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+maxh+gap);
61+ fwrite(b, 1, bw*(y+maxh+gap), out);
5762 free(b);
5863 }
5964
@@ -99,20 +104,20 @@ usage(void) · 39 unmodified lines
99104 fprintf(stderr, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-s PX] font.otf ...\n", argv0);
100105 fprintf(stderr, " -g: specifies a single glyph id\n");
101106 fprintf(stderr, " -G: print out glyph ids, only ones that can be drawn atm (no compound yet)\n");
102− fprintf(stderr, " -s: draw (of size PX) and write the image to stdout\n");
107+ fprintf(stderr, " -p: draw (of size in pixels per em) and write the image to stdout\n");
103108 exit(1);
104109 }
105110
106111 int
107112 main(int argc, char **argv)
108113 {
109− int i, gi, G, h;
114+ int i, gi, G, ppem;
110115 Otfile in, out;
111116 Otf *o;
112117
113118 gi = -1;
114119 G = 0;
115− h = 0;
120+ ppem = 0;
116121 ARGBEGIN{
117122 case 'g':
118123 gi = strtol(EARGF(usage()), NULL, 0);
@@ -120,8 +125,8 @@ main(int argc, char **argv) · 1 unmodified line
120125 case 'G':
121126 G++;
122127 break;
123− case 's':
124− h = strtol(EARGF(usage()), NULL, 0);
128+ case 'p':
129+ ppem = strtol(EARGF(usage()), NULL, 0);
125130 break;
126131 default:
127132 usage();
@@ -137,30 +142,27 @@ main(int argc, char **argv) · 9 unmodified lines
137142 err(1, "%s", argv[i]);
138143 if((o = otfopen(&in)) == NULL)
139144 errx(1, "%s: %s", argv[i], otferrstr());
140− if(h <= 0)
145+ if(ppem <= 0)
141146 fprintf(out.aux, "%s\n", argv[i]);
142147 if(G && gi < 0){
143148 int i, n = otfglyfnum(o);
144− Image *im = h > 0 ? calloc(n, sizeof(*im)) : NULL;
149+ Image *im = ppem > 0 ? calloc(n, sizeof(*im)) : NULL;
145150 for(i = 0; i < n; i++){
146151 Glyf *g = otfglyf(o, i);
147152 if(g == NULL)
148153 errx(1, "glyph %d: %s", i, otferrstr());
149− if(h > 0 && g->simple != NULL && g->numberOfContours > 0){
150− int w;
151− u8int *b = otfdrawglyf(g, h, &w);
152− if(b == NULL)
154+ if(ppem > 0 && g->simple != NULL && g->numberOfContours > 0){
155+ im[i].b = otfdrawglyf(g, ppem, &im[i].w, &im[i].h);
156+ if(im[i].b == NULL)
153157 errx(1, "glyph %d: %s", i, otferrstr());
154− im[i].w = w;
155− im[i].b = b;
156− }else if(h <= 0){
158+ }else if(ppem <= 0){
157159 fprintf(out.aux, "%d (%s):\n", i, g->simple ? "simple" : "component");
158160 print_Glyf(&out, indentΔ, o, g);
159161 }
160162 free(g);
161163 }
162− if(h > 0){
163− dumpmap(out.aux, im, n, h);
164+ if(ppem > 0){
165+ dumpmap(out.aux, im, n);
164166 for(i = 0; i < n; i++)
165167 free(im[i].b);
166168 free(im);
@@ -174,17 +176,17 @@ main(int argc, char **argv) · 7 unmodified lines
174176 Glyf *g = otfglyf(o, gi);
175177 if(g == NULL){
176178 errx(1, "glyph %d: %s", gi, otferrstr());
177− }else if(h > 0){
179+ }else if(ppem > 0){
178180 if(g->component != NULL)
179181 errx(1, "glyph %d: component", gi);
180182 else{
181− int w;
182− u8int *b = otfdrawglyf(g, h, &w);
183− if(b == NULL)
183+ Image im;
184+ im.b = otfdrawglyf(g, ppem, &im.w, &im.h);
185+ if(im.b == NULL)
184186 errx(1, "glyph %d: %s", gi, otferrstr());
185− fprintf(out.aux, "%11s %11d %11d %11d %11d ", "k8", 0, 0, w, h);
186− fwrite(b, 1, w*h, out.aux);
187− free(b);
187+ fprintf(out.aux, "%11s %11d %11d %11d %11d ", "k8", 0, 0, im.w, im.h);
188+ fwrite(im.b, 1, im.w*im.h, out.aux);
189+ free(im.b);
188190 }
189191 }else{
190192 fprintf(out.aux, "\n%d:\n", gi);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t