src/drv_bdf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_BDF
- bdf_create
- bdf_close
- bdf_get_metric1
- bdf_get_fontbbx1
- bdf_get_bitmap1
- bdf_get_outline
- bdf_get_metric2
- bdf_get_fontbbx2
- bdf_get_bitmap2
- bdf_get_bitmap
- bdf_get_font_prop
- bdf_debug
- bdf_debug2
- mag_mode_1
- mag_mode_2
- STRCMP
- BDF_SetBDF
- BDF_GetBDF
1 /*
2 * drv_bdf.c - A font driver for BDF format fonts.
3 * by Hirotsugu Kakugawa
4 *
5 * 2 Sep 1996 First version.
6 * 13 Dec 1996 for VFlib 3.1
7 * 16 Jan 1997 Added font directory customizing feature.
8 * 28 Jan 1997 Added debug feature.
9 * 26 Feb 1997 Added 'query_font_type'.
10 * 25 Apr 1997 Added multiple file extension feature.
11 * 4 Aug 1997 VFlib 3.3 Changed API.
12 * 20 Jan 1998 VFlib 3.4 Changed API.
13 * 22 Apr 1998 Improved get_font_property()
14 * 10 Jun 1998 Added multiple font files in 'font-file' capability.
15 * 17 Jun 1998 Support for CCV system. Support for 'font-directory'
16 * capability in font definition.
17 * 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
18 * 26 Nov 1998 Added debug flag control by environment variable.
19 */
20 /*
21 * Copyright (C) 1996-1998 Hirotsugu Kakugawa.
22 * All rights reserved.
23 *
24 * This file is part of the VFlib Library. This library is free
25 * software; you can redistribute it and/or modify it under the terms of
26 * the GNU Library General Public License as published by the Free
27 * Software Foundation; either version 2 of the License, or (at your
28 * option) any later version. This library is distributed in the hope
29 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
30 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
31 * PURPOSE. See the GNU Library General Public License for more details.
32 * You should have received a copy of the GNU Library General Public
33 * License along with this library; if not, write to the Free Software
34 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 */
36
37
38 #include "config.h"
39 #include <stdio.h>
40 #include <stdlib.h>
41 #ifdef HAVE_UNISTD_H
42 # include <unistd.h>
43 #endif
44 #include <ctype.h>
45 #include <math.h>
46 #include "VFlib-3_6.h"
47 #include "VFsys.h"
48 #include "vflibcap.h"
49 #include "ccv.h"
50 #include "sexp.h"
51 #include "str.h"
52 #include "path.h"
53 #include "fsearch.h"
54 #include "cache.h"
55 #include "bdf.h"
56
57 #define POINTS_PER_INCH 72.27
58 #define DEFAULT_POINT_SIZE 10.0
59 #define DEFAULT_PIXEL_SIZE 16
60 #define DEFAULT_DPI 75
61
62 struct s_font_bdf {
63 char *font_name;
64 char *font_file;
65 double point_size;
66 int pixel_size;
67 double dpi_x, dpi_y;
68 double mag;
69 double aspect;
70 int bdf_id;
71 int ccv_id;
72 SEXP_ALIST props;
73 };
74 typedef struct s_font_bdf *FONT_BDF;
75
76 Private SEXP_LIST default_fontdirs;
77 Private SEXP_LIST default_compressed_ext;
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_STRING default_debug_mode;
85 Private char *env_debug_mode = NULL;
86 #define DEBUG_ENV_NAME "VFLIB_BDF_DEBUG"
87
88
89 Private int bdf_create(VF_FONT font, char *font_class,
90 char *font_name, int implicit, SEXP entry);
91 Private int bdf_close(VF_FONT font);
92 Private int bdf_get_metric1(VF_FONT font, long code_point,
93 VF_METRIC1 metric1, double,double);
94 Private int bdf_get_metric2(VF_FONT font, long code_point,
95 VF_METRIC2 metric2, double,double);
96 Private int bdf_get_fontbbx1(VF_FONT font,double,double,
97 double*,double*,double*,double*);
98 Private int bdf_get_fontbbx2(VF_FONT font, double,double,
99 int*,int*,int*,int*);
100 Private VF_BITMAP bdf_get_bitmap1(VF_FONT,long,double,double);
101 Private VF_BITMAP bdf_get_bitmap2(VF_FONT,long,double,double);
102 Private VF_BITMAP bdf_get_bitmap(FONT_BDF,long);
103 Private VF_OUTLINE bdf_get_outline(VF_FONT,long,double,double);
104 Private char* bdf_get_font_prop(VF_FONT,char*);
105
106 Private void mag_mode_1(double font_size, int size,
107 double font_dpi_x, double font_dpi_y,
108 FONT_BDF font_bdf, VF_FONT font,
109 double mag_x, double mag_y,
110 double *ret_mag_x, double *ret_mag_y,
111 double *ret_point_size,
112 double *ret_dpix, double *ret_dpiy);
113 Private void mag_mode_2(int font_size, int size,
114 FONT_BDF font_bdf, VF_FONT font,
115 double mag_x, double mag_y,
116 double *ret_mag_x, double *ret_mag_y,
117 double *ret_pixel_size);
118 Private int bdf_debug(char);
119
120 Private BDF BDF_GetBDF(int bdf_id);
121 Private void BDF_SetBDF(int bdf_id, BDF bdf);
122
123 Private int BDF_Init(void);
124 Private int BDF_Open(char*,SEXP);
125 Private void BDF_Close(int);
126 Private BDF_CHAR BDF_GetBitmap(int,long);
127 Private BDF_CHAR BDF_GetBDFChar(BDF,long);
128 Private char *BDF_GetProp(BDF,char*);
129
130
131
132 Public int
133 VF_Init_Driver_BDF(void)
/* [<][>][^][v][top][bottom][index][help] */
134 {
135 int z;
136 struct s_capability_table ct[20];
137
138 z = 0;
139 /* VF_CAPE_FONT_DIRECTORIES */
140 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_STRING_LIST0;
141 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
142 /* VF_CAPE_COMPRESSION_EXT */
143 ct[z].cap = VF_CAPE_COMPRESSION_EXT; ct[z].type = CAPABILITY_STRING_LIST0;
144 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_compressed_ext;
145 /* VF_CAPE_DPI */
146 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
147 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
148 /* VF_CAPE_DPI_X */
149 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
150 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_x;
151 /* VF_CAPE_DPI_Y */
152 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
153 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_y;
154 /* VF_CAPE_ASPECT_RATIO */
155 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
156 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_aspect;
157 /* VF_CAPE_PROPERTIES */
158 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
159 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
160 /* VF_CAPE_VARIABLE_VALUES */
161 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
162 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
163 /* VF_CAPE_DEBUG */
164 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
165 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
166 /* end */
167 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
168
169 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL)
170 == VFLIBCAP_PARSED_ERROR)
171 return -1;
172
173 v_default_dpi_x = -1;
174 v_default_dpi_y = -1;
175 if (default_dpi != NULL)
176 v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
177 if (default_dpi_x != NULL)
178 v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
179 if (default_dpi_y != NULL)
180 v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
181
182 v_default_aspect = 1.0;
183 if (default_aspect != NULL)
184 v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
185
186 if (BDF_Init() < 0)
187 return -1;
188
189 env_debug_mode = getenv(DEBUG_ENV_NAME);
190
191 VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)bdf_create);
192
193 return 0;
194 }
195
196
197 Private int
198 bdf_create(VF_FONT font, char *font_class,
/* [<][>][^][v][top][bottom][index][help] */
199 char *font_name, int implicit, SEXP entry)
200 {
201 FONT_BDF font_bdf;
202 BDF bdf;
203 int bdf_id, val;
204 char *font_file;
205 SEXP cap_font, cap_point, cap_pixel;
206 SEXP cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
207 SEXP cap_charset, cap_encoding, cap_font_charset, cap_font_encoding;
208 SEXP cap_fontdirs, cap_props;
209 SEXP font_file_list, s;
210 SEXP fontdirs;
211 char *charset, *encoding, *font_charset, *font_encoding;
212 char *s1, *s2, s_font_charset[1024];
213 int z;
214 struct s_capability_table ct[24];
215
216 z = 0;
217 /* VF_CAPE_FONT_CLASS */
218 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
219 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
220 /* VF_CAPE_FONT_DIRECTORIES */
221 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_STRING_LIST0;
222 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_fontdirs;
223 /* VF_CAPE_FONT_FILE */
224 ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING_LIST1;
225 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font;
226 /* VF_CAPE_POINT_SIZE */
227 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
228 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
229 /* VF_CAPE_PIXEL_SIZE */
230 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
231 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
232 /* VF_CAPE_DPI */
233 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
234 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
235 /* VF_CAPE_DPI_X */
236 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
237 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_x;
238 /* VF_CAPE_DPI_Y */
239 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
240 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_y;
241 /* VF_CAPE_MAG */
242 ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
243 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
244 /* VF_CAPE_ASPECT_RATIO */
245 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
246 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_aspect;
247 /* VF_CAPE_CHARSET */
248 ct[z].cap = VF_CAPE_CHARSET; ct[z].type = CAPABILITY_STRING;
249 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_charset;
250 /* VF_CAPE_ENCODING */
251 ct[z].cap = VF_CAPE_ENCODING; ct[z].type = CAPABILITY_STRING;
252 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_encoding;
253 /* VF_CAPE_FONT_CHARSET */
254 ct[z].cap = VF_CAPE_FONT_CHARSET; ct[z].type = CAPABILITY_STRING;
255 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font_charset;
256 /* VF_CAPE_FONT_ENCODING */
257 ct[z].cap = VF_CAPE_FONT_ENCODING; ct[z].type = CAPABILITY_STRING;
258 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font_encoding;
259 /* VF_CAPE_PROPERTIES */
260 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
261 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
262 /* end */
263 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
264
265
266 val = -1;
267
268 fontdirs = default_fontdirs;
269 font_bdf = NULL;
270 font_file_list = NULL;
271 font_file = font_name;
272 bdf_id = -1;
273
274 if (implicit == 1){ /* implicit font */
275 font_file = font_name;
276 } else { /* explicit font */
277 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
278 default_variables, NULL)
279 == VFLIBCAP_PARSED_ERROR)
280 return -1;
281 if (cap_fontdirs != NULL)
282 fontdirs = cap_fontdirs;
283 if (cap_font == NULL){
284 /* Use font name as font file name if font file name is not given. */
285 font_file = font_name;
286 } else {
287 if (vf_sexp_listp(cap_font)){
288 switch (vf_sexp_length(cap_font)){
289 case 0:
290 goto End;
291 default:
292 font_file_list = cap_font;
293 break;
294 }
295 } else {
296 goto End;
297 }
298 }
299 }
300
301 bdf_id = -1;
302 if (font_file_list == NULL){
303 bdf_id = BDF_Open(font_file, fontdirs);
304 } else {
305 for (s = font_file_list; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
306 if (vf_sexp_stringp(vf_sexp_car(s))){
307 font_file = vf_sexp_get_cstring(vf_sexp_car(s));
308 bdf_id = BDF_Open(font_file, fontdirs);
309 if (bdf_id >= 0){
310 break;
311 }
312 }
313 }
314 }
315 if (bdf_id < 0)
316 goto End;
317
318 font->font_type = VF_FONT_TYPE_BITMAP;
319 font->get_metric1 = bdf_get_metric1;
320 font->get_metric2 = bdf_get_metric2;
321 font->get_fontbbx1 = bdf_get_fontbbx1;
322 font->get_fontbbx2 = bdf_get_fontbbx2;
323 font->get_bitmap1 = bdf_get_bitmap1;
324 font->get_bitmap2 = bdf_get_bitmap2;
325 font->get_outline = bdf_get_outline;
326 font->get_font_prop = bdf_get_font_prop;
327 font->query_font_type = NULL;
328 font->close = bdf_close;
329
330 ALLOC_IF_ERR(font_bdf, struct s_font_bdf){
331 vf_error = VF_ERR_NO_MEMORY;
332 goto End;
333 }
334
335 font_bdf->bdf_id = bdf_id;
336 font_bdf->font_name = NULL;
337 font_bdf->font_file = NULL;
338 font_bdf->point_size = -1;
339 font_bdf->pixel_size = -1;
340 font_bdf->dpi_x = -1;
341 font_bdf->dpi_y = -1;
342 font_bdf->mag = 1.0;
343 font_bdf->aspect = 1.0;
344 font_bdf->ccv_id = -1;
345 font_bdf->props = NULL;
346
347 charset = NULL;
348 encoding = NULL;
349 font_charset = NULL;
350 font_encoding = NULL;
351
352 if (implicit == 0){
353 if (cap_point != NULL)
354 font_bdf->point_size = atof(vf_sexp_get_cstring(cap_point));
355 if (cap_pixel != NULL)
356 font_bdf->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
357 if (cap_dpi != NULL)
358 font_bdf->dpi_x = font_bdf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
359 if (cap_dpi_x != NULL)
360 font_bdf->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
361 if (cap_dpi_y != NULL)
362 font_bdf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
363 if (cap_mag != NULL)
364 font_bdf->mag = atof(vf_sexp_get_cstring(cap_mag));
365 if (cap_aspect != NULL)
366 font_bdf->aspect = atof(vf_sexp_get_cstring(cap_aspect));
367 if (cap_charset != NULL)
368 charset = vf_sexp_get_cstring(cap_charset);
369 if (cap_encoding != NULL)
370 font_encoding = vf_sexp_get_cstring(cap_encoding);
371 if (cap_font_charset != NULL)
372 font_charset = vf_sexp_get_cstring(cap_font_charset);
373 if (cap_font_encoding != NULL)
374 font_encoding = vf_sexp_get_cstring(cap_font_encoding);
375 if (cap_props != NULL)
376 font_bdf->props = cap_props;
377 }
378
379 if ((font_bdf->font_file = vf_strdup(font_file)) == NULL){
380 vf_error = VF_ERR_NO_MEMORY;
381 goto End;
382 }
383 if ((font_bdf->font_name = vf_strdup(font_name)) == NULL){
384 vf_error = VF_ERR_NO_MEMORY;
385 goto End;
386 }
387
388 if ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL){
389 fprintf(stderr, "VFlib internal error: in bdf_create()\n");
390 vf_error = VF_ERR_INTERNAL;
391 goto End;
392 }
393
394 font_bdf->ccv_id = -1;
395 if ((charset != NULL) || (encoding != NULL)){
396 if (font_charset == NULL){
397 s1 = bdf_get_font_prop(font, "CHARSET_REGISTRY");
398 s2 = bdf_get_font_prop(font, "CHARSET_ENCODING");
399 if (s1 == NULL)
400 goto no_ccv;
401 if (s2 == NULL)
402 s2 = "";
403 sprintf(s_font_charset, "%s%s", s1, s2);
404 font_charset = s_font_charset;
405 }
406 font_bdf->ccv_id
407 = vf_ccv_require(charset, encoding, font_charset, font_encoding);
408 }
409 no_ccv:
410
411 font->private = font_bdf;
412 val = 0;
413
414
415 End:
416 if (implicit == 0){ /* explicit font */
417 vf_sexp_free3(&cap_font, &cap_point, &cap_pixel);
418 vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
419 vf_sexp_free2(&cap_mag, &cap_aspect);
420 vf_sexp_free2(&cap_charset, &cap_encoding);
421 vf_sexp_free2(&cap_font_charset, &cap_font_encoding);
422 vf_sexp_free1(&cap_fontdirs);
423 }
424 if (val < 0){
425 if (implicit == 0)
426 vf_sexp_free1(&cap_props);
427 if (bdf_id >= 0)
428 BDF_Close(bdf_id);
429 if (font_bdf != NULL){
430 vf_free(font_bdf->font_name);
431 vf_free(font_bdf->font_file);
432 }
433 vf_free(font_bdf);
434 }
435
436 return val;
437 }
438
439
440 Private int
441 bdf_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
442 {
443 FONT_BDF font_bdf;
444
445 font_bdf = (FONT_BDF)font->private;
446
447 if (font_bdf->bdf_id >= 0)
448 BDF_Close(font_bdf->bdf_id);
449
450 vf_sexp_free1(&font_bdf->props);
451 vf_free(font_bdf->font_name);
452 vf_free(font_bdf->font_file);
453 vf_free(font_bdf);
454
455 return 0;
456 }
457
458
459 Private int
460 bdf_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
461 double mag_x, double mag_y)
462 {
463 long cp;
464 FONT_BDF font_bdf;
465 BDF bdf;
466 BDF_CHAR bdf_char;
467 double mx, my;
468
469 if (metric == NULL){
470 fprintf(stderr, "VFlib internal error: in bdf_get_metric1()\n");
471 abort();
472 }
473 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
474 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
475 fprintf(stderr, "VFlib internal error: in bdf_get_metric1()\n");
476 abort();
477 }
478
479 cp = code_point;
480 if (font_bdf->ccv_id >= 0)
481 cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
482 if (bdf_debug('c'))
483 printf("VFlib BDF: CCV 0x%lx => 0x%lx\n", code_point, cp);
484
485 if ((bdf_char = BDF_GetBDFChar(bdf, cp)) == NULL)
486 return -1;
487
488 mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y,
489 font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
490
491 /* 72*pix/dpi = 72*pix/(pix/inch) = 72*inch = 72*(pt/72) = pt */
492 /* 1inch = 72pt */
493
494 metric->bbx_width
495 = 72.0 * mx * bdf_char->bbx_width / bdf->dpi_x;
496 metric->bbx_height
497 = 72.0 * my * bdf_char->bbx_height / bdf->dpi_y;
498 metric->off_x
499 = 72.0 * mx * (bdf_char->off_x / bdf->dpi_x) / bdf->dpi_x;
500 metric->off_y
501 = 72.0 * my * (bdf_char->bbx_height + bdf_char->off_y) / bdf->dpi_y;
502 metric->mv_x
503 = 72.0 * mx * bdf_char->mv_x / bdf->dpi_x;
504 metric->mv_y
505 = 72.0 * my * bdf_char->mv_y / bdf->dpi_y;
506
507 return 0;
508 }
509
510 Private int
511 bdf_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
512 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
513 {
514 FONT_BDF font_bdf;
515 BDF bdf;
516 double mx, my;
517
518 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
519 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
520 fprintf(stderr, "VFlib internal error: in bdf_get_fontbbx1()\n");
521 abort();
522 }
523
524 mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y,
525 font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
526
527 *w_p = 72.0 * mx * bdf->font_bbx_width / bdf->dpi_x;
528 *h_p = 72.0 * my * bdf->font_bbx_height / bdf->dpi_y;
529 *xoff_p = 72.0 * mx * bdf->font_bbx_xoff / bdf->dpi_x;
530 *yoff_p = 72.0 * my * bdf->font_bbx_yoff / bdf->dpi_y;
531
532 return 0;
533 }
534
535
536 Private VF_BITMAP
537 bdf_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
538 double mag_x, double mag_y)
539 {
540 long cp;
541 BDF bdf;
542 FONT_BDF font_bdf;
543 double mx, my;
544 VF_BITMAP bm;
545
546 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
547 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
548 fprintf(stderr, "VFlib internal error: in bdf_get_bitmap1()\n");
549 abort();
550 }
551
552 cp = code_point;
553 if (font_bdf->ccv_id >= 0)
554 cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
555 if (bdf_debug('c'))
556 printf("VFlib BDF: CCV 0x%lx => 0x%lx\n", code_point, cp);
557
558 if ((bm = bdf_get_bitmap(font_bdf, cp)) == NULL)
559 return NULL;
560
561 mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y,
562 font_bdf, font, mag_x, mag_y, &mx, &my, NULL, NULL, NULL);
563
564 return VF_MakeScaledBitmap(bm, mx, my);
565 /* WE SOULD NOT RELEASE "bm". See bdf_get_bitmap(). */
566 }
567
568 Private VF_OUTLINE
569 bdf_get_outline(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
570 double mag_x, double mag_y)
571 {
572 long cp;
573 FONT_BDF font_bdf;
574 BDF bdf;
575 VF_BITMAP bm;
576 VF_OUTLINE ol;
577 double mx, my, ps, dpi_x, dpi_y, f_bbx_w, f_bbx_h;
578
579 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
580 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
581 fprintf(stderr, "VFlib internal error: in bdf_get_outline()\n");
582 abort();
583 }
584
585 cp = code_point;
586 if (font_bdf->ccv_id >= 0)
587 cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
588 if (bdf_debug('c'))
589 printf("VFlib BDF: CCV 0x%lx => 0x%lx\n", code_point, cp);
590
591 if ((bm = bdf_get_bitmap1(font, cp, mag_x, mag_y)) == NULL)
592 return NULL;
593
594 mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y,
595 font_bdf, font, mag_x, mag_y, &mx, &my, &ps, &dpi_x, &dpi_y);
596
597 f_bbx_w = bdf->font_bbx_width * mx;
598 f_bbx_h = bdf->font_bbx_height * my;
599
600 ol = vf_bitmap_to_outline(bm, f_bbx_w, f_bbx_h, dpi_x, dpi_y, ps, 1, 1);
601 VF_FreeBitmap(bm);
602
603 return ol;
604 }
605
606
607 Private int
608 bdf_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
609 double mag_x, double mag_y)
610 {
611 long cp;
612 FONT_BDF font_bdf;
613 BDF bdf;
614 BDF_CHAR bdf_char;
615 double mx, my;
616
617 if (metric == NULL){
618 fprintf(stderr, "VFlib internal error: in bdf_get_metric2()\n");
619 abort();
620 }
621 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
622 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
623 fprintf(stderr, "VFlib internal error: in bdf_get_metric2()\n");
624 abort();
625 }
626
627 cp = code_point;
628 if (font_bdf->ccv_id >= 0)
629 cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
630 if (bdf_debug('c'))
631 printf("VFlib BDF: CCV 0x%lx => 0x%lx\n", code_point, cp);
632
633 if ((bdf_char = BDF_GetBDFChar(bdf, cp)) == NULL)
634 return -1;
635
636 mag_mode_2(bdf->pixel_size, bdf->size,
637 font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
638
639 metric->bbx_width = toint(mx * bdf_char->bbx_width);
640 metric->bbx_height = toint(my * bdf_char->bbx_height);
641 metric->off_x = toint(mx * bdf_char->off_x);
642 metric->off_y = toint(my * (bdf_char->bbx_height + bdf_char->off_y));
643 metric->mv_x = toint(mx * bdf_char->mv_x);
644 metric->mv_y = toint(my * bdf_char->mv_y);
645
646 return 0;
647 }
648
649 Private int
650 bdf_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
651 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
652 {
653 FONT_BDF font_bdf;
654 BDF bdf;
655 double mx, my;
656
657 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
658 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
659 fprintf(stderr, "VFlib internal error: in bdf_get_fontbbx1()\n");
660 abort();
661 }
662
663 mag_mode_2(bdf->pixel_size, bdf->size,
664 font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
665 *w_p = toint(mx * bdf->font_bbx_width);
666 *h_p = toint(my * bdf->font_bbx_height);
667 *xoff_p = toint(mx * bdf->font_bbx_xoff);
668 *yoff_p = toint(my * bdf->font_bbx_yoff);
669
670 return 0;
671 }
672
673
674 Private VF_BITMAP
675 bdf_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
676 double mag_x, double mag_y)
677 {
678 long cp;
679 BDF bdf;
680 FONT_BDF font_bdf;
681 VF_BITMAP bm;
682 double mx, my;
683
684 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
685 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
686 fprintf(stderr, "VFlib internal error: in bdf_get_bitmap2()\n");
687 abort();
688 }
689
690 cp = code_point;
691 if (font_bdf->ccv_id >= 0)
692 cp = vf_ccv_conv(font_bdf->ccv_id, code_point);
693 if (bdf_debug('c'))
694 printf("VFlib BDF: CCV 0x%lx => 0x%lx\n", code_point, cp);
695
696 if ((bm = bdf_get_bitmap(font_bdf, cp)) == NULL)
697 return NULL;
698
699 /* WE SOULD NOT RELEASE "bm". See bdf_get_bitmap(). */
700
701 mag_mode_2(bdf->pixel_size, bdf->size,
702 font_bdf, font, mag_x, mag_y, &mx, &my, NULL);
703
704 return VF_MakeScaledBitmap(bm, mx, my);
705 }
706
707
708 Private VF_BITMAP
709 bdf_get_bitmap(FONT_BDF font_bdf, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
710 {
711 BDF_CHAR bdf_char;
712 static struct vf_s_bitmap bitmap;
713
714 bdf_char = BDF_GetBitmap(font_bdf->bdf_id, code_point);
715 if ((bdf_char == NULL) || (bdf_char->bitmap == NULL))
716 return NULL;
717
718 bitmap.bbx_width = bdf_char->bbx_width;
719 bitmap.bbx_height = bdf_char->bbx_height;
720 bitmap.off_x = bdf_char->off_x;
721 bitmap.off_y = bdf_char->bbx_height + bdf_char->off_y;
722 bitmap.mv_x = bdf_char->mv_x;
723 bitmap.mv_y = bdf_char->mv_y;
724 bitmap.bitmap = bdf_char->bitmap;
725 bitmap.raster = bdf_char->raster;
726
727 return &bitmap;
728 /* CALLER MUST *NOT* CALL VF_FreeBitmap()! */
729 }
730
731
732 Private char*
733 bdf_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
734 /* CALLER MUST RELEASE RETURNED STRING */
735 {
736 FONT_BDF font_bdf;
737 BDF bdf;
738 SEXP v;
739 double ps, dpix, dpiy;
740 char str[512], *r;
741
742 if ( ((font_bdf = (FONT_BDF)font->private) == NULL)
743 || ((bdf = BDF_GetBDF(font_bdf->bdf_id)) == NULL) ){
744 fprintf(stderr, "VFlib: internal error: in bdf_get_font_prop()\n");
745 abort();
746 }
747
748 if ((v = vf_sexp_assoc(prop_name, font_bdf->props)) != NULL){
749 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
750 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
751 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
752 } else {
753 if (font->mode == 1){
754 mag_mode_1(bdf->point_size, bdf->size, bdf->dpi_x, bdf->dpi_y,
755 font_bdf, font, 1, 1, NULL, NULL, &ps, &dpix, &dpiy);
756 /**printf("** Mode1 %.3f %.3f %.3f %.3f %.3f\n", ps, dpix, dpiy,
757 font->point_size, font_bdf->point_size);**/
758 if (strcmp(prop_name, "POINT_SIZE") == 0){
759 sprintf(str, "%d", toint(10.0 * ps));
760 return vf_strdup(str);
761 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
762 sprintf(str, "%d", toint(ps * dpiy / POINTS_PER_INCH));
763 return vf_strdup(str);
764 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
765 sprintf(str, "%d", toint(dpix));
766 return vf_strdup(str);
767 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
768 sprintf(str, "%d", toint(dpiy));
769 return vf_strdup(str);
770 }
771 } else if (font->mode == 2){
772 mag_mode_2(bdf->pixel_size, bdf->size,
773 font_bdf, font, 1, 1, NULL, NULL, &ps);
774 /**printf("** Mode2 %.3f\n", ps);**/
775 if (strcmp(prop_name, "POINT_SIZE") == 0){
776 sprintf(str, "%d", toint(10.0 * ps * POINTS_PER_INCH / DEFAULT_DPI));
777 return vf_strdup(str);
778 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
779 sprintf(str, "%d", toint(ps));
780 return vf_strdup(str);
781 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
782 sprintf(str, "%d", toint(DEFAULT_DPI));
783 return vf_strdup(str);
784 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
785 sprintf(str, "%d", toint(DEFAULT_DPI));
786 return vf_strdup(str);
787 #ifndef HAVE_FONT_ASCENT
788 } else if (strcmp(prop_name, "FONT_ASCENT") == 0){
789 sprintf(str, "%d", bdf->ascent);
790 return vf_strdup(str);
791 #endif /*HAVE_FONT_ASCENT*/
792 #ifndef HAVE_FONT_DESCENT
793 } else if (strcmp(prop_name, "FONT_DESCENT") == 0){
794 sprintf(str, "%d", bdf->descent);
795 return vf_strdup(str);
796 #endif /*HAVE_FONT_DESCNET*/
797 }
798 }
799 }
800
801 if ((r = BDF_GetProp(bdf, prop_name)) != NULL)
802 return vf_strdup(r);
803
804 return NULL;
805 }
806
807
808 Private int bdf_debug2(char type, char *str);
809
810 Private int
811 bdf_debug(char type)
/* [<][>][^][v][top][bottom][index][help] */
812 {
813 int v;
814 char *p0;
815
816 v = FALSE;
817 if (env_debug_mode != NULL){
818 if ((v = bdf_debug2(type, env_debug_mode)) == TRUE)
819 return TRUE;
820 }
821
822 if (default_debug_mode == NULL)
823 return FALSE;
824 if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
825 return FALSE;
826 return bdf_debug2(type, p0);
827 }
828
829 Private int
830 bdf_debug2(char type, char *p0)
/* [<][>][^][v][top][bottom][index][help] */
831 {
832 char *p;
833
834 for (p = p0; *p != '\0'; p++){
835 if (*p == type)
836 return TRUE;
837 }
838 for (p = p0; *p != '\0'; p++){
839 if (*p == '*')
840 return TRUE;
841 }
842 return FALSE;
843 }
844
845
846 Private void
847 mag_mode_1(double font_size, int size,
/* [<][>][^][v][top][bottom][index][help] */
848 double font_dpi_x, double font_dpi_y,
849 FONT_BDF font_bdf, VF_FONT font,
850 double mag_x, double mag_y,
851 double *ret_mag_x, double *ret_mag_y, double *ret_point_size,
852 double *ret_dpix, double *ret_dpiy)
853 {
854 double mx, my, dpix, dpiy, ps, asp;
855
856 if ((ps = font->point_size) < 0)
857 if ((ps = font_bdf->point_size) < 0)
858 if ((ps = font_size) < 0)
859 if ((ps = size) < 0)
860 ps = DEFAULT_PIXEL_SIZE;
861
862 asp = (v_default_aspect * font_bdf->aspect);
863
864 mx = mag_x * font_bdf->mag * font->mag_x * asp * ps / (double)font_size;
865 my = mag_y * font_bdf->mag * font->mag_y * ps / (double)font_size;
866
867 ps = mag_y * font_bdf->mag * font->mag_y * ps;
868
869 if ((font->dpi_x > 0) && (font->dpi_y > 0)){
870 dpix = font->dpi_x;
871 dpiy = font->dpi_y;
872 } else if ((font_bdf->dpi_x > 0) && (font_bdf->dpi_y > 0)){
873 dpix = font_bdf->dpi_x;
874 dpiy = font_bdf->dpi_y;
875 } else if ((v_default_dpi_x > 0) && (v_default_dpi_y > 0)){
876 dpix = v_default_dpi_x;
877 dpiy = v_default_dpi_y;
878 } else {
879 dpix = font_dpi_x;
880 dpiy = font_dpi_y;
881 }
882
883 if (ret_mag_x != NULL)
884 *ret_mag_x = mx * (dpix / font_dpi_x);
885 if (ret_mag_y != NULL)
886 *ret_mag_y = my * (dpiy / font_dpi_y);
887
888 #if 0
889 printf("*** %.3f %.3f %.3f\n", mag_x, font_bdf->mag, font->mag_x);
890 printf(" %.3f %.3f %.3f\n", mag_y, font_bdf->mag, font->mag_y);
891 printf(" dpix=%.3f font_dpi_x=%.3f\n", dpix, font_dpi_x);
892 printf(" dpiy=%.3f font_dpi_y=%.3f\n", dpiy, font_dpi_y);
893 printf(" asp=%.3f\n", asp);
894 printf(" mx=%.3f, my=%.3f\n", mx, my);
895 if (ret_mag_x != NULL)
896 printf(" mag_x=%.3f, mag_y=%.3f\n", *ret_mag_x, *ret_mag_y);
897 #endif
898
899 if (ret_point_size != NULL)
900 *ret_point_size = ps;
901
902 if (ret_dpix != NULL)
903 *ret_dpix = dpix;
904 if (ret_dpiy != NULL)
905 *ret_dpiy = dpiy;
906 }
907
908 Private void
909 mag_mode_2(int font_size, int size,
/* [<][>][^][v][top][bottom][index][help] */
910 FONT_BDF font_bdf, VF_FONT font,
911 double mag_x, double mag_y,
912 double *ret_mag_x, double *ret_mag_y, double *ret_pixel_size)
913 {
914 double mx, my, ps, asp;
915
916 if ((ps = font->pixel_size) < 0)
917 if ((ps = font_bdf->pixel_size) < 0)
918 if ((ps = font_size) < 0)
919 if ((ps = size) < 0)
920 ps = DEFAULT_PIXEL_SIZE;
921
922 asp = v_default_aspect * font_bdf->aspect;
923
924 if (font_size <= 0){
925 mx = mag_x * font_bdf->mag * font->mag_x * asp;
926 my = mag_y * font_bdf->mag * font->mag_y;
927 } else {
928 mx = mag_x * font_bdf->mag * font->mag_x * asp * ps /(double)font_size;
929 my = mag_y * font_bdf->mag * font->mag_y * ps /(double)font_size;
930 }
931
932 ps = ps * font_bdf->mag * font->mag_y;
933
934 if (ret_mag_x != NULL)
935 *ret_mag_x = mx;
936 if (ret_mag_y != NULL)
937 *ret_mag_y = my;
938
939 if (ret_pixel_size != NULL)
940 *ret_pixel_size = ps;
941 }
942
943
944
945
946
947 /*
948 * Include Low-Level Font Interface Routine.
949 */
950 #define STRCMP(s1,s2) strncmp(s1,s2,sizeof(s2)-1)
/* [<][>][^][v][top][bottom][index][help] */
951
952 #include "bdf.c"
953
954
955 static int bdf_last_bdf_id = -1;
956 static BDF bdf_last_bdf = NULL;
957
958 Private void
959 BDF_SetBDF(int bdf_id, BDF bdf)
/* [<][>][^][v][top][bottom][index][help] */
960 {
961 bdf_last_bdf_id = bdf_id;
962 bdf_last_bdf = bdf;
963 }
964
965 Private BDF
966 BDF_GetBDF(int bdf_id)
/* [<][>][^][v][top][bottom][index][help] */
967 {
968 BDF bdf;
969
970 if (bdf_id == -1){
971 bdf_last_bdf_id = -1;
972 bdf_last_bdf = NULL;
973 return NULL;
974 }
975
976 if ( (bdf_last_bdf_id == bdf_id)
977 && (bdf_last_bdf != NULL)
978 && (bdf_last_bdf_id != -1))
979 return bdf_last_bdf;
980
981 bdf = (bdf_table->get_obj_by_id)(bdf_table, bdf_id);
982 bdf_last_bdf_id = bdf_id;
983 bdf_last_bdf = bdf;
984
985 return bdf;
986 }
987
988
989 /*EOF*/