Blame src/TextExt.c

Packit 5bd3a9
/*
Packit 5bd3a9
Packit 5bd3a9
Copyright 1989, 1998  The Open Group
Packit 5bd3a9
Packit 5bd3a9
Permission to use, copy, modify, distribute, and sell this software and its
Packit 5bd3a9
documentation for any purpose is hereby granted without fee, provided that
Packit 5bd3a9
the above copyright notice appear in all copies and that both that
Packit 5bd3a9
copyright notice and this permission notice appear in supporting
Packit 5bd3a9
documentation.
Packit 5bd3a9
Packit 5bd3a9
The above copyright notice and this permission notice shall be included
Packit 5bd3a9
in all copies or substantial portions of the Software.
Packit 5bd3a9
Packit 5bd3a9
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Packit 5bd3a9
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 5bd3a9
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Packit 5bd3a9
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
Packit 5bd3a9
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Packit 5bd3a9
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Packit 5bd3a9
OTHER DEALINGS IN THE SOFTWARE.
Packit 5bd3a9
Packit 5bd3a9
Except as contained in this notice, the name of The Open Group shall
Packit 5bd3a9
not be used in advertising or otherwise to promote the sale, use or
Packit 5bd3a9
other dealings in this Software without prior written authorization
Packit 5bd3a9
from The Open Group.
Packit 5bd3a9
Packit 5bd3a9
*/
Packit 5bd3a9
/*
Packit 5bd3a9
 * Copyright 1995 by FUJITSU LIMITED
Packit 5bd3a9
 * This is source code modified by FUJITSU LIMITED under the Joint
Packit 5bd3a9
 * Development Agreement for the CDE/Motif PST.
Packit 5bd3a9
 */
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
#ifdef HAVE_CONFIG_H
Packit 5bd3a9
#include <config.h>
Packit 5bd3a9
#endif
Packit 5bd3a9
#include "Xlibint.h"
Packit 5bd3a9
Packit 5bd3a9
#define min_byte2 min_char_or_byte2
Packit 5bd3a9
#define max_byte2 max_char_or_byte2
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
 * CI_GET_ROWZERO_CHAR_INFO_2D - do the same thing as CI_GET_CHAR_INFO_1D,
Packit 5bd3a9
 * except that the font has more than one row.  This is special case of more
Packit 5bd3a9
 * general version used in XTextExt16.c since row == 0.  This is used when
Packit 5bd3a9
 * max_byte2 is not zero.  A further optimization would do the check for
Packit 5bd3a9
 * min_byte1 being zero ahead of time.
Packit 5bd3a9
 */
