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