src/drv_jtex.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_Init_Driver_JTEX
- jtex_create
- release_font_jtex
- jtex_close
- jtex_get_metric1
- jtex_get_fontbbx1
- jtex_get_bitmap1
- jtex_get_outline
- jtex_get_metric2
- jtex_get_fontbbx2
- jtex_get_bitmap2
- jtex_get_font_prop
- jtex_query_font_type
- jtex_rotate_bitmap
- jtex_met_adjustment
- jtex_met_cc_adjustment
- jtex_read_met_adjustment_file
- jtex_free_adj
- realloc_cc_corr
- find_adj
1 /*
2 * drv_jtex.c - A font driver for ASCII Japanese TeX Kanji fonts.
3 *
4 * 4 Oct 1996 First version.
5 * 17 Jan 1997 for VFlib 3.1
6 * 26 Feb 1997 Added 'query_font_type'.
7 * 4 Aug 1997 VFlib 3.3 Changed API.
8 * 15 Feb 1998 VFlib 3.4 Changed API.
9 * 21 Apr 1998 Added 'implicit-font-mapping-suffix' capability
10 * 27 Jul 1998 Added a code to return some font properties by itself.
11 * 07 Sep 1998 Added 'char-all' directive in adj file.
12 * 24 Nov 1998 Added get_fontbbx1() and get_fontbbx2().
13 * 20 Jan 1999 Changed to adj file searching.
14 * 29 Jul 1999 Fixed bugs in jtex_met_adjustment().
15 */
16 /*
17 * Copyright (C) 1996-1999 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 #include "config.h"
34 #include <stdio.h>
35 #include <stdlib.h>
36 #ifdef HAVE_UNISTD_H
37 # include <unistd.h>
38 #endif
39 #include <ctype.h>
40 #include <sys/param.h>
41 #include <math.h>
42 #include "VFlib-3_6.h"
43 #include "VFsys.h"
44 #include "vflibcap.h"
45 #include "bitmap.h"
46 #include "sexp.h"
47 #include "str.h"
48 #include "path.h"
49 #include "vflpaths.h"
50 #include "metric.h"
51 #include "fsearch.h"
52 #include "tfm.h"
53 #include "jtex.h"
54
55 Private int vf_dbg_drv_ascii_jtex = 0;
56 Private int vf_dbg_drv_ascii_jtex_dump = 0;
57 Private int vf_dbg_drv_ascii_jtex_adj = 0;
58
59
60 #define KW_CHAR_TYPE "char-type"
61 #define KW_CHAR_CODE "char-code"
62 #define KW_CHAR_ALL "char-all"
63
64 #define KW_SEMANTICS "semantics"
65 #define KW_SEM_BITMAP "bitmap-size"
66 #define KW_SEM_DESIGN "design-size"
67 #define SEMANTICS_AUX_BITMAP 0
68 #define SEMANTICS_DESIGN_SIZE 1
69
70 #define KW_DIR "direction"
71 #define KW_DIR_HORIZONTAL "horizontal"
72 #define KW_DIR_VERTICAL "vertical"
73 #define DIR_HORIZONTAL 0
74 #define DIR_VERTICAL 1
75
76 #define KW_ROTATION "rotation-semantics"
77 #define KW_ROT_PTEX "ptex"
78 #define KW_ROT_JISX0208 "jisx0208"
79 #define ROT_JISX0208 (1<<0)
80 #define ROT_PTEX ((1<<1) | ROT_JISX0208)
81
82
83
84 #define N_CC_CORR 64
85
86 struct s_met_adj_ct_corr {
87 int need_cc_corr;
88 int may_need_rotate;
89 double dx, dy;
90 };
91 struct s_met_adj_cc_corr {
92 long code_point;
93 double dx, dy;
94 };
95 typedef struct s_met_adj_cc_corr *ADJ_CC_CORR;
96
97 struct s_met_adj_table {
98 int semantics;
99 int dir;
100 int rot_semantics;
101 struct s_met_adj_ct_corr ct_corr[JTEX_MAX_CHARTYPE];
102 struct s_met_adj_ct_corr ct_corr_all;
103 int n_cc_corr;
104 struct s_met_adj_cc_corr *cc_corr;
105 };
106 typedef struct s_met_adj_table *ADJ;
107
108
109 struct s_vert_rotation {
110 int code_point;
111 int angle;
112 int mirror;
113 int rot_semantics;
114 };
115 static struct s_vert_rotation VertCharInfo[] = {
116 /* Code, Rotation Angle, Mirror, Rotation in JISX0208 */
117 { 0x213c, VF_BM_ROTATE_270, 1, ROT_JISX0208 }, /* Chou-On */
118 { 0x213d, VF_BM_ROTATE_270, 0, ROT_PTEX }, /* Zenkaku-dash */
119 { 0x213e, VF_BM_ROTATE_270, 0, ROT_PTEX }, /* Hyphen-dash */
120 { 0x2141, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Nami-dash */
121 { 0x2144, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Santen leader */
122 { 0x2142, VF_BM_ROTATE_270, 0, ROT_PTEX }, /* Heikou */
123 { 0x2143, VF_BM_ROTATE_270, 0, ROT_PTEX }, /* Tatesen */
124 { 0x2145, VF_BM_ROTATE_270, 0, ROT_PTEX }, /* Niten leader */
125 { 0x214a, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Syou-Kakko */
126 { 0x214b, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Syou-Kakko */
127 { 0x214c, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kikkou-Kakko */
128 { 0x214d, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kikkou-Kakko */
129 { 0x214e, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kaku-Kakko */
130 { 0x214f, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kaku-Kakko */
131 { 0x2150, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Chuu-Kakko */
132 { 0x2151, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Chuu-Kakko */
133 { 0x2152, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Yama-Kakko */
134 { 0x2153, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Yama-Kakko */
135 { 0x2154, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* NijuuYama-Kakko */
136 { 0x2155, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* NijuuYama-Kakko */
137 { 0x2156, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kagi-Kakko */
138 { 0x2157, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Kagi-Kakko */
139 { 0x2158, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* NijuuKagi-Kakko */
140 { 0x2159, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* NijuuKagi-Kakko */
141 { 0x215a, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Sumitsuki-Kakko */
142 { 0x215b, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* Sumitsuki-Kakko */
143 { 0x2161, VF_BM_ROTATE_270, 0, ROT_JISX0208 }, /* '=' sign */
144 { -1, -1, -1, -1 }
145 };
146
147
148 struct s_font_jtex {
149 char *font_name;
150 char *kanji_font;
151 int kanji_font_id;
152 double kf_point_size;
153 int kf_pixel_size;
154 double kf_mag;
155 char *tfm_file;
156 TFM tfm;
157 char *adj_file;
158 ADJ adj;
159 double mode2_factor_x, mode2_factor_y;
160 SEXP props;
161 };
162 typedef struct s_font_jtex *FONT_JTEX;
163
164
165 Private SEXP_STRING default_map_suffix = NULL;
166 Private SEXP_LIST default_tfm_dirs = NULL;
167 Private SEXP_LIST default_tfm_extensions = NULL;
168 Private SEXP_ALIST default_properties = NULL;
169 Private SEXP_ALIST default_variables = NULL;
170 Private SEXP_STRING default_debug_mode = NULL;
171
172
173 Private int jtex_create(VF_FONT,char*,char*,int,SEXP);
174 Private int jtex_close(VF_FONT);
175 Private int jtex_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
176 Private int jtex_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
177 Private int jtex_get_fontbbx1(VF_FONT,double,double,
178 double*,double*,double*,double*);
179 Private int jtex_get_fontbbx2(VF_FONT,double,double,
180 int*,int*,int*,int*);
181 Private VF_BITMAP jtex_get_bitmap1(VF_FONT,long,double,double);
182 Private VF_BITMAP jtex_get_bitmap2(VF_FONT,long,double,double);
183 Private VF_OUTLINE jtex_get_outline(VF_FONT,long,double,double);
184 Private int jtex_query_font_type(VF_FONT,long);
185 Private char *jtex_get_font_prop(VF_FONT,char*);
186 Private VF_BITMAP jtex_rotate_bitmap(VF_BITMAP bm0, long code_point,
187 FONT_JTEX font_jtex, int *need_free_p);
188 Private int jtex_met_adjustment(VF_BITMAP,VF_METRIC2,long,
189 VF_FONT,FONT_JTEX,double,double);
190 Private ADJ jtex_read_met_adjustment_file(FONT_JTEX,char*);
191 Private void jtex_free_adj(ADJ adj);
192 Private void jtex_met_cc_adjustment(ADJ adj, long code_point,
193 int char_type,
194 double *fxp, double *fyp);
195 Private ADJ realloc_cc_corr(ADJ adj);
196 Private char *find_adj(char *fname);
197 Private void release_font_jtex(FONT_JTEX);
198
199
200
201
202 Public int
203 VF_Init_Driver_JTEX(void)
/* [<][>][^][v][top][bottom][index][help] */
204 {
205 struct s_capability_table ct[10];
206 int z;
207
208 z = 0;
209 /* VF_CAPE_JTEX_MAP_SUFIX */
210 ct[z].cap = VF_CAPE_JTEX_MAP_SUFIX; ct[z].type = CAPABILITY_STRING;
211 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_map_suffix;
212 /* VF_CAPE_TEX_TFM_DIRECTORIES */
213 ct[z].cap = VF_CAPE_TEX_TFM_DIRECTORIES; ct[z].type = CAPABILITY_LIST;
214 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_tfm_dirs;
215 /* VF_CAPE_TEX_TFM_EXTENSIONS */
216 ct[z].cap = VF_CAPE_TEX_TFM_EXTENSIONS; ct[z].type = CAPABILITY_LIST;
217 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_tfm_extensions;
218 /* VF_CAPE_PROPERTIES */
219 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
220 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_properties;
221 /* VF_CAPE_VARIABLE_VALUES */
222 ct[z].cap = VF_CAPE_VARIABLE_VALUES; ct[z].type = CAPABILITY_ALIST;
223 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_variables;
224 /* VF_CAPE_DEBUG */
225 ct[z].cap = VF_CAPE_DEBUG; ct[z].type = CAPABILITY_STRING;
226 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &default_debug_mode;
227 /* end */
228 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
229
230
231 if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME_JTEX, ct, NULL, NULL)
232 == VFLIBCAP_PARSED_ERROR)
233 return -1;
234
235 if (vf_tex_init() < 0)
236 return -1;
237
238 if (getenv("VFLIB_DEBUG_ASCII_JTEX") != NULL)
239 vf_dbg_drv_ascii_jtex = 1;
240
241 if (getenv("VFLIB_DEBUG_ASCII_JTEX_DUMP") != NULL)
242 vf_dbg_drv_ascii_jtex_dump = 1;
243
244 if (getenv("VFLIB_DEBUG_ASCII_JTEX_ADJ") != NULL)
245 vf_dbg_drv_ascii_jtex_adj = 1;
246
247 VF_InstallFontDriver(FONTCLASS_NAME_JTEX, (DRIVER_FUNC_TYPE)jtex_create);
248
249 return 0;
250 }
251
252
253 Private int
254 jtex_create(VF_FONT font, char *font_class,
/* [<][>][^][v][top][bottom][index][help] */
255 char *font_name, int implicit, SEXP entry)
256 {
257 FONT_JTEX font_jtex;
258 double point_size, dpi, dpix = 0.0, dpiy = 0.0;
259 int pixel_size;
260 char *mapped_font, *name_core, *suffix, *tfm_path, *p;
261 SEXP entry2, cap_kanji, cap_kf_point, cap_kf_pixel, cap_kf_mag;
262 SEXP cap_tfm, cap_adj, cap_props;
263 SEXP tfm_ext;
264 struct s_capability_table ct[10];
265 int z;
266
267 z = 0;
268 /* VF_CAPE_FONT_CLASS */
269 ct[z].cap = VF_CAPE_FONT_CLASS; ct[z].type = CAPABILITY_STRING;
270 ct[z].ess = CAPABILITY_ESSENTIAL; ct[z++].val = NULL;
271 /* VF_CAPE_JTEX_KANJI_FONT */
272 ct[z].cap = VF_CAPE_JTEX_KANJI_FONT; ct[z].type = CAPABILITY_STRING;
273 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_kanji;
274 /* VF_CAPE_JTEX_KF_POINT_SIZE */
275 ct[z].cap = VF_CAPE_JTEX_KF_POINT_SIZE; ct[z].type = CAPABILITY_STRING;
276 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_kf_point;
277 /* VF_CAPE_JTEX_KF_PIXEL_SIZE */
278 ct[z].cap = VF_CAPE_JTEX_KF_PIXEL_SIZE; ct[z].type = CAPABILITY_STRING;
279 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_kf_pixel;
280 /* VF_CAPE_JTEX_KF_MAG */
281 ct[z].cap = VF_CAPE_JTEX_KF_MAG; ct[z].type = CAPABILITY_STRING;
282 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_kf_mag;
283 /* VF_CAPE_JTEX_TFM_FILE */
284 ct[z].cap = VF_CAPE_JTEX_TFM_FILE; ct[z].type = CAPABILITY_STRING;
285 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_tfm;
286 /* VF_CAPE_JTEX_ADJUSTMENT_FILE */
287 ct[z].cap = VF_CAPE_JTEX_ADJUSTMENT_FILE; ct[z].type = CAPABILITY_STRING;
288 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_adj;
289 /* VF_CAPE_PROPERTIES */
290 ct[z].cap = VF_CAPE_PROPERTIES; ct[z].type = CAPABILITY_ALIST;
291 ct[z].ess = CAPABILITY_OPTIONAL; ct[z++].val = &cap_props;
292 /* end */
293 ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;
294
295
296 font_jtex = NULL;
297 mapped_font = NULL;
298 name_core = NULL;
299 tfm_path = NULL;
300 entry2 = NULL;
301
302 if (vf_dbg_drv_ascii_jtex == 1){
303 printf(">>VFlib ascii jtex: open request %s\n", font_name);
304 }
305
306 if (implicit == 1){
307 /* font name mapping:
308 * requested font: "min10.400pk" or "min10.pk"
309 * ==> "min10XXX", where XXX is a suffix (e.g., ".pk")
310 */
311 suffix = "";
312 if ((default_map_suffix != NULL)
313 && (vf_sexp_get_cstring(default_map_suffix) != NULL)){
314 suffix = vf_sexp_get_cstring(default_map_suffix);
315 }
316 if ((name_core = vf_path_base_core(font_name)) == NULL)
317 return -1;
318 ALLOCN_IF_ERR(mapped_font, char, strlen(name_core)+strlen(suffix)+1){
319 vf_free(name_core);
320 return -1;
321 }
322 sprintf(mapped_font, "%s%s", name_core, suffix);
323 if (vf_dbg_drv_ascii_jtex == 1){
324 printf(">>VFlib ascii jtex font mapping: %s ==> %s\n",
325 font_name, mapped_font);
326 }
327 if (strcmp(mapped_font, font_name) == 0){ /* a loop */
328 vf_free(name_core);
329 vf_free(mapped_font);
330 return -1;
331 }
332
333 /* Parse font name. Formats of file names that this routine supports:
334 * "cmr10.300XX" - A "cmr10" font for 300 dpi.
335 * "cmr10.XX" - A "cmr10" font. Dpi value is default value.
336 * "cmr10" - ditto.
337 * ("XX" can be any string such as "pk", "gf", and "tfm".)
338 */
339 if (font->mode == 1){
340 p = vf_index(font_name, '.');
341 dpi = font->dpi_y;
342 if ((p != NULL) && (isdigit((int)*(p+1)))){ /* "cmr10.300gf" */
343 if (dpi < 0)
344 dpi = (double)atoi(p+1);
345 } else { /* "cmr10" or "cmr10.gf" */
346 if (dpi < 0)
347 dpi = (double)vf_tex_default_dpi();
348 }
349 dpix = dpi * (double)font->dpi_x / (double)font->dpi_y;
350 dpiy = dpi;
351 }
352
353 if ((entry2 = vf_cap_GetFontEntry(mapped_font)) == NULL){
354 vf_error = VF_ERR_NO_FONT_ENTRY;
355 vf_free(name_core);
356 vf_free(mapped_font);
357 return -1;
358 }
359 if (vf_cap_GetParsedFontEntry(entry2, mapped_font, ct,
360 default_variables, NULL)
361 == VFLIBCAP_PARSED_ERROR){
362 vf_sexp_free(&entry2);
363 vf_free(name_core);
364 vf_free(mapped_font);
365 return -1;
366 }
367 } else {
368 if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
369 default_variables, NULL)
370 == VFLIBCAP_PARSED_ERROR){
371 return -1;
372 }
373 dpi = font->dpi_y;
374 if (dpi < 0)
375 dpi = (double)vf_tex_default_dpi();
376 dpix = dpi * (double)font->dpi_x / (double)font->dpi_y;
377 dpiy = dpi;
378 }
379
380 font->font_type = VF_FONT_TYPE_UNDEF; /* call jtex_query_font_type() */
381 font->get_metric1 = jtex_get_metric1;
382 font->get_metric2 = jtex_get_metric2;
383 font->get_fontbbx1 = jtex_get_fontbbx1;
384 font->get_fontbbx2 = jtex_get_fontbbx2;
385 font->get_bitmap1 = jtex_get_bitmap1;
386 font->get_bitmap2 = jtex_get_bitmap2;
387 font->get_outline = jtex_get_outline;
388 font->get_font_prop = jtex_get_font_prop;
389 font->query_font_type = jtex_query_font_type;
390 font->close = jtex_close;
391
392 ALLOC_IF_ERR(font_jtex, struct s_font_jtex){
393 vf_error = VF_ERR_NO_MEMORY;
394 vf_sexp_free(&entry2);
395 vf_free(name_core);
396 vf_free(mapped_font);
397 return -1;
398 }
399
400 font_jtex->font_name = vf_strdup(font_name);
401 font_jtex->kanji_font = NULL;
402 font_jtex->kanji_font_id = -1;
403 font_jtex->kf_point_size = -1;
404 font_jtex->kf_pixel_size = -1;
405 font_jtex->kf_mag = 1.0;
406 font_jtex->tfm_file = NULL;
407 font_jtex->tfm = NULL;
408 font_jtex->adj_file = NULL;
409 font_jtex->adj = NULL;
410 font_jtex->mode2_factor_x = -1;
411 font_jtex->mode2_factor_y = -1;
412 font_jtex->props = NULL;
413
414 if (default_tfm_extensions == NULL)
415 default_tfm_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS_TFM);
416 if (cap_kanji != NULL)
417 font_jtex->kanji_font = vf_strdup(vf_sexp_get_cstring(cap_kanji));
418 else
419 font_jtex->kanji_font = vf_path_base_core(font_name);
420 if (font_jtex->kanji_font == NULL){
421 vf_error = VF_ERR_NO_AUX_FONT_NAME;
422 vf_sexp_free(&entry2);
423 vf_free(name_core);
424 vf_free(mapped_font);
425 vf_free(font_jtex);
426 return -1;
427 }
428 if (cap_kf_point != NULL)
429 font_jtex->kf_point_size = atof(vf_sexp_get_cstring(cap_kf_point));
430 if (cap_kf_pixel != NULL)
431 font_jtex->kf_pixel_size = atoi(vf_sexp_get_cstring(cap_kf_pixel));
432 if (cap_kf_mag != NULL)
433 font_jtex->kf_mag = atof(vf_sexp_get_cstring(cap_kf_mag));
434 if (cap_tfm != NULL)
435 font_jtex->tfm_file = vf_strdup(vf_sexp_get_cstring(cap_tfm));
436 else
437 font_jtex->tfm_file = vf_path_base_core(font_name);
438 if (cap_adj != NULL)
439 font_jtex->adj_file = vf_strdup(vf_sexp_get_cstring(cap_adj));
440 font_jtex->props = cap_props;
441
442 if (vf_dbg_drv_ascii_jtex == 1){
443 printf(">>VFlib ascii jtex font name: %s\n", font_jtex->font_name);
444 printf(">>VFlib ascii jtex kanji font: %s\n", font_jtex->kanji_font);
445 printf(">>VFlib ascii jtex tfm file: %s\n", font_jtex->tfm_file);
446 printf(">>VFlib ascii jtex adj file: %s\n", font_jtex->adj_file);
447 printf(">>VFlib ascii jtex kf point: %.3f\n", font_jtex->kf_point_size);
448 printf(">>VFlib ascii jtex kf pixel: %d\n", font_jtex->kf_pixel_size);
449 printf(">>VFlib ascii jtex kf mag: %.3f\n", font_jtex->kf_mag);
450 }
451
452 /* Open aux kanji font */
453 if (font->mode == 1){
454 if ((point_size = font->point_size) < 0)
455 point_size = font_jtex->kf_point_size;
456 font_jtex->kanji_font_id
457 = VF_OpenFont1(font_jtex->kanji_font, dpix, dpiy, point_size,
458 font->mag_x * font_jtex->kf_mag,
459 font->mag_y * font_jtex->kf_mag);
460 } else if (font->mode == 2){
461 if ((pixel_size = font->pixel_size) < 0)
462 pixel_size = font_jtex->kf_pixel_size;
463 font_jtex->kanji_font_id
464 = VF_OpenFont2(font_jtex->kanji_font, pixel_size,
465 font->mag_x * font_jtex->kf_mag,
466 font->mag_y * font_jtex->kf_mag);
467 }
468 if (vf_dbg_drv_ascii_jtex == 1)
469 printf(">>VFlib ascii jtex: Aux Kanji font ID: %d\n",
470 font_jtex->kanji_font_id);
471
472 if (font_jtex->kanji_font_id < 0){
473 vf_error = VF_ERR_NO_FONT_ENTRY;
474 goto Error;
475 }
476
477 /* Search TFM */
478 tfm_ext = (cap_tfm != NULL) ? NULL : default_tfm_extensions;
479 tfm_path = vf_tex_search_file_tfm(font_jtex->tfm_file,
480 default_tfm_dirs, tfm_ext);
481 if (vf_dbg_drv_ascii_jtex == 1)
482 printf(">>VFlib ascii jtex: TFM path: %s ==> %s\n",
483 font_jtex->tfm_file, (tfm_path==NULL)?"(not found)":tfm_path);
484 if (tfm_path == NULL)
485 goto Error;
486 if ((font_jtex->tfm = vf_tfm_open(tfm_path)) == NULL)
487 goto Error;
488
489 /* Check if it is a JFM (Japanese Font Metric) format */
490 if (font_jtex->tfm->type != METRIC_TYPE_JFM){
491 vf_error = VF_ERR_NOT_JFM;
492 goto Error;
493 }
494
495 /* Read ADJ file */
496 if (cap_adj != NULL){
497 font_jtex->adj_file = vf_strdup(vf_sexp_get_cstring(cap_adj));
498 if (font_jtex->adj_file != NULL)
499 font_jtex->adj
500 = jtex_read_met_adjustment_file(font_jtex, font_jtex->adj_file);
501 if (font_jtex->adj == NULL){
502 fprintf(stderr, "VFlib warning: Can't read: %s\n", font_jtex->adj_file);
503 }
504 } else {
505 fprintf(stderr, "VFlib warning: no ADJ file.\n");
506 }
507
508 if (font->mode == 2){
509 p = VF_GetFontProp(font_jtex->kanji_font_id, "PIXEL_SIZE");
510 if (p != NULL){
511 font_jtex->mode2_factor_x
512 = font->mag_x * atof(p) / font_jtex->tfm->design_size;
513 font_jtex->mode2_factor_y
514 = font->mag_y * atof(p) / font_jtex->tfm->design_size;
515 #if 0
516 printf("*** pixel_size:%.3f design_size: %.3f\n",
517 atof(p), font_jtex->tfm->design_size);
518 printf("*** factor_x:%.3f factor_y: %.3f\n",
519 font_jtex->mode2_factor_x, font_jtex->mode2_factor_y);
520 #endif
521 }
522 }
523
524 font->private = font_jtex;
525
526 vf_free(mapped_font);
527 vf_free(name_core);
528 vf_free(tfm_path);
529 if (implicit == 0){
530 vf_sexp_free4(&cap_kanji, &cap_kf_point, &cap_kf_pixel, &cap_kf_mag);
531 vf_sexp_free2(&cap_tfm, &cap_adj);
532 }
533 vf_sexp_free(&entry2);
534 return 0;
535
536
537 Error:
538 release_font_jtex(font_jtex);
539 vf_free(mapped_font);
540 vf_free(name_core);
541 vf_free(tfm_path);
542 if (implicit == 0){
543 vf_sexp_free4(&cap_kanji, &cap_kf_point, &cap_kf_pixel, &cap_kf_mag);
544 vf_sexp_free2(&cap_tfm, &cap_adj);
545 vf_sexp_free(&cap_props);
546 }
547 vf_sexp_free(&entry2);
548 return -1;
549 }
550
551
552 Private void
553 release_font_jtex(FONT_JTEX font_jtex)
/* [<][>][^][v][top][bottom][index][help] */
554 {
555 if (font_jtex != NULL){
556 vf_free(font_jtex->font_name);
557 vf_free(font_jtex->kanji_font);
558 if (font_jtex->kanji_font_id >= 0)
559 VF_CloseFont(font_jtex->kanji_font_id);
560 vf_free(font_jtex->tfm_file);
561 vf_tfm_free(font_jtex->tfm);
562 vf_free(font_jtex->adj_file);
563 jtex_free_adj(font_jtex->adj);
564 vf_sexp_free1(&font_jtex->props);
565 vf_free(font_jtex);
566 }
567 }
568
569
570 Private int
571 jtex_close(VF_FONT font)
/* [<][>][^][v][top][bottom][index][help] */
572 {
573 FONT_JTEX font_jtex;
574
575 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
576 fprintf(stderr, "VFlib: internal error in jtex_close()\n");
577 abort();
578 }
579
580 release_font_jtex(font_jtex);
581 return 0;
582 }
583
584
585 Private int
586 jtex_get_metric1(VF_FONT font, long code_point, VF_METRIC1 metric,
/* [<][>][^][v][top][bottom][index][help] */
587 double mag_x, double mag_y)
588 {
589 FONT_JTEX font_jtex;
590 double ds, dr;
591
592 if ( (metric == NULL)
593 || ((font_jtex = (FONT_JTEX)font->private) == NULL) ){
594 fprintf(stderr, "VFlib internal error in jtex_get_metric1()\n");
595 abort();
596 }
597
598 if (vf_tfm_metric(font_jtex->tfm, code_point, metric) == NULL)
599 return -1;
600
601 ds = font_jtex->tfm->design_size;
602 dr = 1.0;
603 if (font->point_size > 0)
604 dr = font->point_size / ds;
605
606 metric->bbx_width *= mag_x * font->mag_x;
607 metric->bbx_height *= mag_y * font->mag_y;
608 metric->off_x *= mag_x * font->mag_x;
609 metric->off_y *= mag_y * font->mag_y;
610 metric->mv_x *= mag_x * font->mag_x * dr;
611 metric->mv_y *= mag_y * font->mag_y * dr;
612
613 return 0;
614 }
615
616 Private int
617 jtex_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
618 double *w_p, double *h_p, double *xoff_p, double *yoff_p)
619 {
620 FONT_JTEX font_jtex;
621
622 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
623 fprintf(stderr, "VFlib internal error in jtex_get_fontbbx1()\n");
624 abort();
625 }
626
627 *w_p = font_jtex->tfm->font_bbx_w * mag_x * font->mag_x;
628 *h_p = font_jtex->tfm->font_bbx_h * mag_y * font->mag_y;
629 *xoff_p = font_jtex->tfm->font_bbx_xoff * mag_x * font->mag_x;
630 *yoff_p = font_jtex->tfm->font_bbx_yoff * mag_y * font->mag_y;
631
632 return 0;
633 }
634
635 Private VF_BITMAP
636 jtex_get_bitmap1(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
637 double mag_x, double mag_y)
638 {
639 FONT_JTEX font_jtex;
640 VF_BITMAP bm_kanji, bm;
641 int need_free;
642 double dpi_x, dpi_y, mx, my;
643 struct vf_s_metric1 met1;
644 struct vf_s_metric2 met2;
645
646 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
647 fprintf(stderr, "VFlib: Internal error in jtex_get_bitmap1().\n");
648 abort();
649 }
650
651 if (font_jtex->kanji_font_id < 0){
652 vf_error = VF_ERR_ILL_CODE_POINT;
653 return NULL;
654 }
655
656 bm_kanji = VF_GetBitmap1(font_jtex->kanji_font_id, code_point, mag_x, mag_y);
657 if (bm_kanji == NULL){
658 #if 1
659 bm_kanji = vf_alloc_bitmap(1, 1);
660 #else
661 return NULL;
662 #endif
663 }
664
665 bm = jtex_rotate_bitmap(bm_kanji, code_point, font_jtex, &need_free);
666 if (bm == NULL){
667 VF_FreeBitmap(bm_kanji);
668 return NULL;
669 }
670
671 if (jtex_get_metric1(font, code_point, &met1, mag_x, mag_y) < 0){
672 VF_FreeBitmap(bm_kanji);
673 if (need_free == 1)
674 VF_FreeBitmap(bm);
675 return NULL;
676 }
677
678 if (((dpi_x = font->dpi_x) < 0) || ((dpi_y = font->dpi_y) < 0)){
679 dpi_x = vf_tex_default_dpi();
680 dpi_y = vf_tex_default_dpi();
681 }
682 mx = dpi_x/72.27;
683 my = dpi_y/72.27;
684
685 met2.bbx_width = bm->bbx_width;
686 met2.bbx_height = bm->bbx_height;
687 met2.off_x = bm->off_x;
688 met2.off_y = bm->off_y;
689 met2.mv_x = toint(met1.mv_x * mx);
690 met2.mv_y = toint(met1.mv_y * my);
691
692 if (vf_dbg_drv_ascii_jtex_dump == 1){
693 printf(">>* ascii_jtex: get bitmap 1\n");
694 printf(" CharCode: 0x%04lx (char-type: %d)\n",
695 code_point, vf_tfm_jfm_chartype(font_jtex->tfm, (UINT4)code_point));
696 printf(">> metric 1\n");
697 vf_dump_metric1(&met1);
698 printf(">> metric 2\n");
699 vf_dump_metric2(&met2);
700 printf(">> bitmap (orig)\n");
701 VF_DumpBitmap(bm);
702 }
703
704 jtex_met_adjustment(bm, &met2, code_point, font, font_jtex, mag_x, mag_y);
705
706 if (vf_dbg_drv_ascii_jtex_dump == 1){
707 printf(">> bitmap (adj)\n");
708 VF_DumpBitmap(bm);
709 }
710
711 if (need_free == 1){
712 VF_FreeBitmap(bm_kanji); /* bm is a new object, we don't need bm_kanji */
713 } else {
714 ; /*empty*/ /* bm and bm_kanji points to the same object.*/
715 }
716
717 return bm;
718 }
719
720
721 Private VF_OUTLINE
722 jtex_get_outline(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
723 double mag_x, double mag_y)
724 {
725 FONT_JTEX font_jtex;
726
727 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
728 fprintf(stderr, "VFlib: Internal error in jtex_get_outline().\n");
729 abort();
730 }
731
732 if (font_jtex->kanji_font_id < 0){
733 vf_error = VF_ERR_ILL_CODE_POINT;
734 return NULL;
735 }
736
737 /**
738 ** Metric correction is not supported. Sorry.
739 **/
740
741 return VF_GetOutline(font_jtex->kanji_font_id, code_point, mag_x, mag_y);
742 }
743
744
745 Private int
746 jtex_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric,
/* [<][>][^][v][top][bottom][index][help] */
747 double mag_x, double mag_y)
748 {
749 FONT_JTEX font_jtex;
750 TFM tfm;
751 struct vf_s_metric1 met1;
752
753 if ( (metric == NULL)
754 || ((font_jtex = (FONT_JTEX)font->private) == NULL)
755 || ((tfm = font_jtex->tfm) == NULL) ){
756 fprintf(stderr, "VFlib internal error in htex_get_metric2()\n");
757 abort();
758 }
759
760 if (vf_tfm_metric(tfm, code_point, &met1) == NULL)
761 return -1;
762
763 metric->bbx_width = toint(met1.bbx_width * mag_x * font->mag_x);
764 metric->bbx_height = toint(met1.bbx_height * mag_y * font->mag_y);
765 metric->off_x = toint(met1.off_x * mag_x * font->mag_x);
766 metric->off_y = toint(met1.off_y * mag_y * font->mag_y);
767 metric->mv_x = toint(met1.mv_x * mag_x * font->mag_x);
768 metric->mv_y = toint(met1.mv_y * mag_y * font->mag_y);
769
770 return 0;
771 }
772
773
774 Private int
775 jtex_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
/* [<][>][^][v][top][bottom][index][help] */
776 int *w_p, int *h_p, int *xoff_p, int *yoff_p)
777 {
778 FONT_JTEX font_jtex;
779
780 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
781 fprintf(stderr, "VFlib internal error in jtex_get_fontbbx2()\n");
782 abort();
783 }
784
785 *w_p = toint(font_jtex->tfm->font_bbx_w * mag_x * font->mag_x);
786 *h_p = toint(font_jtex->tfm->font_bbx_h * mag_y * font->mag_y);
787 *xoff_p = toint(font_jtex->tfm->font_bbx_xoff * mag_x * font->mag_x);
788 *yoff_p = toint(font_jtex->tfm->font_bbx_yoff * mag_y * font->mag_y);
789
790 return 0;
791 }
792
793 Private VF_BITMAP
794 jtex_get_bitmap2(VF_FONT font, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
795 double mag_x, double mag_y)
796 {
797 FONT_JTEX font_jtex;
798 VF_BITMAP bm_kanji, bm;
799 int need_free;
800 struct vf_s_metric1 met1;
801 struct vf_s_metric2 met2;
802
803 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
804 fprintf(stderr, "VFlib: Internal error in jtex_get_bitmap2().\n");
805 abort();
806 }
807
808 if (font_jtex->kanji_font_id < 0){
809 vf_error = VF_ERR_ILL_CODE_POINT;
810 return NULL;
811 }
812
813 bm_kanji = VF_GetBitmap2(font_jtex->kanji_font_id, code_point, mag_x, mag_y);
814 if (bm_kanji == NULL){
815 #if 1
816 bm_kanji = vf_alloc_bitmap(1, 1);
817 #else
818 return NULL;
819 #endif
820 }
821
822 bm = jtex_rotate_bitmap(bm_kanji, code_point, font_jtex, &need_free);
823 if (bm == NULL){
824 VF_FreeBitmap(bm_kanji);
825 return NULL;
826 }
827
828 if (vf_tfm_metric(font_jtex->tfm, code_point, &met1) == NULL){
829 VF_FreeBitmap(bm_kanji);
830 if (need_free == 1)
831 VF_FreeBitmap(bm);
832 return NULL;
833 }
834
835 met2.bbx_width = bm->bbx_width;
836 met2.bbx_height = bm->bbx_height;
837 met2.off_x = bm->off_x;
838 met2.off_y = bm->off_y;
839 if ((font_jtex->mode2_factor_x > 0) && (font_jtex->mode2_factor_x > 0)){
840 met2.mv_x = met1.mv_x * font_jtex->mode2_factor_x;
841 met2.mv_y = met1.mv_y * font_jtex->mode2_factor_y;
842 } else {
843 met2.mv_x = bm->mv_x;
844 met2.mv_y = bm->mv_y;
845 }
846
847 if (vf_dbg_drv_ascii_jtex_dump == 1){
848 printf(">>* ascii_jtex: get bitmap 2\n");
849 printf(">> metric\n");
850 vf_dump_metric2(&met2);
851 printf(">> bitmap (orig)\n");
852 VF_DumpBitmap(bm);
853 }
854
855 jtex_met_adjustment(bm, &met2, code_point, font, font_jtex, mag_x, mag_y);
856
857 if (vf_dbg_drv_ascii_jtex_dump == 1){
858 printf(">> bitmap (adj)\n");
859 VF_DumpBitmap(bm);
860 }
861
862 if (need_free == 1){
863 VF_FreeBitmap(bm_kanji); /* bm is a new object, we don't need bm_kanji */
864 } else {
865 ; /*empty*/ /* bm and bm_kanji points to the same object.*/
866 }
867
868 return bm;
869 }
870
871
872 Private char*
873 jtex_get_font_prop(VF_FONT font, char *prop_name)
/* [<][>][^][v][top][bottom][index][help] */
874 {
875 FONT_JTEX font_jtex;
876 double dpi_x, dpi_y;
877 SEXP v;
878 char *r;
879
880 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
881 fprintf(stderr, "VFlib: Internal error in jtex_get_font_prop().\n");
882 abort();
883 }
884 if (font_jtex->kanji_font_id < 0){
885 return NULL;
886 }
887
888 if ((v = vf_sexp_assoc(prop_name, font_jtex->props)) != NULL){
889 if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
890 vf_error = VF_ERR_NO_MEMORY;
891 return NULL;
892 }
893 return r;
894 } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
895 if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
896 vf_error = VF_ERR_NO_MEMORY;
897 return NULL;
898 }
899 return r;
900 }
901
902 if (((dpi_x = font->dpi_x)<=0) || ((dpi_y = font->dpi_y)<=0)){
903 dpi_x = vf_tex_default_dpi();
904 dpi_y = vf_tex_default_dpi();
905 }
906
907 #if 0
908 if (font->mode == 1){
909 if ((ps = font->point_size) < 0)
910 ps = font_jtex->tfm->design_size;
911 ps = ps * font->mag_y;
912 if (strcmp(prop_name, "POINT_SIZE") == 0){
913 sprintf(str, "%d", toint(ps * 10.0));
914 return vf_strdup(str);
915 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
916 sprintf(str, "%d", toint(ps * dpi_y / 72.27));
917 return vf_strdup(str);
918 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
919 sprintf(str, "%d", toint(dpi_x));
920 return vf_strdup(str);
921 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
922 sprintf(str, "%d", toint(dpi_y));
923 return vf_strdup(str);
924 }
925
926 } else if (font->mode == 2){
927 if (strcmp(prop_name, "POINT_SIZE") == 0){
928 if ((ps = font->pixel_size) < 0){
929 sprintf(str, "%d", toint(font_jtex->tfm->design_size
930 * 10.0 * font->mag_y));
931 return vf_strdup(str);
932 }
933 ps = ps * font->mag_y;
934 sprintf(str, "%d", toint(ps * 10.0 * 72.27 / dpi_y));
935 return vf_strdup(str);
936 } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
937 if ((ps = font->pixel_size) < 0)
938 ps = font_jtex->tfm->design_size * dpi_y / 72.27;
939 ps = ps * font->mag_y;
940 sprintf(str, "%d", toint(ps));
941 return vf_strdup(str);
942 } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
943 sprintf(str, "%d", toint(dpi_x));
944 return vf_strdup(str);
945 } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
946 sprintf(str, "%d", toint(dpi_y));
947 return vf_strdup(str);
948 }
949 }
950 #endif
951
952 return VF_GetFontProp(font_jtex->kanji_font_id, prop_name);
953 }
954
955
956 Private int
957 jtex_query_font_type(VF_FONT font, long code_point)
/* [<][>][^][v][top][bottom][index][help] */
958 {
959 FONT_JTEX font_jtex;
960
961 if ((font_jtex = (FONT_JTEX)font->private) == NULL){
962 fprintf(stderr, "VFlib: Internal error in jtex_get_font_prop().\n");
963 abort();
964 }
965
966 return VF_QueryFontType(font_jtex->kanji_font_id, code_point);
967 }
968
969
970
971 Private VF_BITMAP
972 jtex_rotate_bitmap(VF_BITMAP bm0, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
973 FONT_JTEX font_jtex, int *need_free_p)
974 {
975 VF_BITMAP bm, bm_mirror;
976 ADJ adj;
977 int ctype, i;
978
979 *need_free_p = 0;
980 if (((adj = font_jtex->adj) == NULL)
981 || (font_jtex->tfm->type_aux != METRIC_TYPE_JFM_AUX_V))
982 return bm0;
983
984 ctype = vf_tfm_jfm_chartype(font_jtex->tfm, (UINT4)code_point);
985 if (adj->ct_corr[ctype].may_need_rotate == FALSE)
986 return bm0;
987
988 for (i = 0; VertCharInfo[i].code_point > 0; i++){
989 if ((VertCharInfo[i].code_point == code_point)
990 && ((VertCharInfo[i].rot_semantics & adj->rot_semantics) != 0)){
991 if ((bm = VF_RotatedBitmap(bm0, VertCharInfo[i].angle)) == NULL)
992 return NULL;
993 if (VertCharInfo[i].mirror == 0){
994 *need_free_p = 1;
995 return bm;
996 }
997 if ((bm_mirror = VF_ReflectedBitmap(bm, 1, 0)) == NULL){
998 VF_FreeBitmap(bm);
999 return NULL;
1000 }
1001 VF_FreeBitmap(bm);
1002 *need_free_p = 1;
1003 return bm_mirror;
1004 }
1005 }
1006
1007 *need_free_p = 0;
1008 return bm0;
1009 }
1010
1011
1012
1013 Private int
1014 jtex_met_adjustment(VF_BITMAP bm, VF_METRIC2 met2, long code_point,
/* [<][>][^][v][top][bottom][index][help] */
1015 VF_FONT font, FONT_JTEX font_jtex,
1016 double mag_x, double mag_y)
1017 {
1018 ADJ adj;
1019 int ctype, dx, dy;
1020 double dpix, dpiy, fdx, fdy, ds, dr;
1021
1022 bm->mv_x = met2->mv_x;
1023 bm->mv_y = met2->mv_y;
1024
1025 if ((adj = font_jtex->adj) == NULL){
1026 if (vf_dbg_drv_ascii_jtex_adj == 1)
1027 printf(">>VFlib ascii jtex ADJ: none\n");
1028 return 0;
1029 }
1030
1031 ctype = vf_tfm_jfm_chartype(font_jtex->tfm, (UINT4)code_point);
1032 fdx = adj->ct_corr[ctype].dx + adj->ct_corr_all.dx;
1033 fdy = adj->ct_corr[ctype].dy + adj->ct_corr_all.dy;
1034 if (adj->ct_corr[ctype].need_cc_corr)
1035 jtex_met_cc_adjustment(adj, code_point, ctype, &fdx, &fdy);
1036
1037 ds = font_jtex->tfm->design_size;
1038 dr = 1.0;
1039 if (font->point_size > 0)
1040 dr = font->point_size / ds;
1041
1042 dx = 0;
1043 dy = 0;
1044
1045 switch (font->mode){
1046 case 1:
1047 if (adj->semantics == SEMANTICS_AUX_BITMAP){
1048 dx = met2->bbx_width * fdx * mag_x * font->mag_x;
1049 dy = met2->bbx_height * fdy * mag_y * font->mag_y;
1050 } else if (adj->semantics == SEMANTICS_DESIGN_SIZE){
1051 if (((dpix = font->dpi_x) < 0) || ((dpiy = font->dpi_y) < 0)){
1052 dpix = vf_tex_default_dpi();
1053 dpiy = vf_tex_default_dpi();
1054 }
1055 dx = (dpix/72.27) * ds * dr * fdx * mag_x * font->mag_x;
1056 dy = (dpiy/72.27) * ds * dr * fdy * mag_y * font->mag_y;
1057 }
1058 break;
1059 case 2:
1060 default:
1061 if (adj->semantics == SEMANTICS_AUX_BITMAP){
1062 dx = met2->bbx_width * fdx * mag_x * font->mag_x;
1063 dy = met2->bbx_height * fdy * mag_y * font->mag_y;
1064 } else if (adj->semantics == SEMANTICS_DESIGN_SIZE){
1065 dx = font_jtex->mode2_factor_x * ds * dr * fdx * mag_x * font->mag_x;
1066 dy = font_jtex->mode2_factor_y * ds * dr * fdy * mag_y * font->mag_y;
1067 }
1068 break;
1069 }
1070 bm->off_x += dx;
1071 bm->off_y += dy;
1072
1073 if (vf_dbg_drv_ascii_jtex_adj == 1){
1074 printf(">>VFlib ascii jtex ADJ 0x%x CharType %d %.3f,%.3f BBX[%d,%d]\n",
1075 (int)code_point, ctype,
1076 adj->ct_corr[ctype].dx, adj->ct_corr[ctype].dy,
1077 met2->bbx_width, met2->bbx_height);
1078 }
1079
1080 return 0;
1081 }
1082
1083 Private void
1084 jtex_met_cc_adjustment(ADJ adj, long code_point, int char_type,
/* [<][>][^][v][top][bottom][index][help] */
1085 double *fxp, double *fyp)
1086 {
1087 int i, last;
1088
1089 last = adj->n_cc_corr - 1;
1090 adj->cc_corr[last].code_point = code_point;
1091 adj->cc_corr[last].dx = 0.0;
1092 adj->cc_corr[last].dy = 0.0;
1093
1094 for (i = 0; adj->cc_corr[i].code_point != code_point; i++)
1095 ;
1096
1097 if (i != last){
1098 if (vf_dbg_drv_ascii_jtex_adj == 1)
1099 printf(">>VFlib: ascii jtex: cc adj: 0x%04lx %.3f %.3f\n",
1100 code_point, adj->cc_corr[i].dx, adj->cc_corr[i].dy);
1101 /* Override! */
1102 *fxp = adj->cc_corr[i].dx;
1103 *fyp = adj->cc_corr[i].dy;
1104 }
1105 }
1106
1107
1108 Private ADJ
1109 jtex_read_met_adjustment_file(FONT_JTEX font_jtex, char* file_name)
/* [<][>][^][v][top][bottom][index][help] */
1110 {
1111 FILE *fp;
1112 ADJ adj;
1113 SEXP s, s0, s1, s2, s3;
1114 int ct, i_cc, i;
1115 long cc;
1116 char *path, *key;
1117
1118 if (file_name == NULL){
1119 vf_error = VF_ERR_CANT_OPEN;
1120 return NULL;
1121 }
1122
1123 path = find_adj(file_name);
1124 if (path == NULL){
1125 vf_error = VF_ERR_CANT_OPEN;
1126 return NULL;
1127 }
1128
1129 if ((fp = vf_fm_OpenTextFileStream(path)) == NULL){
1130 vf_free(path);
1131 vf_error = VF_ERR_CANT_OPEN;
1132 return NULL;
1133 }
1134
1135 ALLOC_IF_ERR(adj, struct s_met_adj_table){
1136 vf_error = VF_ERR_NO_MEMORY;
1137 vf_free(path);
1138 return NULL;
1139 }
1140
1141 adj->semantics = -1;
1142 adj->dir = -1;
1143 adj->rot_semantics = -1;
1144 for (ct = 0; ct < JTEX_MAX_CHARTYPE; ct++){
1145 adj->ct_corr[ct].need_cc_corr = FALSE;
1146 adj->ct_corr[ct].may_need_rotate = FALSE;
1147 adj->ct_corr[ct].dx = 0.0;
1148 adj->ct_corr[ct].dy = 0.0;
1149 }
1150 adj->ct_corr_all.dx = 0.0;
1151 adj->ct_corr_all.dy = 0.0;
1152
1153 for (i = 0; VertCharInfo[i].code_point > 0; i++){
1154 ct = vf_tfm_jfm_chartype(font_jtex->tfm,
1155 (UINT4)VertCharInfo[i].code_point);
1156 adj->ct_corr[ct].may_need_rotate = TRUE;
1157 }
1158
1159 adj->n_cc_corr = 0;
1160 if (realloc_cc_corr(adj) == NULL){
1161 vf_free(adj);
1162 vf_free(path);
1163 return NULL;
1164 }
1165
1166 i_cc = 0;
1167 s = NULL;
1168
1169 for (;;){
1170 vf_sexp_free(&s);
1171 if ((s = vf_sexp_read(fp)) == NULL)
1172 break;
1173
1174 if (vf_dbg_drv_ascii_jtex_adj == 1){
1175 printf(">>VFlib ascii jtex ADJ: ");
1176 vf_sexp_pp(s);
1177 }
1178
1179 if (!vf_sexp_listp(s)){
1180 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ", path);
1181 vf_sexp_pp(s);
1182 continue;
1183 }
1184 s0 = vf_sexp_car(s);
1185 if (!vf_sexp_stringp(s0)){
1186 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ", path);
1187 vf_sexp_pp(s);
1188 continue;
1189 }
1190
1191 key = vf_sexp_get_cstring(s0);
1192
1193 if (vf_strcmp_ci(key, KW_CHAR_ALL) == 0){
1194 if (vf_sexp_length(s) != 3){
1195 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1196 path);
1197 vf_sexp_pp(s);
1198 continue;
1199 }
1200 s1 = vf_sexp_cadr(s);
1201 s2 = vf_sexp_caddr(s);
1202 if (!vf_sexp_stringp(s1)||!vf_sexp_stringp(s2)){
1203 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1204 path);
1205 vf_sexp_pp(s);
1206 continue;
1207 }
1208 adj->ct_corr_all.dx = atof(vf_sexp_get_cstring(s1));
1209 adj->ct_corr_all.dy = atof(vf_sexp_get_cstring(s2));
1210 if (vf_dbg_drv_ascii_jtex_adj == 1){
1211 printf(">> %s: Correction: %.3f,%.3f\n",
1212 KW_CHAR_ALL, adj->ct_corr_all.dx, adj->ct_corr_all.dy);
1213 }
1214
1215 } else if (vf_strcmp_ci(key, KW_CHAR_TYPE) == 0){
1216 if (vf_sexp_length(s) != 4){
1217 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1218 path);
1219 vf_sexp_pp(s);
1220 continue;
1221 }
1222 s1 = vf_sexp_cadr(s);
1223 s2 = vf_sexp_caddr(s);
1224 s3 = vf_sexp_caddr(vf_sexp_cdr(s));
1225 if (!vf_sexp_stringp(s1)||!vf_sexp_stringp(s2)||!vf_sexp_stringp(s2)){
1226 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1227 path);
1228 vf_sexp_pp(s);
1229 continue;
1230 }
1231 ct = atoi(vf_sexp_get_cstring(s1));
1232 if ((ct < 0) || (JTEX_MAX_CHARTYPE <= ct)){
1233 fprintf(stderr, "VFlib warning: %s %d out of range in %s.\n",
1234 KW_CHAR_TYPE, ct, path);
1235 continue;
1236 }
1237 adj->ct_corr[ct].dx = atof(vf_sexp_get_cstring(s2));
1238 adj->ct_corr[ct].dy = atof(vf_sexp_get_cstring(s3));
1239 if (vf_dbg_drv_ascii_jtex_adj == 1){
1240 printf(">> %s CharType: %02d, Correction: %.3f,%.3f\n",
1241 KW_CHAR_TYPE, ct, adj->ct_corr[ct].dx, adj->ct_corr[ct].dy);
1242 }
1243
1244 } else if (vf_strcmp_ci(key, KW_CHAR_CODE) == 0){
1245 if (vf_sexp_length(s) != 4){
1246 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1247 path);
1248 vf_sexp_pp(s);
1249 continue;
1250 }
1251 s1 = vf_sexp_cadr(s);
1252 s2 = vf_sexp_caddr(s);
1253 s3 = vf_sexp_caddr(vf_sexp_cdr(s));
1254 if (!vf_sexp_stringp(s1)||!vf_sexp_stringp(s2)||!vf_sexp_stringp(s2)){
1255 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1256 path);
1257 vf_sexp_pp(s);
1258 continue;
1259 }
1260 cc = atoi(vf_sexp_get_cstring(s1));
1261 if (cc < 0){
1262 fprintf(stderr, "VFlib warning: %s %d out of range in %s.\n",
1263 KW_CHAR_CODE, ct, path);
1264 continue;
1265 }
1266 if (i_cc >= (adj->n_cc_corr-1))
1267 realloc_cc_corr(adj);
1268 sscanf(vf_sexp_get_cstring(s1), "%li", &cc);
1269 adj->cc_corr[i_cc].code_point = cc;
1270 adj->cc_corr[i_cc].dx = atof(vf_sexp_get_cstring(s2));
1271 adj->cc_corr[i_cc].dy = atof(vf_sexp_get_cstring(s3));
1272 if (vf_dbg_drv_ascii_jtex_adj == 1){
1273 printf(">> %s Code: 0x%lx, Correection: %.3f,%.3f\n",
1274 KW_CHAR_CODE, cc,
1275 adj->cc_corr[i_cc].dx, adj->cc_corr[i_cc].dy);
1276 }
1277 i_cc++;
1278 ct = vf_tfm_jfm_chartype(font_jtex->tfm, (UINT4)cc);
1279 adj->ct_corr[ct].need_cc_corr = TRUE;
1280
1281 } else if (vf_strcmp_ci(key, KW_SEMANTICS) == 0){
1282 if (vf_sexp_length(s) != 2){
1283 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1284 path);
1285 vf_sexp_pp(s);
1286 continue;
1287 }
1288 s1 = vf_sexp_cadr(s);
1289 if (!vf_sexp_stringp(s1)){
1290 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1291 path);
1292 vf_sexp_pp(s);
1293 continue;
1294 }
1295 if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_SEM_BITMAP) == 0){
1296 adj->semantics = SEMANTICS_AUX_BITMAP;
1297 } else if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_SEM_DESIGN) == 0){
1298 adj->semantics = SEMANTICS_DESIGN_SIZE;
1299 } else {
1300 fprintf(stderr, "VFlib warning: Unknown semantics name %s in %s.\n",
1301 vf_sexp_get_cstring(s1), path);
1302 }
1303
1304 } else if (vf_strcmp_ci(key, KW_DIR) == 0){
1305 if (vf_sexp_length(s) != 2){
1306 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1307 path);
1308 vf_sexp_pp(s);
1309 continue;
1310 }
1311 s1 = vf_sexp_cadr(s);
1312 if (!vf_sexp_stringp(s1)){
1313 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1314 path);
1315 vf_sexp_pp(s);
1316 continue;
1317 }
1318 if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_DIR_HORIZONTAL) == 0){
1319 adj->dir = DIR_HORIZONTAL;
1320 } else if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_DIR_VERTICAL) == 0){
1321 adj->dir = DIR_VERTICAL;
1322 } else {
1323 fprintf(stderr, "VFlib warning: Unknown direction name %s in %s.\n",
1324 vf_sexp_get_cstring(s1), path);
1325 fprintf(stderr, "Use \"%s\" or \"%s\"\n",
1326 KW_DIR_HORIZONTAL, KW_DIR_VERTICAL);
1327 }
1328
1329 } else if (vf_strcmp_ci(key, KW_ROTATION) == 0){
1330 if (vf_sexp_length(s) != 2){
1331 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1332 path);
1333 vf_sexp_pp(s);
1334 continue;
1335 }
1336 s1 = vf_sexp_cadr(s);
1337 if (!vf_sexp_stringp(s1)){
1338 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ",
1339 path);
1340 vf_sexp_pp(s);
1341 continue;
1342 }
1343 if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_ROT_PTEX) == 0){
1344 adj->rot_semantics = ROT_PTEX;
1345 } else if (vf_strcmp_ci(vf_sexp_get_cstring(s1), KW_ROT_JISX0208) == 0){
1346 adj->rot_semantics = ROT_JISX0208;
1347 } else {
1348 fprintf(stderr, "VFlib warning: Unknown keyword %s in %s.\n",
1349 vf_sexp_get_cstring(s1), path);
1350 fprintf(stderr, "Use \"%s\" or \"%s\"\n",
1351 KW_ROT_PTEX, KW_ROT_JISX0208);
1352 }
1353
1354 } else {
1355 fprintf(stderr, "VFlib warning: Illegal ADJ file format in %s: ", path);
1356 vf_sexp_pp(s);
1357 continue;
1358 }
1359 }
1360
1361 /* default values */
1362 if (adj->semantics == -1)
1363 adj->semantics = SEMANTICS_AUX_BITMAP;
1364 if (adj->dir == -1)
1365 adj->dir = DIR_HORIZONTAL;
1366 if (adj->rot_semantics == -1)
1367 adj->rot_semantics = ROT_PTEX;
1368
1369 vf_free(path);
1370
1371 return adj;
1372 }
1373
1374 Private void
1375 jtex_free_adj(ADJ adj)
/* [<][>][^][v][top][bottom][index][help] */
1376 {
1377 if (adj != NULL){
1378 vf_free(adj->cc_corr);
1379 vf_free(adj);
1380 }
1381 }
1382
1383 Private ADJ
1384 realloc_cc_corr(ADJ adj)
/* [<][>][^][v][top][bottom][index][help] */
1385 {
1386 ADJ_CC_CORR new_cc_corr;
1387 int new_size, i;
1388
1389 new_size = 2 * adj->n_cc_corr;
1390 if (new_size <= 0)
1391 new_size = N_CC_CORR;
1392
1393 ALLOCN_IF_ERR(new_cc_corr, struct s_met_adj_cc_corr, new_size){
1394 vf_error = VF_ERR_NO_MEMORY;
1395 return NULL;
1396 }
1397
1398 for (i = 0; i < adj->n_cc_corr; i++){
1399 new_cc_corr[i].code_point = adj->cc_corr[i].code_point;
1400 new_cc_corr[i].dx = adj->cc_corr[i].dx;
1401 new_cc_corr[i].dy = adj->cc_corr[i].dy;
1402 }
1403 for (i = adj->n_cc_corr; i < new_size; i++){
1404 new_cc_corr[i].code_point = -1L;
1405 new_cc_corr[i].dx = 0.0;
1406 new_cc_corr[i].dy = 0.0;
1407 }
1408
1409 vf_free(adj->cc_corr);
1410 adj->n_cc_corr = new_size;
1411 adj->cc_corr = new_cc_corr;
1412
1413 return adj;
1414 }
1415
1416
1417 Private char*
1418 find_adj(char *fname)
/* [<][>][^][v][top][bottom][index][help] */
1419 {
1420 char *path;
1421
1422 if (fname == NULL)
1423 return NULL;
1424
1425 if (vf_dbg_drv_ascii_jtex_adj == 1)
1426 printf(">>VFlib ascii jtex: Searching ADJ file: %s\n", fname);
1427
1428 path = NULL;
1429 if (vf_path_absolute(fname)){
1430 if (vf_path_file_read_ok(fname)){
1431 if ((path = vf_strdup(fname)) == NULL)
1432 vf_error = VF_ERR_NO_MEMORY;
1433 }
1434 } else {
1435 path = vf_path_find_runtime_file("ascii-jtex", fname,
1436 VFLIB_ENV_ASCII_JTEX_DIR);
1437 }
1438
1439 if (vf_dbg_drv_ascii_jtex_adj == 1){
1440 if (path != NULL)
1441 printf(">> --- found: %s\n", path);
1442 else
1443 printf(">> --- not found\n");
1444 }
1445
1446 return path;
1447 }
1448
1449
1450
1451 /*EOF*/