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