9 #define NGLYPHS (1 << 14)
11 #define BUFLEN (1 << 23)
13 #define MAX(a, b) ((a) < (b) ? (b) : (a))
15 #define U32(buf, off) (htonl(*(u32 *) ((buf) + (off))))
16 #define U16(buf, off) (htons(*(u16 *) ((buf) + (off))))
17 #define U8(buf, off) (*(u8 *) ((buf) + (off)))
18 #define S16(buf, off) ((s16) htons(*(u16 *) ((buf) + (off))))
19 #define S32(buf, off) ((s32) htonl(*(u32 *) ((buf) + (off))))
21 #define OTFLEN 12 /* otf header length */
22 #define OTFRECLEN 16 /* otf header record length */
23 #define CMAPLEN 4 /* cmap header length */
24 #define CMAPRECLEN 8 /* cmap record length */
25 #define CMAP4LEN 8 /* format 4 cmap subtable header length */
26 #define GCTXLEN 16 /* number of context backtrack coverage arrays */
28 typedef unsigned int u32
;
29 typedef unsigned short u16
;
30 typedef unsigned char u8
;
34 static char glyph_name
[NGLYPHS
][GNLEN
];
35 static int glyph_code
[NGLYPHS
];
36 static int glyph_bbox
[NGLYPHS
][4];
37 static int glyph_wid
[NGLYPHS
];
39 static int upm
; /* units per em */
40 static int res
; /* device resolution */
41 static int kmin
; /* minimum kerning value */
44 static char *macset
[];
46 static int owid(int w
)
48 return (w
< 0 ? w
* 1000 - upm
/ 2 : w
* 1000 + upm
/ 2) / upm
;
51 static int uwid(int w
)
54 return (w
< 0 ? owid(w
) - d
/ 2 : owid(w
) + d
/ 2) / d
;
57 /* report unsupported otf tables */
58 static void otf_unsupported(char *sub
, int type
, int fmt
)
61 fprintf(stderr
, "neatmkfn: unsupported %s lookup %d", sub
, type
);
63 fprintf(stderr
, " format %d", fmt
);
64 fprintf(stderr
, "\n");
68 /* find the otf table with the given name */
69 static void *otf_table(void *otf
, char *name
)
71 void *recs
= otf
+ OTFLEN
; /* otf table records */
72 void *rec
; /* beginning of a table record */
73 int nrecs
= U16(otf
, 4);
75 for (i
= 0; i
< nrecs
; i
++) {
76 rec
= recs
+ i
* OTFRECLEN
;
77 if (!strncmp(rec
, name
, 4))
78 return otf
+ U32(rec
, 8);
83 /* parse otf cmap format 4 subtable */
84 static void otf_cmap4(void *otf
, void *cmap4
)
87 void *ends
, *begs
, *deltas
, *offsets
;
88 int beg
, end
, delta
, offset
;
90 nsegs
= U16(cmap4
, 6) / 2;
92 begs
= ends
+ 2 * nsegs
+ 2;
93 deltas
= begs
+ 2 * nsegs
;
94 offsets
= deltas
+ 2 * nsegs
;
95 for (i
= 0; i
< nsegs
; i
++) {
96 beg
= U16(begs
, 2 * i
);
97 end
= U16(ends
, 2 * i
);
98 delta
= U16(deltas
, 2 * i
);
99 offset
= U16(offsets
, 2 * i
);
101 for (j
= beg
; j
<= end
; j
++)
102 glyph_code
[(U16(offsets
+ 2 * i
,
103 offset
+ (j
- beg
) * 2) + delta
) & 0xffff] = j
;
105 for (j
= beg
; j
<= end
; j
++)
106 glyph_code
[(j
+ delta
) & 0xffff] = j
;
111 /* parse otf cmap header */
112 static void otf_cmap(void *otf
, void *cmap
)
114 void *recs
= cmap
+ CMAPLEN
; /* cmap records */
115 void *rec
; /* a cmap record */
116 void *tab
; /* a cmap subtable */
119 int nrecs
= U16(cmap
, 2);
121 for (i
= 0; i
< nrecs
; i
++) {
122 rec
= recs
+ i
* CMAPRECLEN
;
125 tab
= cmap
+ U32(rec
, 4);
127 if (plat
== 3 && enc
== 1 && fmt
== 4)
132 static void otf_post(void *otf
, void *post
)
134 void *post2
; /* version 2.0 header */
135 void *index
; /* glyph name indices */
136 void *names
; /* glyph names */
139 if (U32(post
, 0) != 0x00020000)
142 glyph_n
= U16(post2
, 0);
144 names
= index
+ 2 * glyph_n
;
145 for (i
= 0; i
< glyph_n
; i
++) {
146 idx
= U16(index
, 2 * i
);
148 strcpy(glyph_name
[i
], macset
[idx
]);
150 memcpy(glyph_name
[i
], names
+ cname
+ 1,
152 glyph_name
[i
][U8(names
, cname
)] = '\0';
153 cname
+= U8(names
, cname
) + 1;
158 static void otf_glyf(void *otf
, void *glyf
)
160 void *maxp
= otf_table(otf
, "maxp");
161 void *head
= otf_table(otf
, "head");
162 void *loca
= otf_table(otf
, "loca");
165 int n
= U16(maxp
, 4);
166 int fmt
= U16(head
, 50);
168 for (i
= 0; i
< n
; i
++) {
170 gdat
= glyf
+ U32(loca
, 4 * i
);
171 gdat_next
= glyf
+ U32(loca
, 4 * (i
+ 1));
173 gdat
= glyf
+ U16(loca
, 2 * i
) * 2;
174 gdat_next
= glyf
+ U16(loca
, 2 * (i
+ 1)) * 2;
176 if (gdat
< gdat_next
)
177 for (j
= 0; j
< 4; j
++)
178 glyph_bbox
[i
][j
] = S16(gdat
, 2 + 2 * j
);
182 static void otf_hmtx(void *otf
, void *hmtx
)
184 void *hhea
= otf_table(otf
, "hhea");
188 for (i
= 0; i
< n
; i
++)
189 glyph_wid
[i
] = U16(hmtx
, i
* 4);
190 for (i
= n
; i
< glyph_n
; i
++)
191 glyph_wid
[i
] = glyph_wid
[n
- 1];
194 static void otf_kern(void *otf
, void *kern
)
196 int n
; /* number of kern subtables */
197 void *tab
; /* a kern subtable */
204 for (i
= 0; i
< n
; i
++) {
208 if ((cov
>> 8) == 0 && (cov
& 1)) { /* format 0 */
209 npairs
= U16(tab
, 6);
210 for (j
= 0; j
< npairs
; j
++) {
211 c1
= U16(tab
, 14 + 6 * j
);
212 c2
= U16(tab
, 14 + 6 * j
+ 2);
213 val
= S16(tab
, 14 + 6 * j
+ 4);
214 trfn_kern(glyph_name
[c1
], glyph_name
[c2
],
221 static int coverage(void *cov
, int *out
)
223 int fmt
= U16(cov
, 0);
229 for (i
= 0; i
< n
; i
++)
230 out
[ncov
++] = U16(cov
, 4 + 2 * i
);
233 for (i
= 0; i
< n
; i
++) {
234 beg
= U16(cov
, 4 + 6 * i
);
235 end
= U16(cov
, 4 + 6 * i
+ 2);
236 for (j
= beg
; j
<= end
; j
++)
243 static int classdef(void *tab
, int *gl
, int *cls
)
245 int fmt
= U16(tab
, 0);
252 for (i
= 0; i
< ngl
; i
++) {
254 cls
[i
] = U16(tab
, 6 + 2 * i
);
259 for (i
= 0; i
< n
; i
++) {
260 beg
= U16(tab
, 4 + 6 * i
);
261 end
= U16(tab
, 4 + 6 * i
+ 2);
262 for (j
= beg
; j
<= end
; j
++) {
264 cls
[ngl
] = U16(tab
, 4 + 6 * i
+ 4);
272 static int intcmp(void *v1
, void *v2
)
274 return *(int *) v1
- *(int *) v2
;
277 int ggrp_make(int *src
, int n
);
279 static int ggrp_class(int *src
, int *cls
, int nsrc
, int id
)
284 for (i
= 0; i
< nsrc
; i
++)
287 qsort(g
, n
, sizeof(g
[0]), (void *) intcmp
);
288 return ggrp_make(g
, n
);
291 static int ggrp_coverage(int *g
, int n
)
293 qsort(g
, n
, sizeof(g
[0]), (void *) intcmp
);
294 return ggrp_make(g
, n
);
297 static int valuerecord_len(int fmt
)
301 for (i
= 0; i
< 8; i
++)
307 static void valuerecord_print(int fmt
, void *rec
)
312 for (i
= 0; i
< 8; i
++) {
313 if (fmt
& (1 << i
)) {
314 vals
[i
] = uwid(S16(rec
, off
));
319 printf(":%+d%+d%+d%+d", vals
[0], vals
[1], vals
[2], vals
[3]);
322 static int valuerecord_small(int fmt
, void *rec
)
326 for (i
= 0; i
< 8; i
++) {
327 if (fmt
& (1 << i
)) {
328 if (abs(uwid(S16(rec
, off
))) >= MAX(1, kmin
))
336 /* single adjustment positioning */
337 static void otf_gpostype1(void *otf
, void *sub
, char *feat
)
339 int fmt
= U16(sub
, 0);
340 int vfmt
= U16(sub
, 4);
343 int vlen
= valuerecord_len(vfmt
);
345 ncov
= coverage(sub
+ U16(sub
, 2), cov
);
347 for (i
= 0; i
< ncov
; i
++) {
348 printf("gpos %s 1 %s", feat
, glyph_name
[cov
[i
]]);
349 valuerecord_print(vfmt
, sub
+ 6);
355 for (i
= 0; i
< nvals
; i
++) {
356 printf("gpos %s 1 %s", feat
, glyph_name
[cov
[i
]]);
357 valuerecord_print(vfmt
, sub
+ 8 + i
* vlen
);
363 /* pair adjustment positioning */
364 static void otf_gpostype2(void *otf
, void *sub
, char *feat
)
366 int fmt
= U16(sub
, 0);
367 int vfmt1
= U16(sub
, 4); /* valuerecord 1 */
368 int vfmt2
= U16(sub
, 6); /* valuerecord 2 */
369 int fmtoff1
, fmtoff2
;
370 int vrlen
; /* the length of vfmt1 and vfmt2 */
372 vrlen
= valuerecord_len(vfmt1
) + valuerecord_len(vfmt2
);
375 int nc1
= U16(sub
, 8);
376 coverage(sub
+ U16(sub
, 2), cov
);
377 for (i
= 0; i
< nc1
; i
++) {
378 void *c2
= sub
+ U16(sub
, 10 + 2 * i
);
379 int nc2
= U16(c2
, 0);
380 for (j
= 0; j
< nc2
; j
++) {
381 int second
= U16(c2
+ 2 + (2 + vrlen
) * j
, 0);
382 fmtoff1
= 2 + (2 + vrlen
) * j
+ 2;
383 fmtoff2
= fmtoff1
+ valuerecord_len(vfmt2
);
384 if (valuerecord_small(vfmt1
, c2
+ fmtoff1
) &&
385 valuerecord_small(vfmt2
, c2
+ fmtoff2
))
387 printf("gpos %s 2", feat
);
388 printf(" %s", glyph_name
[cov
[i
]]);
389 valuerecord_print(vfmt1
, c2
+ fmtoff1
);
390 printf(" %s", glyph_name
[second
]);
391 valuerecord_print(vfmt2
, c2
+ fmtoff2
);
397 int gl1
[NGLYPHS
], gl2
[NGLYPHS
];
398 int cls1
[NGLYPHS
], cls2
[NGLYPHS
];
399 int grp1
[NGLYPHS
], grp2
[NGLYPHS
];
400 int ngl1
= classdef(sub
+ U16(sub
, 8), gl1
, cls1
);
401 int ngl2
= classdef(sub
+ U16(sub
, 10), gl2
, cls2
);
402 int ncls1
= U16(sub
, 12);
403 int ncls2
= U16(sub
, 14);
404 for (i
= 0; i
< ncls1
; i
++)
405 grp1
[i
] = ggrp_class(gl1
, cls1
, ngl1
, i
);
406 for (i
= 0; i
< ncls2
; i
++)
407 grp2
[i
] = ggrp_class(gl2
, cls2
, ngl2
, i
);
408 for (i
= 0; i
< ncls1
; i
++) {
409 for (j
= 0; j
< ncls2
; j
++) {
410 fmtoff1
= 16 + (i
* ncls2
+ j
) * vrlen
;
411 fmtoff2
= fmtoff1
+ valuerecord_len(vfmt1
);
412 if (valuerecord_small(vfmt1
, sub
+ fmtoff1
) &&
413 valuerecord_small(vfmt2
, sub
+ fmtoff2
))
415 printf("gpos %s %d", feat
, 2);
416 printf(" @%d", grp1
[i
]);
417 valuerecord_print(vfmt1
, sub
+ fmtoff1
);
418 printf(" @%d", grp2
[j
]);
419 valuerecord_print(vfmt2
, sub
+ fmtoff2
);
426 /* cursive attachment positioning */
427 static void otf_gpostype3(void *otf
, void *sub
, char *feat
)
429 int fmt
= U16(sub
, 0);
432 coverage(sub
+ U16(sub
, 2), cov
);
436 for (i
= 0; i
< n
; i
++) {
437 int prev
= U16(sub
, 6 + 4 * i
);
438 int next
= U16(sub
, 6 + 4 * i
+ 2);
439 printf("gcur %s %s", feat
, glyph_name
[cov
[i
]]);
441 printf(" %d %d", uwid(S16(sub
, prev
+ 2)),
442 uwid(S16(sub
, prev
+ 4)));
446 printf(" %d %d", uwid(S16(sub
, next
+ 2)),
447 uwid(S16(sub
, next
+ 4)));
454 /* parse the given gpos feature table */
455 static void otf_gposfeatrec(void *otf
, void *gpos
, void *featrec
)
457 void *feats
= gpos
+ U16(gpos
, 6);
458 void *lookups
= gpos
+ U16(gpos
, 8);
463 memcpy(tag
, featrec
, 4);
464 feat
= feats
+ U16(featrec
, 4);
465 nlookups
= U16(feat
, 2);
466 for (i
= 0; i
< nlookups
; i
++) {
467 void *lookup
= lookups
+ U16(lookups
, 2 + 2 * U16(feat
, 4 + 2 * i
));
468 int ltype
= U16(lookup
, 0);
469 int ntabs
= U16(lookup
, 4);
470 for (j
= 0; j
< ntabs
; j
++) {
471 void *tab
= lookup
+ U16(lookup
, 6 + 2 * j
);
473 if (type
== 9) { /* extension positioning */
475 tab
= tab
+ U32(tab
, 4);
479 otf_gpostype1(otf
, tab
, tag
);
482 otf_gpostype2(otf
, tab
, tag
);
485 otf_gpostype3(otf
, tab
, tag
);
488 otf_unsupported("GPOS", type
, 0);
494 /* parse the given gpos language table and its feature tables */
495 static void otf_gposlang(void *otf
, void *gpos
, void *lang
)
497 void *feats
= gpos
+ U16(gpos
, 6);
498 int featidx
= U16(lang
, 2);
499 int nfeat
= U16(lang
, 4);
501 if (featidx
!= 0xffff)
502 otf_gposfeatrec(otf
, gpos
, feats
+ 2 + 6 * featidx
);
503 for (i
= 0; i
< nfeat
; i
++)
504 otf_gposfeatrec(otf
, gpos
,
505 feats
+ 2 + 6 * U16(lang
, 6 + 2 * i
));
508 static void otf_gpos(void *otf
, void *gpos
)
510 void *scripts
= gpos
+ U16(gpos
, 4);
511 int nscripts
, nlangs
;
516 nscripts
= U16(scripts
, 0);
517 for (i
= 0; i
< nscripts
; i
++) {
518 grec
= scripts
+ 2 + 6 * i
;
519 memcpy(tag
, grec
, 4);
521 if (!trfn_script(tag
, nscripts
))
523 script
= scripts
+ U16(grec
, 4);
524 nlangs
= U16(script
, 2);
525 if (U16(script
, 0) && trfn_lang(NULL
, nlangs
+ (U16(script
, 0) != 0)))
526 otf_gposlang(otf
, gpos
, script
+ U16(script
, 0));
527 for (j
= 0; j
< nlangs
; j
++) {
528 lrec
= script
+ 4 + 6 * j
;
529 memcpy(tag
, lrec
, 4);
531 if (trfn_lang(tag
, nlangs
+ (U16(script
, 0) != 0)))
532 otf_gposlang(otf
, gpos
, script
+ U16(lrec
, 4));
539 int bgrp
[GCTXLEN
]; /* backtrack coverage arrays */
540 int igrp
[GCTXLEN
]; /* input coverage arrays */
541 int lgrp
[GCTXLEN
]; /* lookahead coverage arrays*/
542 int bn
, in
, ln
; /* size of b[], i[], l[] */
543 int seqidx
; /* sequence index */
546 static int gctx_len(struct gctx
*ctx
, int patlen
)
548 return ctx
? ctx
->bn
+ ctx
->in
+ ctx
->ln
- patlen
: 0;
551 static void gctx_backtrack(struct gctx
*ctx
)
556 for (i
= 0; i
< ctx
->bn
; i
++)
557 printf(" =@%d", ctx
->bgrp
[i
]);
558 for (i
= 0; i
< ctx
->seqidx
; i
++)
559 printf(" =@%d", ctx
->igrp
[i
]);
562 static void gctx_lookahead(struct gctx
*ctx
, int patlen
)
567 for (i
= ctx
->seqidx
+ patlen
; i
< ctx
->in
; i
++)
568 printf(" =@%d", ctx
->igrp
[i
]);
569 for (i
= 0; i
< ctx
->ln
; i
++)
570 printf(" =@%d", ctx
->lgrp
[i
]);
573 /* single substitution */
574 static void otf_gsubtype1(void *otf
, void *sub
, char *feat
, struct gctx
*ctx
)
577 int fmt
= U16(sub
, 0);
581 ncov
= coverage(sub
+ U16(sub
, 2), cov
);
583 for (i
= 0; i
< ncov
; i
++) {
584 printf("gsub %s %d", feat
, 2 + gctx_len(ctx
, 1));
586 printf(" -%s +%s", glyph_name
[cov
[i
]],
587 glyph_name
[cov
[i
] + S16(sub
, 4)]);
588 gctx_lookahead(ctx
, 1);
594 for (i
= 0; i
< n
; i
++) {
595 printf("gsub %s %d", feat
, 2 + gctx_len(ctx
, 1));
597 printf(" -%s +%s", glyph_name
[cov
[i
]],
598 glyph_name
[U16(sub
, 6 + 2 * i
)]);
599 gctx_lookahead(ctx
, 1);
605 /* alternate substitution */
606 static void otf_gsubtype3(void *otf
, void *sub
, char *feat
, struct gctx
*ctx
)
609 int fmt
= U16(sub
, 0);
613 coverage(sub
+ U16(sub
, 2), cov
);
615 for (i
= 0; i
< n
; i
++) {
616 void *alt
= sub
+ U16(sub
, 6 + 2 * i
);
617 int nalt
= U16(alt
, 0);
618 for (j
= 0; j
< nalt
; j
++) {
619 printf("gsub %s %d", feat
, 2 + gctx_len(ctx
, 1));
621 printf(" -%s +%s", glyph_name
[cov
[i
]],
622 glyph_name
[U16(alt
, 2 + 2 * j
)]);
623 gctx_lookahead(ctx
, 1);
629 /* ligature substitution */
630 static void otf_gsubtype4(void *otf
, void *sub
, char *feat
, struct gctx
*ctx
)
632 int fmt
= U16(sub
, 0);
637 coverage(sub
+ U16(sub
, 2), cov
);
639 for (i
= 0; i
< n
; i
++) {
640 void *set
= sub
+ U16(sub
, 6 + 2 * i
);
641 int nset
= U16(set
, 0);
642 for (j
= 0; j
< nset
; j
++) {
643 void *lig
= set
+ U16(set
, 2 + 2 * j
);
644 int nlig
= U16(lig
, 2);
645 printf("gsub %s %d", feat
, nlig
+ 1 + gctx_len(ctx
, nlig
));
647 printf(" -%s", glyph_name
[cov
[i
]]);
648 for (k
= 0; k
< nlig
- 1; k
++)
649 printf(" -%s", glyph_name
[U16(lig
, 4 + 2 * k
)]);
650 printf(" +%s", glyph_name
[U16(lig
, 0)]);
651 gctx_lookahead(ctx
, nlig
);
657 /* chaining contextual substitution */
658 static void otf_gsubtype6(void *otf
, void *sub
, char *feat
, void *gsub
)
660 struct gctx ctx
= {{0}};
661 void *lookups
= gsub
+ U16(gsub
, 8);
662 int fmt
= U16(sub
, 0);
664 int i
, j
, nsub
, ncov
;
667 otf_unsupported("GSUB", 6, fmt
);
670 ctx
.bn
= U16(sub
, off
);
671 for (i
= 0; i
< ctx
.bn
; i
++) {
672 ncov
= coverage(sub
+ U16(sub
, off
+ 2 + 2 * i
), cov
);
673 ctx
.bgrp
[i
] = ggrp_coverage(cov
, ncov
);
675 off
+= 2 + 2 * ctx
.bn
;
676 ctx
.in
= U16(sub
, off
);
677 for (i
= 0; i
< ctx
.in
; i
++) {
678 ncov
= coverage(sub
+ U16(sub
, off
+ 2 + 2 * i
), cov
);
679 ctx
.igrp
[i
] = ggrp_coverage(cov
, ncov
);
681 off
+= 2 + 2 * ctx
.in
;
682 ctx
.ln
= U16(sub
, off
);
683 for (i
= 0; i
< ctx
.ln
; i
++) {
684 ncov
= coverage(sub
+ U16(sub
, off
+ 2 + 2 * i
), cov
);
685 ctx
.lgrp
[i
] = ggrp_coverage(cov
, ncov
);
687 off
+= 2 + 2 * ctx
.ln
;
688 nsub
= U16(sub
, off
); /* nsub > 1 is not supported */
689 for (i
= 0; i
< nsub
&& i
< 1; i
++) {
690 int lidx
= U16(sub
, off
+ 2 + 4 * i
+ 2);
691 void *lookup
= lookups
+ U16(lookups
, 2 + 2 * lidx
);
692 int ltype
= U16(lookup
, 0);
693 int ntabs
= U16(lookup
, 4);
694 ctx
.seqidx
= U16(sub
, off
+ 2 + 4 * i
);
695 for (j
= 0; j
< ntabs
; j
++) {
696 void *tab
= lookup
+ U16(lookup
, 6 + 2 * j
);
698 if (type
== 7) { /* extension substitution */
700 tab
= tab
+ U32(tab
, 4);
703 otf_gsubtype1(otf
, tab
, feat
, &ctx
);
705 otf_gsubtype3(otf
, tab
, feat
, &ctx
);
707 otf_gsubtype4(otf
, tab
, feat
, &ctx
);
712 /* parse the given gsub feature table */
713 static void otf_gsubfeatrec(void *otf
, void *gsub
, void *featrec
)
715 void *feats
= gsub
+ U16(gsub
, 6);
716 void *lookups
= gsub
+ U16(gsub
, 8);
721 memcpy(tag
, featrec
, 4);
722 feat
= feats
+ U16(featrec
, 4);
723 nlookups
= U16(feat
, 2);
724 for (i
= 0; i
< nlookups
; i
++) {
725 void *lookup
= lookups
+ U16(lookups
, 2 + 2 * U16(feat
, 4 + 2 * i
));
726 int ltype
= U16(lookup
, 0);
727 int ntabs
= U16(lookup
, 4);
728 for (j
= 0; j
< ntabs
; j
++) {
729 void *tab
= lookup
+ U16(lookup
, 6 + 2 * j
);
731 if (type
== 7) { /* extension substitution */
733 tab
= tab
+ U32(tab
, 4);
737 otf_gsubtype1(otf
, tab
, tag
, NULL
);
740 otf_gsubtype3(otf
, tab
, tag
, NULL
);
743 otf_gsubtype4(otf
, tab
, tag
, NULL
);
746 otf_gsubtype6(otf
, tab
, tag
, gsub
);
749 otf_unsupported("GSUB", type
, 0);
755 /* parse the given gsub language table and its feature tables */
756 static void otf_gsublang(void *otf
, void *gsub
, void *lang
)
758 void *feats
= gsub
+ U16(gsub
, 6);
759 int featidx
= U16(lang
, 2);
760 int nfeat
= U16(lang
, 4);
762 if (featidx
!= 0xffff)
763 otf_gsubfeatrec(otf
, gsub
, feats
+ 2 + 6 * featidx
);
764 for (i
= 0; i
< nfeat
; i
++)
765 otf_gsubfeatrec(otf
, gsub
,
766 feats
+ 2 + 6 * U16(lang
, 6 + 2 * i
));
769 static void otf_gsub(void *otf
, void *gsub
)
771 void *scripts
= gsub
+ U16(gsub
, 4);
772 int nscripts
, nlangs
;
777 nscripts
= U16(scripts
, 0);
778 for (i
= 0; i
< nscripts
; i
++) {
779 grec
= scripts
+ 2 + 6 * i
;
780 memcpy(tag
, grec
, 4);
782 if (!trfn_script(tag
, nscripts
))
784 script
= scripts
+ U16(scripts
+ 2 + 6 * i
, 4);
785 nlangs
= U16(script
, 2);
786 if (U16(script
, 0) && trfn_lang(NULL
, nlangs
+ (U16(script
, 0) != 0)))
787 otf_gsublang(otf
, gsub
, script
+ U16(script
, 0));
788 for (j
= 0; j
< nlangs
; j
++) {
789 lrec
= script
+ 4 + 6 * j
;
790 memcpy(tag
, lrec
, 4);
792 if (trfn_lang(tag
, nlangs
+ (U16(script
, 0) != 0)))
793 otf_gsublang(otf
, gsub
, script
+ U16(lrec
, 4));
798 int xread(int fd
, char *buf
, int len
)
802 int ret
= read(fd
, buf
+ nr
, len
- nr
);
803 if (ret
== -1 && (errno
== EAGAIN
|| errno
== EINTR
))
812 static char buf
[BUFLEN
];
817 if (xread(0, buf
, sizeof(buf
)) <= 0)
819 upm
= U16(otf_table(buf
, "head"), 18);
820 otf_cmap(buf
, otf_table(buf
, "cmap"));
821 otf_post(buf
, otf_table(buf
, "post"));
822 if (otf_table(buf
, "glyf"))
823 otf_glyf(buf
, otf_table(buf
, "glyf"));
824 otf_hmtx(buf
, otf_table(buf
, "hmtx"));
825 for (i
= 0; i
< glyph_n
; i
++) {
826 trfn_char(glyph_name
[i
], -1,
827 glyph_code
[i
] != 0xffff ? glyph_code
[i
] : 0,
829 owid(glyph_bbox
[i
][0]), owid(glyph_bbox
[i
][1]),
830 owid(glyph_bbox
[i
][2]), owid(glyph_bbox
[i
][3]));
832 if (otf_table(buf
, "kern"))
833 otf_kern(buf
, otf_table(buf
, "kern"));
837 void otf_feat(int r
, int k
, int w
)
842 if (otf_table(buf
, "GSUB"))
843 otf_gsub(buf
, otf_table(buf
, "GSUB"));
844 if (otf_table(buf
, "GPOS"))
845 otf_gpos(buf
, otf_table(buf
, "GPOS"));
849 static int *ggrp_g
[NGRPS
];
850 static int ggrp_len
[NGRPS
];
853 static int ggrp_find(int *src
, int n
)
856 for (i
= 0; i
< ggrp_n
; i
++) {
857 if (ggrp_len
[i
] == n
) {
858 for (j
= 0; j
< n
; j
++)
859 if (src
[j
] != ggrp_g
[i
][j
])
868 int ggrp_make(int *src
, int n
)
870 int id
= ggrp_find(src
, n
);
875 ggrp_g
[id
] = malloc(n
* sizeof(ggrp_g
[id
][0]));
877 for (i
= 0; i
< n
; i
++)
878 ggrp_g
[id
][i
] = src
[i
];
879 printf("ggrp %d %d", id
, n
);
880 for (i
= 0; i
< n
; i
++)
881 printf(" %s", glyph_name
[src
[i
]]);
886 static char *macset
[] = {
887 ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
888 "quotedbl", "numbersign", "dollar", "percent", "ampersand",
889 "quotesingle", "parenleft", "parenright", "asterisk", "plus",
890 "comma", "hyphen", "period", "slash", "zero",
891 "one", "two", "three", "four", "five",
892 "six", "seven", "eight", "nine", "colon",
893 "semicolon", "less", "equal", "greater", "question",
894 "at", "A", "B", "C", "D",
895 "E", "F", "G", "H", "I",
896 "J", "K", "L", "M", "N",
897 "O", "P", "Q", "R", "S",
898 "T", "U", "V", "W", "X",
899 "Y", "Z", "bracketleft", "backslash", "bracketright",
900 "asciicircum", "underscore", "grave", "a", "b",
901 "c", "d", "e", "f", "g",
902 "h", "i", "j", "k", "l",
903 "m", "n", "o", "p", "q",
904 "r", "s", "t", "u", "v",
905 "w", "x", "y", "z", "braceleft",
906 "bar", "braceright", "asciitilde", "Adieresis", "Aring",
907 "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
908 "aacute", "agrave", "acircumflex", "adieresis", "atilde",
909 "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
910 "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
911 "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
912 "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
913 "dagger", "degree", "cent", "sterling", "section",
914 "bullet", "paragraph", "germandbls", "registered", "copyright",
915 "trademark", "acute", "dieresis", "notequal", "AE",
916 "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
917 "yen", "mu", "partialdiff", "summation", "product",
918 "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
919 "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
920 "radical", "florin", "approxequal", "Delta", "guillemotleft",
921 "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
922 "Otilde", "OE", "oe", "endash", "emdash",
923 "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
924 "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
925 "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
926 "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
927 "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
928 "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
929 "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
930 "dotlessi", "circumflex", "tilde", "macron", "breve",
931 "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
932 "caron", "Lslash", "lslash", "Scaron", "scaron",
933 "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
934 "Yacute", "yacute", "Thorn", "thorn", "minus",
935 "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
936 "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
937 "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
938 "Ccaron", "ccaron", "dcroat",