src/texfonts.c

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

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_TeX
  2. vf_tex_init
  3. syntax_check_resolution_corr
  4. tex_create
  5. vf_tex_try_map_and_open_font
  6. match_font_name
  7. decompose_filename
  8. try_open_mapped_font
  9. get_design_size_from_tfm
  10. tex_map_name
  11. vf_tex_syntax_check_font_mapping
  12. tex_close
  13. tex_get_metric1
  14. tex_get_fontbbx1
  15. tex_get_bitmap1
  16. tex_get_outline
  17. tex_get_metric2
  18. tex_get_fontbbx2
  19. tex_get_bitmap2
  20. tex_get_font_prop
  21. tex_query_font_type
  22. vf_tex_default_dpi
  23. vf_tex_fix_resolution
  24. vf_tex_search_file_tfm
  25. vf_tex_search_file_glyph
  26. vf_tex_search_file_misc
  27. vf_tex_parse_open_style
  28. vf_tex_parse_glyph_style
  29. vf_tex_read_uintn
  30. vf_tex_read_intn
  31. vf_tex_skip_n
  32. vf_tex_get_uintn
  33. vf_tex_get_intn

   1 /*
   2  * texfonts.c - Pseudo font class for TeX-related files  (GF, PK, VF, TFM)
   3  *
   4  * 28 Sep 1996
   5  * 25 Mar 1997  Added setting a program name for kpathsea by variable.
   6  * 02 Apr 1997  Added support for .ofm files (Omega metrics file) (WL)
   7  *  3 Jul 1997  Added Virtual Font support.
   8  *  8 Aug 1997  for VFlib 3.3  
   9  *  1 Feb 1998  for VFlib 3.4
  10  * 22 Jul 1998  Added TeX font mapping feafure.
  11  * 24 Nov 1998  Added get_fontbbx1() and get_fontbbx2().
  12  * 16 Sep 1999  Modified TeX-font-mapper not to open TFM files as possible.
  13  */
  14 /*
  15  * Copyright (C) 1996-1999  Hirotsugu Kakugawa. 
  16  * All rights reserved.
  17  *
  18  * This file is part of the VFlib Library.  This library is free
  19  * software; you can redistribute it and/or modify it under the terms of
  20  * the GNU Library General Public License as published by the Free
  21  * Software Foundation; either version 2 of the License, or (at your
  22  * option) any later version.  This library is distributed in the hope
  23  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  24  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  25  * PURPOSE.  See the GNU Library General Public License for more details.
  26  * You should have received a copy of the GNU Library General Public
  27  * License along with this library; if not, write to the Free Software
  28  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  29  */
  30 
  31 #include  "config.h"
  32 #include  "with.h"
  33 #include  <stdio.h>
  34 #include  <stdlib.h>
  35 #include  <ctype.h>
  36 #ifdef HAVE_UNISTD_H
  37 #  include <unistd.h>
  38 #endif
  39 #include  "VFlib-3_6.h"
  40 #include  "VFsys.h"
  41 #include  "vflibcap.h"
  42 #include  "consts.h"
  43 #include  "cache.h"
  44 #include  "bitmap.h"
  45 #include  "sexp.h"
  46 #include  "str.h"
  47 #include  "path.h"
  48 #include  "fsearch.h"
  49 #include  "texfonts.h"
  50 #include  "tfm.h"
  51 
  52 Private SEXP_STRING  default_tex_dpi            = NULL;
  53 Private int          v_default_tex_dpi          = DEFAULT_DPI;
  54 Private SEXP_LIST    default_fontdirs           = NULL;
  55 Private SEXP_LIST    default_tfm_dirs           = NULL;
  56 Private SEXP_LIST    default_tfm_extensions     = NULL;
  57 Private SEXP         default_font_mapping       = NULL;
  58 Private SEXP         default_resolution_corr    = NULL;
  59 Private SEXP         default_resolution_accu    = NULL;
  60 Private double       v_default_resolution_accu  = DEFAULT_RESOLUTION_ACCU;
  61 Private SEXP_STRING  default_debug_mode         = NULL;
  62 
  63 Glocal SEXP_ALIST    vf_tex_default_properties  = NULL;
  64 Glocal SEXP_ALIST    vf_tex_default_variables   = NULL;
  65 Glocal int           vf_dbg_drv_texfonts        = 0;
  66 
  67 
  68 Private int   tex_create(VF_FONT,char*,char*,int,SEXP);
  69 Private int   syntax_check_resolution_corr(void);
  70 
  71 Private int          tex_create(VF_FONT font, char *font_class, 
  72                                 char *font_name, int implicit, SEXP entry);
  73 Private int          tex_close(VF_FONT font);
  74 Private int          tex_get_metric1(VF_FONT font, long code_point,
  75                                      VF_METRIC1 metric1, double,double);
  76 Private int          tex_get_metric2(VF_FONT font, long code_point,
  77                                      VF_METRIC2 metric2, double,double);
  78 Private int          tex_get_fontbbx1(VF_FONT,double,double,
  79                                       double*,double*,double*,double*);
  80 Private int          tex_get_fontbbx2(VF_FONT,double,double, 
  81                                       int*,int*,int*,int*);
  82 Private VF_BITMAP    tex_get_bitmap1(VF_FONT,long,double,double);
  83 Private VF_BITMAP    tex_get_bitmap2(VF_FONT,long,double,double);
  84 Private VF_OUTLINE   tex_get_outline(VF_FONT,long,double,double);
  85 Private char*        tex_get_font_prop(VF_FONT,char*);
  86 Private int          tex_query_font_type(VF_FONT font, long code_point);
  87 
  88 
  89 Private void  tex_map_name(char *fontname, int n, char *mapping, 
  90                            char *name_str, char *dpi_str, char *ext_str);
  91 Private int   try_open_mapped_font(SEXP s,
  92                                    char *name_str, char *dpi_str,
  93                                    char *ext_str, VF_FONT font, 
  94                                    char *name, double design_size,
  95                                    SEXP tfm_dirs, SEXP tfm_extensions,
  96                                    double opt_mag);
  97 Private double get_design_size_from_tfm(char *font_name, 
  98                                         SEXP tfm_dirs, SEXP tfm_extensions);
  99 Private int    match_font_name(char *name, char *pat);
 100 Private int    decompose_filename(char*,char**,char**,char**,char**);
 101 
 102 
 103 
 104 
 105 Glocal int
 106 VF_Init_Driver_TeX(void)
     /* [<][>][^][v][top][bottom][index][help] */
 107 {
 108   return  vf_tex_init();  
 109 }
 110 
 111 
 112 Glocal int
 113 vf_tex_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 114 {
 115   static int  inited = 0;
 116   struct s_capability_table  ct[20];
 117   int  z;
 118   
 119   z = 0;
 120   /* VF_CAPE_FONT_DIRECTORIES */
 121   ct[z].cap = VF_CAPE_FONT_DIRECTORIES;
 122   ct[z].type = CAPABILITY_STRING_LIST0;
 123   ct[z].ess = CAPABILITY_OPTIONAL;
 124   ct[z++].val = &default_fontdirs;
 125   /* VF_CAPE_DPI */
 126   ct[z].cap = VF_CAPE_DPI;
 127   ct[z].type = CAPABILITY_STRING;
 128   ct[z].ess = CAPABILITY_OPTIONAL;
 129   ct[z++].val = &default_tex_dpi;
 130   /* VF_CAPE_TEX_TFM_DIRECTORIES */
 131   ct[z].cap = VF_CAPE_TEX_TFM_DIRECTORIES; 
 132   ct[z].type = CAPABILITY_STRING_LIST0;
 133   ct[z].ess = CAPABILITY_OPTIONAL;
 134   ct[z++].val = &default_tfm_dirs;
 135   /* VF_CAPE_TEX_TFM_EXTENSIONS */
 136   ct[z].cap = VF_CAPE_TEX_TFM_EXTENSIONS; 
 137   ct[z].type = CAPABILITY_STRING_LIST0;
 138   ct[z].ess = CAPABILITY_OPTIONAL;
 139   ct[z++].val = &default_tfm_extensions;
 140   /* VF_CAPE_TEX_FONT_MAPPING */
 141   ct[z].cap = VF_CAPE_TEX_FONT_MAPPING;
 142   ct[z].type = CAPABILITY_LIST;
 143   ct[z].ess = CAPABILITY_OPTIONAL;
 144   ct[z++].val = &default_font_mapping;
 145   /* VF_CAPE_PROPERTIES */
 146   ct[z].cap = VF_CAPE_PROPERTIES;
 147   ct[z].type = CAPABILITY_ALIST;
 148   ct[z].ess = CAPABILITY_OPTIONAL;
 149   ct[z++].val = &vf_tex_default_properties;
 150   /* VF_CAPE_VARIABLE_VALUES */
 151   ct[z].cap = VF_CAPE_VARIABLE_VALUES;
 152   ct[z].type = CAPABILITY_ALIST;
 153   ct[z].ess = CAPABILITY_OPTIONAL;
 154   ct[z++].val = &vf_tex_default_variables;
 155   /* VF_CAPE_RESOLUTION_CORR */
 156   ct[z].cap = VF_CAPE_RESOLUTION_CORR;
 157   ct[z].type = CAPABILITY_LIST;
 158   ct[z].ess = CAPABILITY_OPTIONAL;
 159   ct[z++].val = &default_resolution_corr;
 160   /* VF_CAPE_RESOLUTION_ACCU */
 161   ct[z].cap = VF_CAPE_RESOLUTION_ACCU;
 162   ct[z].type = CAPABILITY_STRING;
 163   ct[z].ess = CAPABILITY_OPTIONAL;
 164   ct[z++].val = &default_resolution_accu;
 165   /* VF_CAPE_DEBUG */
 166   ct[z].cap = VF_CAPE_DEBUG;
 167   ct[z].type = CAPABILITY_STRING;
 168   ct[z].ess = CAPABILITY_OPTIONAL;
 169   ct[z++].val = &default_debug_mode;
 170   /* end */
 171   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 172 
 173 
 174   if (inited == 1)
 175     return 0;
 176   inited = 1;
 177 
 178   if (getenv("VFLIB_DEBUG_TEXFONTS") != NULL)
 179     vf_dbg_drv_texfonts = 1;
 180 
 181   if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_TeX, ct, NULL, NULL)
 182       == VFLIBCAP_PARSED_ERROR)
 183     return -1;
 184 
 185   v_default_tex_dpi  = DEFAULT_DPI;
 186   if (default_tex_dpi != NULL)
 187     v_default_tex_dpi = atoi(vf_sexp_get_cstring(default_tex_dpi));
 188 
 189   if (default_tfm_extensions == NULL)
 190     default_tfm_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_TFM);
 191   vf_tfm_init();
 192 
 193   if (default_resolution_corr != NULL){
 194     if (syntax_check_resolution_corr() > 0){
 195       vf_sexp_free(&default_resolution_corr);
 196       fprintf(stderr, 
 197               "VFlib: value for capability %s is ignored.\n", 
 198               VF_CAPE_RESOLUTION_CORR);
 199     }
 200   }
 201 
 202   v_default_resolution_accu = DEFAULT_RESOLUTION_ACCU; 
 203   if (default_resolution_accu != NULL){
 204     v_default_resolution_accu 
 205       = atof(vf_sexp_get_cstring(default_resolution_accu));
 206     if (v_default_resolution_accu <= 0)
 207       v_default_resolution_accu = DEFAULT_RESOLUTION_ACCU; 
 208   }
 209 
 210   if (default_font_mapping != NULL){
 211     if (vf_tex_syntax_check_font_mapping(default_font_mapping) > 0){
 212       vf_sexp_free(&default_font_mapping);
 213       fprintf(stderr, 
 214               "VFlib: capability %s is ignored because of syntax error.\n", 
 215               VF_CAPE_TEX_FONT_MAPPING);
 216     }
 217   }
 218 
 219   VF_InstallFontDriver(FONTCLASS_NAME_TeX, (DRIVER_FUNC_TYPE)tex_create);
 220 
 221   return 0;
 222 }
 223 
 224 Private int 
 225 syntax_check_resolution_corr(void)
     /* [<][>][^][v][top][bottom][index][help] */
 226 {
 227   int   syntax_err, syntax_nerrs;
 228   SEXP  s, t, u;
 229   
 230   syntax_nerrs = 0;
 231 
 232   for (s = default_resolution_corr; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 233     syntax_err = 0;
 234     u = t = vf_sexp_car(s); 
 235     /* e.g., u = (300  300 329 360 394 ...) */
 236     if (!vf_sexp_listp(u)){
 237       syntax_err = 1;
 238       syntax_nerrs++;
 239       goto rc_try_next;
 240     }
 241     for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
 242       if (!vf_sexp_stringp(vf_sexp_car(u))
 243           || (atoi(vf_sexp_get_cstring(vf_sexp_car(u))) <= 0)){
 244         syntax_err = 1;
 245         syntax_nerrs++;
 246         goto rc_try_next;
 247       }
 248     }
 249   rc_try_next:
 250     if (syntax_err != 0){
 251       fprintf(stderr, 
 252               "VFlib: %s in capability %s of %s font class default: \n", 
 253               "Syntax error", VF_CAPE_RESOLUTION_CORR, FONTCLASS_NAME_TeX);
 254       vf_sexp_pp_fp(t, stderr);
 255     }
 256   }
 257 
 258   return syntax_nerrs;
 259 }
 260 
 261 
 262 
 263 Private int
 264 tex_create(VF_FONT font, char *font_class, char *font_name, 
     /* [<][>][^][v][top][bottom][index][help] */
 265            int implicit, SEXP entry)
 266 {
 267   int    fid;
 268 
 269   if (implicit == 0){
 270     vf_error = VF_ERR_NO_FONT_ENTRY;
 271     return -1;  /* this driver does not support explicit fonts. */
 272   }
 273 
 274   if (default_font_mapping == NULL){
 275     vf_error = VF_ERR_NO_FONT_ENTRY;
 276     return -1;
 277   }
 278 
 279 #if 1
 280   fid = vf_tex_try_map_and_open_font(font, font_name, default_font_mapping,
 281                                      -1, default_tfm_dirs, 
 282                                      default_tfm_extensions, 1.0);
 283 #else
 284   fid = vf_tex_try_map_and_open_font(font, font_name, default_font_mapping,
 285                                      default_tfm_dirs, 
 286                                      NULL, default_tfm_extensions,
 287                                      1.0);
 288 #endif
 289   if (fid < 0)
 290     return -1;
 291   
 292   font->font_type       = VF_FONT_TYPE_UNDEF;
 293   font->get_metric1     = tex_get_metric1;
 294   font->get_metric2     = tex_get_metric2;
 295   font->get_fontbbx1    = tex_get_fontbbx1;
 296   font->get_fontbbx2    = tex_get_fontbbx2;
 297   font->get_bitmap1     = tex_get_bitmap1;
 298   font->get_bitmap2     = tex_get_bitmap2;
 299   font->get_outline     = tex_get_outline;
 300   font->get_font_prop   = tex_get_font_prop;
 301   font->query_font_type = tex_query_font_type;
 302   font->close           = tex_close;
 303 
 304   font->private         = (void*)fid;
 305 
 306   return 0;
 307 }
 308 
 309 
 310 
 311 Glocal int
 312 vf_tex_try_map_and_open_font(VF_FONT font, char *font_name, SEXP font_mapping,
     /* [<][>][^][v][top][bottom][index][help] */
 313                              double tfm_design_size, 
 314                              SEXP tfm_dirs, SEXP tfm_extensions,
 315                              double opt_mag)
 316 {
 317   char   *name_str, *dpi_str, *ext_str, *ns, *pat;
 318   int    fid;
 319   SEXP   s, t;
 320 
 321   if (font_mapping == NULL){
 322     vf_error = VF_ERR_NO_FONT_ENTRY;
 323     return -1;
 324   }
 325 
 326   fid = -1;
 327   name_str = dpi_str = ext_str = ns = NULL;
 328 
 329   if (decompose_filename(font_name, &name_str, &dpi_str, &ext_str, &ns) < 0)
 330     goto search_end;
 331 
 332   for (s = font_mapping; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 333     for (t = vf_sexp_car(s); 
 334          vf_sexp_consp(t) && !vf_sexp_stringp(vf_sexp_car(t));
 335          t = vf_sexp_cdr(t))
 336       ; /* empty */ 
 337     if (!vf_sexp_consp(t)) 
 338       goto search_end;
 339     while (vf_sexp_consp(t) && vf_sexp_stringp(vf_sexp_car(t))){
 340       pat = vf_sexp_get_cstring(vf_sexp_car(t));
 341       if ((strcmp(ns, pat) == 0) || (strcmp(pat, "*") == 0) 
 342           || (match_font_name(ns, pat) == 1)){
 343         if ((fid = try_open_mapped_font(vf_sexp_car(s), 
 344                                         name_str, dpi_str, ext_str, 
 345                                         font, font_name, 
 346                                         tfm_design_size, 
 347                                         tfm_dirs, tfm_extensions,
 348                                         opt_mag)) >= 0)
 349           goto search_end;
 350       }
 351       t = vf_sexp_cdr(t);
 352     }
 353   }
 354   if (fid < 0)
 355     vf_error = VF_ERR_NO_FONT_ENTRY;
 356 
 357 search_end:
 358   vf_free(name_str);
 359   vf_free(dpi_str);
 360   vf_free(ext_str);
 361 
 362   return fid;
 363 }
 364 
 365 Private int
 366 match_font_name(char *name, char *patt)
     /* [<][>][^][v][top][bottom][index][help] */
 367 {
 368   while (*name != '\0'){
 369     if (*patt == '*'){
 370       return 1;
 371     } else {
 372       if (*patt != *name)
 373         return -1;
 374     }
 375     name++;
 376     patt++;
 377   }
 378 
 379   if (*patt != '\0')
 380     return -1;
 381   return 0;
 382 }
 383 
 384 Private int
 385 decompose_filename(char *font_name, 
     /* [<][>][^][v][top][bottom][index][help] */
 386                    char **name_str_p, char **dpi_str_p, 
 387                    char **ext_str_p, char **ns_p)
 388 {
 389   int     len, i, i0, i1, dellen;
 390   char   *name_str, *dpi_str, *ext_str, *ns;
 391 
 392   name_str = dpi_str = ext_str = ns = NULL;
 393 
 394   len = strlen(font_name);
 395   for (i0 = len-1; i0 >= 0; i0--){
 396     if (font_name[i0] == '.'){ 
 397       /* "cmr10.360pk" ==>           len=11
 398        *     name_str = "cmr10"      i0=5
 399        *     dpi_str  = "360"        i1=9
 400        *     ext_str  = "pk" 
 401        */
 402       if ((name_str = (char*)malloc(i0+1)) == NULL){
 403         vf_error = VF_ERR_NO_MEMORY;
 404         goto end;
 405       }
 406       strncpy(name_str, font_name, i0);
 407       name_str[i0] = '\0';
 408       for (i1 = i0+1; isdigit((int)font_name[i1]); i1++)
 409            ;
 410       if ((dpi_str = (char*)malloc(i1-i0+1)) == NULL){
 411         vf_error = VF_ERR_NO_MEMORY;
 412         goto end;
 413       }
 414       strncpy(dpi_str, &font_name[i0+1], i1-i0-1);
 415       dpi_str[i1-i0-1] = '\0';
 416       if ((ext_str = (char*)malloc(strlen(&font_name[i1]+1))) == NULL){
 417         vf_error = VF_ERR_NO_MEMORY;
 418         goto end;
 419       }
 420       strcpy(ext_str, &font_name[i1]);
 421       break;
 422     }
 423   }
 424 
 425   if ((len > 0)
 426       && (name_str == NULL) && (dpi_str == NULL) && (ext_str == NULL)){
 427     if ((name_str = (char*)malloc(len+1)) == NULL){
 428       vf_error = VF_ERR_NO_MEMORY;
 429       goto end;
 430     }
 431     strcpy(name_str, font_name);
 432   }
 433 
 434 
 435   if (name_str == NULL){
 436     if ((name_str = (char*)malloc(1)) == NULL){
 437       vf_error = VF_ERR_NO_MEMORY;
 438       goto end;
 439     }
 440     name_str[0] = '\0';
 441   } 
 442   if (dpi_str == NULL){
 443     if ((dpi_str = (char*)malloc(1)) == NULL){
 444       vf_error = VF_ERR_NO_MEMORY;
 445       goto end;
 446     }
 447     dpi_str[0] = '\0';
 448   } 
 449   if (ext_str == NULL){
 450     if ((ext_str = (char*)malloc(1)) == NULL){
 451       vf_error = VF_ERR_NO_MEMORY;
 452       goto end;
 453     }
 454     ext_str[0] = '\0';
 455   }
 456   
 457   dellen = strlen(vf_directory_delimiter);
 458   if ((ns = name_str) != NULL){
 459     for (i = strlen(name_str)-1; i >= 0; i--){
 460       if (strncmp(&name_str[i], vf_directory_delimiter, dellen) == 0){
 461         ns = &name_str[i+dellen];
 462         break;
 463       }
 464     }
 465   }
 466 #if 0
 467   printf("*** \"%s\"  => \"%s\", \"%s\", \"%s\", \"%s\"\n",
 468          font_name, name_str, ns, dpi_str, ext_str);
 469 #endif
 470 
 471 end:
 472   if ((name_str == NULL) || (dpi_str == NULL) || (ext_str == NULL)){
 473     vf_free(name_str);
 474     vf_free(dpi_str);
 475     vf_free(ext_str);
 476     return -1;
 477   }
 478 
 479   *name_str_p = name_str;
 480   *dpi_str_p  = dpi_str;
 481   *ext_str_p  = ext_str;
 482   *ns_p       = ns;
 483 
 484   return 0;
 485 }
 486 
 487 Private int
 488 try_open_mapped_font(SEXP s, char *name_str, char *dpi_str, char *ext_str, 
     /* [<][>][^][v][top][bottom][index][help] */
 489                      VF_FONT font, char *font_name, 
 490                      double tfm_design_size, 
 491                      SEXP tfm_dirs, SEXP tfm_extensions,                     
 492                      double opt_mag)
 493 {
 494   SEXP    t, u;
 495   char   *drvname, *mapping;
 496   char    mapped_name[1024];
 497   int     fid, dpix, dpiy;
 498   double  ptsize, mag_adj, mag_x, mag_y;
 499 
 500   fid = -1;
 501   for (fid = -1; 
 502        vf_sexp_consp(s) && vf_sexp_consp(vf_sexp_car(s)); 
 503        s = vf_sexp_cdr(s)){
 504 
 505     t = vf_sexp_car(s);
 506     if (   !vf_sexp_listp(t) 
 507         || (vf_sexp_length(t) < 2)
 508         || !vf_sexp_stringp(vf_sexp_car(t)) 
 509         || !vf_sexp_stringp(vf_sexp_cadr(t)))
 510       continue;
 511 
 512     drvname = vf_sexp_get_cstring(vf_sexp_car(t));
 513     mapping = vf_sexp_get_cstring(vf_sexp_cadr(t));
 514 
 515     ptsize  = font->point_size;
 516     mag_adj = 1.0;
 517     for (t = vf_sexp_cddr(t); vf_sexp_consp(t); t = vf_sexp_cdr(t)){
 518       u = vf_sexp_car(t);
 519       if (vf_sexp_stringp(u)){
 520         if (strcmp(TEX_FONT_MAPPING_PTSIZE, vf_sexp_get_cstring(u)) == 0){
 521           if (tfm_design_size > 0){
 522             ptsize = tfm_design_size;
 523           } else {
 524             ptsize = get_design_size_from_tfm(font_name, 
 525                                               tfm_dirs, tfm_extensions);
 526           }
 527           if (ptsize < 0)
 528             continue;
 529         } else {
 530           fprintf(stderr, 
 531                   "VFlib: %s %s in capability %s for %s class default.\n", 
 532                   "Unknown optional keyword", vf_sexp_get_cstring(u), 
 533                   VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
 534         }
 535       } else if (vf_sexp_listp(u) && (vf_sexp_length(u) >= 2)){
 536         if (vf_sexp_stringp(vf_sexp_car(u))
 537             && vf_sexp_stringp(vf_sexp_cadr(u))
 538             && (strcmp(TEX_FONT_MAPPING_MAG_ADJ, 
 539                        vf_sexp_get_cstring(vf_sexp_car(u))) == 0)){
 540           mag_adj = atof(vf_sexp_get_cstring(vf_sexp_cadr(u)));
 541           if (mag_adj <= 0)
 542             mag_adj = 1.0;
 543         } else {
 544           fprintf(stderr, 
 545                   "VFlib: %s %s for %s class default: ", 
 546                   "Unknown option in capability", 
 547                   VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
 548           vf_sexp_pp_fp(u, stderr);
 549         }
 550       }
 551     }
 552 
 553     mag_x = font->mag_x * opt_mag;
 554     mag_y = font->mag_y * opt_mag;
 555 
 556     tex_map_name(mapped_name, sizeof(mapped_name), mapping, 
 557                  name_str, dpi_str, ext_str);
 558     if (((dpix = font->dpi_x) <= 0) || ((dpiy = font->dpi_y) <= 0)){
 559       dpix = v_default_tex_dpi;
 560       dpiy = v_default_tex_dpi;
 561     }
 562     if (vf_dbg_drv_texfonts == 1){
 563       printf(">> TeX font mapping: %s=>%s (driver:%s)\n", 
 564              font_name, mapped_name, drvname);
 565       printf(">>     pt:%.3f, dpi:%d,%d, mag:%.3f,%.3f, mag_adj=%.3f\n", 
 566              ptsize, dpix, dpiy, mag_x, mag_y, mag_adj); 
 567     }
 568     if (strcmp(drvname, "*") != 0){ 
 569       if (font->mode == 1){
 570         fid = vf_openfont1(mapped_name, drvname, dpix, dpiy, ptsize,
 571                            mag_x * mag_adj, mag_y * mag_adj);
 572       } else {
 573         fid = vf_openfont2(mapped_name, drvname, font->pixel_size, 
 574                            mag_x * mag_adj, mag_y * mag_adj);
 575       } 
 576     } else {
 577       if (font->mode == 1){
 578         fid = VF_OpenFont1(mapped_name, dpix, dpiy, ptsize,
 579                            mag_x * mag_adj, mag_y * mag_adj);
 580       } else {
 581         fid = VF_OpenFont2(mapped_name, font->pixel_size, 
 582                            mag_x * mag_adj, mag_y * mag_adj);
 583       }
 584     }
 585 
 586     if (fid >= 0)
 587       break;
 588   }  
 589 
 590   return fid;
 591 }
 592 
 593 Private double 
 594 get_design_size_from_tfm(char *font_name, SEXP tfm_dirs, SEXP tfm_extensions)
     /* [<][>][^][v][top][bottom][index][help] */
 595 {
 596   TFM     tfm;
 597   char   *tfm_path;
 598   double  ds;
 599 
 600   if (vf_dbg_drv_texfonts == 1)
 601     printf(">> TeX font mapper: search TFM path for %s\n", font_name);
 602   tfm_path = vf_tex_search_file_tfm(font_name, tfm_dirs, tfm_extensions);
 603   if (vf_dbg_drv_texfonts == 1){
 604     if (tfm_path != NULL){
 605       printf(">> TeX font mapper: TFM path: %s\n", tfm_path);
 606     } else {
 607       printf(">> TeX font mapper: TFM not found: %s\n", font_name);
 608       return -1;
 609     }
 610   }
 611   if (tfm_path == NULL)
 612     return -1;
 613 
 614   if ((tfm = vf_tfm_open(tfm_path)) == NULL){
 615     if (vf_dbg_drv_texfonts == 1)
 616       printf(">> TeX font mapper: failed to open TFM: %s\n", tfm_path);
 617     return -1;
 618   }
 619 
 620   ds = tfm->design_size;
 621 
 622   vf_tfm_free(tfm);
 623   vf_free(tfm_path);
 624 
 625   return ds;
 626 }
 627 
 628 Private void
 629 tex_map_name(char *mapped_name, int n, char *mapping, 
     /* [<][>][^][v][top][bottom][index][help] */
 630              char *name_str, char *dpi_str, char *ext_str)
 631 {
 632   char  *p, *s, *t;
 633   int  r;
 634 
 635   p = mapping;
 636   s = mapped_name;
 637   r = n;
 638   while (*p != '\0'){
 639     if (r <= 0)
 640       break;
 641     if (*p != '%'){
 642       *(s++) = *(p++);
 643       r--;
 644     } else {
 645       p++;
 646       switch (*p){
 647       default:
 648         *(s++) = *p;
 649         r--;
 650         break;
 651       case '\0':
 652         *(s++) = '\0';
 653         r--;
 654         break;
 655       case 'f':
 656         /* %f ... font name of requested font name (e.g., "cmr10") */
 657         if (name_str == NULL)
 658           break;
 659         for (t = name_str; (*t != '\0') && (r > 0); r--)
 660           *(s++) = *(t++);
 661         break;
 662       case 'd':
 663         /* %d ... device resolution of requested font name (e.g., "300") */
 664         if (dpi_str == NULL)
 665           break;
 666         for (t = dpi_str; (*t != '\0') && (r > 0); r--)
 667           *(s++) = *(t++);
 668         break;
 669       case 'e':
 670         /* %d ... font name extension of requested font name (e.g., "pk") */
 671         if (ext_str == NULL)
 672           break;
 673         for (t = ext_str; (*t != '\0') && (r > 0); r--)
 674           *(s++) = *(t++);
 675         break;
 676       }
 677       p++;
 678     }
 679   }
 680   *s = '\0';
 681 }
 682 
 683 
 684 Glocal int
 685 vf_tex_syntax_check_font_mapping(SEXP font_mapping)
     /* [<][>][^][v][top][bottom][index][help] */
 686 { 
 687   int   syntax_err, syntax_nerrs;
 688   SEXP  s, t, u, v;
 689 
 690   syntax_nerrs = 0;
 691   for (s = font_mapping; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 692     syntax_err = 0;
 693     u = t = vf_sexp_car(s); 
 694     /* e.g., u = ((pk "%f.pk") (tfm "%f.tfm") "cmr10" "cmti10") */
 695     for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
 696       v = vf_sexp_car(u);
 697       if (vf_sexp_stringp(v))
 698         break;
 699       if (   !vf_sexp_listp(v) || (vf_sexp_length(v) < 2)
 700           || !vf_sexp_stringp(vf_sexp_car(v)) 
 701           || !vf_sexp_stringp(vf_sexp_cadr(v)) ){
 702         syntax_err = 1;
 703         syntax_nerrs++;
 704         goto fm_try_next;
 705       }
 706     }
 707     /* e.g., u = ("cmr10" "cmti10") */
 708     for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
 709       v = vf_sexp_car(u);
 710       if (!vf_sexp_stringp(v)){
 711         syntax_err = 1;
 712         syntax_nerrs++;
 713         goto fm_try_next;
 714       }
 715     }
 716   fm_try_next:
 717     if (syntax_err != 0){
 718       fprintf(stderr, 
 719               "VFlib: %s in capability %s of %s font class default: \n", 
 720               "Syntax error", VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
 721       vf_sexp_pp_fp(t, stderr);
 722     }
 723   }
 724   
 725   return syntax_nerrs;
 726 }
 727 
 728 
 729 
 730 Private int
 731 tex_close(VF_FONT font)
     /* [<][>][^][v][top][bottom][index][help] */
 732 {
 733   return VF_CloseFont((int)font->private);
 734 }
 735 
 736 Private int
 737 tex_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 738                 double mag_x, double mag_y)
 739 {
 740   VF_METRIC1  met;
 741 
 742   met = VF_GetMetric1((int)font->private, code_point, metric, mag_x, mag_y);
 743   if (met == NULL)
 744     return -1;
 745   return 0;
 746 }
 747 
 748 Private int
 749 tex_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 750                  double *w_p, double *h_p, double *xoff_p, double *yoff_p)
 751 {
 752   return VF_GetFontBoundingBox1((int)font->private, 
 753                                mag_x, mag_y, w_p, h_p, xoff_p, yoff_p);
 754 }
 755 
 756 Private VF_BITMAP
 757 tex_get_bitmap1(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 758                 double mag_x, double mag_y)
 759 {
 760   return  VF_GetBitmap1((int)font->private, code_point, mag_x, mag_y);
 761 }
 762 
 763 Private VF_OUTLINE
 764 tex_get_outline(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 765                 double mag_x, double mag_y)
 766 {
 767   return  VF_GetOutline((int)font->private, code_point, mag_x, mag_y);
 768 }
 769 
 770 Private int
 771 tex_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
     /* [<][>][^][v][top][bottom][index][help] */
 772                 double mag_x, double mag_y)
 773 {
 774   VF_METRIC2 met;
 775 
 776   met = VF_GetMetric2((int)font->private, code_point, metric, mag_x, mag_y);
 777   if (met == NULL)
 778     return -1;
 779   return 0;
 780 }
 781 
 782 Private int
 783 tex_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 784                  int *w_p, int *h_p, int *xoff_p, int *yoff_p)
 785 {
 786   return VF_GetFontBoundingBox2((int)font->private, 
 787                                 mag_x, mag_y, w_p, h_p, xoff_p, yoff_p);
 788 }
 789 
 790 Private VF_BITMAP
 791 tex_get_bitmap2(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 792                 double mag_x, double mag_y)
 793 {
 794   return  VF_GetBitmap2((int)font->private, code_point, mag_x, mag_y);
 795 }
 796 
 797 Private char*
 798 tex_get_font_prop(VF_FONT font, char *prop_name)
     /* [<][>][^][v][top][bottom][index][help] */
 799 {
 800   return  VF_GetFontProp((int)font->private, prop_name);
 801 }
 802 
 803 Private int
 804 tex_query_font_type(VF_FONT font, long code_point)
     /* [<][>][^][v][top][bottom][index][help] */
 805 {
 806   return  VF_QueryFontType((int)font->private, code_point);
 807 }
 808 
 809 
 810 
 811 
 812 
 813 Glocal int
 814 vf_tex_default_dpi(void)
     /* [<][>][^][v][top][bottom][index][help] */
 815 {
 816   return v_default_tex_dpi;
 817 }
 818 
 819 
 820 Glocal int
 821 vf_tex_fix_resolution(int dev_dpi, double mag)
     /* [<][>][^][v][top][bottom][index][help] */
 822 {
 823   int   mdpi, fixed_mdpi, d, dpi_lo, dpi_hi;
 824   SEXP  s, t;
 825 
 826   if (dev_dpi <= 0)
 827     dev_dpi = v_default_tex_dpi;
 828 
 829   fixed_mdpi = mdpi = toint(dev_dpi * mag);
 830 
 831   if (default_resolution_corr == NULL)
 832     goto found;
 833   for (s = default_resolution_corr; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 834     t = vf_sexp_car(s);
 835     if (dev_dpi != atoi(vf_sexp_get_cstring(vf_sexp_car(t))))
 836       continue;
 837     for (t = vf_sexp_cdr(t); vf_sexp_consp(t); t = vf_sexp_cdr(t)){
 838       if ((d = atoi(vf_sexp_get_cstring(vf_sexp_car(t)))) < 1)
 839         continue;
 840       if (d == mdpi)
 841         goto found;
 842       dpi_lo = (1.0 - v_default_resolution_accu) * d; 
 843       dpi_hi = (1.0 + v_default_resolution_accu) * d; 
 844       if ((dpi_lo <= mdpi) && (mdpi <= dpi_hi)){
 845         fixed_mdpi = d;
 846         goto found;
 847       }
 848     }
 849   }
 850 
 851 found:
 852   if (vf_dbg_drv_texfonts == 1)
 853     printf(">> TeX resolution correction: %d dpi x %f = %d  ==>  %d\n", 
 854            dev_dpi, mag, toint(mdpi), fixed_mdpi);
 855 
 856   return fixed_mdpi;
 857 }
 858 
 859 
 860 Glocal char*
 861 vf_tex_search_file_tfm(char *filename, SEXP dirs, SEXP exts)
     /* [<][>][^][v][top][bottom][index][help] */
 862      /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
 863 {
 864   char  *name, *e, *path; 
 865   char  target_name[1024];
 866   SEXP  s;
 867 
 868   if (vf_dbg_drv_texfonts == 1)
 869     printf(">> TeX file search tfm: %s\n", filename);
 870 
 871   /* "cmr10.400pk" ==> "cmr10"  */
 872   if ((name = vf_path_base_core(filename)) == NULL)
 873     return NULL;
 874 
 875   if (dirs == NULL)
 876     dirs = default_tfm_dirs;
 877 
 878   if (exts == NULL)
 879     exts = default_tfm_extensions;
 880 
 881   path = NULL;
 882   if (exts == NULL){
 883     path = vf_search_file(name, -1, NULL, TRUE, 
 884                           FSEARCH_FORMAT_TYPE_TFM, dirs, NULL, NULL);
 885   } else {
 886     for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){ 
 887       e = vf_sexp_get_cstring(vf_sexp_car(s));
 888       if (*e == '.')
 889         e = e+1;                /*  ".tfm"  ==> "tfm" */
 890       sprintf(target_name, "%s.%s", name, e);   /* "cmr10" ==> "cmr10.tfm" */
 891       if (vf_dbg_drv_texfonts == 1)
 892         printf(">> TeX file search tfm: Checking %s\n", target_name);
 893       path = vf_search_file(target_name, -1, NULL, TRUE, 
 894                             FSEARCH_FORMAT_TYPE_TFM, dirs, NULL, NULL);
 895       if (path != NULL)
 896         break;
 897     }
 898   }
 899   vf_free(name);
 900   return path;
 901 }
 902 
 903 Glocal char*
 904 vf_tex_search_file_glyph(char *filename, int implicit, int format,
     /* [<][>][^][v][top][bottom][index][help] */
 905                          SEXP dirs, int dpi, double mag, SEXP exts)
 906 {
 907   SEXP    s;
 908   char    *path, *corename, *e, target_name[1024];
 909   int     mdpi; 
 910 
 911   if (vf_dbg_drv_texfonts == 1){
 912     printf(">> TeX file search glyph: %s\n", filename);
 913     printf(">>   dirs: ");
 914     if (dirs != NULL)
 915       vf_sexp_pp(dirs);
 916     else 
 917       printf("null\n");
 918     printf(">>   exts: ");
 919     if (exts != NULL)
 920       vf_sexp_pp(exts);
 921     else 
 922       printf("null\n");
 923   }
 924 
 925   if (exts == NULL)
 926     return NULL;
 927 
 928   mdpi = vf_tex_fix_resolution(dpi, mag);
 929 #if 0
 930   printf("*** %d %.14f  %.14f  %d\n", dpi, mag, dpi*mag, mdpi);
 931 #endif
 932 
 933   /* "cmr10.400pk" ==> "cmr10" */
 934   if ((corename = vf_path_base_core(filename)) == NULL)
 935     return NULL;
 936   if (vf_dbg_drv_texfonts == 1)
 937     printf(">>   core: %s\n", corename);
 938 
 939   path = NULL;
 940   if (implicit == 1){
 941     for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){ 
 942       e = vf_sexp_get_cstring(vf_sexp_car(s));
 943       if (*e == '.')
 944         e = e+1;     /* ".pk" ==> "pk" */
 945       sprintf(target_name, "%s.%d%s", corename, mdpi, e);
 946       path = vf_search_file(target_name, mdpi, corename, TRUE, 
 947                             format, dirs, NULL, NULL);
 948       if (path != NULL)
 949         break;
 950     }
 951   } else {
 952     path = vf_search_file(filename, mdpi, corename, TRUE, 
 953                           format, dirs, NULL, NULL);
 954   }
 955 
 956   vf_free(corename);
 957   return path;
 958 }
 959 
 960 Glocal char*
 961 vf_tex_search_file_misc(char *filename, int implicit, int format,
     /* [<][>][^][v][top][bottom][index][help] */
 962                         SEXP dirs, SEXP exts)
 963 {
 964   SEXP    s;
 965   char    *path, *corename, *e, target_name[1024];
 966 
 967   if (vf_dbg_drv_texfonts == 1)
 968     printf(">>  TeX file search file: %s\n", filename);
 969 
 970   path = NULL;
 971   corename = NULL;
 972   e = NULL;
 973   if (implicit == 1){
 974     corename = vf_path_base_core(filename);  /* "cmr10.400pk" ==> "cmr10"  */
 975     for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){ 
 976       e = vf_sexp_get_cstring(vf_sexp_car(s));
 977       if (*e == '.')
 978         e = e+1;     /* ".vf" ==> "vf" */
 979       sprintf(target_name, "%s.%s", corename, e);
 980       path = vf_search_file(target_name, 0, NULL, 
 981                             TRUE, format, dirs, NULL, NULL);
 982       if (path != NULL)
 983         break;
 984     }
 985   } else {
 986     path = vf_search_file(filename, 0, NULL, TRUE, format, dirs, NULL, NULL);
 987   }
 988 
 989   vf_free(corename);
 990   return path;
 991 }
 992 
 993 
 994 
 995 Glocal int
 996 vf_tex_parse_open_style(char *s, int def_value)
     /* [<][>][^][v][top][bottom][index][help] */
 997 {
 998   int  val;
 999 
1000   if (s == NULL)
1001     return def_value;
1002 
1003   if (vf_strcmp_ci(s, TEX_OPEN_STYLE_REQUIRE_STR) == 0){
1004     val = TEX_OPEN_STYLE_REQUIRE;
1005   } else if (vf_strcmp_ci(s, TEX_OPEN_STYLE_TRY_STR) == 0){
1006     val = TEX_OPEN_STYLE_TRY;
1007   } else if (vf_strcmp_ci(s, TEX_OPEN_STYLE_NONE_STR) == 0){
1008     val = TEX_OPEN_STYLE_NONE;
1009   } else {
1010     fprintf(stderr, 
1011             "VFlib Warning: Unknown open style: %s.\n", s);
1012     val = def_value;
1013   }
1014 
1015   return val;
1016 }
1017 
1018 
1019 Glocal int
1020 vf_tex_parse_glyph_style(char *s, int def_value)
     /* [<][>][^][v][top][bottom][index][help] */
