2
* drv_t1.c - A font driver for Type 1 fonts with t1ib library.
3
* by Hirotsugu Kakugawa
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.
17
* Copyright (C) 1998-2001 Hirotsugu Kakugawa.
18
* All rights reserved.
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.
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
49
#include <sys/param.h>
52
#include "VFlib-3_6.h"
67
Private VF_TABLE t1_free_table = NULL;
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"
111
typedef struct s_font_type1 *FONT_TYPE1;
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);
128
Private int log_level(SEXP s);
129
Private int add_file_search_path(int type, SEXP dirs);
132
#define LASTVAL_NONE -10000
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
147
typedef struct s_fontbbx1 *FONTBBX1;
152
typedef struct s_fontbbx2 *FONTBBX2;
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);
162
static int Initialized_t1lib = 0;
169
VF_Init_Driver_Type1(void)
172
struct s_capability_table ct[20];
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;
192
ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
193
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
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;
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;
213
ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
214
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
216
ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
218
if ((t1_free_table = vf_table_create()) == NULL){
219
vf_error = VF_ERR_NO_MEMORY;
223
if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL)
224
== VFLIBCAP_PARSED_ERROR)
227
env_debug_mode = getenv(DEBUG_ENV_NAME);
229
if (Initialized_t1lib == 0){
231
level = log_level(default_log_level);
232
T1_SetLogLevel(level);
233
ini_arg = ((level > 0) ? LOGFILE : NO_LOGFILE)
234
| IGNORE_CONFIGFILE | IGNORE_FONTDATABASE;
236
if (T1_InitLib(ini_arg) == NULL){
237
vf_error = VF_ERR_T1LIB_INIT;
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);
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));
256
Initialized_t1lib = 1;
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;
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;
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;
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;
290
VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)type1_create);
301
|| (!vf_sexp_stringp(s))
302
|| ((p = vf_sexp_get_cstring(s)) == NULL)){
306
if (vf_strcmp_ci(p, "") == 0)
308
if (vf_strncmp_ci(p, "NO", 2) == 0)
311
if (vf_strncmp_ci(p, "ERR", 3) == 0)
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)
324
add_file_search_path(int type, SEXP dirs)
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");
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);
347
&& (strcmp(p, "") != 0)
348
&& (strcmp(p, "TEXMF") != 0)
349
&& (strcmp(p, "KPATHSEA") != 0)
350
&& vf_path_directory_read_ok(p)){
352
printf("Path (%d): %s\n", type, p);
354
T1_AddToFileSearchPath(type, T1_APPEND_PATH, p);
357
dirs = vf_sexp_cdr(dirs);
366
type1_create(VF_FONT font, char *font_class, char *font_name,
367
int implicit, SEXP entry)
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;
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;
396
ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
397
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
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;
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;
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;
426
ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
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)
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;
444
font_file = NULL; /* list in 'cap_font' */
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;
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);
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)
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;
482
if (type1_debug('f'))
483
printf("VFlib Type1: font file %s\n ==> %s\n", font_file, font_path);
485
ALLOC_IF_ERR(font_type1, struct s_font_type1){
486
vf_error = VF_ERR_NO_MEMORY;
492
if ((font_type1->font_name = vf_strdup(font_name)) == NULL){
493
vf_error = VF_ERR_NO_MEMORY;
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;
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;
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));
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));
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));
545
if (type1_debug('f'))
546
printf("VFlib Type1: opening font: %s\n", font_name);
548
i = (t1_free_table->get_id_by_key)(t1_free_table,
549
font_type1->font_path,
550
strlen(font_type1->font_path)+1);
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);
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;
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;
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;
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);
593
font_type1->t1encvect = NULL;
594
if (T1_ReencodeFont(font_type1->t1fid, NULL) < 0){
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);
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);
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));
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;
624
if (type1_debug('t'))
625
printf("VFlib Type1: TFM path=%s\n", tfm_path);
626
font_type1->tfm = vf_tfm_open(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;
636
#if 1 /*** NO SUPPORT FOR CCV **/
637
font_type1->ccv_id = -1;
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);
646
font->private = font_type1;
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);
666
type1_close(VF_FONT font)
668
FONT_TYPE1 font_type1;
671
font_type1 = (FONT_TYPE1)font->private;
673
if (font_type1 != NULL){
674
if (font_type1->t1fid >= 0){
675
ALLOC_IF_ERR(ip, int){
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);
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);
703
type1_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
704
double mag_x, double mag_y)
706
if (type1_get_xxx(MODE_METRIC1, font, code_point, mag_x, mag_y,
707
metric, NULL, NULL, NULL) == NULL)
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)
717
struct s_fontbbx1 bbx1;
719
if (type1_get_xxx(MODE_FONTBBX1, font, -1, mag_x, mag_y,
720
NULL, NULL, &bbx1, NULL) == NULL)
732
type1_get_bitmap1(VF_FONT font, long code_point,
733
double mag_x, double mag_y)
737
FONT_TYPE1 font_type1;
738
struct vf_s_metric1 met;
743
bm = (VF_BITMAP)type1_get_xxx(MODE_BITMAP1, font, code_point, mag_x, mag_y,
744
NULL, NULL, NULL, NULL);
747
if (type1_get_xxx(MODE_METRIC1, font, code_point, mag_x, mag_y,
748
&met, NULL, NULL, NULL) == 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;
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;
770
type1_get_outline1(VF_FONT font, long code_point,
771
double mag_x, double mag_y)
775
ol = type1_get_xxx(MODE_OUTLINE, font, code_point, mag_x, mag_y,
776
NULL, NULL, NULL, NULL);
782
type1_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
783
double mag_x, double mag_y)
785
if (type1_get_xxx(MODE_METRIC2, font, code_point, mag_x, mag_y,
786
NULL, metric, NULL, NULL) == NULL)
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)
796
struct s_fontbbx2 bbx2;
798
if (type1_get_xxx(MODE_FONTBBX2, font, -1, mag_x, mag_y,
799
NULL, NULL, NULL, &bbx2) == NULL)
811
type1_get_bitmap2(VF_FONT font, long code_point,
812
double mag_x, double mag_y)
816
struct vf_s_metric2 met;
819
bm = (VF_BITMAP)type1_get_xxx(MODE_BITMAP2, font, code_point, mag_x, mag_y,
820
NULL, NULL, NULL, NULL);
823
if (type1_get_xxx(MODE_METRIC2, font, code_point, mag_x, mag_y,
824
NULL, &met, NULL, NULL) == NULL){
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;
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)
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);
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);
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)
866
FONT_TYPE1 font_type1;
871
int x, y, w, f_bbx_w, f_bbx_h, i;
873
T1_TMATRIX unity_matrix = {1.0, 0.0, 0.0, 1.0};
875
double ps = 0.0, ps0 = 0.0, mx, my, asp, dpix = 0.0, dpiy = 0.0;
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 };
884
* 0000 1000 0100 1100 0010 1010 0110 1110 exchanged
885
* 0001 1001 0101 1101 0011 1011 0111 1111
887
* 0000 0001 0010 0011 0100 0101 0110 0111 original
888
* 1000 1001 1010 1011 1100 1101 1110 1111
891
if ((font_type1 = (FONT_TYPE1)font->private) == NULL){
892
fprintf(stderr, "VFlib: internal error in type1_get_xxx() 1\n");
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;
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;
916
fprintf(stderr, "VFlib: internal error in type1_get_xxx() 2\n");
920
mag_factor(font, font_type1, mag_x, mag_y, ps0, &mx, &my, &asp, &ps);
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);
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;
945
if (type1_debug('r'))
946
printf("T1_SetDeviceResolutions %.3f %.3f\n", dpix, dpiy);
951
if ((mode == MODE_FONTBBX1) || (mode == MODE_FONTBBX2)){
954
if (font_type1->ccv_id < 0){
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);
963
if (type1_debug('m')){
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);
975
if ( (mode == MODE_BITMAP1)
976
|| (mode == MODE_BITMAP2)
977
|| (mode == MODE_OUTLINE) ){
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;
993
= t1_glyph->metrics.rightSideBearing-t1_glyph->metrics.leftSideBearing;
995
= t1_glyph->metrics.ascent - t1_glyph->metrics.descent;
997
if (t1_glyph->bits == NULL){
998
bm = vf_alloc_bitmap(bbxw, bbxh);
1000
ALLOC_IF_ERR(bm, struct vf_s_bitmap){
1001
vf_error = VF_ERR_NO_MEMORY;
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];
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;
1021
if ((mode == MODE_BITMAP1) || (mode == MODE_BITMAP2)){
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;
1031
f_bbx_w = font_bbox.urx - font_bbox.llx;
1032
f_bbx_h = font_bbox.ury - font_bbox.lly;
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);
1040
fprintf(stderr, "VFlib: internal error in type1_get_xxx() 3\n");
1044
} else if (mode == MODE_METRIC1){
1045
if (font_type1->tfm == NULL) {
1046
w = T1_GetCharWidth(font_type1->t1fid, (char)cp);
1048
vf_error = VF_ERR_NO_GLYPH;
1051
bbox = T1_GetCharBBox(font_type1->t1fid, (char)cp);
1052
if (metric1 != NULL){
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;
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);
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;
1079
if (metric1 != NULL)
1080
val = (void*) metric1;
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;
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;
1099
val = (void*) metric2;
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;
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;
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;
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;
1132
fprintf(stderr, "VFlib: internal error in type1_get_xxx() 4\n");
1133
fprintf(stderr, "Unknown mode: %d\n", mode);
1143
type1_get_font_prop(VF_FONT font, char *prop_name)
1144
{ /* CALLER MUST RELEASE RETURNED STRING LATER */
1146
FONT_TYPE1 font_type1;
1148
double dpix, dpiy, p;
1150
if ((font_type1 = (FONT_TYPE1)font->private) == NULL){
1151
fprintf(stderr, "VFlib: internal error in type1_get_font_prop()\n");
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)));
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);
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){
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);
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);
1226
if (strcmp(prop_name, "FONT_ASCENT") == 0){
1228
} else if (strcmp(prop_name, "FONT_DESCENT") == 0){
1238
Private int type1_debug2(char type, char *str);
1241
type1_debug(char type)
1247
if (env_debug_mode != NULL){
1248
if ((v = type1_debug2(type, env_debug_mode)) == TRUE)
1252
if (default_debug_mode == NULL)
1254
if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
1256
return type1_debug2(type, p0);
1260
type1_debug2(char type, char *p0)
1264
for (p = p0; *p != '\0'; p++){
1268
for (p = p0; *p != '\0'; p++){