7 /* look up a character in chead[]/cnext[] table */
8 static int font_cidx(struct font
*fn
, char *name
)
10 int i
= fn
->chead
[(unsigned char) name
[0]];
11 while (i
>= 0 && strcmp(name
, fn
->c
[i
]))
16 /* look up a character in ghead[]/gnext[] table */
17 static int font_gidx(struct font
*fn
, char *id
)
19 int i
= fn
->ghead
[(unsigned char) id
[0]];
20 while (i
>= 0 && strcmp(fn
->glyphs
[i
].id
, id
))
25 struct glyph
*font_find(struct font
*fn
, char *name
)
27 int i
= font_cidx(fn
, name
);
30 return fn
->g_map
[i
] ? fn
->g_map
[i
] : fn
->g
[i
];
33 struct glyph
*font_glyph(struct font
*fn
, char *id
)
35 int i
= font_gidx(fn
, id
);
36 return i
>= 0 ? &fn
->glyphs
[i
] : NULL
;
39 static struct glyph
*font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
41 int i
= fn
->nglyphs
++;
45 strcpy(g
->name
, name
);
48 fn
->gnext
[i
] = fn
->ghead
[(unsigned char) id
[0]];
49 fn
->ghead
[(unsigned char) id
[0]] = i
;
53 /* map character name to the given glyph */
54 int font_map(struct font
*fn
, char *name
, struct glyph
*g
)
56 int i
= font_cidx(fn
, name
);
57 if (g
&& g
->font
!= fn
)
63 strcpy(fn
->c
[i
], name
);
64 fn
->cnext
[i
] = fn
->chead
[(unsigned char) name
[0]];
65 fn
->chead
[(unsigned char) name
[0]] = i
;
71 /* return nonzero if character name has been mapped with font_map() */
72 int font_mapped(struct font
*fn
, char *name
)
74 int i
= font_cidx(fn
, name
);
75 return i
>= 0 && fn
->g_map
[i
];
78 /* glyph index in fn->glyphs[] */
79 static int font_idx(struct font
*fn
, struct glyph
*g
)
81 return g
? g
- fn
->glyphs
: -1;
85 * Given a list of characters in the reverse order, font_lig()
86 * returns the number of characters from the beginning of this
87 * list that form a ligature in this font. Zero naturally means
88 * no ligature was matched.
90 int font_lig(struct font
*fn
, char **c
, int n
)
93 /* concatenated characters in c[], in the correct order */
94 char s
[GNLEN
* 2] = "";
95 /* b[i] is the number of character of c[] in s + i */
96 int b
[GNLEN
* 2] = {0};
98 for (i
= 0; i
< n
; i
++) {
99 char *cur
= c
[n
- i
- 1];
101 strcpy(s
+ len
, cur
);
104 for (i
= 0; i
< fn
->lgn
; i
++) {
105 int l
= strlen(fn
->lg
[i
]);
106 if (b
[len
- l
] > 1 && !strcmp(s
+ len
- l
, fn
->lg
[i
]))
107 if (font_find(fn
, fn
->lg
[i
]))
113 /* return nonzero if s is a ligature */
114 int font_islig(struct font
*fn
, char *s
)
117 for (i
= 0; i
< fn
->lgn
; i
++)
118 if (!strcmp(s
, fn
->lg
[i
]))
123 /* return pairwise kerning value between c1 and c2 */
124 int font_kern(struct font
*fn
, char *c1
, char *c2
)
127 i1
= font_idx(fn
, font_find(fn
, c1
));
128 i2
= font_idx(fn
, font_find(fn
, c2
));
129 if (i1
< 0 || i2
< 0)
133 if (fn
->knpair
[i
] == i2
)
140 static int font_readchar(struct font
*fn
, FILE *fin
)
145 struct glyph
*glyph
= NULL
;
147 if (fn
->n
>= NGLYPHS
)
149 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
151 if (!strcmp("---", name
))
152 sprintf(name
, "c%04d", fn
->n
);
153 if (!strcmp("\"", tok
)) {
154 glyph
= fn
->g
[fn
->n
- 1];
156 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
158 glyph
= font_glyph(fn
, id
);
160 glyph
= font_glyphput(fn
, id
, name
, type
);
161 sscanf(tok
, "%d,%d,%d,%d,%d", &glyph
->wid
,
162 &glyph
->llx
, &glyph
->lly
, &glyph
->urx
, &glyph
->ury
);
165 strcpy(fn
->c
[fn
->n
], name
);
166 fn
->g
[fn
->n
] = glyph
;
167 fn
->cnext
[fn
->n
] = fn
->chead
[(unsigned char) name
[0]];
168 fn
->chead
[(unsigned char) name
[0]] = fn
->n
;
173 static int font_readkern(struct font
*fn
, FILE *fin
)
175 char c1
[ILNLEN
], c2
[ILNLEN
];
177 if (fscanf(fin
, "%s %s %d", c1
, c2
, &val
) != 3)
179 i1
= font_idx(fn
, font_glyph(fn
, c1
));
180 i2
= font_idx(fn
, font_glyph(fn
, c2
));
181 if (fn
->knn
< NKERNS
&& i1
>= 0 && i2
>= 0) {
182 fn
->knnext
[fn
->knn
] = fn
->knhead
[i1
];
183 fn
->knhead
[i1
] = fn
->knn
;
184 fn
->knval
[fn
->knn
] = val
;
185 fn
->knpair
[fn
->knn
] = i2
;
191 static void skipline(FILE* filp
)
196 } while (c
!= '\n' && c
!= EOF
);
199 struct font
*font_open(char *path
)
205 fin
= fopen(path
, "r");
208 fn
= malloc(sizeof(*fn
));
213 memset(fn
, 0, sizeof(*fn
));
214 for (i
= 0; i
< LEN(fn
->ghead
); i
++)
216 for (i
= 0; i
< LEN(fn
->chead
); i
++)
218 for (i
= 0; i
< LEN(fn
->knhead
); i
++)
220 while (fscanf(fin
, "%s", tok
) == 1) {
221 if (!strcmp("char", tok
)) {
222 font_readchar(fn
, fin
);
223 } else if (!strcmp("kern", tok
)) {
224 font_readkern(fn
, fin
);
225 } else if (!strcmp("spacewidth", tok
)) {
226 fscanf(fin
, "%d", &fn
->spacewid
);
227 } else if (!strcmp("special", tok
)) {
229 } else if (!strcmp("name", tok
)) {
230 fscanf(fin
, "%s", fn
->name
);
231 } else if (!strcmp("fontname", tok
)) {
232 fscanf(fin
, "%s", fn
->fontname
);
233 } else if (!strcmp("ligatures", tok
)) {
234 while (fscanf(fin
, "%s", tok
) == 1) {
235 if (!strcmp("0", tok
))
238 strcpy(fn
->lg
[fn
->lgn
++], tok
);
240 } else if (!strcmp("charset", tok
)) {
241 while (!font_readchar(fn
, fin
))
251 void font_close(struct font
*fn
)