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