summaryrefslogtreecommitdiff
path: root/src/xftextent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xftextent.c')
-rw-r--r--src/xftextent.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/xftextent.c b/src/xftextent.c
new file mode 100644
index 0000000..d8e91e5
--- /dev/null
+++ b/src/xftextent.c
@@ -0,0 +1,291 @@
+/*
+ * $XFree86: xc/lib/Xft/xftextent.c,v 1.10 2002/12/14 01:59:38 dawes Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include "xftint.h"
+
+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 = 0;
+ while (n)
+ {
+ glyph = *g++;
+ n--;
+ if (glyph < font->num_glyphs &&
+ (xftg = font->glyphs[glyph]))
+ break;
+ }
+ if (n == 0 && !xftg)
+ {
+ extents->width = 0;
+ extents->height = 0;
+ extents->x = 0;
+ extents->y = 0;
+ extents->yOff = 0;
+ extents->xOff = 0;
+ }
+ 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
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}