src/drv_jg.c

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

FUNCTIONS

This source file includes following functions.
  1. VF_Init_Driver_JG
  2. jg_create
  3. jg_close
  4. mag_mode_1
  5. jg_get_metric1
  6. jg_get_fontbbx1
  7. jg_get_bitmap1
  8. jg_get_outline1
  9. mag_mode_2
  10. jg_get_metric2
  11. jg_get_fontbbx2
  12. jg_get_bitmap2
  13. get_outline2
  14. jg_get_font_prop
  15. JG_SetJG
  16. JG_GetJG
  17. debug_on

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

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