XDefaultOMIF.c revision 0f8248bf
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 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 640 Xfree(gen->font_set); 641 Xfree(oc->core.base_name_list); 642 XFreeStringList(oc->core.font_info.font_name_list); 643 644 if ((font_list = oc->core.font_info.font_struct_list)) { 645 if ((font = *font_list)) { 646 if (font->fid) 647 XFreeFont(dpy, font); 648 else 649 XFreeFontInfo(NULL, font, 1); 650 } 651 Xfree(oc->core.font_info.font_struct_list); 652 } 653 654 655 XFreeStringList(oc->core.missing_list.charset_list); 656 657#ifdef notdef 658 Xfree(oc->core.res_name); 659 Xfree(oc->core.res_class); 660#endif 661 662 Xfree(oc); 663} 664 665static char * 666set_oc_values( 667 XOC oc, 668 XlcArgList args, 669 int num_args) 670{ 671 if (oc->core.resources == NULL) 672 return NULL; 673 674 return _XlcSetValues((XPointer) oc, oc->core.resources, 675 oc->core.num_resources, args, num_args, XlcSetMask); 676} 677 678static char * 679get_oc_values( 680 XOC oc, 681 XlcArgList args, 682 int num_args) 683{ 684 if (oc->core.resources == NULL) 685 return NULL; 686 687 return _XlcGetValues((XPointer) oc, oc->core.resources, 688 oc->core.num_resources, args, num_args, XlcGetMask); 689} 690 691static Bool 692wcs_to_mbs( 693 XOC oc, 694 char *to, 695 _Xconst wchar_t *from, 696 int length) 697{ 698 XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs; 699 XLCd lcd; 700 int ret, to_left = length; 701 702 if (conv == NULL) { 703 lcd = oc->core.om->core.lcd; 704 conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); 705 if (conv == NULL) 706 return False; 707 XOC_GENERIC(oc)->wcs_to_cs = conv; 708 } else 709 _XlcResetConverter(conv); 710 711 ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, 712 &to_left, NULL, 0); 713 if (ret != 0 || length > 0) 714 return False; 715 716 return True; 717} 718 719static int 720_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) 721{ 722 return XTextWidth(*oc->core.font_info.font_struct_list, text, length); 723} 724 725static int 726_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) 727{ 728 DefineLocalBuf; 729 char *buf = AllocLocalBuf(length); 730 int ret = 0; 731 732 if (buf == NULL) 733 return 0; 734 735 if (wcs_to_mbs(oc, buf, text, length) == False) 736 goto err; 737 738 ret = _XmbDefaultTextEscapement(oc, buf, length); 739 740err: 741 FreeLocalBuf(buf); 742 743 return ret; 744} 745 746static int 747_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, 748 XRectangle *overall_ink, XRectangle *overall_logical) 749{ 750 int direction, logical_ascent, logical_descent; 751 XCharStruct overall; 752 753 XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, 754 &logical_ascent, &logical_descent, &overall); 755 756 if (overall_ink) { 757 overall_ink->x = overall.lbearing; 758 overall_ink->y = -(overall.ascent); 759 overall_ink->width = overall.rbearing - overall.lbearing; 760 overall_ink->height = overall.ascent + overall.descent; 761 } 762 763 if (overall_logical) { 764 overall_logical->x = 0; 765 overall_logical->y = -(logical_ascent); 766 overall_logical->width = overall.width; 767 overall_logical->height = logical_ascent + logical_descent; 768 } 769 770 return overall.width; 771} 772 773static int 774_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, 775 XRectangle *overall_ink, XRectangle *overall_logical) 776{ 777 DefineLocalBuf; 778 char *buf = AllocLocalBuf(length); 779 int ret = 0; 780 781 if (buf == NULL) 782 return 0; 783 784 if (wcs_to_mbs(oc, buf, text, length) == False) 785 goto err; 786 787 ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); 788 789err: 790 FreeLocalBuf(buf); 791 792 return ret; 793} 794 795static Status 796_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, 797 XRectangle *ink_buf, XRectangle *logical_buf, 798 int buf_size, int *num_chars, 799 XRectangle *overall_ink, 800 XRectangle *overall_logical) 801{ 802 XFontStruct *font = *oc->core.font_info.font_struct_list; 803 XCharStruct *def, *cs, overall; 804 Bool first = True; 805 806 if (buf_size < length) 807 return 0; 808 809 bzero((char *) &overall, sizeof(XCharStruct)); 810 *num_chars = 0; 811 812 CI_GET_DEFAULT_INFO_1D(font, def) 813 814 while (length-- > 0) { 815 CI_GET_CHAR_INFO_1D(font, *text, def, cs) 816 text++; 817 if (cs == NULL) 818 continue; 819 820 ink_buf->x = overall.width + cs->lbearing; 821 ink_buf->y = -(cs->ascent); 822 ink_buf->width = cs->rbearing - cs->lbearing; 823 ink_buf->height = cs->ascent + cs->descent; 824 ink_buf++; 825 826 logical_buf->x = overall.width; 827 logical_buf->y = -(font->ascent); 828 logical_buf->width = cs->width; 829 logical_buf->height = font->ascent + font->descent; 830 logical_buf++; 831 832 if (first) { 833 overall = *cs; 834 first = False; 835 } else { 836 overall.ascent = max(overall.ascent, cs->ascent); 837 overall.descent = max(overall.descent, cs->descent); 838 overall.lbearing = min(overall.lbearing, overall.width + 839 cs->lbearing); 840 overall.rbearing = max(overall.rbearing, overall.width + 841 cs->rbearing); 842 overall.width += cs->width; 843 } 844 (*num_chars)++; 845 } 846 847 if (overall_ink) { 848 overall_ink->x = overall.lbearing; 849 overall_ink->y = -(overall.ascent); 850 overall_ink->width = overall.rbearing - overall.lbearing; 851 overall_ink->height = overall.ascent + overall.descent; 852 } 853 854 if (overall_logical) { 855 overall_logical->x = 0; 856 overall_logical->y = -(font->ascent); 857 overall_logical->width = overall.width; 858 overall_logical->height = font->ascent + font->descent; 859 } 860 861 return 1; 862} 863 864static Status 865_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, 866 XRectangle *ink_buf, XRectangle *logical_buf, 867 int buf_size, int *num_chars, 868 XRectangle *overall_ink, 869 XRectangle *overall_logical) 870{ 871 DefineLocalBuf; 872 char *buf = AllocLocalBuf(length); 873 Status ret = 0; 874 875 if (buf == NULL) 876 return 0; 877 878 if (wcs_to_mbs(oc, buf, text, length) == False) 879 goto err; 880 881 ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, 882 buf_size, num_chars, overall_ink, 883 overall_logical); 884 885err: 886 FreeLocalBuf(buf); 887 888 return ret; 889} 890 891static int 892_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 893 _Xconst char *text, int length) 894{ 895 XFontStruct *font = *oc->core.font_info.font_struct_list; 896 897 XSetFont(dpy, gc, font->fid); 898 XDrawString(dpy, d, gc, x, y, text, length); 899 900 return XTextWidth(font, text, length); 901} 902 903static int 904_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 905 _Xconst wchar_t *text, int length) 906{ 907 DefineLocalBuf; 908 char *buf = AllocLocalBuf(length); 909 int ret = 0; 910 911 if (buf == NULL) 912 return 0; 913 914 if (wcs_to_mbs(oc, buf, text, length) == False) 915 goto err; 916 917 ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); 918 919err: 920 FreeLocalBuf(buf); 921 922 return ret; 923} 924 925static void 926_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 927 int y, _Xconst char *text, int length) 928{ 929 XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); 930 XDrawImageString(dpy, d, gc, x, y, text, length); 931} 932 933static void 934_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 935 int y, _Xconst wchar_t *text, int length) 936{ 937 DefineLocalBuf; 938 char *buf = AllocLocalBuf(length); 939 940 if (buf == NULL) 941 return; 942 943 if (wcs_to_mbs(oc, buf, text, length) == False) 944 goto err; 945 946 _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); 947 948err: 949 FreeLocalBuf(buf); 950} 951 952static _Xconst XOCMethodsRec oc_default_methods = { 953 destroy_oc, 954 set_oc_values, 955 get_oc_values, 956 _XmbDefaultTextEscapement, 957 _XmbDefaultTextExtents, 958 _XmbDefaultTextPerCharExtents, 959 _XmbDefaultDrawString, 960 _XmbDefaultDrawImageString, 961 _XwcDefaultTextEscapement, 962 _XwcDefaultTextExtents, 963 _XwcDefaultTextPerCharExtents, 964 _XwcDefaultDrawString, 965 _XwcDefaultDrawImageString 966}; 967 968static XlcResource oc_resources[] = { 969 { XNBaseFontName, NULLQUARK, sizeof(char *), 970 XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, 971 { XNOMAutomatic, NULLQUARK, sizeof(Bool), 972 XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, 973 { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), 974 XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, 975 { XNDefaultString, NULLQUARK, sizeof(char *), 976 XOffsetOf(XOCRec, core.default_string), XlcGetMask }, 977 { XNOrientation, NULLQUARK, sizeof(XOrientation), 978 XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask }, 979 { XNResourceName, NULLQUARK, sizeof(char *), 980 XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, 981 { XNResourceClass, NULLQUARK, sizeof(char *), 982 XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, 983 { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), 984 XOffsetOf(XOCRec, core.font_info), XlcGetMask } 985}; 986 987static XOC 988create_oc( 989 XOM om, 990 XlcArgList args, 991 int num_args) 992{ 993 XOC oc; 994 995 oc = Xcalloc(1, sizeof(XOCGenericRec)); 996 if (oc == NULL) 997 return (XOC) NULL; 998 999 oc->core.om = om; 1000 1001 if (oc_resources[0].xrm_name == NULLQUARK) 1002 _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); 1003 1004 if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), 1005 args, num_args, XlcCreateMask | XlcDefaultMask)) 1006 goto err; 1007 1008 if (oc->core.base_name_list == NULL) 1009 goto err; 1010 1011 oc->core.resources = oc_resources; 1012 oc->core.num_resources = XlcNumber(oc_resources); 1013 1014 if (create_fontset(oc) == False) 1015 goto err; 1016 1017 oc->methods = (XOCMethods)&oc_default_methods; 1018 1019 return oc; 1020 1021err: 1022 destroy_oc(oc); 1023 1024 return (XOC) NULL; 1025} 1026 1027static Status 1028close_om( 1029 XOM om) 1030{ 1031 XOMGenericPart *gen = XOM_GENERIC(om); 1032 OMData data; 1033 FontData font_data; 1034 int count; 1035 1036 if ((data = gen->data)) { 1037 if (data->font_data) { 1038 for (font_data = data->font_data, count = data->font_data_count; 1039 count-- > 0 ; font_data++) { 1040 Xfree(font_data->name); 1041 } 1042 Xfree(data->font_data); 1043 } 1044 Xfree(gen->data); 1045 } 1046 1047 1048 Xfree(om->core.res_name); 1049 Xfree(om->core.res_class); 1050 1051 if (om->core.required_charset.charset_list) 1052 XFreeStringList(om->core.required_charset.charset_list); 1053 else 1054 Xfree((char*)om->core.required_charset.charset_list); 1055 1056 Xfree(om->core.orientation_list.orientation); 1057 Xfree(om); 1058 1059 return 1; 1060} 1061 1062static char * 1063set_om_values( 1064 XOM om, 1065 XlcArgList args, 1066 int num_args) 1067{ 1068 if (om->core.resources == NULL) 1069 return NULL; 1070 1071 return _XlcSetValues((XPointer) om, om->core.resources, 1072 om->core.num_resources, args, num_args, XlcSetMask); 1073} 1074 1075static char * 1076get_om_values( 1077 XOM om, 1078 XlcArgList args, 1079 int num_args) 1080{ 1081 if (om->core.resources == NULL) 1082 return NULL; 1083 1084 return _XlcGetValues((XPointer) om, om->core.resources, 1085 om->core.num_resources, args, num_args, XlcGetMask); 1086} 1087 1088static _Xconst XOMMethodsRec methods = { 1089 close_om, 1090 set_om_values, 1091 get_om_values, 1092 create_oc 1093}; 1094 1095static XlcResource om_resources[] = { 1096 { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), 1097 XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, 1098 { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), 1099 XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, 1100 { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), 1101 XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, 1102 { XNContextualDrawing, NULLQUARK, sizeof(Bool), 1103 XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } 1104}; 1105 1106static OMData 1107add_data( 1108 XOM om) 1109{ 1110 XOMGenericPart *gen = XOM_GENERIC(om); 1111 OMData new; 1112 1113 new = Xcalloc(1, sizeof(OMDataRec)); 1114 1115 if (new == NULL) 1116 return NULL; 1117 1118 gen->data = new; 1119 1120 return new; 1121} 1122 1123static _Xconst char *supported_charset_list[] = { 1124 "ISO8859-1", 1125/* fix for bug4332979 */ 1126 "adobe-fontspecific", 1127/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from 1128 supported_charset_list because it is not a supported_charset for C locale 1129 "JISX0201.1976-0", */ 1130 "SUNOLCURSOR-1", 1131 "SUNOLGLYPH-1" 1132}; 1133 1134static Bool 1135init_om( 1136 XOM om) 1137{ 1138 XOMGenericPart *gen = XOM_GENERIC(om); 1139 OMData data; 1140 FontData font_data; 1141 char **required_list; 1142 XOrientation *orientation; 1143 char *bufptr; 1144 int i, count, length = 0; 1145 1146 count = XlcNumber(supported_charset_list); 1147 1148 data = add_data(om); 1149 if (data == NULL) 1150 return False; 1151 1152 font_data = Xcalloc(count, sizeof(FontDataRec)); 1153 if (font_data == NULL) 1154 return False; 1155 data->font_data = font_data; 1156 data->font_data_count = count; 1157 1158 for (i = 0; i < count; i++, font_data++) { 1159 font_data->name = strdup(supported_charset_list[i]); 1160 if (font_data->name == NULL) 1161 return False; 1162 } 1163 1164 length += strlen(data->font_data->name) + 1; 1165 1166 /* required charset list */ 1167 required_list = Xmalloc(sizeof(char *)); 1168 if (required_list == NULL) 1169 return False; 1170 1171 bufptr = Xmalloc(length); 1172 if (bufptr == NULL) { 1173 Xfree(required_list); 1174 return False; 1175 } 1176 1177 om->core.required_charset.charset_list = required_list; 1178 om->core.required_charset.charset_count = 1; /* always 1 */ 1179 1180 data = gen->data; 1181 1182 strcpy(bufptr, data->font_data->name); 1183 *required_list++ = bufptr; 1184 bufptr += strlen(bufptr) + 1; 1185 1186 /* orientation list */ 1187 orientation = Xmalloc(sizeof(XOrientation)); 1188 if (orientation == NULL) 1189 return False; 1190 1191 *orientation = XOMOrientation_LTR_TTB; 1192 om->core.orientation_list.orientation = orientation; 1193 om->core.orientation_list.num_orientation = 1; 1194 1195 /* directional dependent drawing */ 1196 om->core.directional_dependent = False; 1197 1198 /* contexual drawing */ 1199 om->core.contextual_drawing = False; 1200 1201 /* context dependent */ 1202 om->core.context_dependent = False; 1203 1204 return True; 1205} 1206 1207XOM 1208_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, 1209 _Xconst char *res_name, _Xconst char *res_class) 1210{ 1211 XOM om; 1212 1213 om = Xcalloc(1, sizeof(XOMGenericRec)); 1214 if (om == NULL) 1215 return (XOM) NULL; 1216 1217 om->methods = (XOMMethods)&methods; 1218 om->core.lcd = lcd; 1219 om->core.display = dpy; 1220 om->core.rdb = rdb; 1221 if (res_name) { 1222 om->core.res_name = strdup(res_name); 1223 if (om->core.res_name == NULL) 1224 goto err; 1225 } 1226 if (res_class) { 1227 om->core.res_class = strdup(res_class); 1228 if (om->core.res_class == NULL) 1229 goto err; 1230 } 1231 1232 if (om_resources[0].xrm_name == NULLQUARK) 1233 _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); 1234 1235 om->core.resources = om_resources; 1236 om->core.num_resources = XlcNumber(om_resources); 1237 1238 if (init_om(om) == False) 1239 goto err; 1240 1241 return om; 1242err: 1243 close_om(om); 1244 1245 return (XOM) NULL; 1246} 1247