src/drv_pk.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_PK
- pk_create
- pk_close
- pk_get_metric1
- pk_get_fontbbx1
- pk_get_bitmap1
- pk_get_outline
- pk_get_metric2
- pk_get_fontbbx2
- pk_get_bitmap2
- pk_get_font_prop
- PK_Init
- PK_Open
- PK_Close
- PK_GetBitmap
- PK_GetMetric
- PK_GetFontBBX
- PK_GetPK
- PK_SetPKGlyph
- PK_GetPKGlyph
- debug_on
1 /* CAUTION! NEVER EDIT THIS FILE */
2 /*
3 * drv_pk.c - A font driver for TeX PK format fonts.
4 *
5 * 28 Sep 1996 First version.
6 * 14 Dec 1996 for VFlib 3.1
7 * 26 Feb 1997 Added 'query_font_type'.
8 * 4 Aug 1997 VFlib 3.3 Changed API.
9 * 30 Jan 1998 VFlib 3.4 Changed API.
10 * 21 Apr 1998 Debugged get_font_prop().
11 * 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
12 * 9 Dec 1998 Fixed bugs in get_fontbbx1() and get_fontbbx2(). (^o^;)
13 * 16 Sep 1999 Changed not to use TFM files.
14 * 18 Oct 2001 Fixed memory leak.
15 */
16 /*
17 * Copyright (C) 1996-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 /*
34
35 (Suppose that default resolution is 300 dpi)
36
37 ARGS FOR FONT OPEN BEHAVIOR of the DRIVER
38 Case# font_name device_dpi mag font_dpi dev_dpi bitmap_mag TFM_mag
39 ----------------------------------------------------------------------------
40 1. cmr10 -1 1 300 300 1 1
41 2. cmr10 -1 1.2 360 300 1 1.2
42 3. cmr10 400 1 400 400 1 1
43 4. cmr10 400 1.2 480 400 1 1.2
44 5. cmr10.pk -1 1 300 300 1 1
45 6. cmr10.pk -1 1.2 360 300 1 1.2
46 7. cmr10.pk 400 1 400 400 1 1
47 8. cmr10.pk 400 1.2 480 400 1 1.2
48 9. cmr10.400pk -1 1 400 400 1 1
49 10. cmr10.400pk -1 1.2 480 400 1 1.2
50 11. cmr10.400pk 400 1 400 400 1 1
51 12. cmr10.400pk 400 1.2 400 400 1.2 1.2
52 13. cmr10.300pk 360 1 300 360 1.2 1
53 14. cmr10.300pk 360 1.2 300 360 1.44 1.2
54
55 Font file is selected from the rules of the table shown above.
56 a. A font file of 'font_dpi' dpi font and opened.
57 b. Bitmaps of a font is scaled by 'bitmap_mag'.
58 c. Font metrics are multiplied by 'TFM_mag'.
59
60 Memo:
61 * Case 5: We want a PK font file "cmr10" default device resolution.
62 Thus, the bitmaps and metrics need not be scaled.
63
64 * Case 6: We want a PK font file "cmr10" default device resolution
65 with maginication factor 1.2. Since default device resolution
66 is 300 and magnification factor is 1.2, the font file we want
67 is "cmr10.360pk". Since device resolution is 300, metrics
68 must be scaled by 1.2.
69
70 * Case 9: This case requires a font "cmr10.400pk" and target device
71 is not considered. Thus bitmaps and metrics are not scaled.
72
73 * Case 10: This case requires a font cmr10 for 400 dpi scaled by 1.2.
74 Thus, "cmr10.480pk" is used for this request.
75 Since it is scaled by 1.2, font metrics are scaled by 1.2 but
76 bitmaps in a font is not magnified.
77
78 * Case 13: We want to use a PK font file "cmr10.300pk" for 360 dpi device.
79 Thus, the bitmaps of the font must be scaled by (360/300) = 1.2.
80 Since the metrics in a TFM file are independent from device
81 resolution, metrics need not be scaled.
82
83 * Case 14: We want to use a PK font file "cmr10.300pk" for 360 dpi device
84 and magnify it by 1.2. Thus, the bitmaps of the font must be scaled
85 by (1.2 x (360/300)) = 1.44.
86 Since the metrics in a TFM file are independent from device
87 resolution, TFM metrics must be scaled by 1.2, which is a
88 magnification factor.
89 */
90
91
92 #include "config.h"
93 #include "with.h"
94 #include <stdio.h>
95 #include <stdlib.h>
96 #ifdef HAVE_UNISTD_H
97 # include <unistd.h>
98 #endif
99 #include <ctype.h>
100
101 #include "VFlib-3_6.h"
102 #include "VFsys.h"
103 #include "vflibcap.h"
104 #include "cache.h"
105 #include "str.h"
106 #include "path.h"
107 #include "fsearch.h"
108 #include "sexp.h"
109 #include "texfonts.h"
110 #include "pk.h"
111
112
113 struct s_font_pk {
114 int pk_id;
115 char *font_name;
116 char *font_file;
117 double point_size;
118 double pixel_size;
119 double mag;
120 double dpi_x, dpi_y;
121 SEXP props;
122 double extra_mag;
123 };
124 typedef struct s_font_pk *FONT_PK;
125
126
127 Private SEXP_LIST default_fontdirs;
128 Private SEXP_LIST default_extensions;
129 Private SEXP_STRING default_point_size;
130 Private double v_default_point_size;
131 Private SEXP_STRING default_pixel_size;
132 Private double v_default_pixel_size;
133 Private SEXP_STRING default_dpi;
134 Private double v_default_dpi_x, v_default_dpi_y;
135 Private SEXP_STRING default_make_glyph;
136 Private int v_default_make_glyph = 0;
137 Private SEXP_ALIST default_properties;
138 Private SEXP_ALIST default_variables;
139 Private SEXP_STRING default_debug_mode;
140
141
142 Private int pk_create(VF_FONT,char*,char*,int,SEXP);
143 Private int pk_close(VF_FONT);
144 Private int pk_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
145 Private int pk_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
146 Private int pk_get_fontbbx1(VF_FONT,double,double,
147 double*,double*,double*,double*);
148 Private int pk_get_fontbbx2(VF_FONT,double,double,
149 int*,int*,int*,int*);
150 Private VF_BITMAP pk_get_bitmap1(VF_FONT,long,double,double);
151 Private VF_BITMAP pk_get_bitmap2(VF_FONT,long,double,double);
152 Private VF_OUTLINE pk_get_outline(VF_FONT,long,double,double);
153 Private char* pk_get_font_prop(VF_FONT,char*);
154
155
156 Private int PK_Init(void);
157 Private int PK_Open(FONT_PK font_pk, VF_FONT font, int implicit);
158 Private void PK_Close(int pk_id);
159 Private VF_BITMAP PK_GetBitmap(int pk_id, long code_point);
160 Private int PK_GetMetric(int pk_id, long code_point, VF_METRIC1 me,
161 double *ret_dpi_x, double *ret_dpi_y,
162 double *ret_design_size);
163 Private void PK_GetFontBBX(int pk_id, int *bbx_w_p, int *bbx_h_p,
164 int *bbx_xoff_p, int *bbx_yoff_p);
165 Private int debug_on(char type);
166
167
168
169
170 Public int
171 VF_Init_Driver_PK(void)
/* [<][>][^][v][top][bottom][index][help] */
172 {
173 int z;
174 struct s_capability_table ct[20];
175
176 z = 0;
177 /* VF_CAPE_FONT_DIRECTORIES */
178 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
179 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
180 /* VF_CAPE_EXTENSIONS */
181 ct[z].cap = VF_CAPE_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
182 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_extensions;
183 /* VF_CAPE_POINT_SIZE */
184 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
185 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_point_size;
186 /* VF_CAPE_PIXEL_SIZE */
187 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
188 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_pixel_size;
189 /* VF_CAPE_DPI */
190 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
191 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
192 /* VF_CAPE_MAKE_MISSING_GLYPH */
193 ct[z].cap = VF_CAPE_MAKE_MISSING_GLYPH; ct[z].type = CAPABILITY_STRING;
194 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_make_glyph;
195 /* VF_CAPE_PROPERTIES */
196 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
197 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
198 /* VF_CAPE_VARIABLE_VALUES */
199 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
200 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
201 /* VF_CAPE_DEBUG */
202 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
203 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
204 /* end */
205 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
206
207 if (vf_tex_init() < 0)
208 return -1;
209
210 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_PK, ct,
211 vf_tex_default_variables, NULL)
212 == VFLIBCAP_PARSED_ERROR)
213 return -1;
214
215 if (default_extensions == NULL)
216 default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_PK);
217
218 v_default_point_size = -1;
219 if (default_point_size != NULL)
220 v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
221
222 v_default_pixel_size = -1;
223 if (default_pixel_size != NULL)
224 v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
225
226 v_default_dpi_x = -1;
227 v_default_dpi_y = -1;
228 if (default_dpi != NULL)
229 v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
230
231 v_default_make_glyph = 0;
232 if (default_make_glyph != NULL){
233 v_default_make_glyph
234 = vf_parse_bool(vf_sexp_get_cstring(default_make_glyph));
235 }
236
237 if (PK_Init() < 0)
238 return -1;
239
240 if ((v_default_dpi_x < 0) || (v_default_dpi_x < 0)){
241 v_default_dpi_x = vf_tex_default_dpi();
242 v_default_dpi_y = vf_tex_default_dpi();
243 }
244
245 VF_InstallFontDriver(FONTCLASS_NAME_PK, (DRIVER_FUNC_TYPE)pk_create);
246
247 return 0;
248 }
249
250
251 Private int
252 pk_create(VF_FONT font, char *font_class,
/* [<][>][^][v][top][bottom][index][help] */
253 char *font_name, int implicit, SEXP entry)
254 {
255 FONT_PK font_pk;
256 SEXP cap_ffile, cap_point, cap_pixel;
257 SEXP cap_dpi, cap_mag, cap_props;
258 char *font_file;
259 int val, pk_id;
260 struct s_capability_table ct[10];
261 int z;
262
263 z = 0;
264 /* VF_CAPE_FONT_CLASS */
265 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
266 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
267 /* VF_CAPE_FONT_FILE */
268 ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING;
269 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_ffile;
270 /* VF_CAPE_POINT_SIZE */
271 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
272 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
273 /* VF_CAPE_PIXEL_SIZE */
274 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
275 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
276 /* VF_CAPE_DPI */
277 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
278 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
279 /* VF_CAPE_MAG */
280 ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
281 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
282 /* VF_CAPE_PROPERTIES */
283 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
284 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
285 /* end */
286 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
287
288 if (implicit == 1){ /* implicit font */
289 font_file = font_name;
290 } else { /* explicit font */
291 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
292 default_variables, vf_tex_default_variables)
293 == VFLIBCAP_PARSED_ERROR)
294 return -1;
295 if (cap_ffile == NULL){
296 /* Use font name as font file name if font file name is not given. */
297 font_file = font_name;
298 } else {
299 font_file = vf_sexp_get_cstring(cap_ffile);
300 }
301 }
302
303 font->font_type = VF_FONT_TYPE_BITMAP;
304 font->get_metric1 = pk_get_metric1;
305 font->get_metric2 = pk_get_metric2;
306 font->get_fontbbx1 = pk_get_fontbbx1;
307 font->get_fontbbx2 = pk_get_fontbbx2;
308 font->get_bitmap1 = pk_get_bitmap1;
309 font->get_bitmap2 = pk_get_bitmap2;
310 font->get_outline = pk_get_outline;
311 font->get_font_prop = pk_get_font_prop;
312 font->query_font_type = NULL;
313 font->close = pk_close;
314
315 val = -1;
316 font_pk = NULL;
317
318 ALLOC_IF_ERR(font_pk, struct s_font_pk)
319 goto NoMemoryError;
320
321 font_pk->pk_id = -1;
322 font_pk->font_name = NULL;
323 font_pk->font_file = NULL;
324 font_pk->point_size = v_default_point_size;
325 font_pk->pixel_size = v_default_pixel_size;
326 font_pk->dpi_x = v_default_dpi_x;
327 font_pk->dpi_y = v_default_dpi_y;
328 font_pk->mag = 1.0;
329 font_pk->props = NULL;
330 font_pk->extra_mag = 1.0;
331
332 if (implicit == 0){
333 if (cap_point != NULL)
334 font_pk->point_size = atof(vf_sexp_get_cstring(cap_point));
335 if (cap_pixel != NULL)
336 font_pk->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
337 if (cap_dpi != NULL)
338 font_pk->dpi_x = font_pk->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
339 if (cap_mag != NULL)
340 font_pk->mag = atof(vf_sexp_get_cstring(cap_mag));
341 if (cap_props != NULL)
342 font_pk->props = cap_props;
343 }
344
345 if ((font_pk->font_file = vf_strdup(font_file)) == NULL)
346 goto NoMemoryError;
347 if ((font_pk->font_name = vf_strdup(font_name)) == NULL)
348 goto NoMemoryError;
349
350 if ((pk_id = PK_Open(font_pk, font, implicit)) < 0)
351 goto Error;
352
353 font_pk->pk_id = pk_id;
354 font->private = font_pk;
355
356 val = 0;
357 goto End;
358
359
360 NoMemoryError:
361 vf_error = VF_ERR_NO_MEMORY;
362 Error:
363 if (font_pk != NULL){
364 vf_free(font_pk->font_name);
365 vf_free(font_pk->font_file);
366 }
367 if (implicit == 0)
368 vf_sexp_free1(&cap_props);
369 vf_free(font_pk);
370
371 End:
372 if (implicit == 0){
373 vf_sexp_free3(&cap_ffile, &cap_point, &cap_pixel);
374 vf_sexp_free2(&cap_dpi, &cap_mag);
375 }
376
377 return val;
378 }
379
380
381 Private int
382 pk_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
383 {
384 FONT_PK font_pk;
385
386 font_pk = (FONT_PK)font->private;
387 if (font_pk != NULL){
388 PK_Close(font_pk->pk_id);
389 vf_sexp_free1(&font_pk->props);
390 vf_free(font_pk->font_name);
391 vf_free(font_pk->font_file);
392 }
393 vf_free(font_pk);
394
395 return 0;
396 }
397
398
399 Private int
400 pk_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
401 double mag_x, double mag_y)
402 {
403 FONT_PK font_pk;
404 double mx, my, ps, design_size;
405
406 if (metric == NULL){
407 fprintf(stderr, "VFlib internal error: in pk_get_metric1()\n");
408 abort();
409 }
410 if ((font_pk = (FONT_PK)font->private) == NULL){
411 fprintf(stderr, "VFlib internal error: in pk_get_metric1()\n");
412 abort();
413 }
414
415 if (PK_GetMetric(font_pk->pk_id, code_point, metric,
416 NULL, NULL, &design_size) < 0)
417 return -1;
418
419 if ((ps = font->point_size) < 0)
420 if ((ps = font_pk->point_size) < 0)
421 ps = -1;
422
423 if ((ps < 0) || (design_size < 1.0e-3)){
424 mx = mag_x * font->mag_x * font_pk->mag;
425 my = mag_y * font->mag_y * font_pk->mag;
426 } else {
427 mx = mag_x * font->mag_x * font_pk->mag * (ps/design_size);
428 my = mag_y * font->mag_y * font_pk->mag * (ps/design_size);
429 }
430
431 metric->bbx_width *= mx;
432 metric->bbx_height *= my;
433 metric->off_x *= mx;
434 metric->off_y *= my;
435 metric->mv_x *= mx;
436 metric->mv_y *= my;
437
438 return 0;
439 }
440
441 Private int
442 pk_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
443 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
444 {
445 FONT_PK font_pk;
446 double mx, my, ps, design_size, dpi_x, dpi_y;
447 int w, h, xoff, yoff;
448
449 if ((font_pk = (FONT_PK)font->private) == NULL){
450 fprintf(stderr, "VFlib internal error: in pk_get_fontbbx1()\n");
451 abort();
452 }
453
454 if (PK_GetMetric(font_pk->pk_id, -1, NULL,
455 &dpi_x, &dpi_y, &design_size) < 0)
456 return -1;
457
458 if ((ps = font->point_size) < 0)
459 if ((ps = font_pk->point_size) < 0)
460 ps = -1;
461
462 if ((ps < 0) || (design_size < 1.0e-3)){
463 mx = mag_x * font->mag_x * font_pk->mag;
464 my = mag_y * font->mag_y * font_pk->mag;
465 } else {
466 mx = mag_x * font->mag_x * font_pk->mag * (ps/design_size);
467 my = mag_y * font->mag_y * font_pk->mag * (ps/design_size);
468 }
469
470 PK_GetFontBBX(font_pk->pk_id, &w, &h, &xoff, &yoff);
471
472 #if 0
473 printf("*** %d %d %d %d %.3f %.3f %.3f %.3f\n",
474 w, h, xoff, yoff, mx, my, dpi_x, dpi_y);
475 #endif
476
477 *w_p = mx * w * 72.27 / dpi_x;
478 *h_p = my * h * 72.27 / dpi_y;
479 *xoff_p = mx * xoff * 72.27 / dpi_x;
480 *yoff_p = my * yoff * 72.27 / dpi_y;
481
482 return 0;
483 }
484
485 Private VF_BITMAP
486 pk_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
487 double mag_x, double mag_y)
488 {
489 VF_BITMAP bm;
490 FONT_PK font_pk;
491 double mx, my, ps, design_size;
492
493 if ((font_pk = (FONT_PK)font->private) == NULL){
494 fprintf(stderr, "VFlib internal error in pk_get_bitmap1()\n");
495 abort();
496 }
497
498 if ((bm = PK_GetBitmap(font_pk->pk_id, code_point)) == NULL)
499 return NULL;
500 /* 'bm' SHOULD NOT BE RELEASED. */
501
502 if (PK_GetMetric(font_pk->pk_id, code_point, NULL,
503 NULL, NULL, &design_size) < 0)
504 return NULL;
505
506 if ((ps = font->point_size) < 0)
507 if ((ps = font_pk->point_size) < 0)
508 ps = -1;
509
510 if ((ps < 0) || (design_size < 1.0e-3)){
511 /* Note: font->mag_x and font_pk->mag are already used to select
512 scaled glyph, e.g., cmr10.360pk for 300dpi with mag 1.2. */
513 mx = font_pk->extra_mag * mag_x;
514 my = font_pk->extra_mag * mag_y;
515 } else {
516 #if 0
517 m = font->mag_y * font_pk->mag;
518 mx = font_pk->extra_mag * mag_x * m * (ps/design_size);
519 my = font_pk->extra_mag * mag_y * m * (ps/design_size);
520 #endif
521 mx = font_pk->extra_mag * mag_x * (ps/design_size);
522 my = font_pk->extra_mag * mag_y * (ps/design_size);
523 }
524
525 if (debug_on('m'))
526 printf("VFlib PK: get_bitmap1: bitmap mag: %.4f %.4f\n", mx, my);
527
528 return VF_MakeScaledBitmap(bm, mx, my);
529 }
530
531 Private VF_OUTLINE
532 pk_get_outline(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
533 double mag_x, double mag_y)
534 {
535 VF_BITMAP bm;
536 VF_OUTLINE ol;
537 FONT_PK font_pk;
538 int bbx_w, bbx_h;
539 double dpi_x, dpi_y, design_size;
540
541 if ((font_pk = (FONT_PK)font->private) == NULL){
542 fprintf(stderr, "VFlib internal error in pk_get_outline()\n");
543 abort();
544 }
545
546 if ((bm = pk_get_bitmap1(font, code_point, mag_x, mag_y)) == NULL)
547 return NULL;
548
549 if (PK_GetMetric(font_pk->pk_id, code_point, NULL,
550 &dpi_x, &dpi_y, &design_size) < 0){
551 VF_FreeBitmap(bm);
552 return NULL;
553 }
554
555 PK_GetFontBBX(font_pk->pk_id, &bbx_w, &bbx_h, NULL, NULL);
556 ol = vf_bitmap_to_outline(bm, bbx_w, bbx_h,
557 dpi_x, dpi_y, design_size, 1.0, 1.0);
558 VF_FreeBitmap(bm);
559
560 return ol;
561 }
562
563
564 Private int
565 pk_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
566 double mag_x, double mag_y)
567 {
568 VF_BITMAP bm;
569 FONT_PK font_pk;
570 double mx, my, dpi_x, dpi_y, ps, design_size;
571
572 if ( (metric == NULL)
573 || ((font_pk = (FONT_PK)font->private) == NULL) ){
574 fprintf(stderr, "VFlib internal error: in pk_get_metric2()\n");
575 abort();
576 }
577
578 if ((bm = PK_GetBitmap(font_pk->pk_id, code_point)) == NULL)
579 return -1;
580 /* 'bm' SHOULD NOT BE RELEASED. */
581
582 if (PK_GetMetric(font_pk->pk_id, code_point, NULL,
583 &dpi_x, &dpi_y, &design_size) < 0)
584 return -1;
585
586 if ((ps = font->pixel_size) < 0)
587 if ((ps = font_pk->pixel_size) < 0)
588 ps = -1;
589
590 if ((ps < 0) || (design_size < 1.0e-3)){
591 mx = font->mag_x * font_pk->mag * mag_x;
592 my = font->mag_y * font_pk->mag * mag_y;
593 } else {
594 mx = font->mag_x * font_pk->mag * mag_x * (ps*72.27)/(design_size*dpi_x);
595 my = font->mag_y * font_pk->mag * mag_y * (ps*72.27)/(design_size*dpi_y);
596 }
597
598 metric->bbx_width = toint(mx * bm->bbx_width);
599 metric->bbx_height = toint(my * bm->bbx_height);
600 metric->off_x = toint(mx * bm->off_x);
601 metric->off_y = toint(my * bm->off_y);
602 metric->mv_x = toint(mx * bm->mv_x);
603 metric->mv_y = toint(my * bm->mv_y);
604
605 return 0;
606 }
607
608 Private int
609 pk_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
610 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
611 {
612 FONT_PK font_pk;
613 double mx, my, dpi_x, dpi_y, ps, design_size;
614
615 if ((font_pk = (FONT_PK)font->private) == NULL){
616 fprintf(stderr, "VFlib internal error: in pk_get_fontbbx2()\n");
617 abort();
618 }
619
620 if (PK_GetMetric(font_pk->pk_id, -1, NULL,
621 &dpi_x, &dpi_y, &design_size) < 0)
622 return -1;
623
624 if ((ps = font->pixel_size) < 0)
625 if ((ps = font_pk->pixel_size) < 0)
626 ps = -1;
627
628 if ((ps < 0) || (design_size < 1.0e-3)){
629 mx = font->mag_x * font_pk->mag * mag_x;
630 my = font->mag_y * font_pk->mag * mag_y;
631 } else {
632 mx = font->mag_x * font_pk->mag * mag_x * (ps*72.27)/(design_size*dpi_x);
633 my = font->mag_y * font_pk->mag * mag_y * (ps*72.27)/(design_size*dpi_y);
634 }
635
636 PK_GetFontBBX(font_pk->pk_id, w_p, h_p, xoff_p, yoff_p);
637
638 *w_p = mx * (*w_p);
639 *h_p = mx * (*h_p);
640 *xoff_p = mx * (*xoff_p);
641 *yoff_p = mx * (*yoff_p);
642
643 return 0;
644 }
645
646
647 Private VF_BITMAP
648 pk_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
649 double mag_x, double mag_y)
650 {
651 VF_BITMAP bm;
652 FONT_PK font_pk;
653 double mx, my, dpi_x, dpi_y, ps, design_size;
654
655 if ((font_pk = (FONT_PK)font->private) == NULL){
656 fprintf(stderr, "VFlib internal error in pk_get_bitmap2()\n");
657 abort();
658 }
659
660 if ((bm = PK_GetBitmap(font_pk->pk_id, code_point)) == NULL)
661 return NULL;
662 /* 'bm' SHOULD NOT BE RELEASED. */
663
664 if (PK_GetMetric(font_pk->pk_id, code_point, NULL,
665 &dpi_x, &dpi_y, &design_size) < 0)
666 return NULL;
667
668 if ((ps = font->pixel_size) < 0)
669 if ((ps = font_pk->pixel_size) < 0)
670 ps = -1;
671
672 #if 0
673 printf("** %.3f %.3f %.3f %.3f %.3f %.3f %d %.3f\n",
674 mag_x, mag_y, ps, design_size, dpi_x, dpi_y,
675 font->pixel_size, font_pk->pixel_size);
676 #endif
677
678 if ((ps < 0) || (design_size < 1.0e-3)){
679 /* Note: font_pk->mag_x and font_pk->mag are already used to select
680 scaled glyph, e.g., cmr10.360pk for 300dpi with mag 1.2. */
681 mx = font_pk->extra_mag * mag_x;
682 my = font_pk->extra_mag * mag_y;
683 } else {
684 #if 0
685 m = font->mag_y * font_pk->mag;
686 mx = font_pk->extra_mag * mag_x * m * (ps*72.27)/(design_size*dpi_x);
687 my = font_pk->extra_mag * mag_y * m * (ps*72.27)/(design_size*dpi_y);
688 #endif
689 mx = font_pk->extra_mag * mag_x
690 * (font->mag_x * font_pk->mag) * (ps*72.27)/(design_size*dpi_x);
691 my = font_pk->extra_mag * mag_y
692 * (font->mag_y * font_pk->mag) * (ps*72.27)/(design_size*dpi_y);
693 }
694
695 return VF_MakeScaledBitmap(bm, mx, my);
696 }
697
698
699 Private char*
700 pk_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
701 {
702 FONT_PK font_pk;
703 double dpi_x, dpi_y, design_size, ps, m;
704 char str[256];
705 SEXP v;
706
707 if ((font_pk = (FONT_PK)font->private) == NULL){
708 fprintf(stderr, "VFlib internal error in pk_get_font_prop()\n");
709 abort();
710 }
711
712 if ((v = vf_sexp_assoc(prop_name, font_pk->props)) != NULL){
713 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
714 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
715 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
716 } else {
717 if (PK_GetMetric(font_pk->pk_id, -1, NULL,
718 &dpi_x, &dpi_y, &design_size) < 0){
719 return NULL;
720 }
721 m = font->mag_y * font_pk->mag;
722 #if 0
723 printf("** %.3f %.3f %.3f %.4f %d %.3f %.3f %.3f\n",
724 dpi_x, dpi_y, design_size, m,
725 font->pixel_size, font_pk->pixel_size,
726 font->point_size, font_pk->point_size);
727 #endif
728 if (font->mode == 1){
729 if ((ps = font->point_size) < 0)
730 if ((ps = font_pk->point_size) < 0)
731 ps = design_size;
732 if (strcmp(prop_name, "POINT_SIZE") == 0){
733 sprintf(str, "%d", toint(ps * m * 10.0));
734 return vf_strdup(str);
735 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
736 sprintf(str, "%d", toint(ps * dpi_y / 72.27));
737 return vf_strdup(str);
738 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
739 sprintf(str, "%d", toint(dpi_x));
740 return vf_strdup(str);
741 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
742 sprintf(str, "%d", toint(dpi_y));
743 return vf_strdup(str);
744 }
745
746 } else if (font->mode == 2){
747 if (strcmp(prop_name, "POINT_SIZE") == 0){
748 if ((ps = font->pixel_size) < 0){
749 if ((ps = font_pk->pixel_size) < 0){
750 sprintf(str, "%d", toint(design_size * m));
751 return vf_strdup(str);
752 }
753 }
754 sprintf(str, "%d", toint(ps * 10.0 * (72.27 / dpi_y)));
755 return vf_strdup(str);
756 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
757 if ((ps = font->pixel_size) < 0)
758 if ((ps = font_pk->pixel_size) < 0){
759 ps = design_size * dpi_y / 72.27;
760 sprintf(str, "%d", toint(ps));
761 return vf_strdup(str);
762 }
763 sprintf(str, "%d", toint(ps * m));
764 return vf_strdup(str);
765 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
766 sprintf(str, "%d", toint(dpi_x));
767 return vf_strdup(str);
768 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
769 sprintf(str, "%d", toint(dpi_y));
770 return vf_strdup(str);
771 }
772 }
773 }
774
775 return NULL;
776 }
777
778
779
780 #ifndef CACHE_SIZE
781 # define CACHE_SIZE 48
782 #endif
783 #ifndef HASH_SIZE
784 # define HASH_SIZE 11
785 #endif
786
787
788 struct s_pk {
789 int type;
790 char *font_path;
791 };
792 typedef struct s_pk *PK;
793
794 struct s_pk_glyph {
795 int code_min, code_max;
796 VF_BITMAP bm_table;
797 double ds, hppp, vppp;
798 int font_bbx_w, font_bbx_h;
799 int font_bbx_xoff, font_bbx_yoff;
800 };
801 typedef struct s_pk_glyph *PK_GLYPH;
802
803 Private VF_TABLE pk_table = NULL;
804 Private VF_CACHE pk_glyph_cache = NULL;
805
806 Private void PK_CacheDisposer(PK_GLYPH go);
807 Private PK_GLYPH PK_CacheLoader(VF_CACHE c, char *path, int l);
808
809 Private PK PK_GetPK(int pk_id);
810 Private void PK_SetPKGlyph(char *path, PK_GLYPH go);
811 Private PK_GLYPH PK_GetPKGlyph(char *path);
812
813
814 Private int
815 PK_Init(void)
/* [<][>][^][v][top][bottom][index][help] */
816 {
817 static int init_flag = 0;
818
819 if (init_flag == 0){
820 init_flag = 1;
821 if ((pk_table = vf_table_create()) == NULL){
822 vf_error = VF_ERR_NO_MEMORY;
823 return -1;
824 }
825 pk_glyph_cache
826 = vf_cache_create(CACHE_SIZE, HASH_SIZE,
827 (void*(*)(VF_CACHE,void*,int))PK_CacheLoader,
828 (void(*)(void*))PK_CacheDisposer);
829 }
830
831 return 0;
832 }
833
834 Private int
835 PK_Open(FONT_PK font_pk, VF_FONT font, int implicit)
/* [<][>][^][v][top][bottom][index][help] */
836 {
837 PK pk;
838 char *pk_path, *p;
839 int pk_id, dev_dpi;
840 double font_mag;
841
842 pk = NULL;
843
844 if (vf_dbg_drv_texfonts == 1)
845 printf(">> PK Open: %s\n", font_pk->font_file);
846
847 /* Parse font name. Formats of file names that this routine supports:
848 * "cmr10.300XX" - A "cmr10" font for 300 dpi.
849 * "cmr10.XX" - A "cmr10" font. Dpi value is default value.
850 * "cmr10" - ditto.
851 * ("XX" can be any string such as "pk", "pk", and "tfm".)
852 */
853 p = vf_index(font_pk->font_file, '.');
854 if ((p != NULL) && (isdigit((int)*(p+1)))){ /* "cmr10.300pk" */
855 dev_dpi = atoi(p+1);
856 if (font->dpi_y > 0)
857 font_pk->extra_mag = (double)font->dpi_y / (double)dev_dpi;
858 else
859 font_pk->extra_mag = 1.0;
860 } else { /* "cmr10" or "cmr10.pk" */
861 if ((dev_dpi = font->dpi_y) < 0)
862 dev_dpi = font_pk->dpi_y;
863 font_pk->extra_mag = 1.0;
864 }
865
866 font_mag = font->mag_y * font_pk->mag;
867 pk_path = vf_tex_search_file_glyph(font_pk->font_file, implicit,
868 FSEARCH_FORMAT_TYPE_PK,
869 default_fontdirs, dev_dpi, font_mag,
870 default_extensions);
871 if (pk_path == NULL){
872 if (vf_dbg_drv_texfonts == 1)
873 printf(">> PK Open: PK file not found\n");
874 if (v_default_make_glyph == 0)
875 return -1;
876 if (vf_tex_make_glyph(FSEARCH_FORMAT_TYPE_PK,
877 font_pk->font_file, dev_dpi, font_mag) < 0)
878 return -1;
879 pk_path = vf_tex_search_file_glyph(font_pk->font_file, implicit,
880 FSEARCH_FORMAT_TYPE_PK,
881 default_fontdirs, dev_dpi, font_mag,
882 default_extensions);
883 if (pk_path == NULL){
884 if (vf_dbg_drv_texfonts == 1)
885 printf(">> PK Open: PK file not found\n");
886 return -1;
887 }
888 }
889
890 if (debug_on('f'))
891 printf("VFlib PK: font:%s, dpi:%d, mag:%f, extra_mag:%f\n ==> %s\n",
892 font_pk->font_file, dev_dpi, font_mag, font_pk->extra_mag, pk_path);
893
894 ALLOC_IF_ERR(pk, struct s_pk){
895 goto NoMemoryError;
896 }
897 pk->font_path = pk_path;
898 if ((pk_id = (pk_table->put)(pk_table, pk, pk->font_path,
899 strlen(pk->font_path)+1)) < 0)
900 goto NoMemoryError;
901
902 return pk_id;
903
904
905 NoMemoryError:
906 vf_error = VF_ERR_NO_MEMORY;
907 if (pk != NULL)
908 vf_free(pk->font_path);
909 vf_free(pk);
910 return -1;
911 }
912
913 Private void
914 PK_Close(int pk_id)
/* [<][>][^][v][top][bottom][index][help] */
915 {
916 PK pk;
917
918 pk = PK_GetPK(pk_id);
919
920 if ((pk_table->unlink_by_id)(pk_table, pk_id) > 0)
921 return;
922
923 if (pk != NULL)
924 vf_free(pk->font_path);
925 vf_free(pk);
926 PK_SetPKGlyph(NULL, NULL);
927 }
928
929
930 Private VF_BITMAP
931 PK_GetBitmap(int pk_id, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
932 /* MEMO: CALLER MUST *NOT* 'FREE' THE BITMAP RETURNED BY THIS FUNC. */
933 {
934 PK_GLYPH go;
935 PK pk;
936
937 pk = PK_GetPK(pk_id);
938 if ((go = PK_GetPKGlyph(pk->font_path)) == NULL)
939 return NULL;
940
941 if ((go->code_min <= code_point) && (code_point <= go->code_max))
942 return &go->bm_table[code_point - go->code_min];
943
944 return NULL;
945 }
946
947 Private int
948 PK_GetMetric(int pk_id, long code_point, VF_METRIC1 me,
/* [<][>][^][v][top][bottom][index][help] */
949 double *ret_dpi_x, double *ret_dpi_y, double *ret_design_size)
950 {
951 VF_BITMAP bm;
952 PK_GLYPH go;
953 PK pk;
954
955 pk = PK_GetPK(pk_id);
956 if ((go = PK_GetPKGlyph(pk->font_path)) == NULL)
957 return -1;
958
959 if (code_point < 0)
960 code_point = go->code_min;
961 if ((code_point < go->code_min) || (go->code_max < code_point)){
962 vf_error = VF_ERR_ILL_CODE_POINT;
963 return -1;
964 }
965
966 if ((bm = &go->bm_table[code_point - go->code_min]) == NULL){
967 vf_error = VF_ERR_ILL_CODE_POINT;
968 return -1;
969 }
970
971 if (me != NULL){
972 me->bbx_width = bm->bbx_width / go->hppp;
973 me->bbx_height = bm->bbx_height / go->vppp;
974 me->off_x = bm->off_x / go->hppp;
975 me->off_y = bm->off_y / go->vppp;
976 me->mv_x = bm->mv_x / go->hppp;
977 me->mv_y = bm->mv_y / go->vppp;
978 }
979
980 if (ret_dpi_x != NULL)
981 *ret_dpi_x = go->hppp * 72.27;
982 if (ret_dpi_y != NULL)
983 *ret_dpi_y = go->vppp * 72.27;
984 if (ret_design_size != NULL)
985 *ret_design_size = go->ds;
986
987 return 0;
988 }
989
990 Private void
991 PK_GetFontBBX(int pk_id, int *bbx_w_p, int *bbx_h_p,
/* [<][>][^][v][top][bottom][index][help] */
992 int *bbx_xoff_p, int *bbx_yoff_p)
993 {
994 PK_GLYPH go;
995 PK pk;
996
997 pk = PK_GetPK(pk_id);
998 if ((go = PK_GetPKGlyph(pk->font_path)) == NULL)
999 return;
1000
1001 if (bbx_w_p != NULL)
1002 *bbx_w_p = go->font_bbx_w;
1003 if (bbx_h_p != NULL)
1004 *bbx_h_p = go->font_bbx_h;
1005 if (bbx_xoff_p != NULL)
1006 *bbx_xoff_p = go->font_bbx_xoff;
1007 if (bbx_yoff_p != NULL)
1008 *bbx_yoff_p = go->font_bbx_yoff;
1009 }
1010
1011
1012 /*
1013 * PK file interface
1014 */
1015
1016 #include "pk.c"
1017
1018
1019 Private PK
1020 PK_GetPK(int pk_id)
/* [<][>][^][v][top][bottom][index][help] */
1021 {
1022 if (pk_id < 0)
1023 abort();
1024 return (pk_table->get_obj_by_id)(pk_table, pk_id);
1025 }
1026
1027
1028 static char *pk_last_go_path = NULL;
1029 static PK_GLYPH pk_last_go = NULL;
1030
1031 Private void
1032 PK_SetPKGlyph(char *path, PK_GLYPH go)
/* [<][>][^][v][top][bottom][index][help] */
1033 {
1034 pk_last_go_path = path;
1035 pk_last_go = go;
1036 }
1037
1038 Private PK_GLYPH
1039 PK_GetPKGlyph(char *path)
/* [<][>][^][v][top][bottom][index][help] */
1040 {
1041 PK_GLYPH go;
1042
1043 if (path == NULL){
1044 pk_last_go_path = NULL;
1045 pk_last_go = NULL;
1046 return NULL;
1047 }
1048 if ((pk_last_go_path != NULL)
1049 && (strcmp(pk_last_go_path, path) == 0)
1050 && (pk_last_go != NULL) ){
1051 return pk_last_go;
1052 }
1053
1054 go = (pk_glyph_cache->get)(pk_glyph_cache, path, strlen(path)+1);
1055 pk_last_go_path = path;
1056 pk_last_go = go;
1057
1058 return go;
1059 }
1060
1061
1062 Private int
1063 debug_on(char type)
/* [<][>][^][v][top][bottom][index][help] */
1064 {
1065 char *p;
1066
1067 if (default_debug_mode == NULL)
1068 return FALSE;
1069 if ((p = vf_sexp_get_cstring(default_debug_mode)) == NULL)
1070 return FALSE;
1071
1072 while (*p != '\0'){
1073 if (*p == type)
1074 return TRUE;
1075 p++;
1076 }
1077
1078 while (*p != '\0'){
1079 if (*p == '*')
1080 return TRUE;
1081 p++;
1082 }
1083
1084 return TRUE;
1085 }
1086
1087
1088 /*EOF*/