src/pk.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- PK_CacheLoader
- PK_CacheDisposer
- pk_loader
- pk_read_14
- pk_read_n14
- pk_read_packed_number
- pk_read_nyble_init
- pk_read_nyble
1 /*
2 * pk.c - TeX PK 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 PK_GLYPH pk_loader(VF_CACHE,FILE*);
27 Private int pk_read_14(FILE*,int,int,UINT4,VF_BITMAP,long);
28 Private int pk_read_n14(FILE*,int,int,UINT4,VF_BITMAP,long);
29 Private long pk_read_packed_number(long*,FILE*,int);
30 Private void pk_read_nyble_init(int);
31 Private int pk_read_nyble(FILE*);
32
33 Private unsigned char bit_table[] = {
34 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
35
36
37
38 Private PK_GLYPH
39 PK_CacheLoader(VF_CACHE c, char *font_path, int l)
/* [<][>][^][v][top][bottom][index][help] */
40 {
41 FILE *fp;
42 UINT1 pre, id;
43
44 if (font_path == NULL)
45 return NULL;
46 if ((fp = vf_fm_OpenBinaryFileStream(font_path)) == NULL)
47 return NULL;
48
49 pre = READ_UINT1(fp);
50 if (pre != PK_PRE)
51 return NULL;
52
53 id = READ_UINT1(fp);
54 if (id != PK_ID)
55 return NULL;
56
57 return pk_loader(c, fp);
58 }
59
60 Private void
61 PK_CacheDisposer(PK_GLYPH go)
/* [<][>][^][v][top][bottom][index][help] */
62 {
63 int nc, i;
64
65 if (go != NULL){
66 if (go->bm_table != NULL){
67 nc = go->code_max - go->code_min + 1;
68 for (i = 0; i < nc; i++)
69 vf_free(go->bm_table[i].bitmap);
70 vf_free(go->bm_table);
71 }
72 vf_free(go);
73 }
74 }
75
76
77 Private PK_GLYPH
78 pk_loader(VF_CACHE c, FILE* fp)
/* [<][>][^][v][top][bottom][index][help] */
79 {
80 PK_GLYPH go;
81 UINT1 instr;
82 UINT4 ds, check_sum, hppp, vppp, k;
83 unsigned int flag, dny_f, bw, ess, size;
84 UINT4 cc, tfm, dx, dy, dm, w, h, rs;
85 INT4 hoff, voff, mv_x, mv_y;
86 long gptr;
87 int bc, ec, nchars, index, i;
88
89 k = READ_UINT1(fp);
90 SKIP_N(fp, k);
91 ds = READ_UINT4(fp);
92 check_sum = READ_UINT4(fp);
93 hppp = READ_UINT4(fp);
94 vppp = READ_UINT4(fp);
95
96 gptr = ftell(fp);
97
98 #if 0
99 /* read min & max char code */
100 bc = 256;
101 ec = -1;
102 for (;;){
103 instr = READ_UINT1(fp);
104 if (instr == PK_POST)
105 break;
106 switch ((int) instr){
107 case PK_XXX1: k = (UINT4)READ_UINT1(fp); SKIP_N(fp, k); break;
108 case PK_XXX2: k = (UINT4)READ_UINT2(fp); SKIP_N(fp, k); break;
109 case PK_XXX3: k = (UINT4)READ_UINT3(fp); SKIP_N(fp, k); break;
110 case PK_XXX4: k = (UINT4)READ_UINT4(fp); SKIP_N(fp, k); break;
111 case PK_YYY: SKIP_N(fp, 4); break;
112 case PK_NO_OP: break;
113 default:
114 size = instr & 0x3; instr >>= 2;
115 ess = instr & 0x1;
116 if (ess == 0){ /* short */
117 rs = (UINT4)(size*256) + (UINT4)READ_UINT1(fp);
118 cc = (UINT4)READ_UINT1(fp);
119 } else if ((ess == 1) && (size != 3)){ /* extended short */
120 rs = (UINT4)(size*65536) + (UINT4)READ_UINT2(fp);
121 cc = (UINT4)READ_UINT1(fp);
122 } else { /* standard */
123 rs = READ_UINT4(fp);
124 cc = (UINT4)READ_UINT4(fp);
125 }
126 SKIP_N(fp, rs);
127 if (cc < bc)
128 bc = cc;
129 if (cc > ec)
130 ec = cc;
131 break;
132 }
133 }
134
135 #else
136 bc = 0;
137 ec = 255;
138 #endif
139
140 nchars = ec - bc + 1;
141 ALLOC_IF_ERR(go, struct s_pk_glyph)
142 return NULL;
143 ALLOCN_IF_ERR(go->bm_table, struct vf_s_bitmap, nchars){
144 vf_free(go);
145 return NULL;
146 }
147 for (i = 0; i < nchars; i++)
148 go->bm_table[i].bitmap = NULL;
149 go->ds = (double)ds/(1<<20);
150 go->hppp = (double)hppp/(1<<16);
151 go->vppp = (double)vppp/(1<<16);
152 go->font_bbx_w = 0;
153 go->font_bbx_h = 0;
154 go->font_bbx_xoff = 0;
155 go->font_bbx_yoff = 0;
156 go->code_min = bc;
157 go->code_max = ec;
158
159 /* read glyphs */
160 fseek(fp, gptr, SEEK_SET);
161 for (;;){
162 if ((instr = READ_UINT1(fp)) == PK_POST)
163 break;
164 switch ((int)instr){
165 case PK_XXX1: k = (UINT4)READ_UINT1(fp); SKIP_N(fp, k); break;
166 case PK_XXX2: k = (UINT4)READ_UINT2(fp); SKIP_N(fp, k); break;
167 case PK_XXX3: k = (UINT4)READ_UINT3(fp); SKIP_N(fp, k); break;
168 case PK_XXX4: k = (UINT4)READ_UINT4(fp); SKIP_N(fp, k); break;
169 case PK_YYY: SKIP_N(fp, 4); break;
170 case PK_NO_OP: break;
171 default:
172 flag = instr;
173 size = flag % 0x04; flag = flag >> 2;
174 ess = flag % 0x02; flag = flag >> 1;
175 bw = flag % 0x02; flag = flag >> 1;
176 dny_f = flag % 0x10;
177 if (ess == 0){ /* short */
178 rs = (UINT4)(size*256) + (UINT4)READ_UINT1(fp) - (UINT4)8;
179 cc = (UINT4)READ_UINT1(fp); tfm = (UINT4)READ_UINT3(fp);
180 dm = (UINT4)READ_UINT1(fp);
181 w = (UINT4)READ_UINT1(fp); h = (UINT4)READ_UINT1(fp);
182 hoff = (INT4)READ_INT1(fp); voff = (INT4)READ_INT1(fp);
183 mv_x = dm;
184 mv_y = 0;
185 } else if ((ess == 1) && (size != 3)){ /* extended short */
186 rs = (UINT4)(size*65536) + (UINT4)READ_UINT2(fp) - (UINT4)13;
187 cc = (UINT4)READ_UINT1(fp); tfm = (UINT4)READ_UINT3(fp);
188 dm = (UINT4)READ_UINT2(fp);
189 w = (UINT4)READ_UINT2(fp); h = (UINT4)READ_UINT2(fp);
190 hoff = (INT4)READ_INT2(fp); voff = (INT4)READ_INT2(fp);
191 mv_x = dm;
192 mv_y = 0;
193 } else { /* standard */
194 rs = READ_UINT4(fp) - (UINT4)28;
195 cc = READ_UINT4(fp); tfm = READ_UINT4(fp);
196 dx = READ_UINT4(fp); dy = READ_UINT4(fp);
197 w = READ_UINT4(fp); h = READ_UINT4(fp);
198 hoff = READ_INT4(fp); voff = READ_INT4(fp);
199 mv_x = (double)dx/(double)(1<<16);
200 mv_y = (double)dy/(double)(1<<16);
201 }
202 if ((cc < go->code_min) || (go->code_max < cc)){
203 vf_error = VF_ERR_ILL_CODE_POINT;
204 goto Error;
205 }
206 index = cc - go->code_min;
207 go->bm_table[index].bbx_width = w;
208 go->bm_table[index].bbx_height = h;
209 go->bm_table[index].raster = (w+7)/8;
210 go->bm_table[index].off_x = -hoff;
211 go->bm_table[index].off_y = voff;
212 go->bm_table[index].mv_x = mv_x;
213 go->bm_table[index].mv_y = mv_y;
214 go->bm_table[index].bitmap = (unsigned char*)malloc(h*((w+7)/8));
215 if (go->bm_table[index].bitmap == NULL){
216 vf_error = VF_ERR_NO_MEMORY;
217 goto Error;
218 }
219 memclr(go->bm_table[index].bitmap, h*((w+7)/8));
220 if (dny_f == 14){
221 if (pk_read_14(fp, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0){
222 vf_error = VF_ERR_ILL_FONT_FILE;
223 goto Error;
224 }
225 } else {
226 if (pk_read_n14(fp, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0){
227 vf_error = VF_ERR_ILL_FONT_FILE;
228 goto Error;
229 }
230 }
231 if (go->font_bbx_w < w)
232 go->font_bbx_w = w;
233 if (go->font_bbx_h < h)
234 go->font_bbx_h = h;
235 if (go->font_bbx_xoff > -hoff)
236 go->font_bbx_xoff = -hoff;
237 if (go->font_bbx_yoff > (voff - h))
238 go->font_bbx_yoff = (voff - h);
239 }
240 }
241 return go;
242
243 Error:
244 for (i = 0; i < nchars; i++){
245 if (go->bm_table[i].bitmap != NULL)
246 vf_free(go->bm_table[i].bitmap);
247 }
248 vf_free(go->bm_table);
249 vf_free(go);
250 return NULL;
251 }
252
253 Private int
254 pk_read_14(FILE* fp, int dyn_f, int bw, UINT4 rs, VF_BITMAP bm, long cc)
/* [<][>][^][v][top][bottom][index][help] */
255 {
256 long x, y, x8, xm;
257 unsigned char *bm_ptr;
258 unsigned long bit16_buff;
259 int rest_bit16_buff;
260 static unsigned int mask_table[] =
261 { 0xdead, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xdead };
262
263 if (rs == 0)
264 return 0;
265
266 x8 = bm->bbx_width / 8;
267 xm = bm->bbx_width % 8;
268 bm_ptr = bm->bitmap;
269
270 bit16_buff = READ_UINT1(fp) << 8;
271 rest_bit16_buff = 8;
272 --rs;
273
274 for(y = 0; y < bm->bbx_height; y++){
275 for(x = 0; x < x8; x++){
276 *(bm_ptr++) = bit16_buff >> 8;
277 rest_bit16_buff -= 8;
278 bit16_buff = (bit16_buff << 8) & 0xffff;
279 if (rs > 0){
280 bit16_buff |= (READ_UINT1(fp) << (8 - rest_bit16_buff));
281 rest_bit16_buff += 8;
282 --rs;
283 }
284 }
285 if (xm != 0){
286 *(bm_ptr++) = (bit16_buff >> 8) & mask_table[xm];
287 rest_bit16_buff -= xm;
288 bit16_buff = (bit16_buff << xm) & 0xffff;
289 if (rest_bit16_buff < 8){
290 if (rs > 0){
291 bit16_buff |= (READ_UINT1(fp) << (8 - rest_bit16_buff));
292 rest_bit16_buff += 8;
293 --rs;
294 }
295 }
296 }
297 }
298
299 return 0;
300 }
301
302 Private int
303 pk_read_n14(FILE* fp, int dyn_f, int bw, UINT4 rs, VF_BITMAP bm, long cc)
/* [<][>][^][v][top][bottom][index][help] */
304 {
305 long x, y, xx, yy, repeat;
306 int bits, b_p;
307 unsigned char *p, *p0, *p1;
308
309 pk_read_nyble_init(rs);
310 p = bm->bitmap;
311 bw = 1-bw;
312 bits = 0;
313 for (y = 0; y < bm->bbx_height; ){
314 b_p = 0;
315 repeat = 0;
316 p0 = p;
317 for (x = 0; x < bm->bbx_width; x++){
318 if (bits == 0){
319 bw = 1-bw;
320 if ((bits = pk_read_packed_number(&repeat, fp, dyn_f)) < 0)
321 return -1;
322 }
323 if (bw == 1)
324 *p = *p | bit_table[b_p];
325 --bits;
326 if (++b_p >= 8){
327 b_p = 0;
328 p++;
329 }
330 }
331 if (b_p != 0)
332 p++;
333 y++;
334 for (yy = 0; yy < repeat; yy++){
335 p1 = p0;
336 for (xx = 0; xx < bm->raster; xx++)
337 *(p++) = *(p1++);
338 y++;
339 }
340 }
341 return 0;
342 }
343
344 Private long
345 pk_read_packed_number(long* repeat, FILE* fp, int dyn_f)
/* [<][>][^][v][top][bottom][index][help] */
346 {
347 int d, n;
348 long di;
349
350 entry:
351 d = pk_read_nyble(fp);
352 if (d == 0){
353 n = 0;
354 do {
355 di = pk_read_nyble(fp);
356 n++;
357 } while (di == 0);
358 for ( ; n > 0; n--)
359 di = di*16 + pk_read_nyble(fp);
360 return di - 15 + (13 - dyn_f)*16 + dyn_f;
361 }
362 if (d <= dyn_f)
363 return d;
364 if (d <= 13)
365 return (d - dyn_f - 1)*16 + pk_read_nyble(fp) + dyn_f + 1;
366 *repeat = 1;
367 if (d == 14)
368 *repeat = pk_read_packed_number(repeat, fp, dyn_f);
369 goto entry;
370 }
371
372 Private int pk_read_nyble_rest_cnt;
373 Private int pk_read_nyble_max_bytes;
374
375 Private void
376 pk_read_nyble_init(int max)
/* [<][>][^][v][top][bottom][index][help] */
377 {
378 pk_read_nyble_rest_cnt = 0;
379 pk_read_nyble_max_bytes = max;
380 }
381
382 Private int
383 pk_read_nyble(FILE* fp)
/* [<][>][^][v][top][bottom][index][help] */
384 {
385 static UINT1 d;
386 int v;
387
388 switch (pk_read_nyble_rest_cnt){
389 case 0:
390 d = READ_UINT1(fp);
391 if (--pk_read_nyble_max_bytes < 0)
392 return -1L;
393 v = d / 0x10;
394 d = d % 0x10;
395 pk_read_nyble_rest_cnt = 1;
396 break;
397 case 1:
398 default:
399 v = d;
400 pk_read_nyble_rest_cnt = 0;
401 break;
402 }
403
404 return v;
405 }
406
407 /*EOF*/