1021 {
1022   int  val;
1023 
1024   if (s == NULL)
1025     return def_value;
1026 
1027   if (vf_strcmp_ci(s, TEX_GLYPH_STYLE_EMPTY_STR) == 0){
1028     val = TEX_GLYPH_STYLE_EMPTY;
1029   } else if (vf_strcmp_ci(s, TEX_GLYPH_STYLE_FILL_STR) == 0){
1030     val = TEX_GLYPH_STYLE_FILL;
1031   } else {
1032     fprintf(stderr, "VFlib Warning: Unknown glyph stype: %s\n", s);
1033     val = def_value;
1034   }
1035 
1036   return val;
1037 }
1038 
1039 
1040 
1041 
1042 
1043 /*
1044  * Reading a Number from file
1045  */
1046 Glocal unsigned long
1047 vf_tex_read_uintn(FILE* fp, int size)
     /* [<][>][^][v][top][bottom][index][help] */
1048 {
1049   unsigned long  v;
1050 
1051   v = 0L;
1052   while (size >= 1){
1053     v = v*256L + (unsigned long)getc(fp);
1054     --size;
1055   }
1056   return v;
1057 }
1058 
1059 Glocal long
1060 vf_tex_read_intn(FILE* fp, int size)
     /* [<][>][^][v][top][bottom][index][help] */
