omDefault.c revision 07fb9b8f
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 *  (c) Copyright 1995 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#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34#include "Xlibint.h"
35#include "XomGeneric.h"
36#include <X11/Xos.h>
37#include <X11/Xatom.h>
38#include <stdio.h>
39
40#define DefineLocalBuf		char local_buf[BUFSIZ]
41#define AllocLocalBuf(length)	(length > BUFSIZ ? (char *)Xmalloc(length) : local_buf)
42#define FreeLocalBuf(ptr)	if (ptr != local_buf) Xfree(ptr)
43
44static Bool
45wcs_to_mbs(
46    XOC oc,
47    char *to,
48    _Xconst wchar_t *from,
49    int length)
50{
51    XlcConv conv;
52    int to_left, ret;
53
54    conv = _XomInitConverter(oc, XOMWideChar);
55    if (conv == NULL)
56	return False;
57
58    to_left = length;
59    ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
60		      &to_left, NULL, 0);
61    if (ret != 0 || length > 0)
62	return False;
63
64    return True;
65}
66
67static Bool
68utf8_to_mbs(
69    XOC oc,
70    char *to,
71    _Xconst char *from,
72    int length)
73{
74    XlcConv conv;
75    int to_left, ret;
76
77    conv = _XomInitConverter(oc, XOMUtf8String);
78    if (conv == NULL)
79	return False;
80
81    to_left = length;
82    ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
83		      &to_left, NULL, 0);
84    if (ret != 0 || length > 0)
85	return False;
86
87    return True;
88}
89
90int
91_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
92{
93    return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
94}
95
96int
97_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
98{
99    DefineLocalBuf;
100    char *buf = AllocLocalBuf(length);
101    int ret;
102
103    if (buf == NULL)
104	return 0;
105
106    if (wcs_to_mbs(oc, buf, text, length) == False) {
107	ret = 0;
108	goto err;
109    }
110
111    ret = _XmbDefaultTextEscapement(oc, buf, length);
112
113err:
114    FreeLocalBuf(buf);
115
116    return ret;
117}
118
119int
120_Xutf8DefaultTextEscapement(XOC oc, _Xconst char *text, int length)
121{
122    DefineLocalBuf;
123    char *buf = AllocLocalBuf(length);
124    int ret;
125
126    if (buf == NULL)
127	return 0;
128
129    if (utf8_to_mbs(oc, buf, text, length) == False) {
130	ret = 0;
131	goto err;
132    }
133
134    ret = _XmbDefaultTextEscapement(oc, buf, length);
135
136err:
137    FreeLocalBuf(buf);
138
139    return ret;
140}
141
142int
143_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
144		       XRectangle *overall_ink, XRectangle *overall_logical)
145{
146    int direction, logical_ascent, logical_descent;
147    XCharStruct overall;
148
149    XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
150		 &logical_ascent, &logical_descent, &overall);
151
152    if (overall_ink) {
153	overall_ink->x = overall.lbearing;
154	overall_ink->y = -(overall.ascent);
155	overall_ink->width = overall.rbearing - overall.lbearing;
156	overall_ink->height = overall.ascent + overall.descent;
157    }
158
159    if (overall_logical) {
160	overall_logical->x = 0;
161        overall_logical->y = -(logical_ascent);
162	overall_logical->width = overall.width;
163        overall_logical->height = logical_ascent + logical_descent;
164    }
165
166    return overall.width;
167}
168
169int
170_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
171		       XRectangle *overall_ink, XRectangle *overall_logical)
172{
173    DefineLocalBuf;
174    char *buf = AllocLocalBuf(length);
175    int ret;
176
177    if (buf == NULL)
178	return 0;
179
180    if (wcs_to_mbs(oc, buf, text, length) == False) {
181	ret = 0;
182	goto err;
183    }
184
185    ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
186
187err:
188    FreeLocalBuf(buf);
189
190    return ret;
191}
192
193int
194_Xutf8DefaultTextExtents(XOC oc, _Xconst char *text, int length,
195			 XRectangle *overall_ink, XRectangle *overall_logical)
196{
197    DefineLocalBuf;
198    char *buf = AllocLocalBuf(length);
199    int ret;
200
201    if (buf == NULL)
202	return 0;
203
204    if (utf8_to_mbs(oc, buf, text, length) == False) {
205	ret = 0;
206	goto err;
207    }
208
209    ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
210
211err:
212    FreeLocalBuf(buf);
213
214    return ret;
215}
216
217Status
218_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
219			      XRectangle *ink_buf, XRectangle *logical_buf,
220			      int buf_size, int *num_chars,
221			      XRectangle *overall_ink,
222			      XRectangle *overall_logical)
223{
224    XFontStruct *font = *oc->core.font_info.font_struct_list;
225    XCharStruct *def, *cs, overall;
226    Bool first = True;
227
228    if (buf_size < length)
229	return 0;
230
231    bzero((char *) &overall, sizeof(XCharStruct));
232    *num_chars = 0;
233
234    CI_GET_DEFAULT_INFO_1D(font, def);
235
236    while (length-- > 0) {
237	CI_GET_CHAR_INFO_1D(font, *text, def, cs);
238	text++;
239	if (cs == NULL)
240	    continue;
241
242	ink_buf->x = overall.width + cs->lbearing;
243	ink_buf->y = -(cs->ascent);
244	ink_buf->width = cs->rbearing - cs->lbearing;
245	ink_buf->height = cs->ascent + cs->descent;
246	ink_buf++;
247
248	logical_buf->x = overall.width;
249	logical_buf->y = -(font->ascent);
250	logical_buf->width = cs->width;
251	logical_buf->height = font->ascent + font->descent;
252	logical_buf++;
253
254	if (first) {
255	    overall = *cs;
256	    first = False;
257	} else {
258	    overall.ascent = max(overall.ascent, cs->ascent);
259	    overall.descent = max(overall.descent, cs->descent);
260	    overall.lbearing = min(overall.lbearing, overall.width +
261				   cs->lbearing);
262	    overall.rbearing = max(overall.rbearing, overall.width +
263				   cs->rbearing);
264	    overall.width += cs->width;
265	}
266
267	(*num_chars)++;
268    }
269
270    if (overall_ink) {
271	overall_ink->x = overall.lbearing;
272	overall_ink->y = -(overall.ascent);
273	overall_ink->width = overall.rbearing - overall.lbearing;
274	overall_ink->height = overall.ascent + overall.descent;
275    }
276
277    if (overall_logical) {
278	overall_logical->x = 0;
279	overall_logical->y = -(font->ascent);
280	overall_logical->width = overall.width;
281	overall_logical->height = font->ascent + font->descent;
282    }
283
284    return 1;
285}
286
287Status
288_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
289			      XRectangle *ink_buf, XRectangle *logical_buf,
290			      int buf_size, int *num_chars,
291			      XRectangle *overall_ink,
292			      XRectangle *overall_logical)
293{
294    DefineLocalBuf;
295    char *buf = AllocLocalBuf(length);
296    Status ret;
297
298    if (buf == NULL)
299	return 0;
300
301    if (wcs_to_mbs(oc, buf, text, length) == False) {
302	ret = 0;
303	goto err;
304    }
305
306    ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
307					buf_size, num_chars, overall_ink,
308					overall_logical);
309
310err:
311    FreeLocalBuf(buf);
312
313    return ret;
314}
315
316Status
317_Xutf8DefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
318				XRectangle *ink_buf, XRectangle *logical_buf,
319				int buf_size, int *num_chars,
320				XRectangle *overall_ink,
321				XRectangle *overall_logical)
322{
323    DefineLocalBuf;
324    char *buf = AllocLocalBuf(length);
325    Status ret;
326
327    if (buf == NULL)
328	return 0;
329
330    if (utf8_to_mbs(oc, buf, text, length) == False) {
331	ret = 0;
332	goto err;
333    }
334
335    ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
336					buf_size, num_chars, overall_ink,
337					overall_logical);
338
339err:
340    FreeLocalBuf(buf);
341
342    return ret;
343}
344
345int
346_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
347		      _Xconst char *text, int length)
348{
349    XFontStruct *font = *oc->core.font_info.font_struct_list;
350
351    XSetFont(dpy, gc, font->fid);
352    XDrawString(dpy, d, gc, x, y, text, length);
353
354    return XTextWidth(font, text, length);
355}
356
357int
358_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
359		      _Xconst wchar_t *text, int length)
360{
361    DefineLocalBuf;
362    char *buf = AllocLocalBuf(length);
363    int ret;
364
365    if (buf == NULL)
366	return 0;
367
368    if (wcs_to_mbs(oc, buf, text, length) == False) {
369	ret = 0;
370	goto err;
371    }
372
373    ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
374
375err:
376    FreeLocalBuf(buf);
377
378    return ret;
379}
380
381int
382_Xutf8DefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
383			_Xconst char *text, int length)
384{
385    DefineLocalBuf;
386    char *buf = AllocLocalBuf(length);
387    int ret;
388
389    if (buf == NULL)
390	return 0;
391
392    if (utf8_to_mbs(oc, buf, text, length) == False) {
393	ret = 0;
394	goto err;
395    }
396
397    ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
398
399err:
400    FreeLocalBuf(buf);
401
402    return ret;
403}
404
405void
406_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
407			   int y, _Xconst char *text, int length)
408{
409    XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
410    XDrawImageString(dpy, d, gc, x, y, text, length);
411}
412
413void
414_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
415			   int y, _Xconst wchar_t *text, int length)
416{
417    DefineLocalBuf;
418    char *buf = AllocLocalBuf(length);
419
420    if (buf == NULL)
421	return;
422
423    if (wcs_to_mbs(oc, buf, text, length) == False)
424	goto err;
425
426    _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
427
428err:
429    FreeLocalBuf(buf);
430}
431
432void
433_Xutf8DefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
434			     int y, _Xconst char *text, int length)
435{
436    DefineLocalBuf;
437    char *buf = AllocLocalBuf(length);
438
439    if (buf == NULL)
440	return;
441
442    if (utf8_to_mbs(oc, buf, text, length) == False)
443	goto err;
444
445    _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
446
447err:
448    FreeLocalBuf(buf);
449}
450