- 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;