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