src/bdf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- BDF_Init
- BDF_Open
- BDF_Close
- bdf_release
- bdf_load_file
- bdf_sort_index
- bdf_sort_index
- bdf_partition
- BDF_GetBitmap
- X_TO_D
- read_bitmap
- bdf_char_index
- BDF_GetProp
- BDF_GetBDFChar
1 /*
2 * bdf.c - low level bdf file interface
3 * by Hirotsugu Kakugawa
4 *
5 * 25 Apr 1997 Added multiple file extension feature.
6 * 20 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 bdf_table = NULL;
30
31
32 Private int
33 BDF_Init(void)
/* [<][>][^][v][top][bottom][index][help] */
34 {
35 static int init_flag = 0;
36
37 if (init_flag == 0){
38 init_flag = 1;
39 BDF_GetBDF(-1);
40 if ((bdf_table = vf_table_create()) == NULL){
41 vf_error = VF_ERR_NO_MEMORY;
42 return -1;
43 }
44 }
45
46 return 0;
47 }
48
49
50 Private void bdf_release(BDF bdf);
51 Private int bdf_char_index(BDF,long);
52 Private int bdf_load_file(BDF);
53 Private BDF_CHAR read_bitmap(BDF_CHAR,FILE*);
54 Private int bdf_sort_index(BDF,int,int);
55 Private int bdf_partition(BDF,int,int);
56
57 Private int
58 BDF_Open(char *font_file, SEXP fontdirs)
/* [<][>][^][v][top][bottom][index][help] */
59 {
60 char *path_name, *uncomp_prog;
61 int bdf_id;
62 BDF bdf;
63
64 path_name = vf_search_file(font_file, -1, NULL, FALSE, -1, fontdirs,
65 default_compressed_ext, &uncomp_prog);
66 if (path_name == NULL){
67 vf_error = VF_ERR_NO_FONT_FILE;
68 return -1;
69 }
70
71 if (bdf_debug('F')){
72 printf("BDF Font File: %s ==> %s\n", font_file, path_name);
73 }
74
75 /* Check the cache here. (Never forget that the fontdir is
76 * not always the same. */
77 if ((bdf_id = (bdf_table->get_id_by_key)(bdf_table, path_name,
78 strlen(path_name)+1)) >= 0){
79 (bdf_table->link_by_id)(bdf_table, bdf_id);
80 vf_free(path_name);
81 return bdf_id;
82 }
83
84
85 ALLOC_IF_ERR(bdf, struct s_bdf){
86 vf_error = VF_ERR_NO_MEMORY;
87 vf_free(path_name);
88 return -1;
89 }
90
91 bdf->point_size = -1;
92 bdf->pixel_size = -1;
93 bdf->size = -1;
94 bdf->dpi_x = -1;
95 bdf->dpi_y = -1;
96 bdf->nchars = 0;
97 bdf->char_table = NULL;
98 bdf->char_table_x = NULL;
99 bdf->path_name = path_name;
100 bdf->uncompress = NULL;
101 bdf->props = NULL;
102
103 if ((uncomp_prog != NULL) &&
104 ((bdf->uncompress = vf_strdup(uncomp_prog)) == NULL)){
105 vf_error = VF_ERR_NO_MEMORY;
106 goto Error;
107 }
108 if ((bdf->props = vf_sexp_empty_list()) == NULL){
109 vf_error = VF_ERR_NO_MEMORY;
110 goto Error;
111 }
112
113 if (bdf_load_file(bdf) < 0)
114 goto Error;
115
116 if ((bdf_id = (bdf_table->put)(bdf_table, bdf,
117 path_name, strlen(path_name)+1)) < 0){
118 vf_error = VF_ERR_NO_MEMORY;
119 goto Error;
120 }
121
122 BDF_SetBDF(bdf_id, bdf);
123
124 return bdf_id;
125
126 Error:
127 bdf_release(bdf);
128 return -1;
129 }
130
131
132 Private void
133 BDF_Close(int bdf_id)
/* [<][>][^][v][top][bottom][index][help] */
134 {
135 BDF bdf;
136
137 if ((bdf = BDF_GetBDF(bdf_id)) == NULL){
138 fprintf(stderr, "VFlib internal error: BDF_Close()\n");
139 vf_error = VF_ERR_INTERNAL;
140 return;
141 }
142 if ((bdf_table->unlink_by_id)(bdf_table, bdf_id) > 0){
143 return;
144 }
145
146 bdf_release(bdf);
147 }
148
149
150 Private void
151 bdf_release(BDF bdf)
/* [<][>][^][v][top][bottom][index][help] */
152 {
153 int ch;
154
155 if (bdf != NULL){
156 vf_free(bdf->path_name);
157 vf_free(bdf->uncompress);
158 if (bdf->char_table != NULL){
159 for (ch = 0; ch < bdf->nchars; ch++)
160 vf_free(bdf->char_table[ch].bitmap);
161 }
162 vf_free(bdf->char_table);
163 vf_free(bdf->char_table_x);
164 vf_sexp_free(&bdf->props);
165 vf_free(bdf);
166 }
167 BDF_GetBDF(-1);
168 }
169
170
171 Private int
172 bdf_load_file(BDF bdf)
/* [<][>][^][v][top][bottom][index][help] */
173 {
174 FILE *fp;
175 char linebuf[BUFSIZ], prop_string[160], *name;
176 char charset_name[256], charset_enc[256], charset[256], *p;
177 long code_point, last_ch;
178 int ch_index, need_sorting, nchars, i;
179 int have_fontboundingbox;
180
181 if (bdf->uncompress == NULL){
182 if ((fp = vf_fm_OpenTextFileStream(bdf->path_name)) == NULL){
183 vf_error = VF_ERR_NO_FONT_FILE;
184 return -1;
185 }
186 } else {
187 if ((fp = vf_open_uncompress_stream(bdf->path_name,
188 bdf->uncompress)) == NULL){
189 vf_error = VF_ERR_UNCOMPRESS;
190 return -1;
191 }
192 }
193
194 strcpy(charset_name, "");
195 strcpy(charset_enc, "");
196 bdf->char_table = NULL;
197 bdf->char_table_x = NULL;
198 have_fontboundingbox = 0;
199 bdf->font_bbx_width = 0;
200 bdf->font_bbx_height = 0;
201 bdf->font_bbx_xoff = 0;
202 bdf->font_bbx_yoff = 0;
203 bdf->ascent = 0;
204 bdf->descent = 0;
205
206 if (bdf_debug('R'))
207 printf(">> BDF reading header\n");
208
209 for (;;){
210 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
211 vf_error = VF_ERR_ILL_FONT_FILE;
212 goto Unexpected_Error;
213 }
214 { int l = strlen(linebuf);
215 if ((l > 0) && (linebuf[l-1] == '\n'))
216 linebuf[l-1] = '\0';
217 }
218 if (strncmp(linebuf, "ENDPROPERTIES", 13) == 0)
219 break;
220 if (strncmp(linebuf, "STARTFONT", 9) == 0)
221 continue;
222 if (strncmp(linebuf, "COMMENT", 7) == 0)
223 continue;
224
225 #if 0
226 { int x;
227 for (x = strlen(linebuf)-1; x >= 0; x--){
228 switch (linebuf[x]){
229 case '\n':
230 case '\r':
231 linebuf[x] = '\0';
232 }
233 }
234 }
235 #endif
236
237 {
238 char *prop_name, *prop_value, *p, *p0, c0;
239
240 prop_name = linebuf;
241 for (p = linebuf; (c0 = *p) != '\0'; p++)
242 if (isspace((int)c0))
243 break;
244 p0 = p;
245 *p = '\0';
246 if (c0 != '\0'){
247 p++;
248 while (isspace((int)(*p)))
249 p++;
250 }
251 if (*p == '\0'){
252 prop_value = "";
253 } else {
254 prop_value = p;
255 if (prop_value[0] == '"'){
256 prop_value = &prop_value[1];
257 prop_value[strlen(prop_value)-1] = '\0';
258 }
259 bdf->props = vf_sexp_alist_put(prop_name, prop_value, bdf->props);
260 if (bdf_debug('P'))
261 printf(">> BDF Prop \"%s\" = \"%s\"\n", prop_name, prop_value);
262 }
263 *p0 = c0;
264 }
265
266 #if 0
267 printf("*** %s\n", linebuf);
268 #endif
269 if (strncmp(linebuf, "SIZE", 4) == 0){
270 sscanf(linebuf, "%*s%lf%lf%lf",
271 &bdf->point_size, &bdf->dpi_x, &bdf->dpi_y);
272 bdf->size = bdf->point_size;
273 } else if (strncmp(linebuf, "FONTBOUNDINGBOX", 15) == 0){
274 sscanf(linebuf, "%*s%d%d%d%d",
275 &bdf->font_bbx_width, &bdf->font_bbx_height,
276 &bdf->font_bbx_xoff, &bdf->font_bbx_yoff);
277 have_fontboundingbox = 1;
278 } else if (strncmp(linebuf, "CHARSET_REGISTRY", 16) == 0){
279 sscanf(linebuf, "%*s%s", prop_string);
280 if (prop_string[0] == '"'){ /* ignore `"' */
281 prop_string[strlen(prop_string)] = '\0';
282 name = &prop_string[1];
283 } else
284 name = prop_string;
285 strncpy(charset_name, name, sizeof(charset_name));
286 } else if (strncmp(linebuf, "CHARSET_ENCODING", 16) == 0){
287 sscanf(linebuf, "%*s%s", prop_string);
288 if (prop_string[0] == '"'){/* ignore `"' */
289 prop_string[strlen(prop_string)] = '\0';
290 name = &prop_string[1];
291 } else
292 name = prop_string;
293 strncpy(charset_enc, name, sizeof(charset_enc));
294 } else if (strncmp(linebuf, "PIXEL_SIZE", 10) == 0){
295 sscanf(linebuf, "%*s%d", &bdf->pixel_size);
296 } else if (strncmp(linebuf, "POINT_SIZE", 10) == 0){
297 sscanf(linebuf, "%*s%lf", &bdf->point_size);
298 bdf->point_size = bdf->point_size / 10.0;
299 } else if (strncmp(linebuf, "RESOLUTION_X", 12) == 0){
300 sscanf(linebuf, "%*s%lf", &bdf->dpi_x);
301 } else if (strncmp(linebuf, "RESOLUTION_Y", 12) == 0){
302 sscanf(linebuf, "%*s%lf", &bdf->dpi_y);
303 } else if (strncmp(linebuf, "FONT_ASCENT", 11) == 0){
304 sscanf(linebuf, "%*s%d", &bdf->ascent);
305 } else if (strncmp(linebuf, "FONT_DESCENT", 12) == 0){
306 sscanf(linebuf, "%*s%d", &bdf->descent);
307 } else if (strncmp(linebuf, "SLANT", 5) == 0){
308 sscanf(linebuf, "%*s%s", prop_string);
309 if (prop_string[0] == '"'){ /* ignore `"' */
310 prop_string[strlen(prop_string)] = '\0';
311 name = &prop_string[1];
312 } else
313 name = prop_string;
314 for (p = name; *p != '\0'; p++)
315 *p = toupper(*p);
316 bdf->slant = 0.0;
317 if ((strcmp(name, "I") == 0) || (strcmp(name, "O") == 0)){
318 bdf->slant = 0.17;
319 } else if ((strcmp(name, "RI") == 0) || (strcmp(name, "RO") == 0)){
320 bdf->slant = -0.17;
321 }
322 }
323 }
324 if ((strcmp(charset_enc, "") != 0) && ((strcmp(charset_enc, "0") != 0)))
325 sprintf(charset, "%s-%s", charset_name, charset_enc);
326 else
327 sprintf(charset, "%s", charset_name);
328 if (bdf_debug('C'))
329 printf(">> BDF Charset (ID=%d) %s\n", bdf->charset, charset);
330
331 if (bdf->dpi_x < 0)
332 bdf->dpi_x = DEFAULT_DPI;
333 if (bdf->dpi_y < 0)
334 bdf->dpi_y = DEFAULT_DPI;
335
336 for (;;){
337 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
338 vf_error = VF_ERR_ILL_FONT_FILE;
339 goto Unexpected_Error;
340 }
341 if (strncmp(linebuf, "CHARS", 5) == 0){
342 sscanf(linebuf, "%*s%d", &bdf->nchars);
343 if (bdf->nchars < 0){
344 vf_error = VF_ERR_ILL_FONT_FILE;
345 goto Unexpected_Error;
346 }
347 vf_free(bdf->char_table);
348 ALLOCN_IF_ERR(bdf->char_table, struct s_bdf_char, bdf->nchars){
349 vf_error = VF_ERR_NO_MEMORY;
350 goto Unexpected_Error;
351 }
352 vf_free(bdf->char_table_x);
353 ALLOCN_IF_ERR(bdf->char_table_x, long, bdf->nchars){
354 vf_error = VF_ERR_NO_MEMORY;
355 goto Unexpected_Error;
356 }
357 for (ch_index = 0; ch_index < bdf->nchars; ch_index++)
358 bdf->char_table_x[ch_index] = ch_index;
359 break;
360 }
361 }
362
363 if (bdf_debug('R'))
364 printf(">> BDF reading chars\n");
365
366 last_ch = -1L;
367 nchars = 0;
368 need_sorting = 0;
369 for (ch_index = 0; ch_index < bdf->nchars; ch_index++){
370 NextChar:
371 for (;;){
372 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
373 vf_error = VF_ERR_ILL_FONT_FILE;
374 goto Unexpected_Error;
375 }
376 if (strncmp(linebuf, "ENDFONT", 7) == 0)
377 goto EndFont;
378 if (strncmp(linebuf, "STARTCHAR", 9) == 0)
379 break;
380 }
381 bdf->char_table[ch_index].f_offset = -1;
382 bdf->char_table[ch_index].bbx_width = -1;
383 bdf->char_table[ch_index].bbx_height = -1;
384 bdf->char_table[ch_index].off_x = 0;
385 bdf->char_table[ch_index].off_y = 0;
386 bdf->char_table[ch_index].mv_x = 0;
387 bdf->char_table[ch_index].mv_y = 0;
388 bdf->char_table[ch_index].bitmap = NULL;
389 for (;;){
390 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
391 vf_error = VF_ERR_ILL_FONT_FILE;
392 goto Unexpected_Error;
393 }
394 if (strncmp(linebuf, "ENDCHAR", 7) == 0)
395 break;
396 if (strncmp(linebuf, "ENCODING", 8) == 0){
397 sscanf(linebuf, "%*s%ld", &code_point);
398 if (code_point < 0L)
399 goto NextChar;
400 bdf->char_table[ch_index].code_point = code_point;
401 #if 0
402 if ((code_point % 0x21) == 0)
403 printf("BDF Reading Char: Encoding=0x%x\n", code_point);
404 #endif
405 } else if (STRCMP(linebuf, "BBX") == 0){
406 sscanf(linebuf, "%*s%d%d%d%d",
407 &bdf->char_table[ch_index].bbx_width,
408 &bdf->char_table[ch_index].bbx_height,
409 &bdf->char_table[ch_index].off_x,
410 &bdf->char_table[ch_index].off_y);
411 if (have_fontboundingbox == 0){
412 if (bdf->font_bbx_width < bdf->char_table[ch_index].bbx_width)
413 bdf->font_bbx_width = bdf->char_table[ch_index].bbx_width;
414 if (bdf->font_bbx_height < bdf->char_table[ch_index].bbx_height)
415 bdf->font_bbx_height = bdf->char_table[ch_index].bbx_height;
416 }
417 } else if (strncmp(linebuf, "DWIDTH", 6) == 0){
418 sscanf(linebuf, "%*s%d%d",
419 &bdf->char_table[ch_index].mv_x,
420 &bdf->char_table[ch_index].mv_y);
421 } else if (strncmp(linebuf, "BITMAP", 6) == 0){
422 if ((bdf->uncompress != NULL)
423 || (bdf->nchars < 512)){ /* LOAD BITMAP */
424 bdf->char_table[ch_index].f_offset = 0L;
425 if (read_bitmap(&bdf->char_table[ch_index], fp) == NULL)
426 goto Unexpected_Error;
427 } else { /* LAZY BITMAP LOADING */
428 bdf->char_table[ch_index].f_offset = (long)ftell(fp);
429 bdf->char_table[ch_index].bitmap = NULL;
430 for (i = 1; i <= bdf->char_table[ch_index].bbx_height; i++){
431 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
432 vf_error = VF_ERR_ILL_FONT_FILE;
433 goto Unexpected_Error;
434 }
435 }
436 }
437 } else {
438 ; /* ignore other keywords */
439 }
440 } /* end char */
441 if ( (bdf->char_table[ch_index].code_point < 0L)
442 || (bdf->char_table[ch_index].f_offset < 0)
443 || (bdf->char_table[ch_index].bbx_width < 0)
444 || (bdf->char_table[ch_index].bbx_height < 0) ){
445 vf_error = VF_ERR_ILL_FONT_FILE;
446 break;
447 }
448 nchars++;
449 if (bdf->char_table[ch_index].code_point < last_ch)
450 need_sorting = 1;
451 last_ch = bdf->char_table[ch_index].code_point;
452 }
453
454 EndFont:
455 bdf->nchars = nchars;
456 if (need_sorting == 1){ /* for binary search */
457 if (bdf_debug('R'))
458 printf(">> BDF sorting\n");
459 bdf_sort_index(bdf, 0, ch_index-1);
460 } else {
461 if (bdf_debug('R'))
462 printf(">> BDF need not sorting\n");
463 }
464 #if 0
465 for (i = 0; i <= bdf->nchars; i++){
466 printf("** %d 0x%x\n",
467 i, bdf->char_table[bdf->char_table_x[i]].code_point);
468 }
469 #endif
470
471 if ((bdf->uncompress != NULL) && (fp != NULL))
472 vf_close_uncompress_stream(fp);
473
474 if (bdf_debug('R'))
475 printf(">> BDF done\n");
476
477 return 0;
478
479
480 Unexpected_Error:
481 if (bdf->uncompress != NULL)
482 vf_close_uncompress_stream(fp);
483 if (bdf->char_table != NULL){
484 for (ch_index = 0; ch_index < bdf->nchars; ch_index++)
485 vf_free(bdf->char_table[ch_index].bitmap);
486 }
487 vf_free(bdf->char_table);
488 vf_free(bdf->char_table_x);
489 bdf->char_table = NULL;
490 bdf->char_table_x = NULL;
491
492 return -1;
493 }
494
495 #if 0
496
497 /* Shell sort */
498 Private int
499 bdf_sort_index(BDF bdf, int x, int y)
/* [<][>][^][v][top][bottom][index][help] */
500 {
501 int gap, i, j, temp, len;
502 long *chx;
503 BDF_CHAR cht;
504
505 cht = bdf->char_table;
506 chx = bdf->char_table_x;
507
508 len = bdf->nchars;
509 for (gap = len/2; gap > 0; gap = gap / 2){
510 for (i = gap; i < len; i++){
511 for (j = i - gap;
512 (j >= 0) && (cht[chx[j]].code_point > cht[chx[j+gap]].code_point);
513 j -= gap){
514 temp = chx[j];
515 chx[j] = chx[j+gap];
516 chx[j+gap] = temp;
517 }
518 }
519 }
520
521 return 0;
522 }
523
524 #else
525
526 /* Quick sort */
527 Private int
528 bdf_sort_index(BDF bdf, int x, int y)
/* [<][>][^][v][top][bottom][index][help] */
529 {
530 int z;
531
532 Loop:
533
534 if (x < y){
535 z = bdf_partition(bdf, x, y);
536
537 #if 0
538 printf("** %d(%d) %d(%d) %d(%d)\n",
539 x, bdf->char_table[bdf->char_table_x[x]].code_point,
540 z, bdf->char_table[bdf->char_table_x[z]].code_point,
541 y, bdf->char_table[bdf->char_table_x[y]].code_point);
542 #endif
543
544 if (x < z-1){
545 (void) bdf_sort_index(bdf, x, z-1);
546 }
547
548 if (z+1 < y){
549 /*(void) bdf_sort_index(bdf, z+1, y);*/
550 x = z+1;
551 goto Loop;
552 }
553
554 }
555 return 0;
556 }
557
558 Private int
559 bdf_partition(BDF bdf, int x, int y)
/* [<][>][^][v][top][bottom][index][help] */
560 {
561 long t;
562 int i, p, tmp;
563 BDF_CHAR cht;
564 long *chx;
565
566 cht = bdf->char_table;
567 chx = bdf->char_table_x;
568
569 t = cht[chx[x]].code_point;
570 i = x+1;
571 p = x;
572
573 for (;;){
574 if (y < i)
575 return p;
576 if (cht[chx[i]].code_point < t){
577 /* swap( d[i], d[p+1]) */
578 tmp = chx[i];
579 chx[i] = chx[p+1];
580 chx[p+1] = tmp;
581 i++; p++;
582 } else {
583 i++;
584 }
585 }
586 }
587 #endif
588
589 Private BDF_CHAR
590 BDF_GetBitmap(int bdf_id, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
591 {
592 int index;
593 FILE *fp;
594 BDF bdf;
595 BDF_CHAR bdf_char;
596
597 if ((bdf = BDF_GetBDF(bdf_id)) == NULL){
598 fprintf(stderr, "VFlib internal error: BDF_GetBitmap()\n");
599 vf_error = VF_ERR_INTERNAL;
600 return NULL;
601 }
602
603 if ((index = bdf_char_index(bdf, code_point)) < 0){
604 vf_error = VF_ERR_ILL_CODE_POINT;
605 return NULL;
606 }
607 bdf_char = &bdf->char_table[index];
608
609 if (bdf_char->bitmap != NULL)
610 return bdf_char;
611
612 if ((fp = vf_fm_OpenTextFileStream(bdf->path_name)) == NULL){
613 /* --- font file is lost (maybe) */
614 vf_error = VF_ERR_NO_FONT_FILE;
615 return NULL;
616 }
617 fseek(fp, bdf_char->f_offset, SEEK_SET);
618 return read_bitmap(bdf_char, fp);
619 }
620
621 #define X_TO_D(c) ((isxdigit((int)(c)))?(Xc_To_Dec_Tbl[c-0x30]):16)
/* [<][>][^][v][top][bottom][index][help] */
622 Private int Xc_To_Dec_Tbl[] = { /* (BDF files are encoded by ASCII) */
623 /* +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F */
624 /*30*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, /* 0,1,2,3,... */
625 /*40*/ -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* @,a,b,c,... */
626 /*50*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
627 /*60*/ -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1};/* `,A,B,C,... */
628
629 Private BDF_CHAR
630 read_bitmap(BDF_CHAR bdf_char, FILE *fp)
/* [<][>][^][v][top][bottom][index][help] */
631 {
632 int bm_size, h, i;
633 char linebuf[(2*2048)/8]; /* Is this really enough? */
634 unsigned char ch1, ch2, *bmp, *lbp;
635
636 bdf_char->raster = (bdf_char->bbx_width+7)/8;
637 bm_size = bdf_char->raster * bdf_char->bbx_height;
638 if ((bdf_char->bitmap = (unsigned char*)calloc(1, bm_size)) == NULL){
639 vf_error = VF_ERR_NO_MEMORY;
640 return NULL;
641 }
642 bmp = bdf_char->bitmap;
643 for (h = 0; h < bdf_char->bbx_height; h++){
644 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
645 vf_free(bdf_char->bitmap);
646 bdf_char->bitmap = NULL;
647 vf_error = VF_ERR_ILL_FONT_FILE;
648 return NULL;
649 }
650 for (i = 0, lbp = (unsigned char *)linebuf; i < bdf_char->raster; i++){
651 ch1 = *(lbp++);
652 ch2 = *(lbp++);
653 *(bmp++) = X_TO_D(ch1)*16 + X_TO_D(ch2);
654 }
655 }
656 return bdf_char;
657 }
658
659 Private int
660 bdf_char_index(BDF bdf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
661 {
662 int hi, lo, m, x1, x2;
663
664 x1 = bdf->char_table_x[0];
665 x2 = bdf->char_table_x[bdf->nchars-1];
666 if ((code_point < bdf->char_table[x1].code_point)
667 || (bdf->char_table[x2].code_point < code_point))
668 return -1;
669
670 /* binary search */
671 lo = 0;
672 hi = bdf->nchars;
673 if (lo >= hi)
674 return -1;
675 while (lo < hi){
676 m = (lo+hi)/2; /*printf("lo=%d hi=%d m=%d\n", lo, hi, m);*/
677 if (bdf->char_table[bdf->char_table_x[m]].code_point < code_point)
678 lo = m+1;
679 else
680 hi = m;
681 }
682 if (bdf->char_table[bdf->char_table_x[hi]].code_point != code_point)
683 return -1;
684
685 return bdf->char_table_x[hi];
686 }
687
688
689 Private char*
690 BDF_GetProp(BDF bdf, char *name)
/* [<][>][^][v][top][bottom][index][help] */
691 {
692 SEXP v;
693 char *r;
694
695 if ((v = vf_sexp_assoc(name, bdf->props)) == NULL)
696 return NULL;
697 if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
698 vf_error = VF_ERR_NO_MEMORY;
699 return NULL;
700 }
701
702 return r; /* CALLER MUST RELEASE THIS STRING LATER */
703 }
704
705
706 Private BDF_CHAR
707 BDF_GetBDFChar(BDF bdf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
708 {
709 int index;
710
711 if ((index = bdf_char_index(bdf, code_point)) < 0){
712 vf_error = VF_ERR_ILL_CODE_POINT;
713 return NULL;
714 }
715 return &bdf->char_table[index];
716 }
717
718
719 /*EOF*/