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