~ubuntu-branches/ubuntu/wily/vflib3/wily

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