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