src/hbf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- HBF_Init
- HBF_Open
- hbf_load_hbf_file
- hbf_release
- HBF_Close
- HBF_GetBitmap
- hbf_find_bitmap
- hbf_load_bitmap
- hbf_subindex
- HBF_GetProp
- HBF_GetHBFChar
1 /*
2 * hbf.c - a low lebel interface for HBF format fonts
3 * by Hirotsugu Kakugawa
4 *
5 * 26 Mar 1997 Fixed bugs.
6 * 26 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 hbf_table = NULL;
30
31
32 Private int
33 HBF_Init(void)
/* [<][>][^][v][top][bottom][index][help] */
34 {
35 HBF_GetHBF(-1);
36
37 if ((hbf_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 int hbf_load_hbf_file(HBF, SEXP);
47 Private int hbf_load_bitmap(HBF,int);
48 Private void hbf_release(HBF);
49 Private int hbf_subindex(HBF,long,long);
50 Private unsigned char* hbf_find_bitmap(HBF,long);
51
52 Private int
53 HBF_Open(char *font_file, SEXP fontdirs)
/* [<][>][^][v][top][bottom][index][help] */
54 {
55 char *path_name, *uncomp_prog;
56 int hbf_id;
57 HBF hbf;
58
59 path_name = vf_search_file(font_file, -1, NULL, FALSE, -1, fontdirs,
60 default_compressed_ext, &uncomp_prog);
61 if (path_name == NULL){
62 vf_error = VF_ERR_NO_FONT_FILE;
63 return -1;
64 }
65 #if 0
66 printf("** HBF Font File: %s ==> %s\n", font_file, path_name);
67 #endif
68
69 if ((hbf_id = (hbf_table->get_id_by_key)(hbf_table, path_name,
70 strlen(path_name)+1)) >= 0){
71 (hbf_table->link_by_id)(hbf_table, hbf_id);
72 return hbf_id;
73 }
74
75 ALLOC_IF_ERR(hbf, struct s_hbf){
76 vf_error = VF_ERR_NO_MEMORY;
77 return -1;
78 }
79
80 hbf->nchars = 0;
81 hbf->point_size = -1;
82 hbf->pixel_size = -1;
83 hbf->size = -1;
84 hbf->dpi_x = -1;
85 hbf->dpi_y = -1;
86 hbf->slant = 0;
87 hbf->ascent = 0;
88 hbf->descent = 0;
89 hbf->font_bbx_width = 0;
90 hbf->font_bbx_height = 0;
91 hbf->font_bbx_xoff = 0;
92 hbf->font_bbx_yoff = 0;
93 hbf->path_name = NULL;
94 hbf->props = NULL;
95 hbf->uncompress = NULL;
96
97 if ((hbf->path_name = vf_strdup(path_name)) == NULL){
98 vf_error = VF_ERR_NO_MEMORY;
99 goto Error;
100 }
101 if ((uncomp_prog != NULL) &&
102 ((hbf->uncompress = vf_strdup(uncomp_prog)) == NULL)){
103 vf_error = VF_ERR_NO_MEMORY;
104 goto Error;
105 }
106 if ((hbf->props = vf_sexp_empty_list()) == NULL){
107 vf_error = VF_ERR_NO_MEMORY;
108 goto Error;
109 }
110
111 if (hbf_load_hbf_file(hbf, fontdirs) < 0)
112 goto Error;
113
114 #if 0
115 printf("** HBF: charset:%d, %fpt, %fdpi(x) %fdpi(y) (%d chars)\n",
116 hbf->charset, hbf->point_size, hbf->dpi_x, hbf->dpi_y, hbf->nchars);
117 #endif
118
119 if ((hbf_id = (hbf_table->put)(hbf_table, hbf,
120 path_name, strlen(path_name)+1)) < 0){
121 vf_error = VF_ERR_NO_MEMORY;
122 goto Error;
123 }
124
125 HBF_SetHBF(hbf_id, hbf);
126
127 return hbf_id;
128
129 Error:
130 hbf_release(hbf);
131 return -1;
132 }
133
134 Private int
135 hbf_load_hbf_file(HBF hbf, SEXP fontdirs)
/* [<][>][^][v][top][bottom][index][help] */
136 {
137 FILE *fp;
138 char linebuf[160], prop_string[160], *name, *file_path, *p;
139 char charset_name[80], charset_name2[80], charset_enc2[5], charset[90];
140 char *uncomp_prog;
141 int index, r, i, n;
142
143 hbf->byte2_range_start = NULL;
144 hbf->byte2_range_end = NULL;
145 hbf->byte2_ranges = 0;
146 hbf->code_range_start = NULL;
147 hbf->code_range_end = NULL;
148 hbf->code_range_offset = NULL;
149 hbf->code_range_bitmap_file_paths = NULL;
150 hbf->code_range_bitmaps = NULL;
151 hbf->code_range_offset = NULL;
152 hbf->code_range_bitmap_uncompresser = NULL;
153
154 if (hbf->uncompress == NULL){
155 if ((fp = vf_fm_OpenTextFileStream(hbf->path_name)) == NULL){
156 vf_error = VF_ERR_NO_FONT_FILE;
157 return -1;
158 }
159 } else {
160 if ((fp = vf_open_uncompress_stream(hbf->path_name,
161 hbf->uncompress)) == NULL){
162 vf_error = VF_ERR_UNCOMPRESS;
163 return -1;
164 }
165 }
166
167 /* Perse: Char set, pixel size, ... */
168 strcpy(charset_name, "");
169 strcpy(charset_name2, "");
170 strcpy(charset_enc2, "");
171 for (;;){
172 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
173 vf_error = VF_ERR_ILL_FONT_FILE;
174 goto Unexpected_Error;
175 }
176 if (STRCMP(linebuf, "HBF_STARTFONT") == 0)
177 continue;
178 if (STRCMP(linebuf, "COMMENT") == 0)
179 continue;
180 if (STRCMP(linebuf, "ENDPROPERTIES") == 0)
181 break;
182
183 { int x;
184 for (x = strlen(linebuf)-1; x >= 0; x--){
185 switch (linebuf[x]){
186 case '\n':
187 case '\r':
188 linebuf[x] = '\0';
189 }
190 }
191 }
192
193 { char *prop_name, *prop_value, *p, *p0, c0;
194
195 prop_name = linebuf;
196 for (p = linebuf; (c0 = *p) != '\0'; p++)
197 if (isspace((int)c0))
198 break;
199 p0 = p;
200 *p = '\0';
201 if (c0 != '\0'){
202 p++;
203 while (isspace((int)*p))
204 p++;
205 }
206 if (*p == '\0'){
207 prop_value = NULL;
208 } else {
209 prop_value = p;
210 if (prop_value[0] == '"'){
211 prop_value = &prop_value[1];
212 prop_value[strlen(prop_value)-1] = '\0';
213 }
214 hbf->props = vf_sexp_alist_put(prop_name, prop_value, hbf->props);
215 if (hbf_debug('P'))
216 printf("HBF Prop \"%s\" = \"%s\"\n", prop_name, prop_value);
217 }
218 *p0 = c0;
219 }
220
221 if (STRCMP(linebuf, "SIZE") == 0){
222 sscanf(linebuf, "%*s%lf%lf%lf",
223 &hbf->point_size, &hbf->dpi_x, &hbf->dpi_y);
224 hbf->size = hbf->point_size;
225 } else if ((STRCMP(linebuf, "HBF_BITMAP_BOUNDING_BOX") == 0)
226 || (STRCMP(linebuf, "FONTBOUNDINGBOX") == 0)){
227 sscanf(linebuf, "%*s%d%d%d%d",
228 &hbf->font_bbx_width, &hbf->font_bbx_height,
229 &hbf->font_bbx_xoff, &hbf->font_bbx_yoff);
230 hbf->ascent = hbf->font_bbx_height + hbf->font_bbx_yoff;
231 hbf->descent = -hbf->font_bbx_yoff;
232 } else if (STRCMP(linebuf, "HBF_CODE_SCHEME") == 0){
233 p = &linebuf[strlen("HBF_CODE_SCHEME")];
234 while (isspace((int)*p))
235 p++;
236 for (i = 0; p[i] != '\0'; i++)
237 if (!isprint((int)p[i]))
238 break;
239 p[i] = '\0';
240 strcpy(charset_name, p);
241 } else if (STRCMP(linebuf, "CHARSET_REGISTRY") == 0){
242 sscanf(linebuf, "%*s%s", prop_string);
243 name = &prop_string[1]; /* ignore `"' */
244 name[strlen(name)-1] = '\0';
245 strncpy(charset_name2, name, sizeof(charset_name));
246 } else if (STRCMP(linebuf, "CHARSET_ENCODING") == 0){
247 sscanf(linebuf, "%*s%s", prop_string);
248 name = &prop_string[1]; /* ignore `"' */
249 name[strlen(name)-1] = '\0';
250 strncpy(charset_enc2, name, sizeof(charset_enc2));
251 } else if (STRCMP(linebuf, "RESOLUTION_X") == 0){
252 sscanf(linebuf, "%*s%lf", &hbf->dpi_x);
253 } else if (STRCMP(linebuf, "RESOLUTION_Y") == 0){
254 sscanf(linebuf, "%*s%lf", &hbf->dpi_y);
255 } else if (STRCMP(linebuf, "PIXEL_SIZE") == 0){
256 sscanf(linebuf, "%*s%d", &hbf->pixel_size);
257 } else if (STRCMP(linebuf, "POINT_SIZE") == 0){
258 sscanf(linebuf, "%*s%lf", &hbf->point_size);
259 hbf->point_size = hbf->point_size / 10.0;
260 } else if (STRCMP(linebuf, "SLANT") == 0){
261 sscanf(linebuf, "%*s%s", prop_string);
262 name = &prop_string[1]; /* ignore `"' */
263 name[strlen(name)-1] = '\0';
264 for (p = name; *p != '\0'; p++)
265 *p = toupper(*p);
266 hbf->slant = 0.0;
267 if ((strcmp(name, "I") == 0) || (strcmp(name, "O") == 0)){
268 hbf->slant = 0.17;
269 } else if ((strcmp(name, "RI") == 0) || (strcmp(name, "RO") == 0)){
270 hbf->slant = -0.17;
271 }
272 }
273 }
274 if (strcmp(charset_name, "") != 0){
275 sprintf(charset, "%s", charset_name);
276 } else {
277 if ((strcmp(charset_enc2, "") != 0) && ((strcmp(charset_enc2, "0") != 0)))
278 sprintf(charset, "%s-%s", charset_name2, charset_enc2);
279 else
280 sprintf(charset, "%s", charset_name2);
281 }
282 #if 0
283 printf("** HBF font file charset (ID=%d) '%s'\n", hbf->charset, charset);
284 printf("*1 %f %f %f\n",
285 hbf->point_size, hbf->dpi_x, hbf->dpi_y);
286 printf("*2 %d %d %d %d\n",
287 hbf->font_bbx_width, hbf->font_bbx_height,
288 hbf->font_bbx_xoff, hbf->font_bbx_yoff);
289 #endif
290
291 if (hbf->point_size < 0)
292 hbf->point_size = DEFAULT_POINT_SIZE;
293 if (hbf->pixel_size < 0)
294 hbf->pixel_size = DEFAULT_PIXEL_SIZE;
295 if (hbf->dpi_x < 0)
296 hbf->dpi_x = DEFAULT_DPI;
297 if (hbf->dpi_y < 0)
298 hbf->dpi_y = DEFAULT_DPI;
299
300 /* parse: CHARS */
301 for (;;){
302 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
303 vf_error = VF_ERR_ILL_FONT_FILE;
304 goto Unexpected_Error;
305 }
306 if (STRCMP(linebuf, "CHARS") == 0){
307 sscanf(linebuf, "%*s%d", &hbf->nchars);
308 if (hbf->nchars < 0){
309 vf_error = VF_ERR_ILL_FONT_FILE;
310 goto Unexpected_Error;
311 }
312 break;
313 }
314 }
315
316 /* Parse: HBF_START_BYTE_2_RANES ... HBF_END_BYTE_2_RANES */
317 hbf->byte2_ranges = 0;
318 for (;;){
319 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
320 vf_error = VF_ERR_ILL_FONT_FILE;
321 goto Unexpected_Error;
322 }
323 if (STRCMP(linebuf, "HBF_START_BYTE_2_RANGES") == 0){
324 sscanf(linebuf, "%*s%d", &hbf->byte2_ranges);
325 if (hbf->byte2_ranges <= 0){
326 vf_error = VF_ERR_ILL_FONT_FILE;
327 goto Unexpected_Error;
328 }
329 ALLOCN_IF_ERR(hbf->byte2_range_start, int, hbf->byte2_ranges){
330 vf_error = VF_ERR_NO_MEMORY;
331 goto Unexpected_Error;
332 }
333 ALLOCN_IF_ERR(hbf->byte2_range_end, int, hbf->byte2_ranges){
334 vf_error = VF_ERR_NO_MEMORY;
335 goto Unexpected_Error;
336 }
337 break;
338 }
339 }
340 hbf->n_byte2 = 0;
341 for (r = 0; r < hbf->byte2_ranges; r++){
342 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
343 vf_error = VF_ERR_ILL_FONT_FILE;
344 goto Unexpected_Error;
345 }
346 if (STRCMP(linebuf, "HBF_END_BYTE_2_RANGES") == 0){
347 vf_error = VF_ERR_ILL_FONT_FILE;
348 goto Unexpected_Error;
349 } else if (STRCMP(linebuf, "HBF_BYTE_2_RANGE") == 0){
350 sscanf(linebuf, "%*s%i-%i",
351 &(hbf->byte2_range_start[r]),
352 &(hbf->byte2_range_end[r]));
353 hbf->n_byte2
354 += (hbf->byte2_range_end[r] - hbf->byte2_range_start[r] + 1);
355 }
356 }
357
358 for (i = 0; i < 256; i++)
359 hbf->byte2_index[i] = -1;
360 index = 0;
361 for (r = 0; r < hbf->byte2_ranges; r++){
362 for (i = hbf->byte2_range_start[r]; i <= hbf->byte2_range_end[r]; i++)
363 hbf->byte2_index[i] = index++;
364 }
365
366 /* Parse: HBF_START_CODE_RANES ... HBF_END_CODE_RANES */
367 for (;;){
368 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
369 vf_error = VF_ERR_ILL_FONT_FILE;
370 goto Unexpected_Error;
371 }
372 if (STRCMP(linebuf, "HBF_START_CODE_RANGES") == 0){
373 sscanf(linebuf, "%*s%d", &hbf->code_ranges);
374 if (hbf->code_ranges <= 0){
375 vf_error = VF_ERR_ILL_FONT_FILE;
376 goto Unexpected_Error;
377 }
378 ALLOCN_IF_ERR(hbf->code_range_start, long, hbf->code_ranges){
379 vf_error = VF_ERR_NO_MEMORY;
380 goto Unexpected_Error;
381 }
382 ALLOCN_IF_ERR(hbf->code_range_end, long, hbf->code_ranges){
383 vf_error = VF_ERR_NO_MEMORY;
384 goto Unexpected_Error;
385 }
386 ALLOCN_IF_ERR(hbf->code_range_bitmaps,
387 unsigned char**, hbf->code_ranges){
388 vf_error = VF_ERR_NO_MEMORY;
389 goto Unexpected_Error;
390 }
391 ALLOCN_IF_ERR(hbf->code_range_offset, long, hbf->code_ranges){
392 vf_error = VF_ERR_NO_MEMORY;
393 goto Unexpected_Error;
394 }
395 ALLOCN_IF_ERR(hbf->code_range_bitmap_file_paths,
396 char*, hbf->code_ranges){
397 vf_error = VF_ERR_NO_MEMORY;
398 goto Unexpected_Error;
399 }
400 ALLOCN_IF_ERR(hbf->code_range_bitmap_uncompresser,
401 char*, hbf->code_ranges){
402 vf_error = VF_ERR_NO_MEMORY;
403 goto Unexpected_Error;
404 }
405 break;
406 }
407 }
408
409 for (r = 0; r < hbf->code_ranges; ){
410 if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
411 vf_error = VF_ERR_ILL_FONT_FILE;
412 goto Unexpected_Error;
413 }
414 if (STRCMP(linebuf, "HBF_END_CODE_RANGES") == 0){
415 vf_error = VF_ERR_ILL_FONT_FILE;
416 goto Unexpected_Error;
417 } else if (STRCMP(linebuf, "HBF_CODE_RANGE") == 0){
418 sscanf(linebuf, "%*s%li-%li%s%li",
419 &(hbf->code_range_start[r]),
420 &(hbf->code_range_end[r]),
421 prop_string,
422 &(hbf->code_range_offset[r]));
423 #if 0
424 printf(">>%s", linebuf);
425 printf(" %lx -- %lx, %s, %ld\n",
426 hbf->code_range_start[r], hbf->code_range_end[r],
427 prop_string, hbf->code_range_offset[r]);
428 #endif
429 file_path = NULL;
430 if (fontdirs != NULL){
431 file_path
432 = vf_search_file(prop_string, -1, NULL, FALSE, -1, fontdirs,
433 default_compressed_ext, &uncomp_prog);
434 }
435 if (file_path == NULL){
436 vf_error = VF_ERR_NO_FONT_FILE;
437 goto Unexpected_Error;
438 }
439 if ((hbf->code_range_bitmap_file_paths[r]
440 = vf_strdup(file_path)) == NULL){
441 vf_error = VF_ERR_NO_MEMORY;
442 goto Unexpected_Error;
443 }
444 #if 0
445 printf("** HBF Bitmap File: %s\n", hbf->code_range_bitmap_file_paths[r]);
446 #endif
447 n = hbf_subindex(hbf, hbf->code_range_end[r],
448 hbf->code_range_start[r]) + 1;
449 ALLOCN_IF_ERR(hbf->code_range_bitmaps[r], unsigned char*, n){
450 vf_error = VF_ERR_NO_MEMORY;
451 goto Unexpected_Error;
452 }
453 for (i = 0; i < n; i++)
454 hbf->code_range_bitmaps[r][i] = NULL;
455
456 if (uncomp_prog == NULL){
457 hbf->code_range_bitmap_uncompresser[r] = NULL;
458 } else {
459 if ((hbf->code_range_bitmap_uncompresser[r]
460 = vf_strdup(uncomp_prog)) == NULL){
461 vf_error = VF_ERR_NO_MEMORY;
462 goto Unexpected_Error;
463 }
464 if (hbf_load_bitmap(hbf, r) < 0){
465 vf_error = VF_ERR_ILL_FONT_FILE;
466 goto Unexpected_Error;
467 }
468 }
469
470 r++;
471 }
472 }
473
474 if ((uncomp_prog != NULL) && (fp != NULL))
475 vf_close_uncompress_stream(fp);
476 return 0;
477
478 Unexpected_Error:
479 if (uncomp_prog != NULL)
480 vf_close_uncompress_stream(fp);
481 hbf_release(hbf);
482 return -1;
483 }
484
485
486 Private void
487 hbf_release(HBF hbf)
/* [<][>][^][v][top][bottom][index][help] */
488 {
489 int i, n, r;
490
491 if (hbf != NULL){
492 vf_free(hbf->path_name);
493 vf_free(hbf->uncompress);
494 vf_free(hbf->byte2_range_start);
495 vf_free(hbf->byte2_range_end);
496 vf_free(hbf->code_range_start);
497 vf_free(hbf->code_range_end);
498 if (hbf->code_range_bitmap_file_paths != NULL)
499 for (r = 0; r < hbf->byte2_ranges; r++)
500 vf_free(hbf->code_range_bitmap_file_paths[r]);
501 vf_free(hbf->code_range_bitmap_file_paths);
502 if (hbf->code_range_bitmap_uncompresser != NULL)
503 for (r = 0; r < hbf->byte2_ranges; r++)
504 vf_free(hbf->code_range_bitmap_uncompresser[r]);
505 vf_free(hbf->code_range_bitmap_uncompresser);
506 if (hbf->code_range_bitmaps != NULL){
507 for (r = 0; r < hbf->byte2_ranges; r++){
508 if (hbf->code_range_bitmaps[r] == NULL)
509 continue;
510 n = hbf_subindex(hbf, hbf->code_range_end[r], hbf->code_range_end[r]);
511 for (i = 0; i <= n; i++)
512 vf_free(hbf->code_range_bitmaps[r][i]);
513 vf_free(hbf->code_range_bitmaps[r]);
514 }
515 }
516 vf_free(hbf->code_range_offset);
517 vf_sexp_free(&hbf->props);
518 vf_free(hbf);
519 }
520 }
521
522 Private void
523 HBF_Close(int hbf_id)
/* [<][>][^][v][top][bottom][index][help] */
524 {
525 HBF hbf;
526
527 if ((hbf = HBF_GetHBF(hbf_id)) == NULL){
528 fprintf(stderr, "VFlib Internal error: HBF_Close()\n");
529 abort();
530 }
531
532 if ((hbf_table->unlink_by_id)(hbf_table, hbf_id) <= 0)
533 hbf_release(hbf);
534 }
535
536
537 Private HBF_CHAR
538 HBF_GetBitmap(int hbf_id, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
539 {
540 HBF hbf;
541
542 hbf = HBF_GetHBF(hbf_id);
543 return HBF_GetHBFChar(hbf, code_point);
544 }
545
546 Private unsigned char*
547 hbf_find_bitmap(HBF hbf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
548 {
549 int subindex, bmsize, r, i;
550 long offset;
551 FILE *fp;
552 unsigned char *p;
553
554 subindex = 0;
555 for (r = 0; r < hbf->code_ranges; r++){
556 if ((hbf->code_range_start[r] <= code_point)
557 && (code_point <= hbf->code_range_end[r])){
558 break;
559 }
560 }
561 if (r == hbf->code_ranges){
562 vf_error = VF_ERR_ILL_CODE_POINT;
563 return NULL;
564 }
565
566 if ((subindex = hbf_subindex(hbf, code_point,
567 hbf->code_range_start[r])) < 0){
568 vf_error = VF_ERR_ILL_CODE_POINT;
569 return NULL;
570 }
571 if (hbf->code_range_bitmaps[r][subindex] != NULL)
572 return hbf->code_range_bitmaps[r][subindex];
573
574 #if 0
575 printf(" Opening bitmap file: %s\n",
576 hbf->code_range_bitmap_file_paths[r]);
577 #endif
578 if (hbf->code_range_bitmap_uncompresser[r] != NULL){
579 fprintf(stderr, "VFlib Internal error: HBF_GetBitmap()\n");
580 abort();
581 }
582
583 if ((fp = vf_fm_OpenBinaryFileStream(hbf->code_range_bitmap_file_paths[r]))
584 == NULL){
585 vf_error = VF_ERR_NO_FONT_FILE;
586 return NULL;
587 }
588 bmsize = ((hbf->font_bbx_width+7)/8) * hbf->font_bbx_height;
589 offset = hbf->code_range_offset[r] + subindex * bmsize;
590 fseek(fp, offset, SEEK_SET);
591 #if 0
592 printf(" code point: 0x%04x, index: %d, offset: %d\n",
593 code_point, subindex, offset);
594 #endif
595
596 ALLOCN_IF_ERR(hbf->code_range_bitmaps[r][subindex], unsigned char, bmsize)
597 return NULL;
598 p = &hbf->code_range_bitmaps[r][subindex][0];
599 for (i = 0; i < bmsize; i++)
600 *(p++) = getc(fp);
601
602 return hbf->code_range_bitmaps[r][subindex];
603 }
604
605 Private int
606 hbf_load_bitmap(HBF hbf, int r)
/* [<][>][^][v][top][bottom][index][help] */
607 {
608 int bmsize, index, i, j;
609 unsigned char *p;
610 FILE *fp;
611
612 if (hbf->code_range_bitmap_uncompresser[r] == NULL){
613 fprintf(stderr, "VFlib fatal: hbf_load_bitmap()\n");
614 abort();
615 }
616
617 fp = vf_open_uncompress_stream(hbf->code_range_bitmap_file_paths[r],
618 hbf->code_range_bitmap_uncompresser[r]);
619 if (fp == NULL){
620 vf_error = VF_ERR_UNCOMPRESS;
621 return -1;
622 }
623
624 if ((index = hbf_subindex(hbf, hbf->code_range_end[r],
625 hbf->code_range_start[r])) < 0){
626 fprintf(stderr, "VFlib fatal: hbf_load_bitmap()\n");
627 abort();
628 }
629
630 fseek(fp, hbf->code_range_offset[r], SEEK_SET);
631 for (i = 0; i <= index; i++){
632 bmsize = ((hbf->font_bbx_width+7)/8) * hbf->font_bbx_height;
633 ALLOCN_IF_ERR(hbf->code_range_bitmaps[r][i], unsigned char, bmsize)
634 return -1;
635 p = &hbf->code_range_bitmaps[r][i][0];
636 for (j = 0; j < bmsize; j++)
637 *(p++) = getc(fp);
638 }
639
640 vf_close_uncompress_stream(fp);
641 return 0;
642 }
643
644 Private int
645 hbf_subindex(HBF hbf, long code_point, long base)
/* [<][>][^][v][top][bottom][index][help] */
646 {
647 int code_hi, code_lo, base_hi, base_lo;
648 int subindex, r;
649
650 code_hi = code_point / 256; code_lo = code_point % 256;
651 base_hi = base / 256; base_lo = base % 256;
652
653 /**
654 printf(" code hi:%x lo:%02x, base hi:%d lo:%d, %d %d\n",
655 code_hi, code_lo, base_hi, base_lo,
656 hbf->byte2_index[code_lo], hbf->byte2_index[base_lo]);
657 **/
658 if (base_hi == code_hi){
659 if ((hbf->byte2_index[code_lo] < 0) || (hbf->byte2_index[base_lo] < 0))
660 return -1;
661 subindex = hbf->byte2_index[code_lo] - hbf->byte2_index[base_lo];
662 } else { /* base_hi != code_hi */
663 /* in base_hi */
664 subindex = hbf->n_byte2 - hbf->byte2_index[base_lo];
665 /* in base_hi+1, ..., code_hi-1 */
666 for (r = base_hi+1; r <= code_hi-1; r++)
667 subindex += hbf->n_byte2;
668 /* in code_hi */
669 subindex += hbf->byte2_index[code_lo];
670 }
671 #if 0
672 printf("hbf_subindex: index:%d, base:0x%lx, code:0x%x\n",
673 subindex, base, code_point);
674 #endif
675 return subindex;
676 }
677
678
679 Private char*
680 HBF_GetProp(HBF hbf, char *name)
/* [<][>][^][v][top][bottom][index][help] */
681 {
682 SEXP v;
683 char *r;
684
685 if ((v = vf_sexp_assoc(name, hbf->props)) == NULL)
686 return NULL;
687 if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
688 vf_error = VF_ERR_NO_MEMORY;
689 return NULL;
690 }
691
692 return r; /* CALLER MUST RELEASE THIS STRING LATER */
693 }
694
695
696 Private HBF_CHAR
697 HBF_GetHBFChar(HBF hbf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
698 {
699 static struct s_hbf_char hbf_char;
700
701 hbf_char.bbx_width = hbf->font_bbx_width;
702 hbf_char.bbx_height = hbf->font_bbx_height;
703 hbf_char.off_x = hbf->font_bbx_xoff;
704 hbf_char.off_y = hbf->font_bbx_yoff;
705 hbf_char.mv_x = hbf->font_bbx_width;
706 hbf_char.mv_y = 0;
707 hbf_char.bitmap = hbf_find_bitmap(hbf, code_point);
708 hbf_char.raster = (hbf->font_bbx_width+7)/8;
709 return &hbf_char;
710 }
711
712
713 /*EOF*/