12 struct glyph
*gl
; /* glyphs present in the font */
13 int gl_n
, gl_sz
; /* number of glyphs in the font */
14 struct dict
*gl_dict
; /* mapping from gl[i].id to i */
15 struct dict
*ch_dict
; /* charset mapping */
16 struct dict
*ch_map
; /* character aliases */
19 /* find a glyph by its name */
20 struct glyph
*font_find(struct font
*fn
, char *name
)
22 int i
= dict_get(fn
->ch_dict
, name
);
23 if (i
< 0) /* maybe a character alias */
24 i
= dict_get(fn
->ch_map
, name
);
25 return i
>= 0 ? fn
->gl
+ i
: NULL
;
28 /* find a glyph by its device-dependent identifier */
29 struct glyph
*font_glyph(struct font
*fn
, char *id
)
31 int i
= dict_get(fn
->gl_dict
, id
);
32 return i
>= 0 ? &fn
->gl
[i
] : NULL
;
35 static int font_glyphput(struct font
*fn
, char *id
, char *name
, int type
)
38 if (fn
->gl_n
== fn
->gl_sz
) {
39 fn
->gl_sz
= fn
->gl_sz
+ 1024;
40 fn
->gl
= mextend(fn
->gl
, fn
->gl_n
, fn
->gl_sz
, sizeof(fn
->gl
[0]));
42 g
= &fn
->gl
[fn
->gl_n
];
44 strcpy(g
->name
, name
);
47 dict_put(fn
->gl_dict
, g
->id
, fn
->gl_n
);
51 static void tilleol(FILE *fin
, char *s
)
54 while (c
!= EOF
&& c
!= '\n') {
63 static int font_readchar(struct font
*fn
, FILE *fin
, int *n
, int *gid
)
70 if (fscanf(fin
, "%s %s", name
, tok
) != 2)
72 if (!strcmp("---", name
))
73 sprintf(name
, "c%04d", *n
);
74 if (strcmp("\"", tok
)) {
75 if (fscanf(fin
, "%d %s", &type
, id
) != 2)
77 *gid
= dict_get(fn
->gl_dict
, id
);
79 *gid
= font_glyphput(fn
, id
, name
, type
);
81 sscanf(tok
, "%d", &g
->wid
);
83 if (sscanf(tok
, "%d", &g
->pos
) != 1)
86 dict_put(fn
->ch_dict
, name
, *gid
);
89 dict_put(fn
->ch_map
, name
, *gid
);
94 static void skipline(FILE* filp
)
99 } while (c
!= '\n' && c
!= EOF
);
102 struct font
*font_open(char *path
)
105 int ch_g
= -1; /* last glyph in the charset */
106 int ch_n
= 0; /* number of glyphs in the charset */
109 fin
= fopen(path
, "r");
112 fn
= malloc(sizeof(*fn
));
117 memset(fn
, 0, sizeof(*fn
));
118 fn
->gl_dict
= dict_make(-1, 1);
119 fn
->ch_dict
= dict_make(-1, 1);
120 fn
->ch_map
= dict_make(-1, 1);
121 while (fscanf(fin
, "%s", tok
) == 1) {
122 if (!strcmp("char", tok
)) {
123 font_readchar(fn
, fin
, &ch_n
, &ch_g
);
124 } else if (!strcmp("spacewidth", tok
)) {
125 fscanf(fin
, "%d", &fn
->spacewid
);
126 } else if (!strcmp("name", tok
)) {
127 fscanf(fin
, "%s", fn
->name
);
128 } else if (!strcmp("fontname", tok
)) {
129 fscanf(fin
, "%s", fn
->fontname
);
130 } else if (!strcmp("fontpath", tok
)) {
135 tilleol(fin
, fn
->fontpath
);
136 } else if (!strcmp("ligatures", tok
)) {
137 while (fscanf(fin
, "%s", tok
) == 1)
138 if (!strcmp("0", tok
))
140 } else if (!strcmp("charset", tok
)) {
141 while (!font_readchar(fn
, fin
, &ch_n
, &ch_g
))
151 void font_close(struct font
*fn
)
153 dict_free(fn
->gl_dict
);
154 dict_free(fn
->ch_dict
);
155 dict_free(fn
->ch_map
);
160 /* return width w for the given font and size */
161 int font_wid(struct font
*fn
, int sz
, int w
)
163 return (w
* sz
+ dev_uwid
/ 2) / dev_uwid
;
166 /* space width for the give word space or sentence space */
167 int font_swid(struct font
*fn
, int sz
)
169 return font_wid(fn
, sz
, fn
->spacewid
);
172 char *font_name(struct font
*fn
)
177 char *font_path(struct font
*fn
)
182 int font_glnum(struct font
*fn
, struct glyph
*g
)
187 struct glyph
*font_glget(struct font
*fn
, int id
)
189 return id
>= 0 && id
< fn
->gl_n
? &fn
->gl
[id
] : NULL
;