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#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29#include "Xlibint.h"
30#include "XomGeneric.h"
31#include <stdio.h>
32
33static Status
34_XomGenericTextPerCharExtents(
35    XOC oc,
36    XOMTextType type,
37    XPointer text,
38    int length,
39    XRectangle *ink_buf,
40    XRectangle *logical_buf,
41    int buf_size,
42    int *num_chars,
43    XRectangle *overall_ink,
44    XRectangle *overall_logical)
45{
46    XlcConv conv;
47    XFontStruct *font;
48    Bool is_xchar2b;
49    XPointer args[2];
50    XChar2b xchar2b_buf[BUFSIZ], *xchar2b_ptr;
51    char *xchar_ptr = NULL;
52    XCharStruct *def, *cs, overall;
53    int buf_len, left, require_num;
54    int logical_ascent, logical_descent;
55    Bool first = True;
56
57    conv = _XomInitConverter(oc, type);
58    if (conv == NULL)
59	return 0;
60
61    bzero((char *) &overall, sizeof(XCharStruct));
62    logical_ascent = logical_descent = require_num = *num_chars = 0;
63
64    args[0] = (XPointer) &font;
65    args[1] = (XPointer) &is_xchar2b;
66
67    while (length > 0) {
68	xchar2b_ptr = xchar2b_buf;
69	left = buf_len = BUFSIZ;
70
71	if (_XomConvert(oc, conv, (XPointer *) &text, &length,
72			(XPointer *) &xchar2b_ptr, &left, args, 2) < 0)
73	    break;
74	buf_len -= left;
75
76	if (require_num) {
77	    require_num += buf_len;
78	    continue;
79	}
80	if (buf_size < buf_len) {
81	    require_num = *num_chars + buf_len;
82	    continue;
83	}
84	buf_size -= buf_len;
85
86	if (first) {
87	    logical_ascent = font->ascent;
88	    logical_descent = font->descent;
89	} else {
90	    logical_ascent = max(logical_ascent, font->ascent);
91	    logical_descent = max(logical_descent, font->descent);
92	}
93
94	if (is_xchar2b) {
95	    CI_GET_DEFAULT_INFO_2D(font, def);
96	    xchar2b_ptr = xchar2b_buf;
97	} else {
98	    CI_GET_DEFAULT_INFO_1D(font, def);
99	    xchar_ptr = (char *) xchar2b_buf;
100	}
101
102	while (buf_len-- > 0) {
103	    if (is_xchar2b) {
104		CI_GET_CHAR_INFO_2D(font, xchar2b_ptr->byte1,
105				    xchar2b_ptr->byte2, def, cs);
106		xchar2b_ptr++;
107	    } else {
108		CI_GET_CHAR_INFO_1D(font, *xchar_ptr, def, cs);
109		xchar_ptr++;
110	    }
111	    if (cs == NULL)
112		continue;
113
114	    ink_buf->x = overall.width + cs->lbearing;
115	    ink_buf->y = -(cs->ascent);
116	    ink_buf->width = cs->rbearing - cs->lbearing;
117	    ink_buf->height = cs->ascent + cs->descent;
118	    ink_buf++;
119
120	    logical_buf->x = overall.width;
121	    logical_buf->y = -(font->ascent);
122	    logical_buf->width = cs->width;
123	    logical_buf->height = font->ascent + font->descent;
124	    logical_buf++;
125
126	    if (first) {
127		overall = *cs;
128		first = False;
129	    } else {
130		overall.ascent = max(overall.ascent, cs->ascent);
131		overall.descent = max(overall.descent, cs->descent);
132		overall.lbearing = min(overall.lbearing,
133				       overall.width + cs->lbearing);
134		overall.rbearing = max(overall.rbearing,
135				       overall.width + cs->rbearing);
136		overall.width += cs->width;
137	    }
138
139	    (*num_chars)++;
140	}
141    }
142
143    if (require_num) {
144	*num_chars = require_num;
145	return 0;
146    } else {
147	if (overall_ink) {
148	    overall_ink->x = overall.lbearing;
149	    overall_ink->y = -(overall.ascent);
150	    overall_ink->width = overall.rbearing - overall.lbearing;
151	    overall_ink->height = overall.ascent + overall.descent;
152	}
153
154	if (overall_logical) {
155	    overall_logical->x = 0;
156	    overall_logical->y = -(logical_ascent);
157	    overall_logical->width = overall.width;
158	    overall_logical->height = logical_ascent + logical_descent;
159	}
160    }
161
162    return 1;
163}
164
165Status
166_XmbGenericTextPerCharExtents(XOC oc, _Xconst char *text, int length,
167			      XRectangle *ink_buf, XRectangle *logical_buf,
168			      int buf_size, int *num_chars,
169			      XRectangle *overall_ink,
170			      XRectangle *overall_logical)
171{
172    return _XomGenericTextPerCharExtents(oc, XOMMultiByte, (XPointer) text,
173					 length, ink_buf, logical_buf, buf_size,
174					 num_chars, overall_ink,
175					 overall_logical);
176}
177
178Status
179_XwcGenericTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
180			      XRectangle *ink_buf, XRectangle *logical_buf,
181			      int buf_size, int *num_chars,
182			      XRectangle *overall_ink,
183			      XRectangle *overall_logical)
184{
185    return _XomGenericTextPerCharExtents(oc, XOMWideChar, (XPointer) text,
186					 length, ink_buf, logical_buf, buf_size,
187					 num_chars, overall_ink,
188					 overall_logical);
189}
190
191Status
192_Xutf8GenericTextPerCharExtents(XOC oc, _Xconst char *text, int length,
193				XRectangle *ink_buf, XRectangle *logical_buf,
194				int buf_size, int *num_chars,
195				XRectangle *overall_ink,
196				XRectangle *overall_logical)
197{
198    return _XomGenericTextPerCharExtents(oc, XOMUtf8String, (XPointer) text,
199					 length, ink_buf, logical_buf, buf_size,
200					 num_chars, overall_ink,
201					 overall_logical);
202}
203