43 #include "qdir.h" |
43 #include "qdir.h" |
44 #include "qfont_p.h" |
44 #include "qfont_p.h" |
45 #include "qfontengine_s60_p.h" |
45 #include "qfontengine_s60_p.h" |
46 #include "qabstractfileengine.h" |
46 #include "qabstractfileengine.h" |
47 #include "qdesktopservices.h" |
47 #include "qdesktopservices.h" |
48 #include "qpixmap_s60_p.h" |
48 #include <private/qpixmap_s60_p.h> |
49 #include "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 #if defined(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 |
90 } |
90 } |
91 return result; |
91 return result; |
92 } |
92 } |
93 |
93 |
94 #if defined(QT_NO_FREETYPE) |
94 #if defined(QT_NO_FREETYPE) |
95 class QFontDatabaseS60StoreImplementation : public QFontDatabaseS60Store |
95 class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras |
96 { |
96 { |
97 public: |
97 public: |
98 QFontDatabaseS60StoreImplementation(); |
98 QSymbianFontDatabaseExtrasImplementation(); |
99 ~QFontDatabaseS60StoreImplementation(); |
99 ~QSymbianFontDatabaseExtrasImplementation(); |
100 |
100 |
101 const QFontEngineS60Extensions *extension(const QString &typeface) const; |
101 const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const; |
102 |
102 |
103 private: |
103 private: |
104 RHeap* m_heap; |
104 RHeap* m_heap; |
105 CFontStore *m_store; |
105 CFontStore *m_store; |
106 COpenFontRasterizer *m_rasterizer; |
106 COpenFontRasterizer *m_rasterizer; |
107 mutable QHash<QString, const QFontEngineS60Extensions *> m_extensions; |
107 mutable QList<const QSymbianTypeFaceExtras *> m_extras; |
|
108 mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; |
108 }; |
109 }; |
109 |
110 |
110 QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation() |
111 QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() |
111 { |
112 { |
112 m_heap = User::ChunkHeap(NULL, 0x1000, 0x100000); |
113 QStringList filters; |
|
114 filters.append(QLatin1String("*.ttf")); |
|
115 filters.append(QLatin1String("*.ccc")); |
|
116 filters.append(QLatin1String("*.ltt")); |
|
117 const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters); |
|
118 |
|
119 const TInt heapMinLength = 0x1000; |
|
120 const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength); |
|
121 m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength); |
113 QT_TRAP_THROWING( |
122 QT_TRAP_THROWING( |
114 m_store = CFontStore::NewL(m_heap); |
123 m_store = CFontStore::NewL(m_heap); |
115 m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); |
124 m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); |
116 CleanupStack::PushL(m_rasterizer); |
125 CleanupStack::PushL(m_rasterizer); |
117 m_store->InstallRasterizerL(m_rasterizer); |
126 m_store->InstallRasterizerL(m_rasterizer); |
118 CleanupStack::Pop(m_rasterizer);); |
127 CleanupStack::Pop(m_rasterizer);); |
119 |
128 |
120 QStringList filters; |
|
121 filters.append(QString::fromLatin1("*.ttf")); |
|
122 filters.append(QString::fromLatin1("*.ccc")); |
|
123 const QFileInfoList fontFiles = alternativeFilePaths(QString::fromLatin1("resource\\Fonts"), filters); |
|
124 foreach (const QFileInfo &fontFileInfo, fontFiles) { |
129 foreach (const QFileInfo &fontFileInfo, fontFiles) { |
125 const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath()); |
130 const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath()); |
126 TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); |
131 TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); |
127 QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); |
132 QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); |
128 } |
133 } |
129 } |
134 } |
130 QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation() |
135 |
131 { |
136 QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation() |
132 typedef QHash<QString, const QFontEngineS60Extensions *>::iterator iterator; |
137 { |
133 for (iterator p = m_extensions.begin(); p != m_extensions.end(); ++p) { |
138 typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; |
|
139 for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) { |
134 m_store->ReleaseFont((*p)->fontOwner()); |
140 m_store->ReleaseFont((*p)->fontOwner()); |
135 delete *p; |
141 delete *p; |
136 } |
142 } |
137 |
143 |
138 delete m_store; |
144 delete m_store; |
154 (COpenFont*)PtrAdd(aBitmapFont, valueIOpenFont & ~1) : // New behavior: iOpenFont is offset |
160 (COpenFont*)PtrAdd(aBitmapFont, valueIOpenFont & ~1) : // New behavior: iOpenFont is offset |
155 (COpenFont*)valueIOpenFont; // Old behavior: iOpenFont is pointer |
161 (COpenFont*)valueIOpenFont; // Old behavior: iOpenFont is pointer |
156 } |
162 } |
157 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM |
163 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM |
158 |
164 |
159 const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const |
165 const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface, |
160 { |
166 bool bold, bool italic) const |
161 if (!m_extensions.contains(typeface)) { |
167 { |
|
168 const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); |
|
169 if (!m_extrasHash.contains(searchKey)) { |
162 CFont* font = NULL; |
170 CFont* font = NULL; |
163 TFontSpec spec(qt_QString2TPtrC(typeface), 1); |
171 TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); |
164 spec.iHeight = 1; |
172 if (bold) |
165 const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec); |
173 searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); |
|
174 if (italic) |
|
175 searchSpec.iFontStyle.SetPosture(EPostureItalic); |
|
176 const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); |
166 Q_ASSERT(err == KErrNone && font); |
177 Q_ASSERT(err == KErrNone && font); |
167 const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); |
178 const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); |
168 COpenFont *openFont = |
179 COpenFont *openFont = |
169 #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM |
180 #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM |
170 bitmapFont->openFont(); |
181 bitmapFont->openFont(); |
171 #else |
182 #else |
172 OpenFontFromBitmapFont(bitmapFont); |
183 OpenFontFromBitmapFont(bitmapFont); |
173 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM |
184 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM |
174 m_extensions.insert(typeface, new QFontEngineS60Extensions(font, openFont)); |
185 const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); |
175 } |
186 const QString foundKey = |
176 return m_extensions.value(typeface); |
187 QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); |
|
188 if (!m_extrasHash.contains(foundKey)) { |
|
189 QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); |
|
190 m_extras.append(extras); |
|
191 m_extrasHash.insert(searchKey, extras); |
|
192 m_extrasHash.insert(foundKey, extras); |
|
193 } else { |
|
194 m_store->ReleaseFont(font); |
|
195 m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); |
|
196 } |
|
197 } |
|
198 return m_extrasHash.value(searchKey); |
177 } |
199 } |
178 #else |
200 #else |
179 class QFontEngineFTS60 : public QFontEngineFT |
201 class QFontEngineFTS60 : public QFontEngineFT |
180 { |
202 { |
181 public: |
203 public: |
238 QFontDatabasePrivate *db = privateDb(); |
260 QFontDatabasePrivate *db = privateDb(); |
239 if(!db || db->count) |
261 if(!db || db->count) |
240 return; |
262 return; |
241 |
263 |
242 #if defined(QT_NO_FREETYPE) |
264 #if defined(QT_NO_FREETYPE) |
243 if (!db->s60Store) |
265 if (!db->symbianExtras) |
244 db->s60Store = new QFontDatabaseS60StoreImplementation; |
266 db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation; |
245 |
267 |
246 QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); |
268 QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); |
247 |
269 |
248 const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); |
270 const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); |
249 const QFontDatabaseS60StoreImplementation *store = |
271 const QSymbianFontDatabaseExtrasImplementation *dbExtras = |
250 static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); |
272 static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); |
251 bool fontAdded = false; |
273 bool fontAdded = false; |
252 for (int i = 0; i < numTypeFaces; i++) { |
274 for (int i = 0; i < numTypeFaces; i++) { |
253 TTypefaceSupport typefaceSupport; |
275 TTypefaceSupport typefaceSupport; |
254 QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i); |
276 QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i); |
255 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 |
271 QtFontFoundry *foundry = family->foundry(QString(), true); |
293 QtFontFoundry *foundry = family->foundry(QString(), true); |
272 QtFontStyle *style = foundry->style(styleKey, true); |
294 QtFontStyle *style = foundry->style(styleKey, true); |
273 style->smoothScalable = typefaceSupport.iIsScalable; |
295 style->smoothScalable = typefaceSupport.iIsScalable; |
274 style->pixelSize(0, true); |
296 style->pixelSize(0, true); |
275 |
297 |
276 const QFontEngineS60Extensions *extension = store->extension(familyName); |
298 const QSymbianTypeFaceExtras *typeFaceExtras = |
277 const QByteArray os2Table = extension->getSfntTable(MAKE_TAG('O', 'S', '/', '2')); |
299 dbExtras->extras(familyName, faceAttrib.IsBold(), faceAttrib.IsItalic()); |
|
300 const QByteArray os2Table = typeFaceExtras->getSfntTable(MAKE_TAG('O', 'S', '/', '2')); |
278 const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData()); |
301 const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData()); |
279 const unsigned char* ulUnicodeRange = data + 42; |
302 const unsigned char* ulUnicodeRange = data + 42; |
280 quint32 unicodeRange[4] = { |
303 quint32 unicodeRange[4] = { |
281 qFromBigEndian<quint32>(ulUnicodeRange), |
304 qFromBigEndian<quint32>(ulUnicodeRange), |
282 qFromBigEndian<quint32>(ulUnicodeRange + 4), |
305 qFromBigEndian<quint32>(ulUnicodeRange + 4), |
392 |
415 |
393 const QString fontFamily = desc.family->name; |
416 const QString fontFamily = desc.family->name; |
394 QFontDef request = req; |
417 QFontDef request = req; |
395 request.family = fontFamily; |
418 request.family = fontFamily; |
396 #if defined(QT_NO_FREETYPE) |
419 #if defined(QT_NO_FREETYPE) |
397 const QFontDatabaseS60StoreImplementation *store = |
420 const QSymbianFontDatabaseExtrasImplementation *dbExtras = |
398 static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); |
421 static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); |
399 const QFontEngineS60Extensions *extension = store->extension(fontFamily); |
422 const QSymbianTypeFaceExtras *typeFaceExtras = |
400 fe = new QFontEngineS60(request, extension); |
423 dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal); |
|
424 fe = new QFontEngineS60(request, typeFaceExtras); |
401 #else |
425 #else |
402 QFontEngine::FaceId faceId; |
426 QFontEngine::FaceId faceId; |
403 const QtFontFamily * const reqQtFontFamily = db->family(fontFamily); |
427 const QtFontFamily * const reqQtFontFamily = db->family(fontFamily); |
404 faceId.filename = reqQtFontFamily->fontFilename; |
428 faceId.filename = reqQtFontFamily->fontFilename; |
405 faceId.index = reqQtFontFamily->fontFileIndex; |
429 faceId.index = reqQtFontFamily->fontFileIndex; |