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