src/gui/text/qfontdatabase_s60.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
--- a/src/gui/text/qfontdatabase_s60.cpp	Mon Jun 21 22:38:13 2010 +0100
+++ b/src/gui/text/qfontdatabase_s60.cpp	Thu Jul 22 16:41:55 2010 +0100
@@ -45,8 +45,8 @@
 #include "qfontengine_s60_p.h"
 #include "qabstractfileengine.h"
 #include "qdesktopservices.h"
-#include "qpixmap_s60_p.h"
-#include "qt_s60_p.h"
+#include <private/qpixmap_s60_p.h>
+#include <private/qt_s60_p.h>
 #include "qendian.h"
 #include <private/qcore_symbian_p.h>
 #if defined(QT_NO_FREETYPE)
@@ -92,24 +92,33 @@
 }
 
 #if defined(QT_NO_FREETYPE)
-class QFontDatabaseS60StoreImplementation : public QFontDatabaseS60Store
+class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
 {
 public:
-    QFontDatabaseS60StoreImplementation();
-    ~QFontDatabaseS60StoreImplementation();
+    QSymbianFontDatabaseExtrasImplementation();
+    ~QSymbianFontDatabaseExtrasImplementation();
 
-    const QFontEngineS60Extensions *extension(const QString &typeface) const;
+    const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
 
 private:
     RHeap* m_heap;
     CFontStore *m_store;
     COpenFontRasterizer *m_rasterizer;
-    mutable QHash<QString, const QFontEngineS60Extensions *> m_extensions;
+    mutable QList<const QSymbianTypeFaceExtras *> m_extras;
+    mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
 };
 
-QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation()
+QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
 {
-    m_heap = User::ChunkHeap(NULL, 0x1000, 0x100000);
+    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));
@@ -117,20 +126,17 @@
         m_store->InstallRasterizerL(m_rasterizer);
         CleanupStack::Pop(m_rasterizer););
 
-    QStringList filters;
-    filters.append(QString::fromLatin1("*.ttf"));
-    filters.append(QString::fromLatin1("*.ccc"));
-    const QFileInfoList fontFiles = alternativeFilePaths(QString::fromLatin1("resource\\Fonts"), filters);
     foreach (const QFileInfo &fontFileInfo, fontFiles) {
         const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
         TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
         QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
     }
 }
-QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation()
+
+QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
 {
-    typedef QHash<QString, const QFontEngineS60Extensions *>::iterator iterator;
-    for (iterator p = m_extensions.begin(); p != m_extensions.end(); ++p) {
+    typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
+    for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
         m_store->ReleaseFont((*p)->fontOwner());
         delete *p;
     }
@@ -156,13 +162,18 @@
 }
 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
 
-const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const
+const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
+                                                                               bool bold, bool italic) const
 {
-    if (!m_extensions.contains(typeface)) {
+    const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
+    if (!m_extrasHash.contains(searchKey)) {
         CFont* font = NULL;
-        TFontSpec spec(qt_QString2TPtrC(typeface), 1);
-        spec.iHeight = 1;
-        const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec);
+        TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
+        if (bold)
+            searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
+        if (italic)
+            searchSpec.iFontStyle.SetPosture(EPostureItalic);
+        const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
         Q_ASSERT(err == KErrNone && font);
         const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
         COpenFont *openFont =
@@ -171,9 +182,20 @@
 #else
             OpenFontFromBitmapFont(bitmapFont);
 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
-        m_extensions.insert(typeface, new QFontEngineS60Extensions(font, openFont));
+        const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
+        const QString foundKey =
+                QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
+        if (!m_extrasHash.contains(foundKey)) {
+            QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
+            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));
+        }
     }
-    return m_extensions.value(typeface);
+    return m_extrasHash.value(searchKey);
 }
 #else
 class QFontEngineFTS60 : public QFontEngineFT
@@ -240,14 +262,14 @@
         return;
 
 #if defined(QT_NO_FREETYPE)
-    if (!db->s60Store)
-        db->s60Store = new QFontDatabaseS60StoreImplementation;
+    if (!db->symbianExtras)
+        db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
 
     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
     
     const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
-    const QFontDatabaseS60StoreImplementation *store =
-            static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
+    const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+            static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
     bool fontAdded = false;
     for (int i = 0; i < numTypeFaces; i++) {
         TTypefaceSupport typefaceSupport;
@@ -273,8 +295,9 @@
             style->smoothScalable = typefaceSupport.iIsScalable;
             style->pixelSize(0, true);
 
-            const QFontEngineS60Extensions *extension = store->extension(familyName);
-            const QByteArray os2Table = extension->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
+            const QSymbianTypeFaceExtras *typeFaceExtras =
+                    dbExtras->extras(familyName, faceAttrib.IsBold(), faceAttrib.IsItalic());
+            const QByteArray os2Table = typeFaceExtras->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
             const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData());
             const unsigned char* ulUnicodeRange = data + 42;
             quint32 unicodeRange[4] = {
@@ -394,10 +417,11 @@
         QFontDef request = req;
         request.family = fontFamily;
 #if defined(QT_NO_FREETYPE)
-        const QFontDatabaseS60StoreImplementation *store =
-                static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
-        const QFontEngineS60Extensions *extension = store->extension(fontFamily);
-        fe = new QFontEngineS60(request, extension);
+        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
         QFontEngine::FaceId faceId;
         const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);