src/drv_zeit.c

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

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_ZEIT
  2. zeit_create
  3. zeit_close
  4. mag_mode_1
  5. zeit_get_metric1
  6. zeit_get_fontbbx1
  7. zeit_get_bitmap1
  8. zeit_get_outline1
  9. mag_mode_2
  10. zeit_get_metric2
  11. zeit_get_fontbbx2
  12. zeit_get_bitmap2
  13. get_outline2
  14. zeit_get_font_prop
  15. ZEIT_SetZEIT
  16. ZEIT_GetZEIT
  17. debug_on

   1 /*
   2  * drv_zeit.c - A font driver for ZEIT format fonts 
   3  *
   4  * by Hirotsugu Kakugawa
   5  *
   6  *  3 Dec 1996  First version.
   7  * 10 Dec 1996  Changed for VFlib version 3.1
   8  * 12 Dec 1996  Eliminated "do" capability.
   9  * 26 Feb 1997  Added 'query_font_type'.
  10  *  7 Aug 1997  VFlib 3.3  Changed API.
  11  * 28 Jan 1998  VFlib 3.4  Changed API.
  12  * 24 Nov 1998  Added get_fontbbx1() and get_fontbbx2().
  13  * 18 Oct 2001    Fixed memory leaks.
  14  *
  15  */
  16 /*
  17  * Copyright (C) 1993-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 - print font file path
  35  *    i - print info on character index 
  36  *    o - print contents of outline data
  37  *    * - everything
  38  */
  39 
  40 #include  "config.h"
  41 #include  <stdio.h>
  42 #include  <stdlib.h>
  43 #ifdef HAVE_UNISTD_H
  44 #  include <unistd.h>
  45 #endif
  46 #include  <ctype.h>
  47 #include  <math.h>
  48 #include  <sys/param.h>
  49 #include  "VFlib-3_6.h"
  50 #include  "VFsys.h"
  51 #include  "vflibcap.h"
  52 #include  "bitmap.h"
  53 #include  "cache.h"
  54 #include  "fsearch.h"
  55 #include  "str.h"
  56 #include  "sexp.h"
  57 
  58 
  59 #include  "zeit.h"
  60 
  61 #define DIRECTION_HORIZONTAL  0
  62 #define DIRECTION_VERTICAL    1
  63 
  64 #define   POINTS_PER_INCH      72.27  /* 1 inch = 72.27 point */
  65 
  66 #define   DEFAULT_DPI          72.27
  67 #define   DEFAULT_POINT_SIZE   32.0
  68 #define   DEFAULT_PIXEL_SIZE   32
  69 #define   DEFAULT_DIRECTION    DIRECTION_HORIZONTAL  
  70 
  71 
  72 Private SEXP_LIST    default_fontdirs;
  73 Private SEXP_LIST    default_extensions;
  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_STRING  default_direction;
  83 Private char         v_default_direction;
  84 Private SEXP_LIST    default_vec_bbxul;
  85 Private double       v_default_vec_bbxul_x, v_default_vec_bbxul_y;
  86 Private SEXP_LIST    default_vec_next;
  87 Private double       v_default_vec_next_x, v_default_vec_next_y;
  88 Private SEXP_ALIST   default_properties;
  89 Private SEXP_ALIST   default_variables;
  90 Private SEXP_STRING  default_debug_mode;
  91 
  92 struct s_font_zeit {
  93   int       zeit_id;
  94   char     *font_name;
  95   double    point_size;
  96   int       pixel_size;
  97   double    dpi_x, dpi_y;
  98   double    aspect;
  99   double    mag;
 100   double    slant;
 101   double    vec_bbxul_x, vec_bbxul_y;
 102   double    vec_next_x, vec_next_y;
 103   char      direction;
 104   SEXP      props;
 105 };
 106 typedef struct s_font_zeit  *FONT_ZEIT;
 107 
 108 Private int        zeit_create(VF_FONT font, char *font_class,
 109                                char *font_name, int implicit, SEXP entry);
 110 Private int        zeit_close(VF_FONT);
 111 Private int        zeit_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
 112 Private int        zeit_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
 113 Private int        zeit_get_fontbbx1(VF_FONT,double,double,
 114                                      double*,double*,double*,double*);
 115 Private int        zeit_get_fontbbx2(VF_FONT,double,double, 
 116                                      int*,int*,int*,int*);
 117 Private VF_BITMAP  zeit_get_bitmap1(VF_FONT,long,double,double);
 118 Private VF_BITMAP  zeit_get_bitmap2(VF_FONT,long,double,double);
 119 Private VF_OUTLINE zeit_get_outline1(VF_FONT,long,double,double);
 120 Private char*      zeit_get_font_prop(VF_FONT,char*);
 121 Private VF_OUTLINE   get_outline2(VF_FONT,FONT_ZEIT,long,int,double,double);
 122 
 123 Private ZEIT       ZEIT_GetZEIT(int zeit_id);
 124 Private void       ZEIT_SetZEIT(int zeit_id, ZEIT zeit);
 125 Private int        debug_on(char type);
 126 
 127 
 128 
 129 Public int
 130 VF_Init_Driver_ZEIT(void)
     /* [<][>][^][v][top][bottom][index][help] */
 131 {
 132   char   *p;
 133   SEXP   s1, s2;
 134   struct s_capability_table  ct[20];
 135   int  z;
 136 
 137   z = 0;
 138   /* VF_CAPE_FONT_DIRECTORIES */
 139   ct[z].cap = VF_CAPE_FONT_DIRECTORIES;   ct[z].type = CAPABILITY_LIST;
 140   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_fontdirs;
 141   /* VF_CAPE_EXTENSIONS */
 142   ct[z].cap = VF_CAPE_EXTENSIONS;         ct[z].type = CAPABILITY_LIST;
 143   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_extensions;
 144   /* VF_CAPE_POINT_SIZE */
 145   ct[z].cap = VF_CAPE_POINT_SIZE;         ct[z].type = CAPABILITY_STRING;
 146   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_point_size;
 147   /* VF_CAPE_PIXEL_SIZE */
 148   ct[z].cap = VF_CAPE_PIXEL_SIZE;         ct[z].type = CAPABILITY_STRING;
 149   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_pixel_size;
 150   /* VF_CAPE_DPI */
 151   ct[z].cap = VF_CAPE_DPI;                ct[z].type = CAPABILITY_STRING;
 152   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi;
 153   /* VF_CAPE_DPI_X */
 154   ct[z].cap = VF_CAPE_DPI_X;              ct[z].type = CAPABILITY_STRING;
 155   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi_x;
 156   /* VF_CAPE_DPI_Y */
 157   ct[z].cap = VF_CAPE_DPI_Y;              ct[z].type = CAPABILITY_STRING;
 158   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi_y;
 159   /* VF_CAPE_ASPECT_RATIO */
 160   ct[z].cap = VF_CAPE_ASPECT_RATIO;       ct[z].type = CAPABILITY_STRING;
 161   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_aspect;
 162   /* VF_CAPE_DIRECTION */
 163   ct[z].cap = VF_CAPE_DIRECTION;          ct[z].type = CAPABILITY_STRING;
 164   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_direction;
 165   /* VF_CAPE_VECTOR_TO_BBX_UL */
 166   ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL;   ct[z].type = CAPABILITY_VECTOR;
 167   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_vec_bbxul;
 168   /* VF_CAPE_VECTOR_TO_NEXT */
 169   ct[z].cap = VF_CAPE_VECTOR_TO_NEXT;     ct[z].type = CAPABILITY_VECTOR;
 170   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_vec_next;
 171   /* VF_CAPE_PROPERTIES */
 172   ct[z].cap = VF_CAPE_PROPERTIES;         ct[z].type = CAPABILITY_ALIST;
 173   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_properties;
 174   /* VF_CAPE_VARIABLE_VALUES */
 175   ct[z].cap = VF_CAPE_VARIABLE_VALUES;    ct[z].type = CAPABILITY_ALIST;
 176   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_variables;
 177   /* VF_CAPE_DEBUG */ 
 178   ct[z].cap = VF_CAPE_DEBUG;              ct[z].type = CAPABILITY_STRING;
 179   ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_debug_mode;
 180   /* end */
 181   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 182 
 183 
 184   if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL) 
 185       == VFLIBCAP_PARSED_ERROR)
 186     return -1;
 187 
 188   if (default_extensions == NULL)
 189     default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS);
 190 
 191   v_default_point_size = DEFAULT_POINT_SIZE;
 192   if (default_point_size != NULL)
 193     v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
 194   if (v_default_point_size < 0)
 195     v_default_point_size = DEFAULT_POINT_SIZE;
 196 
 197   v_default_pixel_size = DEFAULT_PIXEL_SIZE;
 198   if (default_pixel_size != NULL)
 199     v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
 200   if (v_default_pixel_size < 0)
 201     v_default_pixel_size  = DEFAULT_PIXEL_SIZE;
 202 
 203   v_default_dpi_x  = DEFAULT_DPI;
 204   v_default_dpi_y  = DEFAULT_DPI;
 205   if (default_dpi != NULL)
 206     v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
 207   if (default_dpi_x != NULL)
 208     v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
 209   if (default_dpi_y != NULL)
 210     v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
 211   if (v_default_dpi_x < 0)
 212     v_default_dpi_x = DEFAULT_DPI;
 213   if (v_default_dpi_y < 0)
 214     v_default_dpi_y = DEFAULT_DPI;
 215 
 216   v_default_aspect = 1.0;
 217   if (default_aspect != NULL)
 218     v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
 219   if (v_default_aspect < 0)
 220     v_default_aspect = 1.0;
 221 
 222   v_default_direction = DEFAULT_DIRECTION;
 223   if (default_direction != NULL){
 224     p = vf_sexp_get_cstring(default_direction);
 225     switch (*p){
 226     case 'h': case 'H':
 227       v_default_direction = DIRECTION_HORIZONTAL;
 228       break;
 229     case 'v': case 'V':
 230       v_default_direction = DIRECTION_VERTICAL;
 231       break;
 232     default:
 233       fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
 234       break;
 235     }
 236   }
 237 
 238   switch(v_default_direction){
 239   case DIRECTION_HORIZONTAL: default:
 240     v_default_vec_bbxul_x = 0;
 241     v_default_vec_bbxul_y = DEFAULT_TO_REF_PT_H;
 242     v_default_vec_next_x  = 1.0;
 243     v_default_vec_next_y  = 0.0;
 244     break;
 245   case DIRECTION_VERTICAL:
 246     v_default_vec_bbxul_x = DEFAULT_TO_REF_PT_V;
 247     v_default_vec_bbxul_y = 0;
 248     v_default_vec_next_x  = 0.0;
 249     v_default_vec_next_y  = -1.0;
 250     break;
 251   }
 252 
 253   if (default_vec_bbxul != NULL){
 254     s1 = vf_sexp_car(default_vec_bbxul);
 255     s2 = vf_sexp_cadr(default_vec_bbxul);
 256     v_default_vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
 257     v_default_vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
 258   }
 259 
 260   if (default_vec_next != NULL){
 261     s1 = vf_sexp_car(default_vec_next);
 262     s2 = vf_sexp_cadr(default_vec_next);
 263     v_default_vec_next_x = atof(vf_sexp_get_cstring(s1));
 264     v_default_vec_next_y = atof(vf_sexp_get_cstring(s2));
 265   }
 266 
 267   if (ZEIT_Init() < 0)
 268     return -1;
 269 
 270   VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)zeit_create);
 271 
 272   return 0;
 273 }
 274   
 275 
 276 Private int
 277 zeit_create(VF_FONT font, char *font_class,
     /* [<][>][^][v][top][bottom][index][help] */
 278             char *font_name, int implicit, SEXP entry)
 279 {
 280   FONT_ZEIT  font_zeit;
 281   ZEIT       zeit;
 282   char      *font_file, *p;
 283   int        zeit_id, val;
 284   SEXP       s1, s2;
 285   SEXP       cap_font, cap_point, cap_pixel;
 286   SEXP       cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
 287   SEXP       cap_direction, cap_vec_bbxul, cap_vec_next, cap_props;
 288   struct s_capability_table  ct[20];
 289   int  z;
 290 
 291   z = 0;
 292   /* VF_CAPE_FONT_CLASS */
 293   ct[z].cap = VF_CAPE_FONT_CLASS;       ct[z].type = CAPABILITY_STRING;
 294   ct[z].ess = CAPABILITY_ESSENTIAL;     ct[z++].val = NULL;
 295   /* VF_CAPE_FONT_FILE */
 296   ct[z].cap = VF_CAPE_FONT_FILE;        ct[z].type = CAPABILITY_STRING;
 297   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_font;
 298   /* VF_CAPE_POINT_SIZE */
 299   ct[z].cap = VF_CAPE_POINT_SIZE;       ct[z].type = CAPABILITY_STRING;
 300   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_point;
 301   /* VF_CAPE_PIXEL_SIZE */
 302   ct[z].cap = VF_CAPE_PIXEL_SIZE;       ct[z].type = CAPABILITY_STRING;
 303   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_pixel;
 304   /* VF_CAPE_DPI */
 305   ct[z].cap = VF_CAPE_DPI;              ct[z].type = CAPABILITY_STRING;
 306   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi;
 307   /* VF_CAPE_DPI_X */
 308   ct[z].cap = VF_CAPE_DPI_X;            ct[z].type = CAPABILITY_STRING;
 309   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_x;
 310   /* VF_CAPE_DPI_Y */
 311   ct[z].cap = VF_CAPE_DPI_Y;            ct[z].type = CAPABILITY_STRING;
 312   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_y;
 313   /* VF_CAPE_MAG */
 314   ct[z].cap = VF_CAPE_MAG;              ct[z].type = CAPABILITY_STRING;
 315   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_mag;
 316   /* VF_CAPE_ASPECT_RATIO */
 317   ct[z].cap = VF_CAPE_ASPECT_RATIO;     ct[z].type = CAPABILITY_STRING;
 318   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_aspect;
 319   /* VF_CAPE_DIRECTION */
 320   ct[z].cap = VF_CAPE_DIRECTION;        ct[z].type = CAPABILITY_STRING;
 321   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_direction;
 322   /* VF_CAPE_VECTOR_TO_BBX_UL */
 323   ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL; ct[z].type = CAPABILITY_VECTOR;
 324   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_vec_bbxul;
 325   /* VF_CAPE_VECTOR_TO_NEXT */
 326   ct[z].cap = VF_CAPE_VECTOR_TO_NEXT;   ct[z].type = CAPABILITY_VECTOR;
 327   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_vec_next;
 328   /* VF_CAPE_PROPERTIES */
 329   ct[z].cap = VF_CAPE_PROPERTIES;       ct[z].type = CAPABILITY_ALIST;
 330   ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_props;
 331   /* end */
 332   ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
 333 
 334 
 335   if (implicit == 1){   /* implicit font */
 336     font_file = font_name;
 337   } else {              /* explicit font */
 338     if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
 339                                   default_variables, NULL) < 0)
 340       return -1;
 341     if (cap_font == NULL){
 342       /* Use font name as font file name if font file name is not given. */
 343       font_file = font_name;
 344     } else {
 345       font_file = vf_sexp_get_cstring(cap_font);
 346     }
 347   }
 348 
 349   val = -1;
 350   font_zeit = NULL;
 351 
 352   if ((zeit_id = ZEIT_Open(font_file)) < 0)
 353       goto End;
 354 
 355   font->font_type       = VF_FONT_TYPE_OUTLINE;
 356   font->get_metric1     = zeit_get_metric1;
 357   font->get_metric2     = zeit_get_metric2;
 358   font->get_fontbbx1    = zeit_get_fontbbx1;
 359   font->get_fontbbx2    = zeit_get_fontbbx2;
 360   font->get_bitmap1     = zeit_get_bitmap1;
 361   font->get_bitmap2     = zeit_get_bitmap2;
 362   font->get_outline     = zeit_get_outline1;
 363   font->get_font_prop   = zeit_get_font_prop;
 364   font->query_font_type = NULL;  /* Use font->font_type value. */
 365   font->close           = zeit_close;
 366 
 367   ALLOC_IF_ERR(font_zeit, struct s_font_zeit){
 368     vf_error = VF_ERR_NO_MEMORY;
 369     goto End;
 370   }
 371 
 372   font_zeit->zeit_id     = zeit_id;
 373   font_zeit->font_name   = NULL;
 374   font_zeit->point_size  = v_default_point_size;
 375   font_zeit->pixel_size  = v_default_pixel_size;
 376   font_zeit->mag         = 1.0;
 377   font_zeit->dpi_x       = v_default_dpi_x;
 378   font_zeit->dpi_y       = v_default_dpi_y;
 379   font_zeit->aspect      = v_default_aspect;
 380   font_zeit->direction   = v_default_direction;
 381   font_zeit->slant       = 0;
 382   font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
 383   font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
 384   font_zeit->vec_next_x  = v_default_vec_next_x;
 385   font_zeit->vec_next_y  = v_default_vec_next_y;
 386 
 387   if (implicit == 0){
 388     if (cap_point != NULL)
 389       font_zeit->point_size = atof(vf_sexp_get_cstring(cap_point));
 390     if (cap_pixel != NULL)
 391       font_zeit->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
 392     if (cap_dpi != NULL)
 393       font_zeit->dpi_x = font_zeit->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
 394     if (cap_dpi_x != NULL)
 395       font_zeit->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
 396     if (cap_dpi_y != NULL)
 397       font_zeit->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
 398     if (cap_mag != NULL)
 399       font_zeit->mag = atof(vf_sexp_get_cstring(cap_mag));
 400     if (cap_aspect != NULL)
 401       font_zeit->aspect = atof(vf_sexp_get_cstring(cap_aspect));
 402     if (cap_direction != NULL){
 403       p = vf_sexp_get_cstring(cap_direction);
 404       switch (*p){
 405       case 'h': case 'H':
 406         font_zeit->direction = DIRECTION_HORIZONTAL;  break;
 407       case 'v': case 'V':
 408         font_zeit->direction = DIRECTION_VERTICAL;    break;
 409       default:
 410         fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
 411         break;
 412       }
 413     }
 414     switch(font_zeit->direction){
 415     case DIRECTION_HORIZONTAL: default:
 416       font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
 417       font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
 418       font_zeit->vec_next_x  = v_default_vec_next_x;
 419       font_zeit->vec_next_y  = v_default_vec_next_y;
 420       break;
 421     case DIRECTION_VERTICAL:
 422       font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
 423       font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
 424       font_zeit->vec_next_x  = v_default_vec_next_x;
 425       font_zeit->vec_next_y  = v_default_vec_next_y;
 426       break;
 427     }
 428     if (cap_vec_bbxul != NULL){
 429       s1 = vf_sexp_car(cap_vec_bbxul);
 430       s2 = vf_sexp_cadr(cap_vec_bbxul);
 431       font_zeit->vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
 432       font_zeit->vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
 433     }
 434     if (cap_vec_next != NULL){
 435       s1 = vf_sexp_car(cap_vec_next);
 436       s2 = vf_sexp_cadr(cap_vec_next);
 437       font_zeit->vec_next_x = atof(vf_sexp_get_cstring(s1));
 438       font_zeit->vec_next_y = atof(vf_sexp_get_cstring(s2));
 439     }
 440     if (cap_props != NULL)
 441       font_zeit->props = cap_props;
 442   }
 443 
 444   if ((font_zeit->font_name = vf_strdup(font_name)) == NULL){
 445     vf_error = VF_ERR_NO_MEMORY;
 446     goto End;
 447   }
 448 
 449   if ((zeit = ZEIT_GetZEIT(font_zeit->zeit_id)) == NULL){
 450     fprintf(stderr, "VFlib: internal error in zeit_create()\n");
 451     vf_error = VF_ERR_INTERNAL;
 452     goto End;
 453   }
 454 
 455   font->private = font_zeit;
 456   val = 0;
 457 
 458 End:
 459   if (implicit == 0){
 460     vf_sexp_free3(&cap_font, &cap_point, &cap_pixel);
 461     vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
 462     vf_sexp_free3(&cap_direction, &cap_vec_bbxul, &cap_vec_next);
 463   }
 464   if (val < 0)
 465     zeit_close(font);
 466 
 467   return val;
 468 }
 469 
 470 
 471 Private int
 472 zeit_close(VF_FONT font)
     /* [<][>][^][v][top][bottom][index][help] */
 473 {
 474   FONT_ZEIT  font_zeit;
 475 
 476   font_zeit = (FONT_ZEIT)font->private;
 477 
 478   if (font_zeit != NULL){
 479     if (font_zeit->zeit_id >= 0)
 480       ZEIT_Close(font_zeit->zeit_id);
 481     vf_free(font_zeit->font_name); 
 482     vf_sexp_free1(&font_zeit->props);
 483     vf_free(font_zeit);
 484   }
 485 
 486   return 0; 
 487 }
 488 
 489 
 490 
 491 Private void
 492 mag_mode_1(FONT_ZEIT font_zeit, VF_FONT font, 
     /* [<][>][^][v][top][bottom][index][help] */
 493            double mag_x, double mag_y,
 494            double *ret_point_size,
 495            double *ret_bbx_w, double *ret_bbx_h, 
 496            double *ret_mag_x, double *ret_mag_y, 
 497            double *ret_dpix, double *ret_dpiy)
 498 {
 499   double  mx, my, dpix, dpiy, ps, asp;
 500 
 501   if ((ps = font->point_size) < 0)
 502     if ((ps = font_zeit->point_size) < 0)
 503       ps = v_default_point_size;
 504 
 505   if (ret_point_size != NULL)
 506     *ret_point_size = ps;
 507 
 508   asp = (v_default_aspect * font_zeit->aspect);
 509 
 510   mx = mag_x * font_zeit->mag * font->mag_x * asp;
 511   my = mag_y * font_zeit->mag * font->mag_y;
 512 
 513   if (ret_mag_x != NULL)
 514     *ret_mag_x = mx;
 515   if (ret_mag_y != NULL)
 516     *ret_mag_y = my;
 517 
 518   if ((font->dpi_x > 0) && (font->dpi_y > 0)){
 519     dpix = font->dpi_x;
 520     dpiy = font->dpi_y;
 521   } else if ((font_zeit->dpi_x > 0) && (font_zeit->dpi_y > 0)){
 522     dpix = font_zeit->dpi_x;
 523     dpiy = font_zeit->dpi_y;
 524   } else {
 525     dpix = v_default_dpi_x;
 526     dpiy = v_default_dpi_y;
 527   }
 528 
 529   if (ret_dpix != NULL)
 530     *ret_dpix = dpix;
 531   if (ret_dpiy != NULL)
 532     *ret_dpiy = dpiy;
 533 
 534   if (ret_bbx_w != NULL)
 535     *ret_bbx_w = dpix * mx * (ps / POINTS_PER_INCH);
 536   if (ret_bbx_h != NULL)
 537     *ret_bbx_h = dpiy * my * (ps / POINTS_PER_INCH);
 538 
 539 #if 0
 540   printf("*** %.3f %.3f %.3f\n", mag_x, font_zeit->mag, font->mag_x);
 541   printf("    %.3f %.3f %.3f\n", mag_y, font_zeit->mag, font->mag_y);
 542   printf("    dpix=%.3f  font_dpi_x=%.3f\n", dpix, font_dpi_x);
 543   printf("    dpiy=%.3f  font_dpi_y=%.3f\n", dpiy, font_dpi_y);
 544   printf("    asp=%.3f\n", asp);
 545   printf("    mx=%.3f, my=%.3f\n", mx, my);
 546   if (ret_bbx_w != NULL)
 547     printf("    W=%.3f  H=%.3f\n", *ret_bbx_w, *ret_bbx_h);
 548 #endif
 549 
 550 }
 551 
 552 
 553 Private int
 554 zeit_get_metric1(VF_FONT font, long code, VF_METRIC1 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 555                  double mag_x, double mag_y)
 556 {
 557   FONT_ZEIT  font_zeit;
 558   double     bbx_w, bbx_h;
 559   double     dpix, dpiy;
 560 
 561   if (   ((font_zeit = (FONT_ZEIT)font->private) == NULL)
 562       || (metric == NULL)){
 563     fprintf(stderr, "VFlib internal error: in zeit_get_metric1()\n");
 564     abort();
 565   }
 566 
 567   mag_mode_1(font_zeit, font, mag_x, mag_y, 
 568              NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);
 569 
 570   metric->bbx_width  = bbx_w;
 571   metric->bbx_height = bbx_h;
 572   metric->off_x = bbx_w * font_zeit->vec_bbxul_x;
 573   metric->off_y = bbx_h * font_zeit->vec_bbxul_y;
 574   metric->mv_x  = bbx_w * font_zeit->vec_next_x;
 575   metric->mv_y  = bbx_h * font_zeit->vec_next_y;
 576 
 577   return 0;
 578 }
 579 
 580 Private int
 581 zeit_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 582                   double *w_p, double *h_p, double *xoff_p, double *yoff_p)
 583 {
 584   FONT_ZEIT  font_zeit;
 585   double     bbx_w, bbx_h;
 586   double     dpix, dpiy;
 587 
 588   if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
 589     fprintf(stderr, "VFlib internal error: in zeit_get_fontbbx1()\n");
 590     abort();
 591   }
 592 
 593   mag_mode_1(font_zeit, font, mag_x, mag_y, 
 594              NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);
 595 
 596   *w_p = bbx_w;
 597   *h_p = bbx_h;
 598   *xoff_p = bbx_w * font_zeit->vec_bbxul_x;
 599   *yoff_p = bbx_h * (1.0 - font_zeit->vec_bbxul_y);
 600 
 601   return 0;
 602 }
 603 
 604 Private VF_BITMAP
 605 zeit_get_bitmap1(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 606                  double mag_x, double mag_y)
 607 {
 608   VF_OUTLINE   outline;
 609   VF_BITMAP    bm;
 610 
 611   if ((outline = zeit_get_outline1(font, code_point, mag_x, mag_y)) == NULL)
 612     return NULL;
 613 
 614   bm = vf_outline_to_bitmap(outline, -1, -1, -1, 1, 1);
 615   VF_FreeOutline(outline);
 616 
 617   return  bm;
 618 }
 619 
 620 Private VF_OUTLINE
 621 zeit_get_outline1(VF_FONT font, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 622                   double mag_x, double mag_y)
 623 {
 624   FONT_ZEIT   font_zeit;
 625   VF_OUTLINE  outline;
 626   double      ps, mx, my, bbx_w, bbx_h, dpix, dpiy, em_mag;
 627 
 628   if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
 629     fprintf(stderr, "VFlib: internal error in zeit_get_outline1()\n");
 630     abort();
 631   }
 632 
 633   mag_mode_1(font_zeit, font, mag_x, mag_y, 
 634              &ps, &bbx_w, &bbx_h, &mx, &my, &dpix, &dpiy);
 635 
 636   em_mag = 1.0;
 637   if (mx > 1){
 638     em_mag /= mx;
 639     my = my/mx;
 640     mx = 1.0;
 641   }
 642   if (my > 1){
 643     em_mag /= my;
 644     mx = mx/my;
 645     my = 1.0;
 646   }
 647 
 648   outline = ZEIT_ReadOutline(font_zeit->zeit_id, (int)code_point, mx, my);
 649   if (outline == NULL)
 650     return NULL;
 651 
 652   outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
 653   outline[VF_OL_HEADER_INDEX_DPI_X]       = VF_OL_HEADER_ENCODE(dpix);
 654   outline[VF_OL_HEADER_INDEX_DPI_Y]       = VF_OL_HEADER_ENCODE(dpiy);
 655   outline[VF_OL_HEADER_INDEX_POINT_SIZE]  = VF_OL_HEADER_ENCODE(ps);
 656   outline[VF_OL_HEADER_INDEX_EM]          = VF_OL_COORD_RANGE * em_mag;
 657   outline[VF_OL_HEADER_INDEX_MAX_X]       = VF_OL_COORD_RANGE * mx;
 658   outline[VF_OL_HEADER_INDEX_MAX_Y]       = VF_OL_COORD_RANGE * my;
 659   outline[VF_OL_HEADER_INDEX_REF_X] 
 660     = VF_OL_COORD_RANGE * (0 -  font_zeit->vec_bbxul_x) * mx;
 661   outline[VF_OL_HEADER_INDEX_REF_Y] 
 662     = VF_OL_COORD_RANGE * font_zeit->vec_bbxul_y * my;
 663   outline[VF_OL_HEADER_INDEX_MV_X] 
 664     = VF_OL_COORD_RANGE * font_zeit->vec_next_x * mx;
 665   outline[VF_OL_HEADER_INDEX_MV_Y]
 666     = VF_OL_COORD_RANGE * font_zeit->vec_next_y * my;
 667 
 668   return outline;
 669 }
 670 
 671 
 672 Private void
 673 mag_mode_2(FONT_ZEIT font_zeit, VF_FONT font, 
     /* [<][>][^][v][top][bottom][index][help] */
 674            double mag_x, double mag_y,
 675            double *ret_pixel_size,
 676            double *ret_magx, double *ret_magy,
 677            double *ret_bbx_w, double *ret_bbx_h)
 678 {
 679   int     ps;
 680   double  mx, my, asp;
 681 
 682   if ((ps = font->pixel_size) < 0)
 683     if ((ps = font_zeit->pixel_size) < 0)
 684       ps = v_default_pixel_size;
 685 
 686   asp = (v_default_aspect * font_zeit->aspect);
 687 
 688   mx = mag_x * font_zeit->mag * font->mag_x * asp;
 689   my = mag_y * font_zeit->mag * font->mag_y;
 690 
 691   if (ret_pixel_size != NULL)
 692     *ret_pixel_size = ps;
 693 
 694   if (ret_magx != NULL)
 695     *ret_magx = mx;
 696   if (ret_magy != NULL)
 697     *ret_magy = my;
 698 
 699   if (ret_bbx_w != NULL)
 700     *ret_bbx_w = mx * ps;
 701   if (ret_bbx_h != NULL)
 702     *ret_bbx_h = my * ps;
 703 }
 704 
 705 
 706 Private int
 707 zeit_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric, 
     /* [<][>][^][v][top][bottom][index][help] */
 708                  double mag_x, double mag_y)
 709 {
 710   FONT_ZEIT  font_zeit;
 711   double     bbx_w, bbx_h;
 712 
 713   if (   ((font_zeit = (FONT_ZEIT)font->private) == NULL)
 714       || (metric == NULL)){
 715     fprintf(stderr, "VFlib internal error: in zeit_get_metric2()\n");
 716     abort();
 717   }
 718 
 719   mag_mode_2(font_zeit, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);
 720 
 721   metric->bbx_width  = (int)ceil(bbx_w);
 722   metric->bbx_height = (int)ceil(bbx_h);
 723   metric->off_x = toint(bbx_w * font_zeit->vec_bbxul_x);
 724   metric->off_y = toint(bbx_h * font_zeit->vec_bbxul_y);
 725   metric->mv_x  = toint(bbx_w * font_zeit->vec_next_x);
 726   metric->mv_y  = toint(bbx_h * font_zeit->vec_next_y);
 727 
 728   return 0;
 729 }
 730 
 731 Private int
 732 zeit_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
     /* [<][>][^][v][top][bottom][index][help] */
 733                   int *w_p, int *h_p, int *xoff_p, int *yoff_p)
 734 {
 735   FONT_ZEIT  font_zeit;
 736   double     bbx_w, bbx_h;
 737 
 738   if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
 739     fprintf(stderr, "VFlib internal error: in zeit_get_fontbbx2()\n");
 740     abort();
 741   }
 742 
 743   mag_mode_2(font_zeit, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);
 744 
 745   *w_p  = toint(bbx_w);
 746   *h_p  = toint(bbx_h);
 747   *xoff_p = toint(bbx_w * font_zeit->vec_bbxul_x);
 748   *yoff_p = toint(bbx_w * (font_zeit->vec_bbxul_y - 1.0));
 749 
 750   return 0;
 751 }
 752 
 753 Private VF_BITMAP
 754 zeit_get_bitmap2(VF_FONT font, long code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 755                  double mag_x, double mag_y)
 756 {
 757   FONT_ZEIT   font_zeit;
 758   VF_OUTLINE  outline; 
 759   VF_BITMAP   bm;
 760   double      ps, mx, my, bbx_w, bbx_h;
 761   int         bbx_width, bbx_height;
 762 
 763   if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
 764     fprintf(stderr, "VFlib internal error: in zeit_get_bitmap2()\n");
 765     abort();
 766   }
 767 
 768   mag_mode_2(font_zeit, font, mag_x, mag_y, &ps, &mx, &my, &bbx_w, &bbx_h);
 769 
 770   bbx_width  = (int)ceil(bbx_w);
 771   bbx_height = (int)ceil(bbx_h);
 772 
 773   if ((bm = vf_alloc_bitmap(bbx_width, bbx_height)) == NULL){
 774     vf_error = VF_ERR_NO_MEMORY;
 775     return NULL;
 776   }
 777 
 778   outline = get_outline2(font, font_zeit, code_point, ps, mx, my);
 779   if (outline == NULL)
 780     return NULL;
 781 
 782   if (vf_draw_outline(bm, outline) < 0){
 783     VF_FreeOutline(outline);
 784     VF_FreeBitmap(bm);
 785     return NULL;
 786   }
 787   VF_FreeOutline(outline);
 788 
 789   bm->off_x = toint(bbx_w * font_zeit->vec_bbxul_x);
 790   bm->off_y = toint(bbx_h * font_zeit->vec_bbxul_y);
 791   bm->mv_x  = toint(bbx_w * font_zeit->vec_next_x);
 792   bm->mv_y  = toint(bbx_h * font_zeit->vec_next_y);
 793 
 794   return bm;
 795 }
 796 
 797 
 798 Private VF_OUTLINE
 799 get_outline2(VF_FONT font, FONT_ZEIT font_zeit, long code_point,
     /* [<][>][^][v][top][bottom][index][help] */
 800              int pixel_size, double mx, double my)
 801 {
 802   VF_OUTLINE   outline;
 803   double       em_mag;
 804   
 805   em_mag = 1.0; 
 806   if (mx > 1){
 807     em_mag /= mx; 
 808     my = my/mx;
 809     mx = 1.0;
 810   }
 811   if (my > 1){
 812     em_mag /= my; 
 813     mx = mx/my;
 814     my = 1.0;
 815   }
 816   
 817   outline = ZEIT_ReadOutline(font_zeit->zeit_id, (int)code_point, mx, my);
 818   if (outline == NULL)
 819     return NULL;
 820 
 821   outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
 822   outline[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
 823   outline[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
 824   outline[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(pixel_size);
 825   outline[VF_OL_HEADER_INDEX_EM]    = VF_OL_COORD_RANGE * my;
 826   outline[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * mx;
 827   outline[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * my;
 828   outline[VF_OL_HEADER_INDEX_REF_X] 
 829     = VF_OL_COORD_RANGE * (0 -  font_zeit->vec_bbxul_x) * mx;
 830   outline[VF_OL_HEADER_INDEX_REF_Y]
 831     = VF_OL_COORD_RANGE * font_zeit->vec_bbxul_y * my;
 832   outline[VF_OL_HEADER_INDEX_MV_X] 
 833     = VF_OL_COORD_RANGE * font_zeit->vec_next_x * mx;
 834   outline[VF_OL_HEADER_INDEX_MV_Y]
 835     = VF_OL_COORD_RANGE * font_zeit->vec_next_y * my;
 836 
 837   return outline;
 838 }
 839 
 840 
 841 Private char*
 842 zeit_get_font_prop(VF_FONT font, char *prop_name)
     /* [<][>][^][v][top][bottom][index][help] */
 843      /* CALLER MUST RELEASE RETURNED STRING */
 844 {
 845   FONT_ZEIT   font_zeit;
 846   char        str[512];
 847   double      ps, dpix, dpiy;
 848   SEXP        v;
 849 
 850   if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
 851     fprintf(stderr, "VFlib: internal error in zeit_get_font_prop()\n");
 852     abort();
 853   }
 854   
 855   if ((v = vf_sexp_assoc(prop_name, font_zeit->props)) != NULL){
 856     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 857   } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
 858     return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
 859   }
 860 
 861   if (font->mode == 1){
 862     mag_mode_1(font_zeit, font, 1.0, 1.0,
 863                &ps, NULL, NULL, NULL, NULL, &dpix, &dpiy);
 864     /**printf("** Mode1 %.3f %.3f %.3f\n", ps, dpix, dpiy);**/
 865     if (strcmp(prop_name, "POINT_SIZE") == 0){
 866       sprintf(str, "%d", toint(10.0 * ps)); 
 867       return vf_strdup(str);
 868     } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 869       sprintf(str, "%d", toint(ps * dpiy / POINTS_PER_INCH));
 870       return vf_strdup(str);
 871     } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 872       sprintf(str, "%d", toint(dpix)); 
 873       return vf_strdup(str);
 874     } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 875       sprintf(str, "%d", toint(dpiy)); 
 876       return vf_strdup(str);
 877     } 
 878   } else if (font->mode == 2){
 879     mag_mode_2(font_zeit, font, 1.0, 1.0, &ps, NULL, NULL, NULL, NULL);
 880     /**printf("** Mode2 %.3f\n", ps);**/
 881     if (strcmp(prop_name, "POINT_SIZE") == 0){
 882       sprintf(str, "%d", toint(10.0 * ps * POINTS_PER_INCH / DEFAULT_DPI)); 
 883       return vf_strdup(str);
 884     } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
 885       sprintf(str, "%d", toint(ps)); 
 886       return vf_strdup(str);
 887     } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
 888       sprintf(str, "%d", toint(DEFAULT_DPI)); 
 889       return vf_strdup(str);
 890     } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
 891       sprintf(str, "%d", toint(DEFAULT_DPI)); 
 892       return vf_strdup(str);
 893     } 
 894   }
 895 
 896   return NULL; 
 897 }
 898 
 899 
 900 /* 
 901  * Include Low-Level Font Interface Routine. 
 902  */ 
 903 
 904 #include "zeit.c"
 905 
 906 
 907 static int    zeit_last_zeit_id = -1;
 908 static ZEIT   zeit_last_zeit   = NULL;
 909 
 910 Private void
 911 ZEIT_SetZEIT(int zeit_id, ZEIT zeit)
     /* [<][>][^][v][top][bottom][index][help] */
 912 {
 913   zeit_last_zeit_id  = zeit_id;
 914   zeit_last_zeit     = zeit;
 915 }
 916 
 917 Private ZEIT
 918 ZEIT_GetZEIT(int zeit_id)
     /* [<][>][^][v][top][bottom][index][help] */
 919 {
 920   ZEIT   zeit;
 921 
 922   if (zeit_id == -1){
 923     zeit_last_zeit_id  = -1;
 924     zeit_last_zeit     = NULL;
 925     return NULL;
 926   }
 927 
 928   if (   (zeit_last_zeit_id == zeit_id) 
 929       && (zeit_last_zeit != NULL) 
 930       && (zeit_last_zeit_id != -1))
 931     return zeit_last_zeit;
 932   
 933   zeit = (zeit_table->get_obj_by_id)(zeit_table, zeit_id);
 934   zeit_last_zeit_id = zeit_id;
 935   zeit_last_zeit    = zeit;  
 936 
 937   return zeit;
 938 }
 939 
 940 
 941 Private int
 942 debug_on(char type)
     /* [<][>][^][v][top][bottom][index][help] */
 943 {
 944   char  *p, *p0;
 945 
 946   if (default_debug_mode == NULL)
 947     return FALSE;
 948   if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
 949     return FALSE;
 950   
 951   for (p = p0; *p != '\0'; p++){
 952     if (*p == type)
 953       return TRUE;
 954   }
 955   for (p = p0; *p != '\0'; p++){
 956     if (*p == '*')
 957       return TRUE;
 958   }
 959   return FALSE;
 960 }
 961 
 962 /*EOF*/

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