6 static void skipline(FILE* filp
)
11 } while (c
!= '\n' && c
!= EOF
);
14 struct glyph
*font_find(struct font
*fn
, char *name
)
16 int i
= fn
->head
[(unsigned char) name
[0]];
18 if (!strcmp(name
, fn
->c
[i
]))
25 struct glyph
*font_glyph(struct font
*fn
, char *id
)
28 for (i
= 0; i
< fn
->nglyphs
; i
++)
29 if (!strcmp(fn
->glyphs
[i
].id
, id
))
30 return &fn
->glyphs
[i
];
34 static int font_idx(struct font
*fn
, struct glyph
*g
)
36 return g
? g
- fn
->glyphs
: -1;
40 * Given a list of characters in the reverse order, font_lig()
41 * returns the number of characters from the beginning of this
42 * list that form a ligature in this font. Zero naturally means
43 * no ligature was matched.
45 int font_lig(struct font
*fn
, char **c
, int n
)
48 /* concatenated characters in c[], in the correct order */
49 char s
[GNLEN
* 2] = "";
50 /* b[i] is the number of character of c[] in s + i */
51 int b
[GNLEN
* 2] = {0};
53 for (i
= 0; i
< n
; i
++) {
54 char *cur
= c
[n
- i
- 1];
59 for (i
= 0; i
< fn
->nlig
; i
++) {
60 int l
= strlen(fn
->lig
[i
]);
61 if (b
[len
- l
] > 1 && !strcmp(s
+ len
- l
, fn
->lig
[i
]))
62 if (font_find(fn
, fn
->lig
[i
]))
68 /* return pairwise kerning value between c1 and c2 */
69 int font_kern(struct font
*fn
, char *c1
, char *c2
)
72 i1
= font_idx(fn
, font_find(fn
, c1
));
73 i2
= font_idx(fn
, font_find(fn
, c2
));
78 if (fn
->knpair
[i
] == i2
)
85 static int font_section(struct font
*fn
, FILE *fin
, char *name
);
87 static void font_charset(struct font
*fn
, FILE *fin
)
92 struct glyph
*glyph
= NULL
;
93 struct glyph
*prev
= NULL
;
95 while (fscanf(fin
, "%s", name
) == 1) {
96 if (!font_section(fn
, fin
, name
))
98 if (fn
->n
>= NGLYPHS
) {
102 fscanf(fin
, "%s", tok
);
104 if (!strcmp("---", name
))
105 sprintf(name
, "c%04d", fn
->n
);
106 if (strcmp("\"", tok
)) {
108 fscanf(fin
, "%d %s", &type
, id
);
110 glyph
= &fn
->glyphs
[fn
->nglyphs
++];
111 strcpy(glyph
->id
, id
);
112 strcpy(glyph
->name
, name
);
118 strcpy(fn
->c
[fn
->n
], name
);
119 fn
->g
[fn
->n
] = glyph
;
120 fn
->next
[fn
->n
] = fn
->head
[(unsigned char) name
[0]];
121 fn
->head
[(unsigned char) name
[0]] = fn
->n
;
126 static void font_kernpairs(struct font
*fn
, FILE *fin
)
128 char c1
[ILNLEN
], c2
[ILNLEN
];
130 while (fscanf(fin
, "%s", c1
) == 1) {
131 if (!font_section(fn
, fin
, c1
))
133 if (fscanf(fin
, "%s %d", c2
, &val
) != 2)
135 if (fn
->knn
< NKERNS
) {
136 i1
= font_idx(fn
, font_find(fn
, c1
));
137 i2
= font_idx(fn
, font_find(fn
, c2
));
138 if (i1
>= 0 && i2
>= 0) {
139 fn
->knnext
[fn
->knn
] = fn
->knhead
[i1
];
140 fn
->knhead
[i1
] = fn
->knn
;
141 fn
->knval
[fn
->knn
] = val
;
142 fn
->knpair
[fn
->knn
] = i2
;
149 static int font_section(struct font
*fn
, FILE *fin
, char *name
)
151 if (!strcmp("charset", name
)) {
152 font_charset(fn
, fin
);
155 if (!strcmp("kernpairs", name
)) {
156 font_kernpairs(fn
, fin
);
162 struct font
*font_open(char *path
)
168 fin
= fopen(path
, "r");
171 fn
= malloc(sizeof(*fn
));
172 memset(fn
, 0, sizeof(*fn
));
173 for (i
= 0; i
< LEN(fn
->head
); i
++)
175 for (i
= 0; i
< LEN(fn
->knhead
); i
++)
177 while (fscanf(fin
, "%s", tok
) == 1) {
182 if (!strcmp("spacewidth", tok
)) {
183 fscanf(fin
, "%d", &fn
->spacewid
);
186 if (!strcmp("special", tok
)) {
190 if (!strcmp("name", tok
)) {
191 fscanf(fin
, "%s", fn
->name
);
194 if (!strcmp("fontname", tok
)) {
195 fscanf(fin
, "%s", fn
->fontname
);
198 if (!strcmp("named", tok
)) {
202 if (!strcmp("ligatures", tok
)) {
203 while (fscanf(fin
, "%s", tok
) == 1) {
204 if (!strcmp("0", tok
))
206 if (fn
->nlig
< NLIGS
)
207 strcpy(fn
->lig
[fn
->nlig
++], tok
);
212 if (!font_section(fn
, fin
, tok
))
220 void font_close(struct font
*fn
)