src/pcf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- PCF_Init
- PCF_Open
- PCF_Close
- pcf_release
- pcf_load_file
- pcf_read_toc
- pcf_read_props
- pcf_read_metrics
- pcf_read_metric_item
- pcf_read_compressed_metric_item
- pcf_read_bitmaps
- pcf_read_ink_metrics
- pcf_read_encodings
- pcf_read_accel
- pcf_seek_to_type
- pcf_type_index
- pcf_bit_order_invert
- pcf_swap_2byte
- pcf_swap_4byte
- pcf_skip_file
- pcf_read_lsb4
- pcf_read_int4
- pcf_read_int2
- pcf_read_int1
- pcf_read_nbyte
- PCF_GetBitmap
- pcf_char_index
- PCF_GetProp
- PCF_GetPCFChar
1 /*
2 * pcf.c - a low level interface for PCF format fonts
3 * by Hirotsugu Kakugawa
4 *
5 * 25 Apr 1997 Added multiple file extension feature.
6 * 23 Jan 1998 VFlib 3.4 Changed API.
7 * 21 Apr 1998 Deleted multiple file extension feature.
8 * 17 Jun 1998 Support for 'font-directory' capability in font definition.
9 */
10 /*
11 * Copyright (C) 1996-1998 Hirotsugu Kakugawa.
12 * All rights reserved.
13 *
14 * This file is part of the VFlib Library. This library is free
15 * software; you can redistribute it and/or modify it under the terms of
16 * the GNU Library General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at your
18 * option) any later version. This library is distributed in the hope
19 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
20 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21 * PURPOSE. See the GNU Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27
28
29 Private VF_TABLE pcf_table = NULL;
30
31
32 Private int
33 PCF_Init(void)
/* [<][>][^][v][top][bottom][index][help] */
34 {
35 PCF_GetPCF(-1);
36
37 if ((pcf_table = vf_table_create()) == NULL){
38 vf_error = VF_ERR_NO_MEMORY;
39 return -1;
40 }
41
42 return 0;
43 }
44
45
46 Private void pcf_release(PCF);
47 Private int pcf_char_index(PCF,long);
48 Private int pcf_load_file(PCF);
49 Private PCF_TABLE pcf_read_toc(FILE*,int*);
50 Private int pcf_read_props(PCF,FILE*,PCF_TABLE,int);
51 Private int pcf_read_metrics(PCF,FILE*,PCF_TABLE,int);
52 Private void pcf_read_metric_item(FILE*,INT4,PCF_CHAR);
53 Private void pcf_read_compressed_metric_item(FILE*,INT4,PCF_CHAR);
54 Private int pcf_read_bitmaps(PCF,FILE*,PCF_TABLE,int);
55 Private int pcf_read_ink_metrics(PCF,FILE*,PCF_TABLE,int);
56 Private int pcf_read_encodings(PCF,FILE*,PCF_TABLE,int);
57 Private int pcf_read_accel(PCF,FILE*,PCF_TABLE,int,INT4);
58 Private PCF_TABLE pcf_seek_to_type(FILE*,PCF_TABLE,int,int);
59 Private int pcf_type_index(PCF_TABLE,int,int);
60 Private void pcf_bit_order_invert(unsigned char*,int);
61 Private void pcf_swap_2byte(unsigned char*,int);
62 Private void pcf_swap_4byte(unsigned char*,int);
63 Private int pcf_skip_file(FILE*,long);
64 Private INT4 pcf_read_lsb4(FILE*);
65 Private INT4 pcf_read_int4(FILE*,INT4);
66 Private INT4 pcf_read_int2(FILE*,INT4);
67 Private INT4 pcf_read_int1(FILE*,INT4);
68 Private int pcf_read_nbyte(FILE*,unsigned char*,int);
69
70 Private int
71 PCF_Open(char *font_file, SEXP fontdirs)
/* [<][>][^][v][top][bottom][index][help] */
72 {
73 char *path_name, *uncomp_prog;
74 int pcf_id;
75 PCF pcf;
76
77 path_name = vf_search_file(font_file, -1, NULL, FALSE, -1, fontdirs,
78 default_compressed_ext, &uncomp_prog);
79 if (path_name == NULL){
80 vf_error = VF_ERR_NO_FONT_FILE;
81 return -1;
82 }
83
84 if (pcf_debug('F')){
85 printf("PCF Font File: %s ==> %s\n", font_file, path_name);
86 }
87
88 /* Check the cache here. (Never forget that the fontdir is
89 * not always the same. */
90 if ((pcf_id = (pcf_table->get_id_by_key)(pcf_table, path_name,
91 strlen(path_name)+1)) >= 0){
92 vf_free(path_name);
93 if ((pcf = PCF_GetPCF(pcf_id)) == NULL){
94 fprintf(stderr, "VFlib internal error: in PCF_Open()\n");
95 abort();
96 }
97 (pcf_table->link_by_id)(pcf_table, pcf_id);
98 return pcf_id;
99 }
100
101 ALLOC_IF_ERR(pcf, struct s_pcf){
102 vf_free(path_name);
103 vf_error = VF_ERR_NO_MEMORY;
104 return -1;
105 }
106
107 pcf->point_size = -1;
108 pcf->pixel_size = -1;
109 pcf->size = -1;
110 pcf->ascent = -1;
111 pcf->descent = -1;
112 pcf->dpi_x = -1;
113 pcf->dpi_y = -1;
114 pcf->nchars = 0;
115 pcf->char_table = NULL;
116 pcf->bitmap_block = NULL;
117 pcf->encoding = NULL;
118 pcf->font_bbx_width = 0;
119 pcf->font_bbx_height = 0;
120 pcf->font_bbx_xoff = 0;
121 pcf->font_bbx_yoff = 0;
122 pcf->path_name = path_name;
123 pcf->uncompress = NULL;
124 pcf->props = NULL;
125
126 if ((uncomp_prog != NULL) &&
127 ((pcf->uncompress = vf_strdup(uncomp_prog)) == NULL)){
128 vf_error = VF_ERR_NO_MEMORY;
129 goto Error;
130 }
131 if ((pcf->props = vf_sexp_empty_list()) == NULL){
132 vf_error = VF_ERR_NO_MEMORY;
133 goto Error;
134 }
135
136 if (pcf_load_file(pcf) < 0)
137 goto Error;
138
139 if ((pcf_id = (pcf_table->put)(pcf_table, pcf,
140 path_name, strlen(path_name)+1)) < 0){
141 vf_error = VF_ERR_NO_MEMORY;
142 goto Error;
143 }
144
145 PCF_SetPCF(pcf_id, pcf);
146
147 return pcf_id;
148
149 Error:
150 pcf_release(pcf);
151 return -1;
152 }
153
154
155 Private void
156 PCF_Close(int pcf_id)
/* [<][>][^][v][top][bottom][index][help] */
157 {
158 PCF pcf;
159
160 if ((pcf = PCF_GetPCF(pcf_id)) == NULL){
161 fprintf(stderr, "VFlib Internal error: PCF_Close()\n");
162 vf_error = VF_ERR_INTERNAL;
163 return;
164 }
165 if ((pcf_table->unlink_by_id)(pcf_table, pcf_id) > 0)
166 return;
167
168 pcf_release(pcf);
169 }
170
171
172 Private void
173 pcf_release(PCF pcf)
/* [<][>][^][v][top][bottom][index][help] */
174 {
175 if (pcf != NULL){
176 vf_free(pcf->path_name);
177 vf_free(pcf->uncompress);
178 vf_free(pcf->char_table);
179 vf_free(pcf->bitmap_block);
180 vf_free(pcf->encoding);
181 vf_sexp_free(&pcf->props);
182 vf_free(pcf);
183 }
184 PCF_GetPCF(-1);
185 }
186
187
188
189 static int pcf_file_pos;
190
191 Private int
192 pcf_load_file(PCF pcf)
/* [<][>][^][v][top][bottom][index][help] */
193 {
194 FILE *fp;
195 PCF_TABLE tbl;
196 int has_bdf_accel, ntbl, val;
197
198 pcf_file_pos = 0;
199 if (pcf->uncompress == NULL){
200 if ((fp = vf_fm_OpenBinaryFileStream(pcf->path_name)) == NULL){
201 vf_error = VF_ERR_NO_FONT_FILE;
202 return -1;
203 }
204 } else {
205 #if 0
206 printf("** PCF \"%s\", \"%s\"\n", pcf->path_name, pcf->uncompress);
207 #endif
208 if ((fp = vf_open_uncompress_stream(pcf->path_name,
209 pcf->uncompress)) == NULL){
210 vf_error = VF_ERR_UNCOMPRESS;
211 return -1;
212 }
213 }
214
215 val = -1;
216 if ((tbl = pcf_read_toc(fp, &ntbl)) == NULL)
217 goto Error;
218 if (pcf_read_props(pcf, fp, tbl, ntbl) < 0)
219 goto Error;
220 if ((has_bdf_accel = pcf_type_index(tbl, ntbl, PCF_BDF_ACCELERATORS)) >= 0)
221 if (pcf_read_accel(pcf, fp, tbl, ntbl, PCF_ACCELERATORS) < 0)
222 goto Error;
223 if (pcf_read_metrics(pcf, fp, tbl, ntbl) < 0)
224 goto Error;
225 if (pcf_read_bitmaps(pcf, fp, tbl, ntbl) < 0)
226 goto Error;
227 if (pcf_read_ink_metrics(pcf, fp, tbl, ntbl) < 0)
228 goto Error;
229 if (pcf_read_encodings(pcf, fp, tbl, ntbl) < 0)
230 goto Error;
231 if (has_bdf_accel > 0)
232 if (pcf_read_accel(pcf, fp, tbl, ntbl, PCF_BDF_ACCELERATORS) < 0)
233 goto Error;
234 val = 0;
235
236 Error:
237 vf_free(tbl);
238 if (pcf->uncompress != NULL)
239 vf_close_uncompress_stream(fp);
240 fp = NULL;
241
242 return val;
243 }
244
245
246 Private PCF_TABLE
247 pcf_read_toc(FILE *fp, int *ntbl)
/* [<][>][^][v][top][bottom][index][help] */
248 {
249 PCF_TABLE tbl;
250 INT4 pcf_version;
251 int i;
252
253 pcf_version = pcf_read_lsb4(fp);
254 if (pcf_version != PCF_FILE_VERSION){
255 *ntbl = 0;
256 return NULL;
257 }
258 if ((*ntbl = pcf_read_lsb4(fp)) < 0)
259 return NULL;
260 ALLOCN_IF_ERR(tbl, struct s_pcf_table, *ntbl)
261 return NULL;
262 for (i = 0; i < *ntbl; i++){
263 tbl[i].type = pcf_read_lsb4(fp);
264 tbl[i].format = pcf_read_lsb4(fp);
265 tbl[i].size = pcf_read_lsb4(fp);
266 tbl[i].offset = pcf_read_lsb4(fp);
267 }
268 return tbl;
269 }
270
271 Private int
272 pcf_read_props(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl)
/* [<][>][^][v][top][bottom][index][help] */
273 {
274 int i, pad, val;
275 INT4 format, nprops;
276 INT4 *prop_name = NULL;
277 char *prop_isstr = NULL;
278 INT4 *prop_value = NULL;
279 char *propstr = NULL;
280 INT4 propstr_size;
281 char *prop, *value, *p;
282 char charset_name[256], charset_enc[64], value_str[256];
283
284 if (pcf_seek_to_type(fp, tbl, ntbl, PCF_PROPERTIES) == NULL)
285 return -1;
286 format = pcf_read_lsb4(fp);
287 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
288 return -1;
289
290 val = -1;
291
292 nprops = pcf_read_int4(fp, format);
293 ALLOCN_IF_ERR(prop_name, INT4, nprops)
294 goto Error;
295 ALLOCN_IF_ERR(prop_isstr, char, nprops)
296 goto Error;
297 ALLOCN_IF_ERR(prop_value, INT4, nprops)
298 goto Error;
299 for (i = 0; i < nprops; i++){
300 prop_name[i] = pcf_read_int4(fp, format);
301 prop_isstr[i] = pcf_read_int1(fp, format);
302 prop_value[i] = pcf_read_int4(fp, format);
303 }
304 if ((i = (nprops % 4)) != 0){
305 pad = 4 - i;
306 pcf_skip_file(fp, (long)pad);
307 }
308
309 propstr_size = pcf_read_int4(fp, format);
310 ALLOCN_IF_ERR(propstr, char, propstr_size+1)
311 goto Error;
312 pcf_read_nbyte(fp, (unsigned char*)propstr, propstr_size);
313
314 strcpy(charset_name, "");
315 strcpy(charset_enc, "");
316 for (i = 0; i < nprops; i++){
317 prop = &propstr[prop_name[i]];
318 value = &propstr[prop_value[i]];
319 if (prop_isstr[i]){
320 pcf->props = vf_sexp_alist_put(prop, value, pcf->props);
321 } else {
322 sprintf(value_str, "%ld", (long)prop_value[i]);
323 pcf->props = vf_sexp_alist_put(prop, value_str, pcf->props);
324 }
325 if (pcf_debug('P')){
326 if (prop_isstr[i])
327 printf("PCF Prop %s: \"%s\"\n", prop, value);
328 else
329 printf("PCF Prop %s: %ld\n", prop, (long)prop_value[i]);
330 }
331 if (STRCMP(prop, "CHARSET_REGISTRY") == 0){
332 strncpy(charset_name, value, sizeof(charset_name)-sizeof(charset_enc));
333 } else if (STRCMP(prop, "CHARSET_ENCODING") == 0){
334 strncpy(charset_enc, value, sizeof(charset_enc));
335 } else if (STRCMP(prop, "POINT_SIZE") == 0){
336 if (prop_isstr[i]) sscanf(value, "%i", &pcf->pixel_size);
337 else pcf->point_size = (double)prop_value[i] / 10.0;
338 } else if (STRCMP(prop, "PIXEL_SIZE") == 0){
339 if (prop_isstr[i]) sscanf(value, "%i", &pcf->pixel_size);
340 else pcf->pixel_size = prop_value[i];
341 } else if (STRCMP(prop, "FONT_ASCENT") == 0){
342 if (prop_isstr[i]) sscanf(value, "%i", &pcf->ascent);
343 else pcf->ascent = prop_value[i];
344 } else if (STRCMP(prop, "FONT_DESCENT") == 0){
345 if (prop_isstr[i]) sscanf(value, "%i", &pcf->descent);
346 else pcf->descent = prop_value[i];
347 } else if (STRCMP(prop, "RESOLUTION_X") == 0){
348 if (prop_isstr[i]) sscanf(value, "%lf", &pcf->dpi_x);
349 else pcf->dpi_x = prop_value[i];
350 } else if (STRCMP(prop, "RESOLUTION_Y") == 0){
351 if (prop_isstr[i]) sscanf(value, "%lf", &pcf->dpi_y);
352 else pcf->dpi_y = prop_value[i];
353 } else if (STRCMP(prop, "SLANT") == 0){
354 for (p = value; *p != '\0'; p++)
355 *p = toupper(*p);
356 pcf->slant = 0.0;
357 if ((strcmp(value, "I") == 0) || (strcmp(value, "O") == 0)){
358 pcf->slant = 0.17;
359 } else if ((strcmp(value, "RI") == 0) || (strcmp(value, "RO") == 0)){
360 pcf->slant = -0.17;
361 }
362 }
363 }
364
365 if ((strcmp(charset_enc, "") != 0) && ((strcmp(charset_enc, "0") != 0))){
366 strcat(charset_name, "-");
367 strcat(charset_name, charset_enc);
368 }
369
370 if ((pcf->size = pcf->point_size) < 0)
371 pcf->size = pcf->ascent + pcf->descent;
372 if (pcf->dpi_x < 0)
373 pcf->dpi_x = DEFAULT_DPI;
374 if (pcf->dpi_y < 0)
375 pcf->dpi_y = DEFAULT_DPI;
376
377 val = 0;
378
379 Error:
380 vf_free(prop_name);
381 vf_free(prop_isstr);
382 vf_free(prop_value);
383 vf_free(propstr);
384
385 return val;
386 }
387
388 Private int
389 pcf_read_metrics(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl)
/* [<][>][^][v][top][bottom][index][help] */
390 {
391 INT4 format, nmetrics;
392 int i;
393
394 if (pcf_seek_to_type(fp, tbl, ntbl, PCF_METRICS) == NULL)
395 return -1;
396 format = pcf_read_lsb4(fp);
397 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)
398 && !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS))
399 return -1;
400 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
401 nmetrics = pcf_read_int4(fp, format);
402 else
403 nmetrics = pcf_read_int2(fp, format);
404 ALLOCN_IF_ERR(pcf->char_table, struct s_pcf_char, nmetrics)
405 goto Error;
406 for (i = 0; i < nmetrics; i++){
407 PCF_CHAR pch;
408 pch = &pcf->char_table[i];
409 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
410 pcf_read_metric_item(fp, format, pch);
411 else
412 pcf_read_compressed_metric_item(fp, format, pch);
413 if (pcf_debug('M')){
414 printf("PCF rightSideBearing: %d\n", pch->rightSideBearing);
415 printf("PCF leftSideBearing: %d\n", pch->leftSideBearing);
416 printf("PCF ascent: %d\n", pch->ascent);
417 printf("PCF descent: %d\n", pch->descent);
418 printf("PCF characterWidth: %d\n", pch->characterWidth);
419 }
420 pch->bbx_width = pch->rightSideBearing - pch->leftSideBearing;
421 pch->bbx_height = pch->ascent + pch->descent;
422 pch->off_x = pch->leftSideBearing;
423 pch->off_y = -pch->descent;
424 pch->mv_x = pch->characterWidth;
425 pch->mv_y = 0;
426
427 if (pch->bbx_width > pcf->font_bbx_width)
428 pcf->font_bbx_width = pch->bbx_width;
429 if (pch->bbx_height > pcf->font_bbx_height)
430 pcf->font_bbx_height = pch->bbx_height;
431 if (pch->off_x < pcf->font_bbx_xoff)
432 pcf->font_bbx_xoff = pch->off_x;
433 if (pch->off_y < pcf->font_bbx_yoff)
434 pcf->font_bbx_yoff = pch->off_y;
435 }
436 if (pcf_debug('B')){
437 printf("PCF FONT BOUNDINGBOX %d %d %d %d\n",
438 pcf->font_bbx_width, pcf->font_bbx_height,
439 pcf->font_bbx_xoff, pcf->font_bbx_yoff);
440 }
441 pcf->nchars = nmetrics;
442 return 0;
443
444 Error:
445 pcf->nchars = 0;
446 return -1;
447 }
448 Private void
449 pcf_read_metric_item(FILE *fp, INT4 format, PCF_CHAR pch)
/* [<][>][^][v][top][bottom][index][help] */
450 {
451 pch->leftSideBearing = pcf_read_int2(fp, format);
452 pch->rightSideBearing = pcf_read_int2(fp, format);
453 pch->characterWidth = pcf_read_int2(fp, format);
454 pch->ascent = pcf_read_int2(fp, format);
455 pch->descent = pcf_read_int2(fp, format);
456 pch->attributes = pcf_read_int2(fp, format);
457 }
458 Private void
459 pcf_read_compressed_metric_item(FILE *fp, INT4 format, PCF_CHAR pch)
/* [<][>][^][v][top][bottom][index][help] */
460 {
461 pch->leftSideBearing = pcf_read_int1(fp, format) - 0x80;
462 pch->rightSideBearing = pcf_read_int1(fp, format) - 0x80;
463 pch->characterWidth = pcf_read_int1(fp, format) - 0x80;
464 pch->ascent = pcf_read_int1(fp, format) - 0x80;
465 pch->descent = pcf_read_int1(fp, format) - 0x80;
466 pch->attributes = 0;
467 }
468
469 Private int
470 pcf_read_bitmaps(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl)
/* [<][>][^][v][top][bottom][index][help] */
471 {
472 INT4 format, nbitmaps;
473 CARD4 *offsets = NULL;
474 CARD4 bitmap_sizes[PCF_GLYPHPADOPTIONS];
475 int i, xsize;
476 int bitmap_block_size;
477
478 if (pcf_seek_to_type(fp, tbl, ntbl, PCF_BITMAPS) == NULL)
479 return -1;
480 format = pcf_read_lsb4(fp);
481 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
482 return -1;
483 if ((nbitmaps = pcf_read_int4(fp, format)) != pcf->nchars)
484 return -1;
485 if (pcf_debug('B')){
486 printf("PCF %ld bitmaps\n", (long)nbitmaps);
487 }
488
489 ALLOCN_IF_ERR(offsets, CARD4, nbitmaps)
490 goto Error;
491 for (i = 0; i < nbitmaps; i++)
492 offsets[i] = pcf_read_int4(fp, format);
493
494 for (i = 0; i < PCF_GLYPHPADOPTIONS; i++)
495 bitmap_sizes[i] = pcf_read_int4(fp, format);
496 bitmap_block_size = bitmap_sizes[PCF_GLYPH_PAD_INDEX(format)];
497 xsize = (bitmap_block_size > 0) ? bitmap_block_size : 1;
498 if (pcf_debug('B')){
499 printf("PCF Bitmaps: %d bytes\n", xsize);
500 }
501 ALLOCN_IF_ERR(pcf->bitmap_block, unsigned char, xsize)
502 goto Error;
503 pcf_read_nbyte(fp, pcf->bitmap_block, bitmap_block_size);
504
505 if (PCF_BIT_ORDER(format) != PCF_MSB_FIRST)
506 pcf_bit_order_invert(pcf->bitmap_block, bitmap_block_size);
507 if (PCF_BYTE_ORDER(format) != PCF_MSB_FIRST){
508 switch (PCF_SCAN_UNIT(format)){
509 case 1:
510 break;
511 case 2:
512 pcf_swap_2byte(pcf->bitmap_block, bitmap_block_size);
513 break;
514 case 4:
515 pcf_swap_4byte(pcf->bitmap_block, bitmap_block_size);
516 break;
517 }
518 }
519
520 for (i = 0; i < nbitmaps; i++){
521 PCF_CHAR pch;
522 int w, h, pad;
523
524 pch = &pcf->char_table[i];
525 w = pch->rightSideBearing - pch->leftSideBearing;
526 h = pch->ascent + pch->descent;
527 pad = PCF_GLYPH_PAD(format);
528 pch->bitmap = &pcf->bitmap_block[offsets[i]];
529 pch->raster = ((w + 8*pad - 1)/(8 * pad)) * pad;
530
531 if (pcf_debug('D')){
532 struct vf_s_bitmap bm;
533 printf("PCF Bitmap #%d\n", i);
534 bm.bbx_width = w;
535 bm.bbx_height = h;
536 bm.bitmap = pch->bitmap;
537 bm.raster = pch->raster;
538 bm.off_x = bm.off_y = bm.mv_x = bm.mv_y = 0;
539 VF_DumpBitmap(&bm);
540 }
541 }
542
543 vf_free(offsets);
544 return 0;
545
546 Error:
547 vf_free(offsets);
548 vf_free(pcf->char_table);
549 pcf->char_table = NULL;
550 vf_free(pcf->bitmap_block);
551 pcf->bitmap_block = NULL;
552 return -1;
553 }
554
555 Private int
556 pcf_read_ink_metrics(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl)
/* [<][>][^][v][top][bottom][index][help] */
557 {
558 return 0; /* ignore */
559 }
560
561 Private int
562 pcf_read_encodings(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl)
/* [<][>][^][v][top][bottom][index][help] */
563 {
564 INT4 format;
565 INT2 i, jth, ne;
566
567 if (pcf_seek_to_type(fp, tbl, ntbl, PCF_BDF_ENCODINGS) == NULL)
568 goto Error;
569 format = pcf_read_lsb4(fp);
570 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
571 goto Error;
572
573 pcf->firstCol = pcf_read_int2(fp, format);
574 pcf->lastCol = pcf_read_int2(fp, format);
575 pcf->firstRow = pcf_read_int2(fp, format);
576 pcf->lastRow = pcf_read_int2(fp, format);
577 pcf->defaultCh = pcf_read_int2(fp, format);
578 pcf->nencodings
579 = (pcf->lastCol - pcf->firstCol + 1) * (pcf->lastRow - pcf->firstRow + 1);
580 ne = (pcf->nencodings > 0) ? pcf->nencodings : 1;
581 ALLOCN_IF_ERR(pcf->encoding, INT2, ne)
582 goto Error;
583 for (i = 0; i < pcf->nencodings; i++){
584 if ((jth = pcf_read_int2(fp, format)) == 0xffff)
585 pcf->encoding[i] = -1;
586 else
587 pcf->encoding[i] = jth;
588 }
589 return 0;
590
591 Error:
592 vf_free(pcf->encoding);
593 pcf->encoding = NULL;
594 pcf->nencodings = 0;
595 return -1;
596 }
597
598 Private int
599 pcf_read_accel(PCF pcf, FILE *fp, PCF_TABLE tbl, int ntbl, INT4 type)
/* [<][>][^][v][top][bottom][index][help] */
600 {
601 INT4 format, junk;
602
603 if (pcf_seek_to_type(fp, tbl, ntbl, type) == NULL)
604 goto Error;
605 format = pcf_read_lsb4(fp);
606 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)
607 && !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
608 goto Error;
609
610 junk = (INT4)pcf_read_int1(fp, format); /* noOverlap */
611 junk = (INT4)pcf_read_int1(fp, format); /* constantMetrics */
612 junk = (INT4)pcf_read_int1(fp, format); /* terminalFont */
613 junk = (INT4)pcf_read_int1(fp, format); /* constantWidth */
614 junk = (INT4)pcf_read_int1(fp, format); /* inkInside */
615 junk = (INT4)pcf_read_int1(fp, format); /* inkMetrics */
616 junk = (INT4)pcf_read_int1(fp, format); /* drawDirection */
617 /* anamorphic */
618 /* cachable */
619 junk = (INT4)pcf_read_int1(fp, format); /* (alignment) */
620 pcf->ascent = pcf_read_int4(fp, format); /* fontAscent */
621 pcf->descent = pcf_read_int4(fp, format); /* fontDescent */
622 junk = (INT4)pcf_read_int4(fp, format); /* maxOverlap */
623 /* Metrics minbounds, maxbounds, (ink_minbounds, and ink_maxbounds)
624 come here */
625 return 0;
626
627 Error:
628 return -1;
629 }
630
631 Private PCF_TABLE
632 pcf_seek_to_type(FILE *fp, PCF_TABLE tbl, int ntbl, int type)
/* [<][>][^][v][top][bottom][index][help] */
633 {
634 int i;
635
636 if ((i = pcf_type_index(tbl, ntbl, type)) < 0)
637 return NULL;
638
639 if (pcf_file_pos > tbl[i].offset)
640 return NULL;
641 if (pcf_skip_file(fp, tbl[i].offset - pcf_file_pos) < 0)
642 return NULL;
643
644 return &tbl[i];
645 }
646
647 Private int
648 pcf_type_index(PCF_TABLE tbl, int ntbl, int type)
/* [<][>][^][v][top][bottom][index][help] */
649 {
650 int i;
651
652 for (i = 0; i < ntbl; i++){
653 if (tbl[i].type == type)
654 return i;
655 }
656 return -1;
657 }
658
659
660 Private void
661 pcf_bit_order_invert(unsigned char *bitmap, int size)
/* [<][>][^][v][top][bottom][index][help] */
662 {
663 unsigned char c1, c2, *p;
664 static unsigned char inv_tbl[] = {
665 0x0, /*0000=>0000*/ 0x8, /*0001=>1000*/
666 0x4, /*0010=>0100*/ 0xc, /*0011=>1100*/
667 0x2, /*0100=>0010*/ 0xa, /*0101=>1010*/
668 0x6, /*0110=>0110*/ 0xe, /*0111=>1110*/
669 0x1, /*1000=>0001*/ 0x9, /*1001=>1001*/
670 0x5, /*1010=>0101*/ 0xd, /*1011=>1101*/
671 0x3, /*1100=>0011*/ 0xb, /*1101=>1011*/
672 0x7, /*1110=>0111*/ 0xf, /*1111=>1111*/
673 };
674
675 for (p = bitmap; size > 0; --size, p++){
676 c1 = inv_tbl[(*p&0xf0) >> 4];
677 c2 = inv_tbl[(*p&0x0f)];
678 *p = (c2<<4)|c1;
679 }
680 }
681
682 Private void
683 pcf_swap_2byte(unsigned char *bitmap, int size)
/* [<][>][^][v][top][bottom][index][help] */
684 {
685 unsigned char *p, p0;
686
687 for (p = bitmap; size > 0; p += 2, size -= 2){
688 p0 = *(p+0);
689 *(p+0) = *(p+1);
690 *(p+1) = p0;
691 }
692 }
693
694 Private void
695 pcf_swap_4byte(unsigned char *bitmap, int size)
/* [<][>][^][v][top][bottom][index][help] */
696 {
697 unsigned char *p, p0, p1;
698
699 for (p = bitmap; size > 0; p += 4, size -= 4){
700 p0 = *(p+0);
701 p1 = *(p+1);
702 *(p+0) = *(p+3);
703 *(p+1) = *(p+2);
704 *(p+2) = p1;
705 *(p+3) = p0;
706 }
707 }
708
709
710 Private int
711 pcf_skip_file(FILE *fp, long nskip)
/* [<][>][^][v][top][bottom][index][help] */
712 {
713 for ( ; nskip > 0; nskip--){
714 if (getc(fp) < 0)
715 return -1;
716 pcf_file_pos++;
717 }
718 return 0;
719 }
720
721 Private INT4
722 pcf_read_lsb4(FILE *fp)
/* [<][>][^][v][top][bottom][index][help] */
723 {
724 INT4 n;
725
726 n = (INT4)getc(fp);
727 n += (INT4)getc(fp) * 0x00000100;
728 n += (INT4)getc(fp) * 0x00010000;
729 n += (INT4)getc(fp) * 0x01000000;
730 pcf_file_pos += 4;
731 return n;
732 }
733
734 Private INT4
735 pcf_read_int4(FILE *fp, INT4 format)
/* [<][>][^][v][top][bottom][index][help] */
736 {
737 INT4 n;
738
739 if (PCF_BYTE_ORDER(format) == PCF_MSB_FIRST){
740 n = (INT4)getc(fp) * 0x01000000;
741 n += (INT4)getc(fp) * 0x00010000;
742 n += (INT4)getc(fp) * 0x00000100;
743 n += (INT4)getc(fp);
744 } else {
745 n = (INT4)getc(fp);
746 n += (INT4)getc(fp) * 0x00000100;
747 n += (INT4)getc(fp) * 0x00010000;
748 n += (INT4)getc(fp) * 0x01000000;
749 }
750 pcf_file_pos += 4;
751 return n;
752 }
753
754 Private INT4
755 pcf_read_int2(FILE *fp, INT4 format)
/* [<][>][^][v][top][bottom][index][help] */
756 {
757 INT4 n;
758
759 if (PCF_BYTE_ORDER(format) == PCF_MSB_FIRST){
760 n = (INT4)getc(fp) * 0x100;
761 n += (INT4)getc(fp);
762 } else {
763 n = (INT4)getc(fp);
764 n += (INT4)getc(fp) * 0x100;
765 }
766 pcf_file_pos += 2;
767 return n;
768 }
769
770 Private INT4
771 pcf_read_int1(FILE *fp, INT4 format)
/* [<][>][^][v][top][bottom][index][help] */
772 {
773 pcf_file_pos++;
774 return (INT4)getc(fp);
775 }
776
777 Private int
778 pcf_read_nbyte(FILE *fp, unsigned char *buff, int size)
/* [<][>][^][v][top][bottom][index][help] */
779 {
780 unsigned char *p;
781 int c;
782
783 for (p = buff; size > 0; size--, p++){
784 if ((c = getc(fp)) < 0)
785 return -1;
786 *p = (unsigned char) c;
787 pcf_file_pos++;
788 }
789 return 0;
790 }
791
792
793 Private PCF_CHAR
794 PCF_GetBitmap(int pcf_id, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
795 {
796 int index;
797 PCF pcf;
798
799 if ((pcf = PCF_GetPCF(pcf_id)) == NULL){
800 fprintf(stderr, "VFlib internal error: BDF_GetBitmap()\n");
801 vf_error = VF_ERR_INTERNAL;
802 return NULL;
803 }
804
805 if ((index = pcf_char_index(pcf, code_point)) < 0){
806 vf_error = VF_ERR_ILL_CODE_POINT;
807 return NULL;
808 }
809 return &pcf->char_table[index];
810 }
811
812 Private int
813 pcf_char_index(PCF pcf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
814 {
815 int char_row, char_col, ncol, i;
816
817 char_row = code_point / 0x100;
818 char_col = code_point % 0x100;
819 if ((char_row < pcf->firstRow) || (pcf->lastRow < char_row)
820 || (char_col < pcf->firstCol) || (pcf->lastCol < char_col))
821 return -1;
822
823 ncol = (pcf->lastCol - pcf->firstCol + 1);
824 i = (char_col - pcf->firstCol) + ncol * (char_row - pcf->firstRow);
825 return pcf->encoding[i];
826 }
827
828
829 Private char*
830 PCF_GetProp(PCF pcf, char *name)
/* [<][>][^][v][top][bottom][index][help] */
831 {
832 SEXP v;
833 char *r;
834
835 #if 0
836 char *prop_value, *val, str[160];
837
838 if (strcmp(name, "DEFAULT_CHAR") == 0){
839 sprintf(str, "%d", pcf->defaultCh);
840 return vf_strdup(str);
841 } else if (strcmp(name, "FONT_ASCENT") == 0){
842 sprintf(str, "%d", pcf->ascent);
843 return vf_strdup(str);
844 } else if (strcmp(name, "FONT_DESCENT") == 0){
845 sprintf(str, "%d", pcf->descent);
846 return vf_strdup(str);
847 }
848 #endif
849
850 if ((v = vf_sexp_assoc(name, pcf->props)) == NULL)
851 return NULL;
852 if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
853 vf_error = VF_ERR_NO_MEMORY;
854 return NULL;
855 }
856
857 return r; /* CALLER MUST RELEASE THIS STRING LATER */
858 }
859
860
861 Private PCF_CHAR
862 PCF_GetPCFChar(PCF pcf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
863 {
864 int index;
865
866 if ((index = pcf_char_index(pcf, code_point)) < 0){
867 vf_error = VF_ERR_ILL_CODE_POINT;
868 return NULL;
869 }
870 return &pcf->char_table[index];
871 }
872
873
874 /*EOF*/