1 /*
2 Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the
6 "Software"), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions: The above copyright notice and this
11 permission notice shall be included in all copies or substantial
12 portions of the Software.
13
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
21 EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
22
23
24 Except as contained in this notice, the name of The Open Group shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from The Open Group.
27
28
29 X Window System is a trademark of The Open Group
30
31 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
32 logo, LBX, X Window System, and Xinerama are trademarks of the Open
33 Group. All other trademarks and registered trademarks mentioned herein
34 are the property of their respective owners. No right, title or
35 interest in or to any trademark, service mark, logo or trade name of
36 Sun Microsystems, Inc. or its licensors is granted.
37
38 */
39 /*
40 * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
41 *
42 * Permission is hereby granted, free of charge, to any person obtaining a
43 * copy of this software and associated documentation files (the "Software"),
44 * to deal in the Software without restriction, including without limitation
45 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
46 * and/or sell copies of the Software, and to permit persons to whom the
47 * Software is furnished to do so, subject to the following conditions:
48 *
49 * The above copyright notice and this permission notice (including the next
50 * paragraph) shall be included in all copies or substantial portions of the
51 * Software.
52 *
53 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
56 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
58 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
59 * DEALINGS IN THE SOFTWARE.
60 */
61
62
63 #ifdef HAVE_CONFIG_H
64 #include <config.h>
65 #endif
66 #include "Xlibint.h"
67 #include "Xlcint.h"
68 #include "XlcPublic.h"
69 #include <X11/Xos.h>
70 #include <X11/Xatom.h>
71 #include <stdio.h>
72
73 #define MAXFONTS 100
74
75 #define XOM_GENERIC(om) (&((XOMGeneric) om)->gen)
76 #define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen)
77
78 #define DefineLocalBuf char local_buf[BUFSIZ]
79 #define AllocLocalBuf(length) (length > BUFSIZ ? Xmalloc(length) : local_buf)
80 #define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr)
81
82 typedef struct _FontDataRec {
83 char *name;
84 } FontDataRec, *FontData;
85
86 typedef struct _OMDataRec {
87 int font_data_count;
88 FontData font_data;
89 } OMDataRec, *OMData;
90
91 typedef struct _XOMGenericPart {
92 OMData data;
93 } XOMGenericPart;
94
95 typedef struct _XOMGenericRec {
96 XOMMethods methods;
97 XOMCoreRec core;
98 XOMGenericPart gen;
99 } XOMGenericRec, *XOMGeneric;
100
101 typedef struct _FontSetRec {
102 int id;
103 int font_data_count;
104 FontData font_data;
105 char *font_name;
106 XFontStruct *info;
107 XFontStruct *font;
108 } FontSetRec, *FontSet;
109
110 typedef struct _XOCGenericPart {
111 XlcConv wcs_to_cs;
112 FontSet font_set;
113 } XOCGenericPart;
114
115 typedef struct _XOCGenericRec {
116 XOCMethods methods;
117 XOCCoreRec core;
118 XOCGenericPart gen;
119 } XOCGenericRec, *XOCGeneric;
120
121 static Bool
init_fontset(XOC oc)122 init_fontset(
123 XOC oc)
124 {
125 XOCGenericPart *gen;
126 FontSet font_set;
127 OMData data;
128
129 data = XOM_GENERIC(oc->core.om)->data;
130
131 font_set = Xcalloc(1, sizeof(FontSetRec));
132 if (font_set == NULL)
133 return False;
134
135 gen = XOC_GENERIC(oc);
136 gen->font_set = font_set;
137
138 font_set->font_data_count = data->font_data_count;
139 font_set->font_data = data->font_data;
140
141 return True;
142 }
143
144 static char *
get_prop_name(Display * dpy,XFontStruct * fs)145 get_prop_name(
146 Display *dpy,
147 XFontStruct *fs)
148 {
149 unsigned long fp;
150
151 if (XGetFontProperty(fs, XA_FONT, &fp))
152 return XGetAtomName(dpy, fp);
153
154 return (char *) NULL;
155 }
156
157 static FontData
check_charset(FontSet font_set,char * font_name)158 check_charset(
159 FontSet font_set,
160 char *font_name)
161 {
162 FontData font_data;
163 char *last;
164 int count;
165 ssize_t length, name_len;
166
167 name_len = (ssize_t) strlen(font_name);
168 last = font_name + name_len;
169
170 count = font_set->font_data_count;
171 font_data = font_set->font_data;
172
173 for ( ; count-- > 0; font_data++) {
174 length = (ssize_t) strlen(font_data->name);
175
176 if (length > name_len)
177 return(NULL);
178
179 if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
180 return font_data;
181 }
182 return (FontData) NULL;
183 }
184
185 static Bool
load_font(XOC oc)186 load_font(
187 XOC oc)
188 {
189 Display *dpy = oc->core.om->core.display;
190 XOCGenericPart *gen = XOC_GENERIC(oc);
191 FontSet font_set = gen->font_set;
192
193 if (font_set->font_name == NULL)
194 return False;
195
196 if (font_set->font == NULL) {
197 font_set->font = XLoadQueryFont(dpy, font_set->font_name);
198 if (font_set->font == NULL)
199 return False;
200 }
201 return True;
202 }
203
204 static void
set_fontset_extents(XOC oc)205 set_fontset_extents(
206 XOC oc)
207 {
208 XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
209 XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
210 XFontStruct **font_list, *font;
211 XCharStruct overall;
212 int logical_ascent, logical_descent;
213
214 font_list = oc->core.font_info.font_struct_list;
215 font = *font_list++;
216 overall = font->max_bounds;
217 overall.lbearing = font->min_bounds.lbearing;
218 logical_ascent = font->ascent;
219 logical_descent = font->descent;
220
221 ink->x = overall.lbearing;
222 ink->y = -(overall.ascent);
223 ink->width = overall.rbearing - overall.lbearing;
224 ink->height = overall.ascent + overall.descent;
225
226 logical->x = 0;
227 logical->y = -(logical_ascent);
228 logical->width = overall.width;
229 logical->height = logical_ascent + logical_descent;
230 }
231
232 static Bool
init_core_part(XOC oc)233 init_core_part(
234 XOC oc)
235 {
236 XOCGenericPart *gen = XOC_GENERIC(oc);
237 FontSet font_set;
238 XFontStruct **font_struct_list;
239 char **font_name_list, *font_name_buf;
240
241 font_set = gen->font_set;
242
243 if (font_set->font_name == NULL)
244 return False;
245
246 font_struct_list = Xmalloc(sizeof(XFontStruct *));
247 if (font_struct_list == NULL)
248 return False;
249
250 font_name_list = Xmalloc(sizeof(char *));
251 if (font_name_list == NULL)
252 goto err;
253
254 font_name_buf = strdup(font_set->font_name);
255 if (font_name_buf == NULL)
256 goto err;
257
258 oc->core.font_info.num_font = 1;
259 oc->core.font_info.font_name_list = font_name_list;
260 oc->core.font_info.font_struct_list = font_struct_list;
261
262 font_set->id = 1;
263 if (font_set->font)
264 *font_struct_list = font_set->font;
265 else
266 *font_struct_list = font_set->info;
267 Xfree(font_set->font_name);
268 *font_name_list = font_set->font_name = font_name_buf;
269
270 set_fontset_extents(oc);
271
272 return True;
273
274 err:
275
276 Xfree(font_name_list);
277 Xfree(font_struct_list);
278
279 return False;
280 }
281
282 static char *
get_font_name(XOC oc,char * pattern)283 get_font_name(
284 XOC oc,
285 char *pattern)
286 {
287 char **list, *name;
288 int count;
289 XFontStruct *fs;
290 Display *dpy = oc->core.om->core.display;
291
292 list = XListFonts(dpy, pattern, 1, &count);
293 if (list != NULL) {
294 name = strdup(*list);
295
296 XFreeFontNames(list);
297 } else {
298 fs = XLoadQueryFont(dpy, pattern);
299 if (fs == NULL) return NULL;
300
301 name = get_prop_name(dpy, fs);
302 XFreeFont(dpy, fs);
303 }
304 return name;
305 }
306
307 static int
parse_fontname(XOC oc)308 parse_fontname(
309 XOC oc)
310 {
311 XOCGenericPart *gen = XOC_GENERIC(oc);
312 FontSet font_set;
313 FontData font_data;
314 char *pattern, *last, buf[BUFSIZ];
315 int font_data_count, found_num = 0;
316 ssize_t length;
317 int count, num_fields;
318 char *base_name, *font_name, **name_list, **cur_name_list;
319 char *charset_p = NULL;
320 Bool append_charset;
321 /*
322 append_charset flag should be set to True when the XLFD fontname
323 doesn't contain a chaset part.
324 */
325
326 name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
327 if (name_list == NULL)
328 return -1;
329 cur_name_list = name_list;
330
331 while (count-- > 0) {
332 pattern = *cur_name_list++;
333 if (pattern == NULL || *pattern == '\0')
334 continue;
335
336 append_charset = False;
337
338 if (strchr(pattern, '*') == NULL &&
339 (font_name = get_font_name(oc, pattern))) {
340
341 font_set = gen->font_set;
342
343 font_data = check_charset(font_set, font_name);
344 if (font_data == NULL) {
345 Display *dpy = oc->core.om->core.display;
346 char **fn_list = NULL, *prop_fname = NULL;
347 int list_num;
348 XFontStruct *fs_list;
349 if ((fn_list = XListFontsWithInfo(dpy, font_name,
350 MAXFONTS,
351 &list_num, &fs_list))
352 && (prop_fname = get_prop_name(dpy, fs_list))
353 && (font_data = check_charset(font_set, prop_fname))) {
354 if (fn_list) {
355 XFreeFontInfo(fn_list, fs_list, list_num);
356 fn_list = NULL;
357 }
358 font_name = prop_fname;
359 }
360 }
361 if (font_data == NULL)
362 continue;
363
364 font_set->font_name = strdup(font_name);
365 Xfree(font_name);
366 if (font_set->font_name == NULL) {
367 goto err;
368 }
369 found_num++;
370 goto found;
371 }
372
373 strncpy(buf, pattern, BUFSIZ);
374 buf[BUFSIZ-1] = '\0';
375 length = (ssize_t) strlen(buf);
376 last = buf + length - 1;
377
378 for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
379 if (*base_name == '-') num_fields++;
380 if (strchr(pattern, '*') == NULL) {
381 if (num_fields == 12) {
382 append_charset = True;
383 *++last = '-';
384 last++;
385 } else
386 continue;
387 } else {
388 if (num_fields == 13 || num_fields == 14) {
389 /*
390 * There are 14 fields in an XLFD name -- make certain the
391 * charset (& encoding) is placed in the correct field.
392 */
393 append_charset = True;
394 last = strrchr (buf, '-');
395 if (num_fields == 14) {
396 *last = '\0';
397 last = strrchr (buf, '-');
398 }
399 last++;
400 } else if (*last == '*') {
401 append_charset = True;
402 if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
403 && *(last-1) == '-') {
404 last -= 2;
405 }
406 *++last = '-';
407 last++;
408 } else {
409 last = strrchr (buf, '-');
410 charset_p = last;
411 charset_p = strrchr (buf, '-');
412 while (*(--charset_p) != '-');
413 charset_p++;
414 }
415 }
416
417 font_set = gen->font_set;
418
419 font_data = font_set->font_data;
420 font_data_count = font_set->font_data_count;
421 for ( ; font_data_count-- > 0; font_data++) {
422 if (append_charset)
423 {
424 strncpy(last, font_data->name, (size_t) (BUFSIZ - length));
425 buf[BUFSIZ-1] = '\0';
426 }
427 else {
428 if (_XlcCompareISOLatin1(charset_p,
429 font_data->name)) {
430 continue;
431 }
432 }
433 if ((font_set->font_name = get_font_name(oc, buf)))
434 break;
435 }
436 if (font_set->font_name != NULL) {
437 found_num++;
438 goto found;
439 }
440 }
441 found:
442 base_name = strdup(oc->core.base_name_list);
443 if (base_name == NULL)
444 goto err;
445
446 oc->core.base_name_list = base_name;
447
448 XFreeStringList(name_list);
449
450 return found_num;
451 err:
452 XFreeStringList(name_list);
453
454 return -1;
455 }
456
457 static Bool
set_missing_list(XOC oc)458 set_missing_list(
459 XOC oc)
460 {
461 XOCGenericPart *gen = XOC_GENERIC(oc);
462 FontSet font_set;
463 char **charset_list, *charset_buf;
464
465 font_set = gen->font_set;
466
467 if (font_set->info == NULL || font_set->font == NULL)
468 return True;
469
470 charset_list = Xmalloc(sizeof(char *));
471 if (charset_list == NULL)
472 return False;
473
474 charset_buf = strdup(font_set->font_data->name);
475 if (charset_buf == NULL) {
476 Xfree(charset_list);
477 return False;
478 }
479
480 oc->core.missing_list.charset_list = charset_list;
481
482 *charset_list = charset_buf;
483
484 return True;
485 }
486
487 static Bool
create_fontset(XOC oc)488 create_fontset(
489 XOC oc)
490 {
491 int found_num;
492
493 if (init_fontset(oc) == False)
494 return False;
495
496 found_num = parse_fontname(oc);
497 if (found_num <= 0) {
498 if (found_num == 0)
499 set_missing_list(oc);
500 return False;
501 }
502
503 if (load_font(oc) == False)
504 return False;
505
506 if (init_core_part(oc) == False)
507 return False;
508
509 if (set_missing_list(oc) == False)
510 return False;
511
512 return True;
513 }
514
515 static void
destroy_oc(XOC oc)516 destroy_oc(
517 XOC oc)
518 {
519 Display *dpy = oc->core.om->core.display;
520 XOCGenericPart *gen = XOC_GENERIC(oc);
521 XFontStruct **font_list, *font;
522
523
524 Xfree(gen->font_set);
525 Xfree(oc->core.base_name_list);
526 XFreeStringList(oc->core.font_info.font_name_list);
527
528 if ((font_list = oc->core.font_info.font_struct_list)) {
529 if ((font = *font_list)) {
530 if (font->fid)
531 XFreeFont(dpy, font);
532 else
533 XFreeFontInfo(NULL, font, 1);
534 }
535 Xfree(oc->core.font_info.font_struct_list);
536 }
537
538
539 XFreeStringList(oc->core.missing_list.charset_list);
540
541 #ifdef notdef
542 Xfree(oc->core.res_name);
543 Xfree(oc->core.res_class);
544 #endif
545
546 Xfree(oc);
547 }
548
549 static char *
set_oc_values(XOC oc,XlcArgList args,int num_args)550 set_oc_values(
551 XOC oc,
552 XlcArgList args,
553 int num_args)
554 {
555 if (oc->core.resources == NULL)
556 return NULL;
557
558 return _XlcSetValues((XPointer) oc, oc->core.resources,
559 oc->core.num_resources, args, num_args, XlcSetMask);
560 }
561
562 static char *
get_oc_values(XOC oc,XlcArgList args,int num_args)563 get_oc_values(
564 XOC oc,
565 XlcArgList args,
566 int num_args)
567 {
568 if (oc->core.resources == NULL)
569 return NULL;
570
571 return _XlcGetValues((XPointer) oc, oc->core.resources,
572 oc->core.num_resources, args, num_args, XlcGetMask);
573 }
574
575 static Bool
wcs_to_mbs(XOC oc,char * to,_Xconst wchar_t * from,int length)576 wcs_to_mbs(
577 XOC oc,
578 char *to,
579 _Xconst wchar_t *from,
580 int length)
581 {
582 XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
583 XLCd lcd;
584 int ret, to_left = length;
585
586 if (conv == NULL) {
587 lcd = oc->core.om->core.lcd;
588 conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
589 if (conv == NULL)
590 return False;
591 XOC_GENERIC(oc)->wcs_to_cs = conv;
592 } else
593 _XlcResetConverter(conv);
594
595 ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
596 &to_left, NULL, 0);
597 if (ret != 0 || length > 0)
598 return False;
599
600 return True;
601 }
602
603 static int
_XmbDefaultTextEscapement(XOC oc,_Xconst char * text,int length)604 _XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
605 {
606 return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
607 }
608
609 static int
_XwcDefaultTextEscapement(XOC oc,_Xconst wchar_t * text,int length)610 _XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
611 {
612 DefineLocalBuf;
613 char *buf = AllocLocalBuf(length);
614 int ret = 0;
615
616 if (buf == NULL)
617 return 0;
618
619 if (wcs_to_mbs(oc, buf, text, length) == False)
620 goto err;
621
622 ret = _XmbDefaultTextEscapement(oc, buf, length);
623
624 err:
625 FreeLocalBuf(buf);
626
627 return ret;
628 }
629
630 static int
_XmbDefaultTextExtents(XOC oc,_Xconst char * text,int length,XRectangle * overall_ink,XRectangle * overall_logical)631 _XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
632 XRectangle *overall_ink, XRectangle *overall_logical)
633 {
634 int direction, logical_ascent, logical_descent;
635 XCharStruct overall;
636
637 XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
638 &logical_ascent, &logical_descent, &overall);
639
640 if (overall_ink) {
641 overall_ink->x = overall.lbearing;
642 overall_ink->y = -(overall.ascent);
643 overall_ink->width = overall.rbearing - overall.lbearing;
644 overall_ink->height = overall.ascent + overall.descent;
645 }
646
647 if (overall_logical) {
648 overall_logical->x = 0;
649 overall_logical->y = -(logical_ascent);
650 overall_logical->width = overall.width;
651 overall_logical->height = logical_ascent + logical_descent;
652 }
653
654 return overall.width;
655 }
656
657 static int
_XwcDefaultTextExtents(XOC oc,_Xconst wchar_t * text,int length,XRectangle * overall_ink,XRectangle * overall_logical)658 _XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
659 XRectangle *overall_ink, XRectangle *overall_logical)
660 {
661 DefineLocalBuf;
662 char *buf = AllocLocalBuf(length);
663 int ret = 0;
664
665 if (buf == NULL)
666 return 0;
667
668 if (wcs_to_mbs(oc, buf, text, length) == False)
669 goto err;
670
671 ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
672
673 err:
674 FreeLocalBuf(buf);
675
676 return ret;
677 }
678
679 static Status
_XmbDefaultTextPerCharExtents(XOC oc,_Xconst char * text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)680 _XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
681 XRectangle *ink_buf, XRectangle *logical_buf,
682 int buf_size, int *num_chars,
683 XRectangle *overall_ink,
684 XRectangle *overall_logical)
685 {
686 XFontStruct *font = *oc->core.font_info.font_struct_list;
687 XCharStruct *def, *cs, overall;
688 Bool first = True;
689
690 if (buf_size < length)
691 return 0;
692
693 bzero((char *) &overall, sizeof(XCharStruct));
694 *num_chars = 0;
695
696 CI_GET_DEFAULT_INFO_1D(font, def)
697
698 while (length-- > 0) {
699 CI_GET_CHAR_INFO_1D(font, *text, def, cs)
700 text++;
701 if (cs == NULL)
702 continue;
703
704 ink_buf->x = overall.width + cs->lbearing;
705 ink_buf->y = -(cs->ascent);
706 ink_buf->width = cs->rbearing - cs->lbearing;
707 ink_buf->height = cs->ascent + cs->descent;
708 ink_buf++;
709
710 logical_buf->x = overall.width;
711 logical_buf->y = -(font->ascent);
712 logical_buf->width = cs->width;
713 logical_buf->height = font->ascent + font->descent;
714 logical_buf++;
715
716 if (first) {
717 overall = *cs;
718 first = False;
719 } else {
720 overall.ascent = max(overall.ascent, cs->ascent);
721 overall.descent = max(overall.descent, cs->descent);
722 overall.lbearing = min(overall.lbearing, overall.width +
723 cs->lbearing);
724 overall.rbearing = max(overall.rbearing, overall.width +
725 cs->rbearing);
726 overall.width += cs->width;
727 }
728 (*num_chars)++;
729 }
730
731 if (overall_ink) {
732 overall_ink->x = overall.lbearing;
733 overall_ink->y = -(overall.ascent);
734 overall_ink->width = overall.rbearing - overall.lbearing;
735 overall_ink->height = overall.ascent + overall.descent;
736 }
737
738 if (overall_logical) {
739 overall_logical->x = 0;
740 overall_logical->y = -(font->ascent);
741 overall_logical->width = overall.width;
742 overall_logical->height = font->ascent + font->descent;
743 }
744
745 return 1;
746 }
747
748 static Status
_XwcDefaultTextPerCharExtents(XOC oc,_Xconst wchar_t * text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)749 _XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
750 XRectangle *ink_buf, XRectangle *logical_buf,
751 int buf_size, int *num_chars,
752 XRectangle *overall_ink,
753 XRectangle *overall_logical)
754 {
755 DefineLocalBuf;
756 char *buf = AllocLocalBuf(length);
757 Status ret = 0;
758
759 if (buf == NULL)
760 return 0;
761
762 if (wcs_to_mbs(oc, buf, text, length) == False)
763 goto err;
764
765 ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
766 buf_size, num_chars, overall_ink,
767 overall_logical);
768
769 err:
770 FreeLocalBuf(buf);
771
772 return ret;
773 }
774
775 static int
_XmbDefaultDrawString(Display * dpy,Drawable d,XOC oc,GC gc,int x,int y,_Xconst char * text,int length)776 _XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
777 _Xconst char *text, int length)
778 {
779 XFontStruct *font = *oc->core.font_info.font_struct_list;
780
781 XSetFont(dpy, gc, font->fid);
782 XDrawString(dpy, d, gc, x, y, text, length);
783
784 return XTextWidth(font, text, length);
785 }
786
787 static int
_XwcDefaultDrawString(Display * dpy,Drawable d,XOC oc,GC gc,int x,int y,_Xconst wchar_t * text,int length)788 _XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
789 _Xconst wchar_t *text, int length)
790 {
791 DefineLocalBuf;
792 char *buf = AllocLocalBuf(length);
793 int ret = 0;
794
795 if (buf == NULL)
796 return 0;
797
798 if (wcs_to_mbs(oc, buf, text, length) == False)
799 goto err;
800
801 ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
802
803 err:
804 FreeLocalBuf(buf);
805
806 return ret;
807 }
808
809 static void
_XmbDefaultDrawImageString(Display * dpy,Drawable d,XOC oc,GC gc,int x,int y,_Xconst char * text,int length)810 _XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
811 int y, _Xconst char *text, int length)
812 {
813 XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
814 XDrawImageString(dpy, d, gc, x, y, text, length);
815 }
816
817 static void
_XwcDefaultDrawImageString(Display * dpy,Drawable d,XOC oc,GC gc,int x,int y,_Xconst wchar_t * text,int length)818 _XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
819 int y, _Xconst wchar_t *text, int length)
820 {
821 DefineLocalBuf;
822 char *buf = AllocLocalBuf(length);
823
824 if (buf == NULL)
825 return;
826
827 if (wcs_to_mbs(oc, buf, text, length) == False)
828 goto err;
829
830 _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
831
832 err:
833 FreeLocalBuf(buf);
834 }
835
836 static _Xconst XOCMethodsRec oc_default_methods = {
837 destroy_oc,
838 set_oc_values,
839 get_oc_values,
840 _XmbDefaultTextEscapement,
841 _XmbDefaultTextExtents,
842 _XmbDefaultTextPerCharExtents,
843 _XmbDefaultDrawString,
844 _XmbDefaultDrawImageString,
845 _XwcDefaultTextEscapement,
846 _XwcDefaultTextExtents,
847 _XwcDefaultTextPerCharExtents,
848 _XwcDefaultDrawString,
849 _XwcDefaultDrawImageString
850 };
851
852 static XlcResource oc_resources[] = {
853 { XNBaseFontName, NULLQUARK, sizeof(char *),
854 XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
855 { XNOMAutomatic, NULLQUARK, sizeof(Bool),
856 XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
857 { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
858 XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
859 { XNDefaultString, NULLQUARK, sizeof(char *),
860 XOffsetOf(XOCRec, core.default_string), XlcGetMask },
861 { XNOrientation, NULLQUARK, sizeof(XOrientation),
862 XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
863 { XNResourceName, NULLQUARK, sizeof(char *),
864 XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
865 { XNResourceClass, NULLQUARK, sizeof(char *),
866 XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
867 { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
868 XOffsetOf(XOCRec, core.font_info), XlcGetMask }
869 };
870
871 static XOC
create_oc(XOM om,XlcArgList args,int num_args)872 create_oc(
873 XOM om,
874 XlcArgList args,
875 int num_args)
876 {
877 XOC oc;
878
879 oc = Xcalloc(1, sizeof(XOCGenericRec));
880 if (oc == NULL)
881 return (XOC) NULL;
882
883 oc->core.om = om;
884
885 if (oc_resources[0].xrm_name == NULLQUARK)
886 _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
887
888 if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
889 args, num_args, XlcCreateMask | XlcDefaultMask))
890 goto err;
891
892 if (oc->core.base_name_list == NULL)
893 goto err;
894
895 oc->core.resources = oc_resources;
896 oc->core.num_resources = XlcNumber(oc_resources);
897
898 if (create_fontset(oc) == False)
899 goto err;
900
901 oc->methods = (XOCMethods)&oc_default_methods;
902
903 return oc;
904
905 err:
906 destroy_oc(oc);
907
908 return (XOC) NULL;
909 }
910
911 static Status
close_om(XOM om)912 close_om(
913 XOM om)
914 {
915 XOMGenericPart *gen = XOM_GENERIC(om);
916 OMData data;
917 FontData font_data;
918 int count;
919
920 if ((data = gen->data)) {
921 if (data->font_data) {
922 for (font_data = data->font_data, count = data->font_data_count;
923 count-- > 0 ; font_data++) {
924 Xfree(font_data->name);
925 }
926 Xfree(data->font_data);
927 }
928 Xfree(gen->data);
929 }
930
931
932 Xfree(om->core.res_name);
933 Xfree(om->core.res_class);
934
935 if (om->core.required_charset.charset_list)
936 XFreeStringList(om->core.required_charset.charset_list);
937 else
938 Xfree((char*)om->core.required_charset.charset_list);
939
940 Xfree(om->core.orientation_list.orientation);
941 Xfree(om);
942
943 return 1;
944 }
945
946 static char *
set_om_values(XOM om,XlcArgList args,int num_args)947 set_om_values(
948 XOM om,
949 XlcArgList args,
950 int num_args)
951 {
952 if (om->core.resources == NULL)
953 return NULL;
954
955 return _XlcSetValues((XPointer) om, om->core.resources,
956 om->core.num_resources, args, num_args, XlcSetMask);
957 }
958
959 static char *
get_om_values(XOM om,XlcArgList args,int num_args)960 get_om_values(
961 XOM om,
962 XlcArgList args,
963 int num_args)
964 {
965 if (om->core.resources == NULL)
966 return NULL;
967
968 return _XlcGetValues((XPointer) om, om->core.resources,
969 om->core.num_resources, args, num_args, XlcGetMask);
970 }
971
972 static _Xconst XOMMethodsRec methods = {
973 close_om,
974 set_om_values,
975 get_om_values,
976 create_oc
977 };
978
979 static XlcResource om_resources[] = {
980 { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
981 XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
982 { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
983 XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
984 { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
985 XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
986 { XNContextualDrawing, NULLQUARK, sizeof(Bool),
987 XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
988 };
989
990 static OMData
add_data(XOM om)991 add_data(
992 XOM om)
993 {
994 XOMGenericPart *gen = XOM_GENERIC(om);
995 OMData new;
996
997 new = Xcalloc(1, sizeof(OMDataRec));
998
999 if (new == NULL)
1000 return NULL;
1001
1002 gen->data = new;
1003
1004 return new;
1005 }
1006
1007 static _Xconst char *supported_charset_list[] = {
1008 "ISO8859-1",
1009 "adobe-fontspecific",
1010 "SUNOLCURSOR-1",
1011 "SUNOLGLYPH-1"
1012 };
1013
1014 static Bool
init_om(XOM om)1015 init_om(
1016 XOM om)
1017 {
1018 XOMGenericPart *gen = XOM_GENERIC(om);
1019 OMData data;
1020 FontData font_data;
1021 char **required_list;
1022 XOrientation *orientation;
1023 char *bufptr;
1024 int i, count;
1025
1026 count = XlcNumber(supported_charset_list);
1027
1028 data = add_data(om);
1029 if (data == NULL)
1030 return False;
1031
1032 font_data = Xcalloc(count, sizeof(FontDataRec));
1033 if (font_data == NULL)
1034 return False;
1035 data->font_data = font_data;
1036 data->font_data_count = count;
1037
1038 for (i = 0; i < count; i++, font_data++) {
1039 font_data->name = strdup(supported_charset_list[i]);
1040 if (font_data->name == NULL)
1041 return False;
1042 }
1043
1044 /* required charset list */
1045 required_list = Xmalloc(sizeof(char *));
1046 if (required_list == NULL)
1047 return False;
1048
1049 bufptr = strdup(data->font_data->name);
1050 if (bufptr == NULL) {
1051 Xfree(required_list);
1052 return False;
1053 }
1054
1055 om->core.required_charset.charset_list = required_list;
1056 om->core.required_charset.charset_count = 1; /* always 1 */
1057
1058 data = gen->data;
1059
1060 *required_list = bufptr;
1061
1062 /* orientation list */
1063 orientation = Xmalloc(sizeof(XOrientation));
1064 if (orientation == NULL)
1065 return False;
1066
1067 *orientation = XOMOrientation_LTR_TTB;
1068 om->core.orientation_list.orientation = orientation;
1069 om->core.orientation_list.num_orientation = 1;
1070
1071 /* directional dependent drawing */
1072 om->core.directional_dependent = False;
1073
1074 /* contextual drawing */
1075 om->core.contextual_drawing = False;
1076
1077 /* context dependent */
1078 om->core.context_dependent = False;
1079
1080 return True;
1081 }
1082
1083 XOM
_XDefaultOpenOM(XLCd lcd,Display * dpy,XrmDatabase rdb,_Xconst char * res_name,_Xconst char * res_class)1084 _XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
1085 _Xconst char *res_name, _Xconst char *res_class)
1086 {
1087 XOM om;
1088
1089 om = Xcalloc(1, sizeof(XOMGenericRec));
1090 if (om == NULL)
1091 return (XOM) NULL;
1092
1093 om->methods = (XOMMethods)&methods;
1094 om->core.lcd = lcd;
1095 om->core.display = dpy;
1096 om->core.rdb = rdb;
1097 if (res_name) {
1098 om->core.res_name = strdup(res_name);
1099 if (om->core.res_name == NULL)
1100 goto err;
1101 }
1102 if (res_class) {
1103 om->core.res_class = strdup(res_class);
1104 if (om->core.res_class == NULL)
1105 goto err;
1106 }
1107
1108 if (om_resources[0].xrm_name == NULLQUARK)
1109 _XlcCompileResourceList(om_resources, XlcNumber(om_resources));
1110
1111 om->core.resources = om_resources;
1112 om->core.num_resources = XlcNumber(om_resources);
1113
1114 if (init_om(om) == False)
1115 goto err;
1116
1117 return om;
1118 err:
1119 close_om(om);
1120
1121 return (XOM) NULL;
1122 }
1123