DirectWrite font db: Fix writing system detection
The implementation here was accidentally missing from the first commit. We use the OS/2 table for determining the writing system support as intended by the font designer, and fall back to actually checking the Unicode ranges if the table should be missing. Change-Id: Ibfdf76c27f3a94eda2142b3e269a1ca30d4bc045 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
63a559845c
commit
2f521438eb
@ -617,6 +617,12 @@ static bool familySupportsWritingSystem(QtFontFamily *family, size_t writingSyst
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script)
|
||||
{
|
||||
return QFontDatabase::WritingSystem(std::find(scriptForWritingSystem,
|
||||
scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
|
||||
script) - scriptForWritingSystem);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
@ -833,9 +839,7 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo
|
||||
QStringList preferredFallbacks;
|
||||
QStringList otherFallbacks;
|
||||
|
||||
size_t writingSystem = std::find(scriptForWritingSystem,
|
||||
scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
|
||||
script) - scriptForWritingSystem;
|
||||
auto writingSystem = qt_writing_system_for_script(script);
|
||||
if (writingSystem >= QFontDatabase::WritingSystemsCount)
|
||||
writingSystem = QFontDatabase::Any;
|
||||
|
||||
@ -1272,8 +1276,7 @@ static int match(int script, const QFontDef &request,
|
||||
|
||||
load(family_name, script);
|
||||
|
||||
size_t writingSystem = std::find(scriptForWritingSystem, scriptForWritingSystem +
|
||||
QFontDatabase::WritingSystemsCount, script) - scriptForWritingSystem;
|
||||
auto writingSystem = qt_writing_system_for_script(script);
|
||||
if (writingSystem >= QFontDatabase::WritingSystemsCount)
|
||||
writingSystem = QFontDatabase::Any;
|
||||
|
||||
@ -2876,9 +2879,7 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
|
||||
|
||||
Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QChar::Script script, const QStringList &families)
|
||||
{
|
||||
size_t writingSystem = std::find(scriptForWritingSystem,
|
||||
scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
|
||||
script) - scriptForWritingSystem;
|
||||
size_t writingSystem = qt_writing_system_for_script(script);
|
||||
if (writingSystem == QFontDatabase::Any
|
||||
|| writingSystem >= QFontDatabase::WritingSystemsCount) {
|
||||
return families;
|
||||
|
@ -533,6 +533,32 @@ enum CsbBits {
|
||||
SymbolCsbBit = 31
|
||||
};
|
||||
|
||||
/*!
|
||||
Helper function that determines the writing system support based on the contents of the OS/2 table
|
||||
in the font.
|
||||
|
||||
\since 6.0
|
||||
*/
|
||||
QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromOS2Table(const char *os2Table, size_t length)
|
||||
{
|
||||
if (length >= 86) {
|
||||
quint32 unicodeRange[4] = {
|
||||
qFromBigEndian<quint32>(os2Table + 42),
|
||||
qFromBigEndian<quint32>(os2Table + 46),
|
||||
qFromBigEndian<quint32>(os2Table + 50),
|
||||
qFromBigEndian<quint32>(os2Table + 54)
|
||||
};
|
||||
quint32 codePageRange[2] = {
|
||||
qFromBigEndian<quint32>(os2Table + 78),
|
||||
qFromBigEndian<quint32>(os2Table + 82)
|
||||
};
|
||||
|
||||
return writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
|
||||
}
|
||||
|
||||
return QSupportedWritingSystems();
|
||||
}
|
||||
|
||||
/*!
|
||||
Helper function that determines the writing systems support by a given
|
||||
\a unicodeRange and \a codePageRange.
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
|
||||
// helper
|
||||
static QSupportedWritingSystems writingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]);
|
||||
static QSupportedWritingSystems writingSystemsFromOS2Table(const char *os2Table, size_t length);
|
||||
static QFont::Weight weightFromInteger(int weight);
|
||||
|
||||
//callback
|
||||
|
@ -268,17 +268,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
Q_UNREACHABLE();
|
||||
Q_ASSERT(length >= 86);
|
||||
}
|
||||
quint32 unicodeRange[4] = {
|
||||
qFromBigEndian<quint32>(os2Table.data() + 42),
|
||||
qFromBigEndian<quint32>(os2Table.data() + 46),
|
||||
qFromBigEndian<quint32>(os2Table.data() + 50),
|
||||
qFromBigEndian<quint32>(os2Table.data() + 54)
|
||||
};
|
||||
quint32 codePageRange[2] = {
|
||||
qFromBigEndian<quint32>(os2Table.data() + 78),
|
||||
qFromBigEndian<quint32>(os2Table.data() + 82)
|
||||
};
|
||||
fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
|
||||
fd->writingSystems = QPlatformFontDatabase::writingSystemsFromOS2Table(reinterpret_cast<const char *>(os2Table.data()), length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "qwindowsdirectwritefontdatabase_p.h"
|
||||
#include "qwindowsfontenginedirectwrite_p.h"
|
||||
|
||||
#include <QtCore/qendian.h>
|
||||
#include <QtCore/qstringbuilder.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
||||
@ -174,16 +175,6 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
|
||||
if (defaultLocaleFamilyName.isEmpty() && englishLocaleFamilyName.isEmpty())
|
||||
englishLocaleFamilyName = familyName;
|
||||
|
||||
QVarLengthArray<DWRITE_UNICODE_RANGE, 64> ranges(QFontDatabase::WritingSystemsCount);
|
||||
|
||||
uint count = 0;
|
||||
if (SUCCEEDED(font1->GetUnicodeRanges(QFontDatabase::WritingSystemsCount, ranges.data(), &count))) {
|
||||
// ###
|
||||
}
|
||||
QSupportedWritingSystems writingSystems;
|
||||
writingSystems.setSupported(QFontDatabase::Any);
|
||||
writingSystems.setSupported(QFontDatabase::Latin);
|
||||
|
||||
{
|
||||
IDWriteLocalizedStrings *names;
|
||||
if (SUCCEEDED(font1->GetFaceNames(&names))) {
|
||||
@ -199,7 +190,47 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
|
||||
|
||||
IDWriteFontFace *face = nullptr;
|
||||
if (SUCCEEDED(font->CreateFontFace(&face))) {
|
||||
QSupportedWritingSystems writingSystems;
|
||||
|
||||
const void *tableData = nullptr;
|
||||
UINT32 tableSize;
|
||||
void *tableContext = nullptr;
|
||||
BOOL exists;
|
||||
HRESULT hr = face->TryGetFontTable(qbswap<quint32>(MAKE_TAG('O','S','/','2')),
|
||||
&tableData,
|
||||
&tableSize,
|
||||
&tableContext,
|
||||
&exists);
|
||||
if (SUCCEEDED(hr) && exists) {
|
||||
writingSystems = QPlatformFontDatabase::writingSystemsFromOS2Table(reinterpret_cast<const char *>(tableData), tableSize);
|
||||
} else { // Fall back to checking first character of each Unicode range in font (may include too many writing systems)
|
||||
quint32 rangeCount;
|
||||
hr = font1->GetUnicodeRanges(0, nullptr, &rangeCount);
|
||||
|
||||
if (rangeCount > 0) {
|
||||
QVarLengthArray<DWRITE_UNICODE_RANGE, QChar::ScriptCount> ranges(rangeCount);
|
||||
|
||||
hr = font1->GetUnicodeRanges(rangeCount, ranges.data(), &rangeCount);
|
||||
if (SUCCEEDED(hr)) {
|
||||
for (uint i = 0; i < rangeCount; ++i) {
|
||||
QChar::Script script = QChar::script(ranges.at(i).first);
|
||||
|
||||
Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script);
|
||||
QFontDatabase::WritingSystem writingSystem = qt_writing_system_for_script(script);
|
||||
|
||||
if (writingSystem > QFontDatabase::Any && writingSystem < QFontDatabase::WritingSystemsCount)
|
||||
writingSystems.setSupported(writingSystem);
|
||||
}
|
||||
} else {
|
||||
const QString errorString = qt_error_string(int(hr));
|
||||
qCWarning(lcQpaFonts) << "Failed to get unicode ranges for font" << englishLocaleFamilyName << englishLocaleStyleName << ":" << errorString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!englishLocaleStyleName.isEmpty() || defaultLocaleStyleName.isEmpty()) {
|
||||
qCDebug(lcQpaFonts) << "Font" << englishLocaleFamilyName << englishLocaleStyleName << "supports writing systems:" << writingSystems;
|
||||
|
||||
QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
|
||||
face->AddRef();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user