src/drv_t1.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_Type1
- log_level
- add_file_search_path
- type1_create
- type1_close
- type1_get_metric1
- type1_get_fontbbx1
- type1_get_bitmap1
- type1_get_outline1
- type1_get_metric2
- type1_get_fontbbx2
- type1_get_bitmap2
- mag_factor
- type1_get_xxx
- type1_get_font_prop
- type1_debug
- type1_debug2
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)
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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,
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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)
/* [<][>][^][v][top][bottom][index][help] */
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*/