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