src/drv_zeit.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_ZEIT
- zeit_create
- zeit_close
- mag_mode_1
- zeit_get_metric1
- zeit_get_fontbbx1
- zeit_get_bitmap1
- zeit_get_outline1
- mag_mode_2
- zeit_get_metric2
- zeit_get_fontbbx2
- zeit_get_bitmap2
- get_outline2
- zeit_get_font_prop
- ZEIT_SetZEIT
- ZEIT_GetZEIT
- debug_on
1 /*
2 * drv_zeit.c - A font driver for ZEIT format fonts
3 *
4 * by Hirotsugu Kakugawa
5 *
6 * 3 Dec 1996 First version.
7 * 10 Dec 1996 Changed for VFlib version 3.1
8 * 12 Dec 1996 Eliminated "do" capability.
9 * 26 Feb 1997 Added 'query_font_type'.
10 * 7 Aug 1997 VFlib 3.3 Changed API.
11 * 28 Jan 1998 VFlib 3.4 Changed API.
12 * 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
13 * 18 Oct 2001 Fixed memory leaks.
14 *
15 */
16 /*
17 * Copyright (C) 1993-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 - print font file path
35 * i - print info on character index
36 * o - print contents of outline data
37 * * - everything
38 */
39
40 #include "config.h"
41 #include <stdio.h>
42 #include <stdlib.h>
43 #ifdef HAVE_UNISTD_H
44 # include <unistd.h>
45 #endif
46 #include <ctype.h>
47 #include <math.h>
48 #include <sys/param.h>
49 #include "VFlib-3_6.h"
50 #include "VFsys.h"
51 #include "vflibcap.h"
52 #include "bitmap.h"
53 #include "cache.h"
54 #include "fsearch.h"
55 #include "str.h"
56 #include "sexp.h"
57
58
59 #include "zeit.h"
60
61 #define DIRECTION_HORIZONTAL 0
62 #define DIRECTION_VERTICAL 1
63
64 #define POINTS_PER_INCH 72.27 /* 1 inch = 72.27 point */
65
66 #define DEFAULT_DPI 72.27
67 #define DEFAULT_POINT_SIZE 32.0
68 #define DEFAULT_PIXEL_SIZE 32
69 #define DEFAULT_DIRECTION DIRECTION_HORIZONTAL
70
71
72 Private SEXP_LIST default_fontdirs;
73 Private SEXP_LIST default_extensions;
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_STRING default_direction;
83 Private char v_default_direction;
84 Private SEXP_LIST default_vec_bbxul;
85 Private double v_default_vec_bbxul_x, v_default_vec_bbxul_y;
86 Private SEXP_LIST default_vec_next;
87 Private double v_default_vec_next_x, v_default_vec_next_y;
88 Private SEXP_ALIST default_properties;
89 Private SEXP_ALIST default_variables;
90 Private SEXP_STRING default_debug_mode;
91
92 struct s_font_zeit {
93 int zeit_id;
94 char *font_name;
95 double point_size;
96 int pixel_size;
97 double dpi_x, dpi_y;
98 double aspect;
99 double mag;
100 double slant;
101 double vec_bbxul_x, vec_bbxul_y;
102 double vec_next_x, vec_next_y;
103 char direction;
104 SEXP props;
105 };
106 typedef struct s_font_zeit *FONT_ZEIT;
107
108 Private int zeit_create(VF_FONT font, char *font_class,
109 char *font_name, int implicit, SEXP entry);
110 Private int zeit_close(VF_FONT);
111 Private int zeit_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
112 Private int zeit_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
113 Private int zeit_get_fontbbx1(VF_FONT,double,double,
114 double*,double*,double*,double*);
115 Private int zeit_get_fontbbx2(VF_FONT,double,double,
116 int*,int*,int*,int*);
117 Private VF_BITMAP zeit_get_bitmap1(VF_FONT,long,double,double);
118 Private VF_BITMAP zeit_get_bitmap2(VF_FONT,long,double,double);
119 Private VF_OUTLINE zeit_get_outline1(VF_FONT,long,double,double);
120 Private char* zeit_get_font_prop(VF_FONT,char*);
121 Private VF_OUTLINE get_outline2(VF_FONT,FONT_ZEIT,long,int,double,double);
122
123 Private ZEIT ZEIT_GetZEIT(int zeit_id);
124 Private void ZEIT_SetZEIT(int zeit_id, ZEIT zeit);
125 Private int debug_on(char type);
126
127
128
129 Public int
130 VF_Init_Driver_ZEIT(void)
/* [<][>][^][v][top][bottom][index][help] */
131 {
132 char *p;
133 SEXP s1, s2;
134 struct s_capability_table ct[20];
135 int z;
136
137 z = 0;
138 /* VF_CAPE_FONT_DIRECTORIES */
139 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
140 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
141 /* VF_CAPE_EXTENSIONS */
142 ct[z].cap = VF_CAPE_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
143 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_extensions;
144 /* VF_CAPE_POINT_SIZE */
145 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
146 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_point_size;
147 /* VF_CAPE_PIXEL_SIZE */
148 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
149 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_pixel_size;
150 /* VF_CAPE_DPI */
151 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
152 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
153 /* VF_CAPE_DPI_X */
154 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
155 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_x;
156 /* VF_CAPE_DPI_Y */
157 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
158 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_y;
159 /* VF_CAPE_ASPECT_RATIO */
160 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
161 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_aspect;
162 /* VF_CAPE_DIRECTION */
163 ct[z].cap = VF_CAPE_DIRECTION; ct[z].type = CAPABILITY_STRING;
164 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_direction;
165 /* VF_CAPE_VECTOR_TO_BBX_UL */
166 ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL; ct[z].type = CAPABILITY_VECTOR;
167 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_vec_bbxul;
168 /* VF_CAPE_VECTOR_TO_NEXT */
169 ct[z].cap = VF_CAPE_VECTOR_TO_NEXT; ct[z].type = CAPABILITY_VECTOR;
170 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_vec_next;
171 /* VF_CAPE_PROPERTIES */
172 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
173 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
174 /* VF_CAPE_VARIABLE_VALUES */
175 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
176 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
177 /* VF_CAPE_DEBUG */
178 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
179 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
180 /* end */
181 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
182
183
184 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL)
185 == VFLIBCAP_PARSED_ERROR)
186 return -1;
187
188 if (default_extensions == NULL)
189 default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS);
190
191 v_default_point_size = DEFAULT_POINT_SIZE;
192 if (default_point_size != NULL)
193 v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
194 if (v_default_point_size < 0)
195 v_default_point_size = DEFAULT_POINT_SIZE;
196
197 v_default_pixel_size = DEFAULT_PIXEL_SIZE;
198 if (default_pixel_size != NULL)
199 v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
200 if (v_default_pixel_size < 0)
201 v_default_pixel_size = DEFAULT_PIXEL_SIZE;
202
203 v_default_dpi_x = DEFAULT_DPI;
204 v_default_dpi_y = DEFAULT_DPI;
205 if (default_dpi != NULL)
206 v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
207 if (default_dpi_x != NULL)
208 v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
209 if (default_dpi_y != NULL)
210 v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
211 if (v_default_dpi_x < 0)
212 v_default_dpi_x = DEFAULT_DPI;
213 if (v_default_dpi_y < 0)
214 v_default_dpi_y = DEFAULT_DPI;
215
216 v_default_aspect = 1.0;
217 if (default_aspect != NULL)
218 v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
219 if (v_default_aspect < 0)
220 v_default_aspect = 1.0;
221
222 v_default_direction = DEFAULT_DIRECTION;
223 if (default_direction != NULL){
224 p = vf_sexp_get_cstring(default_direction);
225 switch (*p){
226 case 'h': case 'H':
227 v_default_direction = DIRECTION_HORIZONTAL;
228 break;
229 case 'v': case 'V':
230 v_default_direction = DIRECTION_VERTICAL;
231 break;
232 default:
233 fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
234 break;
235 }
236 }
237
238 switch(v_default_direction){
239 case DIRECTION_HORIZONTAL: default:
240 v_default_vec_bbxul_x = 0;
241 v_default_vec_bbxul_y = DEFAULT_TO_REF_PT_H;
242 v_default_vec_next_x = 1.0;
243 v_default_vec_next_y = 0.0;
244 break;
245 case DIRECTION_VERTICAL:
246 v_default_vec_bbxul_x = DEFAULT_TO_REF_PT_V;
247 v_default_vec_bbxul_y = 0;
248 v_default_vec_next_x = 0.0;
249 v_default_vec_next_y = -1.0;
250 break;
251 }
252
253 if (default_vec_bbxul != NULL){
254 s1 = vf_sexp_car(default_vec_bbxul);
255 s2 = vf_sexp_cadr(default_vec_bbxul);
256 v_default_vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
257 v_default_vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
258 }
259
260 if (default_vec_next != NULL){
261 s1 = vf_sexp_car(default_vec_next);
262 s2 = vf_sexp_cadr(default_vec_next);
263 v_default_vec_next_x = atof(vf_sexp_get_cstring(s1));
264 v_default_vec_next_y = atof(vf_sexp_get_cstring(s2));
265 }
266
267 if (ZEIT_Init() < 0)
268 return -1;
269
270 VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)zeit_create);
271
272 return 0;
273 }
274
275
276 Private int
277 zeit_create(VF_FONT font, char *font_class,
/* [<][>][^][v][top][bottom][index][help] */
278 char *font_name, int implicit, SEXP entry)
279 {
280 FONT_ZEIT font_zeit;
281 ZEIT zeit;
282 char *font_file, *p;
283 int zeit_id, val;
284 SEXP s1, s2;
285 SEXP cap_font, cap_point, cap_pixel;
286 SEXP cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
287 SEXP cap_direction, cap_vec_bbxul, cap_vec_next, cap_props;
288 struct s_capability_table ct[20];
289 int z;
290
291 z = 0;
292 /* VF_CAPE_FONT_CLASS */
293 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
294 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
295 /* VF_CAPE_FONT_FILE */
296 ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING;
297 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font;
298 /* VF_CAPE_POINT_SIZE */
299 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
300 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
301 /* VF_CAPE_PIXEL_SIZE */
302 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
303 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
304 /* VF_CAPE_DPI */
305 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
306 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
307 /* VF_CAPE_DPI_X */
308 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
309 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_x;
310 /* VF_CAPE_DPI_Y */
311 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
312 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_y;
313 /* VF_CAPE_MAG */
314 ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
315 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
316 /* VF_CAPE_ASPECT_RATIO */
317 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
318 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_aspect;
319 /* VF_CAPE_DIRECTION */
320 ct[z].cap = VF_CAPE_DIRECTION; ct[z].type = CAPABILITY_STRING;
321 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_direction;
322 /* VF_CAPE_VECTOR_TO_BBX_UL */
323 ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL; ct[z].type = CAPABILITY_VECTOR;
324 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_vec_bbxul;
325 /* VF_CAPE_VECTOR_TO_NEXT */
326 ct[z].cap = VF_CAPE_VECTOR_TO_NEXT; ct[z].type = CAPABILITY_VECTOR;
327 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_vec_next;
328 /* VF_CAPE_PROPERTIES */
329 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
330 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
331 /* end */
332 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
333
334
335 if (implicit == 1){ /* implicit font */
336 font_file = font_name;
337 } else { /* explicit font */
338 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
339 default_variables, NULL) < 0)
340 return -1;
341 if (cap_font == NULL){
342 /* Use font name as font file name if font file name is not given. */
343 font_file = font_name;
344 } else {
345 font_file = vf_sexp_get_cstring(cap_font);
346 }
347 }
348
349 val = -1;
350 font_zeit = NULL;
351
352 if ((zeit_id = ZEIT_Open(font_file)) < 0)
353 goto End;
354
355 font->font_type = VF_FONT_TYPE_OUTLINE;
356 font->get_metric1 = zeit_get_metric1;
357 font->get_metric2 = zeit_get_metric2;
358 font->get_fontbbx1 = zeit_get_fontbbx1;
359 font->get_fontbbx2 = zeit_get_fontbbx2;
360 font->get_bitmap1 = zeit_get_bitmap1;
361 font->get_bitmap2 = zeit_get_bitmap2;
362 font->get_outline = zeit_get_outline1;
363 font->get_font_prop = zeit_get_font_prop;
364 font->query_font_type = NULL; /* Use font->font_type value. */
365 font->close = zeit_close;
366
367 ALLOC_IF_ERR(font_zeit, struct s_font_zeit){
368 vf_error = VF_ERR_NO_MEMORY;
369 goto End;
370 }
371
372 font_zeit->zeit_id = zeit_id;
373 font_zeit->font_name = NULL;
374 font_zeit->point_size = v_default_point_size;
375 font_zeit->pixel_size = v_default_pixel_size;
376 font_zeit->mag = 1.0;
377 font_zeit->dpi_x = v_default_dpi_x;
378 font_zeit->dpi_y = v_default_dpi_y;
379 font_zeit->aspect = v_default_aspect;
380 font_zeit->direction = v_default_direction;
381 font_zeit->slant = 0;
382 font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
383 font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
384 font_zeit->vec_next_x = v_default_vec_next_x;
385 font_zeit->vec_next_y = v_default_vec_next_y;
386
387 if (implicit == 0){
388 if (cap_point != NULL)
389 font_zeit->point_size = atof(vf_sexp_get_cstring(cap_point));
390 if (cap_pixel != NULL)
391 font_zeit->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
392 if (cap_dpi != NULL)
393 font_zeit->dpi_x = font_zeit->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
394 if (cap_dpi_x != NULL)
395 font_zeit->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
396 if (cap_dpi_y != NULL)
397 font_zeit->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
398 if (cap_mag != NULL)
399 font_zeit->mag = atof(vf_sexp_get_cstring(cap_mag));
400 if (cap_aspect != NULL)
401 font_zeit->aspect = atof(vf_sexp_get_cstring(cap_aspect));
402 if (cap_direction != NULL){
403 p = vf_sexp_get_cstring(cap_direction);
404 switch (*p){
405 case 'h': case 'H':
406 font_zeit->direction = DIRECTION_HORIZONTAL; break;
407 case 'v': case 'V':
408 font_zeit->direction = DIRECTION_VERTICAL; break;
409 default:
410 fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
411 break;
412 }
413 }
414 switch(font_zeit->direction){
415 case DIRECTION_HORIZONTAL: default:
416 font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
417 font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
418 font_zeit->vec_next_x = v_default_vec_next_x;
419 font_zeit->vec_next_y = v_default_vec_next_y;
420 break;
421 case DIRECTION_VERTICAL:
422 font_zeit->vec_bbxul_x = v_default_vec_bbxul_x;
423 font_zeit->vec_bbxul_y = v_default_vec_bbxul_y;
424 font_zeit->vec_next_x = v_default_vec_next_x;
425 font_zeit->vec_next_y = v_default_vec_next_y;
426 break;
427 }
428 if (cap_vec_bbxul != NULL){
429 s1 = vf_sexp_car(cap_vec_bbxul);
430 s2 = vf_sexp_cadr(cap_vec_bbxul);
431 font_zeit->vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
432 font_zeit->vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
433 }
434 if (cap_vec_next != NULL){
435 s1 = vf_sexp_car(cap_vec_next);
436 s2 = vf_sexp_cadr(cap_vec_next);
437 font_zeit->vec_next_x = atof(vf_sexp_get_cstring(s1));
438 font_zeit->vec_next_y = atof(vf_sexp_get_cstring(s2));
439 }
440 if (cap_props != NULL)
441 font_zeit->props = cap_props;
442 }
443
444 if ((font_zeit->font_name = vf_strdup(font_name)) == NULL){
445 vf_error = VF_ERR_NO_MEMORY;
446 goto End;
447 }
448
449 if ((zeit = ZEIT_GetZEIT(font_zeit->zeit_id)) == NULL){
450 fprintf(stderr, "VFlib: internal error in zeit_create()\n");
451 vf_error = VF_ERR_INTERNAL;
452 goto End;
453 }
454
455 font->private = font_zeit;
456 val = 0;
457
458 End:
459 if (implicit == 0){
460 vf_sexp_free3(&cap_font, &cap_point, &cap_pixel);
461 vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
462 vf_sexp_free3(&cap_direction, &cap_vec_bbxul, &cap_vec_next);
463 }
464 if (val < 0)
465 zeit_close(font);
466
467 return val;
468 }
469
470
471 Private int
472 zeit_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
473 {
474 FONT_ZEIT font_zeit;
475
476 font_zeit = (FONT_ZEIT)font->private;
477
478 if (font_zeit != NULL){
479 if (font_zeit->zeit_id >= 0)
480 ZEIT_Close(font_zeit->zeit_id);
481 vf_free(font_zeit->font_name);
482 vf_sexp_free1(&font_zeit->props);
483 vf_free(font_zeit);
484 }
485
486 return 0;
487 }
488
489
490
491 Private void
492 mag_mode_1(FONT_ZEIT font_zeit, VF_FONT font,
/* [<][>][^][v][top][bottom][index][help] */
493 double mag_x, double mag_y,
494 double *ret_point_size,
495 double *ret_bbx_w, double *ret_bbx_h,
496 double *ret_mag_x, double *ret_mag_y,
497 double *ret_dpix, double *ret_dpiy)
498 {
499 double mx, my, dpix, dpiy, ps, asp;
500
501 if ((ps = font->point_size) < 0)
502 if ((ps = font_zeit->point_size) < 0)
503 ps = v_default_point_size;
504
505 if (ret_point_size != NULL)
506 *ret_point_size = ps;
507
508 asp = (v_default_aspect * font_zeit->aspect);
509
510 mx = mag_x * font_zeit->mag * font->mag_x * asp;
511 my = mag_y * font_zeit->mag * font->mag_y;
512
513 if (ret_mag_x != NULL)
514 *ret_mag_x = mx;
515 if (ret_mag_y != NULL)
516 *ret_mag_y = my;
517
518 if ((font->dpi_x > 0) && (font->dpi_y > 0)){
519 dpix = font->dpi_x;
520 dpiy = font->dpi_y;
521 } else if ((font_zeit->dpi_x > 0) && (font_zeit->dpi_y > 0)){
522 dpix = font_zeit->dpi_x;
523 dpiy = font_zeit->dpi_y;
524 } else {
525 dpix = v_default_dpi_x;
526 dpiy = v_default_dpi_y;
527 }
528
529 if (ret_dpix != NULL)
530 *ret_dpix = dpix;
531 if (ret_dpiy != NULL)
532 *ret_dpiy = dpiy;
533
534 if (ret_bbx_w != NULL)
535 *ret_bbx_w = dpix * mx * (ps / POINTS_PER_INCH);
536 if (ret_bbx_h != NULL)
537 *ret_bbx_h = dpiy * my * (ps / POINTS_PER_INCH);
538
539 #if 0
540 printf("*** %.3f %.3f %.3f\n", mag_x, font_zeit->mag, font->mag_x);
541 printf(" %.3f %.3f %.3f\n", mag_y, font_zeit->mag, font->mag_y);
542 printf(" dpix=%.3f font_dpi_x=%.3f\n", dpix, font_dpi_x);
543 printf(" dpiy=%.3f font_dpi_y=%.3f\n", dpiy, font_dpi_y);
544 printf(" asp=%.3f\n", asp);
545 printf(" mx=%.3f, my=%.3f\n", mx, my);
546 if (ret_bbx_w != NULL)
547 printf(" W=%.3f H=%.3f\n", *ret_bbx_w, *ret_bbx_h);
548 #endif
549
550 }
551
552
553 Private int
554 zeit_get_metric1(VF_FONT font, long code, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
555 double mag_x, double mag_y)
556 {
557 FONT_ZEIT font_zeit;
558 double bbx_w, bbx_h;
559 double dpix, dpiy;
560
561 if ( ((font_zeit = (FONT_ZEIT)font->private) == NULL)
562 || (metric == NULL)){
563 fprintf(stderr, "VFlib internal error: in zeit_get_metric1()\n");
564 abort();
565 }
566
567 mag_mode_1(font_zeit, font, mag_x, mag_y,
568 NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);
569
570 metric->bbx_width = bbx_w;
571 metric->bbx_height = bbx_h;
572 metric->off_x = bbx_w * font_zeit->vec_bbxul_x;
573 metric->off_y = bbx_h * font_zeit->vec_bbxul_y;
574 metric->mv_x = bbx_w * font_zeit->vec_next_x;
575 metric->mv_y = bbx_h * font_zeit->vec_next_y;
576
577 return 0;
578 }
579
580 Private int
581 zeit_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
582 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
583 {
584 FONT_ZEIT font_zeit;
585 double bbx_w, bbx_h;
586 double dpix, dpiy;
587
588 if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
589 fprintf(stderr, "VFlib internal error: in zeit_get_fontbbx1()\n");
590 abort();
591 }
592
593 mag_mode_1(font_zeit, font, mag_x, mag_y,
594 NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);
595
596 *w_p = bbx_w;
597 *h_p = bbx_h;
598 *xoff_p = bbx_w * font_zeit->vec_bbxul_x;
599 *yoff_p = bbx_h * (1.0 - font_zeit->vec_bbxul_y);
600
601 return 0;
602 }
603
604 Private VF_BITMAP
605 zeit_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
606 double mag_x, double mag_y)
607 {
608 VF_OUTLINE outline;
609 VF_BITMAP bm;
610
611 if ((outline = zeit_get_outline1(font, code_point, mag_x, mag_y)) == NULL)
612 return NULL;
613
614 bm = vf_outline_to_bitmap(outline, -1, -1, -1, 1, 1);
615 VF_FreeOutline(outline);
616
617 return bm;
618 }
619
620 Private VF_OUTLINE
621 zeit_get_outline1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
622 double mag_x, double mag_y)
623 {
624 FONT_ZEIT font_zeit;
625 VF_OUTLINE outline;
626 double ps, mx, my, bbx_w, bbx_h, dpix, dpiy, em_mag;
627
628 if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
629 fprintf(stderr, "VFlib: internal error in zeit_get_outline1()\n");
630 abort();
631 }
632
633 mag_mode_1(font_zeit, font, mag_x, mag_y,
634 &ps, &bbx_w, &bbx_h, &mx, &my, &dpix, &dpiy);
635
636 em_mag = 1.0;
637 if (mx > 1){
638 em_mag /= mx;
639 my = my/mx;
640 mx = 1.0;
641 }
642 if (my > 1){
643 em_mag /= my;
644 mx = mx/my;
645 my = 1.0;
646 }
647
648 outline = ZEIT_ReadOutline(font_zeit->zeit_id, (int)code_point, mx, my);
649 if (outline == NULL)
650 return NULL;
651
652 outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
653 outline[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(dpix);
654 outline[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(dpiy);
655 outline[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(ps);
656 outline[VF_OL_HEADER_INDEX_EM] = VF_OL_COORD_RANGE * em_mag;
657 outline[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * mx;
658 outline[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * my;
659 outline[VF_OL_HEADER_INDEX_REF_X]
660 = VF_OL_COORD_RANGE * (0 - font_zeit->vec_bbxul_x) * mx;
661 outline[VF_OL_HEADER_INDEX_REF_Y]
662 = VF_OL_COORD_RANGE * font_zeit->vec_bbxul_y * my;
663 outline[VF_OL_HEADER_INDEX_MV_X]
664 = VF_OL_COORD_RANGE * font_zeit->vec_next_x * mx;
665 outline[VF_OL_HEADER_INDEX_MV_Y]
666 = VF_OL_COORD_RANGE * font_zeit->vec_next_y * my;
667
668 return outline;
669 }
670
671
672 Private void
673 mag_mode_2(FONT_ZEIT font_zeit, VF_FONT font,
/* [<][>][^][v][top][bottom][index][help] */
674 double mag_x, double mag_y,
675 double *ret_pixel_size,
676 double *ret_magx, double *ret_magy,
677 double *ret_bbx_w, double *ret_bbx_h)
678 {
679 int ps;
680 double mx, my, asp;
681
682 if ((ps = font->pixel_size) < 0)
683 if ((ps = font_zeit->pixel_size) < 0)
684 ps = v_default_pixel_size;
685
686 asp = (v_default_aspect * font_zeit->aspect);
687
688 mx = mag_x * font_zeit->mag * font->mag_x * asp;
689 my = mag_y * font_zeit->mag * font->mag_y;
690
691 if (ret_pixel_size != NULL)
692 *ret_pixel_size = ps;
693
694 if (ret_magx != NULL)
695 *ret_magx = mx;
696 if (ret_magy != NULL)
697 *ret_magy = my;
698
699 if (ret_bbx_w != NULL)
700 *ret_bbx_w = mx * ps;
701 if (ret_bbx_h != NULL)
702 *ret_bbx_h = my * ps;
703 }
704
705
706 Private int
707 zeit_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
708 double mag_x, double mag_y)
709 {
710 FONT_ZEIT font_zeit;
711 double bbx_w, bbx_h;
712
713 if ( ((font_zeit = (FONT_ZEIT)font->private) == NULL)
714 || (metric == NULL)){
715 fprintf(stderr, "VFlib internal error: in zeit_get_metric2()\n");
716 abort();
717 }
718
719 mag_mode_2(font_zeit, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);
720
721 metric->bbx_width = (int)ceil(bbx_w);
722 metric->bbx_height = (int)ceil(bbx_h);
723 metric->off_x = toint(bbx_w * font_zeit->vec_bbxul_x);
724 metric->off_y = toint(bbx_h * font_zeit->vec_bbxul_y);
725 metric->mv_x = toint(bbx_w * font_zeit->vec_next_x);
726 metric->mv_y = toint(bbx_h * font_zeit->vec_next_y);
727
728 return 0;
729 }
730
731 Private int
732 zeit_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
733 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
734 {
735 FONT_ZEIT font_zeit;
736 double bbx_w, bbx_h;
737
738 if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
739 fprintf(stderr, "VFlib internal error: in zeit_get_fontbbx2()\n");
740 abort();
741 }
742
743 mag_mode_2(font_zeit, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);
744
745 *w_p = toint(bbx_w);
746 *h_p = toint(bbx_h);
747 *xoff_p = toint(bbx_w * font_zeit->vec_bbxul_x);
748 *yoff_p = toint(bbx_w * (font_zeit->vec_bbxul_y - 1.0));
749
750 return 0;
751 }
752
753 Private VF_BITMAP
754 zeit_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
755 double mag_x, double mag_y)
756 {
757 FONT_ZEIT font_zeit;
758 VF_OUTLINE outline;
759 VF_BITMAP bm;
760 double ps, mx, my, bbx_w, bbx_h;
761 int bbx_width, bbx_height;
762
763 if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
764 fprintf(stderr, "VFlib internal error: in zeit_get_bitmap2()\n");
765 abort();
766 }
767
768 mag_mode_2(font_zeit, font, mag_x, mag_y, &ps, &mx, &my, &bbx_w, &bbx_h);
769
770 bbx_width = (int)ceil(bbx_w);
771 bbx_height = (int)ceil(bbx_h);
772
773 if ((bm = vf_alloc_bitmap(bbx_width, bbx_height)) == NULL){
774 vf_error = VF_ERR_NO_MEMORY;
775 return NULL;
776 }
777
778 outline = get_outline2(font, font_zeit, code_point, ps, mx, my);
779 if (outline == NULL)
780 return NULL;
781
782 if (vf_draw_outline(bm, outline) < 0){
783 VF_FreeOutline(outline);
784 VF_FreeBitmap(bm);
785 return NULL;
786 }
787 VF_FreeOutline(outline);
788
789 bm->off_x = toint(bbx_w * font_zeit->vec_bbxul_x);
790 bm->off_y = toint(bbx_h * font_zeit->vec_bbxul_y);
791 bm->mv_x = toint(bbx_w * font_zeit->vec_next_x);
792 bm->mv_y = toint(bbx_h * font_zeit->vec_next_y);
793
794 return bm;
795 }
796
797
798 Private VF_OUTLINE
799 get_outline2(VF_FONT font, FONT_ZEIT font_zeit, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
800 int pixel_size, double mx, double my)
801 {
802 VF_OUTLINE outline;
803 double em_mag;
804
805 em_mag = 1.0;
806 if (mx > 1){
807 em_mag /= mx;
808 my = my/mx;
809 mx = 1.0;
810 }
811 if (my > 1){
812 em_mag /= my;
813 mx = mx/my;
814 my = 1.0;
815 }
816
817 outline = ZEIT_ReadOutline(font_zeit->zeit_id, (int)code_point, mx, my);
818 if (outline == NULL)
819 return NULL;
820
821 outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
822 outline[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
823 outline[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
824 outline[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(pixel_size);
825 outline[VF_OL_HEADER_INDEX_EM] = VF_OL_COORD_RANGE * my;
826 outline[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * mx;
827 outline[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * my;
828 outline[VF_OL_HEADER_INDEX_REF_X]
829 = VF_OL_COORD_RANGE * (0 - font_zeit->vec_bbxul_x) * mx;
830 outline[VF_OL_HEADER_INDEX_REF_Y]
831 = VF_OL_COORD_RANGE * font_zeit->vec_bbxul_y * my;
832 outline[VF_OL_HEADER_INDEX_MV_X]
833 = VF_OL_COORD_RANGE * font_zeit->vec_next_x * mx;
834 outline[VF_OL_HEADER_INDEX_MV_Y]
835 = VF_OL_COORD_RANGE * font_zeit->vec_next_y * my;
836
837 return outline;
838 }
839
840
841 Private char*
842 zeit_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
843 /* CALLER MUST RELEASE RETURNED STRING */
844 {
845 FONT_ZEIT font_zeit;
846 char str[512];
847 double ps, dpix, dpiy;
848 SEXP v;
849
850 if ((font_zeit = (FONT_ZEIT)font->private) == NULL){
851 fprintf(stderr, "VFlib: internal error in zeit_get_font_prop()\n");
852 abort();
853 }
854
855 if ((v = vf_sexp_assoc(prop_name, font_zeit->props)) != NULL){
856 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
857 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
858 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
859 }
860
861 if (font->mode == 1){
862 mag_mode_1(font_zeit, font, 1.0, 1.0,
863 &ps, NULL, NULL, NULL, NULL, &dpix, &dpiy);
864 /**printf("** Mode1 %.3f %.3f %.3f\n", ps, dpix, dpiy);**/
865 if (strcmp(prop_name, "POINT_SIZE") == 0){
866 sprintf(str, "%d", toint(10.0 * ps));
867 return vf_strdup(str);
868 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
869 sprintf(str, "%d", toint(ps * dpiy / POINTS_PER_INCH));
870 return vf_strdup(str);
871 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
872 sprintf(str, "%d", toint(dpix));
873 return vf_strdup(str);
874 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
875 sprintf(str, "%d", toint(dpiy));
876 return vf_strdup(str);
877 }
878 } else if (font->mode == 2){
879 mag_mode_2(font_zeit, font, 1.0, 1.0, &ps, NULL, NULL, NULL, NULL);
880 /**printf("** Mode2 %.3f\n", ps);**/
881 if (strcmp(prop_name, "POINT_SIZE") == 0){
882 sprintf(str, "%d", toint(10.0 * ps * POINTS_PER_INCH / DEFAULT_DPI));
883 return vf_strdup(str);
884 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
885 sprintf(str, "%d", toint(ps));
886 return vf_strdup(str);
887 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
888 sprintf(str, "%d", toint(DEFAULT_DPI));
889 return vf_strdup(str);
890 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
891 sprintf(str, "%d", toint(DEFAULT_DPI));
892 return vf_strdup(str);
893 }
894 }
895
896 return NULL;
897 }
898
899
900 /*
901 * Include Low-Level Font Interface Routine.
902 */
903
904 #include "zeit.c"
905
906
907 static int zeit_last_zeit_id = -1;
908 static ZEIT zeit_last_zeit = NULL;
909
910 Private void
911 ZEIT_SetZEIT(int zeit_id, ZEIT zeit)
/* [<][>][^][v][top][bottom][index][help] */
912 {
913 zeit_last_zeit_id = zeit_id;
914 zeit_last_zeit = zeit;
915 }
916
917 Private ZEIT
918 ZEIT_GetZEIT(int zeit_id)
/* [<][>][^][v][top][bottom][index][help] */
919 {
920 ZEIT zeit;
921
922 if (zeit_id == -1){
923 zeit_last_zeit_id = -1;
924 zeit_last_zeit = NULL;
925 return NULL;
926 }
927
928 if ( (zeit_last_zeit_id == zeit_id)
929 && (zeit_last_zeit != NULL)
930 && (zeit_last_zeit_id != -1))
931 return zeit_last_zeit;
932
933 zeit = (zeit_table->get_obj_by_id)(zeit_table, zeit_id);
934 zeit_last_zeit_id = zeit_id;
935 zeit_last_zeit = zeit;
936
937 return zeit;
938 }
939
940
941 Private int
942 debug_on(char type)
/* [<][>][^][v][top][bottom][index][help] */
943 {
944 char *p, *p0;
945
946 if (default_debug_mode == NULL)
947 return FALSE;
948 if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
949 return FALSE;
950
951 for (p = p0; *p != '\0'; p++){
952 if (*p == type)
953 return TRUE;
954 }
955 for (p = p0; *p != '\0'; p++){
956 if (*p == '*')
957 return TRUE;
958 }
959 return FALSE;
960 }
961
962 /*EOF*/