src/drv_tfm.c

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

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_TFM
  2. tfm_create
  3. tfm_close
  4. tfm_get_metric1
  5. tfm_get_fontbbx1
  6. tfm_get_bitmap1
  7. tfm_get_outline
  8. tfm_get_metric2
  9. tfm_get_fontbbx2
  10. tfm_get_bitmap2
  11. tfm_get_font_prop

   1 /*
   2  * drv_tfm.c - A font driver for TFM fonts.
   3  *
   4  * 30 Sep 1996  First version.
   5  * 17 Jan 1997  for VFlib 3.1
   6  * 24 Feb 1997  Changed metric computation.
   7  * 26 Feb 1997  Added 'query_font_type'.
   8  *  4 Aug 1997  VFlib 3.3  Changed API.
   9  *  1 Feb 1998  for VFlib 3.4
  10  * 21 Apr 1998  Debugged get_font_prop().
  11  */
  12 /*
  13  * Copyright (C) 1996-1998  by Hirotsugu Kakugawa. 
  14  * All rights reserved.
  15  *
  16  * This file is part of the VFlib Library.  This library is free
  17  * software; you can redistribute it and/or modify it under the terms of
  18  * the GNU Library General Public License as published by the Free
  19  * Software Foundation; either version 2 of the License, or (at your
  20  * option) any later version.  This library is distributed in the hope
  21  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  22  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  23  * PURPOSE.  See the GNU Library General Public License for more details.
  24  * You should have received a copy of the GNU Library General Public
  25  * License along with this library; if not, write to the Free Software
  26  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  27  */
  28 
  29 #include  "config.h"
  30 #include  <stdio.h>
  31 #include  <stdlib.h>
  32 #ifdef HAVE_UNISTD_H
  33 #  include <unistd.h>
  34 #endif
  35 #include  <ctype.h>
  36 #include  "VFlib-3_6.h"
  37 #include  "VFsys.h"
  38 #include  "vflibcap.h"
  39 #include  "sexp.h"
  40 #include  "cache.h"
  41 #include  "bitmap.h"
  42 #include  "str.h"
  43 #include  "path.h"
  44 #include  "fsearch.h"
  45 #include  "texfonts.h"
  46 #include  "tfm.h"
  47 
  48 
  49 
  50 struct s_font_tfm {
  51   TFM      tfm;
  52   char     *font_name;
  53   char     *font_file;
  54   double   point_size;
  55   double   pixel_size;
  56   int      glyph_style;
  57   double   mag;
  58   double   aspect;
  59   double   dpi_x, dpi_y;
  60   SEXP     props;
  61   double   extra_mag;
  62 };
  63 typedef struct s_font_tfm  *FONT_TFM;
  64 
  65 
  66 Private SEXP_LIST    default_fontdirs;
  67 Private SEXP_LIST    default_extensions;
  68 Private SEXP_STRING  default_glyph_style;
  69 Private int          v_default_glyph_style;
  70 Private SEXP_STRING  default_point_size;
  71 Private double       v_default_point_size;
  72 Private SEXP_STRING  default_pixel_size;
  73 Private double       v_default_pixel_size;
  74 Private SEXP_STRING  default_dpi;
  75 Private double       v_default_dpi_x, v_default_dpi_y;
  76 Private SEXP_STRING  default_aspect;
  77 Private double       v_default_aspect;
  78 Private SEXP_ALIST   default_properties;
  79 Private SEXP_ALIST   default_variables;
  80 Private SEXP_STRING  default_debug_mode;
  81 
  82 
  83 Private int         tfm_create(VF_FONT,char*,char*,int,SEXP);
  84 Private int         tfm_close(VF_FONT);
  85 Private int         tfm_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
  86 Private int         tfm_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
  87 Private int         tfm_get_fontbbx1(VF_FONT,double,double,
  88                                      double*,double*,double*,double*);
  89 Private int         tfm_get_fontbbx2(VF_FONT,double,double, 
  90                                      int*,int*,int*,int*);
  91 Private VF_BITMAP   tfm_get_bitmap1(VF_FONT,long,double,double);
  92 Private VF_BITMAP   tfm_get_bitmap2(VF_FONT,long,double,double);
  93 Private VF_OUTLINE  tfm_get_outline(VF_FONT,long,double,double);
  94 Private char*       tfm_get_font_prop(VF_FONT,char*);
  95 
  96 
  97 
  98 Public int
  99 VF_Init_Driver_TFM(void)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101   struct s_capability_table  ct[20];
 102   int  z;
 103 
 104   z = 0;
 105   /* VF_CAPE_FONT_DIRECTORIES */
 106   ct[z].cap = VF_CAPE_FONT_DIRECTORIES;  ct[z].type = CAPABILITY_LIST;
 107   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_fontdirs;
 108   /* VF_CAPE_EXTENSIONS */
 109   ct[z].cap = VF_CAPE_EXTENSIONS;        ct[z].type = CAPABILITY_LIST;
 110   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_extensions;
 111   /* VF_CAPE_TEX_GLYPH_STYLE */
 112   ct[z].cap = VF_CAPE_TEX_GLYPH_STYLE;   ct[z].type = CAPABILITY_STRING;
 113   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_glyph_style;
 114   /* VF_CAPE_POINT_SIZE */
 115   ct[z].cap = VF_CAPE_POINT_SIZE;        ct[z].type = CAPABILITY_STRING;
 116   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_point_size;
 117   /* VF_CAPE_PIXEL_SIZE */
 118   ct[z].cap = VF_CAPE_PIXEL_SIZE;        ct[z].type = CAPABILITY_STRING;
 119   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_pixel_size;
 120   /* VF_CAPE_DPI */
 121   ct[z].cap = VF_CAPE_DPI;               ct[z].type = CAPABILITY_STRING;
 122   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_dpi;
 123   /* VF_CAPE_ASPECT_RATIO */
 124   ct[z].cap = VF_CAPE_ASPECT_RATIO;      ct[z].type = CAPABILITY_STRING;
 125   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_aspect;
 126   /* VF_CAPE_PROPERTIES */
 127   ct[z].cap = VF_CAPE_PROPERTIES;        ct[z].type = CAPABILITY_ALIST;
 128   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_properties;
 129   /* VF_CAPE_VARIABLE_VALUES */
 130   ct[z].cap = VF_CAPE_VARIABLE_VALUES;   ct[z].type = CAPABILITY_ALIST;
 131   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_variables;
 132   /* VF_CAPE_DEBUG */
 133   ct[z].cap = VF_CAPE_DEBUG;             ct[z].type = CAPABILITY_STRING;
 134   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &default_debug_mode;
 135   /* end */
 136   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 137 
 138 
 139   if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_TFM, ct, 
 140                                    vf_tex_default_variables, NULL) 
 141       == VFLIBCAP_PARSED_ERROR)
 142     return -1;
 143 
 144   if (default_extensions == NULL)
 145     default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_TFM);
 146 
 147   v_default_glyph_style = TEX_GLYPH_STYLE_EMPTY;
 148   if (default_glyph_style != NULL)
 149     v_default_glyph_style
 150       = vf_tex_parse_glyph_style(vf_sexp_get_cstring(default_glyph_style),
 151                                  TEX_GLYPH_STYLE_EMPTY);
 152 
 153   v_default_point_size = -1;
 154   if (default_point_size != NULL)
 155     v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
 156 
 157   v_default_pixel_size = -1;
 158   if (default_pixel_size != NULL)
 159     v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
 160 
 161   v_default_dpi_x  = -1;
 162   v_default_dpi_y  = -1;
 163   if (default_dpi != NULL)
 164     v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
 165 
 166   v_default_aspect = 1.0;
 167   if (default_aspect != NULL)
 168     v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
 169 
 170   vf_tex_init();
 171   vf_tfm_init();
 172 
 173   VF_InstallFontDriver(FONTCLASS_NAME_TFM, (DRIVER_FUNC_TYPE)tfm_create);
 174 
 175   return 0;
 176 }
 177 
 178 Private int
 179 tfm_create(VF_FONT font, char *font_class, 
     /* [<][>][^][v][top][bottom][index][help] */
 180            char *font_name, int implicit, SEXP entry)
 181 {
 182   FONT_TFM  font_tfm;
 183   char      *font_file, *tfm_path, *p;
 184   int       dev_dpi;
 185   SEXP      cap_ffile, cap_glyph_style, cap_point, cap_pixel;
 186   SEXP      cap_dpi, cap_mag, cap_aspect, cap_props;
 187   struct s_capability_table  ct[20];
 188   int  z;
 189 
 190   z = 0;
 191   /* VF_CAPE_FONT_CLASS */
 192   ct[z].cap = VF_CAPE_FONT_CLASS;        ct[z].type = CAPABILITY_STRING;
 193   ct[z].ess = CAPABILITY_ESSENTIAL;      ct[z++].val = NULL;
 194   /* VF_CAPE_FONT_FILE */
 195   ct[z].cap = VF_CAPE_FONT_FILE;         ct[z].type = CAPABILITY_STRING;
 196   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_ffile;
 197   /* VF_CAPE_TEX_GLYPH_STYLE */
 198   ct[z].cap = VF_CAPE_TEX_GLYPH_STYLE;   ct[z].type = CAPABILITY_STRING;
 199   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_glyph_style;
 200   /* VF_CAPE_POINT_SIZE */
 201   ct[z].cap = VF_CAPE_POINT_SIZE;        ct[z].type = CAPABILITY_STRING;
 202   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_point;
 203   /* VF_CAPE_PIXEL_SIZE */
 204   ct[z].cap = VF_CAPE_PIXEL_SIZE;        ct[z].type = CAPABILITY_STRING;
 205   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_pixel;
 206   /* VF_CAPE_DPI */
 207   ct[z].cap = VF_CAPE_DPI;               ct[z].type = CAPABILITY_STRING;
 208   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_dpi;
 209   /* VF_CAPE_MAG */
 210   ct[z].cap = VF_CAPE_MAG;               ct[z].type = CAPABILITY_STRING;
 211   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_mag;
 212   /* VF_CAPE_ASPECT_RATIO */
 213   ct[z].cap = VF_CAPE_ASPECT_RATIO;      ct[z].type = CAPABILITY_STRING;
 214   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_aspect;
 215   /* VF_CAPE_PROPERTIES */
 216   ct[z].cap = VF_CAPE_PROPERTIES;        ct[z].type = CAPABILITY_ALIST;
 217   ct[z].ess = CAPABILITY_OPTIONAL;       ct[z++].val = &cap_props;
 218   /* end */
 219   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 220 
 221 
 222   if (implicit == 1){   /* implicit font */
 223     font_file = font_name;
 224   } else {              /* explicit font */
 225     if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
 226                                   default_variables, vf_tex_default_variables) 
 227         == VFLIBCAP_PARSED_ERROR)
 228       return -1;
 229     if (cap_ffile == NULL){
 230       /* Use font name as font file name if font file name is not given. */
 231       font_file = font_name;
 232     } else {
 233       font_file = vf_sexp_get_cstring(cap_ffile);
 234     }
 235   }
 236 
 237   font->font_type       = VF_FONT_TYPE_BITMAP;
 238   font->get_metric1     = tfm_get_metric1;
 239   font->get_metric2     = tfm_get_metric2;
 240   font->get_fontbbx1    = tfm_get_fontbbx1;
 241   font->get_fontbbx2    = tfm_get_fontbbx2;
 242   font->get_bitmap1     = tfm_get_bitmap1;
 243   font->get_bitmap2     = tfm_get_bitmap2;
 244   font->get_outline     = tfm_get_outline;
 245   font->get_font_prop   = tfm_get_font_prop;
 246   font->query_font_type = NULL;
 247   font->close           = tfm_close;
 248 
 249   tfm_path = NULL;
 250   font_tfm = NULL;
 251   ALLOC_IF_ERR(font_tfm, struct s_font_tfm)
 252     goto NoMemoryError;
 253   font->private = font_tfm;
 254 
 255   font_tfm->tfm        = NULL;
 256   font_tfm->font_name  = NULL; 
 257   font_tfm->font_file  = NULL; 
 258   font_tfm->point_size = v_default_point_size;
 259   font_tfm->pixel_size = v_default_pixel_size;
 260   font_tfm->glyph_style= v_default_glyph_style;
 261   font_tfm->dpi_x      = v_default_dpi_x;
 262   font_tfm->dpi_y      = v_default_dpi_y;
 263   font_tfm->mag        = 1.0;
 264   font_tfm->aspect     = v_default_aspect;
 265   font_tfm->props      = NULL;
 266 
 267   if (implicit == 0){
 268     if (cap_point != NULL)
 269       font_tfm->point_size = atof(vf_sexp_get_cstring(cap_point));
 270     if (cap_pixel != NULL)
 271       font_tfm->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
 272     if (cap_glyph_style != NULL){
 273       if (strcmp(vf_sexp_get_cstring(cap_glyph_style),
 274                  TEX_GLYPH_STYLE_EMPTY_STR) == 0)
 275         font_tfm->glyph_style = TEX_GLYPH_STYLE_EMPTY;
 276       else if (strcmp(vf_sexp_get_cstring(cap_glyph_style),
 277                       TEX_GLYPH_STYLE_FILL_STR) == 0)
 278         font_tfm->glyph_style = TEX_GLYPH_STYLE_FILL;
 279     }
 280     if (cap_dpi != NULL)
 281       font_tfm->dpi_x = font_tfm->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
 282     if (cap_mag != NULL)
 283       font_tfm->mag = atof(vf_sexp_get_cstring(cap_mag));
 284     if (cap_aspect != NULL)
 285       font_tfm->aspect = atof(vf_sexp_get_cstring(cap_aspect));
 286     if (cap_props != NULL)
 287       font_tfm->props = cap_props;
 288   }
 289 
 290   if ((font_tfm->font_file = vf_strdup(font_file)) == NULL)
 291     goto NoMemoryError;
 292   if ((font_tfm->font_name = vf_strdup(font_name)) == NULL)
 293     goto NoMemoryError;
 294 
 295 
 296   /* Parse font name.  Formats of file names that this routine supports:
 297    *    "cmr10.300XX" - A "cmr10" font for 300 dpi.
 298    *    "cmr10.XX"    - A "cmr10" font. Dpi value is default value.
 299    *    "cmr10"       -   ditto.
 300    * ("XX" can be any string such as "pk", "gf", and "tfm".)
 301    */
 302   p = vf_index(font_tfm->font_file, '.');
 303   if ((p != NULL) && (isdigit((int)*(p+1)))){   /* "cmr10.300tfm" */
 304     dev_dpi = atoi(p+1);
 305     if ((font_tfm->dpi_x < 0) || (font_tfm->dpi_y < 0)){
 306       font_tfm->dpi_x = (double)dev_dpi;
 307       font_tfm->dpi_y = (double)dev_dpi;
 308     }
 309   } else {                                 /* "cmr10" or "cmr10.tfm" */
 310     ;
 311   }
 312  
 313   tfm_path = vf_tex_search_file_tfm(font_tfm->font_file, 
 314                                     default_fontdirs, default_extensions);
 315 #if 0
 316   printf("* TFM: %s ==> %s\n", font_name, tfm_path);
 317 #endif
 318   if (tfm_path == NULL)
 319     goto Error;
 320 
 321   font_tfm->tfm = vf_tfm_open(tfm_path);
 322   vf_free(tfm_path);
 323   if (font_tfm->tfm == NULL)
 324     goto Error;
 325 
 326   if (implicit == 0){
 327     vf_sexp_free2(&cap_ffile, &cap_glyph_style);
 328     vf_sexp_free2(&cap_point, &cap_pixel);
 329     vf_sexp_free3(&cap_dpi, &cap_mag, &cap_aspect);
 330   }
 331 
 332   return 0;
 333 
 334 
 335 NoMemoryError:
 336   vf_error = VF_ERR_NO_MEMORY;
 337 Error:
 338   if (implicit == 0){
 339     vf_sexp_free2(&cap_ffile, &cap_glyph_style);
 340     vf_sexp_free2(&cap_point, &cap_pixel);
 341     vf_sexp_free3(&cap_dpi, &cap_mag, &cap_aspect);
 342   }
 343   tfm_close(font);
 344   return -1;
 345 }
 346 
 347 
 348 Private int
 349 tfm_close(VF_FONT font)
     /* [<][>][^][v][top][bottom][index][help] */
 350 {
 351   FONT_TFM  font_tfm;
 352 
 353   font_tfm = (FONT_TFM)font->private;
 354   if (font_tfm != NULL){
 355     vf_tfm_free(font_tfm->tfm);
 356     vf_free(font_tfm->font_name);
 357     vf_free(font_tfm->font_file);
 358     vf_sexp_free1(&font_tfm->props);
 359     vf_free(font_tfm);
 360   }
 361 
 362   return 0; 
 363 }
 364 
 365 Private int
 366 tfm_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
     /* [<][>][^][v][top][bottom][index][help] */
 367                 double mag_x, double mag_y)
 368 {
 369   FONT_TFM  font_tfm;
 370   TFM       tfm;
 371   double    mx, my, ps, f;
 372 
 373   if (   (metric == NULL)
 374       || ((font_tfm = (FONT_TFM)font->private) == NULL)
 375       || ((tfm = font_tfm->tfm) == NULL) ){
 376     fprintf(stderr, "VFlib internal error: tfm_get_metric1()\n");
 377     abort();
 378   }
 379 
 380   if (vf_tfm_metric(tfm, code_point, metric) == NULL)
 381     return -1;
 382 
 383   if ((ps = font->point_size) < 0)
 384     if ((ps = font_tfm->point_size) < 0)
 385       ps = -1;
 386 
 387   if ((ps < 0) || (tfm->design_size < 1.0e-3)){
 388     mx = mag_x * font->mag_x * font_tfm->mag;
 389     my = mag_y * font->mag_y * font_tfm->mag;
 390   } else {
 391     f = ps / tfm->design_size;
 392     mx = mag_x * font->mag_x * font_tfm->mag * f;
 393     my = mag_y * font->mag_y * font_tfm->mag * f;
 394   }
 395 
 396   metric->bbx_width  *= mx;
 397   metric->bbx_height *= my;
 398   metric->off_x      *= mx;
 399   metric->off_y      *= my;
 400   metric->mv_x       *= mx;
 401   metric->mv_y       *= my;
 402 
 403   return 0;
 404 }
 405 
 406 Private int
 407 tfm_get_fontbbx1(VF_FONT font, double mag_x, double mag_y, 
     /* [<][>][^][v][top][bottom][index][help] */
 408                  double *w_p, double *h_p, double *xoff_p, double *yoff_p)
 409 {
 410   FONT_TFM  font_tfm;
 411   TFM       tfm;
 412   double    mx, my, ps, f;
 413 
 414   if (((font_tfm = (FONT_TFM)font->private) == NULL)
 415       || ((tfm = font_tfm->tfm) == NULL) ){
 416     fprintf(stderr, "VFlib internal error: tfm_get_fontbbx1()\n");
 417     abort();
 418   }
 419 
 420   if ((ps = font->point_size) < 0)
 421     if ((ps = font_tfm->point_size) < 0)
 422       ps = -1;
 423 
 424   if ((ps < 0) || (tfm->design_size < 1.0e-3)){
 425     mx = mag_x * font->mag_x * font_tfm->mag;
 426     my = mag_y * font->mag_y * font_tfm->mag;
 427   } else {
 428     f = ps / tfm->design_size;
 429     mx = mag_x * font->mag_x * font_tfm->mag * f;
 430     my = mag_y * font->mag_y * font_tfm->mag * f;
 431   }
 432 
 433   *w_p    = tfm->font_bbx_w * mx;
 434   *h_p    = tfm->font_bbx_h * my;
 435   *xoff_p = tfm->font_bbx_xoff * mx;
 436   *yoff_p = tfm->font_bbx_yoff * my;
 437 
 438   return 0;
 439 }
 440 
 441 Private VF_BITMAP
 442 tfm_get_bitmap1(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 443                 double mag_x, double mag_y)
 444 {
 445   FONT_TFM   font_tfm;
 446   VF_BITMAP  bm;
 447   double     dpi_x, dpi_y;
 448   struct vf_s_metric1  met; 
 449 
 450   if ((font_tfm = (FONT_TFM)font->private) == NULL){
 451     fprintf(stderr, "VFlib internal error: tfm_get_bitmap1()\n");
 452     abort();
 453   }
 454 
 455   if (tfm_get_metric1(font, code_point, &met, mag_x, mag_y) < 0)
 456     return NULL;
 457 
 458   if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
 459     if (((dpi_x = font_tfm->dpi_x) < 0) || ((dpi_y = font_tfm->dpi_y) < 0)){
 460       dpi_x = vf_tex_default_dpi();
 461       dpi_y = vf_tex_default_dpi();
 462     }
 463   }
 464 
 465   bm = vf_alloc_bitmap_with_metric1(&met, dpi_x, dpi_y);
 466 
 467   switch (font_tfm->glyph_style){
 468   default:
 469   case TEX_GLYPH_STYLE_EMPTY:
 470     break;
 471   case TEX_GLYPH_STYLE_FILL:
 472     VF_FillBitmap(bm);
 473     break;
 474   }
 475 
 476   return bm;
 477 }
 478 
 479 Private VF_OUTLINE
 480 tfm_get_outline(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 481                 double mag_x, double mag_y)
 482 {
 483   FONT_TFM            font_tfm;
 484   TFM                 tfm;
 485   VF_OUTLINE          ol;
 486   double              dpi_x, dpi_y, bbx, ps;
 487   int                 size, x1, y1, x2, y2, index;
 488   struct vf_s_metric1 met;
 489 
 490   if ( ((font_tfm = (FONT_TFM)font->private) == NULL)
 491       || ((tfm = font_tfm->tfm) == NULL) ){
 492     fprintf(stderr, "VFlib internal error: tfm_get_outline()\n");
 493     abort();
 494   }
 495 
 496   if (tfm_get_metric1(font, code_point, &met, mag_x, mag_y) < 0)
 497     return NULL;
 498 
 499   if ((ps = font->point_size) < 0)
 500     if ((ps = font_tfm->point_size) < 0)
 501       ps = tfm->design_size;
 502 
 503   if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
 504     if (((dpi_x = font_tfm->dpi_x) < 0) || ((dpi_y = font_tfm->dpi_y) < 0)){
 505       dpi_x = vf_tex_default_dpi();
 506       dpi_y = vf_tex_default_dpi();
 507     }
 508   }
 509 
 510   if ((bbx = tfm->font_bbx_w) < tfm->font_bbx_h)
 511     bbx = tfm->font_bbx_h;
 512 
 513   size = VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + 6;
 514   if ((ol = (VF_OUTLINE)calloc(size, sizeof(VF_OUTLINE_ELEM))) == NULL){
 515     vf_error = VF_ERR_NO_MEMORY;
 516     return NULL;
 517   }
 518 
 519   ol[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
 520   ol[VF_OL_HEADER_INDEX_DATA_SIZE]   = size;
 521   ol[VF_OL_HEADER_INDEX_DPI_X]       = VF_OL_HEADER_ENCODE(dpi_x);
 522   ol[VF_OL_HEADER_INDEX_DPI_Y]       = VF_OL_HEADER_ENCODE(dpi_y);
 523   ol[VF_OL_HEADER_INDEX_POINT_SIZE]  = VF_OL_HEADER_ENCODE(ps);
 524   ol[VF_OL_HEADER_INDEX_EM]    = VF_OL_COORD_RANGE;
 525   ol[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * met.bbx_width/bbx;
 526   ol[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * met.bbx_height/bbx;
 527   ol[VF_OL_HEADER_INDEX_REF_X] = VF_OL_COORD_RANGE * (0.0 - met.off_x/bbx);
 528   ol[VF_OL_HEADER_INDEX_REF_Y] = VF_OL_COORD_RANGE * met.off_y/bbx;
 529   ol[VF_OL_HEADER_INDEX_MV_X]  = VF_OL_COORD_RANGE * met.mv_x/bbx;
 530   ol[VF_OL_HEADER_INDEX_MV_Y]  = VF_OL_COORD_RANGE * met.mv_y/bbx;
 531 
 532   x1 = VF_OL_COORD_OFFSET + 0;
 533   x2 = VF_OL_COORD_OFFSET + VF_OL_COORD_RANGE * met.bbx_width / bbx;
 534   y1 = VF_OL_COORD_OFFSET + 0;
 535   y2 = VF_OL_COORD_OFFSET + VF_OL_COORD_RANGE * met.bbx_height / bbx;
 536 
 537   index = VF_OL_OUTLINE_HEADER_SIZE_TYPE0;
 538   ol[index++] =   VF_OL_INSTR_TOKEN | VF_OL_INSTR_CCWCURV
 539                 | VF_OL_INSTR_LINE  | VF_OL_INSTR_CHAR;
 540   ol[index++] = VF_OL_MAKE_XY(x1, y1);
 541   ol[index++] = VF_OL_MAKE_XY(x1, y2);
 542   ol[index++] = VF_OL_MAKE_XY(x2, y2);
 543   ol[index++] = VF_OL_MAKE_XY(x2, y1);
 544   ol[index++] = 0L;
 545 
 546   return ol;
 547 }
 548 
 549 Private int
 550 tfm_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 551                 double mag_x, double mag_y)
 552 {
 553   FONT_TFM             font_tfm;
 554   TFM                  tfm;
 555   struct vf_s_metric1  met1;
 556   int                  ps;
 557   double               dpi_x, dpi_y, mx, my;
 558 
 559   if (   (metric == NULL)
 560       || ((font_tfm = (FONT_TFM)font->private) == NULL)
 561       || ((tfm = font_tfm->tfm) == NULL) ){
 562     fprintf(stderr, "VFlib internal error in tfm_get_metric2()\n");
 563     abort();
 564   }
 565 
 566   if (vf_tfm_metric(tfm, code_point, &met1) == NULL)
 567     return -1;
 568 
 569   if (((dpi_x = font_tfm->dpi_x) <= 0) || ((dpi_y = font_tfm->dpi_y) <= 0)){
 570     dpi_x = vf_tex_default_dpi();
 571     dpi_y = vf_tex_default_dpi();
 572   }
 573 
 574   if ((ps = font->pixel_size) < 0)
 575     if ((ps = font_tfm->pixel_size) < 0)
 576       ps = -1;
 577 
 578   if ((ps < 0) || (tfm->design_size < 1.0e-3)){
 579     mx = mag_x * font->mag_x * font_tfm->mag * dpi_x / 72.27;
 580     my = mag_y * font->mag_y * font_tfm->mag * dpi_y / 72.27;
 581   } else {
 582     mx = mag_x * font->mag_x * font_tfm->mag * (ps/tfm->design_size);
 583     my = mag_y * font->mag_y * font_tfm->mag * (ps/tfm->design_size);
 584   }
 585 
 586   metric->bbx_width  = toint(met1.bbx_width  * mx);
 587   metric->bbx_height = toint(met1.bbx_height * my);
 588   metric->off_x      = toint(met1.off_x * mx);
 589   metric->off_y      = toint(met1.off_y * my);
 590   metric->mv_x       = toint(met1.mv_x  * mx);
 591   metric->mv_y       = toint(met1.mv_y  * my);
 592 
 593   return 0;
 594 }
 595 
 596 Private int
 597 tfm_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 598                  int *w_p, int *h_p, int *xoff_p, int *yoff_p)
 599 {
 600   FONT_TFM             font_tfm;
 601   TFM                  tfm;
 602   int                  ps;
 603   double               dpi_x, dpi_y, mx, my;
 604 
 605   if (((font_tfm = (FONT_TFM)font->private) == NULL)
 606       || ((tfm = font_tfm->tfm) == NULL) ){
 607     fprintf(stderr, "VFlib internal error in tfm_get_fontbbx2()\n");
 608     abort();
 609   }
 610 
 611   if (((dpi_x = font_tfm->dpi_x) <= 0) || ((dpi_y = font_tfm->dpi_y) <= 0)){
 612     dpi_x = vf_tex_default_dpi();
 613     dpi_y = vf_tex_default_dpi();
 614   }
 615 
 616   if ((ps = font->pixel_size) < 0)
 617     if ((ps = font_tfm->pixel_size) < 0)
 618       ps = -1;
 619 
 620   if ((ps < 0) || (tfm->design_size < 1.0e-3)){
 621     mx = mag_x * font->mag_x * font_tfm->mag * dpi_x / 72.27;
 622     my = mag_y * font->mag_y * font_tfm->mag * dpi_y / 72.27;
 623   } else {
 624     mx = mag_x * font->mag_x * font_tfm->mag * (ps/tfm->design_size);
 625     my = mag_y * font->mag_y * font_tfm->mag * (ps/tfm->design_size);
 626   }
 627 
 628   *w_p    = toint(tfm->font_bbx_w  * mx);
 629   *h_p    = toint(tfm->font_bbx_h  * my);
 630   *xoff_p = toint(tfm->font_bbx_xoff  * mx);
 631   *yoff_p = toint(tfm->font_bbx_yoff  * my);
 632 
 633   return 0;
 634 }
 635 
 636 Private VF_BITMAP
 637 tfm_get_bitmap2(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 638                 double mag_x, double mag_y)
 639 {
 640   FONT_TFM   font_tfm;
 641   VF_BITMAP  bm;
 642   struct vf_s_metric2  met;
 643 
 644   if ((font_tfm = (FONT_TFM)font->private) == NULL){
 645     fprintf(stderr, "VFlib internal error in tfm_get_bitmap2()\n");
 646     abort();
 647   }
 648 
 649   if (tfm_get_metric2(font, code_point, &met, mag_x, mag_y) < 0)
 650     return NULL;
 651   
 652   bm = vf_alloc_bitmap_with_metric2(&met);
 653 
 654   switch (font_tfm->glyph_style){
 655   default:
 656   case TEX_GLYPH_STYLE_EMPTY:
 657     break;
 658   case TEX_GLYPH_STYLE_FILL:
 659     VF_FillBitmap(bm);
 660     break;
 661   }
 662 
 663   return bm;
 664 }
 665 
 666 
 667 Private char*
 668 tfm_get_font_prop(VF_FONT font, char *prop_name)
     /* [<][>][^][v][top][bottom][index][help] */
 669 {
 670   FONT_TFM  font_tfm;
 671   TFM       tfm;
 672   SEXP      v;
 673   double    ps, dpi_x, dpi_y;
 674   char      str[256];
 675 
 676   if (   ((font_tfm = (FONT_TFM)font->private) == NULL)
 677       || ((tfm = font_tfm->tfm) == NULL) ){
 678     fprintf(stderr, "VFlib internal error in tfm_get_font_prop()\n");
 679     abort();
 680   }
 681 
 682   if ((v = vf_sexp_assoc(prop_name, font_tfm->props)) != NULL){
 683     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 684   } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
 685     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 686   } else {
 687 
 688     if (((dpi_x = font->dpi_x)<=0) || ((dpi_y = font->dpi_y)<=0)){
 689       if (((dpi_x = font_tfm->dpi_x)<=0) || ((dpi_y = font_tfm->dpi_y)<=0)){
 690         dpi_x = vf_tex_default_dpi();
 691         dpi_y = vf_tex_default_dpi();
 692       }
 693     }
 694 #if 0
 695     printf("** %.3f %.3f %.3f  %d %.3f %.3f %.3f\n",
 696            dpi_x, dpi_y, tfm->design_size, 
 697            font->pixel_size, font_tfm->pixel_size,
 698            font->point_size, font_tfm->point_size);
 699 #endif
 700 
 701     if (font->mode == 1){
 702       if ((ps = font->point_size) < 0)
 703         if ((ps = font_tfm->point_size) < 0)
 704           ps = tfm->design_size;
 705       ps = ps * font->mag_y * font_tfm->mag;
 706       if (strcmp(prop_name, "POINT_SIZE") == 0){
 707         sprintf(str, "%d", toint(ps * 10.0));
 708         return vf_strdup(str);
 709       } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 710         sprintf(str, "%d", toint(ps * dpi_y / 72.27));
 711         return vf_strdup(str);
 712       } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 713         sprintf(str, "%d", toint(dpi_x));
 714         return vf_strdup(str);
 715       } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 716         sprintf(str, "%d", toint(dpi_y));
 717         return vf_strdup(str);
 718       }
 719 
 720     } else if (font->mode == 2){
 721       if (strcmp(prop_name, "POINT_SIZE") == 0){
 722         if ((ps = font->pixel_size) < 0){
 723           if ((ps = font_tfm->pixel_size) < 0){
 724             sprintf(str, "%d", toint(tfm->design_size * 10.0 
 725                                      * font->mag_y * font_tfm->mag));
 726             return vf_strdup(str);
 727           }
 728         }
 729         ps = ps * font->mag_y * font_tfm->mag;
 730         sprintf(str, "%d", toint(ps * 10.0 * 72.27 / dpi_y));
 731         return vf_strdup(str);
 732       } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 733         if ((ps = font->pixel_size) < 0)
 734           if ((ps = font_tfm->pixel_size) < 0)
 735             ps = tfm->design_size * dpi_y / 72.27;
 736         ps = ps * font->mag_y * font_tfm->mag;
 737         sprintf(str, "%d", toint(ps));
 738         return vf_strdup(str);
 739       } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 740         sprintf(str, "%d", toint(dpi_x));
 741         return vf_strdup(str);
 742       } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 743         sprintf(str, "%d", toint(dpi_y));
 744         return vf_strdup(str);
 745       }
 746     }
 747   }
 748 
 749   return NULL;
 750 }
 751 
 752 
 753 /*EOF*/

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