11 struct glyph
*gl
; /* glyphs present in the font */
12 int gl_n
, gl_sz
; /* number of glyphs in the font */
13 struct dict
*gl_dict
; /* mapping from gl[i].id to i */
14 struct dict
*ch_dict
; /* charset mapping */
15 struct dict
*ch_map
; /* character aliases */
18 /* find a glyph by its name */
19 struct glyph
*font_find(struct font
*fn
, char *name
)
21 int i
= dict_get(fn
->ch_dict
, name
);
22 if (i
< 0) /* maybe a character alias */
23 i
= dict_get(fn
->ch_map
, name
);
24 return i
>= 0 ? fn
->gl
+ i
: NULL
;
27 /* find a glyph by its device-dependent identifier */
28 struct glyph
*font_glyph(struct font
*fn
, char *id
)
30 int i
= dict_get(fn
->gl_dict
, id
);
31 return i
>= 0 ? &fn
->gl
[i
] : NULL
;
34 static int font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
37 if (fn
->gl_n
== fn
->gl_sz
) {
38 fn
->gl_sz
= fn
->gl_sz
+ 1024;
39 fn
->gl
= mextend(fn
->gl
, fn
->gl_n
, fn
->gl_sz
, sizeof(fn
->gl
[0]));
41 g
= &fn
->gl
[fn
->gl_n
];
43 strcpy(g
->name
, name
);
46 dict_put(fn
->gl_dict
, g
->id
, fn
->gl_n
);
50 static void tilleol(FILE *fin
, char *s
)
53 while (c
!= EOF
&& c
!= '\n') {
62 static int font_readchar(struct font
*fn
, FILE *fin
, int *n
, int *gid
)
69 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
71 if (!strcmp("---", name
))
72 sprintf(name
, "c%04d", *n
);
73 if (strcmp("\"", tok
)) {
74 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
76 *gid
= dict_get(fn
->gl_dict
, id
);
78 *gid
= font_glyphput(fn
, id
, name
, type
);
80 sscanf(tok
, "%d", &g
->wid
);
82 if (sscanf(tok
, "%d", &g
->pos
) != 1)
85 dict_put(fn
->ch_dict
, name
, *gid
);
88 dict_put(fn
->ch_map
, name
, *gid
);
93 static void skipline(FILE* filp
)
98 } while (c
!= '\n' && c
!= EOF
);
101 struct font
*font_open(char *path
)
104 int ch_g
= -1; /* last glyph in the charset */
105 int ch_n
= 0; /* number of glyphs in the charset */
108 fin
= fopen(path
, "r");
111 fn
= xmalloc(sizeof(*fn
));
116 memset(fn
, 0, sizeof(*fn
));
117 fn
->gl_dict
= dict_make(-1, 1);
118 fn
->ch_dict
= dict_make(-1, 1);
119 fn
->ch_map
= dict_make(-1, 1);
120 while (fscanf(fin
, "%s", tok
) == 1) {
121 if (!strcmp("char", tok
)) {
122 font_readchar(fn
, fin
, &ch_n
, &ch_g
);
123 } else if (!strcmp("spacewidth", tok
)) {
124 fscanf(fin
, "%d", &fn
->spacewid
);
125 } else if (!strcmp("name", tok
)) {
126 fscanf(fin
, "%s", fn
->name
);
127 } else if (!strcmp("fontname", tok
)) {
128 fscanf(fin
, "%s", fn
->fontname
);
129 } else if (!strcmp("ligatures", tok
)) {
130 while (fscanf(fin
, "%s", tok
) == 1)
131 if (!strcmp("0", tok
))
133 } else if (!strcmp("charset", tok
)) {
134 while (!font_readchar(fn
, fin
, &ch_n
, &ch_g
))
144 void font_close(struct font
*fn
)
146 dict_free(fn
->gl_dict
);
147 dict_free(fn
->ch_dict
);
148 dict_free(fn
->ch_map
);
153 /* return width w for the given font and size */
154 int font_wid(struct font
*fn
, int sz
, int w
)
156 return (w
* sz
+ dev_uwid
/ 2) / dev_uwid
;
159 /* space width for the give word space or sentence space */
160 int font_swid(struct font
*fn
, int sz
)
162 return font_wid(fn
, sz
, fn
->spacewid
);
165 char *font_name(struct font
*fn
)