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 
33 static Status
_XomGenericTextPerCharExtents(XOC oc,XOMTextType type,XPointer text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)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 
165 Status
_XmbGenericTextPerCharExtents(XOC oc,_Xconst char * text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)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 
178 Status
_XwcGenericTextPerCharExtents(XOC oc,_Xconst wchar_t * text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)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 
191 Status
_Xutf8GenericTextPerCharExtents(XOC oc,_Xconst char * text,int length,XRectangle * ink_buf,XRectangle * logical_buf,int buf_size,int * num_chars,XRectangle * overall_ink,XRectangle * overall_logical)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