diff -ur qt-x11-free-3.2.3-fix/src-orig/kernel/qfont.cpp qt-x11-free-3.2.3-fix/src/kernel/qfont.cpp --- qt-x11-free-3.2.3-fix/src-orig/kernel/qfont.cpp Mon Nov 10 19:21:57 2003 +++ qt-x11-free-3.2.3-fix/src/kernel/qfont.cpp Fri Nov 28 20:44:37 2003 @@ -208,6 +208,10 @@ #ifndef Q_WS_MAC memset( widthCache, 0, widthCacheSize*sizeof( uchar ) ); #endif +#ifdef Q_WS_X11 + memset( scripts_uniEngine, 0, QFont::LastPrivateScript * sizeof( uchar ) ); + uniEngine = 0; +#endif } QFontEngineData::~QFontEngineData() @@ -223,6 +227,10 @@ engine->deref(); engine = 0; #endif // Q_WS_X11 || Q_WS_WIN +#ifdef Q_WS_X11 + memset( scripts_uniEngine, 0, QFont::LastPrivateScript * sizeof( uchar ) ); + uniEngine = 0; +#endif } @@ -1244,7 +1252,7 @@ */ bool QFont::exactMatch() const { - QFontEngine *engine = d->engineForScript( QFont::NoScript ); + QFontEngine *engine = d->m_engineForScript( QFont::NoScript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -1976,8 +1984,8 @@ */ int QFontMetrics::ascent() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2000,8 +2008,8 @@ */ int QFontMetrics::descent() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2020,8 +2028,8 @@ */ int QFontMetrics::height() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2040,8 +2048,8 @@ */ int QFontMetrics::leading() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2059,8 +2067,8 @@ */ int QFontMetrics::lineSpacing() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2083,8 +2091,8 @@ */ int QFontMetrics::minLeftBearing() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2105,8 +2113,8 @@ */ int QFontMetrics::minRightBearing() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *latin_engine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *latin_engine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( latin_engine != 0 ); @@ -2120,8 +2128,8 @@ */ int QFontMetrics::maxWidth() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); - QFontEngine *lengine = d->engineForScript( QFont::Latin ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); + QFontEngine *lengine = d->m_engineForScript( QFont::Latin ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); Q_ASSERT( lengine != 0 ); @@ -2137,7 +2145,7 @@ bool QFontMetrics::inFont(QChar ch) const { QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE @@ -2164,7 +2172,7 @@ int QFontMetrics::leftBearing(QChar ch) const { QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE @@ -2198,7 +2206,7 @@ int QFontMetrics::rightBearing(QChar ch) const { QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE @@ -2248,7 +2256,7 @@ width += d->engineData->widthCache[uc]; else if ( ::category( *ch ) != QChar::Mark_NonSpacing ) { QFont::Script script; - SCRIPT_FOR_CHAR( script, *ch ); + SCRIPT_FOR_CHAR( script, *ch, d ); if (script >= QFont::Arabic && script <= QFont::Khmer) break; @@ -2378,7 +2386,7 @@ QRect QFontMetrics::boundingRect( QChar ch ) const { QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE @@ -2519,7 +2527,7 @@ */ int QFontMetrics::underlinePos() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2559,7 +2567,7 @@ */ int QFontMetrics::lineWidth() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2715,7 +2723,7 @@ */ QString QFontInfo::family() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2729,7 +2737,7 @@ */ int QFontInfo::pointSize() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2743,7 +2751,7 @@ */ int QFontInfo::pixelSize() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2757,7 +2765,7 @@ */ bool QFontInfo::italic() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2771,7 +2779,7 @@ */ int QFontInfo::weight() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2838,7 +2846,7 @@ */ bool QFontInfo::fixedPitch() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2865,7 +2873,7 @@ */ QFont::StyleHint QFontInfo::styleHint() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -2895,7 +2903,7 @@ */ bool QFontInfo::exactMatch() const { - QFontEngine *engine = d->engineForScript( (QFont::Script) fscript ); + QFontEngine *engine = d->m_engineForScript( (QFont::Script) fscript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE diff -ur qt-x11-free-3.2.3-fix/src-orig/kernel/qfont_x11.cpp qt-x11-free-3.2.3-fix/src/kernel/qfont_x11.cpp --- qt-x11-free-3.2.3-fix/src-orig/kernel/qfont_x11.cpp Mon Nov 10 19:22:04 2003 +++ qt-x11-free-3.2.3-fix/src/kernel/qfont_x11.cpp Fri Nov 28 20:44:37 2003 @@ -56,6 +56,7 @@ #include "qfontdata_p.h" #include "qfontengine_p.h" #include "qtextengine_p.h" +#include "qscriptengine_p.h" #include "qt_x11_p.h" @@ -277,7 +278,7 @@ QFontPrivate *priv = new QFontPrivate; for ( uint i = 0; i < sample.length(); i++ ) { - SCRIPT_FOR_CHAR( tmp, *uc ); + SCRIPT_FOR_CHAR( tmp, *uc, 0 ); uc++; if ( tmp != cs && tmp != QFont::UnknownScript ) { cs = tmp; @@ -364,12 +365,23 @@ // the cached engineData could have already loaded the engine we want if ( engineData->engines[script] ) return; + static ShapeFunction basic_shape = scriptEngines[QFont::Latin].shape; + QFontEngine *uniEngine = 0; + + if ( script != QFont::Unicode && + scriptEngines[script].shape == basic_shape ) { + if ( !engineData->engines[QFont::Unicode] ) + load( QFont::Unicode ); + uniEngine = engineData->uniEngine; + } + // load the font QFontEngine *engine = 0; // double scale = 1.0; // ### TODO: fix the scale calculations // list of families to try QStringList family_list = QStringList::split( ',', req.family ); + int count = family_list.count(); // append the substitute list for each family in family_list QStringList subs_list; @@ -399,13 +411,17 @@ family_list << QString::null; it = family_list.begin(), end = family_list.end(); - for ( ; ! engine && it != end; ++it ) { + for ( ; ! engine && it != end; ++it, --count ) { req.family = *it; engine = QFontDatabase::findFont( script, this, req ); if ( engine ) { - if ( engine->type() != QFontEngine::Box ) - break; + if ( engine->type() != QFontEngine::Box ) { + if ( script != QFont::Unicode && engine == uniEngine ) + engineData->scripts_uniEngine[script] = 1; + if ( engine != uniEngine ) + break; + } if ( ! req.family.isEmpty() ) engine = 0; @@ -416,6 +432,49 @@ engine->ref(); engineData->engines[script] = engine; + + if ( script == QFont::Unicode && count > 0 ) { + QString req_family, req_foundry, font_family, font_foundry; + + QFontDatabase::parseFontName(req.family, req_foundry, req_family); + QFontDatabase::parseFontName(engine->fontDef.family, + font_foundry, font_family); + + if ( req_family == font_family && + ( req_foundry.isEmpty() || + font_foundry.isEmpty() || + req_foundry == font_foundry ) ) + engineData->uniEngine = engine; + } +} + +QFont::Script QFontPrivate::checkSpecialScript( QFont::Script script, + const QChar &ch ) +{ + static ShapeFunction basic_shape = scriptEngines[QFont::Latin].shape; + + if ( scriptEngines[script].shape != basic_shape ) + return script; + + if ( !engineData || !engineData->engines[QFont::Unicode] ) + load( QFont::Unicode ); + + if ( engineData->uniEngine ) { + if ( engineData->uniEngine->canRender( &ch, 1 ) ) + return QFont::Unicode; + + } else { + if ( script != QFontPrivate::defaultScript && + QFontPrivate::defaultScript != QFont::Unicode && + QFontPrivate::defaultScript != QFont::UnknownScript ) { + QFontEngine *fe = engineForScript( QFontPrivate::defaultScript ); + + if ( fe->type() == QFontEngine::XLFD && fe->canRender( &ch, 1 ) ) + return QFontPrivate::defaultScript; + } + } + + return script; } /*! @@ -433,7 +492,7 @@ */ Qt::HANDLE QFont::handle() const { - QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript ); + QFontEngine *engine = d->m_engineForScript( QFontPrivate::defaultScript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -466,7 +525,7 @@ */ QString QFont::rawName() const { - QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript ); + QFontEngine *engine = d->m_engineForScript( QFontPrivate::defaultScript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE @@ -656,7 +715,7 @@ return 0; QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); QFontEngine *engine = d->engineForScript( script ); #ifdef QT_CHECK_STATE @@ -690,7 +749,7 @@ return 0; QFont::Script script; - SCRIPT_FOR_CHAR( script, ch ); + SCRIPT_FOR_CHAR( script, ch, d ); int width; diff -ur qt-x11-free-3.2.3-fix/src-orig/kernel/qfontdata_p.h qt-x11-free-3.2.3-fix/src/kernel/qfontdata_p.h --- qt-x11-free-3.2.3-fix/src-orig/kernel/qfontdata_p.h Mon Nov 10 19:21:58 2003 +++ qt-x11-free-3.2.3-fix/src/kernel/qfontdata_p.h Fri Nov 28 20:44:37 2003 @@ -125,6 +125,10 @@ enum { widthCacheSize = 0x500 }; uchar widthCache[widthCacheSize]; #endif +#ifdef Q_WS_X11 + uchar scripts_uniEngine[QFont::LastPrivateScript]; + QFontEngine *uniEngine; +#endif // Q_WS_X11 }; @@ -154,6 +158,21 @@ return engineData->engine; #endif // Q_WS_X11 || Q_WS_WIN } + + QFontEngine *m_engineForScript( QFont::Script script ) const { + if ( script == QFont::NoScript ) + script = QFontPrivate::defaultScript; + QFontEngine *engine = engineForScript( script ); +#ifdef Q_WS_X11 + if ( engineData->scripts_uniEngine[script] ) + return engineData->uniEngine; +#endif + return engine; + } + +#ifdef Q_WS_X11 + QFont::Script checkSpecialScript( QFont::Script script, const QChar &ch ); +#endif // Q_WS_X11 QFontDef request; QFontEngineData *engineData; diff -ur qt-x11-free-3.2.3-fix/src-orig/kernel/qfontdatabase_x11.cpp qt-x11-free-3.2.3-fix/src/kernel/qfontdatabase_x11.cpp --- qt-x11-free-3.2.3-fix/src-orig/kernel/qfontdatabase_x11.cpp Mon Nov 10 19:21:59 2003 +++ qt-x11-free-3.2.3-fix/src/kernel/qfontdatabase_x11.cpp Fri Nov 28 20:44:37 2003 @@ -852,6 +852,7 @@ } } #endif // QT_XFT2 + family->scripts[QFont::Unicode] = QtFontFamily::Supported; QCString file = file_value; family->fontFilename = file; diff -ur qt-x11-free-3.2.3-fix/src-orig/kernel/qtextengine.cpp qt-x11-free-3.2.3-fix/src/kernel/qtextengine.cpp --- qt-x11-free-3.2.3-fix/src-orig/kernel/qtextengine.cpp Mon Nov 10 19:22:03 2003 +++ qt-x11-free-3.2.3-fix/src/kernel/qtextengine.cpp Fri Nov 28 20:44:37 2003 @@ -186,8 +186,7 @@ if ( control.singleLine ) { for ( int i = start; i <= stop; i++ ) { - unsigned short uc = text[i].unicode(); - QFont::Script s = (QFont::Script)scriptForChar( uc ); + QFont::Script s = (QFont::Script)scriptForChar( text[i], engine->fnt ); if (s == QFont::UnknownScript) s = script; @@ -203,19 +202,19 @@ for ( int i = start; i <= stop; i++ ) { unsigned short uc = text[i].unicode(); - QFont::Script s = (QFont::Script)scriptForChar( uc ); + QFont::Script s = (QFont::Script)scriptForChar( text[i], engine->fnt ); if (s == QFont::UnknownScript) s = script; QChar::Category category = ::category( uc ); if ( uc == 0xfffcU || uc == 0x2028U ) { item.analysis.bidiLevel = level % 2 ? level-1 : level; - item.analysis.script = QFont::Latin; + item.analysis.script = s; item.isObject = TRUE; s = QFont::NoScript; } else if ((uc >= 9 && uc <=13) || (category >= QChar::Separator_Space && category <= QChar::Separator_Paragraph)) { - item.analysis.script = QFont::Latin; + item.analysis.script = s; item.isSpace = TRUE; item.isTab = ( uc == '\t' ); item.analysis.bidiLevel = item.isTab ? control.baseLevel() : level; diff -ur qt-x11-free-3.2.3-fix/src-orig/tools/qunicodetables_p.h qt-x11-free-3.2.3-fix/src/tools/qunicodetables_p.h --- qt-x11-free-3.2.3-fix/src-orig/tools/qunicodetables_p.h Mon Nov 10 19:21:38 2003 +++ qt-x11-free-3.2.3-fix/src/tools/qunicodetables_p.h Fri Nov 28 20:44:37 2003 @@ -37,6 +37,7 @@ #define QUNICODETABLES_P_H #include "qstring.h" +#include "private/qfontdata_p.h" #ifdef QT_NO_UNICODETABLES # include @@ -206,8 +207,9 @@ return QUnicodeTables::line_break_info[pos]; } -inline int scriptForChar( ushort uc ) +inline int scriptForChar( const QChar &ch, QFontPrivate *fnt = 0 ) { + unsigned short uc = ch.unicode(); unsigned char script = QUnicodeTables::scriptTable[(uc>>8)]; if ( script >= QUnicodeTables::SCRIPTS_INDIC ) { if ( script == QUnicodeTables::SCRIPTS_INDIC ) { @@ -221,22 +223,18 @@ script = QUnicodeTables::otherScripts[index]; } } - return script; -} #ifdef Q_WS_X11 -#define SCRIPT_FOR_CHAR( script, c ) \ -do { \ - unsigned short _uc = (c).unicode(); \ - if ( _uc < 0x100 ) { \ - script = QFont::Latin; \ - } else { \ - script = (QFont::Script)scriptForChar( _uc ); \ - } \ -} while( FALSE ) + if ( fnt ) + script = fnt->checkSpecialScript( (QFont::Script)script, ch ); #else -#define SCRIPT_FOR_CHAR( script, c ) \ - script = (QFont::Script)scriptForChar( (c).unicode() ) -#endif + Q_UNUSED( fnt ); +#endif // Q_WS_X11 + + return script; +} + +#define SCRIPT_FOR_CHAR( script, c, fnt ) \ + script = (QFont::Script)scriptForChar( c, fnt ) #endif