src/gui/text/qfontdatabase_s60.cpp
changeset 30 5dc02b23752f
parent 29 b72c6db6890b
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    47 #include "qdesktopservices.h"
    47 #include "qdesktopservices.h"
    48 #include <private/qpixmap_s60_p.h>
    48 #include <private/qpixmap_s60_p.h>
    49 #include <private/qt_s60_p.h>
    49 #include <private/qt_s60_p.h>
    50 #include "qendian.h"
    50 #include "qendian.h"
    51 #include <private/qcore_symbian_p.h>
    51 #include <private/qcore_symbian_p.h>
    52 #ifdef QT_NO_FREETYPE
    52 #if defined(QT_NO_FREETYPE)
    53 #include <openfont.h>
    53 #include <openfont.h>
    54 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    54 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    55 #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
    55 #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
    56 #endif // SYMBIAN_ENABLE_SPLIT_HEADERS
    56 #endif // SYMBIAN_ENABLE_SPLIT_HEADERS
    57 #endif // QT_NO_FREETYPE
    57 #endif
    58 
    58 
    59 QT_BEGIN_NAMESPACE
    59 QT_BEGIN_NAMESPACE
    60 
    60 
    61 QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameFilters,
    61 QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameFilters,
    62     QDir::Filters filters = QDir::NoFilter, QDir::SortFlags sort = QDir::NoSort,
    62     QDir::Filters filters = QDir::NoFilter, QDir::SortFlags sort = QDir::NoSort,
    89         }
    89         }
    90     }
    90     }
    91     return result;
    91     return result;
    92 }
    92 }
    93 
    93 
    94 #ifdef QT_NO_FREETYPE
    94 #if defined(QT_NO_FREETYPE)
    95 class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
    95 class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
    96 {
    96 {
    97 public:
    97 public:
    98     QSymbianFontDatabaseExtrasImplementation();
    98     QSymbianFontDatabaseExtrasImplementation();
    99     ~QSymbianFontDatabaseExtrasImplementation();
    99     ~QSymbianFontDatabaseExtrasImplementation();
   100 
   100 
   101     const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
   101     const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
   102 
   102 
   103 #ifndef Q_SYMBIAN_HAS_FONTTABLE_API
       
   104     struct CFontFromFontStoreReleaser {
       
   105         static inline void cleanup(CFont *font)
       
   106         {
       
   107             if (!font)
       
   108                 return;
       
   109             const QSymbianFontDatabaseExtrasImplementation *dbExtras =
       
   110                     static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras);
       
   111             dbExtras->m_store->ReleaseFont(font);
       
   112         }
       
   113     };
       
   114 #endif // !Q_SYMBIAN_HAS_FONTTABLE_API
       
   115 
       
   116     struct CFontFromScreenDeviceReleaser {
       
   117         static inline void cleanup(CFont *font)
       
   118         {
       
   119             if (!font)
       
   120                 return;
       
   121             QS60Data::screenDevice()->ReleaseFont(font);
       
   122         }
       
   123     };
       
   124 
       
   125 private:
   103 private:
   126 #ifndef Q_SYMBIAN_HAS_FONTTABLE_API
       
   127     RHeap* m_heap;
   104     RHeap* m_heap;
   128     CFontStore *m_store;
   105     CFontStore *m_store;
   129     COpenFontRasterizer *m_rasterizer;
   106     COpenFontRasterizer *m_rasterizer;
   130     mutable QList<const QSymbianTypeFaceExtras *> m_extras;
   107     mutable QList<const QSymbianTypeFaceExtras *> m_extras;
   131 #endif // !Q_SYMBIAN_HAS_FONTTABLE_API
       
   132     mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
   108     mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
   133 };
   109 };
   134 
   110 
   135 QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
   111 QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
   136 {
   112 {
   137 #ifndef Q_SYMBIAN_HAS_FONTTABLE_API
       
   138     QStringList filters;
   113     QStringList filters;
   139     filters.append(QLatin1String("*.ttf"));
   114     filters.append(QLatin1String("*.ttf"));
   140     filters.append(QLatin1String("*.ccc"));
   115     filters.append(QLatin1String("*.ccc"));
   141     filters.append(QLatin1String("*.ltt"));
   116     filters.append(QLatin1String("*.ltt"));
   142     const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters);
   117     const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters);
   154     foreach (const QFileInfo &fontFileInfo, fontFiles) {
   129     foreach (const QFileInfo &fontFileInfo, fontFiles) {
   155         const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
   130         const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
   156         TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
   131         TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
   157         QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
   132         QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
   158     }
   133     }
   159 #endif // !Q_SYMBIAN_HAS_FONTTABLE_API
       
   160 }
   134 }
   161 
   135 
   162 QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
   136 QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
   163 {
   137 {
   164 #ifdef Q_SYMBIAN_HAS_FONTTABLE_API
       
   165     qDeleteAll(m_extrasHash);
       
   166 #else // Q_SYMBIAN_HAS_FONTTABLE_API
       
   167     typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
   138     typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
   168     for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
   139     for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
   169         m_store->ReleaseFont((*p)->fontOwner());
   140         m_store->ReleaseFont((*p)->fontOwner());
   170         delete *p;
   141         delete *p;
   171     }
   142     }
   172 
   143 
   173     delete m_store;
   144     delete m_store;
   174     m_heap->Close();
   145     m_heap->Close();
   175 #endif // Q_SYMBIAN_HAS_FONTTABLE_API
       
   176 }
   146 }
   177 
   147 
   178 #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM
   148 #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM
   179 /*
   149 /*
   180  Workaround: fntstore.h has an inlined function 'COpenFont* CBitmapFont::OpenFont()'
   150  Workaround: fntstore.h has an inlined function 'COpenFont* CBitmapFont::OpenFont()'
   195 const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
   165 const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
   196                                                                                bool bold, bool italic) const
   166                                                                                bool bold, bool italic) const
   197 {
   167 {
   198     const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
   168     const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
   199     if (!m_extrasHash.contains(searchKey)) {
   169     if (!m_extrasHash.contains(searchKey)) {
       
   170         CFont* font = NULL;
   200         TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
   171         TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
   201         if (bold)
   172         if (bold)
   202             searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
   173             searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
   203         if (italic)
   174         if (italic)
   204             searchSpec.iFontStyle.SetPosture(EPostureItalic);
   175             searchSpec.iFontStyle.SetPosture(EPostureItalic);
   205 
       
   206         CFont* font = NULL;
       
   207 #ifdef Q_SYMBIAN_HAS_FONTTABLE_API
       
   208         const TInt err = QS60Data::screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec);
       
   209         Q_ASSERT(err == KErrNone && font);
       
   210         QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font);
       
   211         QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font);
       
   212         sFont.take();
       
   213         m_extrasHash.insert(searchKey, extras);
       
   214 #else // Q_SYMBIAN_HAS_FONTTABLE_API
       
   215         const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
   176         const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
   216         Q_ASSERT(err == KErrNone && font);
   177         Q_ASSERT(err == KErrNone && font);
   217         const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
   178         const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
   218         COpenFont *openFont =
   179         COpenFont *openFont =
   219 #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM
   180 #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM
   220             bitmapFont->OpenFont();
   181             bitmapFont->openFont();
   221 #else // FNTSTORE_H_INLINES_SUPPORT_FMM
   182 #else
   222             OpenFontFromBitmapFont(bitmapFont);
   183             OpenFontFromBitmapFont(bitmapFont);
   223 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
   184 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
   224         const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
   185         const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
   225         const QString foundKey =
   186         const QString foundKey =
   226                 QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
   187                 QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
   227         if (!m_extrasHash.contains(foundKey)) {
   188         if (!m_extrasHash.contains(foundKey)) {
   228             QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font);
       
   229             QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
   189             QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
   230             sFont.take();
       
   231             m_extras.append(extras);
   190             m_extras.append(extras);
   232             m_extrasHash.insert(searchKey, extras);
   191             m_extrasHash.insert(searchKey, extras);
   233             m_extrasHash.insert(foundKey, extras);
   192             m_extrasHash.insert(foundKey, extras);
   234         } else {
   193         } else {
   235             m_store->ReleaseFont(font);
   194             m_store->ReleaseFont(font);
   236             m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
   195             m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
   237         }
   196         }
   238 #endif // Q_SYMBIAN_HAS_FONTTABLE_API
       
   239     }
   197     }
   240     return m_extrasHash.value(searchKey);
   198     return m_extrasHash.value(searchKey);
   241 }
   199 }
   242 #else // QT_NO_FREETYPE
   200 #else
   243 class QFontEngineFTS60 : public QFontEngineFT
   201 class QFontEngineFTS60 : public QFontEngineFT
   244 {
   202 {
   245 public:
   203 public:
   246     QFontEngineFTS60(const QFontDef &fd);
   204     QFontEngineFTS60(const QFontDef &fd);
   247 };
   205 };
   249 QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd)
   207 QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd)
   250     : QFontEngineFT(fd)
   208     : QFontEngineFT(fd)
   251 {
   209 {
   252     default_hint_style = HintFull;
   210     default_hint_style = HintFull;
   253 }
   211 }
   254 #endif // QT_NO_FREETYPE
   212 #endif // defined(QT_NO_FREETYPE)
   255 
   213 
   256 /*
   214 /*
   257  QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60
   215  QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60
   258  and QFontEngineMultiS60::QFontEngineMultiS60 should be in qfontengine_s60.cpp. But since also the
   216  and QFontEngineMultiS60::QFontEngineMultiS60 should be in qfontengine_s60.cpp. But since also the
   259  Freetype based font rendering need them, they are here.
   217  Freetype based font rendering need them, they are here.
   301 {
   259 {
   302     QFontDatabasePrivate *db = privateDb();
   260     QFontDatabasePrivate *db = privateDb();
   303     if(!db || db->count)
   261     if(!db || db->count)
   304         return;
   262         return;
   305 
   263 
   306 #ifdef QT_NO_FREETYPE
   264 #if defined(QT_NO_FREETYPE)
   307     if (!db->symbianExtras)
   265     if (!db->symbianExtras)
   308         db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
   266         db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
   309 
   267 
   310     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
   268     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
   311 
   269     
   312     const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
   270     const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
   313     const QSymbianFontDatabaseExtrasImplementation *dbExtras =
   271     const QSymbianFontDatabaseExtrasImplementation *dbExtras =
   314             static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
   272             static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
   315     bool fontAdded = false;
   273     bool fontAdded = false;
   316     for (int i = 0; i < numTypeFaces; i++) {
   274     for (int i = 0; i < numTypeFaces; i++) {
   318         QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i);
   276         QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i);
   319         CFont *font; // We have to get a font instance in order to know all the details
   277         CFont *font; // We have to get a font instance in order to know all the details
   320         TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11);
   278         TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11);
   321         if (QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
   279         if (QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
   322             continue;
   280             continue;
   323         QScopedPointer<CFont, QSymbianFontDatabaseExtrasImplementation::CFontFromScreenDeviceReleaser> sFont(font);
       
   324         if (font->TypeUid() == KCFbsFontUid) {
   281         if (font->TypeUid() == KCFbsFontUid) {
   325             TOpenFontFaceAttrib faceAttrib;
   282             TOpenFontFaceAttrib faceAttrib;
   326             const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font);
   283             const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font);
   327             cfbsFont->GetFaceAttrib(faceAttrib);
   284             cfbsFont->GetFaceAttrib(faceAttrib);
   328 
   285 
   359             foreach (const QFontDatabase::WritingSystem system, writingSystems)
   316             foreach (const QFontDatabase::WritingSystem system, writingSystems)
   360                 family->writingSystems[system] = QtFontFamily::Supported;
   317                 family->writingSystems[system] = QtFontFamily::Supported;
   361 
   318 
   362             fontAdded = true;
   319             fontAdded = true;
   363         }
   320         }
       
   321         QS60Data::screenDevice()->ReleaseFont(font);
   364     }
   322     }
   365 
   323 
   366     Q_ASSERT(fontAdded);
   324     Q_ASSERT(fontAdded);
   367     
   325     
   368     lock.relock();
   326 	lock.relock();
   369 
   327 
   370 #else // QT_NO_FREETYPE
   328 #else // defined(QT_NO_FREETYPE)
   371     QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation));
   329     QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation));
   372     dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
   330     dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
   373                        << QLatin1String("*.ttc") << QLatin1String("*.pfa")
   331                        << QLatin1String("*.ttc") << QLatin1String("*.pfa")
   374                        << QLatin1String("*.pfb"));
   332                        << QLatin1String("*.pfb"));
   375     for (int i = 0; i < int(dir.count()); ++i) {
   333     for (int i = 0; i < int(dir.count()); ++i) {
   376         const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
   334         const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
   377         db->addTTFile(file);
   335         db->addTTFile(file);
   378     }
   336     }
   379 #endif // QT_NO_FREETYPE
   337 #endif // defined(QT_NO_FREETYPE)
   380 }
   338 }
   381 
   339 
   382 static inline void load(const QString &family = QString(), int script = -1)
   340 static inline void load(const QString &family = QString(), int script = -1)
   383 {
   341 {
   384     Q_UNUSED(family)
   342     Q_UNUSED(family)
   456         }
   414         }
   457 
   415 
   458         const QString fontFamily = desc.family->name;
   416         const QString fontFamily = desc.family->name;
   459         QFontDef request = req;
   417         QFontDef request = req;
   460         request.family = fontFamily;
   418         request.family = fontFamily;
   461 #ifdef QT_NO_FREETYPE
   419 #if defined(QT_NO_FREETYPE)
   462         const QSymbianFontDatabaseExtrasImplementation *dbExtras =
   420         const QSymbianFontDatabaseExtrasImplementation *dbExtras =
   463                 static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
   421                 static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
   464         const QSymbianTypeFaceExtras *typeFaceExtras =
   422         const QSymbianTypeFaceExtras *typeFaceExtras =
   465                 dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
   423                 dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
   466         fe = new QFontEngineS60(request, typeFaceExtras);
   424         fe = new QFontEngineS60(request, typeFaceExtras);
   467 #else // QT_NO_FREETYPE
   425 #else
   468         QFontEngine::FaceId faceId;
   426         QFontEngine::FaceId faceId;
   469         const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);
   427         const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);
   470         faceId.filename = reqQtFontFamily->fontFilename;
   428         faceId.filename = reqQtFontFamily->fontFilename;
   471         faceId.index = reqQtFontFamily->fontFileIndex;
   429         faceId.index = reqQtFontFamily->fontFileIndex;
   472 
   430 
   473         QFontEngineFTS60 *fte = new QFontEngineFTS60(cleanedFontDef(request));
   431         QFontEngineFTS60 *fte = new QFontEngineFTS60(cleanedFontDef(request));
   474         if (fte->init(faceId, true, QFontEngineFT::Format_A8))
   432         if (fte->init(faceId, true, QFontEngineFT::Format_A8))
   475             fe = fte;
   433             fe = fte;
   476         else
   434         else
   477             delete fte;
   435             delete fte;
   478 #endif // QT_NO_FREETYPE
   436 #endif
   479 
   437 
   480         Q_ASSERT(fe);
   438         Q_ASSERT(fe);
   481         if (script == QUnicodeTables::Common
   439         if (script == QUnicodeTables::Common
   482             && !(req.styleStrategy & QFont::NoFontMerging)
   440             && !(req.styleStrategy & QFont::NoFontMerging)
   483             && !fe->symbol) {
   441             && !fe->symbol) {