src/drv_t1.c

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

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_Type1
  2. log_level
  3. add_file_search_path
  4. type1_create
  5. type1_close
  6. type1_get_metric1
  7. type1_get_fontbbx1
  8. type1_get_bitmap1
  9. type1_get_outline1
  10. type1_get_metric2
  11. type1_get_fontbbx2
  12. type1_get_bitmap2
  13. mag_factor
  14. type1_get_xxx
  15. type1_get_font_prop
  16. type1_debug
  17. type1_debug2

   1 /*
   2  * drv_t1.c - A font driver for Type 1 fonts with t1ib library.  
   3  * by Hirotsugu Kakugawa
   4  *
   5  * 15 Jan 1998  First implementation by T1Lib 0.7.1-beta
   6  * 21 Jan 1998  Added type1_get_outline1() using vf_bitmap_to_outline(). 
   7  *              The obtained outline is very ugly but it works, anyway.
   8  * 17 Oct 1998  A bug in Get font metric 1 is fixed.
   9  * 29 Nov 1998  Changed to use T1Lib 0.8 beta.
  10  * 24 Dec 1998  Code for obtaining metrics in mode 1 fonts is fixed.
  11  * 28 Dec 1998  Improved not to open the same font file more than once.
  12  *  3 May 2001  Improved.
  13  * 18 May 2001  Font file names can be given more than one.
  14  * 28 Oct 2001  Upgrade to T1Lib 1.3.
  15  */
  16 /*
  17  * Copyright (C) 1998-2001 Hirotsugu Kakugawa. 
  18  * All rights reserved.
  19  *
  20  * This file is part of the VFlib Library.  This library is free
  21  * software; you can redistribute it and/or modify it under the terms of
  22  * the GNU Library General Public License as published by the Free
  23  * Software Foundation; either version 2 of the License, or (at your
  24  * option) any later version.  This library is distributed in the hope
  25  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  26  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  27  * PURPOSE.  See the GNU Library General Public License for more details.
  28  * You should have received a copy of the GNU Library General Public
  29  * License along with this library; if not, write to the Free Software
  30  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  31  */
  32 
  33 /* debug flag in vflibcap (debug capability):
  34  *    f - font path and font open information
  35  *    c - code mapping table information (ccv info)
  36  *    p - code mapping table information (non-ccv info)
  37  *    m - font metric information
  38  *    * - everything
  39  */
  40 
  41 #include  "config.h"
  42 #include  <stdio.h>
  43 #include  <stdlib.h>
  44 #ifdef HAVE_UNISTD_H
  45 #  include <unistd.h>
  46 #endif
  47 #include  <ctype.h>
  48 #include  <math.h>
  49 #include  <sys/param.h>
  50 
  51 #include  <t1lib.h>
  52 #include  "VFlib-3_6.h"
  53 #include  "VFsys.h"
  54 #include  "vflibcap.h"
  55 #include  "bitmap.h"
  56 #include  "cache.h"
  57 #include  "fsearch.h"
  58 #include  "path.h"
  59 #include  "str.h"
  60 #include  "sexp.h"
  61 #include  "ccv.h"
  62 #include  "t1.h"
  63 #include  "texfonts.h"
  64 #include  "tfm.h"
  65 
  66 
  67 Private VF_TABLE     t1_free_table  = NULL;
  68 
  69 
  70 
  71 Private SEXP_LIST    default_font_dirs;
  72 Private SEXP_LIST    default_afm_dirs;
  73 Private SEXP_LIST    default_enc_dirs;
  74 Private SEXP_STRING  default_point_size;
  75 Private double       v_default_point_size;
  76 Private SEXP_STRING  default_pixel_size;
  77 Private double       v_default_pixel_size;
  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_ALIST   default_log_level;
  85 Private SEXP_STRING  default_debug_mode;
  86 Private char        *env_debug_mode = NULL;
  87 #define DEBUG_ENV_NAME   "VFLIB_DEBUG_TYPE1"
  88 
  89 
  90 struct s_font_type1 {
  91   char     *font_name;
  92   char     *font_path;
  93   int       t1fid;
  94   char     *t1encfile;
  95   char    **t1encvect;
  96   double    point_size;
  97   double    pixel_size;
  98   double    dpi_x, dpi_y; 
  99   double    aspect;
 100   double    mag;
 101   double    slant;
 102   int       font_number;
 103   char     *charset_name;
 104   char     *encoding_name;
 105   SEXP      props;
 106   int       ccv_id;
 107   double    last_extend;
 108   char     *tfm_name;
 109   TFM       tfm;
 110 };
 111 typedef struct s_font_type1  *FONT_TYPE1;
 112 
 113 
 114 Private int         type1_create(VF_FONT,char*,char*,int,SEXP);
 115 Private int         type1_close(VF_FONT);
 116 Private int         type1_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
 117 Private int         type1_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
 118 Private int         type1_get_fontbbx1(VF_FONT font,double,double,
 119                                        double*,double*,double*,double*);
 120 Private int         type1_get_fontbbx2(VF_FONT font, double,double,
 121                                        int*,int*,int*,int*);
 122 Private VF_BITMAP   type1_get_bitmap1(VF_FONT,long,double,double);
 123 Private VF_BITMAP   type1_get_bitmap2(VF_FONT,long,double,double);
 124 Private VF_OUTLINE  type1_get_outline1(VF_FONT,long,double,double);
 125 Private char       *type1_get_font_prop(VF_FONT,char*);
 126 Private int         type1_debug(char);
 127 
 128 Private int  log_level(SEXP s);
 129 Private int  add_file_search_path(int type,  SEXP dirs);
 130 
 131 
 132 #define LASTVAL_NONE  -10000
 133 
 134 
 135 #define MODE_METRIC1  1  
 136 #define MODE_BITMAP1  2  
 137 #define MODE_FONTBBX1 3  
 138 #define MODE_OUTLINE  4
 139 #define MODE_METRIC2  5
 140 #define MODE_FONTBBX2 6  
 141 #define MODE_BITMAP2  7
 142 
 143 struct s_fontbbx1 {
 144   double  w, h;
 145   double  xoff, yoff;
 146 };
 147 typedef struct s_fontbbx1  *FONTBBX1; 
 148 struct s_fontbbx2 {
 149   int     w, h;
 150   int     xoff, yoff;
 151 };
 152 typedef struct s_fontbbx2  *FONTBBX2;
 153 
 154 Private void* type1_get_xxx(int mode, 
 155                             VF_FONT font, long code_point, 
 156                             double mag_x, double mag_y, 
 157                             VF_METRIC1 metric1, VF_METRIC2 metric2,
 158                             FONTBBX1 bbx1, FONTBBX2 bbx2);
 159 
 160 
 161 
 162 static int   Initialized_t1lib = 0;
 163 
 164 
 165 
 166 
 167 
 168 Public int
 169 VF_Init_Driver_Type1(void)
     /* [<][>][^][v][top][bottom][index][help] */
 170 {
 171   int       ini_arg, level;
 172   struct s_capability_table  ct[20];
 173   int  z;
 174 
 175   z = 0;
 176   /* VF_CAPE_FONT_DIRECTORIES */
 177   ct[z].cap = VF_CAPE_FONT_DIRECTORIES;      ct[z].type = CAPABILITY_LIST;
 178   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_font_dirs;
 179   /* VF_CAPE_TYPE1_AFM_DIRECTORIES */
 180   ct[z].cap = VF_CAPE_TYPE1_AFM_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
 181   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_afm_dirs;
 182   /* VF_CAPE_TYPE1_ENC_DIRECTORIES */
 183   ct[z].cap = VF_CAPE_TYPE1_ENC_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
 184   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_enc_dirs;
 185   /* VF_CAPE_POINT_SIZE */
 186   ct[z].cap = VF_CAPE_POINT_SIZE;            ct[z].type = CAPABILITY_STRING; 
 187   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_point_size;
 188   /* VF_CAPE_PIXEL_SIZE */
 189   ct[z].cap = VF_CAPE_PIXEL_SIZE;            ct[z].type = CAPABILITY_STRING;
 190   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_pixel_size;
 191   /* VF_CAPE_DPI */
 192   ct[z].cap = VF_CAPE_DPI;                   ct[z].type = CAPABILITY_STRING;
 193   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_dpi;
 194   /* VF_CAPE_DPI_X */
 195   ct[z].cap = VF_CAPE_DPI_X;                 ct[z].type = CAPABILITY_STRING;
 196   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_dpi_x;
 197   /* VF_CAPE_DPI_Y */
 198   ct[z].cap = VF_CAPE_DPI_Y;                 ct[z].type = CAPABILITY_STRING;
 199   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_dpi_y;
 200   /* VF_CAPE_ASPECT_RATIO */
 201   ct[z].cap = VF_CAPE_ASPECT_RATIO;          ct[z].type = CAPABILITY_STRING;
 202   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_aspect;
 203   /* VF_CAPE_PROPERTIES */
 204   ct[z].cap = VF_CAPE_PROPERTIES;            ct[z].type = CAPABILITY_ALIST;
 205   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_properties;
 206   /* VF_CAPE_VARIABLE_VALUES */
 207   ct[z].cap = VF_CAPE_VARIABLE_VALUES;       ct[z].type = CAPABILITY_ALIST;
 208   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_variables;
 209   /* VF_CAPE_TYPE1_LOG_LEVEL */
 210   ct[z].cap = VF_CAPE_TYPE1_LOG_LEVEL;       ct[z].type = CAPABILITY_STRING;
 211   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_log_level;
 212   /* VF_CAPE_DEBUG */
 213   ct[z].cap = VF_CAPE_DEBUG;                 ct[z].type = CAPABILITY_STRING;
 214   ct[z].ess = CAPABILITY_OPTIONAL;           ct[z++].val = &default_debug_mode;
 215   /* end */
 216   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 217 
 218   if ((t1_free_table = vf_table_create()) == NULL){
 219     vf_error = VF_ERR_NO_MEMORY;
 220     return -1;
 221   }
 222 
 223   if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL) 
 224       == VFLIBCAP_PARSED_ERROR)
 225     return -1;
 226 
 227   env_debug_mode = getenv(DEBUG_ENV_NAME);
 228 
 229   if (Initialized_t1lib == 0){
 230     T1_SetBitmapPad(8);
 231     level = log_level(default_log_level);
 232     T1_SetLogLevel(level);
 233     ini_arg = ((level > 0) ? LOGFILE : NO_LOGFILE)
 234               | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE;
 235 
 236     if (T1_InitLib(ini_arg) == NULL){
 237       vf_error = VF_ERR_T1LIB_INIT;
 238       return -1;
 239     }
 240 
 241     T1_SetFileSearchPath(T1_PFAB_PATH, DIR_T1);
 242     T1_SetFileSearchPath(T1_AFM_PATH,  DIR_T1);
 243     add_file_search_path(T1_AFM_PATH,  default_afm_dirs);
 244     T1_SetFileSearchPath(T1_ENC_PATH,  DIR_T1);
 245     add_file_search_path(T1_ENC_PATH,  default_enc_dirs);
 246 
 247     if (type1_debug('f')) {
 248       printf("VFlib Type1: Search Path (%d) = %s\n",
 249              T1_PFAB_PATH, T1_GetFileSearchPath(T1_PFAB_PATH));
 250       printf("VFlib Type1: Search Path (%d) = %s\n",
 251              T1_AFM_PATH,  T1_GetFileSearchPath(T1_AFM_PATH));
 252       printf("VFlib Type1: Search Path (%d) = %s\n",
 253              T1_ENC_PATH,  T1_GetFileSearchPath(T1_ENC_PATH));
 254     }  
 255 
 256     Initialized_t1lib = 1;
 257   }
 258 
 259   v_default_point_size = DEFAULT_POINT_SIZE;
 260   if (default_point_size != NULL)
 261     v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
 262   if (v_default_point_size < 0)
 263     v_default_point_size = DEFAULT_POINT_SIZE;
 264 
 265   v_default_pixel_size = DEFAULT_PIXEL_SIZE;
 266   if (default_pixel_size != NULL)
 267     v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
 268   if (v_default_pixel_size < 0)
 269     v_default_pixel_size  = DEFAULT_PIXEL_SIZE;
 270 
 271   v_default_dpi_x  = TYPE1_DEFAULT_DPI;
 272   v_default_dpi_y  = TYPE1_DEFAULT_DPI;
 273   if (default_dpi != NULL)
 274     v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
 275   if (default_dpi_x != NULL)
 276     v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
 277   if (default_dpi_y != NULL)
 278     v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
 279   if (v_default_dpi_x < 0)
 280     v_default_dpi_x = TYPE1_DEFAULT_DPI;
 281   if (v_default_dpi_y < 0)
 282     v_default_dpi_y = TYPE1_DEFAULT_DPI;
 283 
 284   v_default_aspect = 1.0;
 285   if (default_aspect != NULL)
 286     v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
 287   if (v_default_aspect < 0)
 288     v_default_aspect = 1.0;
 289 
 290   VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)type1_create);
 291 
 292   return 0;
 293 }
 294 
 295 Private int
 296 log_level(SEXP s) 
     /* [<][>][^][v][top][bottom][index][help] */
 297 {
 298   char  *p;
 299 
 300   if (   (s == NULL) 
 301       || (!vf_sexp_stringp(s)) 
 302       || ((p = vf_sexp_get_cstring(s)) == NULL)){
 303     return -1;
 304   }
 305 
 306   if (vf_strcmp_ci(p, "") == 0)
 307     return -1;
 308   if (vf_strncmp_ci(p, "NO", 2) == 0)
 309     return -1;
 310 
 311   if (vf_strncmp_ci(p, "ERR", 3) == 0)
 312     return T1LOG_ERROR;
 313   if (vf_strncmp_ci(p, "WARN", 4) == 0)
 314     return T1LOG_WARNING;
 315   if (vf_strncmp_ci(p, "STAT", 4) == 0)
 316     return T1LOG_STATISTIC;
 317   if (vf_strncmp_ci(p, "DEBUG", 5) == 0)
 318     return T1LOG_DEBUG;
 319 
 320   return -1;
 321 }
 322 
 323 Private int
 324 add_file_search_path(int type,  SEXP dirs)
     /* [<][>][^][v][top][bottom][index][help] */
 325 {
 326   char  *p;
 327   SEXP  d;
 328 
 329   if (type == T1_ENC_PATH){  
 330     if ((dirs == NULL) || (vf_sexp_null(dirs))){
 331       /* add default directory */
 332       T1_AddToFileSearchPath(T1_ENC_PATH, 
 333                              T1_APPEND_PATH, DIR_T1);
 334       T1_AddToFileSearchPath(T1_ENC_PATH, 
 335                              T1_APPEND_PATH, DIR_RUNTIME_SITE_LIB);
 336       T1_AddToFileSearchPath(T1_ENC_PATH, 
 337                              T1_APPEND_PATH, DIR_RUNTIME_SITE_LIB "/t1lib");
 338       return 0;
 339     }
 340   }
 341 
 342   while (vf_sexp_consp(dirs)){
 343     d = vf_sexp_car(dirs);
 344     if (vf_sexp_stringp(d)){ 
 345       p = vf_sexp_get_cstring(d);
 346       if ((p != NULL) 
 347           && (strcmp(p, "") != 0)
 348           && (strcmp(p, "TEXMF") != 0)
 349           && (strcmp(p, "KPATHSEA") != 0)
 350           && vf_path_directory_read_ok(p)){
 351 #if 0
 352         printf("Path (%d): %s\n", type, p);
 353 #endif
 354         T1_AddToFileSearchPath(type, T1_APPEND_PATH, p);
 355       }
 356     }
 357     dirs = vf_sexp_cdr(dirs);
 358   }
 359   
 360   return 0;
 361 }
 362   
 363 
 364 
 365 Private int
 366 type1_create(VF_FONT font, char *font_class, char *font_name, 
     /* [<][>][^][v][top][bottom][index][help] */
 367              int implicit, SEXP entry)
 368 {
 369   FONT_TYPE1    font_type1;
 370   char      *font_file = NULL, *font_path = NULL;
 371   SEXP       cap_font, cap_encfile, cap_point, cap_pixel;
 372   SEXP       cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect, cap_slant;
 373   SEXP       cap_charset, cap_encoding, cap_tfm, cap_props;
 374   struct s_capability_table  ct[20];
 375   int        z, val, *ip, i, lk;
 376   SEXP      s;
 377   char     *tfm_path;
 378   
 379   z = 0;
 380   /* VF_CAPE_FONT_CLASS */
 381   ct[z].cap = VF_CAPE_FONT_CLASS;     ct[z].type = CAPABILITY_STRING;
 382   ct[z].ess = CAPABILITY_ESSENTIAL;   ct[z++].val = NULL;
 383   /* VF_CAPE_FONT_FILE */
 384   ct[z].cap = VF_CAPE_FONT_FILE;      ct[z].type = CAPABILITY_STRING_LIST1;
 385   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_font;
 386   /* VF_CAPE_TYPE1_ENC_VECT */
 387   ct[z].cap = VF_CAPE_TYPE1_ENC_VECT; ct[z].type = CAPABILITY_STRING;
 388   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_encfile;
 389   /* VF_CAPE_POINT_SIZE */
 390   ct[z].cap = VF_CAPE_POINT_SIZE;     ct[z].type = CAPABILITY_STRING;
 391   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_point;
 392   /* VF_CAPE_PIXEL_SIZE */
 393   ct[z].cap = VF_CAPE_PIXEL_SIZE;     ct[z].type = CAPABILITY_STRING;
 394   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_pixel;
 395   /* VF_CAPE_DPI */
 396   ct[z].cap = VF_CAPE_DPI;            ct[z].type = CAPABILITY_STRING;
 397   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_dpi;
 398   /* VF_CAPE_DPI_X */
 399   ct[z].cap = VF_CAPE_DPI_X;          ct[z].type = CAPABILITY_STRING;
 400   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_dpi_x;
 401   /* VF_CAPE_DPI_Y */
 402   ct[z].cap = VF_CAPE_DPI_Y;          ct[z].type = CAPABILITY_STRING;
 403   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_dpi_y;
 404   /* VF_CAPE_MAG */
 405   ct[z].cap = VF_CAPE_MAG;            ct[z].type = CAPABILITY_STRING;
 406   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_mag;
 407   /* VF_CAPE_ASPECT_RATIO */
 408   ct[z].cap = VF_CAPE_ASPECT_RATIO;   ct[z].type = CAPABILITY_STRING;
 409   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_aspect;
 410   /* VF_CAPE_SLANT_FACTOR */
 411   ct[z].cap = VF_CAPE_SLANT_FACTOR;   ct[z].type = CAPABILITY_STRING;
 412   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_slant;
 413   /* VF_CAPE_CHARSET */
 414   ct[z].cap = VF_CAPE_CHARSET;        ct[z].type = CAPABILITY_STRING;
 415   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_charset;
 416   /* VF_CAPE_ENCODING */
 417   ct[z].cap = VF_CAPE_ENCODING;       ct[z].type = CAPABILITY_STRING;
 418   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_encoding;
 419   /* VF_CAPE_TYPE1_TFM */
 420   ct[z].cap = VF_CAPE_TYPE1_TFM;      ct[z].type = CAPABILITY_STRING;
 421   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_tfm;
 422   /* VF_CAPE_PROPERTIES */
 423   ct[z].cap = VF_CAPE_PROPERTIES;     ct[z].type = CAPABILITY_ALIST;
 424   ct[z].ess = CAPABILITY_OPTIONAL;    ct[z++].val = &cap_props;
 425   /* end */
 426   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 427 
 428   val = -1;
 429   font_type1 = NULL;
 430   font_file = NULL;
 431   font_path = NULL;
 432 
 433 
 434   if (implicit == 1){   /* implicit font */
 435     font_file = font_name;
 436   } else {              /* explicit font */
 437     if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
 438                                   default_variables, NULL) < 0)
 439       return -1;
 440     if (cap_font == NULL){
 441       /* Use font name as font file name if font file name is not given. */
 442       font_file = font_name;
 443     } else {
 444       font_file = NULL;   /* list in 'cap_font' */
 445     }
 446   }
 447 
 448   font->font_type       = VF_FONT_TYPE_OUTLINE;
 449   font->get_metric1     = type1_get_metric1;
 450   font->get_metric2     = type1_get_metric2;
 451   font->get_fontbbx1    = type1_get_fontbbx1;
 452   font->get_fontbbx2    = type1_get_fontbbx2;
 453   font->get_bitmap1     = type1_get_bitmap1;
 454   font->get_bitmap2     = type1_get_bitmap2;
 455   font->get_outline     = type1_get_outline1;
 456   font->get_font_prop   = type1_get_font_prop;
 457   font->query_font_type = NULL;  /* Use font->font_type value. */
 458   font->close           = type1_close;
 459 
 460   if (font_file != NULL){
 461     font_path = vf_search_file(font_file, -1, NULL, 
 462                                TRUE, FSEARCH_FORMAT_TYPE_TYPE1, 
 463                                default_font_dirs, NULL, NULL);
 464   } else {
 465     font_path = NULL;
 466     for (s = cap_font; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 467       font_file = vf_sexp_get_cstring(vf_sexp_car(s));
 468       font_path = vf_search_file(font_file, -1, NULL, 
 469                                  TRUE, FSEARCH_FORMAT_TYPE_TYPE1, 
 470                                  default_font_dirs, NULL, NULL);
 471       if (font_path != NULL)
 472         break;
 473     }
 474   }
 475 
 476   if (font_path == NULL){
 477     if (type1_debug('f')) 
 478       printf("VFlib Type1: font file %s not found\n", font_file);
 479     vf_error = VF_ERR_NO_FONT_FILE;
 480     goto End;
 481   }
 482   if (type1_debug('f')) 
 483     printf("VFlib Type1: font file %s\n   ==> %s\n", font_file, font_path);
 484 
 485   ALLOC_IF_ERR(font_type1, struct s_font_type1){
 486     vf_error = VF_ERR_NO_MEMORY;
 487     vf_free(font_path);
 488     goto End;
 489     return -1;
 490   }
 491 
 492   if ((font_type1->font_name = vf_strdup(font_name)) == NULL){
 493     vf_error = VF_ERR_NO_MEMORY;
 494     vf_free(font_path);
 495     goto End;
 496   }
 497   font_type1->font_path      = font_path;
 498   font_type1->t1fid          = -1;
 499   font_type1->t1encfile      = NULL;
 500   font_type1->t1encvect      = NULL;
 501   font_type1->point_size     = -1;
 502   font_type1->pixel_size     = -1;
 503   font_type1->mag            = 1;
 504   font_type1->dpi_x          = v_default_dpi_x;
 505   font_type1->dpi_y          = v_default_dpi_y;
 506   font_type1->aspect         = v_default_aspect;
 507   font_type1->slant          = 0;
 508   font_type1->charset_name   = NULL;
 509   font_type1->encoding_name  = NULL;
 510   font_type1->last_extend    = LASTVAL_NONE;
 511   font_type1->tfm_name       = NULL;
 512   font_type1->tfm            = NULL;
 513 
 514   if (implicit == 0){
 515     if (cap_encfile != NULL)
 516       font_type1->t1encfile = vf_strdup(vf_sexp_get_cstring(cap_encfile));
 517     if (cap_point != NULL)
 518       font_type1->point_size = atof(vf_sexp_get_cstring(cap_point));
 519     if (cap_pixel != NULL)
 520       font_type1->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
 521     if (cap_dpi != NULL)
 522       font_type1->dpi_x = font_type1->dpi_y 
 523         = atof(vf_sexp_get_cstring(cap_dpi));
 524     if (cap_dpi_x != NULL)
 525       font_type1->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
 526     if (cap_dpi_y != NULL)
 527       font_type1->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
 528     if (cap_mag != NULL)
 529       font_type1->mag = atof(vf_sexp_get_cstring(cap_mag));
 530     if (cap_aspect != NULL)
 531       font_type1->aspect = atof(vf_sexp_get_cstring(cap_aspect));
 532     if (cap_slant != NULL)
 533       font_type1->slant = atof(vf_sexp_get_cstring(cap_slant));
 534     if (cap_charset != NULL)
 535       font_type1->charset_name = vf_strdup(vf_sexp_get_cstring(cap_charset));
 536     if (cap_encoding != NULL)
 537       font_type1->encoding_name = vf_strdup(vf_sexp_get_cstring(cap_encoding));
 538     if (cap_props != NULL)
 539       font_type1->props = cap_props;
 540     if (cap_tfm != NULL){
 541       font_type1->tfm_name = vf_strdup(vf_sexp_get_cstring(cap_tfm));
 542     }
 543   }
 544 
 545   if (type1_debug('f')) 
 546     printf("VFlib Type1: opening font: %s\n", font_name);
 547 
 548   i = (t1_free_table->get_id_by_key)(t1_free_table, 
 549                                      font_type1->font_path, 
 550                                      strlen(font_type1->font_path)+1);
 551   if (i >= 0){
 552     ip = (t1_free_table->get_obj_by_id)(t1_free_table, i);
 553     font_type1->t1fid = *ip;
 554     lk = (t1_free_table->unlink_by_id)(t1_free_table, i);
 555     if (lk == 0)
 556       vf_free(ip);
 557   } else {
 558     if (type1_debug('f')) 
 559       printf("VFlib Type1: T1_AddFont(%s)\n", font_type1->font_path);
 560     if ((font_type1->t1fid = T1_AddFont(font_type1->font_path)) < 0){
 561       fprintf(stderr, "VFlib Type1: cannot add file: %s\n", 
 562               font_type1->font_path);
 563       vf_error = VF_ERR_NO_FONT_FILE;
 564       goto End;
 565     }
 566   }
 567 
 568   if (type1_debug('f'))
 569     printf("VFlib Type1: T1_LoadFont(%d)\n", font_type1->t1fid);
 570   if (T1_LoadFont(font_type1->t1fid) < 0){
 571     fprintf(stderr, "VFlib Type1: cannot load file: %s\n", 
 572             font_type1->font_path);
 573     vf_error = VF_ERR_NO_FONT_FILE;
 574     goto End;
 575   }
 576 
 577   if (font_type1->t1encfile != NULL){
 578     font_type1->t1encvect = T1_LoadEncoding(font_type1->t1encfile);
 579     if (font_type1->t1encvect  == NULL){
 580       fprintf(stderr, "VFlib Type1: cannot load encoding vector: %s\n",
 581               font_type1->t1encfile);
 582       vf_error = VF_ERR_NO_FONT_FILE;
 583       goto End;
 584     }
 585     if (type1_debug('f')) 
 586       printf("VFlib Type1: use encoding vector: %s\n", font_type1->t1encfile);
 587     if (T1_ReencodeFont(font_type1->t1fid, font_type1->t1encvect) < 0){
 588       fprintf(stderr, "VFlib Type1: failed to reencode font: %s, %s\n", 
 589               font_type1->font_path, font_type1->t1encfile);
 590       goto End;
 591     }
 592   } else {
 593     font_type1->t1encvect = NULL;
 594     if (T1_ReencodeFont(font_type1->t1fid, NULL) < 0){
 595       goto End;
 596     }
 597   }
 598 
 599   if (T1_SlantFont(font_type1->t1fid, font_type1->slant) < 0){
 600     fprintf(stderr, "VFlib Type1: failed slanting: %s, %.3f\n", 
 601             font_type1->font_path, font_type1->slant);
 602     goto End;
 603   }
 604 
 605   if (T1_ExtendFont(font_type1->t1fid, font_type1->aspect) < 0){
 606     fprintf(stderr, "VFlib Type1: failed extending: %s, %.3f\n", 
 607             font_type1->font_path, font_type1->aspect);
 608     goto End;
 609   }
 610   
 611   if (type1_debug('f')){
 612     printf("VFlib Type1: t1lib font id %d, name=%s\n", 
 613            font_type1->t1fid, T1_GetFontName(font_type1->t1fid));
 614   }
 615 
 616   if (font_type1->tfm_name != NULL){
 617     if (type1_debug('t'))
 618       printf("VFlib Type1: TFM file=%s\n", font_type1->tfm_name);
 619     tfm_path = vf_tex_search_file_tfm(font_type1->tfm_name, NULL, NULL);
 620     if (tfm_path == NULL){
 621       vf_error = VF_ERR_NO_FONT_FILE;
 622       goto End;
 623     }
 624     if (type1_debug('t'))
 625       printf("VFlib Type1: TFM path=%s\n", tfm_path);
 626     font_type1->tfm = vf_tfm_open(tfm_path);
 627     vf_free(tfm_path);
 628     if (font_type1->tfm == NULL){
 629       fprintf(stderr, "VFlib: Cannot open TFM %s for font %s\n", 
 630               font_type1->tfm_name, font_file);
 631       vf_error = VF_ERR_NO_FONT_FILE;
 632       goto End;
 633     }
 634   }
 635 
 636 #if 1   /*** NO SUPPORT FOR CCV **/
 637   font_type1->ccv_id = -1;
 638 #else
 639   font_type1->ccv_id 
 640     = vf_ccv_require(charset, encoding, font_charset, font_encoding);
 641   if (type1_debug('c'))
 642     printf("VFlib Type1: CCV ID = %d\n", ccv_id);
 643 #endif
 644 
 645   /* OK */
 646   font->private = font_type1;
 647   val = 0;
 648 
 649 End:
 650   if (implicit == 0){   /* explicit font */
 651     vf_sexp_free4(&cap_font, &cap_encfile, &cap_point, &cap_pixel);
 652     vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
 653     vf_sexp_free3(&cap_mag, &cap_aspect, &cap_slant);
 654     vf_sexp_free3(&cap_charset, &cap_encoding, &cap_tfm);
 655     vf_sexp_free1(&cap_props);
 656   }
 657   if (val < 0){
 658     type1_close(font);
 659   }
 660 
 661   return val;
 662 }
 663 
 664 
 665 Private int
 666 type1_close(VF_FONT font)
     /* [<][>][^][v][top][bottom][index][help] */
 667 {
 668   FONT_TYPE1  font_type1;
 669   int  *ip;
 670 
 671   font_type1 = (FONT_TYPE1)font->private;
 672 
 673   if (font_type1 != NULL){ 
 674     if (font_type1->t1fid >= 0){
 675       ALLOC_IF_ERR(ip, int){
 676         goto err;
 677       }
 678       *ip = font_type1->t1fid;
 679       (t1_free_table->put2)(t1_free_table, ip, font_type1->font_path, 
 680                             strlen(font_type1->font_path)+1);
 681     }
 682   err:
 683     vf_sexp_free(&font_type1->props);
 684     vf_free(font_type1->font_name); 
 685     vf_free(font_type1->font_path); 
 686     vf_free(font_type1->charset_name);
 687     vf_free(font_type1->encoding_name);
 688     vf_free(font_type1->tfm_name);
 689     vf_tfm_free(font_type1->tfm);
 690     vf_free(font_type1->t1encfile); 
 691     if (font_type1->t1encvect != NULL)
 692       T1_DeleteEncoding(font_type1->t1encvect);
 693     if (font_type1->t1fid >= 0)
 694       T1_DeleteFont(font_type1->t1fid);
 695     vf_free(font_type1);
 696   }
 697 
 698   return 0; 
 699 }
 700 
 701 
 702 Private int
 703 type1_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 704                   double mag_x, double mag_y)
 705 {
 706   if (type1_get_xxx(MODE_METRIC1, font, code_point, mag_x, mag_y, 
 707                     metric, NULL, NULL, NULL) == NULL)
 708     return -1;
 709   return 0;
 710 }
 711 
 712 
 713 Private int
 714 type1_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 715                    double *w_p, double *h_p, double *xoff_p, double *yoff_p)
 716 {
 717   struct s_fontbbx1  bbx1;
 718 
 719   if (type1_get_xxx(MODE_FONTBBX1, font, -1, mag_x, mag_y, 
 720                     NULL, NULL, &bbx1, NULL) == NULL)
 721     return -1;
 722 
 723   *w_p    = bbx1.w;
 724   *h_p    = bbx1.h; 
 725   *xoff_p = bbx1.xoff;
 726   *yoff_p = bbx1.yoff;
 727   return 0;
 728 }
 729 
 730 
 731 Private VF_BITMAP
 732 type1_get_bitmap1(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 733                   double mag_x, double mag_y)
 734 {
 735   VF_BITMAP  bm;  
 736 #if 0
 737   FONT_TYPE1 font_type1;
 738   struct vf_s_metric1 met;
 739   long       w, h;
 740   double     dpix, dpiy;
 741 #endif
 742  
 743   bm = (VF_BITMAP)type1_get_xxx(MODE_BITMAP1, font, code_point, mag_x, mag_y, 
 744                                 NULL, NULL, NULL, NULL);
 745 #if 0
 746   if (bm == NULL){
 747     if (type1_get_xxx(MODE_METRIC1, font, code_point, mag_x, mag_y, 
 748                       &met, NULL, NULL, NULL) == NULL)
 749       return NULL;
 750     font_type1 = (FONT_TYPE1)font->private;
 751     if (((dpix = font->dpi_x) < 0) || ((dpiy = font->dpi_y) < 0)){
 752       dpix = font_type1->dpi_x;
 753       dpiy = font_type1->dpi_y;
 754     }
 755     w = met.bbx_width  * dpix;
 756     h = met.bbx_height * dpiy;
 757     bm = vf_alloc_bitmap(w, h);
 758     bm->off_x      = met.bbx_width  * dpix;
 759     bm->off_y      = met.bbx_height * dpiy;
 760     bm->mv_x       = met.mv_x       * dpix;
 761     bm->mv_y       = met.mv_y       * dpiy;
 762   }
 763 #endif
 764 
 765   return bm;
 766 }
 767 
 768 
 769 Private VF_OUTLINE
 770 type1_get_outline1(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 771                  double mag_x, double mag_y)
 772 {
 773   VF_OUTLINE  ol;
 774 
 775   ol = type1_get_xxx(MODE_OUTLINE, font, code_point, mag_x, mag_y, 
 776                      NULL, NULL, NULL, NULL);
 777   return  ol;
 778 }
 779 
 780 
 781 Private int
 782 type1_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
     /* [<][>][^][v][top][bottom][index][help] */
 783                 double mag_x, double mag_y)
 784 {
 785   if (type1_get_xxx(MODE_METRIC2, font, code_point, mag_x, mag_y, 
 786                     NULL, metric, NULL, NULL) == NULL)
 787     return -1;
 788   return 0;
 789 }
 790 
 791 
 792 Private int
 793 type1_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 794                    int *w_p, int *h_p, int *xoff_p, int *yoff_p)
 795 {
 796   struct s_fontbbx2  bbx2;
 797 
 798   if (type1_get_xxx(MODE_FONTBBX2, font, -1, mag_x, mag_y, 
 799                     NULL, NULL, NULL, &bbx2) == NULL)
 800     return -1;
 801 
 802   *w_p    = bbx2.w;
 803   *h_p    = bbx2.h; 
 804   *xoff_p = bbx2.xoff;
 805   *yoff_p = bbx2.yoff;
 806   return 0;
 807 }
 808 
 809 
 810 Private VF_BITMAP
 811 type1_get_bitmap2(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 812                 double mag_x, double mag_y)
 813 {
 814   VF_BITMAP  bm;
 815 #if 0
 816   struct vf_s_metric2 met;
 817 #endif
 818 
 819   bm = (VF_BITMAP)type1_get_xxx(MODE_BITMAP2, font, code_point, mag_x, mag_y,
 820                                 NULL, NULL, NULL, NULL);
 821 #if 0
 822   if (bm == NULL){
 823     if (type1_get_xxx(MODE_METRIC2, font, code_point, mag_x, mag_y, 
 824                       NULL, &met, NULL, NULL) == NULL){
 825       return NULL;
 826     }
 827     bm = vf_alloc_bitmap(met.bbx_width, met.bbx_height);
 828     bm->off_x = met.bbx_width;
 829     bm->off_y = met.bbx_height;
 830     bm->mv_x  = met.mv_x;
 831     bm->mv_y  = met.mv_y;
 832   }
 833 #endif
 834 
 835   return bm;
 836 }
 837 
 838 
 839 Private void
 840 mag_factor(VF_FONT font, FONT_TYPE1 font_type1, 
     /* [<][>][^][v][top][bottom][index][help] */
 841            double mag_x, double mag_y, double ps0,
 842            double *mx, double *my, double *asp, double *ps)
 843 {
 844   *mx = mag_x * font_type1->mag * font->mag_x;
 845   *my = mag_y * font_type1->mag * font->mag_y;
 846   *asp = v_default_aspect * font_type1->aspect * (*mx / *my);
 847   if (*asp < 0)
 848     *asp = 0.0 - *asp;
 849   *ps = ps0 * *my;
 850 
 851   if (type1_debug('x'))
 852     printf("VFlib Type1: asp=%.3f mx=%.3f my=%.3f\n", *asp, *mx, *my);
 853   if (type1_debug('p'))
 854     printf("VFlib Type1: ps=%.3f ps0=%.3f\n", *ps, ps0);
 855 }
 856 
 857 
 858 Private void*
 859 type1_get_xxx(int mode, 
     /* [<][>][^][v][top][bottom][index][help] */
 860               VF_FONT font, long code_point, 
 861               double mag_x, double mag_y,
 862               VF_METRIC1 metric1, VF_METRIC2 metric2,
 863               FONTBBX1 bbx1, FONTBBX2 bbx2)
 864 {
 865   void         *val;
 866   FONT_TYPE1    font_type1;
 867   VF_BITMAP     bm;
 868   GLYPH        *t1_glyph;
 869   BBox          bbox;
 870   long          cp;
 871   int           x, y, w, f_bbx_w, f_bbx_h, i; 
 872   BBox          font_bbox;
 873   T1_TMATRIX    unity_matrix = {1.0, 0.0, 0.0, 1.0};
 874   T1_TMATRIX    matrix;
 875   double        ps = 0.0, ps0 = 0.0, mx, my, asp, dpix = 0.0, dpiy = 0.0; 
 876   unsigned char *p;
 877   static double last_dpix = LASTVAL_NONE;
 878   static double last_dpiy = LASTVAL_NONE;
 879   /* a table for LSB-MSB exchange for 4 bits */
 880   static unsigned char  EXCHG_MLSB4[] = {  
 881        0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
 882        0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
 883   /*
 884    *   0000 1000 0100 1100 0010 1010 0110 1110   exchanged
 885    *   0001 1001 0101 1101 0011 1011 0111 1111 
 886    * <===
 887    *   0000 0001 0010 0011 0100 0101 0110 0111   original
 888    *   1000 1001 1010 1011 1100 1101 1110 1111 
 889    */
 890   
 891   if ((font_type1 = (FONT_TYPE1)font->private) == NULL){
 892     fprintf(stderr, "VFlib: internal error in type1_get_xxx() 1\n");
 893     abort();
 894   }
 895 
 896   if (   (mode == MODE_METRIC1)
 897       || (mode == MODE_FONTBBX1)
 898       || (mode == MODE_BITMAP1)
 899       || (mode == MODE_OUTLINE)){
 900     if (((dpix = font->dpi_x) < 0) || ((dpiy = font->dpi_y) < 0)){
 901       dpix = font_type1->dpi_x;
 902       dpiy = font_type1->dpi_y;
 903     }
 904     if ((ps0 = font->point_size) < 0)
 905       if ((ps0 = font_type1->point_size) < 0)
 906         ps0 = v_default_point_size;
 907   } else if (   (mode == MODE_METRIC2)
 908              || (mode == MODE_FONTBBX2)
 909              || (mode == MODE_BITMAP2)){
 910     dpix = TYPE1_POINTS_PER_INCH;
 911     dpiy = TYPE1_POINTS_PER_INCH;
 912     if ((ps0 = font->pixel_size) < 0)
 913       if ((ps0 = font_type1->pixel_size) < 0)
 914         ps0 = v_default_pixel_size;
 915   } else {
 916     fprintf(stderr, "VFlib: internal error in type1_get_xxx() 2\n");
 917     abort();
 918   }
 919 
 920   mag_factor(font, font_type1, mag_x, mag_y, ps0, &mx, &my, &asp, &ps);
 921 #if 0
 922   mx = mag_x * font_type1->mag * font->mag_x;
 923   my = mag_y * font_type1->mag * font->mag_y;
 924   asp = v_default_aspect * font_type1->aspect * (mx / my);
 925   if (asp < 0)
 926     asp = 0.0 - asp;
 927   ps = ps0 * my;
 928 #endif
 929 
 930 
 931   if (ps0 < 0)
 932     ps0 = 0.0 - ps0;
 933   if (ps < 0)
 934     ps = 0.0 - ps;
 935 
 936   if ((last_dpix != dpix) || (last_dpiy != dpiy)){
 937     for (i = 0; i < T1_Get_no_fonts(); i++)
 938       T1_DeleteAllSizes(i);
 939     if (T1_SetDeviceResolutions((float)dpix, (float)dpiy) < 0){
 940       last_dpix = LASTVAL_NONE; 
 941       last_dpiy = LASTVAL_NONE; 
 942       vf_error = VF_ERR_NO_GLYPH;
 943       return NULL;
 944     }
 945     if (type1_debug('r'))
 946       printf("T1_SetDeviceResolutions %.3f %.3f\n", dpix, dpiy);
 947     last_dpix = dpix;
 948     last_dpiy = dpiy;
 949   }
 950 
 951   if ((mode == MODE_FONTBBX1) || (mode == MODE_FONTBBX2)){
 952     cp = -1;
 953   } else {
 954     if (font_type1->ccv_id < 0){
 955       cp = code_point;
 956     } else {
 957       cp = vf_ccv_conv(font_type1->ccv_id, code_point);
 958       if (type1_debug('c')) 
 959         printf("VFlib Type1: CCV  0x%lx => 0x%lx\n", code_point, cp);
 960     }
 961     if (cp < 0)
 962       return NULL;
 963     if (type1_debug('m')){
 964       if (cp >= 0){
 965         bbox = T1_GetCharBBox(font_type1->t1fid, (char)(cp%256));
 966         printf("T1_CharBBox %ld (0x%lx)  => ", (cp%256), cp);
 967         printf("  llx=%d, lly=%d, urx=%d ury=%d\n",
 968                bbox.llx, bbox.lly, bbox.urx, bbox.ury);
 969       }
 970     }
 971   }
 972   cp = cp % 256;
 973 
 974   val = NULL;
 975   if (   (mode == MODE_BITMAP1) 
 976       || (mode == MODE_BITMAP2) 
 977       || (mode == MODE_OUTLINE) ){
 978     matrix.cxx = asp;
 979     matrix.cxy = 0.0;
 980     matrix.cyx = 0.0;
 981     matrix.cyy = 1.0;
 982     t1_glyph = T1_SetChar(font_type1->t1fid, (char)cp, (float)ps, &matrix);
 983     if (type1_debug('s'))
 984       printf("T1_SetChar fid=%d, 0x%02x, ps=%.3f, asp=%.2f mx=%.2f my=%.2f\n",
 985              font_type1->t1fid, (unsigned int)cp, ps, asp, mx, my);
 986     if (t1_glyph == NULL){
 987       vf_error = VF_ERR_NO_GLYPH;
 988       return NULL;
 989     }
 990 
 991     {
 992       int bbxw
 993         = t1_glyph->metrics.rightSideBearing-t1_glyph->metrics.leftSideBearing;
 994       int bbxh
 995         = t1_glyph->metrics.ascent - t1_glyph->metrics.descent;
 996 
 997       if (t1_glyph->bits == NULL){
 998         bm = vf_alloc_bitmap(bbxw, bbxh);
 999       } else {
1000         ALLOC_IF_ERR(bm, struct vf_s_bitmap){
1001           vf_error = VF_ERR_NO_MEMORY;
1002           return NULL;
1003         }
1004         bm->bbx_width  = bbxw;
1005         bm->bbx_height = bbxh;
1006         bm->raster     = (bm->bbx_width + 7) / 8;
1007         bm->bitmap = (unsigned char*)t1_glyph->bits;
1008         t1_glyph->bits = NULL;
1009         for (y = 0; y < bm->bbx_height; y++){
1010           p = &bm->bitmap[y*bm->raster];
1011           for (x = 0; x < bm->raster; x++, p++)
1012             *p = ((EXCHG_MLSB4[(*p)&0x0f]) << 4) | EXCHG_MLSB4[(*p) >> 4];
1013         }
1014       }
1015       bm->off_x      = t1_glyph->metrics.leftSideBearing;
1016       bm->off_y      = t1_glyph->metrics.ascent;
1017       bm->mv_x       = t1_glyph->metrics.advanceX;
1018       bm->mv_y       = t1_glyph->metrics.advanceY;
1019     }
1020 
1021     if ((mode == MODE_BITMAP1) || (mode == MODE_BITMAP2)){
1022       val = (void*) bm;
1023     } else if (mode == MODE_OUTLINE){
1024       font_bbox = T1_GetFontBBox(font_type1->t1fid);
1025       if (   (font_bbox.urx == 0) && (font_bbox.llx == 0) 
1026           && (font_bbox.ury == 0) && (font_bbox.lly == 0) ){
1027         bbox = T1_GetCharBBox(font_type1->t1fid, (char)cp);
1028         f_bbx_w = bbox.urx - bbox.llx;
1029         f_bbx_h = bbox.ury - bbox.lly;
1030       } else {
1031         f_bbx_w = font_bbox.urx - font_bbox.llx;
1032         f_bbx_h = font_bbox.ury - font_bbox.lly;
1033       }
1034       f_bbx_w = (f_bbx_w * ps / 1000.0) * dpix / TYPE1_POINTS_PER_INCH;
1035       f_bbx_h = (f_bbx_h * ps / 1000.0) * dpiy / TYPE1_POINTS_PER_INCH;
1036       val = (void*) vf_bitmap_to_outline(bm, f_bbx_w, f_bbx_h, 
1037                                          dpix, dpiy, ps0, mx, my);
1038       VF_FreeBitmap(bm);
1039     } else {
1040       fprintf(stderr, "VFlib: internal error in type1_get_xxx() 3\n");
1041       abort();
1042     }
1043     
1044   } else if (mode == MODE_METRIC1){
1045     if (font_type1->tfm == NULL) {
1046       w = T1_GetCharWidth(font_type1->t1fid, (char)cp);
1047       if (w == 0){
1048         vf_error = VF_ERR_NO_GLYPH;
1049         return NULL;
1050       }
1051       bbox = T1_GetCharBBox(font_type1->t1fid, (char)cp);
1052       if (metric1 != NULL){
1053         mx *= ps / 1000.0;
1054         my *= ps / 1000.0;
1055         metric1->bbx_width  = (double)(bbox.urx - bbox.llx) * mx;
1056         metric1->bbx_height = (double)(bbox.ury - bbox.lly) * my;
1057         metric1->off_x      = (double)(bbox.llx) * mx;
1058         metric1->off_y      = (double)(bbox.ury) * my;
1059         metric1->mv_x       = (double)(w) * mx;
1060         metric1->mv_y       = (double)(0) * my;
1061       }
1062     } else {
1063       struct vf_s_metric1  m1;
1064       if (type1_debug('t')){
1065         printf("VFlib Type1 ps=%.2f ps0=%.2f ds=%.2f\n", 
1066                ps, ps0, font_type1->tfm->design_size);
1067       }
1068       m1.mv_x = 0;
1069       vf_tfm_metric(font_type1->tfm, cp, &m1);
1070       if (metric1 != NULL){
1071         metric1->bbx_width  = (double)(m1.bbx_width)  * mx;
1072         metric1->bbx_height = (double)(m1.bbx_height) * my;
1073         metric1->off_x      = (double)(m1.off_x) * mx;
1074         metric1->off_y      = (double)(m1.off_y) * my;
1075         metric1->mv_x       = (double)(m1.mv_x) * mx;
1076         metric1->mv_y       = (double)(m1.mv_y) * my;
1077       }
1078     }
1079     if (metric1 != NULL)
1080       val = (void*) metric1;
1081 
1082   } else if (mode == MODE_METRIC2){
1083     t1_glyph = T1_SetChar(font_type1->t1fid, (char)cp,
1084                           (float)ps, &unity_matrix);
1085     if (t1_glyph == NULL){
1086       vf_error = VF_ERR_NO_GLYPH;
1087       return NULL;
1088     }
1089     if (metric2 != NULL){
1090       metric2->bbx_width  = t1_glyph->metrics.rightSideBearing 
1091                             - t1_glyph->metrics.leftSideBearing;
1092       metric2->bbx_height = t1_glyph->metrics.ascent
1093                             - t1_glyph->metrics.descent;
1094       metric2->off_x      = t1_glyph->metrics.leftSideBearing;
1095       metric2->off_y      = t1_glyph->metrics.ascent;
1096       metric2->mv_x       = t1_glyph->metrics.advanceX;
1097       metric2->mv_y       = t1_glyph->metrics.advanceY;
1098     }
1099     val = (void*) metric2;
1100 
1101   } else if (mode == MODE_FONTBBX1){
1102     font_bbox = T1_GetFontBBox(font_type1->t1fid);
1103     if (type1_debug('m'))
1104       printf("T1_GetFontBBox: urx=%d, ury=%d, llx=%d, lly=%d, x=%.3f\n",
1105              font_bbox.urx, font_bbox.ury, font_bbox.llx, font_bbox.lly,ps);
1106     f_bbx_w = font_bbox.urx - font_bbox.llx;
1107     f_bbx_h = font_bbox.ury - font_bbox.lly;
1108     if (bbx1 != NULL){
1109       bbx1->w = f_bbx_w * ps / 1000.0;
1110       bbx1->h = f_bbx_h * ps / 1000.0;
1111       bbx1->xoff = font_bbox.llx * ps / 1000.0;
1112       bbx1->yoff = font_bbox.lly * ps / 1000.0;
1113     }
1114     val = (void*) bbx1;
1115 
1116   } else if (mode == MODE_FONTBBX2){
1117     font_bbox = T1_GetFontBBox(font_type1->t1fid);
1118     if (type1_debug('m'))
1119       printf("T1_GetFontBBox: urx=%d, ury=%d, llx=%d, lly=%d, x=%.3f\n",
1120              font_bbox.urx, font_bbox.ury, font_bbox.llx, font_bbox.lly, ps);
1121     f_bbx_w = font_bbox.urx - font_bbox.llx;
1122     f_bbx_h = font_bbox.ury - font_bbox.lly;
1123     if (bbx2 != NULL){
1124       bbx2->w = f_bbx_w * ps / 1000.0;
1125       bbx2->h = f_bbx_h * ps / 1000.0;
1126       bbx2->xoff = font_bbox.llx * ps / 1000.0;
1127       bbx2->yoff = font_bbox.lly * ps / 1000.0;
1128     }
1129     val = (void*) bbx2;
1130 
1131   } else {
1132     fprintf(stderr, "VFlib: internal error in type1_get_xxx() 4\n");
1133     fprintf(stderr, "Unknown mode: %d\n", mode);
1134     abort();
1135   }
1136 
1137   return val;
1138 }
1139 
1140 
1141 
1142 Private char*
1143 type1_get_font_prop(VF_FONT font, char *prop_name)
     /* [<][>][^][v][top][bottom][index][help] */
1144 { /* CALLER MUST RELEASE RETURNED STRING LATER */
1145   SEXP       v;
1146   FONT_TYPE1   font_type1;
1147   char       str[512], *s;
1148   double     dpix, dpiy, p;
1149   
1150   if ((font_type1 = (FONT_TYPE1)font->private) == NULL){
1151     fprintf(stderr, "VFlib: internal error in type1_get_font_prop()\n");
1152     abort();
1153   }
1154 
1155   if ((v = vf_sexp_assoc(prop_name, font_type1->props)) != NULL){
1156     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
1157   } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
1158     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
1159   }
1160 
1161   if (font->mode == 1){
1162     if ((dpix = font->dpi_x) < 0)
1163       if ((dpix = font_type1->dpi_x) < 0)
1164         dpix = v_default_dpi_x; 
1165     if ((dpiy = font->dpi_y) < 0)
1166       if ((dpiy = font_type1->dpi_y) < 0)
1167         dpiy = v_default_dpi_y; 
1168     if ((p = font->point_size) < 0)
1169       if ((p = font_type1->point_size) < 0)
1170         p = v_default_point_size;
1171     p = p * font->mag_y * font_type1->mag;
1172     if (strcmp(prop_name, "POINT_SIZE") == 0){  
1173       sprintf(str, "%d", toint(p * 10.0)); 
1174       return vf_strdup(str);
1175     } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
1176       sprintf(str, "%d", toint(p * dpiy / TYPE1_POINTS_PER_INCH));
1177       return vf_strdup(str);
1178     } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
1179       sprintf(str, "%d", toint(dpix)); 
1180       return vf_strdup(str);
1181     } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
1182       sprintf(str, "%d", toint(dpiy)); 
1183       return vf_strdup(str);
1184     }
1185 
1186   } else if (font->mode == 2){
1187     if ((p = font->pixel_size) < 0)
1188       if ((p = font_type1->pixel_size) < 0)
1189         p = v_default_pixel_size;
1190     p = p * font->mag_y * font_type1->mag;
1191     if (strcmp(prop_name, "POINT_SIZE") == 0){  
1192       sprintf(str, "%d", 
1193               toint(p * 10.0 * TYPE1_POINTS_PER_INCH / TYPE1_DEFAULT_DPI)); 
1194     } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
1195       sprintf(str, "%d", toint(p));
1196       return vf_strdup(str);
1197     } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
1198       sprintf(str, "%d", toint(TYPE1_DEFAULT_DPI)); 
1199       return vf_strdup(str);
1200     } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
1201       sprintf(str, "%d", toint(TYPE1_DEFAULT_DPI)); 
1202       return vf_strdup(str);
1203     }
1204   }
1205     
1206   if ((strcmp(prop_name, "FONT_NAME") == 0)
1207       || (strcmp(prop_name, "FontName") == 0)){
1208     if ((s = T1_GetFontName(font_type1->t1fid))!= NULL)
1209       return vf_strdup(s);
1210   } else if ((strcmp(prop_name, "FULL_NAME") == 0)
1211              || (strcmp(prop_name, "FullName") == 0)){
1212     if ((s = T1_GetFullName(font_type1->t1fid))!= NULL)
1213       return vf_strdup(s);
1214   } else if ((strcmp(prop_name, "FAMILY_NAME") == 0)
1215              || (strcmp(prop_name, "FamilyName") == 0)){
1216     if ((s = T1_GetFamilyName(font_type1->t1fid))!= NULL)
1217       return vf_strdup(s);
1218   } else if ((strcmp(prop_name, "WEIGHT_NAME") == 0)
1219              || (strcmp(prop_name, "WEIGHT") == 0)
1220              || (strcmp(prop_name, "Weight") == 0)){
1221     if ((s = T1_GetWeight(font_type1->t1fid))!= NULL)
1222       return vf_strdup(s);
1223   }
1224 
1225 #if 0
1226   if (strcmp(prop_name, "FONT_ASCENT") == 0){
1227     ;
1228   } else if (strcmp(prop_name, "FONT_DESCENT") == 0){
1229     ;
1230   }
1231 #endif
1232 
1233   return NULL;
1234 }
1235 
1236 
1237 
1238 Private int  type1_debug2(char type, char *str);
1239 
1240 Private int
1241 type1_debug(char type)
     /* [<][>][^][v][top][bottom][index][help] */
1242 {
1243   int    v;
1244   char  *p0;
1245 
1246   v = FALSE;
1247   if (env_debug_mode != NULL){
1248     if ((v = type1_debug2(type, env_debug_mode)) == TRUE)
1249       return TRUE;
1250   }
1251 
1252   if (default_debug_mode == NULL)
1253     return FALSE;
1254   if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
1255     return FALSE;
1256   return type1_debug2(type, p0);
1257 }
1258 
1259 Private int
1260 type1_debug2(char type, char *p0)
     /* [<][>][^][v][top][bottom][index][help] */
1261 {
1262   char  *p;
1263 
1264   for (p = p0; *p != '\0'; p++){
1265     if (*p == type)
1266       return TRUE;
1267   }
1268   for (p = p0; *p != '\0'; p++){
1269     if (*p == '*')
1270       return TRUE;
1271   }
1272   return FALSE;
1273 }
1274 
1275 /*EOF*/

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