otf: use ggrp lines to define groups of glyphs
[neatmkfn.git] / mkfn.c
blob4227882695adbd6ace143fe4b4a32f9b0666c9e7
1 /*
2 * mktrfn - produce troff font descriptions
4 * Copyright (C) 2012-2014 Ali Gholami Rudi <ali at rudi dot ir>
6 * This program is released under the Modified BSD license.
7 */
8 #include <ctype.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include "trfn.h"
16 #define TOKLEN 256
18 static char *trfn_scripts; /* filtered scripts */
19 static char *trfn_langs; /* filtered languages */
21 static char *afm_charfield(char *s, char *d)
23 while (*s && !isspace(*s) && *s != ';')
24 *d++ = *s++;
25 while (isspace(*s) || *s == ';')
26 s++;
27 *d = '\0';
28 return s;
31 static int afm_read(void)
33 char ln[1024];
34 char ch[TOKLEN] = "", pos[TOKLEN] = "";
35 char c1[TOKLEN] = "", c2[TOKLEN] = "";
36 char wid[TOKLEN] = "", field[TOKLEN] = "";
37 char llx[TOKLEN] = "0", lly[TOKLEN] = "0";
38 char urx[TOKLEN] = "0", ury[TOKLEN] = "0";
39 char *s;
40 while (fgets(ln, sizeof(ln), stdin)) {
41 if (ln[0] == '#')
42 continue;
43 if (!strncmp("FontName ", ln, 8)) {
44 sscanf(ln, "FontName %s", ch);
45 trfn_psfont(ch);
46 continue;
48 if (!strncmp("StartCharMetrics", ln, 16))
49 break;
51 while (fgets(ln, sizeof(ln), stdin)) {
52 if (ln[0] == '#')
53 continue;
54 if (!strncmp("EndCharMetrics", ln, 14))
55 break;
56 s = ln;
57 while (*s) {
58 s = afm_charfield(s, field);
59 if (!strcmp("C", field)) {
60 s = afm_charfield(s, pos);
61 continue;
63 if (!strcmp("WX", field)) {
64 s = afm_charfield(s, wid);
65 continue;
67 if (!strcmp("N", field)) {
68 s = afm_charfield(s, ch);
69 continue;
71 if (!strcmp("B", field)) {
72 s = afm_charfield(s, llx);
73 s = afm_charfield(s, lly);
74 s = afm_charfield(s, urx);
75 s = afm_charfield(s, ury);
76 continue;
78 if (!strcmp("L", field)) {
79 s = afm_charfield(s, c1);
80 s = afm_charfield(s, c2);
81 continue;
83 break;
85 if (ch[0] && pos[0] && wid[0])
86 trfn_char(ch, atoi(pos), 0, atoi(wid),
87 atoi(llx), atoi(lly), atoi(urx), atoi(ury));
89 while (fgets(ln, sizeof(ln), stdin)) {
90 if (ln[0] == '#')
91 continue;
92 if (!strncmp("StartKernPairs", ln, 14))
93 break;
95 while (fgets(ln, sizeof(ln), stdin)) {
96 if (ln[0] == '#')
97 continue;
98 if (!strncmp("EndKernPairs", ln, 12))
99 break;
100 if (sscanf(ln, "KPX %s %s %s", c1, c2, wid) == 3)
101 trfn_kern(c1, c2, atoi(wid));
103 return 0;
106 /* return 1 if script script is to be included */
107 int trfn_script(char *script, int nscripts)
109 if (!trfn_scripts)
110 return nscripts == 1 || !script ||
111 !strcmp("DFLT", script) || !strcmp("latn", script);
112 if (!strcmp("help", trfn_scripts))
113 fprintf(stderr, "script: %s\n", script ? script : "");
114 if (strchr(script, ' '))
115 *strchr(script, ' ') = '\0';
116 return !!strstr(trfn_scripts, script);
119 /* return 1 if language lang is to be included */
120 int trfn_lang(char *lang, int nlangs)
122 if (!trfn_langs)
123 return nlangs == 1 || !lang;
124 if (!lang)
125 lang = "";
126 if (!strcmp("help", trfn_langs))
127 fprintf(stderr, "lang: %s\n", lang);
128 if (strchr(lang, ' '))
129 *strchr(lang, ' ') = '\0';
130 return !!strstr(trfn_langs, lang);
133 int otf_read(void);
134 void otf_feat(int res, int kmin, int warn);
136 static char *usage =
137 "Usage: mktrfn [options] <input >output\n"
138 "Options:\n"
139 " -a \tread an AFM file (default)\n"
140 " -o \tread an OTF file\n"
141 " -s \tspecial font\n"
142 " -p name \toverride font postscript name\n"
143 " -t name \tset font troff name\n"
144 " -r res \tset device resolution (720)\n"
145 " -k kmin \tspecify the minimum amount of kerning (0)\n"
146 " -b \tinclude glyph bounding boxes\n"
147 " -S scrs \tcomma-separated list of scripts to include (help to list)\n"
148 " -L langs\tcomma-separated list of languages to include (help to list)\n"
149 " -w \twarn about unsupported font features\n";
151 int main(int argc, char *argv[])
153 int afm = 1;
154 int res = 720;
155 int spc = 0;
156 int kmin = 0;
157 int bbox = 0;
158 int warn = 0;
159 int i;
160 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
161 switch (argv[i][1]) {
162 case 'a':
163 afm = 1;
164 break;
165 case 'b':
166 bbox = 1;
167 break;
168 case 'k':
169 kmin = atoi(argv[i][2] ? argv[i] + 2 : argv[++i]);
170 break;
171 case 'L':
172 trfn_langs = argv[i][2] ? argv[i] + 2 : argv[++i];
173 break;
174 case 'o':
175 afm = 0;
176 break;
177 case 'p':
178 trfn_psfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
179 break;
180 case 'r':
181 res = atoi(argv[i][2] ? argv[i] + 2 : argv[++i]);
182 break;
183 case 's':
184 spc = 1;
185 break;
186 case 'S':
187 trfn_scripts = argv[i][2] ? argv[i] + 2 : argv[++i];
188 break;
189 case 't':
190 trfn_trfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
191 break;
192 case 'w':
193 warn = 1;
194 break;
195 default:
196 printf("%s", usage);
197 return 0;
200 trfn_init(res, spc, kmin, bbox);
201 if (afm)
202 afm_read();
203 else
204 otf_read();
205 trfn_print();
206 if (!afm)
207 otf_feat(res, kmin, warn);
208 trfn_done();
209 return 0;