src/gui/text/qfontdatabase_s60.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
--- a/src/gui/text/qfontdatabase_s60.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/text/qfontdatabase_s60.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -49,12 +49,12 @@
 #include <private/qt_s60_p.h>
 #include "qendian.h"
 #include <private/qcore_symbian_p.h>
-#if defined(QT_NO_FREETYPE)
+#ifdef QT_NO_FREETYPE
 #include <openfont.h>
 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
 #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
 #endif // SYMBIAN_ENABLE_SPLIT_HEADERS
-#endif
+#endif // QT_NO_FREETYPE
 
 QT_BEGIN_NAMESPACE
 
@@ -91,7 +91,7 @@
     return result;
 }
 
-#if defined(QT_NO_FREETYPE)
+#ifdef QT_NO_FREETYPE
 class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
 {
 public:
@@ -100,16 +100,40 @@
 
     const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
 
-private:
+#ifndef Q_SYMBIAN_HAS_FONTTABLE_API
+    struct CFontFromFontStoreReleaser {
+        static inline void cleanup(CFont *font)
+        {
+            if (!font)
+                return;
+            const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+                    static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras);
+            dbExtras->m_store->ReleaseFont(font);
+        }
+    };
+#endif // !Q_SYMBIAN_HAS_FONTTABLE_API
+
+    struct CFontFromScreenDeviceReleaser {
+        static inline void cleanup(CFont *font)
+        {
+            if (!font)
+                return;
+            S60->screenDevice()->ReleaseFont(font);
+        }
+    };
+
+#ifndef Q_SYMBIAN_HAS_FONTTABLE_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"));
@@ -131,18 +155,35 @@
         TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
         QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
     }
+#endif // !Q_SYMBIAN_HAS_FONTTABLE_API
+}
+
+void qt_cleanup_symbianFontDatabaseExtras()
+{
+    const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+            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;
+    }
+    dbExtras->m_extras.clear();
+#endif // Q_SYMBIAN_HAS_FONTTABLE_API
+    dbExtras->m_extrasHash.clear();
 }
 
 QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
 {
-    typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
-    for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
-        m_store->ReleaseFont((*p)->fontOwner());
-        delete *p;
-    }
-
+    qt_cleanup_symbianFontDatabaseExtras();
+#ifndef Q_SYMBIAN_HAS_FONTTABLE_API
     delete m_store;
     m_heap->Close();
+#endif // !Q_SYMBIAN_HAS_FONTTABLE_API
 }
 
 #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM
@@ -167,26 +208,37 @@
 {
     const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
     if (!m_extrasHash.contains(searchKey)) {
-        CFont* font = NULL;
         TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
         if (bold)
             searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
         if (italic)
             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
+            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);
@@ -194,10 +246,11 @@
             m_store->ReleaseFont(font);
             m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
         }
+#endif // Q_SYMBIAN_HAS_FONTTABLE_API
     }
     return m_extrasHash.value(searchKey);
 }
-#else
+#else // QT_NO_FREETYPE
 class QFontEngineFTS60 : public QFontEngineFT
 {
 public:
@@ -209,7 +262,7 @@
 {
     default_hint_style = HintFull;
 }
-#endif // defined(QT_NO_FREETYPE)
+#endif // QT_NO_FREETYPE
 
 /*
  QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60
@@ -218,17 +271,19 @@
 */
 qreal QFontEngineS60::pixelsToPoints(qreal pixels, Qt::Orientation orientation)
 {
+    CWsScreenDevice* device = S60->screenDevice();
     return (orientation == Qt::Horizontal?
-        S60->screenDevice()->HorizontalPixelsToTwips(pixels)
-        :S60->screenDevice()->VerticalPixelsToTwips(pixels)) / KTwipsPerPoint;
+        device->HorizontalPixelsToTwips(pixels)
+        :device->VerticalPixelsToTwips(pixels)) / KTwipsPerPoint;
 }
 
 qreal QFontEngineS60::pointsToPixels(qreal points, Qt::Orientation orientation)
 {
+    CWsScreenDevice* device = S60->screenDevice();
     const int twips = points * KTwipsPerPoint;
     return orientation == Qt::Horizontal?
-        S60->screenDevice()->HorizontalTwipsToPixels(twips)
-        :S60->screenDevice()->VerticalTwipsToPixels(twips);
+        device->HorizontalTwipsToPixels(twips)
+        :device->VerticalTwipsToPixels(twips);
 }
 
 QFontEngineMultiS60::QFontEngineMultiS60(QFontEngine *first, int script, const QStringList &fallbackFamilies)
@@ -261,23 +316,24 @@
     if(!db || db->count)
         return;
 
-#if defined(QT_NO_FREETYPE)
+#ifdef QT_NO_FREETYPE
     if (!db->symbianExtras)
         db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
 
     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-    
-    const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
+
+    const int numTypeFaces = S60->screenDevice()->NumTypefaces();
     const QSymbianFontDatabaseExtrasImplementation *dbExtras =
             static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
     bool fontAdded = false;
     for (int i = 0; i < numTypeFaces; i++) {
         TTypefaceSupport typefaceSupport;
-        QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i);
+        S60->screenDevice()->TypefaceSupport(typefaceSupport, i);
         CFont *font; // We have to get a font instance in order to know all the details
         TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11);
-        if (QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
+        if (S60->screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
             continue;
+        QScopedPointer<CFont, QSymbianFontDatabaseExtrasImplementation::CFontFromScreenDeviceReleaser> sFont(font);
         if (font->TypeUid() == KCFbsFontUid) {
             TOpenFontFaceAttrib faceAttrib;
             const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font);
@@ -318,14 +374,13 @@
 
             fontAdded = true;
         }
-        QS60Data::screenDevice()->ReleaseFont(font);
     }
 
     Q_ASSERT(fontAdded);
     
-	lock.relock();
+    lock.relock();
 
-#else // defined(QT_NO_FREETYPE)
+#else // QT_NO_FREETYPE
     QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation));
     dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
                        << QLatin1String("*.ttc") << QLatin1String("*.pfa")
@@ -334,7 +389,7 @@
         const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
         db->addTTFile(file);
     }
-#endif // defined(QT_NO_FREETYPE)
+#endif // QT_NO_FREETYPE
 }
 
 static inline void load(const QString &family = QString(), int script = -1)
@@ -416,13 +471,13 @@
         const QString fontFamily = desc.family->name;
         QFontDef request = req;
         request.family = fontFamily;
-#if defined(QT_NO_FREETYPE)
+#ifdef QT_NO_FREETYPE
         const QSymbianFontDatabaseExtrasImplementation *dbExtras =
                 static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
         const QSymbianTypeFaceExtras *typeFaceExtras =
                 dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
         fe = new QFontEngineS60(request, typeFaceExtras);
-#else
+#else // QT_NO_FREETYPE
         QFontEngine::FaceId faceId;
         const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);
         faceId.filename = reqQtFontFamily->fontFilename;
@@ -433,7 +488,7 @@
             fe = fte;
         else
             delete fte;
-#endif
+#endif // QT_NO_FREETYPE
 
         Q_ASSERT(fe);
         if (script == QUnicodeTables::Common