diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/qml/qdeclarativeimport.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_s60.cpp | 130 | ||||
-rw-r--r-- | src/gui/text/qfontengine_s60.cpp | 182 | ||||
-rw-r--r-- | src/gui/text/qfontengine_s60_p.h | 16 |
4 files changed, 188 insertions, 148 deletions
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index acc13de..94765f2 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -382,7 +382,13 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name); - +#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN) + if (resolvedFilePath.isEmpty()) { + // In case of libinfixed build, attempt to load libinfixed version, too. + QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX); + resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName); + } +#endif if (!resolvedFilePath.isEmpty()) { if (!database->importPlugin(resolvedFilePath, uri, errorString)) { if (errorString) diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 5e168c6..9a77a7a 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -116,7 +116,6 @@ public: const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const; void addFontFileToFontStore(const QFileInfo &fontFileInfo); -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API struct CFontFromFontStoreReleaser { static inline void cleanup(CFont *font) { @@ -127,7 +126,6 @@ public: dbExtras->m_store->ReleaseFont(font); } }; -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API struct CFontFromScreenDeviceReleaser { static inline void cleanup(CFont *font) @@ -138,37 +136,38 @@ public: } }; -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API +// m_heap, m_store, m_rasterizer and m_extras are used if Symbian +// does not provide the Font Table API RHeap* m_heap; CFontStore *m_store; COpenFontRasterizer *m_rasterizer; mutable QList<const QSymbianTypeFaceExtras *> m_extras; -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; }; QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() { -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API - QStringList filters; - filters.append(QLatin1String("*.ttf")); - filters.append(QLatin1String("*.ccc")); - filters.append(QLatin1String("*.ltt")); - const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters); - - const TInt heapMinLength = 0x1000; - const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength); - m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength); - QT_TRAP_THROWING( - m_store = CFontStore::NewL(m_heap); - m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); - CleanupStack::PushL(m_rasterizer); - m_store->InstallRasterizerL(m_rasterizer); - CleanupStack::Pop(m_rasterizer);); - - foreach (const QFileInfo &fontFileInfo, fontFiles) - addFontFileToFontStore(fontFileInfo); -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + QStringList filters; + filters.append(QLatin1String("*.ttf")); + filters.append(QLatin1String("*.ccc")); + filters.append(QLatin1String("*.ltt")); + const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters); + + const TInt heapMinLength = 0x1000; + const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength); + m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength); + QT_TRAP_THROWING( + m_store = CFontStore::NewL(m_heap); + m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); + CleanupStack::PushL(m_rasterizer); + m_store->InstallRasterizerL(m_rasterizer); + CleanupStack::Pop(m_rasterizer);); + + foreach (const QFileInfo &fontFileInfo, fontFiles) + addFontFileToFontStore(fontFileInfo); + } } void qt_cleanup_symbianFontDatabaseExtras() @@ -177,26 +176,26 @@ void qt_cleanup_symbianFontDatabaseExtras() static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras); if (!dbExtras) return; // initializeDb() has never been called -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API - qDeleteAll(dbExtras->m_extrasHash); -#else // Q_SYMBIAN_HAS_FONTTABLE_API - typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; - for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { - dbExtras->m_store->ReleaseFont((*p)->fontOwner()); - delete *p; + if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + qDeleteAll(dbExtras->m_extrasHash); + } else { + typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; + for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { + dbExtras->m_store->ReleaseFont((*p)->fontOwner()); + delete *p; + } + dbExtras->m_extras.clear(); } - dbExtras->m_extras.clear(); -#endif // Q_SYMBIAN_HAS_FONTTABLE_API dbExtras->m_extrasHash.clear(); } QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation() { qt_cleanup_symbianFontDatabaseExtras(); -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API - delete m_store; - m_heap->Close(); -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + delete m_store; + m_heap->Close(); + } } #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM @@ -228,44 +227,45 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c searchSpec.iFontStyle.SetPosture(EPostureItalic); CFont* font = NULL; -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API - const TInt err = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); - Q_ASSERT(err == KErrNone && font); - QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font); - QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); - sFont.take(); - m_extrasHash.insert(searchKey, extras); -#else // Q_SYMBIAN_HAS_FONTTABLE_API - const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); - Q_ASSERT(err == KErrNone && font); - const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); - COpenFont *openFont = -#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM - bitmapFont->OpenFont(); -#else // FNTSTORE_H_INLINES_SUPPORT_FMM - OpenFontFromBitmapFont(bitmapFont); -#endif // FNTSTORE_H_INLINES_SUPPORT_FMM - const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); - const QString foundKey = - QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); - if (!m_extrasHash.contains(foundKey)) { - QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font); - QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + const TInt err = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); sFont.take(); - m_extras.append(extras); m_extrasHash.insert(searchKey, extras); - m_extrasHash.insert(foundKey, extras); } else { - m_store->ReleaseFont(font); - m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); + COpenFont *openFont = +#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM + bitmapFont->OpenFont(); +#else // FNTSTORE_H_INLINES_SUPPORT_FMM + OpenFontFromBitmapFont(bitmapFont); +#endif // FNTSTORE_H_INLINES_SUPPORT_FMM + const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); + const QString foundKey = + QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); + if (!m_extrasHash.contains(foundKey)) { + QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + sFont.take(); + m_extras.append(extras); + m_extrasHash.insert(searchKey, extras); + m_extrasHash.insert(foundKey, extras); + } else { + m_store->ReleaseFont(font); + m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + } } -#endif // Q_SYMBIAN_HAS_FONTTABLE_API } return m_extrasHash.value(searchKey); } void QSymbianFontDatabaseExtrasImplementation::addFontFileToFontStore(const QFileInfo &fontFileInfo) { + Q_ASSERT(!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()); const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath()); TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index bf30e1c..f8e5b4a 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -46,114 +46,115 @@ #include <private/qapplication_p.h> #include "qimage.h" #include <private/qt_s60_p.h> +#include <private/qpixmap_s60_p.h> #include <e32base.h> #include <e32std.h> #include <eikenv.h> #include <gdi.h> -#if defined(Q_SYMBIAN_HAS_FONTTABLE_API) || defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) +#if defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) #include <graphics/gdi/gdiplatapi.h> -#endif // Q_SYMBIAN_HAS_FONTTABLE_API || Q_SYMBIAN_HAS_GLYPHOUTLINE_API +#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + +// Replication of TGetFontTableParam & friends. +// There is unfortunately no compile time flag like SYMBIAN_FONT_TABLE_API +// that would help us to only replicate these things for Symbian versions +// that do not yet have the font table Api. Symbian's public SDK does +// generally not define any usable macros. +class QSymbianTGetFontTableParam +{ +public: + TUint32 iTag; + TAny *iContent; + TInt iLength; +}; +const TUid QSymbianKFontGetFontTable = {0x102872C1}; +const TUid QSymbianKFontReleaseFontTable = {0x2002AC24}; QT_BEGIN_NAMESPACE -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) : m_cFont(cFont) , m_symbolCMap(false) + , m_openFont(openFont) { - Q_UNUSED(openFont) + if (!symbianFontTableApiAvailable()) { + TAny *trueTypeExtension = NULL; + m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); + m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension); + Q_ASSERT(m_trueTypeExtension); + } } QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() { - S60->screenDevice()->ReleaseFont(m_cFont); + if (symbianFontTableApiAvailable()) + S60->screenDevice()->ReleaseFont(m_cFont); } QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const { - RFontTable fontTable; - if (fontTable.Open(*m_cFont, tag) != KErrNone) + if (symbianFontTableApiAvailable()) { + QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 }; + if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + const char* const fontTableContent = + static_cast<const char *>(fontTableParams.iContent); + const QByteArray fontTable(fontTableContent, fontTableParams.iLength); + m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + return fontTable; + } return QByteArray(); - const QByteArray byteArray(reinterpret_cast<const char *> - (fontTable.TableContent()),fontTable.TableLength()); - fontTable.Close(); - return byteArray; + } else { + Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); + TInt error = KErrNone; + TInt tableByteLength = 0; + TAny *table = q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); + const QByteArray result(static_cast<const char*>(table), tableByteLength); + m_trueTypeExtension->ReleaseTrueTypeTable(table); + return result; + } } bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const { - RFontTable fontTable; - if (fontTable.Open(*m_cFont, tag) != KErrNone) - return false; - bool result = true; - const TInt tableByteLength = fontTable.TableLength(); - - if (*length > 0 && *length < tableByteLength) { - result = false; // Caller did not allocate enough memory + if (symbianFontTableApiAvailable()) { + QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 }; + if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + if (*length > 0 && *length < fontTableParams.iLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = fontTableParams.iLength; + if (buffer) + memcpy(buffer, fontTableParams.iContent, fontTableParams.iLength); + } + m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + } else { + result = false; + } } else { - *length = tableByteLength; - if (buffer) - memcpy(buffer, fontTable.TableContent(), tableByteLength); - } - - fontTable.Close(); - return result; -} - -#else // Q_SYMBIAN_HAS_FONTTABLE_API -QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) - : m_cFont(cFont) - , m_symbolCMap(false) - , m_openFont(openFont) -{ - TAny *trueTypeExtension = NULL; - m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); - m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension); - Q_ASSERT(m_trueTypeExtension); -} - -QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() -{ -} - -QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const -{ - Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); - TInt error = KErrNone; - TInt tableByteLength = 0; - TAny *table = q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); - QByteArray result(static_cast<const char*>(table), tableByteLength); - m_trueTypeExtension->ReleaseTrueTypeTable(table); - return result; -} + if (!m_trueTypeExtension->HasTrueTypeTable(tag)) + return false; -bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const -{ - if (!m_trueTypeExtension->HasTrueTypeTable(tag)) - return false; + TInt error = KErrNone; + TInt tableByteLength; + TAny *table = + q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); - bool result = true; - TInt error = KErrNone; - TInt tableByteLength; - TAny *table = - q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); + if (error != KErrNone) { + return false; + } else if (*length > 0 && *length < tableByteLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = tableByteLength; + if (buffer) + memcpy(buffer, table, tableByteLength); + } - if (error != KErrNone) { - return false; - } else if (*length > 0 && *length < tableByteLength) { - result = false; // Caller did not allocate enough memory - } else { - *length = tableByteLength; - if (buffer) - memcpy(buffer, table, tableByteLength); + m_trueTypeExtension->ReleaseTrueTypeTable(table); } - - m_trueTypeExtension->ReleaseTrueTypeTable(table); return result; } -#endif // Q_SYMBIAN_HAS_FONTTABLE_API const uchar *QSymbianTypeFaceExtras::cmap() const { @@ -195,6 +196,39 @@ QFixed QSymbianTypeFaceExtras::unitsPerEm() const return m_unitsPerEm; } +bool QSymbianTypeFaceExtras::symbianFontTableApiAvailable() +{ + enum FontTableApiAvailability { + Unknown, + Available, + Unavailable + }; + static FontTableApiAvailability availability = + QSysInfo::symbianVersion() < QSysInfo::SV_SF_3 ? + Unavailable : Unknown; + if (availability == Unknown) { + // Actually, we should ask CFeatureDiscovery::IsFeatureSupportedL() + // with FfFontTable here. But since at the time of writing, the + // FfFontTable flag check either gave false positives or false + // negatives. Here comes an implicit check via CFont::ExtendedFunction. + QSymbianTGetFontTableParam fontTableParams = { + MAKE_TAG('O', 'S', '/', '2'), 0, 0 }; + QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); + CFont *font; + const TInt getFontErr = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec()); + Q_ASSERT(getFontErr == KErrNone); + if (font->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + font->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + availability = Available; + } else { + availability = Unavailable; + } + S60->screenDevice()->ReleaseFont(font); + lock.relock(); + } + return availability == Available; +} + // duplicated from qfontengine_xyz.cpp static inline unsigned int getChar(const QChar *str, int &i, const int len) { diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index c65ce55..cdf2185 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -58,13 +58,11 @@ #include "qsize.h" #include <openfont.h> -#ifdef SYMBIAN_GDI_GLYPHDATA -#define Q_SYMBIAN_HAS_FONTTABLE_API -#endif - -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +// The glyph outline code is intentionally disabled. It will be reactivated as +// soon as the glyph outline API is backported from Symbian(^4) to Symbian(^3). +#if 0 #define Q_SYMBIAN_HAS_GLYPHOUTLINE_API -#endif // Q_SYMBIAN_HAS_FONTTABLE_API +#endif class CFont; @@ -83,16 +81,18 @@ public: CFont *fontOwner() const; bool isSymbolCMap() const; QFixed unitsPerEm() const; + static bool symbianFontTableApiAvailable(); private: CFont* m_cFont; mutable bool m_symbolCMap; mutable QByteArray m_cmapTable; mutable QFixed m_unitsPerEm; -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + + // m_openFont and m_openFont are used if Symbian does not provide + // the Font Table API COpenFont *m_openFont; mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; -#endif // Q_SYMBIAN_HAS_FONTTABLE_API }; class QFontEngineS60 : public QFontEngine |