diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-01-25 03:12:02 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-01-25 03:12:02 (GMT) |
commit | a0e0a9378d10db9c8ab3ba4d59f5c576ee4cbc40 (patch) | |
tree | fafbbb89ac57a26ec4397b650ab4be1c6f2e6b46 | |
parent | 4fcce8c4b2323e054c90048a11a2a483f7884dd7 (diff) | |
parent | cfb7c16d738993fc8a594361f4bdf10e24fa754a (diff) | |
download | Qt-a0e0a9378d10db9c8ab3ba4d59f5c576ee4cbc40.zip Qt-a0e0a9378d10db9c8ab3ba4d59f5c576ee4cbc40.tar.gz Qt-a0e0a9378d10db9c8ab3ba4d59f5c576ee4cbc40.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public:
Avoid possible font name collisions on fbserv
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_s60.cpp | 357 | ||||
-rw-r--r-- | src/gui/text/qfontengine_s60.cpp | 5 |
3 files changed, 343 insertions, 23 deletions
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 637957d..6b612eb 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2543,6 +2543,8 @@ bool QFontDatabasePrivate::isApplicationFont(const QString &fileName) \note Adding application fonts on Unix/X11 platforms without fontconfig is currently not supported. + \note On Symbian, the font family names get truncated to a length of 20 characters. + \sa addApplicationFontFromData(), applicationFontFamilies(), removeApplicationFont() */ int QFontDatabase::addApplicationFont(const QString &fileName) @@ -2573,6 +2575,8 @@ int QFontDatabase::addApplicationFont(const QString &fileName) \bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is currently not supported. + \note On Symbian, the font family names get truncated to a length of 20 characters. + \sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont() */ int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData) diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 06462c4..ad67189 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -46,6 +46,7 @@ #include "qabstractfileengine.h" #include "qdesktopservices.h" #include "qtemporaryfile.h" +#include "qtextcodec.h" #include <private/qpixmap_s60_p.h> #include <private/qt_s60_p.h> #include "qendian.h" @@ -152,10 +153,11 @@ public: mutable QList<const QSymbianTypeFaceExtras *> m_extras; mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; + mutable QSet<QString> m_applicationFontFamilies; }; const QString QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix = - QLatin1String("qaf"); + QLatin1String("Q"); inline QString QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder() { @@ -166,21 +168,60 @@ QString QSymbianFontDatabaseExtrasImplementation::appFontMarker() { static QString result; if (result.isEmpty()) { - const quint32 uid = RProcess().Type().MostDerived().iUid; - quint16 crossSum = static_cast<quint16>(uid + (uid >> 16)); - if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + quint16 id = 0; + if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + // We are allowed to load app fonts even from previous, crashed runs + // of this application, since we can access the font tables. + const quint32 uid = RProcess().Type().MostDerived().iUid; + id = static_cast<quint16>(uid + (uid >> 16)); + } else { // If no font table Api is available, we must not even load a font // from a previous (crashed) run of this application. Reason: we // won't get the font tables, they are not in the CFontStore. - // So, we add the pid to the uniqueness of the marker. - const quint32 pid = static_cast<quint32>(RProcess().Id().Id()); - crossSum += static_cast<quint16>(pid + (pid >> 16)); + // So, we use the pid, for more uniqueness. + id = static_cast<quint16>(RProcess().Id().Id()); } - result = appFontMarkerPrefix + QString::number(crossSum, 16); + result = appFontMarkerPrefix + QString::fromLatin1("%1").arg(id & 0x7fff, 3, 32, QLatin1Char('0')); + Q_ASSERT(appFontMarkerPrefix.length() == 1 && result.length() == 4); } return result; } +static inline bool qt_symbian_fontNameHasAppFontMarker(const QString &fontName) +{ + const int idLength = 3; // Keep in sync with id length in appFontMarker(). + const QString &prefix = QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix; + if (fontName.length() < prefix.length() + idLength + || fontName.mid(fontName.length() - idLength - prefix.length(), prefix.length()) != prefix) + return false; + // Testing if the the id is base32 data + for (int i = fontName.length() - idLength; i < fontName.length(); ++i) { + const QChar &c = fontName.at(i); + if (!(c >= QLatin1Char('0') && c <= QLatin1Char('9') + || c >= QLatin1Char('a') && c <= QLatin1Char('v'))) + return false; + } + return true; +} + +// If fontName is an application font of this app, prepend the app font marker +QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName) +{ + QFontDatabasePrivate *db = privateDb(); + Q_ASSERT(db); + const QSymbianFontDatabaseExtrasImplementation *dbExtras = + static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); + return dbExtras->m_applicationFontFamilies.contains(fontName) ? + fontName + QSymbianFontDatabaseExtrasImplementation::appFontMarker() + : fontName; +} + +static inline QString qt_symbian_appFontNameWithoutMarker(const QString &markedFontName) +{ + return markedFontName.left(markedFontName.length() + - QSymbianFontDatabaseExtrasImplementation::appFontMarker().length()); +} + QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() { if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { @@ -276,9 +317,10 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont) } #endif // FNTSTORE_H_INLINES_SUPPORT_FMM -const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface, +const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface, bool bold, bool italic) const { + const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface); const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); if (!m_extrasHash.contains(searchKey)) { TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); @@ -331,6 +373,8 @@ void QSymbianFontDatabaseExtrasImplementation::removeAppFontData( if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable() && fnt->fontStoreFontFileUid.iUid != 0) m_store->RemoveFile(fnt->fontStoreFontFileUid); + if (!fnt->families.isEmpty()) + m_applicationFontFamilies.remove(fnt->families.first()); if (fnt->screenDeviceFontFileId != 0) S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId); QFile::remove(fnt->temporaryFileName); @@ -425,6 +469,18 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, { TTypefaceSupport typefaceSupport; S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex); + + QString familyName((const QChar*)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length()); + if (qt_symbian_fontNameHasAppFontMarker(familyName)) { + const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker(); + if (familyName.endsWith(marker)) { + familyName = qt_symbian_appFontNameWithoutMarker(familyName); + dbExtras->m_applicationFontFamilies.insert(familyName); + } else { + return false; // This was somebody else's application font. Skip it. + } + } + CFont *font; // We have to get a font instance in order to know all the details TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11); if (S60->screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone) @@ -440,7 +496,6 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, styleKey.style = faceAttrib.IsItalic()?QFont::StyleItalic:QFont::StyleNormal; styleKey.weight = faceAttrib.IsBold()?QFont::Bold:QFont::Normal; - QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length()); QtFontFamily *family = privateDb()->family(familyName, true); family->fixedPitch = faceAttrib.IsMonoWidth(); QtFontFoundry *foundry = family->foundry(QString(), true); @@ -515,14 +570,268 @@ static inline void load(const QString &family = QString(), int script = -1) initializeDb(); } -static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) +struct OffsetTable { + quint32 sfntVersion; + quint16 numTables, searchRange, entrySelector, rangeShift; +}; + +struct TableRecord { + quint32 tag, checkSum, offset, length; +}; + +struct NameTableHead { + quint16 format, count, stringOffset; +}; + +struct NameRecord { + quint16 platformID, encodingID, languageID, nameID, length, offset; +}; + +static quint32 ttfCalcChecksum(const char *data, quint32 bytesCount) +{ + quint32 result = 0; + const quint32 *ptr = reinterpret_cast<const quint32*>(data); + const quint32 *endPtr = + ptr + (bytesCount + sizeof(quint32) - 1) / sizeof(quint32); + while (ptr < endPtr) { + const quint32 unit32Value = *ptr++; + result += qFromBigEndian(unit32Value); + } + return result; +} + +static inline quint32 toDWordBoundary(quint32 value) +{ + return (value + 3) & ~3; +} + +static inline quint32 dWordPadding(quint32 value) +{ + return (4 - (value & 3)) & 3; +} + +static inline bool ttfMarkNameTable(QByteArray &table, const QString &marker) +{ + const quint32 tableLength = static_cast<quint32>(table.size()); + + if (tableLength > 50000 // hard limit + || tableLength < sizeof(NameTableHead)) // corrupt name table + return false; + + const NameTableHead *head = reinterpret_cast<const NameTableHead*>(table.constData()); + const quint16 count = qFromBigEndian(head->count); + const quint16 stringOffset = qFromBigEndian(head->stringOffset); + if (count > 200 // hard limit + || stringOffset >= tableLength // corrupt name table + || sizeof(NameTableHead) + count * sizeof(NameRecord) >= tableLength) // corrupt name table + return false; + + QTextEncoder encoder(QTextCodec::codecForName("UTF-16BE"), QTextCodec::IgnoreHeader); + const QByteArray markerUtf16BE = encoder.fromUnicode(marker); + const QByteArray markerAscii = marker.toAscii(); + + QByteArray markedTable; + markedTable.reserve(tableLength + marker.length() * 20); // Original size plus some extra + markedTable.append(table, stringOffset); + QByteArray markedStrings; + quint32 stringDataCount = stringOffset; + for (quint16 i = 0; i < count; ++i) { + const quint32 nameRecordOffset = sizeof(NameTableHead) + sizeof(NameRecord) * i; + NameRecord *nameRecord = + reinterpret_cast<NameRecord*>(markedTable.data() + nameRecordOffset); + const quint16 nameID = qFromBigEndian(nameRecord->nameID); + const quint16 platformID = qFromBigEndian(nameRecord->platformID); + const quint16 encodingID = qFromBigEndian(nameRecord->encodingID); + const quint16 offset = qFromBigEndian(nameRecord->offset); + const quint16 length = qFromBigEndian(nameRecord->length); + stringDataCount += length; + if (stringDataCount > 80000 // hard limit. String data may be > name table size. Multiple records can reference the same string. + || static_cast<quint32>(stringOffset + offset + length) > tableLength) // String outside bounds + return false; + const bool needsMarker = + nameID == 1 || nameID == 3 || nameID == 4 || nameID == 16 || nameID == 21; + const bool isUnicode = + platformID == 0 || platformID == 3 && encodingID == 1; + const QByteArray originalString = + QByteArray::fromRawData(table.constData() + stringOffset + offset, length); + QByteArray markedString; + if (needsMarker) { + const int maxBytesLength = (KMaxTypefaceNameLength - marker.length()) * (isUnicode ? 2 : 1); + markedString = originalString.left(maxBytesLength) + (isUnicode ? markerUtf16BE : markerAscii); + } else { + markedString = originalString; + } + nameRecord->offset = qToBigEndian(static_cast<quint16>(markedStrings.length())); + nameRecord->length = qToBigEndian(static_cast<quint16>(markedString.length())); + markedStrings.append(markedString); + } + markedTable.append(markedStrings); + table = markedTable; + return true; +} + +const quint32 ttfMaxFileSize = 3500000; + +static inline bool ttfMarkAppFont(QByteArray &ttf, const QString &marker) { - if (QSysInfo::symbianVersion() <= QSysInfo::SV_SF_2) - return; // See QTBUG-16514 for what 'font collisions' can cause in Symbian^1 and lower + const quint32 ttfChecksumNumber = 0xb1b0afba; + const quint32 alignment = 4; + const quint32 ttfLength = static_cast<quint32>(ttf.size()); + if (ttfLength > ttfMaxFileSize // hard limit + || ttfLength % alignment != 0 // ttf sizes are always factors of 4 + || ttfLength <= sizeof(OffsetTable) // ttf too short + || ttfCalcChecksum(ttf.constData(), ttf.size()) != ttfChecksumNumber) // ttf checksum is invalid + return false; + + const OffsetTable *offsetTable = reinterpret_cast<const OffsetTable*>(ttf.constData()); + const quint16 numTables = qFromBigEndian(offsetTable->numTables); + const quint32 recordsLength = + toDWordBoundary(sizeof(OffsetTable) + numTables * sizeof(TableRecord)); + if (numTables > 30 // hard limit + || recordsLength + numTables * alignment > ttfLength) // Corrupt ttf. Tables would not fit, even if empty. + return false; + + QByteArray markedTtf; + markedTtf.reserve(ttfLength + marker.length() * 20); // Original size plus some extra + markedTtf.append(ttf.constData(), recordsLength); + + const quint32 ttfCheckSumAdjustmentOffset = 8; // Offset from the start of 'head' + int indexOfHeadTable = -1; + quint32 ttfDataSize = recordsLength; + typedef QPair<quint32, quint32> Range; + QList<Range> memoryRanges; + memoryRanges.reserve(numTables); + for (int i = 0; i < numTables; ++i) { + TableRecord *tableRecord = + reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord)); + const quint32 offset = qFromBigEndian(tableRecord->offset); + const quint32 length = qFromBigEndian(tableRecord->length); + const quint32 lengthAligned = toDWordBoundary(length); + ttfDataSize += lengthAligned; + if (offset < recordsLength // must not intersect ttf header/records + || offset % alignment != 0 // must be aligned + || offset > ttfLength - alignment // table out of bounds + || offset + lengthAligned > ttfLength // table out of bounds + || ttfDataSize > ttfLength) // tables would not fit into the ttf + return false; - if (QSymbianFontDatabaseExtrasImplementation::appFontLimitReached()) + foreach (const Range &range, memoryRanges) + if (offset < range.first + range.second && offset + lengthAligned > range.first) + return false; // Overlaps with another table + memoryRanges.append(Range(offset, lengthAligned)); + + quint32 checkSum = qFromBigEndian(tableRecord->checkSum); + if (tableRecord->tag == qToBigEndian('head')) { + if (length < ttfCheckSumAdjustmentOffset + sizeof(quint32)) + return false; // Invalid 'head' table + const quint32 *checkSumAdjustmentTag = + reinterpret_cast<const quint32*>(ttf.constData() + offset + ttfCheckSumAdjustmentOffset); + const quint32 checkSumAdjustment = qFromBigEndian(*checkSumAdjustmentTag); + checkSum += checkSumAdjustment; + indexOfHeadTable = i; // For the ttf checksum re-calculation, later + } + if (checkSum != ttfCalcChecksum(ttf.constData() + offset, length)) + return false; // Table checksum is invalid + + bool updateTableChecksum = false; + QByteArray table; + if (tableRecord->tag == qToBigEndian('name')) { + table = QByteArray(ttf.constData() + offset, length); + if (!ttfMarkNameTable(table, marker)) + return false; // Name table was not markable. + updateTableChecksum = true; + } else { + table = QByteArray::fromRawData(ttf.constData() + offset, length); + } + + tableRecord->offset = qToBigEndian(markedTtf.size()); + tableRecord->length = qToBigEndian(table.size()); + markedTtf.append(table); + markedTtf.append(QByteArray(dWordPadding(table.size()), 0)); // 0-padding + if (updateTableChecksum) { + TableRecord *tableRecord = // Need to recalculate, since markedTtf changed + reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord)); + const quint32 offset = qFromBigEndian(tableRecord->offset); + const quint32 length = qFromBigEndian(tableRecord->length); + tableRecord->checkSum = qToBigEndian(ttfCalcChecksum(markedTtf.constData() + offset, length)); + } + } + if (indexOfHeadTable == -1 // 'head' table is mandatory + || ttfDataSize != ttfLength) // We do not allow ttf data "holes". Neither does Symbian. + return false; + TableRecord *headRecord = + reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + indexOfHeadTable * sizeof(TableRecord)); + quint32 *checkSumAdjustmentTag = + reinterpret_cast<quint32*>(markedTtf.data() + qFromBigEndian(headRecord->offset) + ttfCheckSumAdjustmentOffset); + *checkSumAdjustmentTag = 0; + const quint32 ttfChecksum = ttfCalcChecksum(markedTtf.constData(), markedTtf.count()); + *checkSumAdjustmentTag = qToBigEndian(ttfChecksumNumber - ttfChecksum); + ttf = markedTtf; + return true; +} + +static inline bool ttfCanSymbianLoadFont(const QByteArray &data, const QString &fileName) +{ + bool result = false; + QString ttfFileName; + QFile tempFileGuard; + QFileInfo info(fileName); + if (!data.isEmpty()) { + QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder() + + QSymbianFontDatabaseExtrasImplementation::appFontMarker() + + QLatin1String("XXXXXX.ttf")); + if (!tempfile.open() || tempfile.write(data) == -1) + return false; + ttfFileName = QDir::toNativeSeparators(QFileInfo(tempfile).canonicalFilePath()); + tempfile.setAutoRemove(false); + tempfile.close(); + tempFileGuard.setFileName(ttfFileName); + if (!tempFileGuard.open(QIODevice::ReadOnly)) + return false; + } else if (info.isFile()) { + ttfFileName = QDir::toNativeSeparators(info.canonicalFilePath()); + } else { + return false; + } + + CFontStore *store = 0; + RHeap* heap = User::ChunkHeap(NULL, 0x1000, 0x20000); + if (heap) { + QT_TRAP_THROWING( + CleanupClosePushL(*heap); + store = CFontStore::NewL(heap); + CleanupStack::PushL(store); + COpenFontRasterizer *rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); + CleanupStack::PushL(rasterizer); + store->InstallRasterizerL(rasterizer); + CleanupStack::Pop(rasterizer); + TUid fontUid = {-1}; + TRAP_IGNORE(fontUid = store->AddFileL(qt_QString2TPtrC(ttfFileName))); + if (fontUid.iUid != -1) + result = true; + CleanupStack::PopAndDestroy(2, heap); // heap, store + ); + } + + if (tempFileGuard.isOpen()) + tempFileGuard.remove(); + + return result; +} + +static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) +{ + if (QSymbianFontDatabaseExtrasImplementation::appFontLimitReached() + || fnt->data.size() > ttfMaxFileSize // hard limit + || fnt->data.isEmpty() && (!fnt->fileName.endsWith(QLatin1String(".ttf"), Qt::CaseInsensitive) // Only buffer or .ttf + || QFileInfo(fnt->fileName).size() > ttfMaxFileSize)) // hard limit return; +// Using ttfCanSymbianLoadFont() causes crashes on app destruction (Symbian^3|PR1 and lower). +// Therefore, not using it for now, but eventually in a later version. +// if (!ttfCanSymbianLoadFont(fnt->data, fnt->fileName)) +// return; + QFontDatabasePrivate *db = privateDb(); if (!db) return; @@ -530,13 +839,13 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) if (!db->count) initializeDb(); - if (fnt->data.isEmpty() && !fnt->fileName.endsWith(QLatin1String(".ttf"), Qt::CaseInsensitive)) - return; // Only buffer or .ttf QSymbianFontDatabaseExtrasImplementation *dbExtras = static_cast<QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); if (!dbExtras) return; + const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker(); + // The QTemporaryFile object being used in the following section must be // destructed before letting Symbian load the TTF file. Symbian would not // load it otherwise, because QTemporaryFile will still keep some handle @@ -548,8 +857,7 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) QFile tempFileGuard; { QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder() - + QSymbianFontDatabaseExtrasImplementation::appFontMarker() - + QLatin1String("XXXXXX.ttf")); + + marker + QLatin1String("XXXXXX.ttf")); if (!tempfile.open()) return; const QString tempFileName = QFileInfo(tempfile).canonicalFilePath(); @@ -559,10 +867,11 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) return; fnt->data = sourceFile.readAll(); } - if (tempfile.write(fnt->data) == -1) + if (!ttfMarkAppFont(fnt->data, marker) || tempfile.write(fnt->data) == -1) return; tempfile.setAutoRemove(false); tempfile.close(); // Tempfile still keeps a file handle, forbidding write access + fnt->data.clear(); // The TTF data was marked and saved. Not needed in memory, anymore. tempFileGuard.setFileName(tempFileName); if (!tempFileGuard.open(QIODevice::ReadOnly)) return; @@ -593,10 +902,14 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) fnt->fontStoreFontFileUid = dbExtras->addFontFileToFontStore(QFileInfo(fullFileName)); - fnt->families.append(fontsOnServerAfter.at(fontOnServerIndex)); - if (!registerScreenDeviceFont(fontOnServerIndex, dbExtras)) + const QString &appFontName = fontsOnServerAfter.at(fontOnServerIndex); + fnt->families.append(qt_symbian_appFontNameWithoutMarker(appFontName)); + if (!qt_symbian_fontNameHasAppFontMarker(appFontName) + || !registerScreenDeviceFont(fontOnServerIndex, dbExtras)) dbExtras->removeAppFontData(fnt); } else { + if (fnt->screenDeviceFontFileId > 0) + S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId); // May still have the file open! QFile::remove(fnt->temporaryFileName); *fnt = QFontDatabasePrivate::ApplicationFont(); } @@ -669,7 +982,7 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *d, const QF QFontDatabasePrivate *db = privateDb(); QtFontDesc desc; QList<int> blacklistedFamilies; - match(script, req, req.family, QString(), -1, &desc, blacklistedFamilies); + match(script, key.def, key.def.family, QString(), -1, &desc, blacklistedFamilies); if (!desc.family) // falling back to application font desc.family = db->family(QApplication::font().defaultFamily()); Q_ASSERT(desc.family); diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index b572cdd..f2b6f5c 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -243,10 +243,13 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len) return uc; } +extern QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName); // qfontdatabase_s60.cpp + CFont *QFontEngineS60::fontWithSize(qreal size) const { CFont *result = 0; - TFontSpec fontSpec(qt_QString2TPtrC(QFontEngine::fontDef.family), TInt(size)); + const QString family = qt_symbian_fontNameWithAppFontMarker(QFontEngine::fontDef.family); + TFontSpec fontSpec(qt_QString2TPtrC(family), TInt(size)); fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); |