}
}
+
+void FontTextExtents8(
+ Display *dpy,
+ NFont *font,
+ const FcChar8 *string,
+ int len,
+ XGlyphInfo *extents)
+{
+ FcChar32 static_buffer[128];
+ FcChar32 *buf = static_buffer;
+ if(len >= 128) {
+ buf = calloc(len, sizeof(FcChar32));
+ }
+
+ // convert string from utf8 to utf32
+ int c = 0;
+ for(int i=0;i<len;) {
+ int n = FcUtf8ToUcs4(string+i, &buf[c++], len-i);
+ i += n;
+ }
+
+ FontTextExtents32(dpy, font, buf, c, extents);
+
+ if(buf != static_buffer) {
+ free(buf);
+ }
+}
+
+void FontTextExtents32(
+ Display *dpy,
+ NFont *font,
+ const FcChar32 *string,
+ int len,
+ XGlyphInfo *extents)
+{
+ XGlyphInfo ret = { 0 };
+
+ XftFont *currentFont = FontDefault(font);
+ int pos = 0;
+ for(int i=0;i<len;i++) {
+ XftFont *cFont = FindFont(font, string[i]);
+ if(cFont != currentFont && i > pos) {
+ const FcChar32 *segStr = string+pos;
+ int segLen = i-pos;
+
+ // get extents of string segment
+ XGlyphInfo ext;
+ XftTextExtents32(dpy, currentFont, segStr, segLen, &ext);
+
+ if(ext.height > ret.height) {
+ ret.height = ext.height;
+ }
+ ret.width += ext.width;
+ ret.xOff += ext.xOff;
+
+ pos = i;
+ }
+ currentFont = cFont;
+ }
+
+ if(pos < len) {
+ const FcChar32 *segStr = string+pos;
+ int segLen = len-pos;
+ // get extents of string segment
+ XGlyphInfo ext;
+ XftTextExtents32(dpy, currentFont, segStr, segLen, &ext);
+
+ if(ext.height > ret.height) {
+ ret.height = ext.height;
+ }
+ ret.width += ext.width;
+ ret.xOff += ext.xOff;
+ }
+
+ *extents = ret;
+}