+int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
+{
+ if( length < 0 )
+ length = wcslen(text);
+ if( !length ) return 0;
+
+ if( !get_resources()->use_xft ) {
+ if( !get_font_struct(font) ) return 0;
+ XChar2b xtext[length], *xp = xtext;
+ for( int i=0; i<length; ++i,++xp ) {
+ xp->byte1 = (unsigned char) (text[i] >> 8);
+ xp->byte2 = (unsigned char) (text[i] & 0xff);
+ }
+ return XTextWidth16(get_font_struct(font), xtext, length);
+ }
+ int x = 0;
+#ifdef HAVE_XFT
+ XftFont *basefont = top_level->get_xft_struct(font);
+ XftFont *curfont = 0, *altfont = 0;
+ const wchar_t *up = text, *ubp = up, *uep = ubp + length;
+
+ while( up < uep ) {
+ XftFont *xft_font = 0;
+ if( XftCharExists(top_level->display, basefont, *up) )
+ xft_font = basefont;
+ else if( altfont ) {
+ if( XftCharExists(top_level->display, altfont, *up))
+ xft_font = altfont;
+ else {
+ XftFontClose(top_level->display, altfont);
+ altfont = 0;
+ }
+ }
+ if( !xft_font ) {
+ FcPattern *pattern = BC_Resources::find_similar_font(*up, basefont->pattern);
+ if( pattern != 0 ) {
+ double psize = 0;
+ FcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE, 0, &psize);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, psize);
+ FcPatternDel(pattern, FC_SCALABLE);
+ xft_font = altfont = XftFontOpenPattern(top_level->display, pattern);
+ }
+ }
+ if( !xft_font )
+ xft_font = basefont;
+ if( xft_font != curfont ) {
+ if( curfont && up > ubp ) {
+ XGlyphInfo extents;
+ XftTextExtents32(top_level->display, curfont,
+ (const FcChar32*)ubp, up-ubp, &extents);
+ x += extents.xOff;
+ }
+ ubp = up; curfont = xft_font;
+ }
+ ++up;
+ }
+
+ if( curfont && up > ubp ) {
+ XGlyphInfo extents;
+ XftTextExtents32(top_level->display, curfont,
+ (const FcChar32*)ubp, up-ubp, &extents);
+ x += extents.xOff;
+ }
+
+ if( altfont )
+ XftFontClose(top_level->display, altfont);
+#endif
+ return x;
+}
+