Packit 5bd3a9
Packit 5bd3a9
#define CI_GET_ROWZERO_CHAR_INFO_2D(fs,col,def,cs) \
Packit 5bd3a9
{ \
Packit 5bd3a9
    cs = def; \
Packit 5bd3a9
    if (fs->min_byte1 == 0 && \
Packit 5bd3a9
	col >= fs->min_byte2 && col <= fs->max_byte2) { \
Packit 5bd3a9
	if (fs->per_char == NULL) { \
Packit 5bd3a9
	    cs = &fs->min_bounds; \
Packit 5bd3a9
	} else { \
Packit 5bd3a9
	    cs = &fs->per_char[(col - fs->min_byte2)]; \
Packit 5bd3a9
	    if (CI_NONEXISTCHAR(cs)) cs = def; \
Packit 5bd3a9
	} \
Packit 5bd3a9
    } \
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
 * XTextExtents - compute the extents of string given as a sequences of eight
Packit 5bd3a9
 * bit bytes.  Since we know that the input characters will always be from the
Packit 5bd3a9
 * first row of the font (i.e. byte1 == 0), we can do some optimizations beyond
Packit 5bd3a9
 * what is done in XTextExtents16.
Packit 5bd3a9
 */
Packit 5bd3a9
int
Packit 5bd3a9
XTextExtents (
Packit 5bd3a9
    XFontStruct *fs,
Packit 5bd3a9
    _Xconst char *string,
Packit 5bd3a9
    int nchars,
Packit 5bd3a9
    int *dir,           /* RETURN font information */
Packit 5bd3a9
    int *font_ascent,   /* RETURN font information */
Packit 5bd3a9
    int *font_descent,  /* RETURN font information */
Packit 5bd3a9
    register XCharStruct *overall)	/* RETURN character information */
Packit 5bd3a9
{
Packit 5bd3a9
    int i;				/* iterator */
Packit 5bd3a9
    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
Packit 5bd3a9
    int nfound = 0;			/* number of characters found */
Packit 5bd3a9
    XCharStruct *def;			/* info about default char */
Packit 5bd3a9
    unsigned char *us;  		/* be 8bit clean */
Packit 5bd3a9
Packit 5bd3a9
    if (singlerow) {			/* optimization */
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_1D (fs, def);
Packit 5bd3a9
    } else {
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_2D (fs, def);
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    *dir = fs->direction;
Packit 5bd3a9
    *font_ascent = fs->ascent;
Packit 5bd3a9
    *font_descent = fs->descent;
Packit 5bd3a9
Packit 5bd3a9
    /*
Packit 5bd3a9
     * Iterate over the input string getting the appropriate * char struct.
Packit 5bd3a9
     * The default (which may be null if there is no def_char) will be returned
Packit 5bd3a9
     * if the character doesn't exist.  On the first time * through the loop,
Packit 5bd3a9
     * assign the values to overall; otherwise, compute * the new values.
Packit 5bd3a9
     */
Packit 5bd3a9
Packit 5bd3a9
    for (i = 0, us = (unsigned char *) string; i < nchars; i++, us++) {
Packit 5bd3a9
	register unsigned uc = (unsigned) *us;	/* since about to do macro */
Packit 5bd3a9
	register XCharStruct *cs;
Packit 5bd3a9
Packit 5bd3a9
	if (singlerow) {		/* optimization */
Packit 5bd3a9
	    CI_GET_CHAR_INFO_1D (fs, uc, def, cs);
Packit 5bd3a9
	} else {
Packit 5bd3a9
	    CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs);
Packit 5bd3a9
	}
Packit 5bd3a9
Packit 5bd3a9
	if (cs) {
Packit 5bd3a9
	    if (nfound++ == 0) {
Packit 5bd3a9
		*overall = *cs;
Packit 5bd3a9
	    } else {
Packit 5bd3a9
		overall->ascent = max (overall->ascent, cs->ascent);
Packit 5bd3a9
		overall->descent = max (overall->descent, cs->descent);
Packit 5bd3a9
		overall->lbearing = min (overall->lbearing,
Packit 5bd3a9
					 overall->width + cs->lbearing);
Packit 5bd3a9
		overall->rbearing = max (overall->rbearing,
Packit 5bd3a9
					 overall->width + cs->rbearing);
Packit 5bd3a9
		overall->width += cs->width;
Packit 5bd3a9
	    }
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    /*
Packit 5bd3a9
     * if there were no characters, then set everything to 0
Packit 5bd3a9
     */
Packit 5bd3a9
    if (nfound == 0) {
Packit 5bd3a9
	overall->width = overall->ascent = overall->descent =
Packit 5bd3a9
	  overall->lbearing = overall->rbearing = 0;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    return 0;
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
 * XTextWidth - compute the width of a string of eightbit bytes.  This is a
Packit 5bd3a9
 * subset of XTextExtents.
Packit 5bd3a9
 */
Packit 5bd3a9
int
Packit 5bd3a9
XTextWidth (
Packit 5bd3a9
    XFontStruct *fs,
Packit 5bd3a9
    _Xconst char *string,
Packit 5bd3a9
    int count)
Packit 5bd3a9
{
Packit 5bd3a9
    int i;				/* iterator */
Packit 5bd3a9
    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
Packit 5bd3a9
    XCharStruct *def;			/* info about default char */
Packit 5bd3a9
    unsigned char *us;  		/* be 8bit clean */
Packit 5bd3a9
    int width = 0;			/* RETURN value */
Packit 5bd3a9
Packit 5bd3a9
    if (singlerow) {			/* optimization */
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_1D (fs, def);
Packit 5bd3a9
    } else {
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_2D (fs, def);
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    if (def && fs->min_bounds.width == fs->max_bounds.width)
Packit 5bd3a9
	return (fs->min_bounds.width * count);
Packit 5bd3a9
Packit 5bd3a9
    /*
Packit 5bd3a9
     * Iterate over all character in the input string; only consider characters
Packit 5bd3a9
     * that exist.
Packit 5bd3a9
     */
Packit 5bd3a9
    for (i = 0, us = (unsigned char *) string; i < count; i++, us++) {
Packit 5bd3a9
	register unsigned uc = (unsigned) *us;	/* since about to do macro */
Packit 5bd3a9
	register XCharStruct *cs;
Packit 5bd3a9
Packit 5bd3a9
	if (singlerow) {		/* optimization */
Packit 5bd3a9
	    CI_GET_CHAR_INFO_1D (fs, uc, def, cs);
Packit 5bd3a9
	} else {
Packit 5bd3a9
	    CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs);
Packit 5bd3a9
	}
Packit 5bd3a9
Packit 5bd3a9
	if (cs) width += cs->width;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    return width;
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
 * _XTextHeight - compute the height of a string of eightbit bytes.
Packit 5bd3a9
 */
Packit 5bd3a9
int
Packit 5bd3a9
_XTextHeight (
Packit 5bd3a9
    XFontStruct *fs,
Packit 5bd3a9
    _Xconst char *string,
Packit 5bd3a9
    int count)
Packit 5bd3a9
{
Packit 5bd3a9
    int i;				/* iterator */
Packit 5bd3a9
    Bool singlerow = (fs->max_byte1 == 0);  /* optimization */
Packit 5bd3a9
    XCharStruct *def;			/* info about default char */
Packit 5bd3a9
    unsigned char *us;  		/* be 8bit clean */
Packit 5bd3a9
    int height = 0;			/* RETURN value */
Packit 5bd3a9
Packit 5bd3a9
    if (singlerow) {			/* optimization */
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_1D (fs, def);
Packit 5bd3a9
    } else {
Packit 5bd3a9
	CI_GET_DEFAULT_INFO_2D (fs, def);
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    if (def && (fs->min_bounds.ascent == fs->max_bounds.ascent)
Packit 5bd3a9
	    && (fs->min_bounds.descent == fs->max_bounds.descent))
Packit 5bd3a9
	return ((fs->min_bounds.ascent + fs->min_bounds.descent) * count);
Packit 5bd3a9
Packit 5bd3a9
    /*
Packit 5bd3a9
     * Iterate over all character in the input string; only consider characters
Packit 5bd3a9
     * that exist.
Packit 5bd3a9
     */
Packit 5bd3a9
    for (i = 0, us = (unsigned char *) string; i < count; i++, us++) {
Packit 5bd3a9
	register unsigned uc = (unsigned) *us;	/* since about to do macro */
Packit 5bd3a9
	register XCharStruct *cs;
Packit 5bd3a9
Packit 5bd3a9
	if (singlerow) {		/* optimization */
Packit 5bd3a9
	    CI_GET_CHAR_INFO_1D (fs, uc, def, cs);
Packit 5bd3a9
	} else {
Packit 5bd3a9
	    CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs);
Packit 5bd3a9
	}
Packit 5bd3a9
Packit 5bd3a9
	if (cs) height += (cs->ascent + cs->descent);
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    return height;
Packit 5bd3a9
}
Packit 5bd3a9