1 /* #define FONTDEBUG */
2 /*
3 * Copyright 1992, 1993 by TOSHIBA Corp.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation for any purpose and without fee is hereby granted, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of TOSHIBA not be used in advertising
10 * or publicity pertaining to distribution of the software without specific,
11 * written prior permission. TOSHIBA make no representations about the
12 * suitability of this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
14 *
15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 * SOFTWARE.
22 *
23 * Author: Katsuhisa Yano TOSHIBA Corp.
24 * mopi@osa.ilab.toshiba.co.jp
25 */
26 /*
27 * Copyright 1995 by FUJITSU LIMITED
28 * This is source code modified by FUJITSU LIMITED under the Joint
29 * Development Agreement for the CDE/Motif PST.
30 *
31 * Modifier: Takanori Tateno FUJITSU LIMITED
32 *
33 */
34
35 /*
36 * Fixed the algorithms in parse_fontname() and parse_fontdata()
37 * to improve the logic for determining which font should be
38 * returned for a given CharSet. We even added some comments
39 * so that you can figure out what in the heck we're doing. We
40 * realize this is a departure from the norm, but hey, we're
41 * rebels! :-) :-)
42 *
43 * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD
44 */
45 /*
46 * Cleaned up mess, removed some blabla
47 * Egbert Eich, SuSE Linux AG
48 */
49
50 #ifdef HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53 #include "Xlibint.h"
54 #include "XomGeneric.h"
55 #include "XlcGeneric.h"
56 #include <X11/Xos.h>
57 #include <X11/Xatom.h>
58 #include <stdio.h>
59 #include <string.h>
60 #include <ctype.h>
61
62 #define MAXFONTS 100
63 #define PIXEL_SIZE_FIELD 7
64 #define POINT_SIZE_FIELD 8
65 #define CHARSET_ENCODING_FIELD 14
66 #define XLFD_MAX_LEN 255
67
68 /* For VW/UDC start */
69
70 static FontData
init_fontdata(FontData font_data,int font_data_count)71 init_fontdata(
72 FontData font_data,
73 int font_data_count)
74 {
75 FontData fd;
76 int i;
77
78 fd = Xcalloc(font_data_count, sizeof(FontDataRec));
79 if(fd == (FontData) NULL)
80 return False;
81
82 for(i = 0 ; i < font_data_count ; i++)
83 fd[i] = font_data[i];
84
85 return fd;
86 }
87
88 static VRotate
init_vrotate(FontData font_data,int font_data_count,int type,CodeRange code_range,int code_range_num)89 init_vrotate(
90 FontData font_data,
91 int font_data_count,
92 int type,
93 CodeRange code_range,
94 int code_range_num)
95 {
96 VRotate vrotate;
97 int i;
98
99 if(type == VROTATE_NONE)
100 return (VRotate)NULL;
101
102 vrotate = Xcalloc(font_data_count, sizeof(VRotateRec));
103 if(vrotate == (VRotate) NULL)
104 return False;
105
106 for(i = 0 ; i < font_data_count ; i++) {
107 vrotate[i].charset_name = font_data[i].name;
108 vrotate[i].side = font_data[i].side;
109 if(type == VROTATE_PART) {
110 vrotate[i].num_cr = code_range_num;
111 vrotate[i].code_range = code_range;
112 }
113 }
114
115 return vrotate;
116 }
117
118 static Bool
init_fontset(XOC oc)119 init_fontset(
120 XOC oc)
121 {
122 XOCGenericPart *gen;
123 FontSet font_set;
124 OMData data;
125 int count;
126
127 count = XOM_GENERIC(oc->core.om)->data_num;
128 data = XOM_GENERIC(oc->core.om)->data;
129
130 font_set = Xcalloc(count, sizeof(FontSetRec));
131 if (font_set == NULL)
132 return False;
133
134 gen = XOC_GENERIC(oc);
135 gen->font_set_num = count;
136 gen->font_set = font_set;
137
138 for ( ; count-- > 0; data++, font_set++) {
139 font_set->charset_count = data->charset_count;
140 font_set->charset_list = data->charset_list;
141
142 if((font_set->font_data = init_fontdata(data->font_data,
143 data->font_data_count)) == NULL)
144 goto err;
145 font_set->font_data_count = data->font_data_count;
146 if((font_set->substitute = init_fontdata(data->substitute,
147 data->substitute_num)) == NULL)
148 goto err;
149 font_set->substitute_num = data->substitute_num;
150 if((font_set->vmap = init_fontdata(data->vmap,
151 data->vmap_num)) == NULL)
152 goto err;
153 font_set->vmap_num = data->vmap_num;
154
155 if(data->vrotate_type != VROTATE_NONE) {
156 /* A vrotate member is specified primary font data */
157 /* as initial value. */
158 if((font_set->vrotate = init_vrotate(data->font_data,
159 data->font_data_count,
160 data->vrotate_type,
161 data->vrotate,
162 data->vrotate_num)) == NULL)
163 goto err;
164 font_set->vrotate_num = data->font_data_count;
165 }
166 }
167 return True;
168
169 err:
170
171 Xfree(font_set->font_data);
172 Xfree(font_set->substitute);
173 Xfree(font_set->vmap);
174 Xfree(font_set->vrotate);
175 Xfree(font_set);
176 gen->font_set = (FontSet) NULL;
177 gen->font_set_num = 0;
178 return False;
179 }
180
181 /* For VW/UDC end */
182
183 static char *
get_prop_name(Display * dpy,XFontStruct * fs)184 get_prop_name(
185 Display *dpy,
186 XFontStruct *fs)
187 {
188 unsigned long fp;
189
190 if (XGetFontProperty(fs, XA_FONT, &fp))
191 return XGetAtomName(dpy, fp);
192
193 return (char *) NULL;
194 }
195
196 /* For VW/UDC start */
197
198 static Bool
load_fontdata(XOC oc,FontData font_data,int font_data_num)199 load_fontdata(
200 XOC oc,
201 FontData font_data,
202 int font_data_num)
203 {
204 Display *dpy = oc->core.om->core.display;
205 FontData fd = font_data;
206
207 if(font_data == NULL) return(True);
208 for( ; font_data_num-- ; fd++) {
209 if(fd->xlfd_name != (char *) NULL && fd->font == NULL) {
210 fd->font = XLoadQueryFont(dpy, fd->xlfd_name);
211 if (fd->font == NULL){
212 return False;
213 }
214 }
215 }
216 return True;
217 }
218
219 static Bool
load_fontset_data(XOC oc,FontSet font_set)220 load_fontset_data(
221 XOC oc,
222 FontSet font_set)
223 {
224 Display *dpy = oc->core.om->core.display;
225
226 if(font_set->font_name == (char *)NULL) return False ;
227
228 /* If font_set->font is not NULL, it contains the *best*
229 * match font for this FontSet.
230 * -- jjw/pma (HP)
231 */
232 if(font_set->font == NULL) {
233 font_set->font = XLoadQueryFont(dpy, font_set->font_name);
234 if (font_set->font == NULL){
235 return False;
236 }
237 }
238 return True;
239 }
240
241 static Bool
load_font(XOC oc)242 load_font(
243 XOC oc)
244 {
245 XOCGenericPart *gen = XOC_GENERIC(oc);
246 FontSet font_set = gen->font_set;
247 int num = gen->font_set_num;
248
249 for ( ; num-- > 0; font_set++) {
250 if (font_set->font_name == NULL)
251 continue;
252
253 if (load_fontset_data (oc, font_set) != True)
254 return False;
255 #ifndef TESTVERSION
256 if(load_fontdata(oc, font_set->font_data,
257 font_set->font_data_count) != True)
258 return False;
259
260 if(load_fontdata(oc, font_set->substitute,
261 font_set->substitute_num) != True)
262 return False;
263 #endif
264
265 /* Add 1996.05.20 */
266 if( oc->core.orientation == XOMOrientation_TTB_RTL ||
267 oc->core.orientation == XOMOrientation_TTB_LTR ){
268 if (font_set->vpart_initialize == 0) {
269 load_fontdata(oc, font_set->vmap, font_set->vmap_num);
270 load_fontdata(oc, (FontData) font_set->vrotate,
271 font_set->vrotate_num);
272 font_set->vpart_initialize = 1;
273 }
274 }
275
276 if (font_set->font->min_byte1 || font_set->font->max_byte1)
277 font_set->is_xchar2b = True;
278 else
279 font_set->is_xchar2b = False;
280 }
281
282 return True;
283 }
284
285 /* For VW/UDC end */
286
287 static Bool
load_font_info(XOC oc)288 load_font_info(
289 XOC oc)
290 {
291 Display *dpy = oc->core.om->core.display;
292 XOCGenericPart *gen = XOC_GENERIC(oc);
293 FontSet font_set = gen->font_set;
294 char **fn_list;
295 int fn_num, num = gen->font_set_num;
296
297 for ( ; num-- > 0; font_set++) {
298 if (font_set->font_name == NULL)
299 continue;
300
301 if (font_set->info == NULL) {
302 fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
303 &font_set->info);
304 if (font_set->info == NULL)
305 return False;
306
307 XFreeFontNames(fn_list);
308 }
309 }
310
311 return True;
312 }
313
314 /* For Vertical Writing start */
315
316 static void
check_fontset_extents(XCharStruct * overall,int * logical_ascent,int * logical_descent,XFontStruct * font)317 check_fontset_extents(
318 XCharStruct *overall,
319 int *logical_ascent,
320 int *logical_descent,
321 XFontStruct *font)
322 {
323 overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing);
324 overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing);
325 overall->ascent = max(overall->ascent, font->max_bounds.ascent);
326 overall->descent = max(overall->descent, font->max_bounds.descent);
327 overall->width = max(overall->width, font->max_bounds.width);
328 *logical_ascent = max(*logical_ascent, font->ascent);
329 *logical_descent = max(*logical_descent, font->descent);
330 }
331
332 /* For Vertical Writing end */
333
334 static void
set_fontset_extents(XOC oc)335 set_fontset_extents(
336 XOC oc)
337 {
338 XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
339 XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
340 XFontStruct **font_list, *font;
341 XCharStruct overall;
342 int logical_ascent, logical_descent;
343 int num = oc->core.font_info.num_font;
344
345 font_list = oc->core.font_info.font_struct_list;
346 font = *font_list++;
347 overall = font->max_bounds;
348 overall.lbearing = font->min_bounds.lbearing;
349 logical_ascent = font->ascent;
350 logical_descent = font->descent;
351
352 /* For Vertical Writing start */
353
354 while (--num > 0) {
355 font = *font_list++;
356 check_fontset_extents(&overall, &logical_ascent, &logical_descent,
357 font);
358 }
359
360 {
361 XOCGenericPart *gen = XOC_GENERIC(oc);
362 FontSet font_set = gen->font_set;
363 FontData font_data;
364 int font_set_num = gen->font_set_num;
365 int font_data_count;
366
367 for( ; font_set_num-- ; font_set++) {
368 if(font_set->vmap_num > 0) {
369 font_data = font_set->vmap;
370 font_data_count = font_set->vmap_num;
371 for( ; font_data_count-- ; font_data++) {
372 if(font_data->font != NULL) {
373 check_fontset_extents(&overall, &logical_ascent,
374 &logical_descent,
375 font_data->font);
376 }
377 }
378 }
379
380 if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) {
381 font_data = (FontData) font_set->vrotate;
382 font_data_count = font_set->vrotate_num;
383 for( ; font_data_count-- ; font_data++) {
384 if(font_data->font != NULL) {
385 check_fontset_extents(&overall, &logical_ascent,
386 &logical_descent,
387 font_data->font);
388 }
389 }
390 }
391 }
392 }
393
394 /* For Vertical Writing start */
395
396 ink->x = overall.lbearing;
397 ink->y = -(overall.ascent);
398 ink->width = overall.rbearing - overall.lbearing;
399 ink->height = overall.ascent + overall.descent;
400
401 logical->x = 0;
402 logical->y = -(logical_ascent);
403 logical->width = overall.width;
404 logical->height = logical_ascent + logical_descent;
405 }
406
407 static Bool
init_core_part(XOC oc)408 init_core_part(
409 XOC oc)
410 {
411 XOCGenericPart *gen = XOC_GENERIC(oc);
412 FontSet font_set;
413 int font_set_num;
414 XFontStruct **font_struct_list;
415 char **font_name_list, *font_name_buf;
416 int count, length;
417
418 font_set = gen->font_set;
419 font_set_num = gen->font_set_num;
420 count = length = 0;
421
422 for ( ; font_set_num-- > 0; font_set++) {
423 if (font_set->font_name == NULL)
424 continue;
425
426 length += strlen(font_set->font_name) + 1;
427
428 count++;
429 }
430 if (count == 0)
431 return False;
432
433 font_struct_list = Xmalloc(sizeof(XFontStruct *) * count);
434 if (font_struct_list == NULL)
435 return False;
436
437 font_name_list = Xmalloc(sizeof(char *) * count);
438 if (font_name_list == NULL)
439 goto err;
440
441 font_name_buf = Xmalloc(length);
442 if (font_name_buf == NULL)
443 goto err;
444
445 oc->core.font_info.num_font = count;
446 oc->core.font_info.font_name_list = font_name_list;
447 oc->core.font_info.font_struct_list = font_struct_list;
448
449 font_set = gen->font_set;
450 font_set_num = gen->font_set_num;
451
452 for (count = 0; font_set_num-- > 0; font_set++) {
453 if (font_set->font_name == NULL)
454 continue;
455
456 font_set->id = count;
457 if (font_set->font)
458 *font_struct_list++ = font_set->font;
459 else
460 *font_struct_list++ = font_set->info;
461 strcpy(font_name_buf, font_set->font_name);
462 Xfree(font_set->font_name);
463 *font_name_list++ = font_set->font_name = font_name_buf;
464 font_name_buf += strlen(font_name_buf) + 1;
465
466 count++;
467 }
468
469 set_fontset_extents(oc);
470
471 return True;
472
473 err:
474
475 Xfree(font_name_list);
476 Xfree(font_struct_list);
477
478 return False;
479 }
480
481 static char *
get_font_name(XOC oc,char * pattern)482 get_font_name(
483 XOC oc,
484 char *pattern)
485 {
486 char **list, *name;
487 int count = 0;
488
489 list = XListFonts(oc->core.om->core.display, pattern, 1, &count);
490 if (list == NULL)
491 return NULL;
492
493 name = strdup(*list);
494
495 XFreeFontNames(list);
496
497 return name;
498 }
499
500 /* For VW/UDC start*/
501
502 static char *
get_rotate_fontname(char * font_name)503 get_rotate_fontname(
504 char *font_name)
505 {
506 char *pattern = NULL, *ptr = NULL;
507 char *fields[CHARSET_ENCODING_FIELD];
508 char str_pixel[32], str_point[4];
509 char *rotate_font_ptr = NULL;
510 int pixel_size = 0;
511 int field_num = 0, len = 0;
512
513 if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0
514 || len > XLFD_MAX_LEN)
515 return NULL;
516
517 pattern = strdup(font_name);
518 if(!pattern)
519 return NULL;
520
521 memset(fields, 0, sizeof(char *) * 14);
522 ptr = pattern;
523 while(isspace(*ptr)) {
524 ptr++;
525 }
526 if(*ptr == '-')
527 ptr++;
528
529 for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ;
530 ptr++, field_num++) {
531 fields[field_num] = ptr;
532
533 if((ptr = strchr(ptr, '-'))) {
534 *ptr = '\0';
535 } else {
536 field_num++; /* Count last field */
537 break;
538 }
539 }
540
541 if(field_num < CHARSET_ENCODING_FIELD)
542 goto free_pattern;
543
544 /* Pixel Size field : fields[6] */
545 for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) {
546 if(!isdigit(*ptr)) {
547 if(*ptr == '['){ /* 960730 */
548 strcpy(pattern, font_name);
549 return(pattern);
550 }
551 goto free_pattern;
552 }
553 }
554 pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]);
555 snprintf(str_pixel, sizeof(str_pixel),
556 "[ 0 ~%d %d 0 ]", pixel_size, pixel_size);
557 fields[6] = str_pixel;
558
559 /* Point Size field : fields[7] */
560 strcpy(str_point, "*");
561 fields[POINT_SIZE_FIELD - 1] = str_point;
562
563 len = 0;
564 for (field_num = 0; field_num < CHARSET_ENCODING_FIELD &&
565 fields[field_num]; field_num++) {
566 len += 1 + strlen(fields[field_num]);
567 }
568
569 /* Max XLFD length is 255 */
570 if (len > XLFD_MAX_LEN)
571 goto free_pattern;
572
573 rotate_font_ptr = Xmalloc(len + 1);
574 if(!rotate_font_ptr)
575 goto free_pattern;
576
577 rotate_font_ptr[0] = '\0';
578
579 for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD &&
580 fields[field_num] ; field_num++) {
581 strcat(rotate_font_ptr, "-");
582 strcat(rotate_font_ptr, fields[field_num]);
583 }
584
585 free_pattern:
586 Xfree(pattern);
587
588 return rotate_font_ptr;
589 }
590
591 static Bool
is_match_charset(FontData font_data,char * font_name)592 is_match_charset(
593 FontData font_data,
594 char *font_name)
595 {
596 char *last;
597 int length, name_len;
598
599 name_len = strlen(font_name);
600 last = font_name + name_len;
601
602 length = strlen(font_data->name);
603 if (length > name_len)
604 return False;
605
606 if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
607 return True;
608
609 return False;
610 }
611
612 static int
parse_all_name(XOC oc,FontData font_data,char * pattern)613 parse_all_name(
614 XOC oc,
615 FontData font_data,
616 char *pattern)
617 {
618
619 #ifdef OLDCODE
620 if(is_match_charset(font_data, pattern) != True)
621 return False;
622
623 font_data->xlfd_name = strdup(pattern);
624 if(font_data->xlfd_name == NULL)
625 return (-1);
626
627 return True;
628 #else /* OLDCODE */
629 Display *dpy = oc->core.om->core.display;
630 char **fn_list = NULL, *prop_fname = NULL;
631 int list_num;
632 XFontStruct *fs_list;
633 if(is_match_charset(font_data, pattern) != True) {
634 /*
635 * pattern should not contain any wildcard (execpt '?')
636 * this was probably added to make this case insensitive.
637 */
638 if ((fn_list = XListFontsWithInfo(dpy, pattern,
639 MAXFONTS,
640 &list_num, &fs_list)) == NULL) {
641 return False;
642 }
643 /* shouldn't we loop here ? */
644 else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) {
645 XFreeFontInfo(fn_list, fs_list, list_num);
646 return False;
647 }
648 else if ((is_match_charset(font_data, prop_fname) != True)) {
649 XFree(prop_fname);
650 XFreeFontInfo(fn_list, fs_list, list_num);
651 return False;
652 }
653 else {
654 font_data->xlfd_name = prop_fname;
655 XFreeFontInfo(fn_list, fs_list, list_num);
656 return True;
657 }
658 }
659
660 font_data->xlfd_name = strdup(pattern);
661 if(font_data->xlfd_name == NULL)
662 return (-1);
663
664 return True;
665 #endif /* OLDCODE */
666 }
667
668 static int
parse_omit_name(XOC oc,FontData font_data,char * pattern)669 parse_omit_name(
670 XOC oc,
671 FontData font_data,
672 char *pattern)
673 {
674 char* last = (char *) NULL;
675 char* base_name;
676 char buf[XLFD_MAX_LEN + 1];
677 int length = 0;
678 int num_fields;
679 /*
680 * If the font specified by "pattern" is expandable to be
681 * a member of "font_data"'s FontSet, we've found a match.
682 */
683 if(is_match_charset(font_data, pattern) == True) {
684 if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) {
685 return True;
686 }
687 }
688
689 length = strlen (pattern);
690
691 if (length > XLFD_MAX_LEN)
692 return -1;
693
694 strcpy(buf, pattern);
695 last = buf + length - 1;
696
697 /* Replace the original encoding with the encoding for this FontSet. */
698
699 /* Figure out how many fields have been specified in this xlfd. */
700 for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
701 if (*base_name == '-') num_fields++;
702
703 switch (num_fields) {
704 case 12:
705 /* This is the best way to have specified the fontset. In this
706 * case, there is no original encoding. E.g.,
707 * -*-*-*-*-*-*-14-*-*-*-*-*
708 * To this, we'll append a dash:
709 * -*-*-*-*-*-*-14-*-*-*-*-*-
710 * then append the encoding to get:
711 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
712 */
713 /*
714 * Take care of:
715 * -*-*-*-*-*-*-14-*-*-*-*-
716 */
717 if (*(last) == '-')
718 *++last = '*';
719
720 *++last = '-';
721 break;
722 case 13:
723 /* Got the charset, not the encoding, zap the charset In this
724 * case, there is no original encoding, but there is a charset. E.g.,
725 * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990
726 * To this, we remove the charset:
727 * -*-*-*-*-*-*-14-*-*-*-*-*-
728 * then append the new encoding to get:
729 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
730 */
731 last = strrchr (buf, '-');
732 num_fields = 12;
733 break;
734 case 14:
735 /* Both the charset and the encoding are specified. Get rid
736 * of them so that we can append the new charset encoding. E.g.,
737 * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0
738 * To this, we'll remove the encoding and charset to get:
739 * -*-*-*-*-*-*-14-*-*-*-*-*-
740 * then append the new encoding to get:
741 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
742 */
743 last = strrchr (buf, '-');
744 *last = '\0';
745 last = strrchr (buf, '-');
746 num_fields = 12;
747 break;
748 default:
749 if (*last != '-')
750 *++last = '-';
751 break;
752 }
753
754 /* At this point, "last" is pointing to the last "-" in the
755 * xlfd, and all xlfd's at this point take a form similar to:
756 * -*-*-*-*-*-*-14-*-*-*-*-*-
757 * (i.e., no encoding).
758 * After the strcpy, we'll end up with something similar to:
759 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
760 *
761 * If the modified font is found in the current FontSet,
762 * we've found a match.
763 */
764
765 last++;
766
767 if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN)
768 return -1;
769
770 strcpy(last, font_data->name);
771 if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
772 return True;
773
774 /* This may not be needed anymore as XListFonts() takes care of this */
775 if (num_fields < 12) {
776 if ((last - buf) > (XLFD_MAX_LEN - 2))
777 return -1;
778 *last = '*';
779 *(last + 1) = '-';
780 strcpy(last + 2, font_data->name);
781 num_fields++;
782 last+=2;
783 if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
784 return True;
785 }
786
787
788 return False;
789 }
790
791
792 typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType;
793
794 static int
parse_fontdata(XOC oc,FontSet font_set,FontData font_data,int font_data_count,char ** name_list,int name_list_count,ClassType class,FontDataRec * font_data_return)795 parse_fontdata(
796 XOC oc,
797 FontSet font_set,
798 FontData font_data,
799 int font_data_count,
800 char **name_list,
801 int name_list_count,
802 ClassType class,
803 FontDataRec *font_data_return)
804 {
805
806 char **cur_name_list = name_list;
807 char *font_name = (char *) NULL;
808 char *pattern = (char *) NULL;
809 int found_num = 0, ret = 0;
810 int count = name_list_count;
811
812 if(name_list == NULL || count <= 0) {
813 return False;
814 }
815
816 if(font_data == NULL || font_data_count <= 0) {
817 return False;
818 }
819
820 /* Loop through each font encoding defined in the "font_data" FontSet. */
821 for ( ; font_data_count-- > 0; font_data++) {
822 Bool is_found = False;
823 font_name = (char *) NULL;
824 count = name_list_count;
825 cur_name_list = name_list;
826
827 /*
828 * Loop through each font specified by the user
829 * in the call to XCreateFontset().
830 */
831 while (count-- > 0) {
832 pattern = *cur_name_list++;
833 if (pattern == NULL || *pattern == '\0')
834 continue;
835 #ifdef FONTDEBUG
836 fprintf(stderr,"Font pattern: %s %s\n",
837 pattern,font_data->name);
838 #endif
839
840 /*
841 * If the current font is fully specified (i.e., the
842 * xlfd contains no wildcards) and the font exists on
843 * the X Server, we have a match.
844 */
845 if (strchr(pattern, '*') == NULL &&
846 (font_name = get_font_name(oc, pattern))) {
847 /*
848 * Find the full xlfd name for this font. If the font is
849 * already in xlfd format, it is simply returned. If the
850 * font is an alias for another font, the xlfd of the
851 * aliased font is returned.
852 */
853 ret = parse_all_name(oc, font_data, font_name);
854 Xfree(font_name);
855
856 if (ret == -1) return -1;
857 if (ret == False) continue;
858 /*
859 * Since there was an exact match of a fully-specified font
860 * or a font alias, we can return now since the desired font
861 * was found for the current font encoding for this FontSet.
862 *
863 * Previous implementations of this algorithm would
864 * not return here. Instead, they continued searching
865 * through the font encodings for this FontSet. The side-effect
866 * of that behavior is you may return a "substitute" match
867 * instead of an "exact" match. We believe there should be a
868 * preference on exact matches. Therefore, as soon as we
869 * find one, we bail.
870 *
871 * Also, previous implementations seemed to think it was
872 * important to find either a primary or substitute font
873 * for each Font encoding in the FontSet before returning an
874 * acceptable font. We don't believe this is necessary.
875 * All the client cares about is finding a reasonable font
876 * for what was passed in. If we find an exact match,
877 * there's no reason to look any further.
878 *
879 * -- jjw/pma (HP)
880 */
881 if (font_data_return) {
882 font_data_return->xlfd_name = strdup(font_data->xlfd_name);
883 if (!font_data_return->xlfd_name) return -1;
884
885 font_data_return->side = font_data->side;
886 }
887 #ifdef FONTDEBUG
888 fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
889 #endif
890
891 return True;
892 }
893 /*
894 * If the font name is not fully specified
895 * (i.e., it has wildcards), we have more work to do.
896 * See the comments in parse_omit_name()
897 * for the list of things to do.
898 */
899 ret = parse_omit_name(oc, font_data, pattern);
900
901 if (ret == -1) return -1;
902 if (ret == False) continue;
903
904 /*
905 * A font which matched the wild-carded specification was found.
906 * Only update the return data if a font has not yet been found.
907 * This maintains the convention that FontSets listed higher in
908 * a CodeSet in the Locale Database have higher priority than
909 * those FontSets listed lower in the CodeSet. In the following
910 * example:
911 *
912 * fs1 {
913 * charset HP-JIS:GR
914 * font JISX0208.1990-0:GL;\
915 * JISX0208.1990-1:GR;\
916 * JISX0208.1983-0:GL;\
917 * JISX0208.1983-1:GR
918 * }
919 *
920 * a font found in the JISX0208.1990-0 FontSet will have a
921 * higher priority than a font found in the JISX0208.1983-0
922 * FontSet.
923 */
924 if (font_data_return && font_data_return->xlfd_name == NULL) {
925
926 #ifdef FONTDEBUG
927 fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
928 #endif
929 font_data_return->xlfd_name = strdup(font_data->xlfd_name);
930 if (!font_data_return->xlfd_name) return -1;
931
932 font_data_return->side = font_data->side;
933 }
934
935 found_num++;
936 is_found = True;
937
938 break;
939 }
940
941 switch(class) {
942 case C_PRIMARY:
943 if(is_found == False) {
944 /*
945 * Did not find a font for the current FontSet. Check the
946 * FontSet's "substitute" font for a match. If we find a
947 * match, we'll keep searching in hopes of finding an exact
948 * match later down the FontSet list.
949 *
950 * when we return and we have found a font font_data_return
951 * contains the first (ie. best) match no matter if this
952 * is a C_PRIMARY or a C_SUBSTITUTE font
953 */
954 ret = parse_fontdata(oc, font_set, font_set->substitute,
955 font_set->substitute_num, name_list,
956 name_list_count, C_SUBSTITUTE,
957 font_data_return);
958 if (ret == -1) return -1;
959 if (ret == False) continue;
960
961 found_num++;
962 is_found = True;
963 }
964 #ifdef TESTVERSION
965 else
966 return True;
967 #endif
968 break;
969
970 case C_SUBSTITUTE:
971 case C_VMAP:
972 if(is_found == True)
973 return True;
974 break;
975
976 case C_VROTATE:
977 if(is_found == True) {
978 char *rotate_name;
979
980 if((rotate_name = get_rotate_fontname(font_data->xlfd_name))
981 != NULL) {
982 Xfree(font_data->xlfd_name);
983 font_data->xlfd_name = rotate_name;
984
985 return True;
986 }
987 Xfree(font_data->xlfd_name);
988 font_data->xlfd_name = NULL;
989 return False;
990 }
991 break;
992 }
993 }
994
995 if(class == C_PRIMARY && found_num >= 1)
996 return True;
997
998 return False;
999 }
1000
1001
1002 static int
parse_vw(XOC oc,FontSet font_set,char ** name_list,int count)1003 parse_vw(
1004 XOC oc,
1005 FontSet font_set,
1006 char **name_list,
1007 int count)
1008 {
1009 FontData vmap = font_set->vmap;
1010 VRotate vrotate = font_set->vrotate;
1011 int vmap_num = font_set->vmap_num;
1012 int vrotate_num = font_set->vrotate_num;
1013 int ret = 0, i = 0;
1014
1015 if(vmap_num > 0) {
1016 if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list,
1017 count, C_VMAP,NULL) == -1)
1018 return (-1);
1019 }
1020
1021 if(vrotate_num > 0) {
1022 ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
1023 name_list, count, C_VROTATE, NULL);
1024 if(ret == -1) {
1025 return (-1);
1026 } else if(ret == False) {
1027 CodeRange code_range;
1028 int num_cr;
1029 int sub_num = font_set->substitute_num;
1030
1031 code_range = vrotate[0].code_range; /* ? */
1032 num_cr = vrotate[0].num_cr; /* ? */
1033 for(i = 0 ; i < vrotate_num ; i++) {
1034 if(vrotate[i].xlfd_name)
1035 Xfree(vrotate[i].xlfd_name);
1036 }
1037 Xfree(vrotate);
1038
1039 if(sub_num > 0) {
1040 vrotate = font_set->vrotate = Xcalloc(sub_num,
1041 sizeof(VRotateRec));
1042 if(font_set->vrotate == (VRotate)NULL)
1043 return (-1);
1044
1045 for(i = 0 ; i < sub_num ; i++) {
1046 vrotate[i].charset_name = font_set->substitute[i].name;
1047 vrotate[i].side = font_set->substitute[i].side;
1048 vrotate[i].code_range = code_range;
1049 vrotate[i].num_cr = num_cr;
1050 }
1051 vrotate_num = font_set->vrotate_num = sub_num;
1052 } else {
1053 vrotate = font_set->vrotate = (VRotate)NULL;
1054 }
1055
1056 ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
1057 name_list, count, C_VROTATE, NULL);
1058 if(ret == -1)
1059 return (-1);
1060 }
1061 }
1062
1063 return True;
1064 }
1065
1066 static int
parse_fontname(XOC oc)1067 parse_fontname(
1068 XOC oc)
1069 {
1070 XOCGenericPart *gen = XOC_GENERIC(oc);
1071 FontSet font_set;
1072 FontDataRec font_data_return;
1073 char *base_name, **name_list;
1074 int font_set_num = 0;
1075 int found_num = 0;
1076 int count = 0;
1077 int ret;
1078 int i;
1079
1080 name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
1081 if (name_list == NULL)
1082 return -1;
1083
1084 font_set = gen->font_set;
1085 font_set_num = gen->font_set_num;
1086
1087 /* Loop through all of the CharSets defined in the Locale
1088 * database for the current Locale.
1089 */
1090 for( ; font_set_num-- > 0 ; font_set++) {
1091 if(font_set->font_name)
1092 continue;
1093
1094 if(font_set->font_data_count > 0) {
1095
1096 /*
1097 * If there are a non-zero number of FontSets defined
1098 * for this CharSet.
1099 * Try to find a font for this CharSet. If we find an
1100 * acceptable font, we save the information for return
1101 * to the client. If we do not find an acceptable font,
1102 * a "missing_charset" will be reported to the client
1103 * for this CharSet.
1104 */
1105 font_data_return.xlfd_name = NULL;
1106 font_data_return.side = XlcUnknown;
1107
1108 ret = parse_fontdata(oc, font_set, font_set->font_data,
1109 font_set->font_data_count,
1110 name_list, count, C_PRIMARY,
1111 &font_data_return);
1112 if(ret == -1) {
1113 goto err;
1114 } else if(ret == True) {
1115 /*
1116 * We can't just loop through fontset->font_data to
1117 * find the first (ie. best) match: parse_fontdata
1118 * will try a substitute font if no primary one could
1119 * be matched. It returns the required information in
1120 * font_data_return.
1121 */
1122 font_set->font_name = strdup(font_data_return.xlfd_name);
1123 if(font_set->font_name == (char *) NULL)
1124 goto err;
1125
1126 font_set->side = font_data_return.side;
1127
1128 Xfree (font_data_return.xlfd_name);
1129 font_data_return.xlfd_name = NULL;
1130
1131 if(parse_vw(oc, font_set, name_list, count) == -1)
1132 goto err;
1133 found_num++;
1134 }
1135
1136 } else if(font_set->substitute_num > 0) {
1137 /*
1138 * If there are no FontSets defined for this
1139 * CharSet. We can only find "substitute" fonts.
1140 */
1141 ret = parse_fontdata(oc, font_set, font_set->substitute,
1142 font_set->substitute_num,
1143 name_list, count, C_SUBSTITUTE, NULL);
1144 if(ret == -1) {
1145 goto err;
1146 } else if(ret == True) {
1147 for(i=0;i<font_set->substitute_num;i++){
1148 if(font_set->substitute[i].xlfd_name != NULL){
1149 break;
1150 }
1151 }
1152 font_set->font_name = strdup(font_set->substitute[i].xlfd_name);
1153 if(font_set->font_name == (char *) NULL)
1154 goto err;
1155
1156 font_set->side = font_set->substitute[i].side;
1157 if(parse_vw(oc, font_set, name_list, count) == -1)
1158 goto err;
1159
1160 found_num++;
1161 }
1162 }
1163 }
1164
1165 base_name = strdup(oc->core.base_name_list);
1166 if (base_name == NULL)
1167 goto err;
1168
1169 oc->core.base_name_list = base_name;
1170
1171 XFreeStringList(name_list);
1172
1173 return found_num;
1174
1175 err:
1176 XFreeStringList(name_list);
1177 /* Prevent this from being freed twice */
1178 oc->core.base_name_list = NULL;
1179
1180 return -1;
1181 }
1182
1183 /* For VW/UDC end*/
1184
1185 static Bool
set_missing_list(XOC oc)1186 set_missing_list(
1187 XOC oc)
1188 {
1189 XOCGenericPart *gen = XOC_GENERIC(oc);
1190 FontSet font_set;
1191 char **charset_list, *charset_buf;
1192 int count, length, font_set_num;
1193 int result = 1;
1194
1195 font_set = gen->font_set;
1196 font_set_num = gen->font_set_num;
1197 count = length = 0;
1198
1199 for ( ; font_set_num-- > 0; font_set++) {
1200 if (font_set->info || font_set->font) {
1201 continue;
1202 }
1203
1204 /* Change 1996.01.23 start */
1205 if(font_set->font_data_count <= 0 ||
1206 font_set->font_data == (FontData)NULL) {
1207 if(font_set->substitute_num <= 0 ||
1208 font_set->substitute == (FontData)NULL) {
1209 if(font_set->charset_list != NULL){
1210 length +=
1211 strlen(font_set->charset_list[0]->encoding_name) + 1;
1212 } else {
1213 length += 1;
1214 }
1215 } else {
1216 length += strlen(font_set->substitute->name) + 1;
1217 }
1218 } else {
1219 length += strlen(font_set->font_data->name) + 1;
1220 }
1221 /* Change 1996.01.23 end */
1222 count++;
1223 }
1224
1225 if (count < 1) {
1226 return True;
1227 }
1228
1229 charset_list = Xmalloc(sizeof(char *) * count);
1230 if (charset_list == NULL) {
1231 return False;
1232 }
1233
1234 charset_buf = Xmalloc(length);
1235 if (charset_buf == NULL) {
1236 Xfree(charset_list);
1237 return False;
1238 }
1239
1240 oc->core.missing_list.charset_list = charset_list;
1241 oc->core.missing_list.charset_count = count;
1242
1243 font_set = gen->font_set;
1244 font_set_num = gen->font_set_num;
1245
1246 for ( ; font_set_num-- > 0; font_set++) {
1247 if (font_set->info || font_set->font) {
1248 continue;
1249 }
1250
1251 /* Change 1996.01.23 start */
1252 if(font_set->font_data_count <= 0 ||
1253 font_set->font_data == (FontData)NULL) {
1254 if(font_set->substitute_num <= 0 ||
1255 font_set->substitute == (FontData)NULL) {
1256 if(font_set->charset_list != NULL){
1257 strcpy(charset_buf,
1258 font_set->charset_list[0]->encoding_name);
1259 } else {
1260 strcpy(charset_buf, "");
1261 }
1262 result = 0;
1263 } else {
1264 strcpy(charset_buf, font_set->substitute->name);
1265 }
1266 } else {
1267 strcpy(charset_buf, font_set->font_data->name);
1268 }
1269 /* Change 1996.01.23 end */
1270 *charset_list++ = charset_buf;
1271 charset_buf += strlen(charset_buf) + 1;
1272 }
1273
1274 if(result == 0) {
1275 return(False);
1276 }
1277
1278 return True;
1279 }
1280
1281 static Bool
create_fontset(XOC oc)1282 create_fontset(
1283 XOC oc)
1284 {
1285 XOMGenericPart *gen = XOM_GENERIC(oc->core.om);
1286 int found_num;
1287
1288 if (init_fontset(oc) == False)
1289 return False;
1290
1291 found_num = parse_fontname(oc);
1292 if (found_num <= 0) {
1293 if (found_num == 0)
1294 set_missing_list(oc);
1295 return False;
1296 }
1297
1298 if (gen->on_demand_loading == True) {
1299 if (load_font_info(oc) == False)
1300 return False;
1301 } else {
1302 if (load_font(oc) == False)
1303 return False;
1304 }
1305
1306 if (init_core_part(oc) == False)
1307 return False;
1308
1309 if (set_missing_list(oc) == False)
1310 return False;
1311
1312 return True;
1313 }
1314
1315 /* For VW/UDC start */
1316 static void
free_fontdataOC(Display * dpy,FontData font_data,int font_data_count)1317 free_fontdataOC(
1318 Display *dpy,
1319 FontData font_data,
1320 int font_data_count)
1321 {
1322 for( ; font_data_count-- ; font_data++) {
1323 if(font_data->xlfd_name){
1324 Xfree(font_data->xlfd_name);
1325 font_data->xlfd_name = NULL;
1326 }
1327 if(font_data->font){ /* ADD 1996.01.7 */
1328 if(font_data->font->fid) /* Add 1996.01.23 */
1329 XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */
1330 else /* Add 1996.01.23 */
1331 XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */
1332 font_data->font = NULL;
1333 }
1334 /*
1335 * font_data->name and font_data->scopes belong to the OM not OC.
1336 * To save space this data is shared between OM and OC. We are
1337 * not allowed to free it here.
1338 * It has been moved to free_fontdataOM()
1339 */
1340 /*
1341 if(font_data->scopes){
1342 Xfree(font_data->scopes);
1343 font_data->scopes = NULL;
1344 }
1345 if(font_data->name){
1346 Xfree(font_data->name);
1347 font_data->name = NULL;
1348 }
1349 */
1350 }
1351 }
1352
destroy_fontdata(XOCGenericPart * gen,Display * dpy)1353 static void destroy_fontdata(
1354 XOCGenericPart *gen,
1355 Display *dpy)
1356 {
1357 FontSet font_set = (FontSet) NULL;
1358 int font_set_num = 0;
1359
1360 if (gen->font_set) {
1361 font_set = gen->font_set;
1362 font_set_num = gen->font_set_num;
1363 for( ; font_set_num-- ; font_set++) {
1364 if (font_set->font) {
1365 if(font_set->font->fid)
1366 XFreeFont(dpy,font_set->font);
1367 else
1368 XFreeFontInfo(NULL, font_set->font, 1);
1369 font_set->font = NULL;
1370 }
1371 if(font_set->font_data) {
1372 if (font_set->info)
1373 XFreeFontInfo(NULL, font_set->info, 1);
1374 free_fontdataOC(dpy,
1375 font_set->font_data, font_set->font_data_count);
1376 Xfree(font_set->font_data);
1377 font_set->font_data = NULL;
1378 }
1379 if(font_set->substitute) {
1380 free_fontdataOC(dpy,
1381 font_set->substitute, font_set->substitute_num);
1382 Xfree(font_set->substitute);
1383 font_set->substitute = NULL;
1384 }
1385 if(font_set->vmap) {
1386 free_fontdataOC(dpy,
1387 font_set->vmap, font_set->vmap_num);
1388 Xfree(font_set->vmap);
1389 font_set->vmap = NULL;
1390 }
1391 if(font_set->vrotate) {
1392 free_fontdataOC(dpy,
1393 (FontData)font_set->vrotate,
1394 font_set->vrotate_num);
1395 Xfree(font_set->vrotate);
1396 font_set->vrotate = NULL;
1397 }
1398 }
1399 Xfree(gen->font_set);
1400 gen->font_set = NULL;
1401 }
1402 }
1403 /* For VW/UDC end */
1404
1405 static void
destroy_oc(XOC oc)1406 destroy_oc(
1407 XOC oc)
1408 {
1409 Display *dpy = oc->core.om->core.display;
1410 XOCGenericPart *gen = XOC_GENERIC(oc);
1411
1412 if (gen->mbs_to_cs)
1413 _XlcCloseConverter(gen->mbs_to_cs);
1414
1415 if (gen->wcs_to_cs)
1416 _XlcCloseConverter(gen->wcs_to_cs);
1417
1418 if (gen->utf8_to_cs)
1419 _XlcCloseConverter(gen->utf8_to_cs);
1420
1421 /* For VW/UDC start */ /* Change 1996.01.8 */
1422 destroy_fontdata(gen,dpy);
1423 /*
1424 */
1425 /* For VW/UDC end */
1426
1427 Xfree(oc->core.base_name_list);
1428 XFreeStringList(oc->core.font_info.font_name_list);
1429 Xfree(oc->core.font_info.font_struct_list);
1430 XFreeStringList(oc->core.missing_list.charset_list);
1431
1432 #ifdef notdef
1433
1434 Xfree(oc->core.res_name);
1435 Xfree(oc->core.res_class);
1436 #endif
1437
1438 Xfree(oc);
1439 }
1440
1441 static char *
set_oc_values(XOC oc,XlcArgList args,int num_args)1442 set_oc_values(
1443 XOC oc,
1444 XlcArgList args,
1445 int num_args)
1446 {
1447 XOCGenericPart *gen = XOC_GENERIC(oc);
1448 FontSet font_set = gen->font_set;
1449 char *ret;
1450 int num = gen->font_set_num;
1451
1452 if (oc->core.resources == NULL)
1453 return NULL;
1454
1455 ret = _XlcSetValues((XPointer) oc, oc->core.resources,
1456 oc->core.num_resources, args, num_args, XlcSetMask);
1457 if(ret != NULL){
1458 return(ret);
1459 } else {
1460 for ( ; num-- > 0; font_set++) {
1461 if (font_set->font_name == NULL)
1462 continue;
1463 if (font_set->vpart_initialize != 0)
1464 continue;
1465 if( oc->core.orientation == XOMOrientation_TTB_RTL ||
1466 oc->core.orientation == XOMOrientation_TTB_LTR ){
1467 load_fontdata(oc, font_set->vmap, font_set->vmap_num);
1468 load_fontdata(oc, (FontData) font_set->vrotate,
1469 font_set->vrotate_num);
1470 font_set->vpart_initialize = 1;
1471 }
1472 }
1473 return(NULL);
1474 }
1475 }
1476
1477 static char *
get_oc_values(XOC oc,XlcArgList args,int num_args)1478 get_oc_values(
1479 XOC oc,
1480 XlcArgList args,
1481 int num_args)
1482 {
1483 if (oc->core.resources == NULL)
1484 return NULL;
1485
1486 return _XlcGetValues((XPointer) oc, oc->core.resources,
1487 oc->core.num_resources, args, num_args, XlcGetMask);
1488 }
1489
1490 static XOCMethodsRec oc_default_methods = {
1491 destroy_oc,
1492 set_oc_values,
1493 get_oc_values,
1494 _XmbDefaultTextEscapement,
1495 _XmbDefaultTextExtents,
1496 _XmbDefaultTextPerCharExtents,
1497 _XmbDefaultDrawString,
1498 _XmbDefaultDrawImageString,
1499 _XwcDefaultTextEscapement,
1500 _XwcDefaultTextExtents,
1501 _XwcDefaultTextPerCharExtents,
1502 _XwcDefaultDrawString,
1503 _XwcDefaultDrawImageString,
1504 _Xutf8DefaultTextEscapement,
1505 _Xutf8DefaultTextExtents,
1506 _Xutf8DefaultTextPerCharExtents,
1507 _Xutf8DefaultDrawString,
1508 _Xutf8DefaultDrawImageString
1509 };
1510
1511 static XOCMethodsRec oc_generic_methods = {
1512 destroy_oc,
1513 set_oc_values,
1514 get_oc_values,
1515 _XmbGenericTextEscapement,
1516 _XmbGenericTextExtents,
1517 _XmbGenericTextPerCharExtents,
1518 _XmbGenericDrawString,
1519 _XmbGenericDrawImageString,
1520 _XwcGenericTextEscapement,
1521 _XwcGenericTextExtents,
1522 _XwcGenericTextPerCharExtents,
1523 _XwcGenericDrawString,
1524 _XwcGenericDrawImageString,
1525 _Xutf8GenericTextEscapement,
1526 _Xutf8GenericTextExtents,
1527 _Xutf8GenericTextPerCharExtents,
1528 _Xutf8GenericDrawString,
1529 _Xutf8GenericDrawImageString
1530 };
1531
1532 typedef struct _XOCMethodsListRec {
1533 const char *name;
1534 XOCMethods methods;
1535 } XOCMethodsListRec, *XOCMethodsList;
1536
1537 static XOCMethodsListRec oc_methods_list[] = {
1538 { "default", &oc_default_methods },
1539 { "generic", &oc_generic_methods }
1540 };
1541
1542 static XlcResource oc_resources[] = {
1543 { XNBaseFontName, NULLQUARK, sizeof(char *),
1544 XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
1545 { XNOMAutomatic, NULLQUARK, sizeof(Bool),
1546 XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
1547 { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
1548 XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
1549 { XNDefaultString, NULLQUARK, sizeof(char *),
1550 XOffsetOf(XOCRec, core.default_string), XlcGetMask },
1551 { XNOrientation, NULLQUARK, sizeof(XOrientation),
1552 XOffsetOf(XOCRec, core.orientation), XlcDefaultMask | XlcSetMask | XlcGetMask },
1553 { XNResourceName, NULLQUARK, sizeof(char *),
1554 XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
1555 { XNResourceClass, NULLQUARK, sizeof(char *),
1556 XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
1557 { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
1558 XOffsetOf(XOCRec, core.font_info), XlcGetMask }
1559 };
1560
1561 static XOC
create_oc(XOM om,XlcArgList args,int num_args)1562 create_oc(
1563 XOM om,
1564 XlcArgList args,
1565 int num_args)
1566 {
1567 XOC oc;
1568 XOMGenericPart *gen = XOM_GENERIC(om);
1569 XOCMethodsList methods_list = oc_methods_list;
1570 int count;
1571
1572 oc = Xcalloc(1, sizeof(XOCGenericRec));
1573 if (oc == NULL)
1574 return (XOC) NULL;
1575
1576 oc->core.om = om;
1577
1578 if (oc_resources[0].xrm_name == NULLQUARK)
1579 _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
1580
1581 if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
1582 args, num_args, XlcCreateMask | XlcDefaultMask))
1583 goto err;
1584
1585 if (oc->core.base_name_list == NULL)
1586 goto err;
1587
1588 oc->core.resources = oc_resources;
1589 oc->core.num_resources = XlcNumber(oc_resources);
1590
1591 if (create_fontset(oc) == False)
1592 goto err;
1593
1594 oc->methods = &oc_generic_methods;
1595
1596 if (gen->object_name) {
1597 count = XlcNumber(oc_methods_list);
1598
1599 for ( ; count-- > 0; methods_list++) {
1600 if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) {
1601 oc->methods = methods_list->methods;
1602 break;
1603 }
1604 }
1605 }
1606
1607 return oc;
1608
1609 err:
1610 destroy_oc(oc);
1611
1612 return (XOC) NULL;
1613 }
1614
1615 static void
free_fontdataOM(FontData font_data,int font_data_count)1616 free_fontdataOM(
1617 FontData font_data,
1618 int font_data_count)
1619 {
1620 if (!font_data)
1621 return;
1622
1623 for( ; font_data_count-- ; font_data++) {
1624 Xfree(font_data->name);
1625 font_data->name = NULL;
1626 Xfree(font_data->scopes);
1627 font_data->scopes = NULL;
1628 }
1629 }
1630
1631 static Status
close_om(XOM om)1632 close_om(
1633 XOM om)
1634 {
1635 XOMGenericPart *gen = XOM_GENERIC(om);
1636 OMData data;
1637 int count;
1638
1639 if ((data = gen->data)) {
1640 for (count = gen->data_num; count-- > 0; data++) {
1641 Xfree(data->charset_list);
1642 data->charset_list = NULL;
1643
1644 /* free font_data for om */
1645 free_fontdataOM(data->font_data,data->font_data_count);
1646 Xfree(data->font_data);
1647 data->font_data = NULL;
1648
1649 /* free substitute for om */
1650 free_fontdataOM(data->substitute,data->substitute_num);
1651 Xfree(data->substitute);
1652 data->substitute = NULL;
1653
1654 /* free vmap for om */
1655 free_fontdataOM(data->vmap,data->vmap_num);
1656 Xfree(data->vmap);
1657 data->vmap = NULL;
1658
1659 /* free vrotate for om */
1660 Xfree(data->vrotate);
1661 data->vrotate = NULL;
1662 }
1663 Xfree(gen->data);
1664 gen->data = NULL;
1665 }
1666
1667 Xfree(gen->object_name);
1668 gen->object_name = NULL;
1669
1670 Xfree(om->core.res_name);
1671 om->core.res_name = NULL;
1672
1673 Xfree(om->core.res_class);
1674 om->core.res_class = NULL;
1675
1676 if (om->core.required_charset.charset_list &&
1677 om->core.required_charset.charset_count > 0){
1678 XFreeStringList(om->core.required_charset.charset_list);
1679 om->core.required_charset.charset_list = NULL;
1680 } else {
1681 Xfree((char*)om->core.required_charset.charset_list);
1682 om->core.required_charset.charset_list = NULL;
1683 }
1684
1685 Xfree(om->core.orientation_list.orientation);
1686 om->core.orientation_list.orientation = NULL;
1687
1688 Xfree(om);
1689
1690 return 1;
1691 }
1692
1693 static char *
set_om_values(XOM om,XlcArgList args,int num_args)1694 set_om_values(
1695 XOM om,
1696 XlcArgList args,
1697 int num_args)
1698 {
1699 if (om->core.resources == NULL)
1700 return NULL;
1701
1702 return _XlcSetValues((XPointer) om, om->core.resources,
1703 om->core.num_resources, args, num_args, XlcSetMask);
1704 }
1705
1706 static char *
get_om_values(XOM om,XlcArgList args,int num_args)1707 get_om_values(
1708 XOM om,
1709 XlcArgList args,
1710 int num_args)
1711 {
1712 if (om->core.resources == NULL)
1713 return NULL;
1714
1715 return _XlcGetValues((XPointer) om, om->core.resources,
1716 om->core.num_resources, args, num_args, XlcGetMask);
1717 }
1718
1719 static XOMMethodsRec methods = {
1720 close_om,
1721 set_om_values,
1722 get_om_values,
1723 create_oc
1724 };
1725
1726 static XlcResource om_resources[] = {
1727 { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
1728 XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
1729 { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
1730 XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
1731 { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
1732 XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
1733 { XNContextualDrawing, NULLQUARK, sizeof(Bool),
1734 XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
1735 };
1736
1737 static XOM
create_om(XLCd lcd,Display * dpy,XrmDatabase rdb,_Xconst char * res_name,_Xconst char * res_class)1738 create_om(
1739 XLCd lcd,
1740 Display *dpy,
1741 XrmDatabase rdb,
1742 _Xconst char *res_name,
1743 _Xconst char *res_class)
1744 {
1745 XOM om;
1746
1747 om = Xcalloc(1, sizeof(XOMGenericRec));
1748 if (om == NULL)
1749 return (XOM) NULL;
1750
1751 om->methods = &methods;
1752 om->core.lcd = lcd;
1753 om->core.display = dpy;
1754 om->core.rdb = rdb;
1755 if (res_name) {
1756 om->core.res_name = strdup(res_name);
1757 if (om->core.res_name == NULL)
1758 goto err;
1759 }
1760 if (res_class) {
1761 om->core.res_class = strdup(res_class);
1762 if (om->core.res_class == NULL)
1763 goto err;
1764 }
1765
1766 if (om_resources[0].xrm_name == NULLQUARK)
1767 _XlcCompileResourceList(om_resources, XlcNumber(om_resources));
1768
1769 om->core.resources = om_resources;
1770 om->core.num_resources = XlcNumber(om_resources);
1771
1772 return om;
1773
1774 err:
1775 close_om(om);
1776
1777 return (XOM) NULL;
1778 }
1779
1780 static OMData
add_data(XOM om)1781 add_data(
1782 XOM om)
1783 {
1784 XOMGenericPart *gen = XOM_GENERIC(om);
1785 OMData new;
1786 int num;
1787
1788 if ((num = gen->data_num))
1789 new = Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec));
1790 else
1791 new = Xmalloc(sizeof(OMDataRec));
1792
1793 if (new == NULL)
1794 return NULL;
1795
1796 gen->data_num = num + 1;
1797 gen->data = new;
1798
1799 new += num;
1800 bzero((char *) new, sizeof(OMDataRec));
1801
1802 return new;
1803 }
1804
1805 /* For VW/UDC */
1806
1807 FontData
read_EncodingInfo(int count,char ** value)1808 read_EncodingInfo(
1809 int count,
1810 char **value)
1811 {
1812 FontData font_data,ret;
1813 char *buf, *bufptr,*scp;
1814 int len, i;
1815 font_data = Xcalloc(count, sizeof(FontDataRec));
1816 if (font_data == NULL)
1817 return NULL;
1818
1819 ret = font_data;
1820 for (i = 0; i < count; i++, font_data++) {
1821 /*
1822 strcpy(buf, *value++);
1823 */
1824 buf = *value; value++;
1825 if ((bufptr = strchr(buf, ':'))) {
1826 len = (int)(bufptr - buf);
1827 bufptr++ ;
1828 } else
1829 len = strlen(buf);
1830 font_data->name = Xmalloc(len + 1);
1831 if (font_data->name == NULL) {
1832 free_fontdataOM(ret, i + 1);
1833 Xfree(ret);
1834 return NULL;
1835 }
1836 strncpy(font_data->name, buf,len);
1837 font_data->name[len] = 0;
1838 if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0)
1839 font_data->side = XlcGL;
1840 else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0)
1841 font_data->side = XlcGR;
1842 else
1843 font_data->side = XlcGLGR;
1844
1845 if (bufptr && (scp = strchr(bufptr, '['))){
1846 font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num));
1847 }
1848 }
1849 return(ret);
1850 }
1851
read_vrotate(int count,char ** value,int * type,int * vrotate_num)1852 static CodeRange read_vrotate(
1853 int count,
1854 char **value,
1855 int *type,
1856 int *vrotate_num)
1857 {
1858 CodeRange range;
1859 if(!strcmp(value[0],"all")){
1860 *type = VROTATE_ALL ;
1861 *vrotate_num = 0 ;
1862 return (NULL);
1863 } else if(*(value[0]) == '['){
1864 *type = VROTATE_PART ;
1865 range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num);
1866 return (range);
1867 } else {
1868 *type = VROTATE_NONE ;
1869 *vrotate_num = 0 ;
1870 return (NULL);
1871 }
1872 }
1873
read_vw(XLCd lcd,OMData font_set,int num)1874 static void read_vw(
1875 XLCd lcd,
1876 OMData font_set,
1877 int num)
1878 {
1879 char **value, buf[BUFSIZ];
1880 int count;
1881
1882 snprintf(buf, sizeof(buf), "fs%d.font.vertical_map", num);
1883 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1884 if (count > 0){
1885 _XlcDbg_printValue(buf,value,count);
1886 font_set->vmap_num = count;
1887 font_set->vmap = read_EncodingInfo(count,value);
1888 }
1889
1890 snprintf(buf, sizeof(buf), "fs%d.font.vertical_rotate", num);
1891 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1892 if (count > 0){
1893 _XlcDbg_printValue(buf,value,count);
1894 font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type),
1895 &(font_set->vrotate_num));
1896 }
1897 }
1898 /* VW/UDC end */
1899 static Bool
init_om(XOM om)1900 init_om(
1901 XOM om)
1902 {
1903 XLCd lcd = om->core.lcd;
1904 XOMGenericPart *gen = XOM_GENERIC(om);
1905 OMData data;
1906 XlcCharSet *charset_list;
1907 FontData font_data;
1908 char **required_list;
1909 XOrientation *orientation;
1910 char **value, buf[BUFSIZ], *bufptr;
1911 int count = 0, num = 0;
1912 unsigned int length = 0;
1913
1914 _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count);
1915 if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0)
1916 gen->on_demand_loading = True;
1917
1918 _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count);
1919 if (count > 0) {
1920 gen->object_name = strdup(*value);
1921 if (gen->object_name == NULL)
1922 return False;
1923 }
1924
1925 for (num = 0; ; num++) {
1926
1927 snprintf(buf, sizeof(buf), "fs%d.charset.name", num);
1928 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1929
1930 if( count < 1){
1931 snprintf(buf, sizeof(buf), "fs%d.charset", num);
1932 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1933 if (count < 1)
1934 break;
1935 }
1936
1937 data = add_data(om);
1938 if (data == NULL)
1939 return False;
1940
1941 charset_list = Xmalloc(sizeof(XlcCharSet) * count);
1942 if (charset_list == NULL)
1943 return False;
1944 data->charset_list = charset_list;
1945 data->charset_count = count;
1946
1947 while (count-- > 0){
1948 *charset_list++ = _XlcGetCharSet(*value++);
1949 }
1950 snprintf(buf, sizeof(buf), "fs%d.charset.udc_area", num);
1951 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1952 if( count > 0){
1953 UDCArea udc;
1954 int i,flag = 0;
1955 udc = Xmalloc(count * sizeof(UDCAreaRec));
1956 if (udc == NULL)
1957 return False;
1958 for(i=0;i<count;i++){
1959 sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start),
1960 &(udc[i].end));
1961 }
1962 for(i=0;i<data->charset_count;i++){
1963 if(data->charset_list[i]->udc_area == NULL){
1964 data->charset_list[i]->udc_area = udc;
1965 data->charset_list[i]->udc_area_num = count;
1966 flag = 1;
1967 }
1968 }
1969 if(flag == 0){
1970 Xfree(udc);
1971 }
1972 }
1973
1974 snprintf(buf, sizeof(buf), "fs%d.font.primary", num);
1975 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1976 if (count < 1){
1977 snprintf(buf, sizeof(buf), "fs%d.font", num);
1978 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1979 if (count < 1)
1980 return False;
1981 }
1982
1983 font_data = read_EncodingInfo(count,value);
1984 if (font_data == NULL)
1985 return False;
1986
1987 data->font_data = font_data;
1988 data->font_data_count = count;
1989
1990 snprintf(buf, sizeof(buf), "fs%d.font.substitute", num);
1991 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
1992 if (count > 0){
1993 font_data = read_EncodingInfo(count,value);
1994 if (font_data == NULL)
1995 return False;
1996 data->substitute = font_data;
1997 data->substitute_num = count;
1998 } else {
1999 snprintf(buf, sizeof(buf), "fs%d.font", num);
2000 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
2001 if (count < 1) {
2002 data->substitute = NULL;
2003 data->substitute_num = 0;
2004 } else {
2005 font_data = read_EncodingInfo(count,value);
2006 data->substitute = font_data;
2007 data->substitute_num = count;
2008 }
2009 }
2010 read_vw(lcd,data,num);
2011 length += strlen(data->font_data->name) + 1;
2012 }
2013
2014 /* required charset list */
2015 required_list = Xmalloc(sizeof(char *) * gen->data_num);
2016 if (required_list == NULL)
2017 return False;
2018
2019 om->core.required_charset.charset_list = required_list;
2020 om->core.required_charset.charset_count = gen->data_num;
2021
2022 count = gen->data_num;
2023 data = gen->data;
2024
2025 if (count > 0) {
2026 bufptr = Xmalloc(length);
2027 if (bufptr == NULL) {
2028 Xfree(required_list);
2029 return False;
2030 }
2031
2032 for ( ; count-- > 0; data++) {
2033 strcpy(bufptr, data->font_data->name);
2034 *required_list++ = bufptr;
2035 bufptr += strlen(bufptr) + 1;
2036 }
2037 }
2038
2039 /* orientation list */
2040 orientation = Xmalloc(sizeof(XOrientation) * 2);
2041 if (orientation == NULL)
2042 return False;
2043
2044 orientation[0] = XOMOrientation_LTR_TTB;
2045 orientation[1] = XOMOrientation_TTB_RTL;
2046 om->core.orientation_list.orientation = orientation;
2047 om->core.orientation_list.num_orientation = 2;
2048
2049 /* directional dependent drawing */
2050 om->core.directional_dependent = False;
2051
2052 /* contextual drawing */
2053 om->core.contextual_drawing = False;
2054
2055 /* context dependent */
2056 om->core.context_dependent = False;
2057
2058 return True;
2059 }
2060
2061 XOM
_XomGenericOpenOM(XLCd lcd,Display * dpy,XrmDatabase rdb,_Xconst char * res_name,_Xconst char * res_class)2062 _XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
2063 _Xconst char *res_name, _Xconst char *res_class)
2064 {
2065 XOM om;
2066
2067 om = create_om(lcd, dpy, rdb, res_name, res_class);
2068 if (om == NULL)
2069 return (XOM) NULL;
2070
2071 if (init_om(om) == False)
2072 goto err;
2073
2074 return om;
2075
2076 err:
2077 close_om(om);
2078
2079 return (XOM) NULL;
2080 }
2081
2082 Bool
_XInitOM(XLCd lcd)2083 _XInitOM(
2084 XLCd lcd)
2085 {
2086 lcd->methods->open_om = _XomGenericOpenOM;
2087
2088 return True;
2089 }
2090