13 struct glyph
*gl
; /* glyphs present in the font */
14 int gl_n
, gl_sz
; /* number of glyphs in the font */
15 struct dict
*gl_dict
; /* mapping from gl[i].id to i */
16 struct dict
*ch_dict
; /* charset mapping */
17 struct dict
*ch_map
; /* character aliases */
20 /* find a glyph by its name */
21 struct glyph
*font_find(struct font
*fn
, char *name
)
23 int i
= dict_get(fn
->ch_dict
, name
);
24 if (i
< 0) /* maybe a character alias */
25 i
= dict_get(fn
->ch_map
, name
);
26 return i
>= 0 ? fn
->gl
+ i
: NULL
;
29 /* find a glyph by its device-dependent identifier */
30 struct glyph
*font_glyph(struct font
*fn
, char *id
)
32 int i
= dict_get(fn
->gl_dict
, id
);
33 return i
>= 0 ? &fn
->gl
[i
] : NULL
;
36 static int font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
39 if (fn
->gl_n
== fn
->gl_sz
) {
40 fn
->gl_sz
= fn
->gl_sz
+ 1024;
41 fn
->gl
= mextend(fn
->gl
, fn
->gl_n
, fn
->gl_sz
, sizeof(fn
->gl
[0]));
43 g
= &fn
->gl
[fn
->gl_n
];
45 strcpy(g
->name
, name
);
48 dict_put(fn
->gl_dict
, g
->id
, fn
->gl_n
);
52 static void tilleol(FILE *fin
, char *s
)
55 while (c
!= EOF
&& c
!= '\n') {
64 static int font_readchar(struct font
*fn
, FILE *fin
, int *n
, int *gid
)
71 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
73 if (!strcmp("---", name
))
74 sprintf(name
, "c%04d", *n
);
75 if (strcmp("\"", tok
)) {
76 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
78 *gid
= dict_get(fn
->gl_dict
, id
);
80 *gid
= font_glyphput(fn
, id
, name
, type
);
82 sscanf(tok
, "%d", &g
->wid
);
84 if (sscanf(tok
, "%d", &g
->pos
) != 1)
87 dict_put(fn
->ch_dict
, name
, *gid
);
90 dict_put(fn
->ch_map
, name
, *gid
);
95 static void skipline(FILE* filp
)
100 } while (c
!= '\n' && c
!= EOF
);
103 struct font
*font_open(char *path
)
106 int ch_g
= -1; /* last glyph in the charset */
107 int ch_n
= 0; /* number of glyphs in the charset */
110 fin
= fopen(path
, "r");
113 fn
= malloc(sizeof(*fn
));
118 memset(fn
, 0, sizeof(*fn
));
119 snprintf(fn
->desc
, sizeof(fn
->desc
), "%s", path
);
120 fn
->gl_dict
= dict_make(-1, 1, 0);
121 fn
->ch_dict
= dict_make(-1, 1, 0);
122 fn
->ch_map
= dict_make(-1, 1, 0);
123 while (fscanf(fin
, "%s", tok
) == 1) {
124 if (!strcmp("char", tok
)) {
125 font_readchar(fn
, fin
, &ch_n
, &ch_g
);
126 } else if (!strcmp("spacewidth", tok
)) {
127 fscanf(fin
, "%d", &fn
->spacewid
);
128 } else if (!strcmp("name", tok
)) {
129 fscanf(fin
, "%s", fn
->name
);
130 } else if (!strcmp("fontname", tok
)) {
131 fscanf(fin
, "%s", fn
->fontname
);
132 } else if (!strcmp("fontpath", tok
)) {
137 tilleol(fin
, fn
->fontpath
);
138 } else if (!strcmp("ligatures", tok
)) {
139 while (fscanf(fin
, "%s", tok
) == 1)
140 if (!strcmp("0", tok
))
142 } else if (!strcmp("charset", tok
)) {
143 while (!font_readchar(fn
, fin
, &ch_n
, &ch_g
))
153 void font_close(struct font
*fn
)
155 dict_free(fn
->gl_dict
);
156 dict_free(fn
->ch_dict
);
157 dict_free(fn
->ch_map
);
162 /* return width w for the given font and size */
163 int font_wid(struct font
*fn
, int sz
, int w
)
165 return (w
* sz
+ dev_uwid
/ 2) / dev_uwid
;
168 /* space width for the give word space or sentence space */
169 int font_swid(struct font
*fn
, int sz
)
171 return font_wid(fn
, sz
, fn
->spacewid
);
174 char *font_name(struct font
*fn
)
179 char *font_path(struct font
*fn
)
184 int font_glnum(struct font
*fn
, struct glyph
*g
)
189 struct glyph
*font_glget(struct font
*fn
, int id
)
191 return id
>= 0 && id
< fn
->gl_n
? &fn
->gl
[id
] : NULL
;
194 char *font_desc(struct font
*fn
)