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