1061 {
1062   long           v;
1063 
1064   v = (long)getc(fp) & 0xffL;
1065   if (v & 0x80L)
1066     v = v - 256L;
1067   --size;
1068   while (size >= 1){
1069     v = v*256L + (unsigned long)getc(fp);
1070     --size;
1071   }
1072 
1073   return v;
1074 }
1075 
1076 Glocal void
1077 vf_tex_skip_n(FILE* fp, int size)
     /* [<][>][^][v][top][bottom][index][help] */
1078 {
1079   while (size > 0){
1080     (void)getc(fp);
1081     --size;
1082   }
1083 }
1084 
1085 Glocal unsigned long
1086 vf_tex_get_uintn(unsigned char *p, int size)
     /* [<][>][^][v][top][bottom][index][help] */
1087 {
1088   unsigned long  v;
1089 
1090   v = 0L;
1091   while (size >= 1){
1092     v = v*256L + (unsigned long) *(p++);
1093     --size;
1094   }
1095 
1096   return v;
1097 }
1098 
1099 Glocal long
1100 vf_tex_get_intn(unsigned char *p, int size)
     /* [<][>][^][v][top][bottom][index][help] */
1101 {
1102   long           v;
1103 
1104   v = (long)*(p++) & 0xffL;
1105   if (v & 0x80L)
1106     v = v - 256L;
1107   --size;
1108   while (size >= 1){
1109     v = v*256L + (unsigned long) *(p++);
1110     --size;
1111   }
1112 
1113   return v;
1114 }
1115 
1116 
1117 
1118 /*EOF*/

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