src/drv_tfm.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_TFM
- tfm_create
- tfm_close
- tfm_get_metric1
- tfm_get_fontbbx1
- tfm_get_bitmap1
- tfm_get_outline
- tfm_get_metric2
- tfm_get_fontbbx2
- tfm_get_bitmap2
- tfm_get_font_prop
1 /*
2 * drv_tfm.c - A font driver for TFM fonts.
3 *
4 * 30 Sep 1996 First version.
5 * 17 Jan 1997 for VFlib 3.1
6 * 24 Feb 1997 Changed metric computation.
7 * 26 Feb 1997 Added 'query_font_type'.
8 * 4 Aug 1997 VFlib 3.3 Changed API.
9 * 1 Feb 1998 for VFlib 3.4
10 * 21 Apr 1998 Debugged get_font_prop().
11 */
12 /*
13 * Copyright (C) 1996-1998 by Hirotsugu Kakugawa.
14 * All rights reserved.
15 *
16 * This file is part of the VFlib Library. This library is free
17 * software; you can redistribute it and/or modify it under the terms of
18 * the GNU Library General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at your
20 * option) any later version. This library is distributed in the hope
21 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23 * PURPOSE. See the GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29 #include "config.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 #include <ctype.h>
36 #include "VFlib-3_6.h"
37 #include "VFsys.h"
38 #include "vflibcap.h"
39 #include "sexp.h"
40 #include "cache.h"
41 #include "bitmap.h"
42 #include "str.h"
43 #include "path.h"
44 #include "fsearch.h"
45 #include "texfonts.h"
46 #include "tfm.h"
47
48
49
50 struct s_font_tfm {
51 TFM tfm;
52 char *font_name;
53 char *font_file;
54 double point_size;
55 double pixel_size;
56 int glyph_style;
57 double mag;
58 double aspect;
59 double dpi_x, dpi_y;
60 SEXP props;
61 double extra_mag;
62 };
63 typedef struct s_font_tfm *FONT_TFM;
64
65
66 Private SEXP_LIST default_fontdirs;
67 Private SEXP_LIST default_extensions;
68 Private SEXP_STRING default_glyph_style;
69 Private int v_default_glyph_style;
70 Private SEXP_STRING default_point_size;
71 Private double v_default_point_size;
72 Private SEXP_STRING default_pixel_size;
73 Private double v_default_pixel_size;
74 Private SEXP_STRING default_dpi;
75 Private double v_default_dpi_x, v_default_dpi_y;
76 Private SEXP_STRING default_aspect;
77 Private double v_default_aspect;
78 Private SEXP_ALIST default_properties;
79 Private SEXP_ALIST default_variables;
80 Private SEXP_STRING default_debug_mode;
81
82
83 Private int tfm_create(VF_FONT,char*,char*,int,SEXP);
84 Private int tfm_close(VF_FONT);
85 Private int tfm_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
86 Private int tfm_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
87 Private int tfm_get_fontbbx1(VF_FONT,double,double,
88 double*,double*,double*,double*);
89 Private int tfm_get_fontbbx2(VF_FONT,double,double,
90 int*,int*,int*,int*);
91 Private VF_BITMAP tfm_get_bitmap1(VF_FONT,long,double,double);
92 Private VF_BITMAP tfm_get_bitmap2(VF_FONT,long,double,double);
93 Private VF_OUTLINE tfm_get_outline(VF_FONT,long,double,double);
94 Private char* tfm_get_font_prop(VF_FONT,char*);
95
96
97
98 Public int
99 VF_Init_Driver_TFM(void)
/* [<][>][^][v][top][bottom][index][help] */
100 {
101 struct s_capability_table ct[20];
102 int z;
103
104 z = 0;
105 /* VF_CAPE_FONT_DIRECTORIES */
106 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
107 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
108 /* VF_CAPE_EXTENSIONS */
109 ct[z].cap = VF_CAPE_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
110 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_extensions;
111 /* VF_CAPE_TEX_GLYPH_STYLE */
112 ct[z].cap = VF_CAPE_TEX_GLYPH_STYLE; ct[z].type = CAPABILITY_STRING;
113 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_glyph_style;
114 /* VF_CAPE_POINT_SIZE */
115 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
116 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_point_size;
117 /* VF_CAPE_PIXEL_SIZE */
118 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
119 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_pixel_size;
120 /* VF_CAPE_DPI */
121 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
122 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
123 /* VF_CAPE_ASPECT_RATIO */
124 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
125 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_aspect;
126 /* VF_CAPE_PROPERTIES */
127 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
128 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
129 /* VF_CAPE_VARIABLE_VALUES */
130 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
131 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
132 /* VF_CAPE_DEBUG */
133 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
134 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
135 /* end */
136 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
137
138
139 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_TFM, ct,
140 vf_tex_default_variables, NULL)
141 == VFLIBCAP_PARSED_ERROR)
142 return -1;
143
144 if (default_extensions == NULL)
145 default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_TFM);
146
147 v_default_glyph_style = TEX_GLYPH_STYLE_EMPTY;
148 if (default_glyph_style != NULL)
149 v_default_glyph_style
150 = vf_tex_parse_glyph_style(vf_sexp_get_cstring(default_glyph_style),
151 TEX_GLYPH_STYLE_EMPTY);
152
153 v_default_point_size = -1;
154 if (default_point_size != NULL)
155 v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
156
157 v_default_pixel_size = -1;
158 if (default_pixel_size != NULL)
159 v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
160
161 v_default_dpi_x = -1;
162 v_default_dpi_y = -1;
163 if (default_dpi != NULL)
164 v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
165
166 v_default_aspect = 1.0;
167 if (default_aspect != NULL)
168 v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
169
170 vf_tex_init();
171 vf_tfm_init();
172
173 VF_InstallFontDriver(FONTCLASS_NAME_TFM, (DRIVER_FUNC_TYPE)tfm_create);
174
175 return 0;
176 }
177
178 Private int
179 tfm_create(VF_FONT font, char *font_class,
/* [<][>][^][v][top][bottom][index][help] */
180 char *font_name, int implicit, SEXP entry)
181 {
182 FONT_TFM font_tfm;
183 char *font_file, *tfm_path, *p;
184 int dev_dpi;
185 SEXP cap_ffile, cap_glyph_style, cap_point, cap_pixel;
186 SEXP cap_dpi, cap_mag, cap_aspect, cap_props;
187 struct s_capability_table ct[20];
188 int z;
189
190 z = 0;
191 /* VF_CAPE_FONT_CLASS */
192 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
193 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
194 /* VF_CAPE_FONT_FILE */
195 ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING;
196 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_ffile;
197 /* VF_CAPE_TEX_GLYPH_STYLE */
198 ct[z].cap = VF_CAPE_TEX_GLYPH_STYLE; ct[z].type = CAPABILITY_STRING;
199 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_glyph_style;
200 /* VF_CAPE_POINT_SIZE */
201 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
202 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
203 /* VF_CAPE_PIXEL_SIZE */
204 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
205 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
206 /* VF_CAPE_DPI */
207 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
208 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
209 /* VF_CAPE_MAG */
210 ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
211 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
212 /* VF_CAPE_ASPECT_RATIO */
213 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
214 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_aspect;
215 /* VF_CAPE_PROPERTIES */
216 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
217 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
218 /* end */
219 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
220
221
222 if (implicit == 1){ /* implicit font */
223 font_file = font_name;
224 } else { /* explicit font */
225 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
226 default_variables, vf_tex_default_variables)
227 == VFLIBCAP_PARSED_ERROR)
228 return -1;
229 if (cap_ffile == NULL){
230 /* Use font name as font file name if font file name is not given. */
231 font_file = font_name;
232 } else {
233 font_file = vf_sexp_get_cstring(cap_ffile);
234 }
235 }
236
237 font->font_type = VF_FONT_TYPE_BITMAP;
238 font->get_metric1 = tfm_get_metric1;
239 font->get_metric2 = tfm_get_metric2;
240 font->get_fontbbx1 = tfm_get_fontbbx1;
241 font->get_fontbbx2 = tfm_get_fontbbx2;
242 font->get_bitmap1 = tfm_get_bitmap1;
243 font->get_bitmap2 = tfm_get_bitmap2;
244 font->get_outline = tfm_get_outline;
245 font->get_font_prop = tfm_get_font_prop;
246 font->query_font_type = NULL;
247 font->close = tfm_close;
248
249 tfm_path = NULL;
250 font_tfm = NULL;
251 ALLOC_IF_ERR(font_tfm, struct s_font_tfm)
252 goto NoMemoryError;
253 font->private = font_tfm;
254
255 font_tfm->tfm = NULL;
256 font_tfm->font_name = NULL;
257 font_tfm->font_file = NULL;
258 font_tfm->point_size = v_default_point_size;
259 font_tfm->pixel_size = v_default_pixel_size;
260 font_tfm->glyph_style= v_default_glyph_style;
261 font_tfm->dpi_x = v_default_dpi_x;
262 font_tfm->dpi_y = v_default_dpi_y;
263 font_tfm->mag = 1.0;
264 font_tfm->aspect = v_default_aspect;
265 font_tfm->props = NULL;
266
267 if (implicit == 0){
268 if (cap_point != NULL)
269 font_tfm->point_size = atof(vf_sexp_get_cstring(cap_point));
270 if (cap_pixel != NULL)
271 font_tfm->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
272 if (cap_glyph_style != NULL){
273 if (strcmp(vf_sexp_get_cstring(cap_glyph_style),
274 TEX_GLYPH_STYLE_EMPTY_STR) == 0)
275 font_tfm->glyph_style = TEX_GLYPH_STYLE_EMPTY;
276 else if (strcmp(vf_sexp_get_cstring(cap_glyph_style),
277 TEX_GLYPH_STYLE_FILL_STR) == 0)
278 font_tfm->glyph_style = TEX_GLYPH_STYLE_FILL;
279 }
280 if (cap_dpi != NULL)
281 font_tfm->dpi_x = font_tfm->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
282 if (cap_mag != NULL)
283 font_tfm->mag = atof(vf_sexp_get_cstring(cap_mag));
284 if (cap_aspect != NULL)
285 font_tfm->aspect = atof(vf_sexp_get_cstring(cap_aspect));
286 if (cap_props != NULL)
287 font_tfm->props = cap_props;
288 }
289
290 if ((font_tfm->font_file = vf_strdup(font_file)) == NULL)
291 goto NoMemoryError;
292 if ((font_tfm->font_name = vf_strdup(font_name)) == NULL)
293 goto NoMemoryError;
294
295
296 /* Parse font name. Formats of file names that this routine supports:
297 * "cmr10.300XX" - A "cmr10" font for 300 dpi.
298 * "cmr10.XX" - A "cmr10" font. Dpi value is default value.
299 * "cmr10" - ditto.
300 * ("XX" can be any string such as "pk", "gf", and "tfm".)
301 */
302 p = vf_index(font_tfm->font_file, '.');
303 if ((p != NULL) && (isdigit((int)*(p+1)))){ /* "cmr10.300tfm" */
304 dev_dpi = atoi(p+1);
305 if ((font_tfm->dpi_x < 0) || (font_tfm->dpi_y < 0)){
306 font_tfm->dpi_x = (double)dev_dpi;
307 font_tfm->dpi_y = (double)dev_dpi;
308 }
309 } else { /* "cmr10" or "cmr10.tfm" */
310 ;
311 }
312
313 tfm_path = vf_tex_search_file_tfm(font_tfm->font_file,
314 default_fontdirs, default_extensions);
315 #if 0
316 printf("* TFM: %s ==> %s\n", font_name, tfm_path);
317 #endif
318 if (tfm_path == NULL)
319 goto Error;
320
321 font_tfm->tfm = vf_tfm_open(tfm_path);
322 vf_free(tfm_path);
323 if (font_tfm->tfm == NULL)
324 goto Error;
325
326 if (implicit == 0){
327 vf_sexp_free2(&cap_ffile, &cap_glyph_style);
328 vf_sexp_free2(&cap_point, &cap_pixel);
329 vf_sexp_free3(&cap_dpi, &cap_mag, &cap_aspect);
330 }
331
332 return 0;
333
334
335 NoMemoryError:
336 vf_error = VF_ERR_NO_MEMORY;
337 Error:
338 if (implicit == 0){
339 vf_sexp_free2(&cap_ffile, &cap_glyph_style);
340 vf_sexp_free2(&cap_point, &cap_pixel);
341 vf_sexp_free3(&cap_dpi, &cap_mag, &cap_aspect);
342 }
343 tfm_close(font);
344 return -1;
345 }
346
347
348 Private int
349 tfm_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
350 {
351 FONT_TFM font_tfm;
352
353 font_tfm = (FONT_TFM)font->private;
354 if (font_tfm != NULL){
355 vf_tfm_free(font_tfm->tfm);
356 vf_free(font_tfm->font_name);
357 vf_free(font_tfm->font_file);
358 vf_sexp_free1(&font_tfm->props);
359 vf_free(font_tfm);
360 }
361
362 return 0;
363 }
364
365 Private int
366 tfm_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
367 double mag_x, double mag_y)
368 {
369 FONT_TFM font_tfm;
370 TFM tfm;
371 double mx, my, ps, f;
372
373 if ( (metric == NULL)
374 || ((font_tfm = (FONT_TFM)font->private) == NULL)
375 || ((tfm = font_tfm->tfm) == NULL) ){
376 fprintf(stderr, "VFlib internal error: tfm_get_metric1()\n");
377 abort();
378 }
379
380 if (vf_tfm_metric(tfm, code_point, metric) == NULL)
381 return -1;
382
383 if ((ps = font->point_size) < 0)
384 if ((ps = font_tfm->point_size) < 0)
385 ps = -1;
386
387 if ((ps < 0) || (tfm->design_size < 1.0e-3)){
388 mx = mag_x * font->mag_x * font_tfm->mag;
389 my = mag_y * font->mag_y * font_tfm->mag;
390 } else {
391 f = ps / tfm->design_size;
392 mx = mag_x * font->mag_x * font_tfm->mag * f;
393 my = mag_y * font->mag_y * font_tfm->mag * f;
394 }
395
396 metric->bbx_width *= mx;
397 metric->bbx_height *= my;
398 metric->off_x *= mx;
399 metric->off_y *= my;
400 metric->mv_x *= mx;
401 metric->mv_y *= my;
402
403 return 0;
404 }
405
406 Private int
407 tfm_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
408 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
409 {
410 FONT_TFM font_tfm;
411 TFM tfm;
412 double mx, my, ps, f;
413
414 if (((font_tfm = (FONT_TFM)font->private) == NULL)
415 || ((tfm = font_tfm->tfm) == NULL) ){
416 fprintf(stderr, "VFlib internal error: tfm_get_fontbbx1()\n");
417 abort();
418 }
419
420 if ((ps = font->point_size) < 0)
421 if ((ps = font_tfm->point_size) < 0)
422 ps = -1;
423
424 if ((ps < 0) || (tfm->design_size < 1.0e-3)){
425 mx = mag_x * font->mag_x * font_tfm->mag;
426 my = mag_y * font->mag_y * font_tfm->mag;
427 } else {
428 f = ps / tfm->design_size;
429 mx = mag_x * font->mag_x * font_tfm->mag * f;
430 my = mag_y * font->mag_y * font_tfm->mag * f;
431 }
432
433 *w_p = tfm->font_bbx_w * mx;
434 *h_p = tfm->font_bbx_h * my;
435 *xoff_p = tfm->font_bbx_xoff * mx;
436 *yoff_p = tfm->font_bbx_yoff * my;
437
438 return 0;
439 }
440
441 Private VF_BITMAP
442 tfm_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
443 double mag_x, double mag_y)
444 {
445 FONT_TFM font_tfm;
446 VF_BITMAP bm;
447 double dpi_x, dpi_y;
448 struct vf_s_metric1 met;
449
450 if ((font_tfm = (FONT_TFM)font->private) == NULL){
451 fprintf(stderr, "VFlib internal error: tfm_get_bitmap1()\n");
452 abort();
453 }
454
455 if (tfm_get_metric1(font, code_point, &met, mag_x, mag_y) < 0)
456 return NULL;
457
458 if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
459 if (((dpi_x = font_tfm->dpi_x) < 0) || ((dpi_y = font_tfm->dpi_y) < 0)){
460 dpi_x = vf_tex_default_dpi();
461 dpi_y = vf_tex_default_dpi();
462 }
463 }
464
465 bm = vf_alloc_bitmap_with_metric1(&met, dpi_x, dpi_y);
466
467 switch (font_tfm->glyph_style){
468 default:
469 case TEX_GLYPH_STYLE_EMPTY:
470 break;
471 case TEX_GLYPH_STYLE_FILL:
472 VF_FillBitmap(bm);
473 break;
474 }
475
476 return bm;
477 }
478
479 Private VF_OUTLINE
480 tfm_get_outline(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
481 double mag_x, double mag_y)
482 {
483 FONT_TFM font_tfm;
484 TFM tfm;
485 VF_OUTLINE ol;
486 double dpi_x, dpi_y, bbx, ps;
487 int size, x1, y1, x2, y2, index;
488 struct vf_s_metric1 met;
489
490 if ( ((font_tfm = (FONT_TFM)font->private) == NULL)
491 || ((tfm = font_tfm->tfm) == NULL) ){
492 fprintf(stderr, "VFlib internal error: tfm_get_outline()\n");
493 abort();
494 }
495
496 if (tfm_get_metric1(font, code_point, &met, mag_x, mag_y) < 0)
497 return NULL;
498
499 if ((ps = font->point_size) < 0)
500 if ((ps = font_tfm->point_size) < 0)
501 ps = tfm->design_size;
502
503 if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
504 if (((dpi_x = font_tfm->dpi_x) < 0) || ((dpi_y = font_tfm->dpi_y) < 0)){
505 dpi_x = vf_tex_default_dpi();
506 dpi_y = vf_tex_default_dpi();
507 }
508 }
509
510 if ((bbx = tfm->font_bbx_w) < tfm->font_bbx_h)
511 bbx = tfm->font_bbx_h;
512
513 size = VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + 6;
514 if ((ol = (VF_OUTLINE)calloc(size, sizeof(VF_OUTLINE_ELEM))) == NULL){
515 vf_error = VF_ERR_NO_MEMORY;
516 return NULL;
517 }
518
519 ol[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
520 ol[VF_OL_HEADER_INDEX_DATA_SIZE] = size;
521 ol[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(dpi_x);
522 ol[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(dpi_y);
523 ol[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(ps);
524 ol[VF_OL_HEADER_INDEX_EM] = VF_OL_COORD_RANGE;
525 ol[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * met.bbx_width/bbx;
526 ol[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * met.bbx_height/bbx;
527 ol[VF_OL_HEADER_INDEX_REF_X] = VF_OL_COORD_RANGE * (0.0 - met.off_x/bbx);
528 ol[VF_OL_HEADER_INDEX_REF_Y] = VF_OL_COORD_RANGE * met.off_y/bbx;
529 ol[VF_OL_HEADER_INDEX_MV_X] = VF_OL_COORD_RANGE * met.mv_x/bbx;
530 ol[VF_OL_HEADER_INDEX_MV_Y] = VF_OL_COORD_RANGE * met.mv_y/bbx;
531
532 x1 = VF_OL_COORD_OFFSET + 0;
533 x2 = VF_OL_COORD_OFFSET + VF_OL_COORD_RANGE * met.bbx_width / bbx;
534 y1 = VF_OL_COORD_OFFSET + 0;
535 y2 = VF_OL_COORD_OFFSET + VF_OL_COORD_RANGE * met.bbx_height / bbx;
536
537 index = VF_OL_OUTLINE_HEADER_SIZE_TYPE0;
538 ol[index++] = VF_OL_INSTR_TOKEN | VF_OL_INSTR_CCWCURV
539 | VF_OL_INSTR_LINE | VF_OL_INSTR_CHAR;
540 ol[index++] = VF_OL_MAKE_XY(x1, y1);
541 ol[index++] = VF_OL_MAKE_XY(x1, y2);
542 ol[index++] = VF_OL_MAKE_XY(x2, y2);
543 ol[index++] = VF_OL_MAKE_XY(x2, y1);
544 ol[index++] = 0L;
545
546 return ol;
547 }
548
549 Private int
550 tfm_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
551 double mag_x, double mag_y)
552 {
553 FONT_TFM font_tfm;
554 TFM tfm;
555 struct vf_s_metric1 met1;
556 int ps;
557 double dpi_x, dpi_y, mx, my;
558
559 if ( (metric == NULL)
560 || ((font_tfm = (FONT_TFM)font->private) == NULL)
561 || ((tfm = font_tfm->tfm) == NULL) ){
562 fprintf(stderr, "VFlib internal error in tfm_get_metric2()\n");
563 abort();
564 }
565
566 if (vf_tfm_metric(tfm, code_point, &met1) == NULL)
567 return -1;
568
569 if (((dpi_x = font_tfm->dpi_x) <= 0) || ((dpi_y = font_tfm->dpi_y) <= 0)){
570 dpi_x = vf_tex_default_dpi();
571 dpi_y = vf_tex_default_dpi();
572 }
573
574 if ((ps = font->pixel_size) < 0)
575 if ((ps = font_tfm->pixel_size) < 0)
576 ps = -1;
577
578 if ((ps < 0) || (tfm->design_size < 1.0e-3)){
579 mx = mag_x * font->mag_x * font_tfm->mag * dpi_x / 72.27;
580 my = mag_y * font->mag_y * font_tfm->mag * dpi_y / 72.27;
581 } else {
582 mx = mag_x * font->mag_x * font_tfm->mag * (ps/tfm->design_size);
583 my = mag_y * font->mag_y * font_tfm->mag * (ps/tfm->design_size);
584 }
585
586 metric->bbx_width = toint(met1.bbx_width * mx);
587 metric->bbx_height = toint(met1.bbx_height * my);
588 metric->off_x = toint(met1.off_x * mx);
589 metric->off_y = toint(met1.off_y * my);
590 metric->mv_x = toint(met1.mv_x * mx);
591 metric->mv_y = toint(met1.mv_y * my);
592
593 return 0;
594 }
595
596 Private int
597 tfm_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
598 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
599 {
600 FONT_TFM font_tfm;
601 TFM tfm;
602 int ps;
603 double dpi_x, dpi_y, mx, my;
604
605 if (((font_tfm = (FONT_TFM)font->private) == NULL)
606 || ((tfm = font_tfm->tfm) == NULL) ){
607 fprintf(stderr, "VFlib internal error in tfm_get_fontbbx2()\n");
608 abort();
609 }
610
611 if (((dpi_x = font_tfm->dpi_x) <= 0) || ((dpi_y = font_tfm->dpi_y) <= 0)){
612 dpi_x = vf_tex_default_dpi();
613 dpi_y = vf_tex_default_dpi();
614 }
615
616 if ((ps = font->pixel_size) < 0)
617 if ((ps = font_tfm->pixel_size) < 0)
618 ps = -1;
619
620 if ((ps < 0) || (tfm->design_size < 1.0e-3)){
621 mx = mag_x * font->mag_x * font_tfm->mag * dpi_x / 72.27;
622 my = mag_y * font->mag_y * font_tfm->mag * dpi_y / 72.27;
623 } else {
624 mx = mag_x * font->mag_x * font_tfm->mag * (ps/tfm->design_size);
625 my = mag_y * font->mag_y * font_tfm->mag * (ps/tfm->design_size);
626 }
627
628 *w_p = toint(tfm->font_bbx_w * mx);
629 *h_p = toint(tfm->font_bbx_h * my);
630 *xoff_p = toint(tfm->font_bbx_xoff * mx);
631 *yoff_p = toint(tfm->font_bbx_yoff * my);
632
633 return 0;
634 }
635
636 Private VF_BITMAP
637 tfm_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
638 double mag_x, double mag_y)
639 {
640 FONT_TFM font_tfm;
641 VF_BITMAP bm;
642 struct vf_s_metric2 met;
643
644 if ((font_tfm = (FONT_TFM)font->private) == NULL){
645 fprintf(stderr, "VFlib internal error in tfm_get_bitmap2()\n");
646 abort();
647 }
648
649 if (tfm_get_metric2(font, code_point, &met, mag_x, mag_y) < 0)
650 return NULL;
651
652 bm = vf_alloc_bitmap_with_metric2(&met);
653
654 switch (font_tfm->glyph_style){
655 default:
656 case TEX_GLYPH_STYLE_EMPTY:
657 break;
658 case TEX_GLYPH_STYLE_FILL:
659 VF_FillBitmap(bm);
660 break;
661 }
662
663 return bm;
664 }
665
666
667 Private char*
668 tfm_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
669 {
670 FONT_TFM font_tfm;
671 TFM tfm;
672 SEXP v;
673 double ps, dpi_x, dpi_y;
674 char str[256];
675
676 if ( ((font_tfm = (FONT_TFM)font->private) == NULL)
677 || ((tfm = font_tfm->tfm) == NULL) ){
678 fprintf(stderr, "VFlib internal error in tfm_get_font_prop()\n");
679 abort();
680 }
681
682 if ((v = vf_sexp_assoc(prop_name, font_tfm->props)) != NULL){
683 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
684 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
685 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
686 } else {
687
688 if (((dpi_x = font->dpi_x)<=0) || ((dpi_y = font->dpi_y)<=0)){
689 if (((dpi_x = font_tfm->dpi_x)<=0) || ((dpi_y = font_tfm->dpi_y)<=0)){
690 dpi_x = vf_tex_default_dpi();
691 dpi_y = vf_tex_default_dpi();
692 }
693 }
694 #if 0
695 printf("** %.3f %.3f %.3f %d %.3f %.3f %.3f\n",
696 dpi_x, dpi_y, tfm->design_size,
697 font->pixel_size, font_tfm->pixel_size,
698 font->point_size, font_tfm->point_size);
699 #endif
700
701 if (font->mode == 1){
702 if ((ps = font->point_size) < 0)
703 if ((ps = font_tfm->point_size) < 0)
704 ps = tfm->design_size;
705 ps = ps * font->mag_y * font_tfm->mag;
706 if (strcmp(prop_name, "POINT_SIZE") == 0){
707 sprintf(str, "%d", toint(ps * 10.0));
708 return vf_strdup(str);
709 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
710 sprintf(str, "%d", toint(ps * dpi_y / 72.27));
711 return vf_strdup(str);
712 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
713 sprintf(str, "%d", toint(dpi_x));
714 return vf_strdup(str);
715 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
716 sprintf(str, "%d", toint(dpi_y));
717 return vf_strdup(str);
718 }
719
720 } else if (font->mode == 2){
721 if (strcmp(prop_name, "POINT_SIZE") == 0){
722 if ((ps = font->pixel_size) < 0){
723 if ((ps = font_tfm->pixel_size) < 0){
724 sprintf(str, "%d", toint(tfm->design_size * 10.0
725 * font->mag_y * font_tfm->mag));
726 return vf_strdup(str);
727 }
728 }
729 ps = ps * font->mag_y * font_tfm->mag;
730 sprintf(str, "%d", toint(ps * 10.0 * 72.27 / dpi_y));
731 return vf_strdup(str);
732 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
733 if ((ps = font->pixel_size) < 0)
734 if ((ps = font_tfm->pixel_size) < 0)
735 ps = tfm->design_size * dpi_y / 72.27;
736 ps = ps * font->mag_y * font_tfm->mag;
737 sprintf(str, "%d", toint(ps));
738 return vf_strdup(str);
739 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
740 sprintf(str, "%d", toint(dpi_x));
741 return vf_strdup(str);
742 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
743 sprintf(str, "%d", toint(dpi_y));
744 return vf_strdup(str);
745 }
746 }
747 }
748
749 return NULL;
750 }
751
752
753 /*EOF*/