1/*
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28/*
29 * Copyright 1995 by FUJITSU LIMITED
30 * This is source code modified by FUJITSU LIMITED under the Joint
31 * Development Agreement for the CDE/Motif PST.
32 */
33
34
35#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif
38#include "Xlibint.h"
39
40#define min_byte2 min_char_or_byte2
41#define max_byte2 max_char_or_byte2
42
43/*
44 * XTextExtents16 - compute the extents of string given as a sequence of
45 * XChar2bs.
46 */
47int
48XTextExtents16 (
49    XFontStruct *fs,
50    _Xconst XChar2b *string,
51    int nchars,
52    int *dir,           /* RETURN font information */
53    int *font_ascent,   /* RETURN font information */
54    int *font_descent,  /* RETURN font information */
55    register XCharStruct *overall)	/* RETURN character information */
56{
57    int i;				/* iterator */
58    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
59    int nfound = 0;			/* number of characters found */
60    XCharStruct *def;			/* info about default char */
61
62    if (singlerow) {
63	CI_GET_DEFAULT_INFO_1D (fs, def);
64    } else {
65	CI_GET_DEFAULT_INFO_2D (fs, def);
66    }
67
68    *dir = fs->direction;
69    *font_ascent = fs->ascent;
70    *font_descent = fs->descent;
71
72    /*
73     * Iterate over the input string getting the appropriate * char struct.
74     * The default (which may be null if there is no def_char) will be returned
75     * if the character doesn't exist.  On the first time * through the loop,
76     * assign the values to overall; otherwise, compute * the new values.
77     */
78
79    for (i = 0; i < nchars; i++, string++) {
80	register XCharStruct *cs;
81	unsigned int r = (unsigned int) string->byte1;	/* watch for macros */
82	unsigned int c = (unsigned int) string->byte2;	/* watch for macros */
83
84	if (singlerow) {
85	    unsigned int ind = ((r << 8) | c);		/* watch for macros */
86	    CI_GET_CHAR_INFO_1D (fs, ind, def, cs);
87	} else {
88	    CI_GET_CHAR_INFO_2D (fs, r, c, def, cs);
89	}
90
91	if (cs) {
92	    if (nfound++ == 0) {
93		*overall = *cs;
94	    } else {
95		overall->ascent = max (overall->ascent, cs->ascent);
96		overall->descent = max (overall->descent, cs->descent);
97		overall->lbearing = min (overall->lbearing,
98					 overall->width + cs->lbearing);
99		overall->rbearing = max (overall->rbearing,
100					 overall->width + cs->rbearing);
101		overall->width += cs->width;
102	    }
103	}
104    }
105
106    /*
107     * if there were no characters, then set everything to 0
108     */
109    if (nfound == 0) {
110	overall->width = overall->ascent = overall->descent =
111	  overall->lbearing = overall->rbearing = 0;
112    }
113
114    return 0;
115}
116
117
118/*
119 * XTextWidth16 - compute the width of sequence of XChar2bs.  This is a
120 * subset of XTextExtents16.
121 */
122int
123XTextWidth16 (
124    XFontStruct *fs,
125    _Xconst XChar2b *string,
126    int count)
127{
128    int i;				/* iterator */
129    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
130    XCharStruct *def;			/* info about default char */
131    int width = 0;			/* RETURN value */
132
133    if (singlerow) {
134	CI_GET_DEFAULT_INFO_1D (fs, def);
135    } else {
136	CI_GET_DEFAULT_INFO_2D (fs, def);
137    }
138
139    if (def && fs->min_bounds.width == fs->max_bounds.width)
140	return (fs->min_bounds.width * count);
141
142    /*
143     * Iterate over all character in the input string; only consider characters
144     * that exist.
145     */
146    for (i = 0; i < count; i++, string++) {
147	register XCharStruct *cs;
148	unsigned int r = (unsigned int) string->byte1;	/* watch for macros */
149	unsigned int c = (unsigned int) string->byte2;	/* watch for macros */
150
151	if (singlerow) {
152	    unsigned int ind = ((r << 8) | c);		/* watch for macros */
153	    CI_GET_CHAR_INFO_1D (fs, ind, def, cs);
154	} else {
155	    CI_GET_CHAR_INFO_2D (fs, r, c, def, cs);
156	}
157
158	if (cs) width += cs->width;
159    }
160
161    return width;
162}
163
164
165/*
166 * _XTextHeight16 - compute the height of sequence of XChar2bs.
167 */
168int
169_XTextHeight16 (
170    XFontStruct *fs,
171    _Xconst XChar2b *string,
172    int count)
173{
174    int i;				/* iterator */
175    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
176    XCharStruct *def;			/* info about default char */
177    int height = 0;			/* RETURN value */
178
179    if (singlerow) {
180	CI_GET_DEFAULT_INFO_1D (fs, def);
181    } else {
182	CI_GET_DEFAULT_INFO_2D (fs, def);
183    }
184
185    if (def && (fs->min_bounds.ascent == fs->max_bounds.ascent)
186	    && (fs->min_bounds.descent == fs->max_bounds.descent))
187	return ((fs->min_bounds.ascent + fs->min_bounds.descent) * count);
188
189    /*
190     * Iterate over all character in the input string; only consider characters
191     * that exist.
192     */
193    for (i = 0; i < count; i++, string++) {
194	register XCharStruct *cs;
195	unsigned int r = (unsigned int) string->byte1;	/* watch for macros */
196	unsigned int c = (unsigned int) string->byte2;	/* watch for macros */
197
198	if (singlerow) {
199	    unsigned int ind = ((r << 8) | c);		/* watch for macros */
200	    CI_GET_CHAR_INFO_1D (fs, ind, def, cs);
201	} else {
202	    CI_GET_CHAR_INFO_2D (fs, r, c, def, cs);
203	}
204
205	if (cs) height += (cs->ascent + cs->descent);
206    }
207
208    return height;
209}
210
211