WinRT: Use registerFontFamily to reduce font registration overhead
Adopt to the new lazy font loading strategy in order to reduce memory and startup time associated with populating the entire font database. Change-Id: I0134cc123f73cb8485fe85c4a6b8e3b3a3a2cab0 Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
parent
071098b08b
commit
244e2ef7b9
@ -63,7 +63,7 @@ QString QWinRTFontDatabase::fontDir() const
|
|||||||
fontDirectory = applicationDirPath + QLatin1String("/fonts");
|
fontDirectory = applicationDirPath + QLatin1String("/fonts");
|
||||||
if (!QFile::exists(fontDirectory)) {
|
if (!QFile::exists(fontDirectory)) {
|
||||||
#ifndef Q_OS_WINPHONE
|
#ifndef Q_OS_WINPHONE
|
||||||
if (m_fonts.isEmpty())
|
if (m_fontFamilies.isEmpty())
|
||||||
#endif
|
#endif
|
||||||
qWarning("No fonts directory found in application package.");
|
qWarning("No fonts directory found in application package.");
|
||||||
fontDirectory = applicationDirPath;
|
fontDirectory = applicationDirPath;
|
||||||
@ -78,6 +78,9 @@ QWinRTFontDatabase::~QWinRTFontDatabase()
|
|||||||
{
|
{
|
||||||
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
|
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
|
||||||
fontFile->Release();
|
fontFile->Release();
|
||||||
|
|
||||||
|
foreach (IDWriteFontFamily *fontFamily, m_fontFamilies)
|
||||||
|
fontFamily->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
QFont QWinRTFontDatabase::defaultFont() const
|
QFont QWinRTFontDatabase::defaultFont() const
|
||||||
@ -132,15 +135,36 @@ void QWinRTFontDatabase::populateFontDatabase()
|
|||||||
}
|
}
|
||||||
QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
|
QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
|
||||||
|
|
||||||
int fontCount = fontFamily->GetFontCount();
|
m_fontFamilies.insert(familyName, fontFamily.Detach());
|
||||||
|
|
||||||
|
registerFontFamily(familyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QBasicFontDatabase::populateFontDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWinRTFontDatabase::populateFamily(const QString &familyName)
|
||||||
|
{
|
||||||
|
IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName);
|
||||||
|
if (!fontFamily) {
|
||||||
|
qWarning("The font family %s was not found.", qPrintable(familyName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fontRegistered = false;
|
||||||
|
const int fontCount = fontFamily->GetFontCount();
|
||||||
for (int j = 0; j < fontCount; ++j) {
|
for (int j = 0; j < fontCount; ++j) {
|
||||||
ComPtr<IDWriteFont> font;
|
ComPtr<IDWriteFont> font;
|
||||||
hr = fontFamily->GetFont(j, &font);
|
HRESULT hr = fontFamily->GetFont(j, &font);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("Unable to get base font: %s", qPrintable(qt_error_string(hr)));
|
qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip simulated faces
|
||||||
|
if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
ComPtr<IDWriteFontFace> baseFontFace;
|
ComPtr<IDWriteFontFace> baseFontFace;
|
||||||
hr = font->CreateFontFace(&baseFontFace);
|
hr = font->CreateFontFace(&baseFontFace);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@ -154,13 +178,6 @@ void QWinRTFontDatabase::populateFontDatabase()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only try to load true-type fonts
|
|
||||||
DWRITE_FONT_FACE_TYPE type = fontFace->GetType();
|
|
||||||
if (!(type == DWRITE_FONT_FACE_TYPE_TRUETYPE
|
|
||||||
|| type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't deal with multi-file fonts
|
// We can't deal with multi-file fonts
|
||||||
quint32 fileCount;
|
quint32 fileCount;
|
||||||
hr = fontFace->GetFiles(&fileCount, NULL);
|
hr = fontFace->GetFiles(&fileCount, NULL);
|
||||||
@ -168,7 +185,7 @@ void QWinRTFontDatabase::populateFontDatabase()
|
|||||||
qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
|
qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fileCount != 1) // Should not happen as we only look at TT fonts
|
if (fileCount != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ComPtr<IDWriteLocalizedStrings> informationalStrings;
|
ComPtr<IDWriteLocalizedStrings> informationalStrings;
|
||||||
@ -293,14 +310,21 @@ void QWinRTFontDatabase::populateFontDatabase()
|
|||||||
m_fonts.insert(fontFile, description);
|
m_fonts.insert(fontFile, description);
|
||||||
registerFont(familyName, QString(), foundryName, weight, style, stretch,
|
registerFont(familyName, QString(), foundryName, weight, style, stretch,
|
||||||
true, true, 0, fixedPitch, writingSystems, fontFile);
|
true, true, 0, fixedPitch, writingSystems, fontFile);
|
||||||
}
|
fontRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QBasicFontDatabase::populateFontDatabase();
|
// Always populate something to avoid an assert
|
||||||
|
if (!fontRegistered) {
|
||||||
|
registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal,
|
||||||
|
QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
|
QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
|
||||||
{
|
{
|
||||||
|
if (!handle) // Happens if a font family population failed
|
||||||
|
return 0;
|
||||||
|
|
||||||
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
|
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
|
||||||
if (!m_fonts.contains(fontFile))
|
if (!m_fonts.contains(fontFile))
|
||||||
return QBasicFontDatabase::fontEngine(fontDef, handle);
|
return QBasicFontDatabase::fontEngine(fontDef, handle);
|
||||||
@ -361,6 +385,9 @@ QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handl
|
|||||||
|
|
||||||
void QWinRTFontDatabase::releaseHandle(void *handle)
|
void QWinRTFontDatabase::releaseHandle(void *handle)
|
||||||
{
|
{
|
||||||
|
if (!handle)
|
||||||
|
return;
|
||||||
|
|
||||||
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
|
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
|
||||||
if (m_fonts.contains(fontFile)) {
|
if (m_fonts.contains(fontFile)) {
|
||||||
m_fonts.remove(fontFile);
|
m_fonts.remove(fontFile);
|
||||||
|
@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
#ifndef Q_OS_WINPHONE
|
#ifndef Q_OS_WINPHONE
|
||||||
struct IDWriteFontFile;
|
struct IDWriteFontFile;
|
||||||
|
struct IDWriteFontFamily;
|
||||||
|
|
||||||
struct FontDescription
|
struct FontDescription
|
||||||
{
|
{
|
||||||
@ -64,10 +65,12 @@ public:
|
|||||||
~QWinRTFontDatabase();
|
~QWinRTFontDatabase();
|
||||||
QFont defaultFont() const Q_DECL_OVERRIDE;
|
QFont defaultFont() const Q_DECL_OVERRIDE;
|
||||||
void populateFontDatabase() Q_DECL_OVERRIDE;
|
void populateFontDatabase() Q_DECL_OVERRIDE;
|
||||||
|
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
|
||||||
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
||||||
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
|
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
|
||||||
private:
|
private:
|
||||||
QHash<IDWriteFontFile *, FontDescription> m_fonts;
|
QHash<IDWriteFontFile *, FontDescription> m_fonts;
|
||||||
|
QHash<QString, IDWriteFontFamily *> m_fontFamilies;
|
||||||
#endif // !Q_OS_WINPHONE
|
#endif // !Q_OS_WINPHONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user