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