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