omXChar.c revision 1ab64890
1/* $Xorg: omXChar.c,v 1.3 2000/08/17 19:45:23 cpqbld Exp $ */ 2/* 3 * Copyright 1992, 1993 by TOSHIBA Corp. 4 * 5 * Permission to use, copy, modify, and distribute this software and its 6 * documentation for any purpose and without fee is hereby granted, provided 7 * that the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of TOSHIBA not be used in advertising 10 * or publicity pertaining to distribution of the software without specific, 11 * written prior permission. TOSHIBA make no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 21 * SOFTWARE. 22 * 23 * Author: Katsuhisa Yano TOSHIBA Corp. 24 * mopi@osa.ilab.toshiba.co.jp 25 */ 26/* 27 * Copyright 1995 by FUJITSU LIMITED 28 * This is source code modified by FUJITSU LIMITED under the Joint 29 * Development Agreement for the CDE/Motif PST. 30 * 31 * Modifier: Takanori Tateno FUJITSU LIMITED 32 * 33 */ 34/* 35 * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD) 36 */ 37/* $XFree86: xc/lib/X11/omXChar.c,v 1.6tsi Exp $ */ 38 39#ifdef HAVE_CONFIG_H 40#include <config.h> 41#endif 42#include "Xlibint.h" 43#include "XlcPublic.h" 44#include "XomGeneric.h" 45#include <stdio.h> 46 47/* for VW/UDC start */ 48static Bool 49ismatch_scopes( 50 FontData fontdata, 51 unsigned long *value, 52 Bool is_shift) 53{ 54 register int scopes_num = fontdata->scopes_num; 55 FontScope scopes = fontdata->scopes; 56 if (!scopes_num) 57 return False; 58 59 if(fontdata->font == NULL) 60 return False; 61 62 for(;scopes_num--;scopes++) 63 if ((scopes->start <= (*value & 0x7f7f)) && 64 ((scopes->end) >= (*value & 0x7f7f))){ 65 if(is_shift == True) { 66 if(scopes->shift){ 67 if(scopes->shift_direction == '+'){ 68 *value += scopes->shift ; 69 } else if( scopes->shift_direction == '-'){ 70 *value -= scopes->shift ; 71 } 72 } 73 } 74 return True; 75 } 76 77 return False; 78} 79 80static int 81check_vertical_fonttype( 82 char *name) 83{ 84 char *ptr; 85 int type = 0; 86 87 if(name == (char *)NULL || (int) strlen(name) <= 0) 88 return False; 89 90 /* Obtains the pointer of CHARSET_ENCODING_FIELD. */ 91 if((ptr = strchr(name, '-')) == (char *) NULL) 92 return False; 93 ptr++; 94 95 /* Obtains the pointer of vertical_map font type. */ 96 if((ptr = strchr(ptr, '.')) == (char *) NULL) 97 return False; 98 ptr++; 99 100 switch(*ptr) { 101 case '1': 102 type = 1; break; 103 case '2': 104 type = 2; break; 105 case '3': 106 type = 3; break; 107 } 108 return type; 109} 110 111/* 112*/ 113#define VMAP 0 114#define VROTATE 1 115#define FONTSCOPE 2 116 117FontData 118_XomGetFontDataFromFontSet( 119 FontSet fs, 120 unsigned char *str, 121 int len, 122 int *len_ret, 123 int is2b, 124 int type) /* VMAP , VROTATE , else */ 125{ 126 unsigned long value; 127 int num,i,hit,csize; 128 FontData fontdata; 129 unsigned char *c; 130 int vfont_type; 131 132 c = str; 133 hit = -1; 134 if(type == VMAP){ 135 fontdata = fs->vmap; 136 num = fs->vmap_num; 137 } else if(type == VROTATE){ 138 fontdata = (FontData)fs->vrotate; 139 num = fs->vrotate_num; 140 } else { 141 if(fs->font_data_count <= 0 || fs->font_data == (FontData)NULL) { 142 fontdata = fs->substitute; 143 num = fs->substitute_num; 144 }else { 145 fontdata = fs->font_data; 146 num = fs->font_data_count; 147 } 148 /* CDExc20229 fix */ 149 if(fontdata == NULL || num == 0){ 150 return(NULL); 151 } 152 } 153 154 155 if(is2b){ 156 csize = 2; 157 } else { 158 csize = 1; 159 } 160 161 for(;len;len--){ 162 if(is2b){ 163 value = (((unsigned long)*c) << 8)|(unsigned long)*(c + 1); 164 } else { 165 value = (unsigned long)*c; 166 } 167 168 /* ### NOTE: This routine DOES NOT WORK! 169 * ### We can work around the problem in the calling routine, 170 * ### but we really need to understand this better. As it 171 * ### stands, the algorithm ALWAYS returns "fontdata[0]" 172 * ### for non-VW text! This is clearly wrong. In fact, 173 * ### given the new parse_font[name|data]() algorithms, 174 * ### we may not even need this routine to do anything 175 * ### for non-VW text (since font_set->font always contains 176 * ### the best font for this fontset). -- jjw/pma (HP) 177 */ 178 for (i=0;i<num;i++) { 179 if(type == VROTATE) { 180 if(fontdata[i].font) { 181 /* If the num_cr equal zero, all character is rotated. */ 182 if(fontdata[i].scopes_num == 0) { 183 break; 184 } else { 185 /* The vertical rotate glyph is not have code shift. */ 186 if (ismatch_scopes(&(fontdata[i]),&value,False)) { 187 break; 188 } 189 } 190 } 191 } else if(type == VMAP) { 192 if(fontdata[i].font) { 193 vfont_type = check_vertical_fonttype(fontdata[i].name); 194 if(vfont_type == 0 || vfont_type == 1) { 195 break; 196 } else if(vfont_type == 2 || vfont_type == 3) { 197 if(fontdata[i].scopes_num <= 0) 198 break; 199 200 if (ismatch_scopes(&(fontdata[i]),&value,True)) { 201 break; 202 } 203 } 204 } 205 } else { /* FONTSCOPE */ 206 if(fontdata[i].font) { 207 if(fontdata[i].scopes_num <= 0) 208 break; 209 if (ismatch_scopes(&(fontdata[i]),&value,True)){ 210 break; 211 } 212 } 213 } 214 } 215 if((hit != -1) && (i != hit)){ 216 break; 217 } 218 if(i == num){ 219 if( type == VROTATE || type == VMAP){ 220 /* Change 1996.01.23 start */ 221 if(fs->font_data_count <= 0 || 222 fs->font_data == (FontData)NULL) 223 fontdata = fs->substitute; 224 else 225 fontdata = fs->font_data; 226 /* Change 1996.01.23 end */ 227 } 228 hit = 0; 229 c += csize; 230 break; 231 } 232 if( hit == -1 ) hit = i; 233 if(is2b){ 234 *c = (unsigned char)(value >> 8); 235 *(c + 1) = (unsigned char)(value); 236 } else { 237 *c = (unsigned char)value; 238 } 239 c += csize; 240 } 241 *len_ret = (c - str); 242 return(&(fontdata[hit])); 243} 244/* for VW/UDC end */ 245 246static FontSet 247_XomGetFontSetFromCharSet( 248 XOC oc, 249 XlcCharSet charset) 250{ 251 register FontSet font_set = XOC_GENERIC(oc)->font_set; 252 register int num = XOC_GENERIC(oc)->font_set_num; 253 XlcCharSet *charset_list; 254 int charset_count; 255 256 for ( ; num-- > 0; font_set++) { 257 charset_count = font_set->charset_count; 258 charset_list = font_set->charset_list; 259 for ( ; charset_count-- > 0; charset_list++) 260 if (*charset_list == charset) 261 return font_set; 262 } 263 264 return (FontSet) NULL; 265} 266 267#ifdef MUSTCOPY 268static void 269cs_to_xchar2b( 270 register char *from, 271 register XChar2b *to, 272 register length) 273{ 274 while (length-- > 0) { 275 to->byte1 = *from++; 276 to->byte2 = *from++; 277 to++; 278 } 279} 280 281static void 282cs_to_xchar2b_gl( 283 register char *from, 284 register XChar2b *to, 285 register length) 286{ 287 while (length-- > 0) { 288 to->byte1 = *from++ & 0x7f; 289 to->byte2 = *from++ & 0x7f; 290 to++; 291 } 292} 293 294static void 295cs_to_xchar2b_gr( 296 register char *from, 297 register XChar2b *to, 298 register length) 299{ 300 while (length-- > 0) { 301 to->byte1 = *from++ | 0x80; 302 to->byte2 = *from++ | 0x80; 303 to++; 304 } 305} 306#endif 307 308static void 309shift_to_gl( 310 register char *text, 311 register int length) 312{ 313 while (length-- > 0) 314 *text++ &= 0x7f; 315} 316 317static void 318shift_to_gr( 319 register char *text, 320 register int length) 321{ 322 while (length-- > 0) 323 *text++ |= 0x80; 324} 325 326static Bool 327load_font( 328 XOC oc, 329 FontSet font_set) 330{ 331 font_set->font = XLoadQueryFont(oc->core.om->core.display, 332 oc->core.font_info.font_name_list[font_set->id]); 333 if (font_set->font == NULL) 334 return False; 335 336 oc->core.font_info.font_struct_list[font_set->id] = font_set->font; 337 XFreeFontInfo(NULL, font_set->info, 1); 338 font_set->info = NULL; 339 340 if (font_set->font->min_byte1 || font_set->font->max_byte1) 341 font_set->is_xchar2b = True; 342 else 343 font_set->is_xchar2b = False; 344 345 return True; 346} 347 348int 349_XomConvert( 350 XOC oc, 351 XlcConv conv, 352 XPointer *from, 353 int *from_left, 354 XPointer *to, 355 int *to_left, 356 XPointer *args, 357 int num_args) 358{ 359 XPointer cs, lc_args[1]; 360 XlcCharSet charset; 361 int length, cs_left, ret; 362 FontSet font_set; 363#ifdef MUSTCOPY 364 XChar2b *xchar2b; 365 char *buf, buf_local[BUFSIZ]; 366#endif 367 368 cs = *to; 369 cs_left = *to_left; 370 lc_args[0] = (XPointer) &charset; 371 372 ret = _XlcConvert(conv, from, from_left, &cs, &cs_left, lc_args, 1); 373 if (ret < 0) 374 return -1; 375 376 font_set = _XomGetFontSetFromCharSet(oc, charset); 377 if (font_set == NULL) 378 return -1; 379 380 if (font_set->font == NULL && load_font(oc, font_set) == False) 381 return -1; 382 383 length = *to_left - cs_left; 384 385#ifdef MUSTCOPY 386 if (font_set->is_xchar2b) { 387 buf = (length > BUFSIZ) ? Xmalloc(length) : buf_local; 388 if (buf == NULL) 389 return -1; 390 memcpy(buf, (char *) *to, length); 391 392 xchar2b = (XChar2b *) *to; 393 length >>= 1; 394 395 if (font_set->side == charset->side) 396 cs_to_xchar2b(buf, xchar2b, length); 397 else if (font_set->side == XlcGL) 398 cs_to_xchar2b_gl(buf, xchar2b, length); 399 else if (font_set->side == XlcGR) 400 cs_to_xchar2b_gr(buf, xchar2b, length); 401 else 402 cs_to_xchar2b(buf, xchar2b, length); 403 404 if (buf != buf_local) 405 Xfree(buf); 406 407 *to = (XPointer) (xchar2b + length); 408 *to_left -= length; 409 } else 410#endif 411 { 412 if (font_set->side != charset->side) { 413 if (font_set->side == XlcGL) 414 shift_to_gl(*to, length); 415 else if (font_set->side == XlcGR) 416 shift_to_gr(*to, length); 417 } 418 419 if (font_set->is_xchar2b) 420 length >>= 1; 421 *to = cs; 422 *to_left -= length; 423 } 424 425 *((XFontStruct **) args[0]) = font_set->font; 426 *((Bool *) args[1]) = font_set->is_xchar2b; 427 if(num_args >= 3){ 428 *((FontSet *) args[2]) = font_set; 429 } 430 431 return ret; 432} 433 434XlcConv 435_XomInitConverter( 436 XOC oc, 437 XOMTextType type) 438{ 439 XOCGenericPart *gen = XOC_GENERIC(oc); 440 XlcConv *convp; 441 const char *conv_type; 442 XlcConv conv; 443 XLCd lcd; 444 445 switch (type) { 446 case XOMWideChar: 447 convp = &gen->wcs_to_cs; 448 conv_type = XlcNWideChar; 449 break; 450 case XOMMultiByte: 451 convp = &gen->mbs_to_cs; 452 conv_type = XlcNMultiByte; 453 break; 454 case XOMUtf8String: 455 convp = &gen->utf8_to_cs; 456 conv_type = XlcNUtf8String; 457 break; 458 default: 459 return (XlcConv) NULL; 460 } 461 462 conv = *convp; 463 if (conv) { 464 _XlcResetConverter(conv); 465 return conv; 466 } 467 468 lcd = oc->core.om->core.lcd; 469 470 conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNFontCharSet); 471 if (conv == (XlcConv) NULL) { 472 conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNCharSet); 473 if (conv == (XlcConv) NULL) 474 return (XlcConv) NULL; 475 } 476 477 *convp = conv; 478 return conv; 479} 480