xftextent.c revision c76ae52d
1/* 2 * $Id: xftextent.c,v 1.1.1.1 2008/07/30 02:49:10 mrg Exp $ 3 * 4 * Copyright © 2000 Keith Packard 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that 9 * copyright notice and this permission notice appear in supporting 10 * documentation, and that the name of Keith Packard not be used in 11 * advertising or publicity pertaining to distribution of the software without 12 * specific, written prior permission. Keith Packard makes no 13 * representations about the suitability of this software for any purpose. It 14 * is provided "as is" without express or implied warranty. 15 * 16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 * PERFORMANCE OF THIS SOFTWARE. 23 */ 24 25#include "xftint.h" 26 27_X_EXPORT void 28XftGlyphExtents (Display *dpy, 29 XftFont *pub, 30 _Xconst FT_UInt *glyphs, 31 int nglyphs, 32 XGlyphInfo *extents) 33{ 34 XftFontInt *font = (XftFontInt *) pub; 35 FT_UInt missing[XFT_NMISSING]; 36 int nmissing; 37 int n; 38 _Xconst FT_UInt *g; 39 FT_UInt glyph; 40 XftGlyph *xftg; 41 FcBool glyphs_loaded; 42 int x, y; 43 int left, right, top, bottom; 44 int overall_left, overall_right; 45 int overall_top, overall_bottom; 46 47 g = glyphs; 48 n = nglyphs; 49 nmissing = 0; 50 glyphs_loaded = FcFalse; 51 while (n--) 52 if (XftFontCheckGlyph (dpy, pub, FcFalse, *g++, missing, &nmissing)) 53 glyphs_loaded = FcTrue; 54 if (nmissing) 55 XftFontLoadGlyphs (dpy, pub, FcFalse, missing, nmissing); 56 g = glyphs; 57 n = nglyphs; 58 xftg = 0; 59 while (n) 60 { 61 glyph = *g++; 62 n--; 63 if (glyph < font->num_glyphs && 64 (xftg = font->glyphs[glyph])) 65 break; 66 } 67 if (n == 0) 68 { 69 if (xftg) 70 *extents = xftg->metrics; 71 else 72 memset (extents, '\0', sizeof (*extents)); 73 } 74 else 75 { 76 x = 0; 77 y = 0; 78 overall_left = x - xftg->metrics.x; 79 overall_top = y - xftg->metrics.y; 80 overall_right = overall_left + (int) xftg->metrics.width; 81 overall_bottom = overall_top + (int) xftg->metrics.height; 82 x += xftg->metrics.xOff; 83 y += xftg->metrics.yOff; 84 while (n--) 85 { 86 glyph = *g++; 87 if (glyph < font->num_glyphs && (xftg = font->glyphs[glyph])) 88 { 89 left = x - xftg->metrics.x; 90 top = y - xftg->metrics.y; 91 right = left + (int) xftg->metrics.width; 92 bottom = top + (int) xftg->metrics.height; 93 if (left < overall_left) 94 overall_left = left; 95 if (top < overall_top) 96 overall_top = top; 97 if (right > overall_right) 98 overall_right = right; 99 if (bottom > overall_bottom) 100 overall_bottom = bottom; 101 x += xftg->metrics.xOff; 102 y += xftg->metrics.yOff; 103 } 104 } 105 extents->x = -overall_left; 106 extents->y = -overall_top; 107 extents->width = overall_right - overall_left; 108 extents->height = overall_bottom - overall_top; 109 extents->xOff = x; 110 extents->yOff = y; 111 } 112 if (glyphs_loaded) 113 _XftFontManageMemory (dpy, pub); 114} 115 116#define NUM_LOCAL 1024 117 118_X_EXPORT void 119XftTextExtents8 (Display *dpy, 120 XftFont *pub, 121 _Xconst FcChar8 *string, 122 int len, 123 XGlyphInfo *extents) 124{ 125 FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 126 int i; 127 128 if (len <= NUM_LOCAL) 129 glyphs = glyphs_local; 130 else 131 { 132 glyphs = malloc (len * sizeof (FT_UInt)); 133 if (!glyphs) 134 { 135 memset (extents, '\0', sizeof (XGlyphInfo)); 136 return; 137 } 138 } 139 for (i = 0; i < len; i++) 140 glyphs[i] = XftCharIndex (dpy, pub, string[i]); 141 XftGlyphExtents (dpy, pub, glyphs, len, extents); 142 if (glyphs != glyphs_local) 143 free (glyphs); 144} 145 146_X_EXPORT void 147XftTextExtents16 (Display *dpy, 148 XftFont *pub, 149 _Xconst FcChar16 *string, 150 int len, 151 XGlyphInfo *extents) 152{ 153 FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 154 int i; 155 156 if (len <= NUM_LOCAL) 157 glyphs = glyphs_local; 158 else 159 { 160 glyphs = malloc (len * sizeof (FT_UInt)); 161 if (!glyphs) 162 { 163 memset (extents, '\0', sizeof (XGlyphInfo)); 164 return; 165 } 166 } 167 for (i = 0; i < len; i++) 168 glyphs[i] = XftCharIndex (dpy, pub, string[i]); 169 XftGlyphExtents (dpy, pub, glyphs, len, extents); 170 if (glyphs != glyphs_local) 171 free (glyphs); 172} 173 174_X_EXPORT void 175XftTextExtents32 (Display *dpy, 176 XftFont *pub, 177 _Xconst FcChar32 *string, 178 int len, 179 XGlyphInfo *extents) 180{ 181 FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 182 int i; 183 184 if (len <= NUM_LOCAL) 185 glyphs = glyphs_local; 186 else 187 { 188 glyphs = malloc (len * sizeof (FT_UInt)); 189 if (!glyphs) 190 { 191 memset (extents, '\0', sizeof (XGlyphInfo)); 192 return; 193 } 194 } 195 for (i = 0; i < len; i++) 196 glyphs[i] = XftCharIndex (dpy, pub, string[i]); 197 XftGlyphExtents (dpy, pub, glyphs, len, extents); 198 if (glyphs != glyphs_local) 199 free (glyphs); 200} 201 202_X_EXPORT void 203XftTextExtentsUtf8 (Display *dpy, 204 XftFont *pub, 205 _Xconst FcChar8 *string, 206 int len, 207 XGlyphInfo *extents) 208{ 209 FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; 210 FcChar32 ucs4; 211 int i; 212 int l; 213 int size; 214 215 i = 0; 216 glyphs = glyphs_local; 217 size = NUM_LOCAL; 218 while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0) 219 { 220 if (i == size) 221 { 222 glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); 223 if (!glyphs_new) 224 { 225 if (glyphs != glyphs_local) 226 free (glyphs); 227 memset (extents, '\0', sizeof (XGlyphInfo)); 228 return; 229 } 230 memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); 231 size *= 2; 232 if (glyphs != glyphs_local) 233 free (glyphs); 234 glyphs = glyphs_new; 235 } 236 glyphs[i++] = XftCharIndex (dpy, pub, ucs4); 237 string += l; 238 len -= l; 239 } 240 XftGlyphExtents (dpy, pub, glyphs, i, extents); 241 if (glyphs != glyphs_local) 242 free (glyphs); 243} 244 245_X_EXPORT void 246XftTextExtentsUtf16 (Display *dpy, 247 XftFont *pub, 248 _Xconst FcChar8 *string, 249 FcEndian endian, 250 int len, 251 XGlyphInfo *extents) 252{ 253 FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; 254 FcChar32 ucs4; 255 int i; 256 int l; 257 int size; 258 259 i = 0; 260 glyphs = glyphs_local; 261 size = NUM_LOCAL; 262 while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0) 263 { 264 if (i == size) 265 { 266 glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); 267 if (!glyphs_new) 268 { 269 if (glyphs != glyphs_local) 270 free (glyphs); 271 memset (extents, '\0', sizeof (XGlyphInfo)); 272 return; 273 } 274 memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); 275 size *= 2; 276 if (glyphs != glyphs_local) 277 free (glyphs); 278 glyphs = glyphs_new; 279 } 280 glyphs[i++] = XftCharIndex (dpy, pub, ucs4); 281 string += l; 282 len -= l; 283 } 284 XftGlyphExtents (dpy, pub, glyphs, i, extents); 285 if (glyphs != glyphs_local) 286 free (glyphs); 287} 288