diff options
Diffstat (limited to 'libXft/src/xftextent.c')
-rw-r--r-- | libXft/src/xftextent.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/libXft/src/xftextent.c b/libXft/src/xftextent.c new file mode 100644 index 000000000..71f5c1c13 --- /dev/null +++ b/libXft/src/xftextent.c @@ -0,0 +1,285 @@ +/* + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xftint.h" + +_X_EXPORT void +XftGlyphExtents (Display *dpy, + XftFont *pub, + _Xconst FT_UInt *glyphs, + int nglyphs, + XGlyphInfo *extents) +{ + XftFontInt *font = (XftFontInt *) pub; + FT_UInt missing[XFT_NMISSING]; + int nmissing; + int n; + _Xconst FT_UInt *g; + FT_UInt glyph; + XftGlyph *xftg; + FcBool glyphs_loaded; + int x, y; + int left, right, top, bottom; + int overall_left, overall_right; + int overall_top, overall_bottom; + + g = glyphs; + n = nglyphs; + nmissing = 0; + glyphs_loaded = FcFalse; + while (n--) + if (XftFontCheckGlyph (dpy, pub, FcFalse, *g++, missing, &nmissing)) + glyphs_loaded = FcTrue; + if (nmissing) + XftFontLoadGlyphs (dpy, pub, FcFalse, missing, nmissing); + g = glyphs; + n = nglyphs; + xftg = NULL; + while (n) + { + glyph = *g++; + n--; + if (glyph < font->num_glyphs && + (xftg = font->glyphs[glyph])) + break; + } + if (n == 0) + { + if (xftg) + *extents = xftg->metrics; + else + memset (extents, '\0', sizeof (*extents)); + } + else + { + x = 0; + y = 0; + overall_left = x - xftg->metrics.x; + overall_top = y - xftg->metrics.y; + overall_right = overall_left + (int) xftg->metrics.width; + overall_bottom = overall_top + (int) xftg->metrics.height; + x += xftg->metrics.xOff; + y += xftg->metrics.yOff; + while (n--) + { + glyph = *g++; + if (glyph < font->num_glyphs && (xftg = font->glyphs[glyph])) + { + left = x - xftg->metrics.x; + top = y - xftg->metrics.y; + right = left + (int) xftg->metrics.width; + bottom = top + (int) xftg->metrics.height; + if (left < overall_left) + overall_left = left; + if (top < overall_top) + overall_top = top; + if (right > overall_right) + overall_right = right; + if (bottom > overall_bottom) + overall_bottom = bottom; + x += xftg->metrics.xOff; + y += xftg->metrics.yOff; + } + } + extents->x = -overall_left; + extents->y = -overall_top; + extents->width = overall_right - overall_left; + extents->height = overall_bottom - overall_top; + extents->xOff = x; + extents->yOff = y; + } + if (glyphs_loaded) + _XftFontManageMemory (dpy, pub); +} + +#define NUM_LOCAL 1024 + +_X_EXPORT void +XftTextExtents8 (Display *dpy, + XftFont *pub, + _Xconst FcChar8 *string, + int len, + XGlyphInfo *extents) +{ + FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; + int i; + + if (len <= NUM_LOCAL) + glyphs = glyphs_local; + else + { + glyphs = malloc (len * sizeof (FT_UInt)); + if (!glyphs) + { + memset (extents, '\0', sizeof (XGlyphInfo)); + return; + } + } + for (i = 0; i < len; i++) + glyphs[i] = XftCharIndex (dpy, pub, string[i]); + XftGlyphExtents (dpy, pub, glyphs, len, extents); + if (glyphs != glyphs_local) + free (glyphs); +} + +_X_EXPORT void +XftTextExtents16 (Display *dpy, + XftFont *pub, + _Xconst FcChar16 *string, + int len, + XGlyphInfo *extents) +{ + FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; + int i; + + if (len <= NUM_LOCAL) + glyphs = glyphs_local; + else + { + glyphs = malloc (len * sizeof (FT_UInt)); + if (!glyphs) + { + memset (extents, '\0', sizeof (XGlyphInfo)); + return; + } + } + for (i = 0; i < len; i++) + glyphs[i] = XftCharIndex (dpy, pub, string[i]); + XftGlyphExtents (dpy, pub, glyphs, len, extents); + if (glyphs != glyphs_local) + free (glyphs); +} + +_X_EXPORT void +XftTextExtents32 (Display *dpy, + XftFont *pub, + _Xconst FcChar32 *string, + int len, + XGlyphInfo *extents) +{ + FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; + int i; + + if (len <= NUM_LOCAL) + glyphs = glyphs_local; + else + { + glyphs = malloc (len * sizeof (FT_UInt)); + if (!glyphs) + { + memset (extents, '\0', sizeof (XGlyphInfo)); + return; + } + } + for (i = 0; i < len; i++) + glyphs[i] = XftCharIndex (dpy, pub, string[i]); + XftGlyphExtents (dpy, pub, glyphs, len, extents); + if (glyphs != glyphs_local) + free (glyphs); +} + +_X_EXPORT void +XftTextExtentsUtf8 (Display *dpy, + XftFont *pub, + _Xconst FcChar8 *string, + int len, + XGlyphInfo *extents) +{ + FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; + FcChar32 ucs4; + int i; + int l; + int size; + + i = 0; + glyphs = glyphs_local; + size = NUM_LOCAL; + while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0) + { + if (i == size) + { + glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); + if (!glyphs_new) + { + if (glyphs != glyphs_local) + free (glyphs); + memset (extents, '\0', sizeof (XGlyphInfo)); + return; + } + memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); + size *= 2; + if (glyphs != glyphs_local) + free (glyphs); + glyphs = glyphs_new; + } + glyphs[i++] = XftCharIndex (dpy, pub, ucs4); + string += l; + len -= l; + } + XftGlyphExtents (dpy, pub, glyphs, i, extents); + if (glyphs != glyphs_local) + free (glyphs); +} + +_X_EXPORT void +XftTextExtentsUtf16 (Display *dpy, + XftFont *pub, + _Xconst FcChar8 *string, + FcEndian endian, + int len, + XGlyphInfo *extents) +{ + FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; + FcChar32 ucs4; + int i; + int l; + int size; + + i = 0; + glyphs = glyphs_local; + size = NUM_LOCAL; + while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0) + { + if (i == size) + { + glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); + if (!glyphs_new) + { + if (glyphs != glyphs_local) + free (glyphs); + memset (extents, '\0', sizeof (XGlyphInfo)); + return; + } + memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); + size *= 2; + if (glyphs != glyphs_local) + free (glyphs); + glyphs = glyphs_new; + } + glyphs[i++] = XftCharIndex (dpy, pub, ucs4); + string += l; + len -= l; + } + XftGlyphExtents (dpy, pub, glyphs, i, extents); + if (glyphs != glyphs_local) + free (glyphs); +} |