src/gf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- GF_CacheLoader
- GF_CacheDisposer
- gf_loader
- gf_read_glyph
1 /*
2 * gf.c - TeX GF format font fonts loader.
3 *
4 * 28 Sep 1996 First version.
5 * 30 Jan 1998 VFlib 3.4 Changed API.
6 * 16 Sep 1999 Changed not to use TFM
7 */
8 /*
9 * Copyright (C) 1996-1999 Hirotsugu Kakugawa.
10 * All rights reserved.
11 *
12 * This file is part of the VFlib Library. This library is free
13 * software; you can redistribute it and/or modify it under the terms of
14 * the GNU Library General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. This library is distributed in the hope
17 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25
26 Private GF_GLYPH gf_loader(VF_CACHE,FILE*);
27 Private int gf_read_glyph(FILE*,VF_BITMAP);
28
29 Private unsigned char bit_table[] = {
30 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
31
32
33 Private GF_GLYPH
34 GF_CacheLoader(VF_CACHE c, char *font_path, int l)
/* [<][>][^][v][top][bottom][index][help] */
35 {
36 FILE *fp;
37 UINT1 pre, id;
38 UINT4 k;
39
40 if (font_path == NULL)
41 return NULL;
42 if ((fp = vf_fm_OpenBinaryFileStream(font_path)) == NULL)
43 return NULL;
44
45 pre = READ_UINT1(fp);
46 if (pre != GF_PRE)
47 return NULL;
48 id = READ_UINT1(fp);
49 if (id != GF_ID)
50 return NULL;
51 k = READ_UINT1(fp);
52 SKIP_N(fp, k);
53
54 return gf_loader(c, fp);
55 }
56
57 Private void
58 GF_CacheDisposer(GF_GLYPH go)
/* [<][>][^][v][top][bottom][index][help] */
59 {
60 int nc, i;
61
62 if (go != NULL){
63 if (go->bm_table != NULL){
64 nc = go->code_max - go->code_min + 1;
65 for (i = 0; i < nc; i++)
66 vf_free(go->bm_table[i].bitmap);
67 vf_free(go->bm_table);
68 }
69 vf_free(go);
70 }
71 }
72
73
74
75 Private GF_GLYPH
76 gf_loader(VF_CACHE c, FILE* fp)
/* [<][>][^][v][top][bottom][index][help] */
77 {
78 GF_GLYPH go;
79 VF_BITMAP bm;
80 UINT1 instr, d;
81 UINT4 ds, check_sum, hppp, vppp;
82 INT4 min_m, max_m, min_n, max_n;
83 INT4 w;
84 UINT4 code;
85 double dx, dy;
86 long ptr_post, ptr_p, ptr, optr, gptr;
87 int bc, ec, nchars, i;
88
89 go = NULL;
90 nchars = -1;
91
92 /* seek to post_post instr. */
93 fseek(fp, -1, SEEK_END);
94 while ((d = READ_UINT1(fp)) == 223)
95 fseek(fp, -2, SEEK_CUR);
96 if (d != GF_ID){
97 vf_error = VF_ERR_ILL_FONT_FILE;
98 goto ErrExit;
99 }
100 fseek(fp, -6, SEEK_CUR);
101
102 /* check if the code is post_post */
103 if (READ_UINT1(fp) != GF_POST_POST){
104 vf_error = VF_ERR_ILL_FONT_FILE;
105 goto ErrExit;
106 }
107
108 /* read pointer to post instr. */
109 if ((ptr_post = READ_UINT4(fp)) == -1){
110 vf_error = VF_ERR_ILL_FONT_FILE;
111 goto ErrExit;
112 }
113
114 /* goto post instr. and read it */
115 fseek(fp, ptr_post, SEEK_SET);
116 if (READ_UINT1(fp) != GF_POST){
117 vf_error = VF_ERR_ILL_FONT_FILE;
118 goto ErrExit;
119 }
120 ptr_p = READ_UINT4(fp);
121 ds = READ_UINT4(fp);
122 check_sum = READ_UINT4(fp);
123 hppp = READ_UINT4(fp);
124 vppp = READ_UINT4(fp);
125 min_m = READ_INT4(fp);
126 max_m = READ_INT4(fp);
127 min_n = READ_INT4(fp);
128 max_n = READ_INT4(fp);
129
130 gptr = ftell(fp);
131
132 #if 0
133 /* read min & max char code */
134 bc = 256;
135 ec = -1;
136 for (;;){
137 instr = READ_UINT1(fp);
138 if (instr == GF_POST_POST){
139 break;
140 } else if (instr == GF_CHAR_LOC){
141 code = READ_UINT1(fp);
142 (void)SKIP_N(fp, 16);
143 } else if (instr == GF_CHAR_LOC0){
144 code = READ_UINT1(fp);
145 (void)SKIP_N(fp, 9);
146 } else {
147 vf_error = VF_ERR_ILL_FONT_FILE;
148 goto ErrExit;
149 }
150 if (code < bc)
151 bc = code;
152 if (code > ec)
153 ec = code;
154 }
155 #else
156 bc = 0;
157 ec = 255;
158 #endif
159
160 nchars = ec - bc + 1;
161 ALLOC_IF_ERR(go, struct s_gf_glyph){
162 vf_error = VF_ERR_NO_MEMORY;
163 goto ErrExit;
164 }
165 ALLOCN_IF_ERR(go->bm_table, struct vf_s_bitmap, nchars){
166 vf_error = VF_ERR_NO_MEMORY;
167 goto ErrExit;
168 }
169
170 for (i = 0; i < nchars; i++)
171 go->bm_table[i].bitmap = NULL;
172 go->ds = (double)ds/(1<<20);
173 go->hppp = (double)hppp/(1<<16);
174 go->vppp = (double)vppp/(1<<16);
175 go->font_bbx_w = max_m - min_m;
176 go->font_bbx_h = max_n - min_n;
177 go->font_bbx_xoff = min_m;
178 go->font_bbx_yoff = min_n;
179 go->code_min = bc;
180 go->code_max = ec;
181
182 /* read glyph */
183 #if 0
184 fseek(fp, gptr, SEEK_SET);
185 #endif
186 for (;;){
187 if ((instr = READ_UINT1(fp)) == GF_POST_POST)
188 break;
189 switch ((int)instr){
190 case GF_CHAR_LOC:
191 code = READ_UINT1(fp);
192 dx = (double)READ_INT4(fp)/(double)(1<<16);
193 dy = (double)READ_INT4(fp)/(double)(1<<16);
194 w = READ_INT4(fp);
195 ptr = READ_INT4(fp);
196 break;
197 case GF_CHAR_LOC0:
198 code = READ_UINT1(fp);
199 dx = (double)READ_INT1(fp);
200 dy = (double)0;
201 w = READ_INT4(fp);
202 ptr = READ_INT4(fp);
203 break;
204 default:
205 vf_error = VF_ERR_ILL_FONT_FILE;
206 goto ErrExit;
207 }
208 optr = ftell(fp);
209 fseek(fp, ptr, SEEK_SET);
210 bm = &go->bm_table[code - bc];
211 if (gf_read_glyph(fp, bm) < 0)
212 goto ErrExit;
213 bm->mv_x = dx;
214 bm->mv_y = dy;
215 fseek(fp, optr, SEEK_SET);
216 }
217 return go;
218
219 ErrExit:
220 printf("*ERROR\n");
221 if (go != NULL){
222 if (go->bm_table != NULL){
223 for (i = 0; i < nchars; i++)
224 vf_free(go->bm_table[i].bitmap);
225 }
226 vf_free(go->bm_table);
227 }
228 vf_free(go);
229 return NULL;
230 }
231
232 Private int
233 gf_read_glyph(FILE* fp, VF_BITMAP bm)
/* [<][>][^][v][top][bottom][index][help] */
234 {
235 long m, n;
236 int paint_sw;
237 int instr;
238 INT4 min_m, max_m, min_n, max_n, del_m, del_n;
239 long w, h, d;
240 int m_b, k;
241 unsigned char *ptr;
242
243 switch (READ_UINT1(fp)){
244 case GF_BOC:
245 SKIP_N(fp, 4);
246 SKIP_N(fp, 4);
247 min_m = READ_INT4(fp);
248 max_m = READ_INT4(fp);
249 min_n = READ_INT4(fp);
250 max_n = READ_INT4(fp);
251 break;
252 case GF_BOC1:
253 SKIP_N(fp, 1);
254 del_m = (INT4)READ_UINT1(fp);
255 max_m = (INT4)READ_UINT1(fp);
256 del_n = (INT4)READ_UINT1(fp);
257 max_n = (INT4)READ_UINT1(fp);
258 min_m = max_m - del_m;
259 min_n = max_n - del_n;
260 break;
261 default:
262 return -1;
263 }
264
265 w = max_m - min_m + 1;
266 h = max_n - min_n + 1;
267 if ((w < 0) || (h < 0)){
268 vf_error = VF_ERR_ILL_FONT_FILE;
269 return -1;
270 }
271
272 if ((bm->bitmap = (unsigned char*)malloc(h*((w+7)/8))) == NULL){
273 vf_error = VF_ERR_NO_MEMORY;
274 return -1;
275 }
276 memclr(bm->bitmap, h*((w+7)/8));
277 bm->raster = (w+7)/8;
278 bm->bbx_width = w;
279 bm->bbx_height = h;
280 bm->off_x = -min_m;
281 bm->off_y = max_n;
282 #if 0
283 bm->mv_x = -min_m;
284 bm->mv_y = max_n;
285 #endif
286
287 m = min_m;
288 n = max_n;
289 paint_sw = 0;
290 while ((instr = (int)READ_UINT1(fp)) != GF_EOC){
291 if (instr == GF_PAINT_0){
292 paint_sw = 1 - paint_sw;
293 } else if ((GF_NEW_ROW_0 <= instr) && (instr <= GF_NEW_ROW_164)){
294 m = min_m + (instr - GF_NEW_ROW_0);
295 n = n - 1;
296 paint_sw = 1;
297 } else if ((GF_PAINT_1 <= instr) && (instr <= GF_PAINT_63)){
298 d = (instr - GF_PAINT_1 + 1);
299 goto Paint;
300 } else {
301 switch ((int)instr){
302 case GF_PAINT1:
303 case GF_PAINT2:
304 case GF_PAINT3:
305 d = (UINT4)READ_UINTN(fp, (instr - GF_PAINT1 + 1));
306 Paint:
307 if (paint_sw == 0){
308 m = m + d;
309 } else {
310 ptr = &bm->bitmap[(max_n - n) * bm->raster + (m - min_m)/8];
311 m_b = (m - min_m) % 8;
312 while (d > 0){
313 *ptr |= bit_table[m_b];
314 m++;
315 if (++m_b >= 8){
316 m_b = 0;
317 ++ptr;
318 }
319 d--;
320 }
321 }
322 paint_sw = 1 - paint_sw;
323 break;
324 case GF_SKIP0:
325 m = min_m;
326 n = n - 1;
327 paint_sw = 0;
328 break;
329 case GF_SKIP1:
330 case GF_SKIP2:
331 case GF_SKIP3:
332 m = min_m;
333 n = n - (UINT4)READ_UINTN(fp, (instr - GF_SKIP1 + 1)) - 1;
334 paint_sw = 0;
335 break;
336 case GF_XXX1:
337 case GF_XXX2:
338 case GF_XXX3:
339 case GF_XXX4:
340 k = READ_UINTN(fp, instr - GF_XXX1 + 1);
341 SKIP_N(fp, k);
342 break;
343 case GF_YYY:
344 SKIP_N(fp, 4);
345 break;
346 case GF_NO_OP:
347 break;
348 default:
349 vf_free(bm->bitmap);
350 bm->bitmap = NULL;
351 vf_error = VF_ERR_ILL_FONT_FILE;
352 return -1;
353 }
354 }
355 }
356
357 return 0;
358 }
359
360
361 /*EOF*/