trfn: minimum kerning value (-k) is in output device units
[neatmkfn.git] / otf.c
blobed4d5adb57e087b8c0fcb722f4a7823b605e23f3
1 #include <arpa/inet.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include "trfn.h"
8 #define NGLYPHS (1 << 14)
9 #define GNLEN (64)
10 #define BUFLEN (1 << 23)
12 #define U32(buf, off) (htonl(*(u32 *) ((buf) + (off))))
13 #define U16(buf, off) (htons(*(u16 *) ((buf) + (off))))
14 #define U8(buf, off) (*(u8 *) ((buf) + (off)))
15 #define S16(buf, off) ((s16) htons(*(u16 *) ((buf) + (off))))
16 #define S32(buf, off) ((s32) htonl(*(u32 *) ((buf) + (off))))
18 #define OTFLEN 12 /* otf header length */
19 #define OTFRECLEN 16 /* otf header record length */
20 #define CMAPLEN 4 /* cmap header length */
21 #define CMAPRECLEN 8 /* cmap record length */
22 #define CMAP4LEN 8 /* format 4 cmap subtable header length */
24 typedef unsigned int u32;
25 typedef unsigned short u16;
26 typedef unsigned char u8;
27 typedef int s32;
28 typedef short s16;
30 static char glyph_name[NGLYPHS][GNLEN];
31 static int glyph_code[NGLYPHS];
32 static int glyph_bbox[NGLYPHS][4];
33 static int glyph_wid[NGLYPHS];
34 static int glyph_n;
35 static int upm; /* units per em */
36 static int res; /* device resolution */
38 static char *macset[];
40 static int owid(int w)
42 return (w < 0 ? w * 1000 - upm / 2 : w * 1000 + upm / 2) / upm;
45 static int uwid(int w)
47 int d = 7200 / res;
48 return (w < 0 ? owid(w) - d / 2 : owid(w) + d / 2) / d;
51 /* find the otf table with the given name */
52 static void *otf_table(void *otf, char *name)
54 void *recs = otf + OTFLEN; /* otf table records */
55 void *rec; /* beginning of a table record */
56 int nrecs = U16(otf, 4);
57 int i;
58 for (i = 0; i < nrecs; i++) {
59 rec = recs + i * OTFRECLEN;
60 if (!strncmp(rec, name, 4))
61 return otf + U32(rec, 8);
63 return NULL;
66 /* parse otf cmap format 4 subtable */
67 static void otf_cmap4(void *otf, void *cmap4)
69 int nsegs;
70 void *ends, *begs, *deltas, *offsets;
71 void *idarray;
72 int beg, end, delta, offset;
73 int i, j;
74 nsegs = U16(cmap4, 6) / 2;
75 ends = cmap4 + 14;
76 begs = ends + 2 * nsegs + 2;
77 deltas = begs + 2 * nsegs;
78 offsets = deltas + 2 * nsegs;
79 idarray = offsets + 2 * nsegs;
80 for (i = 0; i < nsegs; i++) {
81 beg = U16(begs, 2 * i);
82 end = U16(ends, 2 * i);
83 delta = U16(deltas, 2 * i);
84 offset = U16(offsets, 2 * i);
85 if (offset) {
86 for (j = beg; j <= end; j++)
87 glyph_code[U16(offsets + i * 2,
88 offset + (j - beg) * 2)] = j;
89 } else {
90 for (j = beg; j <= end; j++)
91 glyph_code[(j + delta) & 0xffff] = j;
96 /* parse otf cmap header */
97 static void otf_cmap(void *otf, void *cmap)
99 void *recs = cmap + CMAPLEN; /* cmap records */
100 void *rec; /* a cmap record */
101 void *tab; /* a cmap subtable */
102 int plat, enc;
103 int fmt;
104 int nrecs = U16(cmap, 2);
105 int i;
106 for (i = 0; i < nrecs; i++) {
107 rec = recs + i * CMAPRECLEN;
108 plat = U16(rec, 0);
109 enc = U16(rec, 2);
110 tab = cmap + U32(rec, 4);
111 fmt = U16(tab, 0);
112 if (plat == 3 && enc == 1 && fmt == 4)
113 otf_cmap4(otf, tab);
117 static void otf_post(void *otf, void *post)
119 void *post2; /* version 2.0 header */
120 void *index; /* glyph name indices */
121 void *names; /* glyph names */
122 int i, idx;
123 int cname = 0;
124 if (U32(post, 0) != 0x00020000)
125 return;
126 post2 = post + 32;
127 glyph_n = U16(post2, 0);
128 index = post2 + 2;
129 names = index + 2 * glyph_n;
130 for (i = 0; i < glyph_n; i++) {
131 idx = U16(index, 2 * i);
132 if (idx <= 257) {
133 strcpy(glyph_name[i], macset[idx]);
134 } else {
135 memcpy(glyph_name[i], names + cname + 1,
136 U8(names, cname));
137 glyph_name[i][U8(names, cname)] = '\0';
138 cname += U8(names, cname) + 1;
143 static void otf_glyf(void *otf, void *glyf)
145 void *maxp = otf_table(otf, "maxp");
146 void *head = otf_table(otf, "head");
147 void *loca = otf_table(otf, "loca");
148 void *gdat;
149 void *gdat_next;
150 int n = U16(maxp, 4);
151 int fmt = U16(head, 50);
152 int i, j;
153 for (i = 0; i < n; i++) {
154 if (fmt) {
155 gdat = glyf + U32(loca, 4 * i);
156 gdat_next = glyf + U32(loca, 4 * (i + 1));
157 } else {
158 gdat = glyf + U16(loca, 2 * i) * 2;
159 gdat_next = glyf + U16(loca, 2 * (i + 1)) * 2;
161 if (gdat < gdat_next)
162 for (j = 0; j < 4; j++)
163 glyph_bbox[i][j] = S16(gdat, 2 + 2 * j);
167 static void otf_hmtx(void *otf, void *hmtx)
169 void *hhea = otf_table(otf, "hhea");
170 int n;
171 int i;
172 n = U16(hhea, 34);
173 for (i = 0; i < n; i++)
174 glyph_wid[i] = U16(hmtx, i * 4);
175 for (i = n; i < glyph_n; i++)
176 glyph_wid[i] = glyph_wid[n - 1];
179 static void otf_kern(void *otf, void *kern)
181 int n; /* number of kern subtables */
182 void *tab; /* a kern subtable */
183 int off = 4;
184 int npairs;
185 int cov;
186 int i, j;
187 int c1, c2, val;
188 n = U16(kern, 2);
189 for (i = 0; i < n; i++) {
190 tab = kern + off;
191 off += U16(tab, 2);
192 cov = U16(tab, 4);
193 if ((cov >> 8) == 0 && (cov & 1)) { /* format 0 */
194 npairs = U16(tab, 6);
195 for (j = 0; j < npairs; j++) {
196 c1 = U16(tab, 14 + 6 * j);
197 c2 = U16(tab, 14 + 6 * j + 2);
198 val = S16(tab, 14 + 6 * j + 4);
199 trfn_kern(glyph_name[c1], glyph_name[c2],
200 owid(val));
206 static int coverage(void *cov, int *out)
208 int fmt = U16(cov, 0);
209 int n = U16(cov, 2);
210 int beg, end;
211 int ncov = 0;
212 int i, j;
213 if (fmt == 1) {
214 for (i = 0; i < n; i++)
215 out[ncov++] = U16(cov, 4 + 2 * i);
217 if (fmt == 2) {
218 for (i = 0; i < n; i++) {
219 beg = U16(cov, 4 + 6 * i);
220 end = U16(cov, 4 + 6 * i + 2);
221 for (j = beg; j <= end; j++)
222 out[ncov++] = j;
225 return ncov;
228 static int valuerecord_len(int fmt)
230 int off = 0;
231 int i;
232 for (i = 0; i < 8; i++)
233 if (fmt & (1 << i))
234 off += 2;
235 return off;
238 static void valuerecord_print(int fmt, void *rec)
240 int vals[8] = {0};
241 int off = 0;
242 int i;
243 for (i = 0; i < 8; i++) {
244 if (fmt & (1 << i)) {
245 vals[i] = uwid(S16(rec, off));
246 off += 2;
249 if (fmt)
250 printf(":%+d%+d%+d%+d", vals[0], vals[1], vals[2], vals[3]);
253 static void otf_gpostype1(void *otf, char *feat, char *sub)
255 int fmt = U16(sub, 0);
256 int vfmt = U16(sub, 4);
257 int cov[NGLYPHS];
258 int ncov, nvals;
259 int vlen = valuerecord_len(vfmt);
260 int i;
261 ncov = coverage(sub + U16(sub, 2), cov);
262 if (fmt == 1) {
263 for (i = 0; i < ncov; i++) {
264 printf("gpos %s %s", feat, glyph_name[cov[i]]);
265 valuerecord_print(vfmt, sub + 6);
266 printf("\n");
269 if (fmt == 2) {
270 nvals = U16(sub, 6);
271 for (i = 0; i < nvals; i++) {
272 printf("gpos %s %s", feat, glyph_name[cov[i]]);
273 valuerecord_print(vfmt, sub + 8 + i * vlen);
274 printf("\n");
279 static void otf_gpostype2(void *otf, char *feat, char *sub)
281 int fmt = U16(sub, 0);
282 int vfmt1 = U16(sub, 4);
283 int vfmt2 = U16(sub, 6);
284 int c2len;
285 int nc1 = U16(sub, 8);
286 int cov[NGLYPHS];
287 void *c2;
288 int ncov, nc2, second;
289 int i, j;
290 if (fmt != 1)
291 return;
292 ncov = coverage(sub + U16(sub, 2), cov);
293 c2len = 2 + valuerecord_len(vfmt1) + valuerecord_len(vfmt2);
294 for (i = 0; i < nc1; i++) {
295 c2 = sub + U16(sub, 10 + 2 * i);
296 nc2 = U16(c2, 0);
297 for (j = 0; j < nc2; j++) {
298 printf("gpos %s 2", feat);
299 second = U16(c2 + 2 + c2len * j, 0);
300 printf(" %s", glyph_name[cov[i]]);
301 valuerecord_print(vfmt1, c2 + 2 + c2len * j + 2);
302 printf(" %s", glyph_name[second]);
303 valuerecord_print(vfmt2, c2 + 2 + c2len * j + 2 +
304 valuerecord_len(vfmt1));
305 printf("\n");
310 static void otf_gpostype3(void *otf, char *feat, char *sub)
312 int fmt = U16(sub, 0);
313 int cov[NGLYPHS];
314 int ncov, i, n;
315 ncov = coverage(sub + U16(sub, 2), cov);
316 if (fmt != 1)
317 return;
318 n = U16(sub, 4);
319 for (i = 0; i < n; i++) {
320 int prev = U16(sub, 6 + 4 * i);
321 int next = U16(sub, 6 + 4 * i + 2);
322 printf("gcur %s %s", feat, glyph_name[cov[i]]);
323 if (prev)
324 printf(" %d %d", uwid(S16(sub, prev + 2)),
325 uwid(S16(sub, prev + 4)));
326 else
327 printf(" - -");
328 if (next)
329 printf(" %d %d", uwid(S16(sub, next + 2)),
330 uwid(S16(sub, next + 4)));
331 else
332 printf(" - -");
333 printf("\n");
337 static void otf_gposfeatrec(void *otf, void *gpos, void *featrec)
339 void *feats = gpos + U16(gpos, 6);
340 void *lookups = gpos + U16(gpos, 8);
341 void *feat, *lookup, *tab;
342 int nlookups, type, flag, ntabs;
343 char tag[8] = "";
344 int i, j;
345 memcpy(tag, featrec, 4);
346 feat = feats + U16(featrec, 4);
347 nlookups = U16(feat, 2);
348 for (i = 0; i < nlookups; i++) {
349 lookup = lookups + U16(lookups, 2 + 2 * U16(feat, 4 + 2 * i));
350 type = U16(lookup, 0);
351 flag = U16(lookup, 2);
352 ntabs = U16(lookup, 4);
353 for (j = 0; j < ntabs; j++) {
354 tab = lookup + U16(lookup, 6 + 2 * j);
355 if (type == 1)
356 otf_gpostype1(otf, tag, tab);
357 if (type == 2)
358 otf_gpostype2(otf, tag, tab);
359 if (type == 3)
360 otf_gpostype3(otf, tag, tab);
365 static void otf_gposlang(void *otf, void *gpos, void *lang)
367 void *feats = gpos + U16(gpos, 6);
368 int featidx = U16(lang, 2);
369 int nfeat = U16(lang, 4);
370 int i;
371 if (featidx != 0xffff)
372 otf_gposfeatrec(otf, gpos, feats + 2 + 6 * featidx);
373 for (i = 0; i < nfeat; i++)
374 otf_gposfeatrec(otf, gpos,
375 feats + 2 + 6 * U16(lang, 6 + 2 * i));
378 static void otf_gpos(void *otf, void *gpos)
380 void *scripts = gpos + U16(gpos, 4);
381 int nscripts, nlangs;
382 void *script;
383 void *grec;
384 int i, j;
385 nscripts = U16(scripts, 0);
386 for (i = 0; i < nscripts; i++) {
387 grec = scripts + 2 + 6 * i;
388 script = scripts + U16(grec, 4);
389 if (U16(script, 0))
390 otf_gposlang(otf, gpos, script + U16(script, 0));
391 nlangs = U16(script, 2);
392 for (j = 0; j < nlangs; j++)
393 otf_gposlang(otf, gpos, script +
394 U16(script, 4 + 6 * j + 4));
398 static void otf_gsubtype1(void *otf, char *feat, char *sub)
400 int cov[NGLYPHS];
401 int fmt = U16(sub, 0);
402 int ncov;
403 int n;
404 int i;
405 ncov = coverage(sub + U16(sub, 2), cov);
406 if (fmt == 1) {
407 for (i = 0; i < ncov; i++)
408 printf("gsub %s 2 -%s +%s\n",
409 feat, glyph_name[cov[i]],
410 glyph_name[cov[i] + S16(sub, 4)]);
412 if (fmt == 2) {
413 n = U16(sub, 4);
414 for (i = 0; i < n; i++)
415 printf("gsub %s 2 -%s +%s\n",
416 feat, glyph_name[cov[i]],
417 glyph_name[U16(sub, 6 + 2 * i)]);
421 static void otf_gsubtype3(void *otf, char *feat, char *sub)
423 int cov[NGLYPHS];
424 int fmt = U16(sub, 0);
425 int ncov, n, i, j;
426 if (fmt != 1)
427 return;
428 ncov = coverage(sub + U16(sub, 2), cov);
429 n = U16(sub, 4);
430 for (i = 0; i < n; i++) {
431 void *alt = sub + U16(sub, 6 + 2 * i);
432 int nalt = U16(alt, 0);
433 for (j = 0; j < nalt; j++)
434 printf("gsub %s 2 -%s +%s\n",
435 feat, glyph_name[cov[i]],
436 glyph_name[U16(alt, 2 + 2 * j)]);
440 static void otf_gsubtype4(void *otf, char *feat, char *sub)
442 int fmt = U16(sub, 0);
443 int cov[NGLYPHS];
444 int ncov, n, i, j, k;
445 if (fmt != 1)
446 return;
447 ncov = coverage(sub + U16(sub, 2), cov);
448 n = U16(sub, 4);
449 for (i = 0; i < n; i++) {
450 void *set = sub + U16(sub, 6 + 2 * i);
451 int nset = U16(set, 0);
452 for (j = 0; j < nset; j++) {
453 void *lig = set + U16(set, 2 + 2 * j);
454 int nlig = U16(lig, 2);
455 printf("gsub %s %d -%s",
456 feat, nlig + 1, glyph_name[cov[i]]);
457 for (k = 0; k < nlig - 1; k++)
458 printf(" -%s", glyph_name[U16(lig, 4 + 2 * k)]);
459 printf(" +%s\n", glyph_name[U16(lig, 0)]);
464 static void otf_gsubfeatrec(void *otf, void *gsub, void *featrec)
466 void *feats = gsub + U16(gsub, 6);
467 void *lookups = gsub + U16(gsub, 8);
468 void *feat, *lookup, *tab;
469 int nlookups, type, flag, ntabs;
470 char tag[8] = "";
471 int i, j;
472 memcpy(tag, featrec, 4);
473 feat = feats + U16(featrec, 4);
474 nlookups = U16(feat, 2);
475 for (i = 0; i < nlookups; i++) {
476 lookup = lookups + U16(lookups, 2 + 2 * U16(feat, 4 + 2 * i));
477 type = U16(lookup, 0);
478 flag = U16(lookup, 2);
479 ntabs = U16(lookup, 4);
480 for (j = 0; j < ntabs; j++) {
481 tab = lookup + U16(lookup, 6 + 2 * j);
482 if (type == 1)
483 otf_gsubtype1(otf, tag, tab);
484 if (type == 3)
485 otf_gsubtype3(otf, tag, tab);
486 if (type == 4)
487 otf_gsubtype4(otf, tag, tab);
492 static void otf_gsublang(void *otf, void *gsub, void *lang)
494 void *feats = gsub + U16(gsub, 6);
495 int featidx = U16(lang, 2);
496 int nfeat = U16(lang, 4);
497 int i;
498 if (featidx != 0xffff)
499 otf_gsubfeatrec(otf, gsub, feats + 2 + 6 * featidx);
500 for (i = 0; i < nfeat; i++)
501 otf_gsubfeatrec(otf, gsub,
502 feats + 2 + 6 * U16(lang, 6 + 2 * i));
505 static void otf_gsub(void *otf, void *gsub)
507 void *scripts = gsub + U16(gsub, 4);
508 int nscripts, nlangs;
509 void *script;
510 int i, j;
511 nscripts = U16(scripts, 0);
512 for (i = 0; i < nscripts; i++) {
513 script = scripts + U16(scripts + 2 + 6 * i, 4);
514 nlangs = U16(script, 2);
515 if (U16(script, 0))
516 otf_gsublang(otf, gsub, script + U16(script, 0));
517 for (j = 0; j < nlangs; j++)
518 otf_gsublang(otf, gsub, script +
519 U16(script, 4 + 6 * j + 4));
523 int xread(int fd, char *buf, int len)
525 int nr = 0;
526 while (nr < len) {
527 int ret = read(fd, buf + nr, len - nr);
528 if (ret == -1 && (errno == EAGAIN || errno == EINTR))
529 continue;
530 if (ret <= 0)
531 break;
532 nr += ret;
534 return nr;
537 static char buf[BUFLEN];
539 int otf_read(void)
541 int i;
542 if (xread(0, buf, sizeof(buf)) <= 0)
543 return 1;
544 upm = U16(otf_table(buf, "head"), 18);
545 otf_cmap(buf, otf_table(buf, "cmap"));
546 otf_post(buf, otf_table(buf, "post"));
547 if (otf_table(buf, "glyf"))
548 otf_glyf(buf, otf_table(buf, "glyf"));
549 otf_hmtx(buf, otf_table(buf, "hmtx"));
550 for (i = 0; i < glyph_n; i++) {
551 trfn_char(glyph_name[i], -1,
552 glyph_code[i] != 0xffff ? glyph_code[i] : 0,
553 owid(glyph_wid[i]),
554 owid(glyph_bbox[i][0]), owid(glyph_bbox[i][1]),
555 owid(glyph_bbox[i][2]), owid(glyph_bbox[i][3]));
557 if (otf_table(buf, "kern"))
558 otf_kern(buf, otf_table(buf, "kern"));
559 return 0;
562 void otf_feat(int r)
564 res = r;
565 if (otf_table(buf, "GSUB"))
566 otf_gsub(buf, otf_table(buf, "GSUB"));
567 if (otf_table(buf, "GPOS"))
568 otf_gpos(buf, otf_table(buf, "GPOS"));
571 static char *macset[] = {
572 ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
573 "quotedbl", "numbersign", "dollar", "percent", "ampersand",
574 "quotesingle", "parenleft", "parenright", "asterisk", "plus",
575 "comma", "hyphen", "period", "slash", "zero",
576 "one", "two", "three", "four", "five",
577 "six", "seven", "eight", "nine", "colon",
578 "semicolon", "less", "equal", "greater", "question",
579 "at", "A", "B", "C", "D",
580 "E", "F", "G", "H", "I",
581 "J", "K", "L", "M", "N",
582 "O", "P", "Q", "R", "S",
583 "T", "U", "V", "W", "X",
584 "Y", "Z", "bracketleft", "backslash", "bracketright",
585 "asciicircum", "underscore", "grave", "a", "b",
586 "c", "d", "e", "f", "g",
587 "h", "i", "j", "k", "l",
588 "m", "n", "o", "p", "q",
589 "r", "s", "t", "u", "v",
590 "w", "x", "y", "z", "braceleft",
591 "bar", "braceright", "asciitilde", "Adieresis", "Aring",
592 "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
593 "aacute", "agrave", "acircumflex", "adieresis", "atilde",
594 "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
595 "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
596 "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
597 "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
598 "dagger", "degree", "cent", "sterling", "section",
599 "bullet", "paragraph", "germandbls", "registered", "copyright",
600 "trademark", "acute", "dieresis", "notequal", "AE",
601 "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
602 "yen", "mu", "partialdiff", "summation", "product",
603 "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
604 "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
605 "radical", "florin", "approxequal", "Delta", "guillemotleft",
606 "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
607 "Otilde", "OE", "oe", "endash", "emdash",
608 "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
609 "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
610 "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
611 "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
612 "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
613 "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
614 "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
615 "dotlessi", "circumflex", "tilde", "macron", "breve",
616 "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
617 "caron", "Lslash", "lslash", "Scaron", "scaron",
618 "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
619 "Yacute", "yacute", "Thorn", "thorn", "minus",
620 "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
621 "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
622 "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
623 "Ccaron", "ccaron", "dcroat",