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