src/drv_bdf.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_BDF
  2. bdf_create
  3. bdf_close
  4. bdf_get_metric1
  5. bdf_get_fontbbx1
  6. bdf_get_bitmap1
  7. bdf_get_outline
  8. bdf_get_metric2
  9. bdf_get_fontbbx2
  10. bdf_get_bitmap2
  11. bdf_get_bitmap
  12. bdf_get_font_prop
  13. bdf_debug
  14. bdf_debug2
  15. mag_mode_1
  16. mag_mode_2
  17. STRCMP
  18. BDF_SetBDF
  19. BDF_GetBDF

   1 /*
   2  * drv_bdf.c -  A font driver for BDF format fonts.
   3  * by Hirotsugu Kakugawa
   4  *
   5  *  2 Sep 1996  First version.
   6  * 13 Dec 1996  for VFlib 3.1
   7  * 16 Jan 1997  Added font directory customizing feature.
   8  * 28 Jan 1997  Added debug feature.
   9  * 26 Feb 1997  Added 'query_font_type'.
  10  * 25 Apr 1997  Added multiple file extension feature.
  11  *  4 Aug 1997  VFlib 3.3  Changed API.
  12  * 20 Jan 1998  VFlib 3.4  Changed API.
  13  * 22 Apr 1998  Improved get_font_property()
  14  * 10 Jun 1998  Added multiple font files in 'font-file' capability.
  15  * 17 Jun 1998  Support for CCV system. Support for 'font-directory'
  16  *              capability in font definition. 
  17  * 24 Nov 1998  Added get_fontbbx1() and get_fontbbx2().
  18  * 26 Nov 1998  Added debug flag control by environment variable.
  19  */
  20 /*
  21  * Copyright (C) 1996-1998  Hirotsugu Kakugawa. 
  22  * All rights reserved.
  23  *
  24  * This file is part of the VFlib Library.  This library is free
  25  * software; you can redistribute it and/or modify it under the terms of
  26  * the GNU Library General Public License as published by the Free
  27  * Software Foundation; either version 2 of the License, or (at your
  28  * option) any later version.  This library is distributed in the hope
  29  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  30  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  31  * PURPOSE.  See the GNU Library General Public License for more details.
  32  * You should have received a copy of the GNU Library General Public
  33  * License along with this library; if not, write to the Free Software
  34  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  35  */
  36 
  37 
  38 #include  "config.h"
  39 #include  <stdio.h>
  40 #include  <stdlib.h>
  41 #ifdef HAVE_UNISTD_H
  42 #  include <unistd.h>
  43 #endif
  44 #include  <ctype.h>
  45 #include  <math.h>
  46 #include  "VFlib-3_6.h"
  47 #include  "VFsys.h"
  48 #include  "vflibcap.h"
  49 #include  "ccv.h"
  50 #include  "sexp.h"
  51 #include  "str.h"
  52 #include  "path.h"
  53 #include  "fsearch.h"
  54 #include  "cache.h"
  55 #include  "bdf.h"
  56 
  57 #define   POINTS_PER_INCH      72.27
  58 #define   DEFAULT_POINT_SIZE   10.0
  59 #define   DEFAULT_PIXEL_SIZE     16
  60 #define   DEFAULT_DPI            75
  61 
  62 struct s_font_bdf {
  63   char     *font_name;
  64   char     *font_file;
  65   double   point_size;
  66   int      pixel_size;
  67   double   dpi_x, dpi_y;
  68   double   mag;
  69   double   aspect;
  70   int      bdf_id;
  71   int      ccv_id;
  72   SEXP_ALIST  props;
  73 };
  74 typedef struct s_font_bdf  *FONT_BDF;
  75 
  76 Private SEXP_LIST    default_fontdirs;
  77 Private SEXP_LIST    default_compressed_ext;
  78 Private SEXP_STRING  default_dpi, default_dpi_x, default_dpi_y;
  79 Private double       v_default_dpi_x, v_default_dpi_y;
  80 Private SEXP_STRING  default_aspect;
  81 Private double       v_default_aspect;
  82 Private SEXP_ALIST   default_properties;
  83 Private SEXP_ALIST   default_variables;
  84 Private SEXP_STRING  default_debug_mode;
  85 Private char         *env_debug_mode = NULL;
  86 #define DEBUG_ENV_NAME   "VFLIB_BDF_DEBUG"
  87 
  88 
  89 Private int          bdf_create(VF_FONT font, char *font_class, 
  90                                 char *font_name, int implicit, SEXP entry);
  91 Private int          bdf_close(VF_FONT font);
  92 Private int          bdf_get_metric1(VF_FONT font, long code_point,
  93                                      VF_METRIC1 metric1, double,double);
  94 Private int          bdf_get_metric2(VF_FONT font, long code_point,
  95                                      VF_METRIC2 metric2, double,double);
  96 Private int          bdf_get_fontbbx1(VF_FONT font,double,double,
  97                                       double*,double*,double*,double*);
  98 Private int          bdf_get_fontbbx2(VF_FONT font, double,double,
  99                                       int*,int*,int*,int*);
 100 Private VF_BITMAP    bdf_get_bitmap1(VF_FONT,long,double,double);
 101 Private VF_BITMAP    bdf_get_bitmap2(VF_FONT,long,double,double);
 102 Private VF_BITMAP      bdf_get_bitmap(FONT_BDF,long);
 103 Private VF_OUTLINE   bdf_get_outline(VF_FONT,long,double,double);
 104 Private char*        bdf_get_font_prop(VF_FONT,char*);
 105 
 106 Private void mag_mode_1(double font_size, int size, 
 107                         double font_dpi_x, double font_dpi_y,
 108                         FONT_BDF font_bdf, VF_FONT font, 
 109                         double mag_x, double mag_y,
 110                         double *ret_mag_x, double *ret_mag_y,
 111                         double *ret_point_size, 
 112                         double *ret_dpix, double *ret_dpiy);
 113 Private void mag_mode_2(int font_size, int size,
 114                         FONT_BDF font_bdf, VF_FONT font, 
 115                         double mag_x, double mag_y,
 116                         double *ret_mag_x, double *ret_mag_y, 
 117                         double *ret_pixel_size);
 118 Private int    bdf_debug(char);
 119 
 120 Private BDF       BDF_GetBDF(int bdf_id);
 121 Private void      BDF_SetBDF(int bdf_id, BDF bdf);
 122 
 123 Private int       BDF_Init(void);
 124 Private int       BDF_Open(char*,SEXP);
 125 Private void      BDF_Close(int);
 126 Private BDF_CHAR  BDF_GetBitmap(int,long);
 127 Private BDF_CHAR  BDF_GetBDFChar(BDF,long);
 128 Private char     *BDF_GetProp(BDF,char*);
 129 
 130 
 131 
 132 Public int
 133 VF_Init_Driver_BDF(void)
     /* [<][>][^][v][top][bottom][index][help] */
 134 {
 135   int z;
 136   struct s_capability_table  ct[20];
 137 
 138   z = 0;
 139   /* VF_CAPE_FONT_DIRECTORIES */
 140   ct[z].cap = VF_CAPE_FONT_DIRECTORIES;  ct[z].type = CAPABILITY_STRING_LIST0;
 141   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_fontdirs;
 142   /* VF_CAPE_COMPRESSION_EXT */
 143   ct[z].cap = VF_CAPE_COMPRESSION_EXT;   ct[z].type = CAPABILITY_STRING_LIST0;
 144   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_compressed_ext;
 145   /* VF_CAPE_DPI */  
 146   ct[z].cap = VF_CAPE_DPI;               ct[z].type = CAPABILITY_STRING;
 147   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_dpi;
 148   /* VF_CAPE_DPI_X */
 149   ct[z].cap = VF_CAPE_DPI_X;             ct[z].type = CAPABILITY_STRING;
 150   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_dpi_x;
 151   /* VF_CAPE_DPI_Y */
 152   ct[z].cap = VF_CAPE_DPI_Y;             ct[z].type = CAPABILITY_STRING;
 153   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_dpi_y;
 154   /* VF_CAPE_ASPECT_RATIO */
 155   ct[z].cap = VF_CAPE_ASPECT_RATIO;      ct[z].type = CAPABILITY_STRING;
 156   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_aspect;
 157   /* VF_CAPE_PROPERTIES */
 158   ct[z].cap = VF_CAPE_PROPERTIES;        ct[z].type = CAPABILITY_ALIST;
 159   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_properties;
 160   /* VF_CAPE_VARIABLE_VALUES */
 161   ct[z].cap = VF_CAPE_VARIABLE_VALUES;   ct[z].type = CAPABILITY_ALIST;
 162   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_variables;
 163   /* VF_CAPE_DEBUG */
 164   ct[z].cap = VF_CAPE_DEBUG;             ct[z].type = CAPABILITY_STRING;
 165   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_debug_mode;
 166   /* end */
 167   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 168 
 169   if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL) 
 170       == VFLIBCAP_PARSED_ERROR)
 171     return -1;
 172 
 173   v_default_dpi_x  = -1;
 174   v_default_dpi_y  = -1;
 175   if (default_dpi != NULL)
 176     v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
 177   if (default_dpi_x != NULL)
 178     v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
 179   if (default_dpi_y != NULL)
 180     v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
 181 
 182   v_default_aspect = 1.0;
 183   if (default_aspect != NULL)
 184     v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
 185 
 186   if (BDF_Init() < 0)
 187     return -1;
 188 
 189   env_debug_mode = getenv(DEBUG_ENV_NAME);
 190 
 191   VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)bdf_create);
 192 
 193   return 0;
 194 }
 195 
 196 
 197 Private int
 198 bdf_create(VF_FONT font, char *font_class, 
     /* [<][>][^][v][top][bottom][index][help] */
 199            char *font_name, int implicit, SEXP entry)
 200 {
 201   FONT_BDF  font_bdf;
 202   BDF       bdf;
 203   int       bdf_id, val;
 204   char      *font_file;
 205   SEXP      cap_font, cap_point, cap_pixel;
 206   SEXP      cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
 207   SEXP      cap_charset, cap_encoding, cap_font_charset, cap_font_encoding;
 208   SEXP      cap_fontdirs, cap_props;
 209   SEXP      font_file_list, s;
 210   SEXP      fontdirs;
 211   char      *charset, *encoding, *font_charset, *font_encoding;
 212   char      *s1, *s2, s_font_charset[1024];
 213   int       z;
 214   struct s_capability_table  ct[24];
 215 
 216   z = 0;
 217   /* VF_CAPE_FONT_CLASS */
 218   ct[z].cap = VF_CAPE_FONT_CLASS;       ct[z].type = CAPABILITY_STRING;
 219   ct[z].ess = CAPABILITY_ESSENTIAL;     ct[z++].val = NULL;
 220   /* VF_CAPE_FONT_DIRECTORIES */
 221   ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_STRING_LIST0;
 222   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_fontdirs;
 223   /* VF_CAPE_FONT_FILE */
 224   ct[z].cap = VF_CAPE_FONT_FILE;        ct[z].type = CAPABILITY_STRING_LIST1;
 225   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_font;
 226   /* VF_CAPE_POINT_SIZE */
 227   ct[z].cap = VF_CAPE_POINT_SIZE;       ct[z].type = CAPABILITY_STRING;
 228   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_point;
 229   /* VF_CAPE_PIXEL_SIZE */
 230   ct[z].cap = VF_CAPE_PIXEL_SIZE;       ct[z].type = CAPABILITY_STRING;
 231   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_pixel;
 232   /* VF_CAPE_DPI */
 233   ct[z].cap = VF_CAPE_DPI;              ct[z].type = CAPABILITY_STRING;
 234   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi;
 235   /* VF_CAPE_DPI_X */
 236   ct[z].cap = VF_CAPE_DPI_X;            ct[z].type = CAPABILITY_STRING;
 237   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_x;
 238   /* VF_CAPE_DPI_Y */
 239   ct[z].cap = VF_CAPE_DPI_Y;            ct[z].type = CAPABILITY_STRING;
 240   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_y;
 241   /* VF_CAPE_MAG */
 242   ct[z].cap = VF_CAPE_MAG;              ct[z].type = CAPABILITY_STRING;
 243   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_mag;
 244   /* VF_CAPE_ASPECT_RATIO */
 245   ct[z].cap = VF_CAPE_ASPECT_RATIO;     ct[z].type = CAPABILITY_STRING;
 246   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_aspect;
 247   /* VF_CAPE_CHARSET */
 248   ct[z].cap = VF_CAPE_CHARSET;         ct[z].type = CAPABILITY_STRING;
 249   ct[z].ess = CAPABILITY_OPTIONAL;     ct[z++].val = &cap_charset;
 250   /* VF_CAPE_ENCODING */
 251   ct[z].cap = VF_CAPE_ENCODING;        ct[z].type = CAPABILITY_STRING;
 252   ct[z].ess = CAPABILITY_OPTIONAL;     ct[z++].val = &cap_encoding;
 253   /* VF_CAPE_FONT_CHARSET */
 254   ct[z].cap = VF_CAPE_FONT_CHARSET;    ct[z].type = CAPABILITY_STRING;
 255   ct[z].ess = CAPABILITY_OPTIONAL;     ct[z++].val = &cap_font_charset;
 256   /* VF_CAPE_FONT_ENCODING */
 257   ct[z].cap = VF_CAPE_FONT_ENCODING;   ct[z].type = CAPABILITY_STRING;
 258   ct[z].ess = CAPABILITY_OPTIONAL;     ct[z++].val = &cap_font_encoding;
 259   /* VF_CAPE_PROPERTIES */
 260   ct[z].cap = VF_CAPE_PROPERTIES;      ct[z].type = CAPABILITY_ALIST;
 261   ct[z].ess = CAPABILITY_OPTIONAL;     ct[z++].val = &cap_props;
 262   /* end */
 263   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val  = NULL;
 264 
 265 
 266   val = -1;
 267 
 268   fontdirs = default_fontdirs;
 269   font_bdf = NULL;
 270   font_file_list = NULL;
 271   font_file = font_name;
 272   bdf_id = -1;
 273 
 274   if (implicit == 1){   /* implicit font */
 275     font_file = font_name;
 276   } else {              /* explicit font */
 277     if (vf_cap_GetParsedFontEntry(entry, font_name, ct, 
 278                                   default_variables, NULL) 
 279         == VFLIBCAP_PARSED_ERROR)
 280       return -1;
 281     if (cap_fontdirs != NULL)
 282       fontdirs = cap_fontdirs;
 283     if (cap_font == NULL){
 284       /* Use font name as font file name if font file name is not given. */
 285       font_file = font_name;
 286     } else {
 287       if (vf_sexp_listp(cap_font)){
 288         switch (vf_sexp_length(cap_font)){
 289         case 0:
 290           goto End;
 291         default:
 292           font_file_list = cap_font;
 293           break;
 294         }
 295       } else {
 296         goto End;
 297       }
 298     }
 299   }
 300 
 301   bdf_id = -1;
 302   if (font_file_list == NULL){
 303     bdf_id = BDF_Open(font_file, fontdirs);
 304   } else {
 305     for (s = font_file_list; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 306       if (vf_sexp_stringp(vf_sexp_car(s))){
 307         font_file = vf_sexp_get_cstring(vf_sexp_car(s));
 308         bdf_id = BDF_Open(font_file, fontdirs);
 309         if (bdf_id >= 0){
 310           break;
 311         }
 312       }
 313     }
 314   }
 315   if (bdf_id < 0)
 316     goto End; 
 317 
 318   font->font_type       = VF_FONT_TYPE_BITMAP;
 319   font->get_metric1     = bdf_get_metric1;
 320   font->get_metric2     = bdf_get_metric2;
 321   font->get_fontbbx1    = bdf_get_fontbbx1;
 322   font->get_fontbbx2    = bdf_get_fontbbx2;
 323   font->get_bitmap1     = bdf_get_bitmap1;
 324   font->get_bitmap2     = bdf_get_bitmap2;
 325   font->get_outline     = bdf_get_outline;
 326   font->get_font_prop   = bdf_get_font_prop;
 327   font->query_font_type = NULL;
 328   font->close           = bdf_close;
 329 
 330   ALLOC_IF_ERR(font_bdf, struct s_font_bdf){
 331     vf_error = VF_ERR_NO_MEMORY;
 332     goto End; 
 333   }
 334 
 335   font_bdf->bdf_id     = bdf_id;
 336   font_bdf->font_name = NULL; 
 337   font_bdf->font_file = NULL; 
 338   font_bdf->point_size = -1;
 339   font_bdf->pixel_size = -1;
 340   font_bdf->dpi_x      = -1;
 341   font_bdf->dpi_y      = -1;
 342   font_bdf->mag        = 1.0;
 343   font_bdf->aspect     = 1.0;
 344   font_bdf->ccv_id     = -1;
 345   font_bdf->props      = NULL;
 346 
 347   charset       = NULL;
 348   encoding      = NULL;
 349   font_charset  = NULL;
 350   font_encoding = NULL;
 351 
 352   if (implicit == 0){
 353     if (cap_point != NULL)
 354       font_bdf->point_size = atof(vf_sexp_get_cstring(cap_point));
 355     if (cap_pixel != NULL)
 356       font_bdf->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
 357     if (cap_dpi != NULL)
 358       font_bdf->dpi_x = font_bdf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
 359     if (cap_dpi_x != NULL)
 360       font_bdf->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
 361     if (cap_dpi_y != NULL)
 362       font_bdf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
 363     if (cap_mag != NULL)
 364       font_bdf->mag = atof(vf_sexp_get_cstring(cap_mag));
 365     if (cap_aspect != NULL)
 366       font_bdf->aspect = atof(vf_sexp_get_cstring(cap_aspect));
 367     if (cap_charset != NULL)
 368       charset = vf_sexp_get_cstring(cap_charset);
 369     if (cap_encoding != NULL)
 370       font_encoding = vf_sexp_get_cstring(cap_encoding);
 371     if (cap_font_charset != NULL)
 372       font_charset = vf_sexp_get_cstring(cap_font_charset);
 373     if (cap_font_encoding != NULL)
 374       font_encoding = vf_sexp_get_cstring(cap_font_encoding);
 375     if (cap_props != NULL)
 376       font_bdf->props = cap_props;
 377   }
 378 
 379   if ((font_bdf->font_file = vf_strdup(font_file)) == NULL){
 380     vf_error = VF_ERR_NO_MEMORY;
 381     goto End;
 382   }
 383   if ((font_bdf->font_name = vf_strdup(font_name)) == NULL){
 384     vf_error = VF_ERR_NO_MEMORY;
 385     goto End;
 386   }
 387 
 388   if ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL){
 389     fprintf(stderr, "VFlib internal error: in bdf_create()\n");
 390     vf_error = VF_ERR_INTERNAL;
 391     goto End;
 392   }
 393 
 394   font_bdf->ccv_id = -1;
 395   if ((charset != NULL) || (encoding != NULL)){
 396     if (font_charset == NULL){
 397       s1 = bdf_get_font_prop(font, "CHARSET_REGISTRY");
 398       s2 = bdf_get_font_prop(font, "CHARSET_ENCODING");
 399       if (s1 == NULL)
 400         goto no_ccv;
 401       if (s2 == NULL)
 402         s2 = "";
 403       sprintf(s_font_charset, "%s%s", s1, s2);
 404       font_charset = s_font_charset;
 405     }
 406     font_bdf->ccv_id 
 407       = vf_ccv_require(charset, encoding, font_charset, font_encoding);
 408   }
 409 no_ccv:
 410 
 411   font->private = font_bdf;
 412   val = 0;
 413 
 414 
 415 End:
 416   if (implicit == 0){ /* explicit font */
 417     vf_sexp_free3(&cap_font, &cap_point, &cap_pixel);
 418     vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
 419     vf_sexp_free2(&cap_mag, &cap_aspect);
 420     vf_sexp_free2(&cap_charset, &cap_encoding);
 421     vf_sexp_free2(&cap_font_charset, &cap_font_encoding);
 422     vf_sexp_free1(&cap_fontdirs);
 423   }
 424   if (val < 0){
 425     if (implicit == 0)
 426       vf_sexp_free1(&cap_props);
 427     if (bdf_id >= 0)
 428       BDF_Close(bdf_id);
 429     if (font_bdf != NULL){
 430       vf_free(font_bdf->font_name); 
 431       vf_free(font_bdf->font_file); 
 432     }
 433     vf_free(font_bdf); 
 434   }
 435 
 436   return val;
 437 }
 438 
 439 
 440 Private int
 441 bdf_close(VF_FONT font)
     /* [<][>][^][v][top][bottom][index][help] */
 442 {
 443   FONT_BDF  font_bdf;
 444 
 445   font_bdf = (FONT_BDF)font->private;
 446 
 447   if (font_bdf->bdf_id >= 0)
 448     BDF_Close(font_bdf->bdf_id);
 449 
 450   vf_sexp_free1(&font_bdf->props);
 451   vf_free(font_bdf->font_name); 
 452   vf_free(font_bdf->font_file); 
 453   vf_free(font_bdf); 
 454 
 455   return 0; 
 456 }
 457 
 458 
 459 Private int
 460 bdf_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 461                 double mag_x, double mag_y)
 462 {
 463   long        cp;
 464   FONT_BDF    font_bdf;
 465   BDF         bdf;
 466   BDF_CHAR    bdf_char;
 467   double      mx, my;
 468 
 469   if (metric == NULL){
 470     fprintf(stderr, "VFlib internal error: in bdf_get_metric1()\n");
 471     abort();
 472   }
 473   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 474       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 475     fprintf(stderr, "VFlib internal error: in bdf_get_metric1()\n");
 476     abort();
 477   }
 478 
 479   cp = code_point;
 480   if (font_bdf->ccv_id >= 0)
 481     cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
 482   if (bdf_debug('c')) 
 483     printf("VFlib BDF: CCV  0x%lx => 0x%lx\n", code_point, cp);
 484 
 485   if ((bdf_char = BDF_GetBDFChar(bdf, cp)) == NULL)
 486     return -1;
 487 
 488   mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y, 
 489              font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
 490 
 491   /* 72*pix/dpi = 72*pix/(pix/inch) = 72*inch = 72*(pt/72) = pt  */
 492   /* 1inch = 72pt */
 493 
 494   metric->bbx_width
 495     = 72.0 * mx * bdf_char->bbx_width / bdf->dpi_x;
 496   metric->bbx_height
 497     = 72.0 * my * bdf_char->bbx_height  / bdf->dpi_y;
 498   metric->off_x 
 499     = 72.0 * mx * (bdf_char->off_x / bdf->dpi_x) / bdf->dpi_x;
 500   metric->off_y 
 501     = 72.0 * my * (bdf_char->bbx_height + bdf_char->off_y) / bdf->dpi_y;
 502   metric->mv_x
 503     = 72.0 * mx * bdf_char->mv_x / bdf->dpi_x;
 504   metric->mv_y
 505     = 72.0 * my * bdf_char->mv_y / bdf->dpi_y;
 506 
 507   return 0;
 508 }
 509 
 510 Private int
 511 bdf_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 512                  double *w_p, double *h_p, double *xoff_p, double *yoff_p)
 513 {
 514   FONT_BDF    font_bdf;
 515   BDF         bdf;
 516   double      mx, my;
 517 
 518   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 519       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 520     fprintf(stderr, "VFlib internal error: in bdf_get_fontbbx1()\n");
 521     abort();
 522   }
 523   
 524   mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y, 
 525              font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
 526 
 527   *w_p    = 72.0 * mx * bdf->font_bbx_width / bdf->dpi_x;
 528   *h_p    = 72.0 * my * bdf->font_bbx_height / bdf->dpi_y;
 529   *xoff_p = 72.0 * mx * bdf->font_bbx_xoff / bdf->dpi_x;
 530   *yoff_p = 72.0 * my * bdf->font_bbx_yoff / bdf->dpi_y;
 531 
 532   return 0;
 533 }
 534 
 535 
 536 Private VF_BITMAP
 537 bdf_get_bitmap1(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 538                 double mag_x, double mag_y)
 539 {
 540   long       cp;
 541   BDF        bdf;
 542   FONT_BDF   font_bdf;
 543   double     mx, my;
 544   VF_BITMAP  bm;
 545 
 546   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 547       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 548     fprintf(stderr, "VFlib internal error: in bdf_get_bitmap1()\n");
 549     abort();
 550   }
 551 
 552   cp = code_point;
 553   if (font_bdf->ccv_id >= 0)
 554     cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
 555   if (bdf_debug('c')) 
 556     printf("VFlib BDF: CCV  0x%lx => 0x%lx\n", code_point, cp);
 557 
 558   if ((bm = bdf_get_bitmap(font_bdf, cp)) == NULL)
 559     return NULL;
 560 
 561   mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y, 
 562              font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
 563 
 564   return VF_MakeScaledBitmap(bm, mx, my);
 565   /* WE SOULD NOT RELEASE "bm". See bdf_get_bitmap(). */
 566 }
 567 
 568 Private VF_OUTLINE
 569 bdf_get_outline(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 570                 double mag_x, double mag_y)
 571 {
 572   long          cp;
 573   FONT_BDF      font_bdf;
 574   BDF           bdf;
 575   VF_BITMAP     bm;
 576   VF_OUTLINE    ol;
 577   double        mx, my, ps, dpi_x, dpi_y, f_bbx_w, f_bbx_h;
 578 
 579   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 580       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 581     fprintf(stderr, "VFlib internal error: in bdf_get_outline()\n");
 582     abort();
 583   }
 584 
 585   cp = code_point;
 586   if (font_bdf->ccv_id >= 0)
 587     cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
 588   if (bdf_debug('c')) 
 589     printf("VFlib BDF: CCV  0x%lx => 0x%lx\n", code_point, cp);
 590 
 591   if ((bm = bdf_get_bitmap1(font, cp, mag_x, mag_y)) == NULL)
 592     return NULL;
 593 
 594   mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y, 
 595              font_bdf, font, mag_x, mag_y, &mx, &my, &ps, &dpi_x, &dpi_y);
 596 
 597   f_bbx_w = bdf->font_bbx_width  * mx;
 598   f_bbx_h = bdf->font_bbx_height * my;
 599 
 600   ol = vf_bitmap_to_outline(bm, f_bbx_w, f_bbx_h, dpi_x, dpi_y, ps, 1, 1);
 601   VF_FreeBitmap(bm);
 602 
 603   return ol;
 604 }
 605 
 606 
 607 Private int
 608 bdf_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
     /* [<][>][^][v][top][bottom][index][help] */
 609                 double mag_x, double mag_y)
 610 {
 611   long        cp;
 612   FONT_BDF    font_bdf;
 613   BDF         bdf;
 614   BDF_CHAR    bdf_char;
 615   double      mx, my;
 616 
 617   if (metric == NULL){
 618     fprintf(stderr, "VFlib internal error: in bdf_get_metric2()\n");
 619     abort();
 620   }
 621   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 622       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 623     fprintf(stderr, "VFlib internal error: in bdf_get_metric2()\n");
 624     abort();
 625   }
 626 
 627   cp = code_point;
 628   if (font_bdf->ccv_id >= 0)
 629     cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
 630   if (bdf_debug('c')) 
 631     printf("VFlib BDF: CCV  0x%lx => 0x%lx\n", code_point, cp);
 632 
 633   if ((bdf_char = BDF_GetBDFChar(bdf, cp)) == NULL)
 634     return -1;
 635 
 636   mag_mode_2(bdf->pixel_size, bdf->size, 
 637              font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
 638 
 639   metric->bbx_width  = toint(mx * bdf_char->bbx_width);
 640   metric->bbx_height = toint(my * bdf_char->bbx_height);
 641   metric->off_x   = toint(mx * bdf_char->off_x);
 642   metric->off_y   = toint(my * (bdf_char->bbx_height + bdf_char->off_y));
 643   metric->mv_x    = toint(mx * bdf_char->mv_x);
 644   metric->mv_y    = toint(my * bdf_char->mv_y);
 645 
 646   return 0;
 647 }
 648 
 649 Private int
 650 bdf_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 651                  int *w_p, int *h_p, int *xoff_p, int *yoff_p)
 652 {
 653   FONT_BDF    font_bdf;
 654   BDF         bdf;
 655   double      mx, my;
 656 
 657   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 658       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 659     fprintf(stderr, "VFlib internal error: in bdf_get_fontbbx1()\n");
 660     abort();
 661   }
 662   
 663   mag_mode_2(bdf->pixel_size, bdf->size, 
 664              font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
 665   *w_p    = toint(mx * bdf->font_bbx_width);
 666   *h_p    = toint(my * bdf->font_bbx_height);
 667   *xoff_p = toint(mx * bdf->font_bbx_xoff);
 668   *yoff_p = toint(my * bdf->font_bbx_yoff);
 669 
 670   return 0;
 671 }
 672 
 673 
 674 Private VF_BITMAP
 675 bdf_get_bitmap2(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 676                 double mag_x, double mag_y)
 677 {
 678   long       cp;
 679   BDF        bdf;
 680   FONT_BDF   font_bdf;
 681   VF_BITMAP  bm;
 682   double     mx, my;
 683 
 684   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 685       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 686     fprintf(stderr, "VFlib internal error: in bdf_get_bitmap2()\n");
 687     abort();
 688   }
 689 
 690   cp = code_point;
 691   if (font_bdf->ccv_id >= 0)
 692     cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
 693   if (bdf_debug('c')) 
 694     printf("VFlib BDF: CCV  0x%lx => 0x%lx\n", code_point, cp);
 695 
 696   if ((bm = bdf_get_bitmap(font_bdf, cp)) == NULL)
 697     return NULL;
 698 
 699   /* WE SOULD NOT RELEASE "bm". See bdf_get_bitmap(). */
 700 
 701   mag_mode_2(bdf->pixel_size, bdf->size,
 702              font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
 703 
 704   return VF_MakeScaledBitmap(bm, mx, my);
 705 }
 706 
 707 
 708 Private VF_BITMAP
 709 bdf_get_bitmap(FONT_BDF font_bdf, long code_point)
     /* [<][>][^][v][top][bottom][index][help] */
 710 {
 711   BDF_CHAR  bdf_char;
 712   static struct vf_s_bitmap   bitmap;
 713 
 714   bdf_char = BDF_GetBitmap(font_bdf->bdf_id, code_point);
 715   if ((bdf_char == NULL) || (bdf_char->bitmap == NULL))
 716     return NULL;
 717 
 718   bitmap.bbx_width  = bdf_char->bbx_width;
 719   bitmap.bbx_height = bdf_char->bbx_height;
 720   bitmap.off_x  = bdf_char->off_x;
 721   bitmap.off_y  = bdf_char->bbx_height + bdf_char->off_y;
 722   bitmap.mv_x   = bdf_char->mv_x;
 723   bitmap.mv_y   = bdf_char->mv_y;
 724   bitmap.bitmap = bdf_char->bitmap;
 725   bitmap.raster = bdf_char->raster;
 726 
 727   return &bitmap;  
 728   /* CALLER MUST *NOT* CALL VF_FreeBitmap()! */
 729 }
 730 
 731 
 732 Private char*
 733 bdf_get_font_prop(VF_FONT font, char *prop_name)
     /* [<][>][^][v][top][bottom][index][help] */
 734      /* CALLER MUST RELEASE RETURNED STRING */
 735 {
 736   FONT_BDF   font_bdf;
 737   BDF        bdf;
 738   SEXP       v;
 739   double     ps, dpix, dpiy;
 740   char       str[512], *r;
 741 
 742   if (   ((font_bdf = (FONT_BDF)font->private) == NULL)
 743       || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
 744     fprintf(stderr, "VFlib: internal error: in bdf_get_font_prop()\n");
 745     abort();
 746   }
 747 
 748   if ((v = vf_sexp_assoc(prop_name, font_bdf->props)) != NULL){
 749     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 750   } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
 751     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 752   } else {
 753     if (font->mode == 1){
 754       mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y, 
 755                  font_bdf, font, 1, 1, NULL, NULL, &ps, &dpix, &dpiy);
 756       /**printf("** Mode1 %.3f %.3f %.3f   %.3f %.3f\n", ps, dpix, dpiy,
 757              font->point_size, font_bdf->point_size);**/
 758       if (strcmp(prop_name, "POINT_SIZE") == 0){
 759         sprintf(str, "%d", toint(10.0 * ps));
 760         return vf_strdup(str);
 761       } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 762         sprintf(str, "%d", toint(ps * dpiy / POINTS_PER_INCH));
 763         return vf_strdup(str);
 764       } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 765         sprintf(str, "%d", toint(dpix)); 
 766         return vf_strdup(str);
 767       } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 768         sprintf(str, "%d", toint(dpiy)); 
 769         return vf_strdup(str);
 770       } 
 771     } else if (font->mode == 2){
 772       mag_mode_2(bdf->pixel_size, bdf->size,
 773                  font_bdf, font, 1, 1, NULL, NULL, &ps);
 774       /**printf("** Mode2 %.3f\n", ps);**/
 775       if (strcmp(prop_name, "POINT_SIZE") == 0){
 776         sprintf(str, "%d", toint(10.0 * ps * POINTS_PER_INCH / DEFAULT_DPI)); 
 777         return vf_strdup(str);
 778       } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 779         sprintf(str, "%d", toint(ps)); 
 780         return vf_strdup(str);
 781       } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 782         sprintf(str, "%d", toint(DEFAULT_DPI)); 
 783         return vf_strdup(str);
 784       } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 785         sprintf(str, "%d", toint(DEFAULT_DPI)); 
 786         return vf_strdup(str);
 787 #ifndef HAVE_FONT_ASCENT
 788       } else if (strcmp(prop_name, "FONT_ASCENT") == 0){
 789         sprintf(str, "%d", bdf->ascent); 
 790         return vf_strdup(str);
 791 #endif /*HAVE_FONT_ASCENT*/
 792 #ifndef HAVE_FONT_DESCENT
 793       } else if (strcmp(prop_name, "FONT_DESCENT") == 0){
 794         sprintf(str, "%d", bdf->descent); 
 795         return vf_strdup(str);
 796 #endif /*HAVE_FONT_DESCNET*/
 797       } 
 798     }      
 799   }
 800 
 801   if ((r = BDF_GetProp(bdf, prop_name)) != NULL)
 802     return vf_strdup(r);
 803 
 804   return NULL;
 805 }
 806 
 807 
 808 Private int  bdf_debug2(char type, char *str);
 809 
 810 Private int
 811 bdf_debug(char type)
     /* [<][>][^][v][top][bottom][index][help] */
 812 {
 813   int   v;
 814   char  *p0;
 815 
 816   v = FALSE;
 817   if (env_debug_mode != NULL){
 818     if ((v = bdf_debug2(type, env_debug_mode)) == TRUE)
 819       return TRUE;
 820   }
 821 
 822   if (default_debug_mode == NULL)
 823     return FALSE;
 824   if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
 825     return FALSE;
 826   return bdf_debug2(type, p0);
 827 }
 828 
 829 Private int
 830 bdf_debug2(char type, char *p0)
     /* [<][>][^][v][top][bottom][index][help] */
 831 {
 832   char  *p;
 833 
 834   for (p = p0; *p != '\0'; p++){
 835     if (*p == type)
 836       return TRUE;
 837   }
 838   for (p = p0; *p != '\0'; p++){
 839     if (*p == '*')
 840       return TRUE;
 841   }
 842   return FALSE;
 843 }
 844 
 845 
 846 Private void
 847 mag_mode_1(double font_size, int size,
     /* [<][>][^][v][top][bottom][index][help] */
 848            double font_dpi_x, double font_dpi_y,
 849            FONT_BDF font_bdf, VF_FONT font, 
 850            double mag_x, double mag_y,
 851            double *ret_mag_x, double *ret_mag_y, double *ret_point_size,
 852            double *ret_dpix, double *ret_dpiy)
 853 {
 854   double  mx, my, dpix, dpiy, ps, asp;
 855 
 856   if ((ps = font->point_size) < 0)
 857     if ((ps = font_bdf->point_size) < 0)
 858       if ((ps = font_size) < 0)
 859         if ((ps = size) < 0)
 860           ps = DEFAULT_PIXEL_SIZE;
 861   
 862   asp = (v_default_aspect * font_bdf->aspect);
 863 
 864   mx = mag_x * font_bdf->mag * font->mag_x * asp * ps / (double)font_size;
 865   my = mag_y * font_bdf->mag * font->mag_y       * ps / (double)font_size;
 866 
 867   ps = mag_y * font_bdf->mag * font->mag_y * ps;
 868 
 869   if ((font->dpi_x > 0) && (font->dpi_y > 0)){
 870     dpix = font->dpi_x;
 871     dpiy = font->dpi_y;
 872   } else if ((font_bdf->dpi_x > 0) && (font_bdf->dpi_y > 0)){
 873     dpix = font_bdf->dpi_x;
 874     dpiy = font_bdf->dpi_y;
 875   } else if ((v_default_dpi_x > 0) && (v_default_dpi_y > 0)){
 876     dpix = v_default_dpi_x;
 877     dpiy = v_default_dpi_y;
 878   } else {
 879     dpix = font_dpi_x;
 880     dpiy = font_dpi_y;
 881   }
 882 
 883   if (ret_mag_x != NULL)
 884     *ret_mag_x = mx * (dpix / font_dpi_x);
 885   if (ret_mag_y != NULL)
 886     *ret_mag_y = my * (dpiy / font_dpi_y);
 887 
 888 #if 0
 889   printf("*** %.3f %.3f %.3f\n", mag_x, font_bdf->mag, font->mag_x);
 890   printf("    %.3f %.3f %.3f\n", mag_y, font_bdf->mag, font->mag_y);
 891   printf("    dpix=%.3f  font_dpi_x=%.3f\n", dpix, font_dpi_x);
 892   printf("    dpiy=%.3f  font_dpi_y=%.3f\n", dpiy, font_dpi_y);
 893   printf("    asp=%.3f\n", asp);
 894   printf("    mx=%.3f, my=%.3f\n", mx, my);
 895   if (ret_mag_x != NULL)
 896     printf("    mag_x=%.3f, mag_y=%.3f\n", *ret_mag_x, *ret_mag_y);
 897 #endif
 898 
 899   if (ret_point_size != NULL)
 900     *ret_point_size = ps;
 901 
 902   if (ret_dpix != NULL)
 903     *ret_dpix = dpix;
 904   if (ret_dpiy != NULL)
 905     *ret_dpiy = dpiy;
 906 }
 907 
 908 Private void
 909 mag_mode_2(int font_size, int size,
     /* [<][>][^][v][top][bottom][index][help] */
 910            FONT_BDF font_bdf, VF_FONT font, 
 911            double mag_x, double mag_y,
 912            double *ret_mag_x, double *ret_mag_y, double *ret_pixel_size)
 913 {
 914   double  mx, my, ps, asp;
 915 
 916   if ((ps = font->pixel_size) < 0)
 917     if ((ps = font_bdf->pixel_size) < 0)
 918       if ((ps = font_size) < 0)
 919         if ((ps = size) < 0)
 920           ps = DEFAULT_PIXEL_SIZE;
 921 
 922   asp = v_default_aspect * font_bdf->aspect;
 923 
 924   if (font_size <= 0){
 925     mx = mag_x * font_bdf->mag * font->mag_x * asp;
 926     my = mag_y * font_bdf->mag * font->mag_y;
 927   } else {
 928     mx = mag_x * font_bdf->mag * font->mag_x * asp * ps /(double)font_size;
 929     my = mag_y * font_bdf->mag * font->mag_y *       ps /(double)font_size;
 930   }
 931 
 932   ps = ps * font_bdf->mag * font->mag_y;
 933 
 934   if (ret_mag_x != NULL)
 935     *ret_mag_x = mx;
 936   if (ret_mag_y != NULL)
 937     *ret_mag_y = my;
 938 
 939   if (ret_pixel_size != NULL)
 940     *ret_pixel_size = ps;
 941 }
 942 
 943 
 944 
 945 
 946 
 947 /* 
 948  * Include Low-Level Font Interface Routine. 
 949  */ 
 950 #define STRCMP(s1,s2) strncmp(s1,s2,sizeof(s2)-1)
     /* [<][>][^][v][top][bottom][index][help] */
 951 
 952 #include "bdf.c"
 953 
 954 
 955 static int   bdf_last_bdf_id = -1;
 956 static BDF   bdf_last_bdf    = NULL;
 957 
 958 Private void
 959 BDF_SetBDF(int bdf_id, BDF bdf)
     /* [<][>][^][v][top][bottom][index][help] */
 960 {
 961   bdf_last_bdf_id  = bdf_id;
 962   bdf_last_bdf     = bdf;
 963 }
 964 
 965 Private BDF
 966 BDF_GetBDF(int bdf_id)
     /* [<][>][^][v][top][bottom][index][help] */
 967 {
 968   BDF   bdf;
 969 
 970   if (bdf_id == -1){
 971     bdf_last_bdf_id  = -1;
 972     bdf_last_bdf     = NULL;
 973     return NULL;
 974   }
 975 
 976   if (   (bdf_last_bdf_id == bdf_id) 
 977       && (bdf_last_bdf != NULL) 
 978       && (bdf_last_bdf_id != -1))
 979     return bdf_last_bdf;
 980   
 981   bdf = (bdf_table->get_obj_by_id)(bdf_table, bdf_id);
 982   bdf_last_bdf_id = bdf_id;
 983   bdf_last_bdf    = bdf;  
 984 
 985   return bdf;
 986 }
 987 
 988 
 989 /*EOF*/

/* [<][>][^][v][top][bottom][index][help] */