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 }; |
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) { |