7 /* find a glyph by its name */
8 struct glyph
*font_find(struct font
*fn
, char *name
)
10 int i
= dict_get(&fn
->cdict
, name
);
13 return fn
->g_map
[i
] ? fn
->g_map
[i
] : fn
->g
[i
];
16 /* find a glyph by its device-dependent identifier */
17 struct glyph
*font_glyph(struct font
*fn
, char *id
)
19 int i
= dict_get(&fn
->gdict
, id
);
20 return i
>= 0 ? &fn
->glyphs
[i
] : NULL
;
23 static struct glyph
*font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
25 int i
= fn
->nglyphs
++;
29 strcpy(g
->name
, name
);
32 dict_put(&fn
->gdict
, g
->id
, i
);
36 /* map character name to the given glyph */
37 int font_map(struct font
*fn
, char *name
, struct glyph
*g
)
39 int i
= dict_get(&fn
->cdict
, name
);
40 if (g
&& g
->font
!= fn
)
46 strcpy(fn
->c
[i
], name
);
47 dict_put(&fn
->cdict
, fn
->c
[i
], i
);
53 /* return nonzero if character name has been mapped with font_map() */
54 int font_mapped(struct font
*fn
, char *name
)
56 int i
= dict_get(&fn
->cdict
, name
);
57 return i
>= 0 && fn
->g_map
[i
];
60 /* glyph index in fn->glyphs[] */
61 static int font_idx(struct font
*fn
, struct glyph
*g
)
63 return g
? g
- fn
->glyphs
: -1;
67 * Given a list of characters in the reverse order, font_lig()
68 * returns the number of characters from the beginning of this
69 * list that form a ligature in this font. Zero naturally means
70 * no ligature was matched.
72 int font_lig(struct font
*fn
, char **c
, int n
)
75 /* concatenated characters in c[], in the correct order */
76 char s
[GNLEN
* 2] = "";
77 /* b[i] is the number of character of c[] in s + i */
78 int b
[GNLEN
* 2] = {0};
80 for (i
= 0; i
< n
; i
++) {
81 char *cur
= c
[n
- i
- 1];
86 for (i
= 0; i
< fn
->lgn
; i
++) {
87 int l
= strlen(fn
->lg
[i
]);
88 if (b
[len
- l
] > 1 && !strcmp(s
+ len
- l
, fn
->lg
[i
]))
89 if (font_find(fn
, fn
->lg
[i
]))
95 /* return nonzero if s is a ligature */
96 int font_islig(struct font
*fn
, char *s
)
99 for (i
= 0; i
< fn
->lgn
; i
++)
100 if (!strcmp(s
, fn
->lg
[i
]))
105 /* return pairwise kerning value between c1 and c2 */
106 int font_kern(struct font
*fn
, char *c1
, char *c2
)
109 i1
= font_idx(fn
, font_find(fn
, c1
));
110 i2
= font_idx(fn
, font_find(fn
, c2
));
111 if (i1
< 0 || i2
< 0)
115 if (fn
->knpair
[i
] == i2
)
122 static int font_readchar(struct font
*fn
, FILE *fin
)
127 struct glyph
*glyph
= NULL
;
129 if (fn
->n
>= NGLYPHS
)
131 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
133 if (!strcmp("---", name
))
134 sprintf(name
, "c%04d", fn
->n
);
135 if (!strcmp("\"", tok
)) {
136 glyph
= fn
->g
[fn
->n
- 1];
138 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
140 glyph
= font_glyph(fn
, id
);
142 glyph
= font_glyphput(fn
, id
, name
, type
);
143 sscanf(tok
, "%d,%d,%d,%d,%d", &glyph
->wid
,
144 &glyph
->llx
, &glyph
->lly
, &glyph
->urx
, &glyph
->ury
);
147 strcpy(fn
->c
[fn
->n
], name
);
148 fn
->g
[fn
->n
] = glyph
;
149 dict_put(&fn
->cdict
, fn
->c
[fn
->n
], fn
->n
);
154 static int font_readkern(struct font
*fn
, FILE *fin
)
156 char c1
[ILNLEN
], c2
[ILNLEN
];
158 if (fscanf(fin
, "%s %s %d", c1
, c2
, &val
) != 3)
160 i1
= font_idx(fn
, font_glyph(fn
, c1
));
161 i2
= font_idx(fn
, font_glyph(fn
, c2
));
162 if (fn
->knn
< NKERNS
&& i1
>= 0 && i2
>= 0) {
163 fn
->knnext
[fn
->knn
] = fn
->knhead
[i1
];
164 fn
->knhead
[i1
] = fn
->knn
;
165 fn
->knval
[fn
->knn
] = val
;
166 fn
->knpair
[fn
->knn
] = i2
;
172 static void skipline(FILE* filp
)
177 } while (c
!= '\n' && c
!= EOF
);
180 struct font
*font_open(char *path
)
186 fin
= fopen(path
, "r");
189 fn
= malloc(sizeof(*fn
));
194 memset(fn
, 0, sizeof(*fn
));
195 dict_init(&fn
->gdict
, NGLYPHS
, -1, 0, 0);
196 dict_init(&fn
->cdict
, NGLYPHS
, -1, 0, 0);
197 for (i
= 0; i
< LEN(fn
->knhead
); i
++)
199 while (fscanf(fin
, "%s", tok
) == 1) {
200 if (!strcmp("char", tok
)) {
201 font_readchar(fn
, fin
);
202 } else if (!strcmp("kern", tok
)) {
203 font_readkern(fn
, fin
);
204 } else if (!strcmp("spacewidth", tok
)) {
205 fscanf(fin
, "%d", &fn
->spacewid
);
206 } else if (!strcmp("special", tok
)) {
208 } else if (!strcmp("name", tok
)) {
209 fscanf(fin
, "%s", fn
->name
);
210 } else if (!strcmp("fontname", tok
)) {
211 fscanf(fin
, "%s", fn
->fontname
);
212 } else if (!strcmp("ligatures", tok
)) {
213 while (fscanf(fin
, "%s", tok
) == 1) {
214 if (!strcmp("0", tok
))
217 strcpy(fn
->lg
[fn
->lgn
++], tok
);
219 } else if (!strcmp("charset", tok
)) {
220 while (!font_readchar(fn
, fin
))
230 void font_close(struct font
*fn
)