omGeneric.c revision 2d67cb4f
1/* #define FONTDEBUG */ 2/* 3 * Copyright 1992, 1993 by TOSHIBA Corp. 4 * 5 * Permission to use, copy, modify, and distribute this software and its 6 * documentation for any purpose and without fee is hereby granted, provided 7 * that the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of TOSHIBA not be used in advertising 10 * or publicity pertaining to distribution of the software without specific, 11 * written prior permission. TOSHIBA make no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 21 * SOFTWARE. 22 * 23 * Author: Katsuhisa Yano TOSHIBA Corp. 24 * mopi@osa.ilab.toshiba.co.jp 25 */ 26/* 27 * Copyright 1995 by FUJITSU LIMITED 28 * This is source code modified by FUJITSU LIMITED under the Joint 29 * Development Agreement for the CDE/Motif PST. 30 * 31 * Modifier: Takanori Tateno FUJITSU LIMITED 32 * 33 */ 34 35/* 36 * Fixed the algorithms in parse_fontname() and parse_fontdata() 37 * to improve the logic for determining which font should be 38 * returned for a given CharSet. We even added some comments 39 * so that you can figure out what in the heck we're doing. We 40 * realize this is a departure from the norm, but hey, we're 41 * rebels! :-) :-) 42 * 43 * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD 44 */ 45/* 46 * Cleaned up mess, removed some blabla 47 * Egbert Eich, SuSE Linux AG 48 */ 49 50#ifdef HAVE_CONFIG_H 51#include <config.h> 52#endif 53#include "Xlibint.h" 54#include "XomGeneric.h" 55#include "XlcGeneric.h" 56#include <X11/Xos.h> 57#include <X11/Xatom.h> 58#include <stdio.h> 59#include <string.h> 60#include <ctype.h> 61 62#define MAXFONTS 100 63#define PIXEL_SIZE_FIELD 7 64#define POINT_SIZE_FIELD 8 65#define CHARSET_ENCODING_FIELD 14 66#define XLFD_MAX_LEN 255 67 68/* For VW/UDC start */ 69 70static FontData 71init_fontdata( 72 FontData font_data, 73 int font_data_count) 74{ 75 FontData fd; 76 int i; 77 78 fd = Xcalloc(font_data_count, sizeof(FontDataRec)); 79 if(fd == (FontData) NULL) 80 return False; 81 82 for(i = 0 ; i < font_data_count ; i++) 83 fd[i] = font_data[i]; 84 85 return fd; 86} 87 88static VRotate 89init_vrotate( 90 FontData font_data, 91 int font_data_count, 92 int type, 93 CodeRange code_range, 94 int code_range_num) 95{ 96 VRotate vrotate; 97 int i; 98 99 if(type == VROTATE_NONE) 100 return (VRotate)NULL; 101 102 vrotate = Xcalloc(font_data_count, sizeof(VRotateRec)); 103 if(vrotate == (VRotate) NULL) 104 return False; 105 106 for(i = 0 ; i < font_data_count ; i++) { 107 vrotate[i].charset_name = font_data[i].name; 108 vrotate[i].side = font_data[i].side; 109 if(type == VROTATE_PART) { 110 vrotate[i].num_cr = code_range_num; 111 vrotate[i].code_range = code_range; 112 } 113 } 114 115 return vrotate; 116} 117 118static Bool 119init_fontset( 120 XOC oc) 121{ 122 XOCGenericPart *gen; 123 FontSet font_set; 124 OMData data; 125 int count; 126 127 count = XOM_GENERIC(oc->core.om)->data_num; 128 data = XOM_GENERIC(oc->core.om)->data; 129 130 font_set = Xcalloc(count, sizeof(FontSetRec)); 131 if (font_set == NULL) 132 return False; 133 134 gen = XOC_GENERIC(oc); 135 gen->font_set_num = count; 136 gen->font_set = font_set; 137 138 for ( ; count-- > 0; data++, font_set++) { 139 font_set->charset_count = data->charset_count; 140 font_set->charset_list = data->charset_list; 141 142 if((font_set->font_data = init_fontdata(data->font_data, 143 data->font_data_count)) == NULL) 144 goto err; 145 font_set->font_data_count = data->font_data_count; 146 if((font_set->substitute = init_fontdata(data->substitute, 147 data->substitute_num)) == NULL) 148 goto err; 149 font_set->substitute_num = data->substitute_num; 150 if((font_set->vmap = init_fontdata(data->vmap, 151 data->vmap_num)) == NULL) 152 goto err; 153 font_set->vmap_num = data->vmap_num; 154 155 if(data->vrotate_type != VROTATE_NONE) { 156 /* A vrotate member is specified primary font data */ 157 /* as initial value. */ 158 if((font_set->vrotate = init_vrotate(data->font_data, 159 data->font_data_count, 160 data->vrotate_type, 161 data->vrotate, 162 data->vrotate_num)) == NULL) 163 goto err; 164 font_set->vrotate_num = data->font_data_count; 165 } 166 } 167 return True; 168 169err: 170 171 Xfree(font_set->font_data); 172 Xfree(font_set->substitute); 173 Xfree(font_set->vmap); 174 Xfree(font_set->vrotate); 175 Xfree(font_set); 176 gen->font_set = (FontSet) NULL; 177 gen->font_set_num = 0; 178 return False; 179} 180 181/* For VW/UDC end */ 182 183static char * 184get_prop_name( 185 Display *dpy, 186 XFontStruct *fs) 187{ 188 unsigned long fp; 189 190 if (XGetFontProperty(fs, XA_FONT, &fp)) 191 return XGetAtomName(dpy, fp); 192 193 return (char *) NULL; 194} 195 196/* For VW/UDC start */ 197 198static Bool 199load_fontdata( 200 XOC oc, 201 FontData font_data, 202 int font_data_num) 203{ 204 Display *dpy = oc->core.om->core.display; 205 FontData fd = font_data; 206 207 if(font_data == NULL) return(True); 208 for( ; font_data_num-- ; fd++) { 209 if(fd->xlfd_name != (char *) NULL && fd->font == NULL) { 210 fd->font = XLoadQueryFont(dpy, fd->xlfd_name); 211 if (fd->font == NULL){ 212 return False; 213 } 214 } 215 } 216 return True; 217} 218 219static Bool 220load_fontset_data( 221 XOC oc, 222 FontSet font_set) 223{ 224 Display *dpy = oc->core.om->core.display; 225 226 if(font_set->font_name == (char *)NULL) return False ; 227 228 /* If font_set->font is not NULL, it contains the *best* 229 * match font for this FontSet. 230 * -- jjw/pma (HP) 231 */ 232 if(font_set->font == NULL) { 233 font_set->font = XLoadQueryFont(dpy, font_set->font_name); 234 if (font_set->font == NULL){ 235 return False; 236 } 237 } 238 return True; 239} 240 241static Bool 242load_font( 243 XOC oc) 244{ 245 XOCGenericPart *gen = XOC_GENERIC(oc); 246 FontSet font_set = gen->font_set; 247 int num = gen->font_set_num; 248 249 for ( ; num-- > 0; font_set++) { 250 if (font_set->font_name == NULL) 251 continue; 252 253 if (load_fontset_data (oc, font_set) != True) 254 return False; 255#ifndef TESTVERSION 256 if(load_fontdata(oc, font_set->font_data, 257 font_set->font_data_count) != True) 258 return False; 259 260 if(load_fontdata(oc, font_set->substitute, 261 font_set->substitute_num) != True) 262 return False; 263#endif 264 265/* Add 1996.05.20 */ 266 if( oc->core.orientation == XOMOrientation_TTB_RTL || 267 oc->core.orientation == XOMOrientation_TTB_LTR ){ 268 if (font_set->vpart_initialize == 0) { 269 load_fontdata(oc, font_set->vmap, font_set->vmap_num); 270 load_fontdata(oc, (FontData) font_set->vrotate, 271 font_set->vrotate_num); 272 font_set->vpart_initialize = 1; 273 } 274 } 275 276 if (font_set->font->min_byte1 || font_set->font->max_byte1) 277 font_set->is_xchar2b = True; 278 else 279 font_set->is_xchar2b = False; 280 } 281 282 return True; 283} 284 285/* For VW/UDC end */ 286 287static Bool 288load_font_info( 289 XOC oc) 290{ 291 Display *dpy = oc->core.om->core.display; 292 XOCGenericPart *gen = XOC_GENERIC(oc); 293 FontSet font_set = gen->font_set; 294 char **fn_list; 295 int fn_num, num = gen->font_set_num; 296 297 for ( ; num-- > 0; font_set++) { 298 if (font_set->font_name == NULL) 299 continue; 300 301 if (font_set->info == NULL) { 302 fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, 303 &font_set->info); 304 if (font_set->info == NULL) 305 return False; 306 307 XFreeFontNames(fn_list); 308 } 309 } 310 311 return True; 312} 313 314/* For Vertical Writing start */ 315 316static void 317check_fontset_extents( 318 XCharStruct *overall, 319 int *logical_ascent, 320 int *logical_descent, 321 XFontStruct *font) 322{ 323 overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing); 324 overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing); 325 overall->ascent = max(overall->ascent, font->max_bounds.ascent); 326 overall->descent = max(overall->descent, font->max_bounds.descent); 327 overall->width = max(overall->width, font->max_bounds.width); 328 *logical_ascent = max(*logical_ascent, font->ascent); 329 *logical_descent = max(*logical_descent, font->descent); 330} 331 332/* For Vertical Writing end */ 333 334static void 335set_fontset_extents( 336 XOC oc) 337{ 338 XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; 339 XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; 340 XFontStruct **font_list, *font; 341 XCharStruct overall; 342 int logical_ascent, logical_descent; 343 int num = oc->core.font_info.num_font; 344 345 font_list = oc->core.font_info.font_struct_list; 346 font = *font_list++; 347 overall = font->max_bounds; 348 overall.lbearing = font->min_bounds.lbearing; 349 logical_ascent = font->ascent; 350 logical_descent = font->descent; 351 352 /* For Vertical Writing start */ 353 354 while (--num > 0) { 355 font = *font_list++; 356 check_fontset_extents(&overall, &logical_ascent, &logical_descent, 357 font); 358 } 359 360 { 361 XOCGenericPart *gen = XOC_GENERIC(oc); 362 FontSet font_set = gen->font_set; 363 FontData font_data; 364 int font_set_num = gen->font_set_num; 365 int font_data_count; 366 367 for( ; font_set_num-- ; font_set++) { 368 if(font_set->vmap_num > 0) { 369 font_data = font_set->vmap; 370 font_data_count = font_set->vmap_num; 371 for( ; font_data_count-- ; font_data++) { 372 if(font_data->font != NULL) { 373 check_fontset_extents(&overall, &logical_ascent, 374 &logical_descent, 375 font_data->font); 376 } 377 } 378 } 379 380 if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) { 381 font_data = (FontData) font_set->vrotate; 382 font_data_count = font_set->vrotate_num; 383 for( ; font_data_count-- ; font_data++) { 384 if(font_data->font != NULL) { 385 check_fontset_extents(&overall, &logical_ascent, 386 &logical_descent, 387 font_data->font); 388 } 389 } 390 } 391 } 392 } 393 394 /* For Vertical Writing start */ 395 396 ink->x = overall.lbearing; 397 ink->y = -(overall.ascent); 398 ink->width = overall.rbearing - overall.lbearing; 399 ink->height = overall.ascent + overall.descent; 400 401 logical->x = 0; 402 logical->y = -(logical_ascent); 403 logical->width = overall.width; 404 logical->height = logical_ascent + logical_descent; 405} 406 407static Bool 408init_core_part( 409 XOC oc) 410{ 411 XOCGenericPart *gen = XOC_GENERIC(oc); 412 FontSet font_set; 413 int font_set_num; 414 XFontStruct **font_struct_list; 415 char **font_name_list, *font_name_buf; 416 int count, length; 417 418 font_set = gen->font_set; 419 font_set_num = gen->font_set_num; 420 count = length = 0; 421 422 for ( ; font_set_num-- > 0; font_set++) { 423 if (font_set->font_name == NULL) 424 continue; 425 426 length += strlen(font_set->font_name) + 1; 427 428 count++; 429 } 430 if (count == 0) 431 return False; 432 433 font_struct_list = Xmalloc(sizeof(XFontStruct *) * count); 434 if (font_struct_list == NULL) 435 return False; 436 437 font_name_list = Xmalloc(sizeof(char *) * count); 438 if (font_name_list == NULL) 439 goto err; 440 441 font_name_buf = Xmalloc(length); 442 if (font_name_buf == NULL) 443 goto err; 444 445 oc->core.font_info.num_font = count; 446 oc->core.font_info.font_name_list = font_name_list; 447 oc->core.font_info.font_struct_list = font_struct_list; 448 449 font_set = gen->font_set; 450 font_set_num = gen->font_set_num; 451 452 for (count = 0; font_set_num-- > 0; font_set++) { 453 if (font_set->font_name == NULL) 454 continue; 455 456 font_set->id = count; 457 if (font_set->font) 458 *font_struct_list++ = font_set->font; 459 else 460 *font_struct_list++ = font_set->info; 461 strcpy(font_name_buf, font_set->font_name); 462 Xfree(font_set->font_name); 463 *font_name_list++ = font_set->font_name = font_name_buf; 464 font_name_buf += strlen(font_name_buf) + 1; 465 466 count++; 467 } 468 469 set_fontset_extents(oc); 470 471 return True; 472 473err: 474 475 Xfree(font_name_list); 476 Xfree(font_struct_list); 477 478 return False; 479} 480 481static char * 482get_font_name( 483 XOC oc, 484 char *pattern) 485{ 486 char **list, *name; 487 int count = 0; 488 489 list = XListFonts(oc->core.om->core.display, pattern, 1, &count); 490 if (list == NULL) 491 return NULL; 492 493 name = strdup(*list); 494 495 XFreeFontNames(list); 496 497 return name; 498} 499 500/* For VW/UDC start*/ 501 502static char * 503get_rotate_fontname( 504 char *font_name) 505{ 506 char *pattern = NULL, *ptr = NULL; 507 char *fields[CHARSET_ENCODING_FIELD]; 508 char str_pixel[32], str_point[4]; 509 char *rotate_font_ptr = NULL; 510 int pixel_size = 0; 511 int field_num = 0, len = 0; 512 513 if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0 514 || len > XLFD_MAX_LEN) 515 return NULL; 516 517 pattern = strdup(font_name); 518 if(!pattern) 519 return NULL; 520 521 memset(fields, 0, sizeof(char *) * 14); 522 ptr = pattern; 523 while(isspace(*ptr)) { 524 ptr++; 525 } 526 if(*ptr == '-') 527 ptr++; 528 529 for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ; 530 ptr++, field_num++) { 531 fields[field_num] = ptr; 532 533 if((ptr = strchr(ptr, '-'))) { 534 *ptr = '\0'; 535 } else { 536 field_num++; /* Count last field */ 537 break; 538 } 539 } 540 541 if(field_num < CHARSET_ENCODING_FIELD) 542 goto free_pattern; 543 544 /* Pixel Size field : fields[6] */ 545 for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) { 546 if(!isdigit(*ptr)) { 547 if(*ptr == '['){ /* 960730 */ 548 strcpy(pattern, font_name); 549 return(pattern); 550 } 551 goto free_pattern; 552 } 553 } 554 pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]); 555 snprintf(str_pixel, sizeof(str_pixel), 556 "[ 0 ~%d %d 0 ]", pixel_size, pixel_size); 557 fields[6] = str_pixel; 558 559 /* Point Size field : fields[7] */ 560 strcpy(str_point, "*"); 561 fields[POINT_SIZE_FIELD - 1] = str_point; 562 563 len = 0; 564 for (field_num = 0; field_num < CHARSET_ENCODING_FIELD && 565 fields[field_num]; field_num++) { 566 len += 1 + strlen(fields[field_num]); 567 } 568 569 /* Max XLFD length is 255 */ 570 if (len > XLFD_MAX_LEN) 571 goto free_pattern; 572 573 rotate_font_ptr = Xmalloc(len + 1); 574 if(!rotate_font_ptr) 575 goto free_pattern; 576 577 rotate_font_ptr[0] = '\0'; 578 579 for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && 580 fields[field_num] ; field_num++) { 581 strcat(rotate_font_ptr, "-"); 582 strcat(rotate_font_ptr, fields[field_num]); 583 } 584 585free_pattern: 586 Xfree(pattern); 587 588 return rotate_font_ptr; 589} 590 591static Bool 592is_match_charset( 593 FontData font_data, 594 char *font_name) 595{ 596 char *last; 597 int length, name_len; 598 599 name_len = strlen(font_name); 600 last = font_name + name_len; 601 602 length = strlen(font_data->name); 603 if (length > name_len) 604 return False; 605 606 if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) 607 return True; 608 609 return False; 610} 611 612static int 613parse_all_name( 614 XOC oc, 615 FontData font_data, 616 char *pattern) 617{ 618 619#ifdef OLDCODE 620 if(is_match_charset(font_data, pattern) != True) 621 return False; 622 623 font_data->xlfd_name = strdup(pattern); 624 if(font_data->xlfd_name == NULL) 625 return (-1); 626 627 return True; 628#else /* OLDCODE */ 629 Display *dpy = oc->core.om->core.display; 630 char **fn_list = NULL, *prop_fname = NULL; 631 int list_num; 632 XFontStruct *fs_list; 633 if(is_match_charset(font_data, pattern) != True) { 634 /* 635 * pattern should not contain any wildcard (execpt '?') 636 * this was probably added to make this case insensitive. 637 */ 638 if ((fn_list = XListFontsWithInfo(dpy, pattern, 639 MAXFONTS, 640 &list_num, &fs_list)) == NULL) { 641 return False; 642 } 643 /* shouldn't we loop here ? */ 644 else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) { 645 XFreeFontInfo(fn_list, fs_list, list_num); 646 return False; 647 } 648 else if ((is_match_charset(font_data, prop_fname) != True)) { 649 XFree(prop_fname); 650 XFreeFontInfo(fn_list, fs_list, list_num); 651 return False; 652 } 653 else { 654 font_data->xlfd_name = prop_fname; 655 XFreeFontInfo(fn_list, fs_list, list_num); 656 return True; 657 } 658 } 659 660 font_data->xlfd_name = strdup(pattern); 661 if(font_data->xlfd_name == NULL) 662 return (-1); 663 664 return True; 665#endif /* OLDCODE */ 666} 667 668static int 669parse_omit_name( 670 XOC oc, 671 FontData font_data, 672 char *pattern) 673{ 674 char* last = (char *) NULL; 675 char* base_name; 676 char buf[XLFD_MAX_LEN + 1]; 677 int length = 0; 678 int num_fields; 679 /* 680 * If the font specified by "pattern" is expandable to be 681 * a member of "font_data"'s FontSet, we've found a match. 682 */ 683 if(is_match_charset(font_data, pattern) == True) { 684 if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) { 685 return True; 686 } 687 } 688 689 length = strlen (pattern); 690 691 if (length > XLFD_MAX_LEN) 692 return -1; 693 694 strcpy(buf, pattern); 695 last = buf + length - 1; 696 697 /* Replace the original encoding with the encoding for this FontSet. */ 698 699 /* Figure out how many fields have been specified in this xlfd. */ 700 for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) 701 if (*base_name == '-') num_fields++; 702 703 switch (num_fields) { 704 case 12: 705 /* This is the best way to have specifed the fontset. In this 706 * case, there is no original encoding. E.g., 707 * -*-*-*-*-*-*-14-*-*-*-*-* 708 * To this, we'll append a dash: 709 * -*-*-*-*-*-*-14-*-*-*-*-*- 710 * then append the encoding to get: 711 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 712 */ 713 /* 714 * Take care of: 715 * -*-*-*-*-*-*-14-*-*-*-*- 716 */ 717 if (*(last) == '-') 718 *++last = '*'; 719 720 *++last = '-'; 721 break; 722 case 13: 723 /* Got the charset, not the encoding, zap the charset In this 724 * case, there is no original encoding, but there is a charset. E.g., 725 * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990 726 * To this, we remove the charset: 727 * -*-*-*-*-*-*-14-*-*-*-*-*- 728 * then append the new encoding to get: 729 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 730 */ 731 last = strrchr (buf, '-'); 732 num_fields = 12; 733 break; 734 case 14: 735 /* Both the charset and the encoding are specified. Get rid 736 * of them so that we can append the new charset encoding. E.g., 737 * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0 738 * To this, we'll remove the encoding and charset to get: 739 * -*-*-*-*-*-*-14-*-*-*-*-*- 740 * then append the new encoding to get: 741 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 742 */ 743 last = strrchr (buf, '-'); 744 *last = '\0'; 745 last = strrchr (buf, '-'); 746 num_fields = 12; 747 break; 748 default: 749 if (*last != '-') 750 *++last = '-'; 751 break; 752 } 753 754 /* At this point, "last" is pointing to the last "-" in the 755 * xlfd, and all xlfd's at this point take a form similar to: 756 * -*-*-*-*-*-*-14-*-*-*-*-*- 757 * (i.e., no encoding). 758 * After the strcpy, we'll end up with something similar to: 759 * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 760 * 761 * If the modified font is found in the current FontSet, 762 * we've found a match. 763 */ 764 765 last++; 766 767 if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN) 768 return -1; 769 770 strcpy(last, font_data->name); 771 if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) 772 return True; 773 774 /* This may mot be needed anymore as XListFonts() takes care of this */ 775 if (num_fields < 12) { 776 if ((last - buf) > (XLFD_MAX_LEN - 2)) 777 return -1; 778 *last = '*'; 779 *(last + 1) = '-'; 780 strcpy(last + 2, font_data->name); 781 num_fields++; 782 last+=2; 783 if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) 784 return True; 785 } 786 787 788 return False; 789} 790 791 792typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType; 793 794static int 795parse_fontdata( 796 XOC oc, 797 FontSet font_set, 798 FontData font_data, 799 int font_data_count, 800 char **name_list, 801 int name_list_count, 802 ClassType class, 803 FontDataRec *font_data_return) 804{ 805 806 char **cur_name_list = name_list; 807 char *font_name = (char *) NULL; 808 char *pattern = (char *) NULL; 809 int found_num = 0, ret = 0; 810 int count = name_list_count; 811 812 if(name_list == NULL || count <= 0) { 813 return False; 814 } 815 816 if(font_data == NULL || font_data_count <= 0) { 817 return False; 818 } 819 820 /* Loop through each font encoding defined in the "font_data" FontSet. */ 821 for ( ; font_data_count-- > 0; font_data++) { 822 Bool is_found = False; 823 font_name = (char *) NULL; 824 count = name_list_count; 825 cur_name_list = name_list; 826 827 /* 828 * Loop through each font specified by the user 829 * in the call to XCreateFontset(). 830 */ 831 while (count-- > 0) { 832 pattern = *cur_name_list++; 833 if (pattern == NULL || *pattern == '\0') 834 continue; 835#ifdef FONTDEBUG 836 fprintf(stderr,"Font pattern: %s %s\n", 837 pattern,font_data->name); 838#endif 839 840 /* 841 * If the current font is fully specified (i.e., the 842 * xlfd contains no wildcards) and the font exists on 843 * the X Server, we have a match. 844 */ 845 if (strchr(pattern, '*') == NULL && 846 (font_name = get_font_name(oc, pattern))) { 847 /* 848 * Find the full xlfd name for this font. If the font is 849 * already in xlfd format, it is simply returned. If the 850 * font is an alias for another font, the xlfd of the 851 * aliased font is returned. 852 */ 853 ret = parse_all_name(oc, font_data, font_name); 854 Xfree(font_name); 855 856 if (ret == -1) return -1; 857 if (ret == False) continue; 858 /* 859 * Since there was an exact match of a fully-specified font 860 * or a font alias, we can return now since the desired font 861 * was found for the current font encoding for this FontSet. 862 * 863 * Previous implementations of this algorithm would 864 * not return here. Instead, they continued searching 865 * through the font encodings for this FontSet. The side-effect 866 * of that behavior is you may return a "substitute" match 867 * instead of an "exact" match. We believe there should be a 868 * preference on exact matches. Therefore, as soon as we 869 * find one, we bail. 870 * 871 * Also, previous implementations seemed to think it was 872 * important to find either a primary or substitute font 873 * for each Font encoding in the FontSet before returning an 874 * acceptable font. We don't believe this is necessary. 875 * All the client cares about is finding a reasonable font 876 * for what was passed in. If we find an exact match, 877 * there's no reason to look any further. 878 * 879 * -- jjw/pma (HP) 880 */ 881 if (font_data_return) { 882 font_data_return->xlfd_name = strdup(font_data->xlfd_name); 883 if (!font_data_return->xlfd_name) return -1; 884 885 font_data_return->side = font_data->side; 886 } 887#ifdef FONTDEBUG 888 fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); 889#endif 890 891 return True; 892 } 893 /* 894 * If the font name is not fully specified 895 * (i.e., it has wildcards), we have more work to do. 896 * See the comments in parse_omit_name() 897 * for the list of things to do. 898 */ 899 ret = parse_omit_name(oc, font_data, pattern); 900 901 if (ret == -1) return -1; 902 if (ret == False) continue; 903 904 /* 905 * A font which matched the wild-carded specification was found. 906 * Only update the return data if a font has not yet been found. 907 * This maintains the convention that FontSets listed higher in 908 * a CodeSet in the Locale Database have higher priority than 909 * those FontSets listed lower in the CodeSet. In the following 910 * example: 911 * 912 * fs1 { 913 * charset HP-JIS:GR 914 * font JISX0208.1990-0:GL;\ 915 * JISX0208.1990-1:GR;\ 916 * JISX0208.1983-0:GL;\ 917 * JISX0208.1983-1:GR 918 * } 919 * 920 * a font found in the JISX0208.1990-0 FontSet will have a 921 * higher priority than a font found in the JISX0208.1983-0 922 * FontSet. 923 */ 924 if (font_data_return && font_data_return->xlfd_name == NULL) { 925 926#ifdef FONTDEBUG 927 fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); 928#endif 929 font_data_return->xlfd_name = strdup(font_data->xlfd_name); 930 if (!font_data_return->xlfd_name) return -1; 931 932 font_data_return->side = font_data->side; 933 } 934 935 found_num++; 936 is_found = True; 937 938 break; 939 } 940 941 switch(class) { 942 case C_PRIMARY: 943 if(is_found == False) { 944 /* 945 * Did not find a font for the current FontSet. Check the 946 * FontSet's "substitute" font for a match. If we find a 947 * match, we'll keep searching in hopes of finding an exact 948 * match later down the FontSet list. 949 * 950 * when we return and we have found a font font_data_return 951 * contains the first (ie. best) match no matter if this 952 * is a C_PRIMARY or a C_SUBSTITUTE font 953 */ 954 ret = parse_fontdata(oc, font_set, font_set->substitute, 955 font_set->substitute_num, name_list, 956 name_list_count, C_SUBSTITUTE, 957 font_data_return); 958 if (ret == -1) return -1; 959 if (ret == False) continue; 960 961 found_num++; 962 is_found = True; 963 } 964#ifdef TESTVERSION 965 else 966 return True; 967#endif 968 break; 969 970 case C_SUBSTITUTE: 971 case C_VMAP: 972 if(is_found == True) 973 return True; 974 break; 975 976 case C_VROTATE: 977 if(is_found == True) { 978 char *rotate_name; 979 980 if((rotate_name = get_rotate_fontname(font_data->xlfd_name)) 981 != NULL) { 982 Xfree(font_data->xlfd_name); 983 font_data->xlfd_name = rotate_name; 984 985 return True; 986 } 987 Xfree(font_data->xlfd_name); 988 font_data->xlfd_name = NULL; 989 return False; 990 } 991 break; 992 } 993 } 994 995 if(class == C_PRIMARY && found_num >= 1) 996 return True; 997 998 return False; 999} 1000 1001 1002static int 1003parse_vw( 1004 XOC oc, 1005 FontSet font_set, 1006 char **name_list, 1007 int count) 1008{ 1009 FontData vmap = font_set->vmap; 1010 VRotate vrotate = font_set->vrotate; 1011 int vmap_num = font_set->vmap_num; 1012 int vrotate_num = font_set->vrotate_num; 1013 int ret = 0, i = 0; 1014 1015 if(vmap_num > 0) { 1016 if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list, 1017 count, C_VMAP,NULL) == -1) 1018 return (-1); 1019 } 1020 1021 if(vrotate_num > 0) { 1022 ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, 1023 name_list, count, C_VROTATE, NULL); 1024 if(ret == -1) { 1025 return (-1); 1026 } else if(ret == False) { 1027 CodeRange code_range; 1028 int num_cr; 1029 int sub_num = font_set->substitute_num; 1030 1031 code_range = vrotate[0].code_range; /* ? */ 1032 num_cr = vrotate[0].num_cr; /* ? */ 1033 for(i = 0 ; i < vrotate_num ; i++) { 1034 if(vrotate[i].xlfd_name) 1035 Xfree(vrotate[i].xlfd_name); 1036 } 1037 Xfree(vrotate); 1038 1039 if(sub_num > 0) { 1040 vrotate = font_set->vrotate = Xcalloc(sub_num, 1041 sizeof(VRotateRec)); 1042 if(font_set->vrotate == (VRotate)NULL) 1043 return (-1); 1044 1045 for(i = 0 ; i < sub_num ; i++) { 1046 vrotate[i].charset_name = font_set->substitute[i].name; 1047 vrotate[i].side = font_set->substitute[i].side; 1048 vrotate[i].code_range = code_range; 1049 vrotate[i].num_cr = num_cr; 1050 } 1051 vrotate_num = font_set->vrotate_num = sub_num; 1052 } else { 1053 vrotate = font_set->vrotate = (VRotate)NULL; 1054 } 1055 1056 ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, 1057 name_list, count, C_VROTATE, NULL); 1058 if(ret == -1) 1059 return (-1); 1060 } 1061 } 1062 1063 return True; 1064} 1065 1066static int 1067parse_fontname( 1068 XOC oc) 1069{ 1070 XOCGenericPart *gen = XOC_GENERIC(oc); 1071 FontSet font_set; 1072 FontDataRec font_data_return; 1073 char *base_name, **name_list; 1074 int font_set_num = 0; 1075 int found_num = 0; 1076 int count = 0; 1077 int ret; 1078 int i; 1079 1080 name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); 1081 if (name_list == NULL) 1082 return -1; 1083 1084 font_set = gen->font_set; 1085 font_set_num = gen->font_set_num; 1086 1087 /* Loop through all of the CharSets defined in the Locale 1088 * database for the current Locale. 1089 */ 1090 for( ; font_set_num-- > 0 ; font_set++) { 1091 if(font_set->font_name) 1092 continue; 1093 1094 if(font_set->font_data_count > 0) { 1095 1096 /* 1097 * If there are a non-zero number of FontSets defined 1098 * for this CharSet. 1099 * Try to find a font for this CharSet. If we find an 1100 * acceptable font, we save the information for return 1101 * to the client. If we do not find an acceptable font, 1102 * a "missing_charset" will be reported to the client 1103 * for this CharSet. 1104 */ 1105 font_data_return.xlfd_name = NULL; 1106 font_data_return.side = XlcUnknown; 1107 1108 ret = parse_fontdata(oc, font_set, font_set->font_data, 1109 font_set->font_data_count, 1110 name_list, count, C_PRIMARY, 1111 &font_data_return); 1112 if(ret == -1) { 1113 goto err; 1114 } else if(ret == True) { 1115 /* 1116 * We can't just loop thru fontset->font_data to 1117 * find the first (ie. best) match: parse_fontdata 1118 * will try a substitute font if no primary one could 1119 * be matched. It returns the required information in 1120 * font_data_return. 1121 */ 1122 font_set->font_name = strdup(font_data_return.xlfd_name); 1123 if(font_set->font_name == (char *) NULL) 1124 goto err; 1125 1126 font_set->side = font_data_return.side; 1127 1128 Xfree (font_data_return.xlfd_name); 1129 font_data_return.xlfd_name = NULL; 1130 1131 if(parse_vw(oc, font_set, name_list, count) == -1) 1132 goto err; 1133 found_num++; 1134 } 1135 1136 } else if(font_set->substitute_num > 0) { 1137 /* 1138 * If there are no FontSets defined for this 1139 * CharSet. We can only find "substitute" fonts. 1140 */ 1141 ret = parse_fontdata(oc, font_set, font_set->substitute, 1142 font_set->substitute_num, 1143 name_list, count, C_SUBSTITUTE, NULL); 1144 if(ret == -1) { 1145 goto err; 1146 } else if(ret == True) { 1147 for(i=0;i<font_set->substitute_num;i++){ 1148 if(font_set->substitute[i].xlfd_name != NULL){ 1149 break; 1150 } 1151 } 1152 font_set->font_name = strdup(font_set->substitute[i].xlfd_name); 1153 if(font_set->font_name == (char *) NULL) 1154 goto err; 1155 1156 font_set->side = font_set->substitute[i].side; 1157 if(parse_vw(oc, font_set, name_list, count) == -1) 1158 goto err; 1159 1160 found_num++; 1161 } 1162 } 1163 } 1164 1165 base_name = strdup(oc->core.base_name_list); 1166 if (base_name == NULL) 1167 goto err; 1168 1169 oc->core.base_name_list = base_name; 1170 1171 XFreeStringList(name_list); 1172 1173 return found_num; 1174 1175err: 1176 XFreeStringList(name_list); 1177 /* Prevent this from being freed twice */ 1178 oc->core.base_name_list = NULL; 1179 1180 return -1; 1181} 1182 1183/* For VW/UDC end*/ 1184 1185static Bool 1186set_missing_list( 1187 XOC oc) 1188{ 1189 XOCGenericPart *gen = XOC_GENERIC(oc); 1190 FontSet font_set; 1191 char **charset_list, *charset_buf; 1192 int count, length, font_set_num; 1193 int result = 1; 1194 1195 font_set = gen->font_set; 1196 font_set_num = gen->font_set_num; 1197 count = length = 0; 1198 1199 for ( ; font_set_num-- > 0; font_set++) { 1200 if (font_set->info || font_set->font) { 1201 continue; 1202 } 1203 1204 /* Change 1996.01.23 start */ 1205 if(font_set->font_data_count <= 0 || 1206 font_set->font_data == (FontData)NULL) { 1207 if(font_set->substitute_num <= 0 || 1208 font_set->substitute == (FontData)NULL) { 1209 if(font_set->charset_list != NULL){ 1210 length += 1211 strlen(font_set->charset_list[0]->encoding_name) + 1; 1212 } else { 1213 length += 1; 1214 } 1215 } else { 1216 length += strlen(font_set->substitute->name) + 1; 1217 } 1218 } else { 1219 length += strlen(font_set->font_data->name) + 1; 1220 } 1221 /* Change 1996.01.23 end */ 1222 count++; 1223 } 1224 1225 if (count < 1) { 1226 return True; 1227 } 1228 1229 charset_list = Xmalloc(sizeof(char *) * count); 1230 if (charset_list == NULL) { 1231 return False; 1232 } 1233 1234 charset_buf = Xmalloc(length); 1235 if (charset_buf == NULL) { 1236 Xfree(charset_list); 1237 return False; 1238 } 1239 1240 oc->core.missing_list.charset_list = charset_list; 1241 oc->core.missing_list.charset_count = count; 1242 1243 font_set = gen->font_set; 1244 font_set_num = gen->font_set_num; 1245 1246 for ( ; font_set_num-- > 0; font_set++) { 1247 if (font_set->info || font_set->font) { 1248 continue; 1249 } 1250 1251 /* Change 1996.01.23 start */ 1252 if(font_set->font_data_count <= 0 || 1253 font_set->font_data == (FontData)NULL) { 1254 if(font_set->substitute_num <= 0 || 1255 font_set->substitute == (FontData)NULL) { 1256 if(font_set->charset_list != NULL){ 1257 strcpy(charset_buf, 1258 font_set->charset_list[0]->encoding_name); 1259 } else { 1260 strcpy(charset_buf, ""); 1261 } 1262 result = 0; 1263 } else { 1264 strcpy(charset_buf, font_set->substitute->name); 1265 } 1266 } else { 1267 strcpy(charset_buf, font_set->font_data->name); 1268 } 1269 /* Change 1996.01.23 end */ 1270 *charset_list++ = charset_buf; 1271 charset_buf += strlen(charset_buf) + 1; 1272 } 1273 1274 if(result == 0) { 1275 return(False); 1276 } 1277 1278 return True; 1279} 1280 1281static Bool 1282create_fontset( 1283 XOC oc) 1284{ 1285 XOMGenericPart *gen = XOM_GENERIC(oc->core.om); 1286 int found_num; 1287 1288 if (init_fontset(oc) == False) 1289 return False; 1290 1291 found_num = parse_fontname(oc); 1292 if (found_num <= 0) { 1293 if (found_num == 0) 1294 set_missing_list(oc); 1295 return False; 1296 } 1297 1298 if (gen->on_demand_loading == True) { 1299 if (load_font_info(oc) == False) 1300 return False; 1301 } else { 1302 if (load_font(oc) == False) 1303 return False; 1304 } 1305 1306 if (init_core_part(oc) == False) 1307 return False; 1308 1309 if (set_missing_list(oc) == False) 1310 return False; 1311 1312 return True; 1313} 1314 1315/* For VW/UDC start */ 1316static void 1317free_fontdataOC( 1318 Display *dpy, 1319 FontData font_data, 1320 int font_data_count) 1321{ 1322 for( ; font_data_count-- ; font_data++) { 1323 if(font_data->xlfd_name){ 1324 Xfree(font_data->xlfd_name); 1325 font_data->xlfd_name = NULL; 1326 } 1327 if(font_data->font){ /* ADD 1996.01.7 */ 1328 if(font_data->font->fid) /* Add 1996.01.23 */ 1329 XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */ 1330 else /* Add 1996.01.23 */ 1331 XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */ 1332 font_data->font = NULL; 1333 } 1334/* 1335 * font_data->name and font_data->scopes belong to the OM not OC. 1336 * To save space this data is shared between OM and OC. We are 1337 * not allowed to free it here. 1338 * It has been moved to free_fontdataOM() 1339 */ 1340/* 1341 if(font_data->scopes){ 1342 Xfree(font_data->scopes); 1343 font_data->scopes = NULL; 1344 } 1345 if(font_data->name){ 1346 Xfree(font_data->name); 1347 font_data->name = NULL; 1348 } 1349*/ 1350 } 1351} 1352 1353static void destroy_fontdata( 1354 XOCGenericPart *gen, 1355 Display *dpy) 1356{ 1357 FontSet font_set = (FontSet) NULL; 1358 int font_set_num = 0; 1359 1360 if (gen->font_set) { 1361 font_set = gen->font_set; 1362 font_set_num = gen->font_set_num; 1363 for( ; font_set_num-- ; font_set++) { 1364 if (font_set->font) { 1365 if(font_set->font->fid) 1366 XFreeFont(dpy,font_set->font); 1367 else 1368 XFreeFontInfo(NULL, font_set->font, 1); 1369 font_set->font = NULL; 1370 } 1371 if(font_set->font_data) { 1372 if (font_set->info) 1373 XFreeFontInfo(NULL, font_set->info, 1); 1374 free_fontdataOC(dpy, 1375 font_set->font_data, font_set->font_data_count); 1376 Xfree(font_set->font_data); 1377 font_set->font_data = NULL; 1378 } 1379 if(font_set->substitute) { 1380 free_fontdataOC(dpy, 1381 font_set->substitute, font_set->substitute_num); 1382 Xfree(font_set->substitute); 1383 font_set->substitute = NULL; 1384 } 1385 if(font_set->vmap) { 1386 free_fontdataOC(dpy, 1387 font_set->vmap, font_set->vmap_num); 1388 Xfree(font_set->vmap); 1389 font_set->vmap = NULL; 1390 } 1391 if(font_set->vrotate) { 1392 free_fontdataOC(dpy, 1393 (FontData)font_set->vrotate, 1394 font_set->vrotate_num); 1395 Xfree(font_set->vrotate); 1396 font_set->vrotate = NULL; 1397 } 1398 } 1399 Xfree(gen->font_set); 1400 gen->font_set = NULL; 1401 } 1402} 1403/* For VW/UDC end */ 1404 1405static void 1406destroy_oc( 1407 XOC oc) 1408{ 1409 Display *dpy = oc->core.om->core.display; 1410 XOCGenericPart *gen = XOC_GENERIC(oc); 1411 1412 if (gen->mbs_to_cs) 1413 _XlcCloseConverter(gen->mbs_to_cs); 1414 1415 if (gen->wcs_to_cs) 1416 _XlcCloseConverter(gen->wcs_to_cs); 1417 1418 if (gen->utf8_to_cs) 1419 _XlcCloseConverter(gen->utf8_to_cs); 1420 1421/* For VW/UDC start */ /* Change 1996.01.8 */ 1422 destroy_fontdata(gen,dpy); 1423/* 1424*/ 1425/* For VW/UDC end */ 1426 1427 Xfree(oc->core.base_name_list); 1428 XFreeStringList(oc->core.font_info.font_name_list); 1429 Xfree(oc->core.font_info.font_struct_list); 1430 XFreeStringList(oc->core.missing_list.charset_list); 1431 1432#ifdef notdef 1433 1434 Xfree(oc->core.res_name); 1435 Xfree(oc->core.res_class); 1436#endif 1437 1438 Xfree(oc); 1439} 1440 1441static char * 1442set_oc_values( 1443 XOC oc, 1444 XlcArgList args, 1445 int num_args) 1446{ 1447 XOCGenericPart *gen = XOC_GENERIC(oc); 1448 FontSet font_set = gen->font_set; 1449 char *ret; 1450 int num = gen->font_set_num; 1451 1452 if (oc->core.resources == NULL) 1453 return NULL; 1454 1455 ret = _XlcSetValues((XPointer) oc, oc->core.resources, 1456 oc->core.num_resources, args, num_args, XlcSetMask); 1457 if(ret != NULL){ 1458 return(ret); 1459 } else { 1460 for ( ; num-- > 0; font_set++) { 1461 if (font_set->font_name == NULL) 1462 continue; 1463 if (font_set->vpart_initialize != 0) 1464 continue; 1465 if( oc->core.orientation == XOMOrientation_TTB_RTL || 1466 oc->core.orientation == XOMOrientation_TTB_LTR ){ 1467 load_fontdata(oc, font_set->vmap, font_set->vmap_num); 1468 load_fontdata(oc, (FontData) font_set->vrotate, 1469 font_set->vrotate_num); 1470 font_set->vpart_initialize = 1; 1471 } 1472 } 1473 return(NULL); 1474 } 1475} 1476 1477static char * 1478get_oc_values( 1479 XOC oc, 1480 XlcArgList args, 1481 int num_args) 1482{ 1483 if (oc->core.resources == NULL) 1484 return NULL; 1485 1486 return _XlcGetValues((XPointer) oc, oc->core.resources, 1487 oc->core.num_resources, args, num_args, XlcGetMask); 1488} 1489 1490static XOCMethodsRec oc_default_methods = { 1491 destroy_oc, 1492 set_oc_values, 1493 get_oc_values, 1494 _XmbDefaultTextEscapement, 1495 _XmbDefaultTextExtents, 1496 _XmbDefaultTextPerCharExtents, 1497 _XmbDefaultDrawString, 1498 _XmbDefaultDrawImageString, 1499 _XwcDefaultTextEscapement, 1500 _XwcDefaultTextExtents, 1501 _XwcDefaultTextPerCharExtents, 1502 _XwcDefaultDrawString, 1503 _XwcDefaultDrawImageString, 1504 _Xutf8DefaultTextEscapement, 1505 _Xutf8DefaultTextExtents, 1506 _Xutf8DefaultTextPerCharExtents, 1507 _Xutf8DefaultDrawString, 1508 _Xutf8DefaultDrawImageString 1509}; 1510 1511static XOCMethodsRec oc_generic_methods = { 1512 destroy_oc, 1513 set_oc_values, 1514 get_oc_values, 1515 _XmbGenericTextEscapement, 1516 _XmbGenericTextExtents, 1517 _XmbGenericTextPerCharExtents, 1518 _XmbGenericDrawString, 1519 _XmbGenericDrawImageString, 1520 _XwcGenericTextEscapement, 1521 _XwcGenericTextExtents, 1522 _XwcGenericTextPerCharExtents, 1523 _XwcGenericDrawString, 1524 _XwcGenericDrawImageString, 1525 _Xutf8GenericTextEscapement, 1526 _Xutf8GenericTextExtents, 1527 _Xutf8GenericTextPerCharExtents, 1528 _Xutf8GenericDrawString, 1529 _Xutf8GenericDrawImageString 1530}; 1531 1532typedef struct _XOCMethodsListRec { 1533 const char *name; 1534 XOCMethods methods; 1535} XOCMethodsListRec, *XOCMethodsList; 1536 1537static XOCMethodsListRec oc_methods_list[] = { 1538 { "default", &oc_default_methods }, 1539 { "generic", &oc_generic_methods } 1540}; 1541 1542static XlcResource oc_resources[] = { 1543 { XNBaseFontName, NULLQUARK, sizeof(char *), 1544 XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, 1545 { XNOMAutomatic, NULLQUARK, sizeof(Bool), 1546 XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, 1547 { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), 1548 XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, 1549 { XNDefaultString, NULLQUARK, sizeof(char *), 1550 XOffsetOf(XOCRec, core.default_string), XlcGetMask }, 1551 { XNOrientation, NULLQUARK, sizeof(XOrientation), 1552 XOffsetOf(XOCRec, core.orientation), XlcDefaultMask | XlcSetMask | XlcGetMask }, 1553 { XNResourceName, NULLQUARK, sizeof(char *), 1554 XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, 1555 { XNResourceClass, NULLQUARK, sizeof(char *), 1556 XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, 1557 { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), 1558 XOffsetOf(XOCRec, core.font_info), XlcGetMask } 1559}; 1560 1561static XOC 1562create_oc( 1563 XOM om, 1564 XlcArgList args, 1565 int num_args) 1566{ 1567 XOC oc; 1568 XOMGenericPart *gen = XOM_GENERIC(om); 1569 XOCMethodsList methods_list = oc_methods_list; 1570 int count; 1571 1572 oc = Xcalloc(1, sizeof(XOCGenericRec)); 1573 if (oc == NULL) 1574 return (XOC) NULL; 1575 1576 oc->core.om = om; 1577 1578 if (oc_resources[0].xrm_name == NULLQUARK) 1579 _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); 1580 1581 if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), 1582 args, num_args, XlcCreateMask | XlcDefaultMask)) 1583 goto err; 1584 1585 if (oc->core.base_name_list == NULL) 1586 goto err; 1587 1588 oc->core.resources = oc_resources; 1589 oc->core.num_resources = XlcNumber(oc_resources); 1590 1591 if (create_fontset(oc) == False) 1592 goto err; 1593 1594 oc->methods = &oc_generic_methods; 1595 1596 if (gen->object_name) { 1597 count = XlcNumber(oc_methods_list); 1598 1599 for ( ; count-- > 0; methods_list++) { 1600 if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) { 1601 oc->methods = methods_list->methods; 1602 break; 1603 } 1604 } 1605 } 1606 1607 return oc; 1608 1609err: 1610 destroy_oc(oc); 1611 1612 return (XOC) NULL; 1613} 1614 1615static void 1616free_fontdataOM( 1617 FontData font_data, 1618 int font_data_count) 1619{ 1620 for( ; font_data_count-- ; font_data++) { 1621 if(font_data->name){ 1622 Xfree(font_data->name); 1623 font_data->name = NULL; 1624 } 1625 if(font_data->scopes){ 1626 Xfree(font_data->scopes); 1627 font_data->scopes = NULL; 1628 } 1629 } 1630} 1631 1632static Status 1633close_om( 1634 XOM om) 1635{ 1636 XOMGenericPart *gen = XOM_GENERIC(om); 1637 OMData data; 1638 int count; 1639 1640 if ((data = gen->data)) { 1641 for (count = gen->data_num; count-- > 0; data++) { 1642 if (data->charset_list){ 1643 Xfree(data->charset_list); 1644 data->charset_list = NULL; 1645 } 1646 /* free font_data for om */ 1647 if (data->font_data) { 1648 free_fontdataOM(data->font_data,data->font_data_count); 1649 Xfree(data->font_data); 1650 data->font_data = NULL; 1651 } 1652 /* free substitute for om */ 1653 if (data->substitute) { 1654 free_fontdataOM(data->substitute,data->substitute_num); 1655 Xfree(data->substitute); 1656 data->substitute = NULL; 1657 } 1658 /* free vmap for om */ 1659 if (data->vmap) { 1660 free_fontdataOM(data->vmap,data->vmap_num); 1661 Xfree(data->vmap); 1662 data->vmap = NULL; 1663 } 1664 /* free vrotate for om */ 1665 if (data->vrotate) { 1666 Xfree(data->vrotate); 1667 data->vrotate = NULL; 1668 } 1669 } 1670 Xfree(gen->data); 1671 gen->data = NULL; 1672 } 1673 1674 if (gen->object_name){ 1675 Xfree(gen->object_name); 1676 gen->object_name = NULL; 1677 } 1678 1679 if (om->core.res_name){ 1680 Xfree(om->core.res_name); 1681 om->core.res_name = NULL; 1682 } 1683 if (om->core.res_class){ 1684 Xfree(om->core.res_class); 1685 om->core.res_class = NULL; 1686 } 1687 if (om->core.required_charset.charset_list && 1688 om->core.required_charset.charset_count > 0){ 1689 XFreeStringList(om->core.required_charset.charset_list); 1690 om->core.required_charset.charset_list = NULL; 1691 } else { 1692 Xfree((char*)om->core.required_charset.charset_list); 1693 om->core.required_charset.charset_list = NULL; 1694 } 1695 if (om->core.orientation_list.orientation){ 1696 Xfree(om->core.orientation_list.orientation); 1697 om->core.orientation_list.orientation = NULL; 1698 } 1699 1700 Xfree(om); 1701 1702 return 1; 1703} 1704 1705static char * 1706set_om_values( 1707 XOM om, 1708 XlcArgList args, 1709 int num_args) 1710{ 1711 if (om->core.resources == NULL) 1712 return NULL; 1713 1714 return _XlcSetValues((XPointer) om, om->core.resources, 1715 om->core.num_resources, args, num_args, XlcSetMask); 1716} 1717 1718static char * 1719get_om_values( 1720 XOM om, 1721 XlcArgList args, 1722 int num_args) 1723{ 1724 if (om->core.resources == NULL) 1725 return NULL; 1726 1727 return _XlcGetValues((XPointer) om, om->core.resources, 1728 om->core.num_resources, args, num_args, XlcGetMask); 1729} 1730 1731static XOMMethodsRec methods = { 1732 close_om, 1733 set_om_values, 1734 get_om_values, 1735 create_oc 1736}; 1737 1738static XlcResource om_resources[] = { 1739 { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), 1740 XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, 1741 { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), 1742 XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, 1743 { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), 1744 XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, 1745 { XNContextualDrawing, NULLQUARK, sizeof(Bool), 1746 XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } 1747}; 1748 1749static XOM 1750create_om( 1751 XLCd lcd, 1752 Display *dpy, 1753 XrmDatabase rdb, 1754 _Xconst char *res_name, 1755 _Xconst char *res_class) 1756{ 1757 XOM om; 1758 1759 om = Xcalloc(1, sizeof(XOMGenericRec)); 1760 if (om == NULL) 1761 return (XOM) NULL; 1762 1763 om->methods = &methods; 1764 om->core.lcd = lcd; 1765 om->core.display = dpy; 1766 om->core.rdb = rdb; 1767 if (res_name) { 1768 om->core.res_name = strdup(res_name); 1769 if (om->core.res_name == NULL) 1770 goto err; 1771 } 1772 if (res_class) { 1773 om->core.res_class = strdup(res_class); 1774 if (om->core.res_class == NULL) 1775 goto err; 1776 } 1777 1778 if (om_resources[0].xrm_name == NULLQUARK) 1779 _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); 1780 1781 om->core.resources = om_resources; 1782 om->core.num_resources = XlcNumber(om_resources); 1783 1784 return om; 1785 1786err: 1787 close_om(om); 1788 1789 return (XOM) NULL; 1790} 1791 1792static OMData 1793add_data( 1794 XOM om) 1795{ 1796 XOMGenericPart *gen = XOM_GENERIC(om); 1797 OMData new; 1798 int num; 1799 1800 if ((num = gen->data_num)) 1801 new = Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec)); 1802 else 1803 new = Xmalloc(sizeof(OMDataRec)); 1804 1805 if (new == NULL) 1806 return NULL; 1807 1808 gen->data_num = num + 1; 1809 gen->data = new; 1810 1811 new += num; 1812 bzero((char *) new, sizeof(OMDataRec)); 1813 1814 return new; 1815} 1816 1817/* For VW/UDC */ 1818 1819FontData 1820read_EncodingInfo( 1821 int count, 1822 char **value) 1823{ 1824 FontData font_data,ret; 1825 char *buf, *bufptr,*scp; 1826 int len, i; 1827 font_data = Xcalloc(count, sizeof(FontDataRec)); 1828 if (font_data == NULL) 1829 return NULL; 1830 1831 ret = font_data; 1832 for (i = 0; i < count; i++, font_data++) { 1833/* 1834 strcpy(buf, *value++); 1835*/ 1836 buf = *value; value++; 1837 if ((bufptr = strchr(buf, ':'))) { 1838 len = (int)(bufptr - buf); 1839 bufptr++ ; 1840 } else 1841 len = strlen(buf); 1842 font_data->name = Xmalloc(len + 1); 1843 if (font_data->name == NULL) { 1844 free_fontdataOM(ret, i + 1); 1845 Xfree(ret); 1846 return NULL; 1847 } 1848 strncpy(font_data->name, buf,len); 1849 font_data->name[len] = 0; 1850 if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0) 1851 font_data->side = XlcGL; 1852 else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0) 1853 font_data->side = XlcGR; 1854 else 1855 font_data->side = XlcGLGR; 1856 1857 if (bufptr && (scp = strchr(bufptr, '['))){ 1858 font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num)); 1859 } 1860 } 1861 return(ret); 1862} 1863 1864static CodeRange read_vrotate( 1865 int count, 1866 char **value, 1867 int *type, 1868 int *vrotate_num) 1869{ 1870 CodeRange range; 1871 if(!strcmp(value[0],"all")){ 1872 *type = VROTATE_ALL ; 1873 *vrotate_num = 0 ; 1874 return (NULL); 1875 } else if(*(value[0]) == '['){ 1876 *type = VROTATE_PART ; 1877 range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num); 1878 return (range); 1879 } else { 1880 *type = VROTATE_NONE ; 1881 *vrotate_num = 0 ; 1882 return (NULL); 1883 } 1884} 1885 1886static void read_vw( 1887 XLCd lcd, 1888 OMData font_set, 1889 int num) 1890{ 1891 char **value, buf[BUFSIZ]; 1892 int count; 1893 1894 snprintf(buf, sizeof(buf), "fs%d.font.vertical_map", num); 1895 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1896 if (count > 0){ 1897 _XlcDbg_printValue(buf,value,count); 1898 font_set->vmap_num = count; 1899 font_set->vmap = read_EncodingInfo(count,value); 1900 } 1901 1902 snprintf(buf, sizeof(buf), "fs%d.font.vertical_rotate", num); 1903 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1904 if (count > 0){ 1905 _XlcDbg_printValue(buf,value,count); 1906 font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type), 1907 &(font_set->vrotate_num)); 1908 } 1909} 1910/* VW/UDC end */ 1911static Bool 1912init_om( 1913 XOM om) 1914{ 1915 XLCd lcd = om->core.lcd; 1916 XOMGenericPart *gen = XOM_GENERIC(om); 1917 OMData data; 1918 XlcCharSet *charset_list; 1919 FontData font_data; 1920 char **required_list; 1921 XOrientation *orientation; 1922 char **value, buf[BUFSIZ], *bufptr; 1923 int count = 0, num = 0, length = 0; 1924 1925 _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count); 1926 if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0) 1927 gen->on_demand_loading = True; 1928 1929 _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count); 1930 if (count > 0) { 1931 gen->object_name = strdup(*value); 1932 if (gen->object_name == NULL) 1933 return False; 1934 } 1935 1936 for (num = 0; ; num++) { 1937 1938 snprintf(buf, sizeof(buf), "fs%d.charset.name", num); 1939 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1940 1941 if( count < 1){ 1942 snprintf(buf, sizeof(buf), "fs%d.charset", num); 1943 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1944 if (count < 1) 1945 break; 1946 } 1947 1948 data = add_data(om); 1949 if (data == NULL) 1950 return False; 1951 1952 charset_list = Xmalloc(sizeof(XlcCharSet) * count); 1953 if (charset_list == NULL) 1954 return False; 1955 data->charset_list = charset_list; 1956 data->charset_count = count; 1957 1958 while (count-- > 0){ 1959 *charset_list++ = _XlcGetCharSet(*value++); 1960 } 1961 snprintf(buf, sizeof(buf), "fs%d.charset.udc_area", num); 1962 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1963 if( count > 0){ 1964 UDCArea udc; 1965 int i,flag = 0; 1966 udc = Xmalloc(count * sizeof(UDCAreaRec)); 1967 if (udc == NULL) 1968 return False; 1969 for(i=0;i<count;i++){ 1970 sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start), 1971 &(udc[i].end)); 1972 } 1973 for(i=0;i<data->charset_count;i++){ 1974 if(data->charset_list[i]->udc_area == NULL){ 1975 data->charset_list[i]->udc_area = udc; 1976 data->charset_list[i]->udc_area_num = count; 1977 flag = 1; 1978 } 1979 } 1980 if(flag == 0){ 1981 Xfree(udc); 1982 } 1983 } 1984 1985 snprintf(buf, sizeof(buf), "fs%d.font.primary", num); 1986 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1987 if (count < 1){ 1988 snprintf(buf, sizeof(buf), "fs%d.font", num); 1989 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 1990 if (count < 1) 1991 return False; 1992 } 1993 1994 font_data = read_EncodingInfo(count,value); 1995 if (font_data == NULL) 1996 return False; 1997 1998 data->font_data = font_data; 1999 data->font_data_count = count; 2000 2001 snprintf(buf, sizeof(buf), "fs%d.font.substitute", num); 2002 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 2003 if (count > 0){ 2004 font_data = read_EncodingInfo(count,value); 2005 if (font_data == NULL) 2006 return False; 2007 data->substitute = font_data; 2008 data->substitute_num = count; 2009 } else { 2010 snprintf(buf, sizeof(buf), "fs%d.font", num); 2011 _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); 2012 if (count < 1) { 2013 data->substitute = NULL; 2014 data->substitute_num = 0; 2015 } else { 2016 font_data = read_EncodingInfo(count,value); 2017 data->substitute = font_data; 2018 data->substitute_num = count; 2019 } 2020 } 2021 read_vw(lcd,data,num); 2022 length += strlen(data->font_data->name) + 1; 2023 } 2024 2025 /* required charset list */ 2026 required_list = Xmalloc(sizeof(char *) * gen->data_num); 2027 if (required_list == NULL) 2028 return False; 2029 2030 om->core.required_charset.charset_list = required_list; 2031 om->core.required_charset.charset_count = gen->data_num; 2032 2033 count = gen->data_num; 2034 data = gen->data; 2035 2036 if (count > 0) { 2037 bufptr = Xmalloc(length); 2038 if (bufptr == NULL) { 2039 Xfree(required_list); 2040 return False; 2041 } 2042 2043 for ( ; count-- > 0; data++) { 2044 strcpy(bufptr, data->font_data->name); 2045 *required_list++ = bufptr; 2046 bufptr += strlen(bufptr) + 1; 2047 } 2048 } 2049 2050 /* orientation list */ 2051 orientation = Xmalloc(sizeof(XOrientation) * 2); 2052 if (orientation == NULL) 2053 return False; 2054 2055 orientation[0] = XOMOrientation_LTR_TTB; 2056 orientation[1] = XOMOrientation_TTB_RTL; 2057 om->core.orientation_list.orientation = orientation; 2058 om->core.orientation_list.num_orientation = 2; 2059 2060 /* directional dependent drawing */ 2061 om->core.directional_dependent = False; 2062 2063 /* contexual drawing */ 2064 om->core.contextual_drawing = False; 2065 2066 /* context dependent */ 2067 om->core.context_dependent = False; 2068 2069 return True; 2070} 2071 2072XOM 2073_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, 2074 _Xconst char *res_name, _Xconst char *res_class) 2075{ 2076 XOM om; 2077 2078 om = create_om(lcd, dpy, rdb, res_name, res_class); 2079 if (om == NULL) 2080 return (XOM) NULL; 2081 2082 if (init_om(om) == False) 2083 goto err; 2084 2085 return om; 2086 2087err: 2088 close_om(om); 2089 2090 return (XOM) NULL; 2091} 2092 2093Bool 2094_XInitOM( 2095 XLCd lcd) 2096{ 2097 lcd->methods->open_om = _XomGenericOpenOM; 2098 2099 return True; 2100} 2101