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/* 31 * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD) 32 */ 33 34#ifdef HAVE_CONFIG_H 35#include <config.h> 36#endif 37#include "Xlibint.h" 38#include "XomGeneric.h" 39#include <stdio.h> 40 41/* For VW/UDC */ 42 43static int 44is_rotate( 45 XOC oc, 46 XFontStruct *font) 47{ 48 XOCGenericPart *gen = XOC_GENERIC(oc); 49 FontSet font_set; 50 VRotate vrotate; 51 int font_set_count; 52 int vrotate_num; 53 54 font_set = gen->font_set; 55 font_set_count = gen->font_set_num; 56 for( ; font_set_count-- ; font_set++) { 57 if((font_set->vrotate_num > 0) && (font_set->vrotate)) { 58 vrotate = font_set->vrotate; 59 vrotate_num = font_set->vrotate_num; 60 for( ; vrotate_num-- ; vrotate++) 61 if(vrotate->font == font) 62 return True; 63 } 64 } 65 return False; 66} 67 68static int 69is_codemap( 70 XOC oc, 71 XFontStruct *font) 72{ 73 XOCGenericPart *gen = XOC_GENERIC(oc); 74 FontSet font_set; 75 FontData vmap; 76 int font_set_count; 77 int vmap_num; 78 79 font_set = gen->font_set; 80 font_set_count = gen->font_set_num; 81 for( ; font_set_count-- ; font_set++) { 82 if(font_set->vmap_num > 0) { 83 vmap = font_set->vmap; 84 vmap_num = font_set->vmap_num; 85 for( ; vmap_num-- ; vmap++) 86 if(vmap->font == font) 87 return True; 88 } 89 } 90 return False; 91} 92 93static int 94draw_vertical( 95 Display *dpy, 96 Drawable d, 97 XOC oc, 98 GC gc, 99 XFontStruct *font, 100 Bool is_xchar2b, 101 int x, int y, 102 XPointer text, 103 int length) 104{ 105 XChar2b *buf2b; 106 char *buf; 107 int wx = 0, wy = 0; 108 int direction = 0; 109 int font_ascent_return = 0, font_descent_return = 0; 110 int i; 111 XCharStruct overall; 112 113 wy = y; 114 if (is_xchar2b) { 115 for(i = 0, buf2b = (XChar2b *) text ; i < length ; i++, buf2b++) { 116 if(is_rotate(oc, font) == True) { 117 XTextExtents16(font, buf2b, 1, 118 &direction, &font_ascent_return, 119 &font_descent_return, &overall); 120 wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) - 121 (int) overall.lbearing; 122 wy += overall.ascent; 123 XDrawString16(dpy, d, gc, wx, wy, buf2b, 1); 124 wy += overall.descent; 125 } else { 126 wx = x - (int)((font->max_bounds.rbearing - 127 font->min_bounds.lbearing) >> 1) - 128 (int) font->min_bounds.lbearing; 129 wy += font->max_bounds.ascent; 130 XDrawString16(dpy, d, gc, wx, wy, buf2b, 1); 131 wy += font->max_bounds.descent; 132 } 133 } 134 } else { 135 for(i = 0, buf = (char *)text ; i < length && *buf ; i++, buf++) { 136 if(is_rotate(oc, font) == True) { 137 XTextExtents(font, buf, 1, 138 &direction, &font_ascent_return, 139 &font_descent_return, &overall); 140 wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) - 141 (int) overall.lbearing; 142 wy += overall.ascent; 143 XDrawString(dpy, d, gc, wx, wy, buf, 1); 144 wy += overall.descent; 145 } else { 146 wx = x - (int)((font->max_bounds.rbearing - 147 font->min_bounds.lbearing) >> 1) - 148 (int) font->min_bounds.lbearing; 149 wy += font->max_bounds.ascent; 150 XDrawString(dpy, d, gc, wx, wy, buf, 1); 151 wy += font->max_bounds.descent; 152 } 153 } 154 } 155 return wy; 156} 157 158#define VMAP 0 159#define VROTATE 1 160#define FONTSCOPE 2 161 162static int 163DrawStringWithFontSet( 164 Display *dpy, 165 Drawable d, 166 XOC oc, 167 FontSet fs, 168 GC gc, 169 int x, int y, 170 XPointer text, 171 int length) 172{ 173 XFontStruct *font; 174 Bool is_xchar2b; 175 unsigned char *ptr; 176 int ptr_len, char_len = 0; 177 FontData fd; 178 int ret = 0; 179 180 ptr = (unsigned char *)text; 181 is_xchar2b = fs->is_xchar2b; 182 183 while (length > 0) { 184 fd = _XomGetFontDataFromFontSet(fs, 185 ptr,length,&ptr_len,is_xchar2b,FONTSCOPE); 186 if(ptr_len <= 0) 187 break; 188 189 /* First, see if the "Best Match" font for the FontSet was set. 190 * If it was, use that font. If it was not set, then use the 191 * font defined by font_set->font_data[0] (which is what 192 * _XomGetFontDataFromFontSet() always seems to return for 193 * non-VW text). Note that given the new algorithm in 194 * parse_fontname() and parse_fontdata(), fs->font will 195 * *always* contain good data. We should probably remove 196 * the check for "fd->font", but we won't :-) -- jjw/pma (HP) 197 */ 198 if((font = fs->font) == (XFontStruct *) NULL){ 199 200 if(fd == (FontData) NULL || 201 (font = fd->font) == (XFontStruct *) NULL) 202 break; 203 } 204 205 switch(oc->core.orientation) { 206 case XOMOrientation_LTR_TTB: 207 case XOMOrientation_RTL_TTB: 208 XSetFont(dpy, gc, font->fid); 209 210 if (is_xchar2b) { 211 char_len = ptr_len / sizeof(XChar2b); 212 XDrawString16(dpy, d, gc, x, y, (XChar2b *)ptr, char_len); 213 x += XTextWidth16(font, (XChar2b *)ptr, char_len); 214 } else { 215 char_len = ptr_len; 216 XDrawString(dpy, d, gc, x, y, (char *)ptr, char_len); 217 x += XTextWidth(font, (char *)ptr, char_len); 218 } 219 break; 220 case XOMOrientation_TTB_RTL: 221 case XOMOrientation_TTB_LTR: 222 if(fs->font == font) { 223 fd = _XomGetFontDataFromFontSet(fs, 224 ptr,length,&ptr_len,is_xchar2b,VMAP); 225 if(ptr_len <= 0) 226 break; 227 if(fd == (FontData) NULL || 228 (font = fd->font) == (XFontStruct *) NULL) 229 break; 230 231 if(is_codemap(oc, fd->font) == False) { 232 fd = _XomGetFontDataFromFontSet(fs, 233 ptr,length,&ptr_len,is_xchar2b,VROTATE); 234 if(ptr_len <= 0) 235 break; 236 if(fd == (FontData) NULL || 237 (font = fd->font) == (XFontStruct *) NULL) 238 break; 239 } 240 } 241 242 if(is_xchar2b) 243 char_len = ptr_len / sizeof(XChar2b); 244 else 245 char_len = ptr_len; 246 XSetFont(dpy, gc, font->fid); 247 y = draw_vertical(dpy, d, oc, gc, font, is_xchar2b, x, y, 248 (char *)ptr, char_len); 249 break; 250 251 case XOMOrientation_Context: 252 /* never used? */ 253 break; 254 } 255 256 if(char_len <= 0) 257 break; 258 259 length -= char_len; 260 ptr += ptr_len; 261 } 262 263 switch(oc->core.orientation) { 264 case XOMOrientation_LTR_TTB: 265 case XOMOrientation_RTL_TTB: 266 ret = x; 267 break; 268 case XOMOrientation_TTB_RTL: 269 case XOMOrientation_TTB_LTR: 270 ret = y; 271 break; 272 case XOMOrientation_Context: 273 /* not used? */ 274 break; 275 } 276 return ret; 277} 278 279/* For VW/UDC */ 280 281int 282_XomGenericDrawString( 283 Display *dpy, 284 Drawable d, 285 XOC oc, 286 GC gc, 287 int x, int y, 288 XOMTextType type, 289 XPointer text, 290 int length) 291{ 292 XlcConv conv; 293 XFontStruct *font; 294 Bool is_xchar2b; 295/* VW/UDC */ 296 XPointer args[3]; 297 FontSet fs; 298/* VW/UDC */ 299 XChar2b xchar2b_buf[BUFSIZ], *buf; 300 int start_x = x; 301 int start_y = y; 302 int left = 0, buf_len = 0; 303 int next = 0; 304 305 conv = _XomInitConverter(oc, type); 306 if (conv == NULL) 307 return -1; 308 309 args[0] = (XPointer) &font; 310 args[1] = (XPointer) &is_xchar2b; 311 args[2] = (XPointer) &fs; 312 313 while (length > 0) { 314 buf = xchar2b_buf; 315 left = buf_len = BUFSIZ; 316 317 if (_XomConvert(oc, conv, (XPointer *) &text, &length, 318 (XPointer *) &buf, &left, args, 3) < 0) 319 break; 320 buf_len -= left; 321 322/* For VW/UDC */ 323 next = DrawStringWithFontSet(dpy, d, oc, fs, gc, x, y, 324 (XPointer)xchar2b_buf, buf_len); 325 326 switch(oc->core.orientation) { 327 case XOMOrientation_LTR_TTB: 328 case XOMOrientation_RTL_TTB: 329 x = next; 330 break; 331 case XOMOrientation_TTB_RTL: 332 case XOMOrientation_TTB_LTR: 333 y = next; 334 break; 335 case XOMOrientation_Context: 336 /* not used */ 337 break; 338 } 339/* For VW/UDC */ 340 } 341 342 x -= start_x; 343 y -= start_y; 344 345 return x; 346} 347 348int 349_XmbGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 350 _Xconst char *text, int length) 351{ 352 return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMMultiByte, 353 (XPointer) text, length); 354} 355 356int 357_XwcGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 358 _Xconst wchar_t *text, int length) 359{ 360 return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMWideChar, 361 (XPointer) text, length); 362} 363 364int 365_Xutf8GenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 366 _Xconst char *text, int length) 367{ 368 return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMUtf8String, 369 (XPointer) text, length); 370} 371