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 */
17 /* find a glyph by its name */
18 struct glyph
*font_find(struct font
*fn
, char *name
)
20 int i
= dict_get(fn
->ch_dict
, name
);
21 return i
>= 0 ? fn
->gl
+ i
: NULL
;
24 /* find a glyph by its device-dependent identifier */
25 struct glyph
*font_glyph(struct font
*fn
, char *id
)
27 int i
= dict_get(fn
->gl_dict
, id
);
28 return i
>= 0 ? &fn
->gl
[i
] : NULL
;
31 static int font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
34 if (fn
->gl_n
== fn
->gl_sz
) {
35 fn
->gl_sz
= fn
->gl_sz
+ 1024;
36 fn
->gl
= mextend(fn
->gl
, fn
->gl_n
, fn
->gl_sz
, sizeof(fn
->gl
[0]));
38 g
= &fn
->gl
[fn
->gl_n
];
40 strcpy(g
->name
, name
);
43 dict_put(fn
->gl_dict
, g
->id
, fn
->gl_n
);
47 static void tilleol(FILE *fin
, char *s
)
50 while (c
!= EOF
&& c
!= '\n') {
59 static int font_readchar(struct font
*fn
, FILE *fin
, int *n
, int *gid
)
66 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
68 if (!strcmp("---", name
))
69 sprintf(name
, "c%04d", *n
);
70 if (strcmp("\"", tok
)) {
71 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
73 *gid
= dict_get(fn
->gl_dict
, id
);
75 *gid
= font_glyphput(fn
, id
, name
, type
);
77 sscanf(tok
, "%d", &g
->wid
);
79 if (sscanf(tok
, "%d", &g
->pos
) != 1)
83 dict_put(fn
->ch_dict
, name
, *gid
);
88 static void skipline(FILE* filp
)
93 } while (c
!= '\n' && c
!= EOF
);
96 struct font
*font_open(char *path
)
99 int ch_g
= -1; /* last glyph in the charset */
100 int ch_n
= 0; /* number of glyphs in the charset */
103 fin
= fopen(path
, "r");
106 fn
= xmalloc(sizeof(*fn
));
111 memset(fn
, 0, sizeof(*fn
));
112 fn
->gl_dict
= dict_make(-1, 1);
113 fn
->ch_dict
= dict_make(-1, 1);
114 while (fscanf(fin
, "%s", tok
) == 1) {
115 if (!strcmp("char", tok
)) {
116 font_readchar(fn
, fin
, &ch_n
, &ch_g
);
117 } else if (!strcmp("spacewidth", tok
)) {
118 fscanf(fin
, "%d", &fn
->spacewid
);
119 } else if (!strcmp("name", tok
)) {
120 fscanf(fin
, "%s", fn
->name
);
121 } else if (!strcmp("fontname", tok
)) {
122 fscanf(fin
, "%s", fn
->fontname
);
123 } else if (!strcmp("ligatures", tok
)) {
124 while (fscanf(fin
, "%s", tok
) == 1)
125 if (!strcmp("0", tok
))
127 } else if (!strcmp("charset", tok
)) {
128 while (!font_readchar(fn
, fin
, &ch_n
, &ch_g
))
138 void font_close(struct font
*fn
)
140 dict_free(fn
->gl_dict
);
141 dict_free(fn
->ch_dict
);
146 /* return width w for the given font and size */
147 int font_wid(struct font
*fn
, int sz
, int w
)
149 return (w
* sz
+ dev_uwid
/ 2) / dev_uwid
;
152 /* space width for the give word space or sentence space */
153 int font_swid(struct font
*fn
, int sz
)
155 return font_wid(fn
, sz
, fn
->spacewid
);
158 char *font_name(struct font
*fn
)