int QFontMetrics::width( QChar ch ) const { unsigned short uc = ch.unicode(); if ( uc < QFontEngineData::widthCacheSize && d->engineData && d->engineData->widthCache[ uc ] ) return d->engineData->widthCache[ uc ]; if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode())) return 0; QFont::Script script; SCRIPT_FOR_CHAR( script, ch ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE glyph_t glyphs[8]; advance_t advances[8]; int nglyphs = 7; engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE ); // ### can nglyphs != 1 happen at all? Not currently I think if ( uc < QFontEngineData::widthCacheSize && advances[0] > 0 && advances[0] < 0x100 ) d->engineData->widthCache[ uc ] = advances[0]; return advances[0]; }
int QFontMetrics::width( QChar ch ) const { unsigned short uc = ch.unicode(); QFontEngine *engine = d->engineForScript( QFont::NoScript ); if ( uc < QFontEngineData::widthCacheSize && d->engineData && d->engineData->widthCache[ uc ] ) return (d->engineData->widthCache[ uc ]*engine->scale)>>8; if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode())) return 0; int width = memorymanager->lockGlyphMetrics( engine->handle(), ch.unicode() )->advance; if ( ch.unicode() < QFontEngineData::widthCacheSize && width > 0 && width < 0x100 ) d->engineData->widthCache[ ch.unicode() ] = width; return (width*engine->scale)>>8; }
int QFontMetrics::charWidth( const QString &str, int pos ) const { if ( pos < 0 || pos > (int)str.length() ) return 0; const QChar &ch = str.unicode()[ pos ]; if ( ch.unicode() < QFontEngineData::widthCacheSize && d->engineData && d->engineData->widthCache[ ch.unicode() ] ) return (d->engineData->widthCache[ ch.unicode() ]*d->engineData->engine->scale)>>8; QFont::Script script; SCRIPT_FOR_CHAR( script, ch ); int width; if ( script >= QFont::Arabic && script <= QFont::Khmer ) { // complex script shaping. Have to do some hard work int from = QMAX( 0, pos - 8 ); int to = QMIN( (int)str.length(), pos + 8 ); QConstString cstr( str.unicode()+from, to-from); QTextEngine layout( cstr.string(), d ); layout.itemize( QTextEngine::WidthOnly ); width = layout.width( pos-from, 1 ); } else if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode())) { width = 0; } else { QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE glyph_t glyphs[8]; advance_t advances[8]; int nglyphs = 7; engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE ); width = advances[0]; } if ( ch.unicode() < QFontEngineData::widthCacheSize && width > 0 && width < 0x100 ) d->engineData->widthCache[ ch.unicode() ] = width; return width; }