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