2
* drv_vf.c - A font driver for vf (virtual font) format fonts.
3
* by Hirotsugu Kakugawa
5
* 30 Jan 1997 First implementation.
6
* 7 Aug 1997 VFlib 3.3 Changed API.
8
* 21 Apr 1998 Debugged get_font_prop().
9
* 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
10
* 16 Sep 1999 Bug fixed.
14
* Copyright (C) 1997-1999 Hirotsugu Kakugawa.
15
* All rights reserved.
17
* This file is part of the VFlib Library. This library is free
18
* software; you can redistribute it and/or modify it under the terms of
19
* the GNU Library General Public License as published by the Free
20
* Software Foundation; either version 2 of the License, or (at your
21
* option) any later version. This library is distributed in the hope
22
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
23
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
24
* PURPOSE. See the GNU Library General Public License for more details.
25
* You should have received a copy of the GNU Library General Public
26
* License along with this library; if not, write to the Free Software
27
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29
/* debug flag in vflibcap (debug capability):
30
* f - print font file path
31
* s - print subfont information
32
* d - trace dvi instruction execution
44
#include "VFlib-3_6.h"
73
typedef struct s_font_vf *FONT_VF;
76
Private SEXP_LIST default_fontdirs = NULL;
77
Private SEXP_LIST default_extensions = NULL;
78
Private SEXP_LIST default_tfm_dirs = NULL;
79
Private SEXP_LIST default_tfm_extensions = NULL;
80
Private SEXP default_font_mapping = NULL;
81
Private SEXP_STRING default_glyph_style = NULL;
82
Private int v_default_glyph_style = TEX_GLYPH_STYLE_DEFAULT;
83
Private SEXP_STRING default_open_style = NULL;
84
Private int v_default_open_style = TEX_OPEN_STYLE_DEFAULT;
85
Private SEXP_STRING default_point_size = NULL;
86
Private double v_default_point_size = -1;
87
Private SEXP_STRING default_pixel_size = NULL;
88
Private double v_default_pixel_size = -1;
89
Private SEXP_STRING default_dpi = NULL;
90
Private double v_default_dpi_x = DEFAULT_DPI;
91
Private double v_default_dpi_y = DEFAULT_DPI;
92
Private SEXP_ALIST default_properties = NULL;
93
Private SEXP_ALIST default_variables = NULL;
94
Private SEXP_STRING default_debug_mode = NULL;
97
Private int vf_create(VF_FONT,char*,char*,int,SEXP);
98
Private int vf_close(VF_FONT);
99
Private int vf_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
100
Private int vf_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
101
Private int vf_get_fontbbx1(VF_FONT,double,double,
102
double*,double*,double*,double*);
103
Private int vf_get_fontbbx2(VF_FONT,double,double,
104
int*,int*,int*,int*);
105
Private VF_BITMAP vf_get_bitmap1(VF_FONT,long,double,double);
106
Private VF_BITMAP vf_get_bitmap2(VF_FONT,long,double,double);
107
Private VF_OUTLINE vf_get_outline(VF_FONT,long,double,double);
108
Private char* vf_get_font_prop(VF_FONT,char*);
109
Private void calc_mag_2(VF_FONT,FONT_VF, double mag_x, double mag_y,
110
double *mx_p, double *my_p);
111
Private int vf_debug(char type);
113
Private int vf_vf_init(void);
114
Private int vf_vf_open(VF_FONT font, FONT_VF font_vf, int implicit);
115
Private void vf_vf_close(int);
116
Private VF_BITMAP vf_vf_get_bitmap(int,int,long,double,double,int,int);
117
Private int vf_vf_get_metric(int,long,VF_METRIC1,double*);
118
Private double vf_vf_get_design_size(int);
119
Private VF vf_vf_get_vf(int);
123
VF_Init_Driver_VF(void)
125
struct s_capability_table ct[20];
129
/* VF_CAPE_FONT_DIRECTORIES */
130
ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
131
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
132
/* VF_CAPE_EXTENSIONS */
133
ct[z].cap = VF_CAPE_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
134
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_extensions;
135
/* VF_CAPE_TEX_TFM_DIRECTORIES */
136
ct[z].cap = VF_CAPE_TEX_TFM_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
137
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_tfm_dirs;
138
/* VF_CAPE_TEX_TFM_EXTENSIONS */
139
ct[z].cap = VF_CAPE_TEX_TFM_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
140
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_tfm_extensions;
141
/* VF_CAPE_TEX_FONT_MAPPING */
142
ct[z].cap = VF_CAPE_TEX_FONT_MAPPING; ct[z].type = CAPABILITY_LIST;
143
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_font_mapping;
144
/* VF_CAPE_TEX_GLYPH_STYLE */
145
ct[z].cap = VF_CAPE_TEX_GLYPH_STYLE; ct[z].type = CAPABILITY_STRING;
146
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_glyph_style;
147
/* VF_CAPE_TEX_OPEN_STYLE */
148
ct[z].cap = VF_CAPE_TEX_OPEN_STYLE; ct[z].type = CAPABILITY_STRING;
149
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_open_style;
150
/* VF_CAPE_POINT_SIZE */
151
ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
152
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_point_size;
153
/* VF_CAPE_PIXEL_SIZE */
154
ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
155
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_pixel_size;
157
ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
158
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
159
/* VF_CAPE_PROPERTIES */
160
ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
161
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
162
/* VF_CAPE_VARIABLE_VALUES */
163
ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
164
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
166
ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
167
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
169
ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
172
if (vf_tex_init() < 0)
174
if (vf_tfm_init() < 0)
176
if (vf_vf_init() < 0)
179
if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_VF, ct,
180
vf_tex_default_variables, NULL)
181
== VFLIBCAP_PARSED_ERROR)
184
if (default_extensions == NULL)
185
default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_VF);
187
if (default_font_mapping != NULL){
188
if (vf_tex_syntax_check_font_mapping(default_font_mapping) > 0){
189
vf_sexp_free(&default_font_mapping);
191
"VFlib: capability %s is ignored because of syntax error.\n",
192
VF_CAPE_TEX_FONT_MAPPING);
196
v_default_glyph_style = TEX_GLYPH_STYLE_DEFAULT;
197
if (default_glyph_style != NULL)
198
v_default_glyph_style
199
= vf_tex_parse_glyph_style(vf_sexp_get_cstring(default_glyph_style),
200
TEX_GLYPH_STYLE_DEFAULT);
202
v_default_open_style = TEX_OPEN_STYLE_DEFAULT;
203
if (default_open_style != NULL)
205
= vf_tex_parse_open_style(vf_sexp_get_cstring(default_open_style),
206
TEX_OPEN_STYLE_DEFAULT);
208
if (default_point_size != NULL)
209
v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
211
if (default_pixel_size != NULL)
212
v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
214
v_default_dpi_x = DEFAULT_DPI;
215
v_default_dpi_y = DEFAULT_DPI;
216
if (default_dpi != NULL)
217
v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
220
VF_InstallFontDriver(FONTCLASS_NAME_VF, (DRIVER_FUNC_TYPE)vf_create);
227
vf_create(VF_FONT font, char *font_class,
228
char *font_name, int implicit, SEXP entry)
233
SEXP cap_ffile, cap_point, cap_pixel, cap_mag, cap_dpi, cap_props;
234
struct s_capability_table ct[10];
238
/* VF_CAPE_FONT_CLASS */
239
ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
240
ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
241
/* VF_CAPE_FONT_FILE */
242
ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING;
243
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_ffile;
244
/* VF_CAPE_POINT_SIZE */
245
ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
246
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
247
/* VF_CAPE_PIXEL_SIZE */
248
ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
249
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
251
ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
252
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
254
ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
255
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
256
/* VF_CAPE_PROPERTIES */
257
ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
258
ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
260
ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
266
if (implicit == 1){ /* implicit font */
267
font_file = font_name;
268
} else { /* explicit font */
269
if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
270
default_variables, vf_tex_default_variables)
271
== VFLIBCAP_PARSED_ERROR)
273
if (cap_ffile == NULL){
274
/* Use font name as font file name if font file name is not given. */
275
font_file = font_name;
277
font_file = vf_sexp_get_cstring(cap_ffile);
281
font->font_type = VF_FONT_TYPE_BITMAP;
282
font->get_metric1 = vf_get_metric1;
283
font->get_metric2 = vf_get_metric2;
284
font->get_fontbbx1 = vf_get_fontbbx1;
285
font->get_fontbbx2 = vf_get_fontbbx2;
286
font->get_bitmap1 = vf_get_bitmap1;
287
font->get_bitmap2 = vf_get_bitmap2;
288
font->get_outline = vf_get_outline;
289
font->get_font_prop = vf_get_font_prop;
290
font->query_font_type = NULL;
291
font->close = vf_close;
294
ALLOC_IF_ERR(font_vf, struct s_font_vf)
298
font_vf->font_name = NULL;
299
font_vf->font_file = NULL;
300
font_vf->open_style = v_default_open_style;
301
font_vf->glyph_style = v_default_glyph_style;
302
font_vf->point_size = v_default_point_size;
303
font_vf->pixel_size = v_default_pixel_size;
305
font_vf->dpi_x = v_default_dpi_x;
306
font_vf->dpi_y = v_default_dpi_y;
307
font_vf->props = NULL;
310
if (cap_point != NULL)
311
font_vf->point_size = atof(vf_sexp_get_cstring(cap_point));
312
if (cap_pixel != NULL)
313
font_vf->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
315
font_vf->dpi_x = font_vf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
317
font_vf->mag = atof(vf_sexp_get_cstring(cap_mag));
318
if (cap_props != NULL)
319
font_vf->props = cap_props;
322
if ((font_vf->font_file = vf_strdup(font_file)) == NULL)
324
if ((font_vf->font_name = vf_strdup(font_name)) == NULL)
327
if ((font_vf->vf_id = vf_vf_open(font, font_vf, implicit)) < 0)
330
font->private = font_vf;
337
vf_error = VF_ERR_NO_MEMORY;
339
if (font_vf != NULL){
340
vf_free(font_vf->font_name);
341
vf_free(font_vf->font_file);
342
vf_sexp_free1(&font_vf->props);
347
vf_sexp_free3(&cap_ffile, &cap_point, &cap_pixel);
348
vf_sexp_free2(&cap_mag, &cap_dpi);
356
vf_close(VF_FONT font)
360
font_vf = (FONT_VF)font->private;
361
if (font_vf != NULL){
362
vf_vf_close(font_vf->vf_id);
363
vf_free(font_vf->font_name);
364
vf_free(font_vf->font_file);
365
vf_sexp_free1(&font_vf->props);
374
vf_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
375
double mag_x, double mag_y)
378
double mx, my, ps, design_size;
381
fprintf(stderr, "VFlib internal error: in vf_get_metric1()\n");
384
if ((font_vf = (FONT_VF)font->private) == NULL){
385
fprintf(stderr, "VFlib internal error: in vf_get_metric1()\n");
389
if (vf_vf_get_metric(font_vf->vf_id, code_point, metric, &design_size) < 0)
392
if ((ps = font->point_size) < 0)
393
if ((ps = font_vf->point_size) < 0)
396
if ((ps < 0) || (design_size < 1.0e-3)){
397
mx = mag_x * font->mag_x * font_vf->mag;
398
my = mag_y * font->mag_y * font_vf->mag;
400
mx = mag_x * font->mag_x * font_vf->mag * (ps/design_size);
401
my = mag_y * font->mag_y * font_vf->mag * (ps/design_size);
404
metric->bbx_width *= mx;
405
metric->bbx_height *= my;
415
vf_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
416
double *w_p, double *h_p, double *xoff_p, double *yoff_p)
420
double mx, my, ps, design_size;
422
if ((font_vf = (FONT_VF)font->private) == NULL){
423
fprintf(stderr, "VFlib internal error: in vf_get_fontbbx1()\n");
427
if (vf_vf_get_metric(font_vf->vf_id, -1, NULL, &design_size) < 0)
430
if ((ps = font->point_size) < 0)
431
if ((ps = font_vf->point_size) < 0)
434
if ((ps < 0) || (design_size < 1.0e-3)){
435
mx = mag_x * font->mag_x * font_vf->mag;
436
my = mag_y * font->mag_y * font_vf->mag;
438
mx = mag_x * font->mag_x * font_vf->mag * (ps/design_size);
439
my = mag_y * font->mag_y * font_vf->mag * (ps/design_size);
442
vf = vf_vf_get_vf(font_vf->vf_id);
444
*w_p = vf->tfm->font_bbx_w * mx;
445
*h_p = vf->tfm->font_bbx_h * my;
446
*xoff_p = vf->tfm->font_bbx_xoff * mx;
447
*yoff_p = vf->tfm->font_bbx_yoff * my;
454
vf_get_bitmap1(VF_FONT font, long code_point,
455
double mag_x, double mag_y)
458
double ps, mx, my, design_size;
460
if ((font_vf = (FONT_VF)font->private) == NULL){
461
fprintf(stderr, "VFlib internal error in vf_get_bitmap1()\n");
465
design_size = vf_vf_get_design_size(font_vf->vf_id);
467
if ((ps = font->point_size) < 0)
468
if ((ps = font_vf->point_size) < 0)
471
if ((ps < 0) || (design_size < 1.0e-3)){
472
/* Note: font->mag_x and font_vf->mag are already used to select
473
scaled glyph, e.g., cmr10.360gf for 300dpi with mag 1.2. */
477
mx = mag_x * (ps/design_size);
478
my = mag_y * (ps/design_size);
481
return vf_vf_get_bitmap(font_vf->vf_id, font->mode, code_point, mx, my,
482
font_vf->open_style, font_vf->glyph_style);
487
vf_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
488
double mag_x, double mag_y)
493
fprintf(stderr, "VFlib internal error: in vf_get_metric2()\n");
497
bm = vf_get_bitmap2(font, code_point, mag_x, mag_y);
501
metric->bbx_width = bm->bbx_width;
502
metric->bbx_height = bm->bbx_height;
503
metric->off_x = bm->off_x;
504
metric->off_y = bm->off_y;
505
metric->mv_x = bm->mv_x;
506
metric->mv_y = bm->mv_y;
514
vf_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
515
int *w_p, int *h_p, int *xoff_p, int *yoff_p)
521
if ((font_vf = (FONT_VF)font->private) == NULL){
522
fprintf(stderr, "VFlib internal error: in vf_get_fontbbx2()\n");
526
vf = vf_vf_get_vf(font_vf->vf_id);
527
calc_mag_2(font, font_vf, mag_x, mag_y, &mx, &my);
529
*w_p = toint(vf->tfm->font_bbx_w * mx);
530
*h_p = toint(vf->tfm->font_bbx_h * my);
531
*xoff_p = toint(vf->tfm->font_bbx_xoff * mx);
532
*yoff_p = toint(vf->tfm->font_bbx_yoff * my);
539
vf_get_bitmap2(VF_FONT font, long code_point,
540
double mag_x, double mag_y)
545
if ((font_vf = (FONT_VF)font->private) == NULL){
546
fprintf(stderr, "VFlib internal error in vf_get_bitmap2()\n");
550
calc_mag_2(font, font_vf, mag_x, mag_y, &mx, &my);
552
return vf_vf_get_bitmap(font_vf->vf_id, font->mode, code_point, mx, my,
553
font_vf->open_style, font_vf->glyph_style);
558
calc_mag_2(VF_FONT font, FONT_VF font_vf, double mag_x, double mag_y,
559
double *mx_p, double *my_p)
561
double design_size, dpi_x, dpi_y, ps;
563
design_size = vf_vf_get_design_size(font_vf->vf_id);
565
if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
566
if (((dpi_x = font_vf->dpi_x) < 0) || ((dpi_y = font_vf->dpi_y) < 0)){
567
dpi_x = vf_tex_default_dpi();
568
dpi_y = vf_tex_default_dpi();
572
if ((ps = font->point_size) < 0)
573
if ((ps = font_vf->point_size) < 0)
577
/* Note: font->mag_x and font_vf->mag are already used to select
578
scaled glyph, e.g., cmr10.360gf for 300dpi with mag 1.2. */
582
*mx_p = mag_x * (ps*72.27)/(design_size*dpi_x);
583
*my_p = mag_y * (ps*72.27)/(design_size*dpi_y);
589
vf_get_outline(VF_FONT font, long code_point,
590
double mag_x, double mag_y)
592
vf_error = VF_ERR_NOT_SUPPORTED_OP;
599
vf_get_font_prop(VF_FONT font, char *prop_name)
602
double dpi_x, dpi_y, ps, design_size;
606
if ((font_vf = (FONT_VF)font->private) == NULL){
607
fprintf(stderr, "VFlib internal error: vf_get_font_prop()\n");
611
if ((v = vf_sexp_assoc(prop_name, font_vf->props)) != NULL){
612
return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
613
} else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
614
return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
617
if (((dpi_x = font->dpi_x)<=0) || ((dpi_y = font->dpi_y)<=0)){
618
if (((dpi_x = font_vf->dpi_x)<=0) || ((dpi_y = font_vf->dpi_y)<=0)){
619
dpi_x = vf_tex_default_dpi();
620
dpi_y = vf_tex_default_dpi();
623
design_size = vf_vf_get_design_size(font_vf->vf_id);
625
if (font->mode == 1){
626
if ((ps = font->point_size) < 0)
627
if ((ps = font_vf->point_size) < 0)
629
ps = ps * font->mag_y * font_vf->mag;
630
if (strcmp(prop_name, "POINT_SIZE") == 0){
631
sprintf(str, "%d", toint(ps * 10.0));
632
return vf_strdup(str);
633
} else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
634
sprintf(str, "%d", toint(ps * dpi_y / 72.27));
635
return vf_strdup(str);
636
} else if (strcmp(prop_name, "RESOLUTION_X") == 0){
637
sprintf(str, "%d", toint(dpi_x));
638
return vf_strdup(str);
639
} else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
640
sprintf(str, "%d", toint(dpi_y));
641
return vf_strdup(str);
643
} else if (font->mode == 2){
644
if (strcmp(prop_name, "POINT_SIZE") == 0){
645
if ((ps = font->pixel_size) < 0){
646
if ((ps = font_vf->pixel_size) < 0){
647
sprintf(str, "%d", toint(design_size * 10.0
648
* font->mag_y * font_vf->mag));
649
return vf_strdup(str);
652
ps = ps * font->mag_y * font_vf->mag;
653
sprintf(str, "%d", toint(ps * 10.0 * 72.27 / dpi_y));
654
return vf_strdup(str);
655
} else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
656
if ((ps = font->pixel_size) < 0)
657
if ((ps = font_vf->pixel_size) < 0)
658
ps = design_size * dpi_y / 72.27;
659
ps = ps * font->mag_y * font_vf->mag;
660
sprintf(str, "%d", toint(ps));
661
return vf_strdup(str);
662
} else if (strcmp(prop_name, "RESOLUTION_X") == 0){
663
sprintf(str, "%d", toint(dpi_x));
664
return vf_strdup(str);
665
} else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
666
sprintf(str, "%d", toint(dpi_y));
667
return vf_strdup(str);
685
if (default_debug_mode == NULL)
687
if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
690
for (p = p0; *p != '\0'; p++){
694
for (p = p0; *p != '\0'; p++){