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