11ab64890Smrg/* 21ab64890Smrg * Copyright 1992, 1993 by TOSHIBA Corp. 31ab64890Smrg * 41ab64890Smrg * Permission to use, copy, modify, and distribute this software and its 51ab64890Smrg * documentation for any purpose and without fee is hereby granted, provided 61ab64890Smrg * that the above copyright notice appear in all copies and that both that 71ab64890Smrg * copyright notice and this permission notice appear in supporting 81ab64890Smrg * documentation, and that the name of TOSHIBA not be used in advertising 91ab64890Smrg * or publicity pertaining to distribution of the software without specific, 101ab64890Smrg * written prior permission. TOSHIBA make no representations about the 111ab64890Smrg * suitability of this software for any purpose. It is provided "as is" 121ab64890Smrg * without express or implied warranty. 131ab64890Smrg * 141ab64890Smrg * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 151ab64890Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 161ab64890Smrg * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 171ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 181ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 191ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 201ab64890Smrg * SOFTWARE. 211ab64890Smrg * 221ab64890Smrg * Author: Katsuhisa Yano TOSHIBA Corp. 231ab64890Smrg * mopi@osa.ilab.toshiba.co.jp 241ab64890Smrg */ 251ab64890Smrg/* 261ab64890Smrg * (c) Copyright 1995 FUJITSU LIMITED 271ab64890Smrg * This is source code modified by FUJITSU LIMITED under the Joint 281ab64890Smrg * Development Agreement for the CDE/Motif PST. 291ab64890Smrg */ 301ab64890Smrg 311ab64890Smrg#ifdef HAVE_CONFIG_H 321ab64890Smrg#include <config.h> 331ab64890Smrg#endif 341ab64890Smrg#include "Xlibint.h" 351ab64890Smrg#include "XomGeneric.h" 361ab64890Smrg#include <X11/Xos.h> 371ab64890Smrg#include <X11/Xatom.h> 381ab64890Smrg#include <stdio.h> 391ab64890Smrg 401ab64890Smrg#define DefineLocalBuf char local_buf[BUFSIZ] 411ab64890Smrg#define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf) 421ab64890Smrg#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) 431ab64890Smrg 441ab64890Smrgstatic Bool 451ab64890Smrgwcs_to_mbs( 461ab64890Smrg XOC oc, 471ab64890Smrg char *to, 481ab64890Smrg _Xconst wchar_t *from, 491ab64890Smrg int length) 501ab64890Smrg{ 511ab64890Smrg XlcConv conv; 521ab64890Smrg int to_left, ret; 531ab64890Smrg 541ab64890Smrg conv = _XomInitConverter(oc, XOMWideChar); 551ab64890Smrg if (conv == NULL) 561ab64890Smrg return False; 571ab64890Smrg 581ab64890Smrg to_left = length; 591ab64890Smrg ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, 601ab64890Smrg &to_left, NULL, 0); 611ab64890Smrg if (ret != 0 || length > 0) 621ab64890Smrg return False; 631ab64890Smrg 641ab64890Smrg return True; 651ab64890Smrg} 661ab64890Smrg 671ab64890Smrgstatic Bool 681ab64890Smrgutf8_to_mbs( 691ab64890Smrg XOC oc, 701ab64890Smrg char *to, 711ab64890Smrg _Xconst char *from, 721ab64890Smrg int length) 731ab64890Smrg{ 741ab64890Smrg XlcConv conv; 751ab64890Smrg int to_left, ret; 761ab64890Smrg 771ab64890Smrg conv = _XomInitConverter(oc, XOMUtf8String); 781ab64890Smrg if (conv == NULL) 791ab64890Smrg return False; 801ab64890Smrg 811ab64890Smrg to_left = length; 821ab64890Smrg ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, 831ab64890Smrg &to_left, NULL, 0); 841ab64890Smrg if (ret != 0 || length > 0) 851ab64890Smrg return False; 861ab64890Smrg 871ab64890Smrg return True; 881ab64890Smrg} 891ab64890Smrg 901ab64890Smrgint 911ab64890Smrg_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) 921ab64890Smrg{ 931ab64890Smrg return XTextWidth(*oc->core.font_info.font_struct_list, text, length); 941ab64890Smrg} 951ab64890Smrg 961ab64890Smrgint 971ab64890Smrg_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) 981ab64890Smrg{ 991ab64890Smrg DefineLocalBuf; 1001ab64890Smrg char *buf = AllocLocalBuf(length); 1011ab64890Smrg int ret; 1021ab64890Smrg 1031ab64890Smrg if (buf == NULL) 1041ab64890Smrg return 0; 1051ab64890Smrg 1061ab64890Smrg if (wcs_to_mbs(oc, buf, text, length) == False) { 1071ab64890Smrg ret = 0; 1081ab64890Smrg goto err; 1091ab64890Smrg } 1101ab64890Smrg 1111ab64890Smrg ret = _XmbDefaultTextEscapement(oc, buf, length); 1121ab64890Smrg 1131ab64890Smrgerr: 1141ab64890Smrg FreeLocalBuf(buf); 1151ab64890Smrg 1161ab64890Smrg return ret; 1171ab64890Smrg} 1181ab64890Smrg 1191ab64890Smrgint 1201ab64890Smrg_Xutf8DefaultTextEscapement(XOC oc, _Xconst char *text, int length) 1211ab64890Smrg{ 1221ab64890Smrg DefineLocalBuf; 1231ab64890Smrg char *buf = AllocLocalBuf(length); 1241ab64890Smrg int ret; 1251ab64890Smrg 1261ab64890Smrg if (buf == NULL) 1271ab64890Smrg return 0; 1281ab64890Smrg 1291ab64890Smrg if (utf8_to_mbs(oc, buf, text, length) == False) { 1301ab64890Smrg ret = 0; 1311ab64890Smrg goto err; 1321ab64890Smrg } 1331ab64890Smrg 1341ab64890Smrg ret = _XmbDefaultTextEscapement(oc, buf, length); 1351ab64890Smrg 1361ab64890Smrgerr: 1371ab64890Smrg FreeLocalBuf(buf); 1381ab64890Smrg 1391ab64890Smrg return ret; 1401ab64890Smrg} 1411ab64890Smrg 1421ab64890Smrgint 1431ab64890Smrg_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, 1441ab64890Smrg XRectangle *overall_ink, XRectangle *overall_logical) 1451ab64890Smrg{ 1461ab64890Smrg int direction, logical_ascent, logical_descent; 1471ab64890Smrg XCharStruct overall; 1481ab64890Smrg 1491ab64890Smrg XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, 1501ab64890Smrg &logical_ascent, &logical_descent, &overall); 1511ab64890Smrg 1521ab64890Smrg if (overall_ink) { 1531ab64890Smrg overall_ink->x = overall.lbearing; 1541ab64890Smrg overall_ink->y = -(overall.ascent); 1551ab64890Smrg overall_ink->width = overall.rbearing - overall.lbearing; 1561ab64890Smrg overall_ink->height = overall.ascent + overall.descent; 1571ab64890Smrg } 1581ab64890Smrg 1591ab64890Smrg if (overall_logical) { 1601ab64890Smrg overall_logical->x = 0; 1611ab64890Smrg overall_logical->y = -(logical_ascent); 1621ab64890Smrg overall_logical->width = overall.width; 1631ab64890Smrg overall_logical->height = logical_ascent + logical_descent; 1641ab64890Smrg } 1651ab64890Smrg 1661ab64890Smrg return overall.width; 1671ab64890Smrg} 1681ab64890Smrg 1691ab64890Smrgint 1701ab64890Smrg_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, 1711ab64890Smrg XRectangle *overall_ink, XRectangle *overall_logical) 1721ab64890Smrg{ 1731ab64890Smrg DefineLocalBuf; 1741ab64890Smrg char *buf = AllocLocalBuf(length); 1751ab64890Smrg int ret; 1761ab64890Smrg 1771ab64890Smrg if (buf == NULL) 1781ab64890Smrg return 0; 1791ab64890Smrg 1801ab64890Smrg if (wcs_to_mbs(oc, buf, text, length) == False) { 1811ab64890Smrg ret = 0; 1821ab64890Smrg goto err; 1831ab64890Smrg } 1841ab64890Smrg 1851ab64890Smrg ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); 1861ab64890Smrg 1871ab64890Smrgerr: 1881ab64890Smrg FreeLocalBuf(buf); 1891ab64890Smrg 1901ab64890Smrg return ret; 1911ab64890Smrg} 1921ab64890Smrg 1931ab64890Smrgint 1941ab64890Smrg_Xutf8DefaultTextExtents(XOC oc, _Xconst char *text, int length, 1951ab64890Smrg XRectangle *overall_ink, XRectangle *overall_logical) 1961ab64890Smrg{ 1971ab64890Smrg DefineLocalBuf; 1981ab64890Smrg char *buf = AllocLocalBuf(length); 1991ab64890Smrg int ret; 2001ab64890Smrg 2011ab64890Smrg if (buf == NULL) 2021ab64890Smrg return 0; 2031ab64890Smrg 2041ab64890Smrg if (utf8_to_mbs(oc, buf, text, length) == False) { 2051ab64890Smrg ret = 0; 2061ab64890Smrg goto err; 2071ab64890Smrg } 2081ab64890Smrg 2091ab64890Smrg ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); 2101ab64890Smrg 2111ab64890Smrgerr: 2121ab64890Smrg FreeLocalBuf(buf); 2131ab64890Smrg 2141ab64890Smrg return ret; 2151ab64890Smrg} 2161ab64890Smrg 2171ab64890SmrgStatus 2181ab64890Smrg_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, 2191ab64890Smrg XRectangle *ink_buf, XRectangle *logical_buf, 2201ab64890Smrg int buf_size, int *num_chars, 2211ab64890Smrg XRectangle *overall_ink, 2221ab64890Smrg XRectangle *overall_logical) 2231ab64890Smrg{ 2241ab64890Smrg XFontStruct *font = *oc->core.font_info.font_struct_list; 2251ab64890Smrg XCharStruct *def, *cs, overall; 2261ab64890Smrg Bool first = True; 2271ab64890Smrg 2281ab64890Smrg if (buf_size < length) 2291ab64890Smrg return 0; 2301ab64890Smrg 2311ab64890Smrg bzero((char *) &overall, sizeof(XCharStruct)); 2321ab64890Smrg *num_chars = 0; 2331ab64890Smrg 23407fb9b8fSmrg CI_GET_DEFAULT_INFO_1D(font, def); 2351ab64890Smrg 2361ab64890Smrg while (length-- > 0) { 23707fb9b8fSmrg CI_GET_CHAR_INFO_1D(font, *text, def, cs); 2381ab64890Smrg text++; 2391ab64890Smrg if (cs == NULL) 2401ab64890Smrg continue; 2411ab64890Smrg 2421ab64890Smrg ink_buf->x = overall.width + cs->lbearing; 2431ab64890Smrg ink_buf->y = -(cs->ascent); 2441ab64890Smrg ink_buf->width = cs->rbearing - cs->lbearing; 2451ab64890Smrg ink_buf->height = cs->ascent + cs->descent; 2461ab64890Smrg ink_buf++; 2471ab64890Smrg 2481ab64890Smrg logical_buf->x = overall.width; 2491ab64890Smrg logical_buf->y = -(font->ascent); 2501ab64890Smrg logical_buf->width = cs->width; 2511ab64890Smrg logical_buf->height = font->ascent + font->descent; 2521ab64890Smrg logical_buf++; 2531ab64890Smrg 2541ab64890Smrg if (first) { 2551ab64890Smrg overall = *cs; 2561ab64890Smrg first = False; 2571ab64890Smrg } else { 2581ab64890Smrg overall.ascent = max(overall.ascent, cs->ascent); 2591ab64890Smrg overall.descent = max(overall.descent, cs->descent); 2601ab64890Smrg overall.lbearing = min(overall.lbearing, overall.width + 2611ab64890Smrg cs->lbearing); 2621ab64890Smrg overall.rbearing = max(overall.rbearing, overall.width + 2631ab64890Smrg cs->rbearing); 2641ab64890Smrg overall.width += cs->width; 2651ab64890Smrg } 2661ab64890Smrg 2671ab64890Smrg (*num_chars)++; 2681ab64890Smrg } 2691ab64890Smrg 2701ab64890Smrg if (overall_ink) { 2711ab64890Smrg overall_ink->x = overall.lbearing; 2721ab64890Smrg overall_ink->y = -(overall.ascent); 2731ab64890Smrg overall_ink->width = overall.rbearing - overall.lbearing; 2741ab64890Smrg overall_ink->height = overall.ascent + overall.descent; 2751ab64890Smrg } 2761ab64890Smrg 2771ab64890Smrg if (overall_logical) { 2781ab64890Smrg overall_logical->x = 0; 2791ab64890Smrg overall_logical->y = -(font->ascent); 2801ab64890Smrg overall_logical->width = overall.width; 2811ab64890Smrg overall_logical->height = font->ascent + font->descent; 2821ab64890Smrg } 2831ab64890Smrg 2841ab64890Smrg return 1; 2851ab64890Smrg} 2861ab64890Smrg 2871ab64890SmrgStatus 2881ab64890Smrg_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, 2891ab64890Smrg XRectangle *ink_buf, XRectangle *logical_buf, 2901ab64890Smrg int buf_size, int *num_chars, 2911ab64890Smrg XRectangle *overall_ink, 2921ab64890Smrg XRectangle *overall_logical) 2931ab64890Smrg{ 2941ab64890Smrg DefineLocalBuf; 2951ab64890Smrg char *buf = AllocLocalBuf(length); 2961ab64890Smrg Status ret; 2971ab64890Smrg 2981ab64890Smrg if (buf == NULL) 2991ab64890Smrg return 0; 3001ab64890Smrg 3011ab64890Smrg if (wcs_to_mbs(oc, buf, text, length) == False) { 3021ab64890Smrg ret = 0; 3031ab64890Smrg goto err; 3041ab64890Smrg } 3051ab64890Smrg 3061ab64890Smrg ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, 3071ab64890Smrg buf_size, num_chars, overall_ink, 3081ab64890Smrg overall_logical); 3091ab64890Smrg 3101ab64890Smrgerr: 3111ab64890Smrg FreeLocalBuf(buf); 3121ab64890Smrg 3131ab64890Smrg return ret; 3141ab64890Smrg} 3151ab64890Smrg 3161ab64890SmrgStatus 3171ab64890Smrg_Xutf8DefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, 3181ab64890Smrg XRectangle *ink_buf, XRectangle *logical_buf, 3191ab64890Smrg int buf_size, int *num_chars, 3201ab64890Smrg XRectangle *overall_ink, 3211ab64890Smrg XRectangle *overall_logical) 3221ab64890Smrg{ 3231ab64890Smrg DefineLocalBuf; 3241ab64890Smrg char *buf = AllocLocalBuf(length); 3251ab64890Smrg Status ret; 3261ab64890Smrg 3271ab64890Smrg if (buf == NULL) 3281ab64890Smrg return 0; 3291ab64890Smrg 3301ab64890Smrg if (utf8_to_mbs(oc, buf, text, length) == False) { 3311ab64890Smrg ret = 0; 3321ab64890Smrg goto err; 3331ab64890Smrg } 3341ab64890Smrg 3351ab64890Smrg ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, 3361ab64890Smrg buf_size, num_chars, overall_ink, 3371ab64890Smrg overall_logical); 3381ab64890Smrg 3391ab64890Smrgerr: 3401ab64890Smrg FreeLocalBuf(buf); 3411ab64890Smrg 3421ab64890Smrg return ret; 3431ab64890Smrg} 3441ab64890Smrg 3451ab64890Smrgint 3461ab64890Smrg_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 3471ab64890Smrg _Xconst char *text, int length) 3481ab64890Smrg{ 3491ab64890Smrg XFontStruct *font = *oc->core.font_info.font_struct_list; 3501ab64890Smrg 3511ab64890Smrg XSetFont(dpy, gc, font->fid); 3521ab64890Smrg XDrawString(dpy, d, gc, x, y, text, length); 3531ab64890Smrg 3541ab64890Smrg return XTextWidth(font, text, length); 3551ab64890Smrg} 3561ab64890Smrg 3571ab64890Smrgint 3581ab64890Smrg_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 3591ab64890Smrg _Xconst wchar_t *text, int length) 3601ab64890Smrg{ 3611ab64890Smrg DefineLocalBuf; 3621ab64890Smrg char *buf = AllocLocalBuf(length); 3631ab64890Smrg int ret; 3641ab64890Smrg 3651ab64890Smrg if (buf == NULL) 3661ab64890Smrg return 0; 3671ab64890Smrg 3681ab64890Smrg if (wcs_to_mbs(oc, buf, text, length) == False) { 3691ab64890Smrg ret = 0; 3701ab64890Smrg goto err; 3711ab64890Smrg } 3721ab64890Smrg 3731ab64890Smrg ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); 3741ab64890Smrg 3751ab64890Smrgerr: 3761ab64890Smrg FreeLocalBuf(buf); 3771ab64890Smrg 3781ab64890Smrg return ret; 3791ab64890Smrg} 3801ab64890Smrg 3811ab64890Smrgint 3821ab64890Smrg_Xutf8DefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 3831ab64890Smrg _Xconst char *text, int length) 3841ab64890Smrg{ 3851ab64890Smrg DefineLocalBuf; 3861ab64890Smrg char *buf = AllocLocalBuf(length); 3871ab64890Smrg int ret; 3881ab64890Smrg 3891ab64890Smrg if (buf == NULL) 3901ab64890Smrg return 0; 3911ab64890Smrg 3921ab64890Smrg if (utf8_to_mbs(oc, buf, text, length) == False) { 3931ab64890Smrg ret = 0; 3941ab64890Smrg goto err; 3951ab64890Smrg } 3961ab64890Smrg 3971ab64890Smrg ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); 3981ab64890Smrg 3991ab64890Smrgerr: 4001ab64890Smrg FreeLocalBuf(buf); 4011ab64890Smrg 4021ab64890Smrg return ret; 4031ab64890Smrg} 4041ab64890Smrg 4051ab64890Smrgvoid 4061ab64890Smrg_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 4071ab64890Smrg int y, _Xconst char *text, int length) 4081ab64890Smrg{ 4091ab64890Smrg XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); 4101ab64890Smrg XDrawImageString(dpy, d, gc, x, y, text, length); 4111ab64890Smrg} 4121ab64890Smrg 4131ab64890Smrgvoid 4141ab64890Smrg_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 4151ab64890Smrg int y, _Xconst wchar_t *text, int length) 4161ab64890Smrg{ 4171ab64890Smrg DefineLocalBuf; 4181ab64890Smrg char *buf = AllocLocalBuf(length); 4191ab64890Smrg 4201ab64890Smrg if (buf == NULL) 4211ab64890Smrg return; 4221ab64890Smrg 4231ab64890Smrg if (wcs_to_mbs(oc, buf, text, length) == False) 4241ab64890Smrg goto err; 4251ab64890Smrg 4261ab64890Smrg _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); 4271ab64890Smrg 4281ab64890Smrgerr: 4291ab64890Smrg FreeLocalBuf(buf); 4301ab64890Smrg} 4311ab64890Smrg 4321ab64890Smrgvoid 4331ab64890Smrg_Xutf8DefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 4341ab64890Smrg int y, _Xconst char *text, int length) 4351ab64890Smrg{ 4361ab64890Smrg DefineLocalBuf; 4371ab64890Smrg char *buf = AllocLocalBuf(length); 4381ab64890Smrg 4391ab64890Smrg if (buf == NULL) 4401ab64890Smrg return; 4411ab64890Smrg 4421ab64890Smrg if (utf8_to_mbs(oc, buf, text, length) == False) 4431ab64890Smrg goto err; 4441ab64890Smrg 4451ab64890Smrg _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); 4461ab64890Smrg 4471ab64890Smrgerr: 4481ab64890Smrg FreeLocalBuf(buf); 4491ab64890Smrg} 450