~ubuntu-branches/ubuntu/precise/vflib3/precise

« back to all changes in this revision

Viewing changes to src/bdf.c

  • Committer: Bazaar Package Importer
  • Author(s): Masayuki Hatta
  • Date: 2002-04-15 12:10:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020415121024-cann32wucyfbq22f
Tags: upstream-3.6.12
ImportĀ upstreamĀ versionĀ 3.6.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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*/