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