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