summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp331
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h3
2 files changed, 182 insertions, 152 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index 3da87de708..70bb9469db 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -63,7 +63,7 @@ QString QWinRTFontDatabase::fontDir() const
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
#ifndef Q_OS_WINPHONE
- if (m_fonts.isEmpty())
+ if (m_fontFamilies.isEmpty())
#endif
qWarning("No fonts directory found in application package.");
fontDirectory = applicationDirPath;
@@ -78,6 +78,9 @@ QWinRTFontDatabase::~QWinRTFontDatabase()
{
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
fontFile->Release();
+
+ foreach (IDWriteFontFamily *fontFamily, m_fontFamilies)
+ fontFamily->Release();
}
QFont QWinRTFontDatabase::defaultFont() const
@@ -132,175 +135,196 @@ void QWinRTFontDatabase::populateFontDatabase()
}
QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
- int fontCount = fontFamily->GetFontCount();
- for (int j = 0; j < fontCount; ++j) {
- ComPtr<IDWriteFont> font;
- hr = fontFamily->GetFont(j, &font);
- if (FAILED(hr)) {
- qWarning("Unable to get base font: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ m_fontFamilies.insert(familyName, fontFamily.Detach());
- ComPtr<IDWriteFontFace> baseFontFace;
- hr = font->CreateFontFace(&baseFontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- ComPtr<IDWriteFontFace1> fontFace;
- hr = baseFontFace.As(&fontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ registerFontFamily(familyName);
+ }
- // 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;
- }
+ QBasicFontDatabase::populateFontDatabase();
+}
- // We can't deal with multi-file fonts
- quint32 fileCount;
- hr = fontFace->GetFiles(&fileCount, NULL);
- if (FAILED(hr)) {
- qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- if (fileCount != 1) // Should not happen as we only look at TT fonts
- continue;
-
- ComPtr<IDWriteLocalizedStrings> informationalStrings;
- BOOL exists;
- hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
- &informationalStrings, &exists);
- if (FAILED(hr)) {
- qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QString foundryName;
- if (exists) {
- quint32 length;
- hr = informationalStrings->GetStringLength(0, &length);
+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) {
+ ComPtr<IDWriteFont> font;
+ HRESULT hr = fontFamily->GetFont(j, &font);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // Skip simulated faces
+ if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE)
+ continue;
+
+ ComPtr<IDWriteFontFace> baseFontFace;
+ hr = font->CreateFontFace(&baseFontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ ComPtr<IDWriteFontFace1> fontFace;
+ hr = baseFontFace.As(&fontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // We can't deal with multi-file fonts
+ quint32 fileCount;
+ hr = fontFace->GetFiles(&fileCount, NULL);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ if (fileCount != 1)
+ continue;
+
+ ComPtr<IDWriteLocalizedStrings> informationalStrings;
+ BOOL exists;
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
+ &informationalStrings, &exists);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString foundryName;
+ if (exists) {
+ quint32 length;
+ hr = informationalStrings->GetStringLength(0, &length);
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr)) {
+ QVector<wchar_t> buffer(length + 1);
+ hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
if (FAILED(hr))
- qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr)) {
- QVector<wchar_t> buffer(length + 1);
- hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
- if (FAILED(hr))
- qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr))
- foundryName = QString::fromWCharArray(buffer.data(), length);
- }
+ qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr))
+ foundryName = QString::fromWCharArray(buffer.data(), length);
}
+ }
- QFont::Weight weight;
- switch (font->GetWeight()) {
- case DWRITE_FONT_WEIGHT_THIN:
- case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
- case DWRITE_FONT_WEIGHT_LIGHT:
- case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
- weight = QFont::Light;
- break;
- default:
- case DWRITE_FONT_WEIGHT_NORMAL:
- case DWRITE_FONT_WEIGHT_MEDIUM:
- weight = QFont::Normal;
- break;
- case DWRITE_FONT_WEIGHT_DEMI_BOLD:
- weight = QFont::DemiBold;
- break;
- case DWRITE_FONT_WEIGHT_BOLD:
- case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
- weight = QFont::Bold;
- break;
- case DWRITE_FONT_WEIGHT_BLACK:
- case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
- weight = QFont::Black;
- break;
- }
+ QFont::Weight weight;
+ switch (font->GetWeight()) {
+ case DWRITE_FONT_WEIGHT_THIN:
+ case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
+ case DWRITE_FONT_WEIGHT_LIGHT:
+ case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
+ weight = QFont::Light;
+ break;
+ default:
+ case DWRITE_FONT_WEIGHT_NORMAL:
+ case DWRITE_FONT_WEIGHT_MEDIUM:
+ weight = QFont::Normal;
+ break;
+ case DWRITE_FONT_WEIGHT_DEMI_BOLD:
+ weight = QFont::DemiBold;
+ break;
+ case DWRITE_FONT_WEIGHT_BOLD:
+ case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
+ weight = QFont::Bold;
+ break;
+ case DWRITE_FONT_WEIGHT_BLACK:
+ case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
+ weight = QFont::Black;
+ break;
+ }
- QFont::Style style;
- switch (font->GetStyle()) {
- default:
- case DWRITE_FONT_STYLE_NORMAL:
- style = QFont::StyleNormal;
- break;
- case DWRITE_FONT_STYLE_OBLIQUE:
- style = QFont::StyleOblique;
- break;
- case DWRITE_FONT_STYLE_ITALIC:
- style = QFont::StyleItalic;
- break;
- }
+ QFont::Style style;
+ switch (font->GetStyle()) {
+ default:
+ case DWRITE_FONT_STYLE_NORMAL:
+ style = QFont::StyleNormal;
+ break;
+ case DWRITE_FONT_STYLE_OBLIQUE:
+ style = QFont::StyleOblique;
+ break;
+ case DWRITE_FONT_STYLE_ITALIC:
+ style = QFont::StyleItalic;
+ break;
+ }
- QFont::Stretch stretch;
- switch (font->GetStretch()) {
- default:
- case DWRITE_FONT_STRETCH_UNDEFINED:
- case DWRITE_FONT_STRETCH_NORMAL:
- stretch = QFont::Unstretched;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
- stretch = QFont::UltraCondensed;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
- stretch = QFont::ExtraCondensed;
- break;
- case DWRITE_FONT_STRETCH_CONDENSED:
- stretch = QFont::Condensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
- stretch = QFont::SemiCondensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
- stretch = QFont::SemiExpanded;
- break;
- case DWRITE_FONT_STRETCH_EXPANDED:
- stretch = QFont::Expanded;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
- stretch = QFont::ExtraExpanded;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
- stretch = QFont::UltraExpanded;
- break;
- }
+ QFont::Stretch stretch;
+ switch (font->GetStretch()) {
+ default:
+ case DWRITE_FONT_STRETCH_UNDEFINED:
+ case DWRITE_FONT_STRETCH_NORMAL:
+ stretch = QFont::Unstretched;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
+ stretch = QFont::UltraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
+ stretch = QFont::ExtraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_CONDENSED:
+ stretch = QFont::Condensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
+ stretch = QFont::SemiCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
+ stretch = QFont::SemiExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXPANDED:
+ stretch = QFont::Expanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
+ stretch = QFont::ExtraExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
+ stretch = QFont::UltraExpanded;
+ break;
+ }
- const bool fixedPitch = fontFace->IsMonospacedFont();
+ const bool fixedPitch = fontFace->IsMonospacedFont();
- quint32 unicodeRange[4];
- quint32 actualRangeCount;
- hr = fontFace->GetUnicodeRanges(
- 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
- if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
- qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- quint32 codePageRange[2] = { 0, 0 };
- QSupportedWritingSystems writingSystems =
- QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-
- IDWriteFontFile *fontFile;
- hr = fontFace->GetFiles(&fileCount, &fontFile);
- if (FAILED(hr)) {
- qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ quint32 unicodeRange[4];
+ quint32 actualRangeCount;
+ hr = fontFace->GetUnicodeRanges(
+ 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
+ if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
+ qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 codePageRange[2] = { 0, 0 };
+ QSupportedWritingSystems writingSystems =
+ QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
- FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
- m_fonts.insert(fontFile, description);
- registerFont(familyName, QString(), foundryName, weight, style, stretch,
- true, true, 0, fixedPitch, writingSystems, fontFile);
+ IDWriteFontFile *fontFile;
+ hr = fontFace->GetFiles(&fileCount, &fontFile);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
+ continue;
}
+
+ FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
+ m_fonts.insert(fontFile, description);
+ registerFont(familyName, QString(), foundryName, weight, style, stretch,
+ 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)
{
+ if (!handle) // Happens if a font family population failed
+ return 0;
+
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
if (!m_fonts.contains(fontFile))
return QBasicFontDatabase::fontEngine(fontDef, handle);
@@ -361,6 +385,9 @@ QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handl
void QWinRTFontDatabase::releaseHandle(void *handle)
{
+ if (!handle)
+ return;
+
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
if (m_fonts.contains(fontFile)) {
m_fonts.remove(fontFile);
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index 6f194a10cc..b318a95502 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINPHONE
struct IDWriteFontFile;
+struct IDWriteFontFamily;
struct FontDescription
{
@@ -64,10 +65,12 @@ public:
~QWinRTFontDatabase();
QFont defaultFont() const 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;
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
private:
QHash<IDWriteFontFile *, FontDescription> m_fonts;
+ QHash<QString, IDWriteFontFamily *> m_fontFamilies;
#endif // !Q_OS_WINPHONE
};