src/texfonts.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_TeX
- vf_tex_init
- syntax_check_resolution_corr
- tex_create
- vf_tex_try_map_and_open_font
- match_font_name
- decompose_filename
- try_open_mapped_font
- get_design_size_from_tfm
- tex_map_name
- vf_tex_syntax_check_font_mapping
- tex_close
- tex_get_metric1
- tex_get_fontbbx1
- tex_get_bitmap1
- tex_get_outline
- tex_get_metric2
- tex_get_fontbbx2
- tex_get_bitmap2
- tex_get_font_prop
- tex_query_font_type
- vf_tex_default_dpi
- vf_tex_fix_resolution
- vf_tex_search_file_tfm
- vf_tex_search_file_glyph
- vf_tex_search_file_misc
- vf_tex_parse_open_style
- vf_tex_parse_glyph_style
- vf_tex_read_uintn
- vf_tex_read_intn
- vf_tex_skip_n
- vf_tex_get_uintn
- vf_tex_get_intn
1 /*
2 * texfonts.c - Pseudo font class for TeX-related files (GF, PK, VF, TFM)
3 *
4 * 28 Sep 1996
5 * 25 Mar 1997 Added setting a program name for kpathsea by variable.
6 * 02 Apr 1997 Added support for .ofm files (Omega metrics file) (WL)
7 * 3 Jul 1997 Added Virtual Font support.
8 * 8 Aug 1997 for VFlib 3.3
9 * 1 Feb 1998 for VFlib 3.4
10 * 22 Jul 1998 Added TeX font mapping feafure.
11 * 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
12 * 16 Sep 1999 Modified TeX-font-mapper not to open TFM files as possible.
13 */
14 /*
15 * Copyright (C) 1996-1999 Hirotsugu Kakugawa.
16 * All rights reserved.
17 *
18 * This file is part of the VFlib Library. This library is free
19 * software; you can redistribute it and/or modify it under the terms of
20 * the GNU Library General Public License as published by the Free
21 * Software Foundation; either version 2 of the License, or (at your
22 * option) any later version. This library is distributed in the hope
23 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
24 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
25 * PURPOSE. See the GNU Library General Public License for more details.
26 * You should have received a copy of the GNU Library General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31 #include "config.h"
32 #include "with.h"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <ctype.h>
36 #ifdef HAVE_UNISTD_H
37 # include <unistd.h>
38 #endif
39 #include "VFlib-3_6.h"
40 #include "VFsys.h"
41 #include "vflibcap.h"
42 #include "consts.h"
43 #include "cache.h"
44 #include "bitmap.h"
45 #include "sexp.h"
46 #include "str.h"
47 #include "path.h"
48 #include "fsearch.h"
49 #include "texfonts.h"
50 #include "tfm.h"
51
52 Private SEXP_STRING default_tex_dpi = NULL;
53 Private int v_default_tex_dpi = DEFAULT_DPI;
54 Private SEXP_LIST default_fontdirs = NULL;
55 Private SEXP_LIST default_tfm_dirs = NULL;
56 Private SEXP_LIST default_tfm_extensions = NULL;
57 Private SEXP default_font_mapping = NULL;
58 Private SEXP default_resolution_corr = NULL;
59 Private SEXP default_resolution_accu = NULL;
60 Private double v_default_resolution_accu = DEFAULT_RESOLUTION_ACCU;
61 Private SEXP_STRING default_debug_mode = NULL;
62
63 Glocal SEXP_ALIST vf_tex_default_properties = NULL;
64 Glocal SEXP_ALIST vf_tex_default_variables = NULL;
65 Glocal int vf_dbg_drv_texfonts = 0;
66
67
68 Private int tex_create(VF_FONT,char*,char*,int,SEXP);
69 Private int syntax_check_resolution_corr(void);
70
71 Private int tex_create(VF_FONT font, char *font_class,
72 char *font_name, int implicit, SEXP entry);
73 Private int tex_close(VF_FONT font);
74 Private int tex_get_metric1(VF_FONT font, long code_point,
75 VF_METRIC1 metric1, double,double);
76 Private int tex_get_metric2(VF_FONT font, long code_point,
77 VF_METRIC2 metric2, double,double);
78 Private int tex_get_fontbbx1(VF_FONT,double,double,
79 double*,double*,double*,double*);
80 Private int tex_get_fontbbx2(VF_FONT,double,double,
81 int*,int*,int*,int*);
82 Private VF_BITMAP tex_get_bitmap1(VF_FONT,long,double,double);
83 Private VF_BITMAP tex_get_bitmap2(VF_FONT,long,double,double);
84 Private VF_OUTLINE tex_get_outline(VF_FONT,long,double,double);
85 Private char* tex_get_font_prop(VF_FONT,char*);
86 Private int tex_query_font_type(VF_FONT font, long code_point);
87
88
89 Private void tex_map_name(char *fontname, int n, char *mapping,
90 char *name_str, char *dpi_str, char *ext_str);
91 Private int try_open_mapped_font(SEXP s,
92 char *name_str, char *dpi_str,
93 char *ext_str, VF_FONT font,
94 char *name, double design_size,
95 SEXP tfm_dirs, SEXP tfm_extensions,
96 double opt_mag);
97 Private double get_design_size_from_tfm(char *font_name,
98 SEXP tfm_dirs, SEXP tfm_extensions);
99 Private int match_font_name(char *name, char *pat);
100 Private int decompose_filename(char*,char**,char**,char**,char**);
101
102
103
104
105 Glocal int
106 VF_Init_Driver_TeX(void)
/* [<][>][^][v][top][bottom][index][help] */
107 {
108 return vf_tex_init();
109 }
110
111
112 Glocal int
113 vf_tex_init(void)
/* [<][>][^][v][top][bottom][index][help] */
114 {
115 static int inited = 0;
116 struct s_capability_table ct[20];
117 int z;
118
119 z = 0;
120 /* VF_CAPE_FONT_DIRECTORIES */
121 ct[z].cap = VF_CAPE_FONT_DIRECTORIES;
122 ct[z].type = CAPABILITY_STRING_LIST0;
123 ct[z].ess = CAPABILITY_OPTIONAL;
124 ct[z++].val = &default_fontdirs;
125 /* VF_CAPE_DPI */
126 ct[z].cap = VF_CAPE_DPI;
127 ct[z].type = CAPABILITY_STRING;
128 ct[z].ess = CAPABILITY_OPTIONAL;
129 ct[z++].val = &default_tex_dpi;
130 /* VF_CAPE_TEX_TFM_DIRECTORIES */
131 ct[z].cap = VF_CAPE_TEX_TFM_DIRECTORIES;
132 ct[z].type = CAPABILITY_STRING_LIST0;
133 ct[z].ess = CAPABILITY_OPTIONAL;
134 ct[z++].val = &default_tfm_dirs;
135 /* VF_CAPE_TEX_TFM_EXTENSIONS */
136 ct[z].cap = VF_CAPE_TEX_TFM_EXTENSIONS;
137 ct[z].type = CAPABILITY_STRING_LIST0;
138 ct[z].ess = CAPABILITY_OPTIONAL;
139 ct[z++].val = &default_tfm_extensions;
140 /* VF_CAPE_TEX_FONT_MAPPING */
141 ct[z].cap = VF_CAPE_TEX_FONT_MAPPING;
142 ct[z].type = CAPABILITY_LIST;
143 ct[z].ess = CAPABILITY_OPTIONAL;
144 ct[z++].val = &default_font_mapping;
145 /* VF_CAPE_PROPERTIES */
146 ct[z].cap = VF_CAPE_PROPERTIES;
147 ct[z].type = CAPABILITY_ALIST;
148 ct[z].ess = CAPABILITY_OPTIONAL;
149 ct[z++].val = &vf_tex_default_properties;
150 /* VF_CAPE_VARIABLE_VALUES */
151 ct[z].cap = VF_CAPE_VARIABLE_VALUES;
152 ct[z].type = CAPABILITY_ALIST;
153 ct[z].ess = CAPABILITY_OPTIONAL;
154 ct[z++].val = &vf_tex_default_variables;
155 /* VF_CAPE_RESOLUTION_CORR */
156 ct[z].cap = VF_CAPE_RESOLUTION_CORR;
157 ct[z].type = CAPABILITY_LIST;
158 ct[z].ess = CAPABILITY_OPTIONAL;
159 ct[z++].val = &default_resolution_corr;
160 /* VF_CAPE_RESOLUTION_ACCU */
161 ct[z].cap = VF_CAPE_RESOLUTION_ACCU;
162 ct[z].type = CAPABILITY_STRING;
163 ct[z].ess = CAPABILITY_OPTIONAL;
164 ct[z++].val = &default_resolution_accu;
165 /* VF_CAPE_DEBUG */
166 ct[z].cap = VF_CAPE_DEBUG;
167 ct[z].type = CAPABILITY_STRING;
168 ct[z].ess = CAPABILITY_OPTIONAL;
169 ct[z++].val = &default_debug_mode;
170 /* end */
171 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
172
173
174 if (inited == 1)
175 return 0;
176 inited = 1;
177
178 if (getenv("VFLIB_DEBUG_TEXFONTS") != NULL)
179 vf_dbg_drv_texfonts = 1;
180
181 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_TeX, ct, NULL, NULL)
182 == VFLIBCAP_PARSED_ERROR)
183 return -1;
184
185 v_default_tex_dpi = DEFAULT_DPI;
186 if (default_tex_dpi != NULL)
187 v_default_tex_dpi = atoi(vf_sexp_get_cstring(default_tex_dpi));
188
189 if (default_tfm_extensions == NULL)
190 default_tfm_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_TFM);
191 vf_tfm_init();
192
193 if (default_resolution_corr != NULL){
194 if (syntax_check_resolution_corr() > 0){
195 vf_sexp_free(&default_resolution_corr);
196 fprintf(stderr,
197 "VFlib: value for capability %s is ignored.\n",
198 VF_CAPE_RESOLUTION_CORR);
199 }
200 }
201
202 v_default_resolution_accu = DEFAULT_RESOLUTION_ACCU;
203 if (default_resolution_accu != NULL){
204 v_default_resolution_accu
205 = atof(vf_sexp_get_cstring(default_resolution_accu));
206 if (v_default_resolution_accu <= 0)
207 v_default_resolution_accu = DEFAULT_RESOLUTION_ACCU;
208 }
209
210 if (default_font_mapping != NULL){
211 if (vf_tex_syntax_check_font_mapping(default_font_mapping) > 0){
212 vf_sexp_free(&default_font_mapping);
213 fprintf(stderr,
214 "VFlib: capability %s is ignored because of syntax error.\n",
215 VF_CAPE_TEX_FONT_MAPPING);
216 }
217 }
218
219 VF_InstallFontDriver(FONTCLASS_NAME_TeX, (DRIVER_FUNC_TYPE)tex_create);
220
221 return 0;
222 }
223
224 Private int
225 syntax_check_resolution_corr(void)
/* [<][>][^][v][top][bottom][index][help] */
226 {
227 int syntax_err, syntax_nerrs;
228 SEXP s, t, u;
229
230 syntax_nerrs = 0;
231
232 for (s = default_resolution_corr; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
233 syntax_err = 0;
234 u = t = vf_sexp_car(s);
235 /* e.g., u = (300 300 329 360 394 ...) */
236 if (!vf_sexp_listp(u)){
237 syntax_err = 1;
238 syntax_nerrs++;
239 goto rc_try_next;
240 }
241 for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
242 if (!vf_sexp_stringp(vf_sexp_car(u))
243 || (atoi(vf_sexp_get_cstring(vf_sexp_car(u))) <= 0)){
244 syntax_err = 1;
245 syntax_nerrs++;
246 goto rc_try_next;
247 }
248 }
249 rc_try_next:
250 if (syntax_err != 0){
251 fprintf(stderr,
252 "VFlib: %s in capability %s of %s font class default: \n",
253 "Syntax error", VF_CAPE_RESOLUTION_CORR, FONTCLASS_NAME_TeX);
254 vf_sexp_pp_fp(t, stderr);
255 }
256 }
257
258 return syntax_nerrs;
259 }
260
261
262
263 Private int
264 tex_create(VF_FONT font, char *font_class, char *font_name,
/* [<][>][^][v][top][bottom][index][help] */
265 int implicit, SEXP entry)
266 {
267 int fid;
268
269 if (implicit == 0){
270 vf_error = VF_ERR_NO_FONT_ENTRY;
271 return -1; /* this driver does not support explicit fonts. */
272 }
273
274 if (default_font_mapping == NULL){
275 vf_error = VF_ERR_NO_FONT_ENTRY;
276 return -1;
277 }
278
279 #if 1
280 fid = vf_tex_try_map_and_open_font(font, font_name, default_font_mapping,
281 -1, default_tfm_dirs,
282 default_tfm_extensions, 1.0);
283 #else
284 fid = vf_tex_try_map_and_open_font(font, font_name, default_font_mapping,
285 default_tfm_dirs,
286 NULL, default_tfm_extensions,
287 1.0);
288 #endif
289 if (fid < 0)
290 return -1;
291
292 font->font_type = VF_FONT_TYPE_UNDEF;
293 font->get_metric1 = tex_get_metric1;
294 font->get_metric2 = tex_get_metric2;
295 font->get_fontbbx1 = tex_get_fontbbx1;
296 font->get_fontbbx2 = tex_get_fontbbx2;
297 font->get_bitmap1 = tex_get_bitmap1;
298 font->get_bitmap2 = tex_get_bitmap2;
299 font->get_outline = tex_get_outline;
300 font->get_font_prop = tex_get_font_prop;
301 font->query_font_type = tex_query_font_type;
302 font->close = tex_close;
303
304 font->private = (void*)fid;
305
306 return 0;
307 }
308
309
310
311 Glocal int
312 vf_tex_try_map_and_open_font(VF_FONT font, char *font_name, SEXP font_mapping,
/* [<][>][^][v][top][bottom][index][help] */
313 double tfm_design_size,
314 SEXP tfm_dirs, SEXP tfm_extensions,
315 double opt_mag)
316 {
317 char *name_str, *dpi_str, *ext_str, *ns, *pat;
318 int fid;
319 SEXP s, t;
320
321 if (font_mapping == NULL){
322 vf_error = VF_ERR_NO_FONT_ENTRY;
323 return -1;
324 }
325
326 fid = -1;
327 name_str = dpi_str = ext_str = ns = NULL;
328
329 if (decompose_filename(font_name, &name_str, &dpi_str, &ext_str, &ns) < 0)
330 goto search_end;
331
332 for (s = font_mapping; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
333 for (t = vf_sexp_car(s);
334 vf_sexp_consp(t) && !vf_sexp_stringp(vf_sexp_car(t));
335 t = vf_sexp_cdr(t))
336 ; /* empty */
337 if (!vf_sexp_consp(t))
338 goto search_end;
339 while (vf_sexp_consp(t) && vf_sexp_stringp(vf_sexp_car(t))){
340 pat = vf_sexp_get_cstring(vf_sexp_car(t));
341 if ((strcmp(ns, pat) == 0) || (strcmp(pat, "*") == 0)
342 || (match_font_name(ns, pat) == 1)){
343 if ((fid = try_open_mapped_font(vf_sexp_car(s),
344 name_str, dpi_str, ext_str,
345 font, font_name,
346 tfm_design_size,
347 tfm_dirs, tfm_extensions,
348 opt_mag)) >= 0)
349 goto search_end;
350 }
351 t = vf_sexp_cdr(t);
352 }
353 }
354 if (fid < 0)
355 vf_error = VF_ERR_NO_FONT_ENTRY;
356
357 search_end:
358 vf_free(name_str);
359 vf_free(dpi_str);
360 vf_free(ext_str);
361
362 return fid;
363 }
364
365 Private int
366 match_font_name(char *name, char *patt)
/* [<][>][^][v][top][bottom][index][help] */
367 {
368 while (*name != '\0'){
369 if (*patt == '*'){
370 return 1;
371 } else {
372 if (*patt != *name)
373 return -1;
374 }
375 name++;
376 patt++;
377 }
378
379 if (*patt != '\0')
380 return -1;
381 return 0;
382 }
383
384 Private int
385 decompose_filename(char *font_name,
/* [<][>][^][v][top][bottom][index][help] */
386 char **name_str_p, char **dpi_str_p,
387 char **ext_str_p, char **ns_p)
388 {
389 int len, i, i0, i1, dellen;
390 char *name_str, *dpi_str, *ext_str, *ns;
391
392 name_str = dpi_str = ext_str = ns = NULL;
393
394 len = strlen(font_name);
395 for (i0 = len-1; i0 >= 0; i0--){
396 if (font_name[i0] == '.'){
397 /* "cmr10.360pk" ==> len=11
398 * name_str = "cmr10" i0=5
399 * dpi_str = "360" i1=9
400 * ext_str = "pk"
401 */
402 if ((name_str = (char*)malloc(i0+1)) == NULL){
403 vf_error = VF_ERR_NO_MEMORY;
404 goto end;
405 }
406 strncpy(name_str, font_name, i0);
407 name_str[i0] = '\0';
408 for (i1 = i0+1; isdigit((int)font_name[i1]); i1++)
409 ;
410 if ((dpi_str = (char*)malloc(i1-i0+1)) == NULL){
411 vf_error = VF_ERR_NO_MEMORY;
412 goto end;
413 }
414 strncpy(dpi_str, &font_name[i0+1], i1-i0-1);
415 dpi_str[i1-i0-1] = '\0';
416 if ((ext_str = (char*)malloc(strlen(&font_name[i1]+1))) == NULL){
417 vf_error = VF_ERR_NO_MEMORY;
418 goto end;
419 }
420 strcpy(ext_str, &font_name[i1]);
421 break;
422 }
423 }
424
425 if ((len > 0)
426 && (name_str == NULL) && (dpi_str == NULL) && (ext_str == NULL)){
427 if ((name_str = (char*)malloc(len+1)) == NULL){
428 vf_error = VF_ERR_NO_MEMORY;
429 goto end;
430 }
431 strcpy(name_str, font_name);
432 }
433
434
435 if (name_str == NULL){
436 if ((name_str = (char*)malloc(1)) == NULL){
437 vf_error = VF_ERR_NO_MEMORY;
438 goto end;
439 }
440 name_str[0] = '\0';
441 }
442 if (dpi_str == NULL){
443 if ((dpi_str = (char*)malloc(1)) == NULL){
444 vf_error = VF_ERR_NO_MEMORY;
445 goto end;
446 }
447 dpi_str[0] = '\0';
448 }
449 if (ext_str == NULL){
450 if ((ext_str = (char*)malloc(1)) == NULL){
451 vf_error = VF_ERR_NO_MEMORY;
452 goto end;
453 }
454 ext_str[0] = '\0';
455 }
456
457 dellen = strlen(vf_directory_delimiter);
458 if ((ns = name_str) != NULL){
459 for (i = strlen(name_str)-1; i >= 0; i--){
460 if (strncmp(&name_str[i], vf_directory_delimiter, dellen) == 0){
461 ns = &name_str[i+dellen];
462 break;
463 }
464 }
465 }
466 #if 0
467 printf("*** \"%s\" => \"%s\", \"%s\", \"%s\", \"%s\"\n",
468 font_name, name_str, ns, dpi_str, ext_str);
469 #endif
470
471 end:
472 if ((name_str == NULL) || (dpi_str == NULL) || (ext_str == NULL)){
473 vf_free(name_str);
474 vf_free(dpi_str);
475 vf_free(ext_str);
476 return -1;
477 }
478
479 *name_str_p = name_str;
480 *dpi_str_p = dpi_str;
481 *ext_str_p = ext_str;
482 *ns_p = ns;
483
484 return 0;
485 }
486
487 Private int
488 try_open_mapped_font(SEXP s, char *name_str, char *dpi_str, char *ext_str,
/* [<][>][^][v][top][bottom][index][help] */
489 VF_FONT font, char *font_name,
490 double tfm_design_size,
491 SEXP tfm_dirs, SEXP tfm_extensions,
492 double opt_mag)
493 {
494 SEXP t, u;
495 char *drvname, *mapping;
496 char mapped_name[1024];
497 int fid, dpix, dpiy;
498 double ptsize, mag_adj, mag_x, mag_y;
499
500 fid = -1;
501 for (fid = -1;
502 vf_sexp_consp(s) && vf_sexp_consp(vf_sexp_car(s));
503 s = vf_sexp_cdr(s)){
504
505 t = vf_sexp_car(s);
506 if ( !vf_sexp_listp(t)
507 || (vf_sexp_length(t) < 2)
508 || !vf_sexp_stringp(vf_sexp_car(t))
509 || !vf_sexp_stringp(vf_sexp_cadr(t)))
510 continue;
511
512 drvname = vf_sexp_get_cstring(vf_sexp_car(t));
513 mapping = vf_sexp_get_cstring(vf_sexp_cadr(t));
514
515 ptsize = font->point_size;
516 mag_adj = 1.0;
517 for (t = vf_sexp_cddr(t); vf_sexp_consp(t); t = vf_sexp_cdr(t)){
518 u = vf_sexp_car(t);
519 if (vf_sexp_stringp(u)){
520 if (strcmp(TEX_FONT_MAPPING_PTSIZE, vf_sexp_get_cstring(u)) == 0){
521 if (tfm_design_size > 0){
522 ptsize = tfm_design_size;
523 } else {
524 ptsize = get_design_size_from_tfm(font_name,
525 tfm_dirs, tfm_extensions);
526 }
527 if (ptsize < 0)
528 continue;
529 } else {
530 fprintf(stderr,
531 "VFlib: %s %s in capability %s for %s class default.\n",
532 "Unknown optional keyword", vf_sexp_get_cstring(u),
533 VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
534 }
535 } else if (vf_sexp_listp(u) && (vf_sexp_length(u) >= 2)){
536 if (vf_sexp_stringp(vf_sexp_car(u))
537 && vf_sexp_stringp(vf_sexp_cadr(u))
538 && (strcmp(TEX_FONT_MAPPING_MAG_ADJ,
539 vf_sexp_get_cstring(vf_sexp_car(u))) == 0)){
540 mag_adj = atof(vf_sexp_get_cstring(vf_sexp_cadr(u)));
541 if (mag_adj <= 0)
542 mag_adj = 1.0;
543 } else {
544 fprintf(stderr,
545 "VFlib: %s %s for %s class default: ",
546 "Unknown option in capability",
547 VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
548 vf_sexp_pp_fp(u, stderr);
549 }
550 }
551 }
552
553 mag_x = font->mag_x * opt_mag;
554 mag_y = font->mag_y * opt_mag;
555
556 tex_map_name(mapped_name, sizeof(mapped_name), mapping,
557 name_str, dpi_str, ext_str);
558 if (((dpix = font->dpi_x) <= 0) || ((dpiy = font->dpi_y) <= 0)){
559 dpix = v_default_tex_dpi;
560 dpiy = v_default_tex_dpi;
561 }
562 if (vf_dbg_drv_texfonts == 1){
563 printf(">> TeX font mapping: %s=>%s (driver:%s)\n",
564 font_name, mapped_name, drvname);
565 printf(">> pt:%.3f, dpi:%d,%d, mag:%.3f,%.3f, mag_adj=%.3f\n",
566 ptsize, dpix, dpiy, mag_x, mag_y, mag_adj);
567 }
568 if (strcmp(drvname, "*") != 0){
569 if (font->mode == 1){
570 fid = vf_openfont1(mapped_name, drvname, dpix, dpiy, ptsize,
571 mag_x * mag_adj, mag_y * mag_adj);
572 } else {
573 fid = vf_openfont2(mapped_name, drvname, font->pixel_size,
574 mag_x * mag_adj, mag_y * mag_adj);
575 }
576 } else {
577 if (font->mode == 1){
578 fid = VF_OpenFont1(mapped_name, dpix, dpiy, ptsize,
579 mag_x * mag_adj, mag_y * mag_adj);
580 } else {
581 fid = VF_OpenFont2(mapped_name, font->pixel_size,
582 mag_x * mag_adj, mag_y * mag_adj);
583 }
584 }
585
586 if (fid >= 0)
587 break;
588 }
589
590 return fid;
591 }
592
593 Private double
594 get_design_size_from_tfm(char *font_name, SEXP tfm_dirs, SEXP tfm_extensions)
/* [<][>][^][v][top][bottom][index][help] */
595 {
596 TFM tfm;
597 char *tfm_path;
598 double ds;
599
600 if (vf_dbg_drv_texfonts == 1)
601 printf(">> TeX font mapper: search TFM path for %s\n", font_name);
602 tfm_path = vf_tex_search_file_tfm(font_name, tfm_dirs, tfm_extensions);
603 if (vf_dbg_drv_texfonts == 1){
604 if (tfm_path != NULL){
605 printf(">> TeX font mapper: TFM path: %s\n", tfm_path);
606 } else {
607 printf(">> TeX font mapper: TFM not found: %s\n", font_name);
608 return -1;
609 }
610 }
611 if (tfm_path == NULL)
612 return -1;
613
614 if ((tfm = vf_tfm_open(tfm_path)) == NULL){
615 if (vf_dbg_drv_texfonts == 1)
616 printf(">> TeX font mapper: failed to open TFM: %s\n", tfm_path);
617 return -1;
618 }
619
620 ds = tfm->design_size;
621
622 vf_tfm_free(tfm);
623 vf_free(tfm_path);
624
625 return ds;
626 }
627
628 Private void
629 tex_map_name(char *mapped_name, int n, char *mapping,
/* [<][>][^][v][top][bottom][index][help] */
630 char *name_str, char *dpi_str, char *ext_str)
631 {
632 char *p, *s, *t;
633 int r;
634
635 p = mapping;
636 s = mapped_name;
637 r = n;
638 while (*p != '\0'){
639 if (r <= 0)
640 break;
641 if (*p != '%'){
642 *(s++) = *(p++);
643 r--;
644 } else {
645 p++;
646 switch (*p){
647 default:
648 *(s++) = *p;
649 r--;
650 break;
651 case '\0':
652 *(s++) = '\0';
653 r--;
654 break;
655 case 'f':
656 /* %f ... font name of requested font name (e.g., "cmr10") */
657 if (name_str == NULL)
658 break;
659 for (t = name_str; (*t != '\0') && (r > 0); r--)
660 *(s++) = *(t++);
661 break;
662 case 'd':
663 /* %d ... device resolution of requested font name (e.g., "300") */
664 if (dpi_str == NULL)
665 break;
666 for (t = dpi_str; (*t != '\0') && (r > 0); r--)
667 *(s++) = *(t++);
668 break;
669 case 'e':
670 /* %d ... font name extension of requested font name (e.g., "pk") */
671 if (ext_str == NULL)
672 break;
673 for (t = ext_str; (*t != '\0') && (r > 0); r--)
674 *(s++) = *(t++);
675 break;
676 }
677 p++;
678 }
679 }
680 *s = '\0';
681 }
682
683
684 Glocal int
685 vf_tex_syntax_check_font_mapping(SEXP font_mapping)
/* [<][>][^][v][top][bottom][index][help] */
686 {
687 int syntax_err, syntax_nerrs;
688 SEXP s, t, u, v;
689
690 syntax_nerrs = 0;
691 for (s = font_mapping; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
692 syntax_err = 0;
693 u = t = vf_sexp_car(s);
694 /* e.g., u = ((pk "%f.pk") (tfm "%f.tfm") "cmr10" "cmti10") */
695 for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
696 v = vf_sexp_car(u);
697 if (vf_sexp_stringp(v))
698 break;
699 if ( !vf_sexp_listp(v) || (vf_sexp_length(v) < 2)
700 || !vf_sexp_stringp(vf_sexp_car(v))
701 || !vf_sexp_stringp(vf_sexp_cadr(v)) ){
702 syntax_err = 1;
703 syntax_nerrs++;
704 goto fm_try_next;
705 }
706 }
707 /* e.g., u = ("cmr10" "cmti10") */
708 for ( ; vf_sexp_consp(u); u = vf_sexp_cdr(u)){
709 v = vf_sexp_car(u);
710 if (!vf_sexp_stringp(v)){
711 syntax_err = 1;
712 syntax_nerrs++;
713 goto fm_try_next;
714 }
715 }
716 fm_try_next:
717 if (syntax_err != 0){
718 fprintf(stderr,
719 "VFlib: %s in capability %s of %s font class default: \n",
720 "Syntax error", VF_CAPE_TEX_FONT_MAPPING, FONTCLASS_NAME_TeX);
721 vf_sexp_pp_fp(t, stderr);
722 }
723 }
724
725 return syntax_nerrs;
726 }
727
728
729
730 Private int
731 tex_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
732 {
733 return VF_CloseFont((int)font->private);
734 }
735
736 Private int
737 tex_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
738 double mag_x, double mag_y)
739 {
740 VF_METRIC1 met;
741
742 met = VF_GetMetric1((int)font->private, code_point, metric, mag_x, mag_y);
743 if (met == NULL)
744 return -1;
745 return 0;
746 }
747
748 Private int
749 tex_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
750 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
751 {
752 return VF_GetFontBoundingBox1((int)font->private,
753 mag_x, mag_y, w_p, h_p, xoff_p, yoff_p);
754 }
755
756 Private VF_BITMAP
757 tex_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
758 double mag_x, double mag_y)
759 {
760 return VF_GetBitmap1((int)font->private, code_point, mag_x, mag_y);
761 }
762
763 Private VF_OUTLINE
764 tex_get_outline(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
765 double mag_x, double mag_y)
766 {
767 return VF_GetOutline((int)font->private, code_point, mag_x, mag_y);
768 }
769
770 Private int
771 tex_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
772 double mag_x, double mag_y)
773 {
774 VF_METRIC2 met;
775
776 met = VF_GetMetric2((int)font->private, code_point, metric, mag_x, mag_y);
777 if (met == NULL)
778 return -1;
779 return 0;
780 }
781
782 Private int
783 tex_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
784 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
785 {
786 return VF_GetFontBoundingBox2((int)font->private,
787 mag_x, mag_y, w_p, h_p, xoff_p, yoff_p);
788 }
789
790 Private VF_BITMAP
791 tex_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
792 double mag_x, double mag_y)
793 {
794 return VF_GetBitmap2((int)font->private, code_point, mag_x, mag_y);
795 }
796
797 Private char*
798 tex_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
799 {
800 return VF_GetFontProp((int)font->private, prop_name);
801 }
802
803 Private int
804 tex_query_font_type(VF_FONT font, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
805 {
806 return VF_QueryFontType((int)font->private, code_point);
807 }
808
809
810
811
812
813 Glocal int
814 vf_tex_default_dpi(void)
/* [<][>][^][v][top][bottom][index][help] */
815 {
816 return v_default_tex_dpi;
817 }
818
819
820 Glocal int
821 vf_tex_fix_resolution(int dev_dpi, double mag)
/* [<][>][^][v][top][bottom][index][help] */
822 {
823 int mdpi, fixed_mdpi, d, dpi_lo, dpi_hi;
824 SEXP s, t;
825
826 if (dev_dpi <= 0)
827 dev_dpi = v_default_tex_dpi;
828
829 fixed_mdpi = mdpi = toint(dev_dpi * mag);
830
831 if (default_resolution_corr == NULL)
832 goto found;
833 for (s = default_resolution_corr; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
834 t = vf_sexp_car(s);
835 if (dev_dpi != atoi(vf_sexp_get_cstring(vf_sexp_car(t))))
836 continue;
837 for (t = vf_sexp_cdr(t); vf_sexp_consp(t); t = vf_sexp_cdr(t)){
838 if ((d = atoi(vf_sexp_get_cstring(vf_sexp_car(t)))) < 1)
839 continue;
840 if (d == mdpi)
841 goto found;
842 dpi_lo = (1.0 - v_default_resolution_accu) * d;
843 dpi_hi = (1.0 + v_default_resolution_accu) * d;
844 if ((dpi_lo <= mdpi) && (mdpi <= dpi_hi)){
845 fixed_mdpi = d;
846 goto found;
847 }
848 }
849 }
850
851 found:
852 if (vf_dbg_drv_texfonts == 1)
853 printf(">> TeX resolution correction: %d dpi x %f = %d ==> %d\n",
854 dev_dpi, mag, toint(mdpi), fixed_mdpi);
855
856 return fixed_mdpi;
857 }
858
859
860 Glocal char*
861 vf_tex_search_file_tfm(char *filename, SEXP dirs, SEXP exts)
/* [<][>][^][v][top][bottom][index][help] */
862 /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
863 {
864 char *name, *e, *path;
865 char target_name[1024];
866 SEXP s;
867
868 if (vf_dbg_drv_texfonts == 1)
869 printf(">> TeX file search tfm: %s\n", filename);
870
871 /* "cmr10.400pk" ==> "cmr10" */
872 if ((name = vf_path_base_core(filename)) == NULL)
873 return NULL;
874
875 if (dirs == NULL)
876 dirs = default_tfm_dirs;
877
878 if (exts == NULL)
879 exts = default_tfm_extensions;
880
881 path = NULL;
882 if (exts == NULL){
883 path = vf_search_file(name, -1, NULL, TRUE,
884 FSEARCH_FORMAT_TYPE_TFM, dirs, NULL, NULL);
885 } else {
886 for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
887 e = vf_sexp_get_cstring(vf_sexp_car(s));
888 if (*e == '.')
889 e = e+1; /* ".tfm" ==> "tfm" */
890 sprintf(target_name, "%s.%s", name, e); /* "cmr10" ==> "cmr10.tfm" */
891 if (vf_dbg_drv_texfonts == 1)
892 printf(">> TeX file search tfm: Checking %s\n", target_name);
893 path = vf_search_file(target_name, -1, NULL, TRUE,
894 FSEARCH_FORMAT_TYPE_TFM, dirs, NULL, NULL);
895 if (path != NULL)
896 break;
897 }
898 }
899 vf_free(name);
900 return path;
901 }
902
903 Glocal char*
904 vf_tex_search_file_glyph(char *filename, int implicit, int format,
/* [<][>][^][v][top][bottom][index][help] */
905 SEXP dirs, int dpi, double mag, SEXP exts)
906 {
907 SEXP s;
908 char *path, *corename, *e, target_name[1024];
909 int mdpi;
910
911 if (vf_dbg_drv_texfonts == 1){
912 printf(">> TeX file search glyph: %s\n", filename);
913 printf(">> dirs: ");
914 if (dirs != NULL)
915 vf_sexp_pp(dirs);
916 else
917 printf("null\n");
918 printf(">> exts: ");
919 if (exts != NULL)
920 vf_sexp_pp(exts);
921 else
922 printf("null\n");
923 }
924
925 if (exts == NULL)
926 return NULL;
927
928 mdpi = vf_tex_fix_resolution(dpi, mag);
929 #if 0
930 printf("*** %d %.14f %.14f %d\n", dpi, mag, dpi*mag, mdpi);
931 #endif
932
933 /* "cmr10.400pk" ==> "cmr10" */
934 if ((corename = vf_path_base_core(filename)) == NULL)
935 return NULL;
936 if (vf_dbg_drv_texfonts == 1)
937 printf(">> core: %s\n", corename);
938
939 path = NULL;
940 if (implicit == 1){
941 for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
942 e = vf_sexp_get_cstring(vf_sexp_car(s));
943 if (*e == '.')
944 e = e+1; /* ".pk" ==> "pk" */
945 sprintf(target_name, "%s.%d%s", corename, mdpi, e);
946 path = vf_search_file(target_name, mdpi, corename, TRUE,
947 format, dirs, NULL, NULL);
948 if (path != NULL)
949 break;
950 }
951 } else {
952 path = vf_search_file(filename, mdpi, corename, TRUE,
953 format, dirs, NULL, NULL);
954 }
955
956 vf_free(corename);
957 return path;
958 }
959
960 Glocal char*
961 vf_tex_search_file_misc(char *filename, int implicit, int format,
/* [<][>][^][v][top][bottom][index][help] */
962 SEXP dirs, SEXP exts)
963 {
964 SEXP s;
965 char *path, *corename, *e, target_name[1024];
966
967 if (vf_dbg_drv_texfonts == 1)
968 printf(">> TeX file search file: %s\n", filename);
969
970 path = NULL;
971 corename = NULL;
972 e = NULL;
973 if (implicit == 1){
974 corename = vf_path_base_core(filename); /* "cmr10.400pk" ==> "cmr10" */
975 for (s = exts; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
976 e = vf_sexp_get_cstring(vf_sexp_car(s));
977 if (*e == '.')
978 e = e+1; /* ".vf" ==> "vf" */
979 sprintf(target_name, "%s.%s", corename, e);
980 path = vf_search_file(target_name, 0, NULL,
981 TRUE, format, dirs, NULL, NULL);
982 if (path != NULL)
983 break;
984 }
985 } else {
986 path = vf_search_file(filename, 0, NULL, TRUE, format, dirs, NULL, NULL);
987 }
988
989 vf_free(corename);
990 return path;
991 }
992
993
994
995 Glocal int
996 vf_tex_parse_open_style(char *s, int def_value)
/* [<][>][^][v][top][bottom][index][help] */
997 {
998 int val;
999
1000 if (s == NULL)
1001 return def_value;
1002
1003 if (vf_strcmp_ci(s, TEX_OPEN_STYLE_REQUIRE_STR) == 0){
1004 val = TEX_OPEN_STYLE_REQUIRE;
1005 } else if (vf_strcmp_ci(s, TEX_OPEN_STYLE_TRY_STR) == 0){
1006 val = TEX_OPEN_STYLE_TRY;
1007 } else if (vf_strcmp_ci(s, TEX_OPEN_STYLE_NONE_STR) == 0){
1008 val = TEX_OPEN_STYLE_NONE;
1009 } else {
1010 fprintf(stderr,
1011 "VFlib Warning: Unknown open style: %s.\n", s);
1012 val = def_value;
1013 }
1014
1015 return val;
1016 }
1017
1018
1019 Glocal int
1020 vf_tex_parse_glyph_style(char *s, int def_value)
/* [<][>][^][v][top][bottom][index][help] */
1021 {
1022 int val;
1023
1024 if (s == NULL)
1025 return def_value;
1026
1027 if (vf_strcmp_ci(s, TEX_GLYPH_STYLE_EMPTY_STR) == 0){
1028 val = TEX_GLYPH_STYLE_EMPTY;
1029 } else if (vf_strcmp_ci(s, TEX_GLYPH_STYLE_FILL_STR) == 0){
1030 val = TEX_GLYPH_STYLE_FILL;
1031 } else {
1032 fprintf(stderr, "VFlib Warning: Unknown glyph stype: %s\n", s);
1033 val = def_value;
1034 }
1035
1036 return val;
1037 }
1038
1039
1040
1041
1042
1043 /*
1044 * Reading a Number from file
1045 */
1046 Glocal unsigned long
1047 vf_tex_read_uintn(FILE* fp, int size)
/* [<][>][^][v][top][bottom][index][help] */
1048 {
1049 unsigned long v;
1050
1051 v = 0L;
1052 while (size >= 1){
1053 v = v*256L + (unsigned long)getc(fp);
1054 --size;
1055 }
1056 return v;
1057 }
1058
1059 Glocal long
1060 vf_tex_read_intn(FILE* fp, int size)
/* [<][>][^][v][top][bottom][index][help] */
1061 {
1062 long v;
1063
1064 v = (long)getc(fp) & 0xffL;
1065 if (v & 0x80L)
1066 v = v - 256L;
1067 --size;
1068 while (size >= 1){
1069 v = v*256L + (unsigned long)getc(fp);
1070 --size;
1071 }
1072
1073 return v;
1074 }
1075
1076 Glocal void
1077 vf_tex_skip_n(FILE* fp, int size)
/* [<][>][^][v][top][bottom][index][help] */
1078 {
1079 while (size > 0){
1080 (void)getc(fp);
1081 --size;
1082 }
1083 }
1084
1085 Glocal unsigned long
1086 vf_tex_get_uintn(unsigned char *p, int size)
/* [<][>][^][v][top][bottom][index][help] */
1087 {
1088 unsigned long v;
1089
1090 v = 0L;
1091 while (size >= 1){
1092 v = v*256L + (unsigned long) *(p++);
1093 --size;
1094 }
1095
1096 return v;
1097 }
1098
1099 Glocal long
1100 vf_tex_get_intn(unsigned char *p, int size)
/* [<][>][^][v][top][bottom][index][help] */
1101 {
1102 long v;
1103
1104 v = (long)*(p++) & 0xffL;
1105 if (v & 0x80L)
1106 v = v - 256L;
1107 --size;
1108 while (size >= 1){
1109 v = v*256L + (unsigned long) *(p++);
1110 --size;
1111 }
1112
1113 return v;
1114 }
1115
1116
1117
1118 /*EOF*/