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