src/drv_ttf.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_TrueType
- ttf_create
- ttf_close
- ttf_open_method
- ttf_close_method
- ttf_get_metric1
- ttf_get_fontbbx1
- ttf_get_bitmap1
- ttf_get_outline1
- ttf_get_metric2
- ttf_get_fontbbx2
- ttf_get_bitmap2
- ttf_get_xxx
- fix_jisx0212_row47_empty_sjis
- get_outline_ttf_to_vflib
- ConvX
- ConvY
- ttf_get_font_prop
- find_encoding_mapping
- get_id_from_platform_name
- get_id_from_encoding_name
- name2id
- conv_encoding_ttf_to_vflib
- platform_id2name
- encoding_id2name
- ttf_debug
- ttf_debug2
1 /*
2 * drv_ttf.c - A font driver for TrueType fonts with FreeType library.
3 * by Hirotsugu Kakugawa
4 *
5 * 6 Jan 1998 First implementation by FreeType 1.0.
6 * 5 Feb 1998 VFlib 3.4 Changed API.
7 * 20 Mar 1998 Added outline data extract routine.
8 * 2 Jun 1998 Added 'hinting' capablity
9 * 18 Jun 1998 Adopted FreeType 1.1
10 * 21 Sep 1998 Fixed a bug that dumps core when a font is closed.
11 * 9 Dec 1998 Adopted FreeType 1.2
12 * 9 Dec 1998 Added debug flag control by environment variable.
13 * Added get_fontbbx1() and get_fontbbx2().
14 * 20 Dec 1998 Added a feature to open/close font files dynamically on demand.
15 * 28 Dec 1998 Fixed a bug in code for dynamic open/close font files.
16 * 4 Mar 1999 Added ad-hoc solution to handle buggy JIS X 0212 fonts
17 * with empty Row 47 (e.g., Ricoh TrueTypeWorld ValueFont DX).
18 * Add "jisx0212-row47-empty-sjis" capability with "yes" value
19 * in vflibcap to use such fonts.
20 * 29 Jul 1999 Fixed a bug in makeing outline data (refrence point).
21 */
22 /*
23 * Copyright (C) 1996-1999 Hirotsugu Kakugawa.
24 * All rights reserved.
25 *
26 * This file is part of the VFlib Library. This library is free
27 * software; you can redistribute it and/or modify it under the terms of
28 * the GNU Library General Public License as published by the Free
29 * Software Foundation; either version 2 of the License, or (at your
30 * option) any later version. This library is distributed in the hope
31 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
32 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
33 * PURPOSE. See the GNU Library General Public License for more details.
34 * You should have received a copy of the GNU Library General Public
35 * License along with this library; if not, write to the Free Software
36 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 */
38
39 /* debug flag in vflibcap (debug capability):
40 * f - print font file path
41 * n - the number of fonts in a font file
42 * c - code mapping table information (ccv info)
43 * p - code mapping table information (non-ccv info)
44 * i - print char index
45 * m - print metrics
46 * * - everything
47 */
48
49 #include "config.h"
50 #include <stdio.h>
51 #include <stdlib.h>
52 #ifdef HAVE_UNISTD_H
53 # include <unistd.h>
54 #endif
55 #include <ctype.h>
56 #include <math.h>
57 #include <sys/param.h>
58 #include "VFlib-3_6.h"
59 #include "VFsys.h"
60 #include "vflibcap.h"
61 #include "bitmap.h"
62 #include "cache.h"
63 #include "fsearch.h"
64 #include "str.h"
65 #include "sexp.h"
66 #include "ccv.h"
67
68
69 #include "freetype.h"
70 #include "ttf.h"
71
72 #define DIRECTION_HORIZONTAL 0
73 #define DIRECTION_VERTICAL 1
74
75
76 Private SEXP_LIST default_fontdirs;
77 Private SEXP_STRING default_point_size;
78 Private double v_default_point_size;
79 Private SEXP_STRING default_pixel_size;
80 Private double v_default_pixel_size;
81 Private SEXP_STRING default_dpi, default_dpi_x, default_dpi_y;
82 Private double v_default_dpi_x, v_default_dpi_y;
83 Private SEXP_STRING default_aspect;
84 Private double v_default_aspect;
85 Private SEXP_STRING default_direction;
86 Private char v_default_direction;
87 Private SEXP_STRING default_platform_id;
88 Private int v_default_platform_id;
89 Private SEXP_STRING default_encoding_id;
90 Private int v_default_encoding_id;
91 Private SEXP_STRING default_hinting;
92 Private int v_default_hinting;
93 Private SEXP_ALIST default_properties;
94 Private SEXP_ALIST default_variables;
95 Private SEXP_STRING default_debug_mode;
96 Private char *env_debug_mode = NULL;
97 #define DEBUG_ENV_NAME "VFLIB_TTF_DEBUG"
98
99
100 struct s_font_ttf {
101 int release_on_close;
102 int ttf_opened;
103 TT_Face tt_face;
104 TT_Instance tt_instance;
105 TT_CharMap tt_charmap;
106 TT_Glyph tt_glyph;
107 TT_Face_Properties tt_fprops;
108 TT_UShort tt_upem;
109 char *font_name;
110 char *file_path;
111 double point_size;
112 double pixel_size;
113 double dpi_x, dpi_y;
114 double aspect;
115 double mag;
116 char direction;
117 int font_number;
118 int platform_id;
119 int encoding_id;
120 int mapping_id;
121 int encoding_force;
122 int hinting;
123 int jisx0212_r47e_sjis;
124 char *charset_name;
125 char *encoding_name;
126 SEXP props;
127 int ccv_id;
128 };
129 typedef struct s_font_ttf *FONT_TTF;
130
131
132 struct s_id_name_tbl {
133 int id;
134 char *name;
135 };
136 typedef struct s_id_name_tbl *ID_NAME_TBL;
137
138
139 struct s_fontbbx1 {
140 double w, h;
141 double xoff, yoff;
142 };
143 typedef struct s_fontbbx1 *FONTBBX1;
144 struct s_fontbbx2 {
145 int w, h;
146 int xoff, yoff;
147 };
148 typedef struct s_fontbbx2 *FONTBBX2;
149
150 #define MODE_METRIC1 1
151 #define MODE_BITMAP1 2
152 #define MODE_FONTBBX1 3
153 #define MODE_OUTLINE 4
154 #define MODE_METRIC2 5
155 #define MODE_FONTBBX2 6
156 #define MODE_BITMAP2 7
157
158 Private TT_Face *ttf_open_method(char*,long,long,VF_FONT,FONT_TTF);
159 Private void ttf_close_method(TT_Face*,long,long,VF_FONT,FONT_TTF);
160
161 Private void* ttf_get_xxx(int mode,
162 VF_FONT font, long code_point,
163 double mag_x, double mag_y,
164 VF_METRIC1 metric1, VF_METRIC2 metric2,
165 FONTBBX1 bbx1, FONTBBX2 bbx2);
166
167 Private int ttf_create(VF_FONT,char*,char*,int,SEXP);
168 Private int ttf_close(VF_FONT);
169 Private int ttf_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
170 Private int ttf_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
171 Private int ttf_get_fontbbx1(VF_FONT font,double,double,
172 double*,double*,double*,double*);
173 Private int ttf_get_fontbbx2(VF_FONT font, double,double,
174 int*,int*,int*,int*);
175 Private VF_BITMAP ttf_get_bitmap1(VF_FONT,long,double,double);
176 Private VF_BITMAP ttf_get_bitmap2(VF_FONT,long,double,double);
177 Private VF_OUTLINE ttf_get_outline1(VF_FONT,long,double,double);
178 Private char *ttf_get_font_prop(VF_FONT,char*);
179
180 Private VF_OUTLINE
181 get_outline_ttf_to_vflib(FONT_TTF,TT_Outline*,
182 TT_Glyph_Metrics*, TT_Instance_Metrics*,
183 double ps, double mag_x, double mag_y,
184 double dpix, double dpiy, double asp);
185 Private long fix_jisx0212_row47_empty_sjis(long code_point);
186 Private int find_encoding_mapping(FONT_TTF);
187 Private int get_id_from_platform_name(char*);
188 Private int get_id_from_encoding_name(char*,int);
189 Private int name2id(char*,ID_NAME_TBL,int,char*);
190 Private char* conv_encoding_ttf_to_vflib(int ttf_enc, int plat);
191 Private char* platform_id2name(int plat_id);
192 Private char* encoding_id2name(int,int);
193 Private int ttf_debug(char);
194
195
196
197
198 static TT_Engine FreeType_Engine;
199 static int Initialized_FreeType = 0;
200
201
202
203 Public int
204 VF_Init_Driver_TrueType(void)
/* [<][>][^][v][top][bottom][index][help] */
205 {
206 TT_Error error;
207 char *p;
208 struct s_capability_table ct[20];
209 int z;
210
211 z = 0;
212 /* VF_CAPE_FONT_DIRECTORIES */
213 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
214 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_fontdirs;
215 /* VF_CAPE_POINT_SIZE */
216 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
217 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_point_size;
218 /* VF_CAPE_PIXEL_SIZE */
219 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
220 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_pixel_size;
221 /* VF_CAPE_DPI */
222 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
223 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi;
224 /* VF_CAPE_DPI_X */
225 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
226 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_x;
227 /* VF_CAPE_DPI_Y */
228 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
229 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_dpi_y;
230 /* VF_CAPE_ASPECT_RATIO */
231 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
232 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_aspect;
233 /* VF_CAPE_DIRECTION */
234 ct[z].cap = VF_CAPE_DIRECTION; ct[z].type = CAPABILITY_STRING;
235 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_direction;
236 /* VF_CAPE_TTF_PLATFORM_ID */
237 ct[z].cap = VF_CAPE_TTF_PLATFORM_ID; ct[z].type = CAPABILITY_STRING;
238 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_platform_id;
239 /* VF_CAPE_TTF_ENCODING_ID */
240 ct[z].cap = VF_CAPE_TTF_ENCODING_ID; ct[z].type = CAPABILITY_STRING;
241 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_encoding_id;
242 /* VF_CAPE_TTF_HINTING */
243 ct[z].cap = VF_CAPE_TTF_HINTING; ct[z].type = CAPABILITY_STRING;
244 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_hinting;
245 /* VF_CAPE_PROPERTIES */
246 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
247 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
248 /* VF_CAPE_VARIABLE_VALUES */
249 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
250 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
251 /* VF_CAPE_DEBUG */
252 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
253 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
254 /* end */
255 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
256
257 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL)
258 == VFLIBCAP_PARSED_ERROR)
259 return -1;
260
261 if (Initialized_FreeType == 0){
262 error = TT_Init_FreeType(&FreeType_Engine);
263 if (error){
264 vf_error = VF_ERR_FREETYPE_INIT;
265 return -1;
266 }
267 Initialized_FreeType = 1;
268 }
269
270 v_default_point_size = DEFAULT_POINT_SIZE;
271 if (default_point_size != NULL)
272 v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
273 if (v_default_point_size < 0)
274 v_default_point_size = DEFAULT_POINT_SIZE;
275
276 v_default_pixel_size = DEFAULT_PIXEL_SIZE;
277 if (default_pixel_size != NULL)
278 v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
279 if (v_default_pixel_size < 0)
280 v_default_pixel_size = DEFAULT_PIXEL_SIZE;
281
282 v_default_dpi_x = VF_DEFAULT_DPI;
283 v_default_dpi_y = VF_DEFAULT_DPI;
284 if (default_dpi != NULL)
285 v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
286 if (default_dpi_x != NULL)
287 v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
288 if (default_dpi_y != NULL)
289 v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
290 if (v_default_dpi_x < 0)
291 v_default_dpi_x = VF_DEFAULT_DPI;
292 if (v_default_dpi_y < 0)
293 v_default_dpi_y = VF_DEFAULT_DPI;
294
295 v_default_aspect = 1.0;
296 if (default_aspect != NULL)
297 v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
298 if (v_default_aspect < 0)
299 v_default_aspect = 1.0;
300
301 v_default_direction = DEFAULT_DIRECTION;
302 if (default_direction != NULL){
303 p = vf_sexp_get_cstring(default_direction);
304 switch (*p){
305 case 'h': case 'H':
306 v_default_direction = DIRECTION_HORIZONTAL;
307 break;
308 case 'v': case 'V':
309 v_default_direction = DIRECTION_VERTICAL;
310 break;
311 default:
312 fprintf(stderr, "VFlib Warning: Unknown writing direction: %s\n", p);
313 break;
314 }
315 }
316
317 v_default_platform_id = TT_PLAT_ID_MICROSOFT;
318 if (default_platform_id != NULL)
319 v_default_platform_id
320 = get_id_from_platform_name(vf_sexp_get_cstring(default_platform_id));
321
322 v_default_encoding_id = TT_ENC_ID_ANY;
323 if (default_encoding_id != NULL)
324 v_default_encoding_id
325 = get_id_from_encoding_name(vf_sexp_get_cstring(default_encoding_id),
326 v_default_platform_id);
327
328 v_default_hinting = TRUE;
329 if (default_hinting != NULL){
330 v_default_hinting = vf_parse_bool(vf_sexp_get_cstring(default_hinting));
331 }
332
333 env_debug_mode = getenv(DEBUG_ENV_NAME);
334
335 VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)ttf_create);
336
337 return 0;
338 }
339
340
341 Private int
342 ttf_create(VF_FONT font, char *font_class, char *font_name,
/* [<][>][^][v][top][bottom][index][help] */
343 int implicit, SEXP entry)
344 {
345 FONT_TTF font_ttf;
346 char *font_file, *font_path, *p;
347 int val;
348 SEXP cap_fontdirs, cap_font, cap_point, cap_pixel;
349 SEXP cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
350 SEXP cap_font_number, cap_direction, cap_platform_id, cap_encoding_id;
351 SEXP cap_hinting, cap_mapping_id, cap_encoding_force;
352 SEXP cap_jisx0212_r47e_sjis;
353 SEXP cap_charset, cap_encoding, cap_props;
354 struct s_capability_table ct[30];
355 int z;
356
357 z = 0;
358 /* VF_CAPE_FONT_CLASS */
359 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
360 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
361 /* VF_CAPE_FONT_DIRECTORIES */
362 ct[z].cap = VF_CAPE_FONT_DIRECTORIES; ct[z].type = CAPABILITY_STRING_LIST1;
363 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_fontdirs;
364 /* VF_CAPE_FONT_FILE */
365 ct[z].cap = VF_CAPE_FONT_FILE; ct[z].type = CAPABILITY_STRING;
366 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font;
367 /* VF_CAPE_POINT_SIZE */
368 ct[z].cap = VF_CAPE_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
369 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_point;
370 /* VF_CAPE_PIXEL_SIZE */
371 ct[z].cap = VF_CAPE_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
372 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_pixel;
373 /* VF_CAPE_DPI */
374 ct[z].cap = VF_CAPE_DPI; ct[z].type = CAPABILITY_STRING;
375 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi;
376 /* VF_CAPE_DPI_X */
377 ct[z].cap = VF_CAPE_DPI_X; ct[z].type = CAPABILITY_STRING;
378 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_x;
379 /* VF_CAPE_DPI_Y */
380 ct[z].cap = VF_CAPE_DPI_Y; ct[z].type = CAPABILITY_STRING;
381 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_dpi_y;
382 /* VF_CAPE_MAG */
383 ct[z].cap = VF_CAPE_MAG; ct[z].type = CAPABILITY_STRING;
384 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mag;
385 /* VF_CAPE_ASPECT_RATIO */
386 ct[z].cap = VF_CAPE_ASPECT_RATIO; ct[z].type = CAPABILITY_STRING;
387 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_aspect;
388 /* VF_CAPE_DIRECTION */
389 ct[z].cap = VF_CAPE_DIRECTION; ct[z].type = CAPABILITY_STRING;
390 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_direction;
391 /* VF_CAPE_TTF_FONT_NUMBER */
392 ct[z].cap = VF_CAPE_TTF_FONT_NUMBER; ct[z].type = CAPABILITY_STRING;
393 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_font_number;
394 /* VF_CAPE_TTF_PLATFORM_ID */
395 ct[z].cap = VF_CAPE_TTF_PLATFORM_ID; ct[z].type = CAPABILITY_STRING;
396 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_platform_id;
397 /* VF_CAPE_TTF_ENCODING_ID */
398 ct[z].cap = VF_CAPE_TTF_ENCODING_ID; ct[z].type = CAPABILITY_STRING;
399 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_encoding_id;
400 /* VF_CAPE_TTF_MAPPING_ID */
401 ct[z].cap = VF_CAPE_TTF_MAPPING_ID; ct[z].type = CAPABILITY_STRING;
402 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_mapping_id;
403 /* VF_CAPE_TTF_HINTING */
404 ct[z].cap = VF_CAPE_TTF_HINTING; ct[z].type = CAPABILITY_STRING;
405 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_hinting;
406 /* VF_CAPE_TTF_ENCODING_FORCE */
407 ct[z].cap = VF_CAPE_TTF_ENCODING_FORCE; ct[z].type = CAPABILITY_STRING;
408 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_encoding_force;
409 /* VF_CAPE_CHARSET */
410 ct[z].cap = VF_CAPE_CHARSET; ct[z].type = CAPABILITY_STRING;
411 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_charset;
412 /* VF_CAPE_ENCODING */
413 ct[z].cap = VF_CAPE_ENCODING; ct[z].type = CAPABILITY_STRING;
414 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_encoding;
415 /* VF_CAPE_TTF_JISX0212_R47E_SJIS */
416 ct[z].cap = VF_CAPE_TTF_JISX0212_R47ES; ct[z].type = CAPABILITY_STRING;
417 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_jisx0212_r47e_sjis;
418 /* VF_CAPE_PROPERTIES */
419 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
420 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
421 /* end */
422 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
423
424
425 if (implicit == 1){ /* implicit font */
426 font_file = font_name;
427 } else { /* explicit font */
428 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
429 default_variables, NULL) < 0)
430 return -1;
431 if (cap_font == NULL){
432 /* Use font name as font file name if font file name is not given. */
433 font_file = font_name;
434 } else {
435 font_file = vf_sexp_get_cstring(cap_font);
436 }
437 }
438
439 val = -1;
440
441 font_path = NULL;
442 if ((implicit == 0) && (cap_fontdirs != NULL)){
443 font_path = vf_search_file(font_file, -1, NULL,
444 TRUE, FSEARCH_FORMAT_TYPE_TTF,
445 cap_fontdirs, NULL, NULL);
446 }
447 if (font_path == NULL){
448 font_path = vf_search_file(font_file, -1, NULL,
449 TRUE, FSEARCH_FORMAT_TYPE_TTF,
450 default_fontdirs, NULL, NULL);
451 }
452 if (font_path == NULL){
453 vf_error = VF_ERR_NO_FONT_FILE;
454 return -1;
455 }
456
457 if (ttf_debug('f'))
458 printf("VFlib TrueType: font file %s\n ==> %s\n", font_file, font_path);
459
460 font->font_type = VF_FONT_TYPE_OUTLINE;
461 font->get_metric1 = ttf_get_metric1;
462 font->get_metric2 = ttf_get_metric2;
463 font->get_fontbbx1 = ttf_get_fontbbx1;
464 font->get_fontbbx2 = ttf_get_fontbbx2;
465 font->get_bitmap1 = ttf_get_bitmap1;
466 font->get_bitmap2 = ttf_get_bitmap2;
467 font->get_outline = ttf_get_outline1;
468 font->get_font_prop = ttf_get_font_prop;
469 font->query_font_type = NULL; /* Use font->font_type value. */
470 font->close = ttf_close;
471
472 ALLOC_IF_ERR(font_ttf, struct s_font_ttf){
473 vf_error = VF_ERR_NO_MEMORY;
474 return -1;
475 }
476 font->private = font_ttf;
477
478 font_ttf->release_on_close = 0;
479 font_ttf->ttf_opened = 0;
480 font_ttf->font_name = NULL;
481 font_ttf->file_path = font_path;
482 font_ttf->point_size = v_default_point_size;
483 font_ttf->pixel_size = v_default_pixel_size;
484 font_ttf->mag = 1.0;
485 font_ttf->dpi_x = v_default_dpi_x;
486 font_ttf->dpi_y = v_default_dpi_y;
487 font_ttf->aspect = v_default_aspect;
488 font_ttf->direction = v_default_direction;
489 font_ttf->font_number = -1;
490 font_ttf->platform_id = v_default_platform_id;
491 font_ttf->encoding_id = v_default_encoding_id;
492 font_ttf->mapping_id = TT_MAP_ID_SEARCH;
493 font_ttf->encoding_force = -1;
494 font_ttf->hinting = v_default_hinting;
495 font_ttf->charset_name = NULL;
496 font_ttf->encoding_name = NULL;
497
498 if (implicit == 0){
499 if (cap_point != NULL)
500 font_ttf->point_size = atof(vf_sexp_get_cstring(cap_point));
501 if (cap_pixel != NULL)
502 font_ttf->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
503 if (cap_dpi != NULL)
504 font_ttf->dpi_x = font_ttf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
505 if (cap_dpi_x != NULL)
506 font_ttf->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
507 if (cap_dpi_y != NULL)
508 font_ttf->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
509 if (cap_mag != NULL)
510 font_ttf->mag = atof(vf_sexp_get_cstring(cap_mag));
511 if (cap_aspect != NULL)
512 font_ttf->aspect = atof(vf_sexp_get_cstring(cap_aspect));
513 if (cap_direction != NULL){
514 p = vf_sexp_get_cstring(cap_direction);
515 switch (*p){
516 case 'h': case 'H':
517 font_ttf->direction = DIRECTION_HORIZONTAL; break;
518 case 'v': case 'V':
519 font_ttf->direction = DIRECTION_VERTICAL; break;
520 default:
521 fprintf(stderr, "VFlib Warning: Unknown writing direction: %s\n", p);
522 break;
523 }
524 }
525 if (cap_font_number != NULL)
526 font_ttf->font_number = atoi(vf_sexp_get_cstring(cap_font_number));
527 if (cap_platform_id != NULL)
528 font_ttf->platform_id
529 = get_id_from_platform_name(vf_sexp_get_cstring(cap_platform_id));
530 if (cap_encoding_id != NULL)
531 font_ttf->encoding_id
532 = get_id_from_encoding_name(vf_sexp_get_cstring(cap_encoding_id),
533 font_ttf->platform_id);
534 if (cap_mapping_id != NULL)
535 font_ttf->mapping_id = atoi(vf_sexp_get_cstring(cap_mapping_id));
536 if (cap_encoding_force != NULL)
537 font_ttf->encoding_force
538 = get_id_from_encoding_name(vf_sexp_get_cstring(cap_encoding_force),
539 font_ttf->platform_id);
540 if (cap_charset != NULL)
541 font_ttf->charset_name = vf_strdup(vf_sexp_get_cstring(cap_charset));
542 if (cap_encoding != NULL)
543 font_ttf->encoding_name = vf_strdup(vf_sexp_get_cstring(cap_encoding));
544 if (cap_props != NULL)
545 font_ttf->props = cap_props;
546 if (cap_hinting != NULL){
547 font_ttf->hinting = vf_parse_bool(vf_sexp_get_cstring(cap_hinting));
548 }
549 if (cap_jisx0212_r47e_sjis != NULL){
550 font_ttf->jisx0212_r47e_sjis
551 = vf_parse_bool(vf_sexp_get_cstring(cap_jisx0212_r47e_sjis));
552 }
553 }
554
555 if ((font_ttf->font_name = vf_strdup(font_name)) == NULL){
556 vf_error = VF_ERR_NO_MEMORY;
557 goto Error;
558 }
559
560 if (vf_fm_OpenFileStreamApp(font_ttf->file_path,
561 font_ttf->font_number, -1, font, font_ttf,
562 (FM_OPEN_METHOD)ttf_open_method,
563 (FM_CLOSE_METHOD)ttf_close_method,
564 "FreeType") == NULL)
565 goto Error;
566
567 font_ttf->ccv_id = find_encoding_mapping(font_ttf);
568
569 val = 0;
570
571 Error:
572 if (implicit == 0){ /* explicit font */
573 vf_sexp_free4(&cap_fontdirs, &cap_font, &cap_point, &cap_pixel);
574 vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
575 vf_sexp_free3(&cap_mag, &cap_aspect, &cap_direction);
576 vf_sexp_free3(&cap_platform_id, &cap_encoding_id, &cap_hinting);
577 vf_sexp_free3(&cap_mapping_id, &cap_encoding_force, &cap_charset);
578 vf_sexp_free1(&cap_encoding);
579 vf_sexp_free1(&cap_jisx0212_r47e_sjis);
580 }
581
582 if ((val != 0) && (font_ttf != NULL)){
583 vf_sexp_free1(&cap_props);
584 vf_free(font_ttf->font_name);
585 vf_free(font_ttf->file_path);
586 vf_free(font_ttf->charset_name);
587 vf_free(font_ttf->encoding_name);
588 vf_free(font_ttf);
589 }
590
591 return val;
592 }
593
594
595 Private int
596 ttf_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
597 {
598 FONT_TTF font_ttf;
599
600 if ((font_ttf = (FONT_TTF)font->private) != NULL){
601 vf_free(font_ttf->charset_name);
602 vf_free(font_ttf->encoding_name);
603 font_ttf->release_on_close = 1;
604 /* `font_ttf' and `font_ttf->font_name' are
605 released in ttf_close_method() */
606 }
607 return 0;
608 }
609
610 Private TT_Face*
611 ttf_open_method(char *font_path, long fontnum, long iarg2,
/* [<][>][^][v][top][bottom][index][help] */
612 VF_FONT font, FONT_TTF font_ttf)
613 {
614 TT_Error error;
615
616 if (font_ttf == NULL)
617 return NULL;
618
619 if (font_ttf->ttf_opened == 0){
620 if (fontnum < 0){
621 if (ttf_debug('f'))
622 printf("VFlib TrueType: TT_Open_Face %s\n", font_ttf->font_name);
623 error = TT_Open_Face(FreeType_Engine, font_path,
624 &font_ttf->tt_face);
625 } else {
626 if (ttf_debug('f'))
627 printf("VFlib TrueType: TT_Open_Collection %s, %ld\n",
628 font_ttf->font_name, fontnum);
629 error = TT_Open_Collection(FreeType_Engine, font_path,
630 fontnum, &font_ttf->tt_face);
631 }
632 if (error)
633 return NULL;
634
635 font_ttf->ttf_opened = 1;
636
637 (void) TT_Get_Face_Properties(font_ttf->tt_face, &font_ttf->tt_fprops);
638 font_ttf->tt_upem = font_ttf->tt_fprops.header->Units_Per_EM;
639
640 if (ttf_debug('n'))
641 printf("VFlib TrueType: the number of embedded faces: %ld\n",
642 (long)font_ttf->tt_fprops.num_Faces);
643
644 error = TT_New_Glyph(font_ttf->tt_face, &font_ttf->tt_glyph);
645 if (error)
646 return NULL;
647 error = TT_New_Instance(font_ttf->tt_face, &font_ttf->tt_instance);
648 if (error)
649 return NULL;
650 }
651
652 return &font_ttf->tt_face;
653 }
654
655 Private void
656 ttf_close_method(TT_Face *ttface, long iarg1, long iarg2,
/* [<][>][^][v][top][bottom][index][help] */
657 VF_FONT font, FONT_TTF font_ttf)
658 {
659 if (font_ttf->release_on_close == 0){
660 /* close temporality by the limitation of
661 the number of simultaneously opened files */
662 if (ttf_debug('f'))
663 printf("VFlib TrueType: TT_Flush_Face %s\n", font_ttf->font_name);
664 TT_Flush_Face(font_ttf->tt_face);
665 } else {
666 /* after a font is closed */
667 if (ttf_debug('f'))
668 printf("VFlib TrueType: TT_Close_Face %s\n", font_ttf->font_name);
669 TT_Done_Glyph(font_ttf->tt_glyph);
670 TT_Done_Instance(font_ttf->tt_instance);
671 TT_Close_Face(font_ttf->tt_face);
672 vf_free(font_ttf->font_name);
673 vf_free(font_ttf->file_path);
674 vf_free(font_ttf);
675 }
676 }
677
678
679 Private int
680 ttf_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
681 double mag_x, double mag_y)
682 {
683 if (ttf_get_xxx(MODE_METRIC1, font, code_point, mag_x, mag_y,
684 metric, NULL, NULL, NULL) == NULL)
685 return -1;
686 return 0;
687 }
688
689 Private int
690 ttf_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
691 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
692 {
693 struct s_fontbbx1 bbx1;
694
695 if (ttf_get_xxx(MODE_FONTBBX1, font, -1, mag_x, mag_y,
696 NULL, NULL, &bbx1, NULL) == NULL)
697 return -1;
698
699 *w_p = bbx1.w;
700 *h_p = bbx1.h;
701 *xoff_p = bbx1.xoff;
702 *yoff_p = bbx1.yoff;
703 return 0;
704 }
705
706 Private VF_BITMAP
707 ttf_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
708 double mag_x, double mag_y)
709 {
710 return (VF_BITMAP)ttf_get_xxx(MODE_BITMAP1, font, code_point, mag_x, mag_y,
711 NULL, NULL, NULL, NULL);
712 }
713
714
715 Private VF_OUTLINE
716 ttf_get_outline1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
717 double mag_x, double mag_y)
718 {
719 return (VF_OUTLINE)ttf_get_xxx(MODE_OUTLINE, font, code_point, mag_x, mag_y,
720 NULL, NULL, NULL, NULL);
721 }
722
723
724 Private int
725 ttf_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
726 double mag_x, double mag_y)
727 {
728 if (ttf_get_xxx(MODE_METRIC2, font, code_point, mag_x, mag_y,
729 NULL, metric, NULL, NULL) == NULL)
730 return -1;
731 return 0;
732 }
733
734 Private int
735 ttf_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
736 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
737 {
738 struct s_fontbbx2 bbx2;
739
740 if (ttf_get_xxx(MODE_FONTBBX2, font, -1, mag_x, mag_y,
741 NULL, NULL, NULL, &bbx2) == NULL)
742 return -1;
743
744 *w_p = bbx2.w;
745 *h_p = bbx2.h;
746 *xoff_p = bbx2.xoff;
747 *yoff_p = bbx2.yoff;
748 return 0;
749 }
750
751 Private VF_BITMAP
752 ttf_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
753 double mag_x, double mag_y)
754 {
755 return (VF_BITMAP)ttf_get_xxx(MODE_BITMAP2,
756 font, code_point, mag_x, mag_y,
757 NULL, NULL, NULL, NULL);
758 }
759
760
761 Private void*
762 ttf_get_xxx(int mode,
/* [<][>][^][v][top][bottom][index][help] */
763 VF_FONT font, long code_point,
764 double mag_x, double mag_y,
765 VF_METRIC1 metric1, VF_METRIC2 metric2,
766 FONTBBX1 fontbbx1, FONTBBX2 fontbbx2)
767 {
768 FONT_TTF font_ttf;
769 VF_BITMAP bm;
770 VF_OUTLINE ol;
771 void *val;
772 double ps = 0.0, mx, my, asp, aspd;
773 double dpix = 0.0, dpiy = 0.0;
774 long cp;
775 int chindex;
776 int load_flag;
777 TT_Raster_Map tt_bitmap;
778 TT_Glyph_Metrics tt_metrics;
779 TT_Instance_Metrics tt_imetrics;
780 TT_Outline tt_outline;
781 TT_Short xoff, yoff;
782 TT_Error error;
783
784 error = 0;
785
786 if ((font_ttf = (FONT_TTF)font->private) == NULL){
787 fprintf(stderr, "VFlib: Internal error in ttf_get_xxx()\n");
788 abort();
789 }
790
791 mx = mag_x * font_ttf->mag * font->mag_x;
792 my = mag_y * font_ttf->mag * font->mag_y;
793 asp = v_default_aspect * font_ttf->aspect * (mx / my);
794
795 if ( (mode == MODE_METRIC1)
796 || (mode == MODE_FONTBBX1)
797 || (mode == MODE_BITMAP1)
798 || (mode == MODE_OUTLINE) ){
799 if (((dpix = font->dpi_x) <= 0) || ((dpiy = font->dpi_y) <= 0)){
800 dpix = font_ttf->dpi_x;
801 dpiy = font_ttf->dpi_y;
802 }
803 if ((ps = font->point_size) < 0)
804 ps = font_ttf->point_size;
805 ps = ps * my;
806 } else if ( (mode == MODE_METRIC2)
807 || (mode == MODE_FONTBBX2)
808 || (mode == MODE_BITMAP2) ){
809 if ((ps = font->pixel_size) < 0)
810 ps = font_ttf->pixel_size;
811 ps = ps * my;
812 dpix = POINTS_PER_INCH;
813 dpiy = POINTS_PER_INCH;
814 }
815
816 vf_fm_OpenFileStreamApp(font_ttf->file_path,
817 font_ttf->font_number, -1, font, font_ttf,
818 (FM_OPEN_METHOD)ttf_open_method,
819 (FM_CLOSE_METHOD)ttf_close_method, "FreeType");
820
821 if (mode != MODE_OUTLINE){
822 TT_Set_Instance_Resolutions(font_ttf->tt_instance, dpix, dpiy);
823 error = TT_Set_Instance_PointSize(font_ttf->tt_instance, ps);
824 } else {
825 TT_Set_Instance_Resolutions(font_ttf->tt_instance,
826 96*4, 96*4); /*XXX THESE ARE AD-HOC VALUES!!*/
827 error = TT_Set_Instance_PointSize(font_ttf->tt_instance, 12);
828 }
829 if (error){
830 vf_error = VF_ERR_NO_GLYPH;
831 return NULL;
832 }
833
834
835 if ((mode == MODE_FONTBBX1) || (mode == MODE_FONTBBX2)){
836 chindex = -1;
837 } else {
838 cp = code_point;
839 if (font_ttf->ccv_id >= 0)
840 cp = vf_ccv_conv(font_ttf->ccv_id, code_point);
841
842 if (ttf_debug('c'))
843 printf("VFlib TrueType: CCV 0x%lx => 0x%lx\n", code_point, cp);
844
845 if (font_ttf->jisx0212_r47e_sjis == TRUE){
846 cp = fix_jisx0212_row47_empty_sjis(cp);
847 }
848
849 chindex = TT_Char_Index(font_ttf->tt_charmap, (int)cp);
850 if (chindex <= 0){
851 vf_error = VF_ERR_ILL_CODE_POINT;
852 return NULL;
853 }
854 if (ttf_debug('i'))
855 printf("VFlib TrueType: charindex 0x%x (code point 0x%lx)\n",
856 chindex, code_point);
857
858 if (font_ttf->hinting == TRUE)
859 load_flag = TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH;
860 else
861 load_flag = TTLOAD_SCALE_GLYPH;
862 error = TT_Load_Glyph(font_ttf->tt_instance, font_ttf->tt_glyph,
863 chindex, load_flag);
864 if (error){
865 vf_error = VF_ERR_NO_GLYPH;
866 return NULL;
867 }
868 (void) TT_Get_Glyph_Metrics(font_ttf->tt_glyph, &tt_metrics);
869 }
870
871 (void) TT_Get_Instance_Metrics(font_ttf->tt_instance, &tt_imetrics);
872
873 if (ttf_debug('m')){
874 printf("VFlib TrueType: Metrics\n");
875 printf(" in Header upem: %d, xMin: %d, yMin:%d, xMax:%d, yMax:%d\n",
876 font_ttf->tt_fprops.header->Units_Per_EM,
877 font_ttf->tt_fprops.header->xMin,
878 font_ttf->tt_fprops.header->yMin,
879 font_ttf->tt_fprops.header->xMax,
880 font_ttf->tt_fprops.header->yMax);
881 printf(" tt_metrics.bbx xMin:%ld, yMin:%ld, xMax:%ld, yMax:%ld\n",
882 tt_metrics.bbox.xMin, tt_metrics.bbox.yMin,
883 tt_metrics.bbox.xMax, tt_metrics.bbox.yMax);
884 printf(" tt_imetrics x_ppem:%d, y_ppem:%d, pointSize:%.4f, upem:%d\n",
885 tt_imetrics.x_ppem, tt_imetrics.y_ppem,
886 (double)tt_imetrics.pointSize/64.0, font_ttf->tt_upem);
887 }
888
889 val = NULL;
890 if ((mode == MODE_BITMAP1) || (mode == MODE_BITMAP2)){
891 tt_bitmap.width = (tt_metrics.bbox.xMax-tt_metrics.bbox.xMin)*asp/64 + 1;
892 tt_bitmap.rows = (tt_metrics.bbox.yMax-tt_metrics.bbox.yMin)/64 + 1;
893 tt_bitmap.cols = (tt_bitmap.width + 7) >> 3;
894 tt_bitmap.size = tt_bitmap.cols * tt_bitmap.rows;
895 tt_bitmap.bitmap = (void *) malloc(tt_bitmap.size);
896 tt_bitmap.flow = TT_Flow_Down;
897 (void)memclr((char*) tt_bitmap.bitmap, tt_bitmap.size);
898 xoff = -tt_metrics.bbox.xMin;
899 yoff = -tt_metrics.bbox.yMin;
900 aspd = 1.0 - asp;
901 if (aspd < 0)
902 aspd = 0.0 - aspd;
903 if (aspd < 1.0e-6){
904 error = TT_Get_Glyph_Bitmap(font_ttf->tt_glyph, &tt_bitmap, xoff, yoff);
905 if (error)
906 return NULL;
907 } else {
908 TT_Matrix mat;
909 mat.xx = asp * (1<<16); mat.xy = 0;
910 mat.yx = 0; mat.yy = 1 * (1<<16);
911 TT_Get_Glyph_Outline(font_ttf->tt_glyph, &tt_outline);
912 TT_Transform_Outline(&tt_outline, &mat);
913 TT_Translate_Outline(&tt_outline,
914 -asp*tt_metrics.bbox.xMin, -tt_metrics.bbox.yMin);
915 error = TT_Get_Outline_Bitmap(FreeType_Engine, &tt_outline, &tt_bitmap);
916 TT_Done_Outline(&tt_outline);
917 }
918 ALLOC_IF_ERR(bm, struct vf_s_bitmap){
919 vf_error = VF_ERR_NO_MEMORY;
920 return NULL;
921 }
922 bm->bbx_width = tt_bitmap.width;
923 bm->bbx_height = tt_bitmap.rows;
924 bm->raster = tt_bitmap.cols;
925 bm->bitmap = (unsigned char*)tt_bitmap.bitmap;
926 bm->off_x = tt_metrics.bearingX * asp / 64;
927 bm->off_y = tt_metrics.bbox.yMax / 64;
928 bm->mv_x = tt_metrics.advance * asp / 64;
929 bm->mv_y = 0;
930 val = (void*) bm;
931
932 } else if (mode == MODE_METRIC1){
933 double xppem = 64.0 * (double)tt_imetrics.x_ppem;
934 double yppem = 64.0 * (double)tt_imetrics.y_ppem;
935 double pt = (double)tt_imetrics.pointSize / 64.0;
936 double ptx = (double)tt_imetrics.pointSize * asp / 64.0;
937 if (metric1 != NULL){
938 metric1->bbx_width
939 = (double)((tt_metrics.bbox.xMax - tt_metrics.bbox.xMin) / xppem)*ptx;
940 metric1->bbx_height
941 = (double)((tt_metrics.bbox.yMax - tt_metrics.bbox.yMin) / yppem)*pt;
942 metric1->off_x = (double)(tt_metrics.bearingX / xppem) * ptx;
943 metric1->off_y = (double)(tt_metrics.bbox.yMax / yppem) * pt;
944 metric1->mv_x = (double)(tt_metrics.advance / xppem) * ptx; /*XXX*/
945 metric1->mv_y = 0.0 * pt; /*XXX*/
946 }
947 val = (void*) metric1;
948
949 } else if (mode == MODE_METRIC2){
950 if (metric2 != NULL){
951 metric2->bbx_width
952 = toint((double)(tt_metrics.bbox.xMax-tt_metrics.bbox.xMin)*asp /64.0);
953 metric2->bbx_height
954 = toint((double)(tt_metrics.bbox.yMax-tt_metrics.bbox.yMin) /64.0);
955 metric2->off_x = toint((double)tt_metrics.bearingX * asp / 64.0);
956 metric2->off_y = toint((double)tt_metrics.bbox.yMax / 64.0);
957 metric2->mv_x = toint((double)tt_metrics.advance * asp / 64.0);
958 metric2->mv_y = 0.0;
959 }
960 val = (void*) metric2;
961
962 } else if (mode == MODE_OUTLINE){
963 error = TT_Get_Glyph_Outline(font_ttf->tt_glyph, &tt_outline);
964 if (error)
965 return NULL;
966 ol = get_outline_ttf_to_vflib(font_ttf,
967 &tt_outline, &tt_metrics, &tt_imetrics,
968 ps, mag_x, mag_y, dpix, dpiy, asp);
969 TT_Done_Outline(&tt_outline);
970 val = (void*) ol;
971
972 } else if (mode == MODE_FONTBBX1){
973 long xmax = font_ttf->tt_fprops.header->xMax;
974 long xmin = font_ttf->tt_fprops.header->xMin;
975 long ymax = font_ttf->tt_fprops.header->yMax;
976 long ymin = font_ttf->tt_fprops.header->yMin;
977 if (fontbbx1 != NULL){
978 fontbbx1->w = (double)(xmax - xmin) * ps * asp / font_ttf->tt_upem;
979 fontbbx1->h = (double)(ymax - ymin) * ps / font_ttf->tt_upem;
980 fontbbx1->xoff = (double) xmin * ps * asp / font_ttf->tt_upem;
981 fontbbx1->yoff = (double) ymin * ps / font_ttf->tt_upem;
982 }
983 val = (void*) fontbbx1;
984
985 } else if (mode == MODE_FONTBBX2){
986 long xmax = font_ttf->tt_fprops.header->xMax;
987 long xmin = font_ttf->tt_fprops.header->xMin;
988 long ymax = font_ttf->tt_fprops.header->yMax;
989 long ymin = font_ttf->tt_fprops.header->yMin;
990 if (fontbbx2 != NULL){
991 fontbbx2->w = (double)(xmax - xmin) * ps * asp / font_ttf->tt_upem;
992 fontbbx2->h = (double)(ymax - ymin) * ps / font_ttf->tt_upem;
993 fontbbx2->xoff = (double) xmin * ps * asp / font_ttf->tt_upem;
994 fontbbx2->yoff = (double) ymin * ps / font_ttf->tt_upem;
995 }
996 val = (void*) fontbbx2;
997
998 } else {
999 fprintf(stderr, "VFlib: Internal error in ttf_get_xxx1()\n");
1000 fprintf(stderr, "Unknown mode: %d\n", mode);
1001 abort();
1002 }
1003
1004 return val;
1005 }
1006
1007 Private long
1008 fix_jisx0212_row47_empty_sjis(long code_point)
/* [<][>][^][v][top][bottom][index][help] */
1009 {
1010 unsigned int c1, c2;
1011 int row_offset, cell_offset, adjust;
1012
1013 if (code_point < 256)
1014 return code_point;
1015
1016 c1 = code_point / 0x100;
1017 c2 = code_point % 0x100;
1018
1019 /* SJIS->JIS */
1020 if (c2 < 159)
1021 adjust = 1;
1022 else
1023 adjust = 0;
1024 row_offset = (c1 < 160) ? 112 : 176;
1025 cell_offset = (adjust == 1) ? ((c2 > 127) ? 32 : 31) : 126;
1026 c1 = ((c1 - row_offset) << 1) - adjust;
1027 c2 -= cell_offset;
1028
1029 /* Fix */
1030 if (c1 >= (47 + 0x20))
1031 c1++;
1032
1033 /* JIS -> SJIS */
1034 row_offset = (c1 < 95) ? 112 : 176;
1035 cell_offset = (c1 % 2) ? ((c2 > 95) ? 32 : 31) : 126;
1036 c1 = ((c1 + 1) >> 1) + row_offset;
1037 c2 += cell_offset;
1038
1039 return c1*0x100 + c2;
1040 }
1041
1042
1043 /*
1044 * The following routine is snarfed from VF_Ftype.c
1045 * in VFlib 2.23 by Mr Matsuda.
1046 * --- H.Kakugawa
1047 */
1048 Private VF_OUTLINE
1049 get_outline_ttf_to_vflib(FONT_TTF font_ttf,
/* [<][>][^][v][top][bottom][index][help] */
1050 TT_Outline *tt_outline,
1051 TT_Glyph_Metrics *tt_metrics,
1052 TT_Instance_Metrics *tt_imetrics,
1053 double ps, double mag_x, double mag_y,
1054 double dpix, double dpiy, double asp)
1055 {
1056 int vfsize, ct, pt, sp, ep, p1, p2, p3;
1057 int maxw, maxh, bbx;
1058 double x1, y1, x2, y2, x3, y3, f, fupem, mmm;
1059 VF_OUTLINE_ELEM token, *vfdata, *vfp;
1060
1061 mmm = 4*4; /*ad-hoc*/
1062
1063 maxw = (tt_metrics->bbox.xMax - tt_metrics->bbox.xMin + 1);
1064 maxh = (tt_metrics->bbox.yMax - tt_metrics->bbox.yMin + 1);
1065 if ((bbx = maxw) < maxh)
1066 bbx = maxh;
1067
1068 #if 0
1069 printf("*** %d %d %d %d %d %d %d %d\n",
1070 maxw, maxh, bbx, font_ttf->tt_upem,
1071 font_ttf->tt_fprops.header->xMin, font_ttf->tt_fprops.header->yMin,
1072 font_ttf->tt_fprops.header->xMax, font_ttf->tt_fprops.header->yMax);
1073 #endif
1074 #if 0
1075 printf("*** %.3f %.3f %.3f %ld %ld %ld %ld\n",
1076 tt_metrics->advance/64.0,
1077 tt_metrics->bearingX/64.0, tt_metrics->bearingY/64.0,
1078 tt_metrics->bbox.xMax/64, tt_metrics->bbox.xMin/64,
1079 tt_metrics->bbox.yMax/64, tt_metrics->bbox.yMin/64);
1080 printf(" %.3f %.3f\n",
1081 (double)tt_imetrics->x_ppem / font_ttf->tt_upem,
1082 (double)tt_imetrics->y_ppem / font_ttf->tt_upem);
1083 #endif
1084
1085 vfsize = VF_OL_OUTLINE_HEADER_SIZE_TYPE0;
1086 for (ct = pt = 0; ct < tt_outline->n_contours; ct++){
1087 token = 0L;
1088 sp = pt;
1089 ep = tt_outline->contours[ct];
1090 for (; pt <= ep; pt++) {
1091 p1 = pt;
1092 p2 = (p1 < ep)? (p1 + 1) : sp;
1093 #if 0
1094 printf(" (%ld %ld)\n",
1095 tt_outline->points.x[p1], tt_outline->points.y[p1]);
1096 #endif
1097 /*XXX 1.0 [] => 1.1 XXX*/
1098 /*XXX conEnds[] => contors[] XXX*/
1099 /*XXX contours => n_contours XXX*/
1100 /*XXX xCoord => points.x XXX*/
1101 /*XXX yCoord => points.y XXX*/
1102 /*XXX flag[] => flags XXX*/
1103 if (tt_outline->flags[p1] & tt_outline->flags[p2] & TTF_OL_ONCURVE){
1104 /* Line */
1105 if (token != VF_OL_INSTR_LINE){
1106 token = VF_OL_INSTR_LINE;
1107 vfsize++;
1108 }
1109 vfsize += 1;
1110 } else {
1111 if (tt_outline->flags[p2] & TTF_OL_ONCURVE)
1112 continue;
1113 /* spline */
1114 if (token != VF_OL_INSTR_BEZ){
1115 token = VF_OL_INSTR_BEZ;
1116 vfsize++;
1117 }
1118 vfsize += 3;
1119 }
1120 }
1121 }
1122 vfsize++;
1123
1124 if ((vfdata = (VF_OUTLINE)malloc(vfsize*sizeof(long))) == (VF_OUTLINE)NULL)
1125 return NULL;
1126
1127 f = (double)VF_OL_COORD_RANGE / (double)(bbx * mmm);
1128 fupem = (double)VF_OL_COORD_RANGE / (double)bbx;
1129 vfdata[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
1130 vfdata[VF_OL_HEADER_INDEX_DATA_SIZE] = vfsize;
1131 vfdata[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(dpix);
1132 vfdata[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(dpiy);
1133 vfdata[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(ps);
1134 vfdata[VF_OL_HEADER_INDEX_EM] = ceil(fupem * font_ttf->tt_upem);
1135 vfdata[VF_OL_HEADER_INDEX_MAX_X]
1136 = toint(f * (tt_metrics->bbox.xMax - tt_metrics->bbox.xMin)) + 1;
1137 vfdata[VF_OL_HEADER_INDEX_MAX_Y]
1138 = toint(f * (tt_metrics->bbox.yMax - tt_metrics->bbox.yMin)) + 1;
1139 /* ... horizintal direction only. B-( */
1140 vfdata[VF_OL_HEADER_INDEX_REF_X] = toint(f * (tt_metrics->bearingX));
1141 vfdata[VF_OL_HEADER_INDEX_REF_Y] = toint(f * tt_metrics->bbox.yMax);
1142 vfdata[VF_OL_HEADER_INDEX_MV_X] = toint(f * (tt_metrics->advance));
1143 vfdata[VF_OL_HEADER_INDEX_MV_Y] = toint(f * 0);
1144
1145 #define ConvX(x) (long)(VF_OL_COORD_OFFSET + f * ((x)-tt_metrics->bbox.xMin))
/* [<][>][^][v][top][bottom][index][help] */
1146 #define ConvY(y) (long)(VF_OL_COORD_OFFSET + f * (tt_metrics->bbox.yMax-(y)))
/* [<][>][^][v][top][bottom][index][help] */
1147
1148 vfp = &vfdata[VF_OL_OUTLINE_HEADER_SIZE_TYPE0];
1149 for (ct = pt = 0; ct < tt_outline->n_contours; ct++){
1150 token = (VF_OL_INSTR_TOKEN | VF_OL_INSTR_CWCURV);
1151 sp = pt;
1152 ep = tt_outline->contours[ct];
1153 for (; pt <= ep; pt++){
1154 p1 = pt;
1155 p2 = (p1 < ep) ? (p1 + 1) : sp;
1156 p3 = (p2 < ep) ? (p2 + 1) : sp;
1157 if (tt_outline->flags[p1] & tt_outline->flags[p2] & TTF_OL_ONCURVE){
1158 /* Line */
1159 if (token != (VF_OL_INSTR_TOKEN | VF_OL_INSTR_LINE)) {
1160 if (token == (VF_OL_INSTR_TOKEN | VF_OL_INSTR_CWCURV)){
1161 *(vfp++) = token | VF_OL_INSTR_LINE;
1162 } else {
1163 *(vfp++) = VF_OL_INSTR_TOKEN | VF_OL_INSTR_LINE;
1164 }
1165 token = VF_OL_INSTR_TOKEN | VF_OL_INSTR_LINE;
1166 }
1167 x1 = tt_outline->points[p1].x;
1168 y1 = tt_outline->points[p1].y;
1169 *(vfp++) = VF_OL_MAKE_XY(ConvX(x1), ConvY(y1));
1170 } else {
1171 if (tt_outline->flags[p2] & TTF_OL_ONCURVE)
1172 continue;
1173 /* spline */
1174 if (token != (VF_OL_INSTR_TOKEN | VF_OL_INSTR_BEZ)){
1175 if (token == (VF_OL_INSTR_TOKEN | VF_OL_INSTR_CWCURV)){
1176 *(vfp++) = token | VF_OL_INSTR_BEZ;
1177 } else {
1178 *(vfp++) = VF_OL_INSTR_TOKEN | VF_OL_INSTR_BEZ;
1179 }
1180 token = VF_OL_INSTR_TOKEN | VF_OL_INSTR_BEZ;
1181 }
1182 if (tt_outline->flags[p1] & TTF_OL_ONCURVE){
1183 x1 = tt_outline->points[p1].x;
1184 y1 = tt_outline->points[p1].y;
1185 } else {
1186 x1 = (tt_outline->points[p1].x + tt_outline->points[p2].x) / 2.0;
1187 y1 = (tt_outline->points[p1].y + tt_outline->points[p2].y) / 2.0;
1188 }
1189 x2 = tt_outline->points[p2].x;
1190 y2 = tt_outline->points[p2].y;
1191 if (tt_outline->flags[p3] & TTF_OL_ONCURVE){
1192 x3 = tt_outline->points[p3].x;
1193 y3 = tt_outline->points[p3].y;
1194 } else {
1195 x3 = (tt_outline->points[p2].x + tt_outline->points[p3].x) / 2.0;
1196 y3 = (tt_outline->points[p2].y + tt_outline->points[p3].y) / 2.0;
1197 }
1198 *(vfp++) = VF_OL_MAKE_XY(ConvX(x1), ConvY(y1));
1199 *(vfp++) = VF_OL_MAKE_XY(ConvX((x1 + 2.0 * x2) / 3.0),
1200 ConvY((y1 + 2.0 * y2) / 3.0));
1201 *(vfp++) = VF_OL_MAKE_XY(ConvX((2.0 * x2 + x3) / 3.0),
1202 ConvY((2.0 * y2 + y3) / 3.0));
1203 }
1204 }
1205 }
1206 *(vfp++) = 0L;
1207
1208 if (vfdata[VF_OL_OUTLINE_HEADER_SIZE_TYPE0] != 0L)
1209 vfdata[VF_OL_OUTLINE_HEADER_SIZE_TYPE0] |= VF_OL_INSTR_CHAR;
1210
1211 return (VF_OUTLINE)vfdata;
1212 }
1213
1214
1215
1216 Private char*
1217 ttf_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
1218 { /* CALLER MUST RELEASE RETURNED STRING LATER */
1219 SEXP v;
1220 FONT_TTF font_ttf;
1221 char str[512];
1222 double dpix, dpiy, p;
1223
1224 if ((font_ttf = (FONT_TTF)font->private) == NULL){
1225 fprintf(stderr, "VFlib: internal error in ttf_get_font_prop()\n");
1226 abort();
1227 }
1228
1229 if ((v = vf_sexp_assoc(prop_name, font_ttf->props)) != NULL){
1230 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
1231 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
1232 return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
1233 }
1234
1235 if (font->mode == 1){
1236 if ((dpix = font->dpi_x) < 0)
1237 if ((dpix = font_ttf->dpi_x) < 0)
1238 dpix = v_default_dpi_x;
1239 if ((dpiy = font->dpi_y) < 0)
1240 if ((dpiy = font_ttf->dpi_y) < 0)
1241 dpiy = v_default_dpi_y;
1242 if ((p = font->point_size) < 0)
1243 if ((p = font_ttf->point_size) < 0)
1244 p = v_default_point_size;
1245 p = p * font->mag_y * font_ttf->mag;
1246 if (strcmp(prop_name, "POINT_SIZE") == 0){
1247 sprintf(str, "%d", toint(p * 10.0));
1248 return vf_strdup(str);
1249 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
1250 sprintf(str, "%d", toint(p * dpiy / POINTS_PER_INCH));
1251 return vf_strdup(str);
1252 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
1253 sprintf(str, "%d", toint(dpix));
1254 return vf_strdup(str);
1255 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
1256 sprintf(str, "%d", toint(dpiy));
1257 return vf_strdup(str);
1258 }
1259
1260 } else if (font->mode == 2){
1261 if ((p = font->pixel_size) < 0)
1262 if ((p = font_ttf->pixel_size) < 0)
1263 p = v_default_pixel_size;
1264 p = p * font->mag_y * font_ttf->mag;
1265 if (strcmp(prop_name, "POINT_SIZE") == 0){
1266 sprintf(str, "%d", toint(p * 10.0 * POINTS_PER_INCH / VF_DEFAULT_DPI));
1267 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
1268 sprintf(str, "%d", toint(p));
1269 return vf_strdup(str);
1270 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
1271 sprintf(str, "%d", toint(VF_DEFAULT_DPI));
1272 return vf_strdup(str);
1273 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
1274 sprintf(str, "%d", toint(VF_DEFAULT_DPI));
1275 return vf_strdup(str);
1276 }
1277 }
1278
1279 #if 0
1280 if (strcmp(prop_name, "FONT_ASCENT") == 0){
1281 ;
1282 } else if (strcmp(prop_name, "FONT_DESCENT") == 0){
1283 ;
1284 }
1285 #endif
1286
1287 return NULL;
1288 }
1289
1290
1291
1292 Private int
1293 find_encoding_mapping(FONT_TTF font_ttf)
/* [<][>][^][v][top][bottom][index][help] */
1294 {
1295 int ccv_id, map, ntables;
1296 char *internal_enc, *cs;
1297 unsigned short platform_id, encoding_id;
1298 TT_Error error;
1299
1300 if (ttf_debug('p')){
1301 printf("VFlib TrueType: Searching platform:%d (%s), encoding:%d (%s))\n",
1302 font_ttf->platform_id,
1303 platform_id2name(font_ttf->platform_id),
1304 font_ttf->encoding_id,
1305 encoding_id2name(font_ttf->platform_id,font_ttf->encoding_id));
1306 }
1307
1308 /* Find mapping table number to be used in TrueType font file. */
1309 map = font_ttf->mapping_id;
1310 ntables = TT_Get_CharMap_Count(font_ttf->tt_face);
1311 if (map != TT_MAP_ID_SEARCH){
1312 if (ntables == 0){
1313 fprintf(stderr, "VFlib TrueType warning: No mapping tables: %s\n",
1314 font_ttf->font_name);
1315 return -1;
1316 } else if (ntables < 0){
1317 fprintf(stderr, "VFlib TrueType Internal error: CharMap_Count()%s\n",
1318 font_ttf->font_name);
1319 return -1;
1320 } else if ((map < 0) || (ntables <= map)){
1321 map = 0;
1322 fprintf(stderr, "VFlib TrueType warning: Illegal mapping table ID.");
1323 fprintf(stderr, "Use mapping table #0.\n");
1324 }
1325 error = TT_Get_CharMap_ID(font_ttf->tt_face, map,
1326 &platform_id, &encoding_id);
1327 if (error)
1328 return -1;
1329 if (ttf_debug('p'))
1330 printf("VFlib TrueType: Platform,Encoding=(%s,%s)\n",
1331 platform_id2name(platform_id),
1332 encoding_id2name(platform_id, encoding_id));
1333 } else {
1334 for (map = 0; map < ntables; map++){
1335 error = TT_Get_CharMap_ID(font_ttf->tt_face, map,
1336 &platform_id, &encoding_id);
1337 if (ttf_debug('p'))
1338 printf("VFlib TrueType: mapping #%d: Platform: %s, Encoding:%s\n",
1339 map,
1340 platform_id2name(platform_id),
1341 encoding_id2name(platform_id, encoding_id));
1342 if ( ((font_ttf->platform_id == TT_PLAT_ID_ANY)
1343 || (platform_id == font_ttf->platform_id))
1344 && ((font_ttf->encoding_id == TT_ENC_ID_ANY)
1345 || (encoding_id == font_ttf->encoding_id)) ){
1346 break;
1347 }
1348 font_ttf->mapping_id = 0;
1349 }
1350 if (map == ntables){
1351 fprintf(stderr, "VFlib TrueType: Mapping table not found.\n");
1352 return -1;
1353 }
1354 }
1355
1356 font_ttf->mapping_id = map;
1357
1358 if (ttf_debug('p'))
1359 printf("VFlib TrueType: Use mapping table #%d (encoding#%d)\n",
1360 font_ttf->mapping_id, encoding_id);
1361
1362 error = TT_Get_CharMap(font_ttf->tt_face, font_ttf->mapping_id,
1363 &font_ttf->tt_charmap);
1364 if (error)
1365 return -1;
1366
1367 if (font_ttf->encoding_force < 0){
1368 internal_enc = conv_encoding_ttf_to_vflib(encoding_id, platform_id);
1369 } else {
1370 internal_enc = conv_encoding_ttf_to_vflib(font_ttf->encoding_force,
1371 platform_id);
1372 if (ttf_debug('p')){
1373 printf("VFlib TrueType: Encoding force: %s ==> %s\n",
1374 encoding_id2name(platform_id, encoding_id),
1375 encoding_id2name(platform_id, font_ttf->encoding_force));
1376 }
1377 }
1378
1379 /* ad-hoc */
1380 cs = font_ttf->charset_name;
1381 if ((internal_enc != NULL) && (strcmp(internal_enc, "UNICODE") == 0))
1382 cs = "UNICODE";
1383
1384 ccv_id = vf_ccv_require(font_ttf->charset_name, font_ttf->encoding_name,
1385 cs, internal_enc);
1386
1387 if (ttf_debug('p') || ttf_debug('c'))
1388 printf("VFlib TrueType: CCV ID = %d\n", ccv_id);
1389
1390 return ccv_id;
1391 }
1392
1393
1394 Private struct s_id_name_tbl PlatformNameTable[] = {
1395 {TT_PLAT_ID_ANY, "any"}, {TT_PLAT_ID_ANY, "?"},
1396 {TT_PLAT_ID_ANY, "*"}, {TT_PLAT_ID_APPLE, "apple"},
1397 {TT_PLAT_ID_MACINTOSH, "macintosh"}, {TT_PLAT_ID_MACINTOSH, "mac"},
1398 {TT_PLAT_ID_ISO, "iso"}, {TT_PLAT_ID_ISO, "ascii"},
1399 {TT_PLAT_ID_MICROSOFT, "windows"}, {TT_PLAT_ID_MICROSOFT, "microsoft"},
1400 {TT_PLAT_ID_MICROSOFT, "ms"}, {-1, NULL}};
1401
1402 Private struct s_id_name_tbl EncodingNameTableISO[] = {
1403 {TT_ENC_ID_ANY, "any"},
1404 {TT_ENC_ID_ANY, "?"},
1405 {TT_ENC_ID_ANY, "*"},
1406 {TT_ENC_ID_ISO_ASCII, "ascii"},
1407 {TT_ENC_ID_ISO_10646, "iso10464"},
1408 {TT_ENC_ID_ISO_8859_1, "iso8859-1"},
1409 {-1, NULL}};
1410 Private struct s_id_name_tbl EncodingNameTableMS[] = {
1411 {TT_ENC_ID_ANY, "any"},
1412 {TT_ENC_ID_ANY, "?"},
1413 {TT_ENC_ID_ANY, "*"},
1414 {TT_ENC_ID_MS_SYMBOL, "symbol"},
1415 {TT_ENC_ID_MS_UNICODE, "unicode"},
1416 {TT_ENC_ID_MS_SHIFT_JIS, "shift-jis"},
1417 {TT_ENC_ID_MS_SHIFT_JIS, "sjis"},
1418 {TT_ENC_ID_MS_SHIFT_JIS, "ms-kanji"},
1419 {TT_ENC_ID_MS_BIG5, "big5"},
1420 {TT_ENC_ID_MS_RPC, "rpc"},
1421 {TT_ENC_ID_MS_WANSUNG, "wansung"},
1422 {TT_ENC_ID_MS_JOHAB, "johab"},
1423 {-1, NULL}};
1424 Private struct s_id_name_tbl EncodingNameTableApple[] = {
1425 {TT_ENC_ID_ANY, "any"},
1426 {TT_ENC_ID_ANY, "?"},
1427 {TT_ENC_ID_ANY, "*"},
1428 {TT_ENC_ID_APPLE_DEFAULT, "default"},
1429 {TT_ENC_ID_APPLE_UNICODE_1_1, "unicode1.1"},
1430 {TT_ENC_ID_APPLE_UNICODE_2_0, "unicode2.0"},
1431 {TT_ENC_ID_APPLE_ISO_10646, "iso10464"},
1432 {-1, NULL}};
1433 Private struct s_id_name_tbl EncodingNameTableMac[] = {
1434 {TT_ENC_ID_ANY, "any"},
1435 {TT_ENC_ID_ANY, "?"},
1436 {TT_ENC_ID_ANY, "*"},
1437 {TT_ENC_ID_MAC_ROMAN, "roman"},
1438 {TT_ENC_ID_MAC_JAPANESE, "japanese"},
1439 {TT_ENC_ID_MAC_TRADITIONAL_CHINESE, "traditional-chinese"},
1440 {TT_ENC_ID_MAC_KOREAN, "korean"},
1441 {TT_ENC_ID_MAC_ARABIC, "arabic"},
1442 {TT_ENC_ID_MAC_HEBREW, "hebrew"},
1443 {TT_ENC_ID_MAC_GREEK, "greek"},
1444 {TT_ENC_ID_MAC_RUSSIAN, "russian"},
1445 {-1, NULL}};
1446 Private struct s_id_name_tbl *EncodingNameTableTable[] = {
1447 EncodingNameTableApple,
1448 EncodingNameTableMac,
1449 EncodingNameTableISO,
1450 EncodingNameTableMS,
1451 NULL
1452 };
1453
1454 Private int
1455 get_id_from_platform_name(char *name)
/* [<][>][^][v][top][bottom][index][help] */
1456 {
1457 return name2id(name, PlatformNameTable, TT_PLAT_ID_ANY, "platform name");
1458 }
1459
1460 Private int
1461 get_id_from_encoding_name(char *name, int platform)
/* [<][>][^][v][top][bottom][index][help] */
1462 {
1463 struct s_id_name_tbl *tbl;
1464
1465 tbl = EncodingNameTableTable[platform];
1466 return name2id(name, tbl, TT_ENC_ID_ANY, "encoding name");
1467 }
1468
1469 Private int
1470 name2id(char *name, ID_NAME_TBL tbl, int value_default, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
1471 {
1472 int id, t;
1473 char *p;
1474
1475 for (p = name; *p != '\0'; p++){
1476 if (!isspace((int)*p))
1477 break;
1478 }
1479 if (*p == '\0'){
1480 id = value_default;
1481 } else if (isdigit((int)*p)){
1482 id = atoi(p);
1483 } else {
1484 id = value_default;
1485 for (t = 0; tbl[t].name != NULL; t++){
1486 if (vf_strncmp_ci(name, tbl[t].name, strlen(tbl[t].name)) == 0)
1487 return tbl[t].id;
1488 }
1489 fprintf(stderr, "VFlib warning: in vflibcap - No such %s: %s\n",
1490 desc, name);
1491 }
1492 return id;
1493 }
1494
1495
1496 struct s_ttf_encoding_tbl {
1497 int ttf_enc;
1498 char *str_name;
1499 };
1500 Private struct s_ttf_encoding_tbl ttf_encoding_tbl_apple[] = {
1501 {-10000, NULL}
1502 };
1503 Private struct s_ttf_encoding_tbl ttf_encoding_tbl_mac[] = {
1504 {-10000, NULL}
1505 };
1506 Private struct s_ttf_encoding_tbl ttf_encoding_tbl_iso[] = {
1507 {-10000, NULL}
1508 };
1509 Private struct s_ttf_encoding_tbl ttf_encoding_tbl_ms[] = {
1510 {TT_ENC_ID_MS_SYMBOL, "Symbol"},
1511 {TT_ENC_ID_MS_UNICODE, "UNICODE"},
1512 {TT_ENC_ID_MS_SHIFT_JIS, "SJIS"},
1513 {TT_ENC_ID_MS_BIG5, "BIG5"},
1514 {TT_ENC_ID_MS_RPC, "RPC"},
1515 {TT_ENC_ID_MS_WANSUNG, "WANSUNG"},
1516 {TT_ENC_ID_MS_JOHAB, "JOHAB"},
1517 {TT_ENC_ID_ANY, NULL},
1518 {-10000, NULL}
1519 };
1520
1521 Private struct s_ttf_encoding_tbl *ttf_encoding_tbltbl[] = {
1522 ttf_encoding_tbl_apple,
1523 ttf_encoding_tbl_mac,
1524 ttf_encoding_tbl_iso,
1525 ttf_encoding_tbl_ms,
1526 NULL
1527 };
1528
1529 Private char*
1530 conv_encoding_ttf_to_vflib(int ttf_enc, int platform)
/* [<][>][^][v][top][bottom][index][help] */
1531 {
1532 int i;
1533 struct s_ttf_encoding_tbl *tbl;
1534
1535 tbl = ttf_encoding_tbltbl[platform];
1536 for (i = 0; tbl[i].ttf_enc >= -10; i++){
1537 if (tbl[i].ttf_enc == ttf_enc)
1538 return tbl[i].str_name;
1539 }
1540 return NULL;
1541 }
1542
1543
1544
1545 Private char* platform_id2name(int);
1546 Private char *ttf_platform_name[] = {
1547 "Apple", "Macintosh", "ISO", "Microsoft", NULL };
1548
1549 Private char *ttf_encoding_name_apple[] = {
1550 "Apple" "Unicode 1.1", "IS10646", "Unicode 2.0", NULL };
1551 Private char *ttf_encoding_name_mac[] = {
1552 "Roman", "Japanese", "Chinese", "Koran", "Arabic",
1553 "Hebrew", "Greek", "Russian", "RSymbol", "Devanagari",
1554 "Gurmukhi", "Gujarati", "Oriya", "Bengali", "Tamil",
1555 "Telugu", "Kannada", "Malayalam", "Singalese", "Burmese",
1556 "Khmer", "Thai", "Laotian", "Georgian", "Armenian",
1557 "Maldivian", "Tibetan", "Mongolian", "Geez", "Slavic",
1558 "Vietnamese", "Sindhi", "Uninterp", NULL };
1559 Private char *ttf_encoding_name_iso[] = {
1560 "7-bit ASCII", "ISO 10646", "ISO 8859-1", NULL};
1561 Private char *ttf_encoding_name_ms[] = {
1562 "Symbol", "Unicode", "Shift JIS", "Big 5",
1563 "RPC", "WanSung", "Johab", NULL };
1564 Private char **ttf_encoding_table[] = {
1565 ttf_encoding_name_apple,
1566 ttf_encoding_name_mac,
1567 ttf_encoding_name_iso,
1568 ttf_encoding_name_ms,
1569 };
1570
1571 Private char*
1572 platform_id2name(int plat_id)
/* [<][>][^][v][top][bottom][index][help] */
1573 {
1574 int j;
1575 char *s;
1576
1577 for (j = 0; ttf_platform_name[j] != NULL; j++){
1578 if (j == plat_id)
1579 break;
1580 }
1581 if ((s = ttf_platform_name[j]) == NULL)
1582 return "?";
1583 return s;
1584 }
1585
1586 Private char*
1587 encoding_id2name(int plat_id, int enc_id)
/* [<][>][^][v][top][bottom][index][help] */
1588 {
1589 int j;
1590 char *s;
1591
1592 for (j = 0; ttf_encoding_table[plat_id][j] != NULL; j++){
1593 if (j == enc_id)
1594 break;
1595 }
1596 if ((s = ttf_encoding_table[plat_id][j]) == NULL)
1597 return "?";
1598 return s;
1599 }
1600
1601
1602
1603 Private int ttf_debug2(char type, char *str);
1604
1605 Private int
1606 ttf_debug(char type)
/* [<][>][^][v][top][bottom][index][help] */
1607 {
1608 int v;
1609 char *p0;
1610
1611 v = FALSE;
1612 if (env_debug_mode != NULL){
1613 if ((v = ttf_debug2(type, env_debug_mode)) == TRUE)
1614 return TRUE;
1615 }
1616
1617 if (default_debug_mode == NULL)
1618 return FALSE;
1619 if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
1620 return FALSE;
1621 return ttf_debug2(type, p0);
1622 }
1623
1624 Private int
1625 ttf_debug2(char type, char *p0)
/* [<][>][^][v][top][bottom][index][help] */
1626 {
1627 char *p;
1628
1629 for (p = p0; *p != '\0'; p++){
1630 if (*p == type)
1631 return TRUE;
1632 }
1633 for (p = p0; *p != '\0'; p++){
1634 if (*p == '*')
1635 return TRUE;
1636 }
1637 return FALSE;
1638 }
1639
1640 /*EOF*/