Windows CE : Fix incorrect text rendering on wince with freetype engine
On wince with freetype engine can't render text for non-latin text. because wince doesn't have truetype font FONTSIGNATURE api. so match function in qwindowsfontdatabase_ft.cpp was always failed and render incorrect text. this patch has 3 changes. 1. extract font unicode signature using GetFontData function 2. append font fallback data from registry (see. http://msdn.microsoft.com/en-us/library/ms901076.aspx) 3. wince's default font path is windows. correct fontdir Task-number: QTBUG-31974 Change-Id: If969df353492141669eeab33119f3506602871b3 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
955052c0d9
commit
f079e9e77f
@ -54,6 +54,9 @@
|
|||||||
#include <QtGui/QFontDatabase>
|
#include <QtGui/QFontDatabase>
|
||||||
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#ifdef Q_OS_WINCE
|
||||||
|
#include <QtEndian>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -271,6 +274,12 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
|
|||||||
continue;
|
continue;
|
||||||
fontCache.insert(fontName, fontFile);
|
fontCache.insert(fontName, fontFile);
|
||||||
settings.setValue(fontName, fontFile);
|
settings.setValue(fontName, fontFile);
|
||||||
|
|
||||||
|
if (localizedName(fontName)) {
|
||||||
|
QString englishFontName = getEnglishName(fontName);
|
||||||
|
fontCache.insert(englishFontName, fontFile);
|
||||||
|
settings.setValue(englishFontName, fontFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = fontCache.value(faceName);
|
value = fontCache.value(faceName);
|
||||||
@ -283,7 +292,11 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!QDir::isAbsolutePath(value))
|
if (!QDir::isAbsolutePath(value))
|
||||||
|
#ifndef Q_OS_WINCE
|
||||||
value.prepend(QFile::decodeName(qgetenv("windir") + "\\Fonts\\"));
|
value.prepend(QFile::decodeName(qgetenv("windir") + "\\Fonts\\"));
|
||||||
|
#else
|
||||||
|
value.prepend(QFile::decodeName("/Windows/"));
|
||||||
|
#endif
|
||||||
|
|
||||||
QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, weight, style, stretch,
|
QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, weight, style, stretch,
|
||||||
antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
|
antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
|
||||||
@ -307,6 +320,24 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINCE
|
||||||
|
static QByteArray getFntTable(HFONT hfont, uint tag)
|
||||||
|
{
|
||||||
|
HDC hdc = GetDC(0);
|
||||||
|
HGDIOBJ oldFont = SelectObject(hdc, hfont);
|
||||||
|
quint32 t = qFromBigEndian<quint32>(tag);
|
||||||
|
QByteArray buffer;
|
||||||
|
|
||||||
|
DWORD length = GetFontData(hdc, t, 0, NULL, 0);
|
||||||
|
if (length != GDI_ERROR) {
|
||||||
|
buffer.resize(length);
|
||||||
|
GetFontData(hdc, t, 0, reinterpret_cast<uchar *>(buffer.data()), length);
|
||||||
|
}
|
||||||
|
SelectObject(hdc, oldFont);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
|
static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
|
||||||
int type, LPARAM namesSetIn)
|
int type, LPARAM namesSetIn)
|
||||||
{
|
{
|
||||||
@ -316,7 +347,33 @@ static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
|
|||||||
+ QString::fromWCharArray(f->elfFullName);
|
+ QString::fromWCharArray(f->elfFullName);
|
||||||
const uchar charSet = f->elfLogFont.lfCharSet;
|
const uchar charSet = f->elfLogFont.lfCharSet;
|
||||||
|
|
||||||
|
#ifndef Q_OS_WINCE
|
||||||
const FONTSIGNATURE signature = textmetric->ntmFontSig;
|
const FONTSIGNATURE signature = textmetric->ntmFontSig;
|
||||||
|
#else
|
||||||
|
FONTSIGNATURE signature;
|
||||||
|
QByteArray table;
|
||||||
|
|
||||||
|
if (type & TRUETYPE_FONTTYPE) {
|
||||||
|
HFONT hfont = CreateFontIndirect(&f->elfLogFont);
|
||||||
|
table = getFntTable(hfont, MAKE_TAG('O', 'S', '/', '2'));
|
||||||
|
DeleteObject((HGDIOBJ)hfont);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table.length() >= 86) {
|
||||||
|
// See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec
|
||||||
|
uchar *tableData = reinterpret_cast<uchar *>(table.data());
|
||||||
|
|
||||||
|
signature.fsUsb[0] = qFromBigEndian<quint32>(tableData + 42);
|
||||||
|
signature.fsUsb[1] = qFromBigEndian<quint32>(tableData + 46);
|
||||||
|
signature.fsUsb[2] = qFromBigEndian<quint32>(tableData + 50);
|
||||||
|
signature.fsUsb[3] = qFromBigEndian<quint32>(tableData + 54);
|
||||||
|
|
||||||
|
signature.fsCsb[0] = qFromBigEndian<quint32>(tableData + 78);
|
||||||
|
signature.fsCsb[1] = qFromBigEndian<quint32>(tableData + 82);
|
||||||
|
} else {
|
||||||
|
memset(&signature, 0, sizeof(signature));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
|
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
|
||||||
// identical to a TEXTMETRIC except for the last four members, which we don't use
|
// identical to a TEXTMETRIC except for the last four members, which we don't use
|
||||||
@ -501,6 +558,17 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF
|
|||||||
default:
|
default:
|
||||||
result << QString::fromLatin1("Arial");
|
result << QString::fromLatin1("Arial");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINCE
|
||||||
|
QSettings settings(QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\FontLink\\SystemLink"), QSettings::NativeFormat);
|
||||||
|
const QStringList fontList = settings.value(family).toStringList();
|
||||||
|
foreach (const QString &fallback, fontList) {
|
||||||
|
const int sep = fallback.indexOf(QLatin1Char(','));
|
||||||
|
if (sep > 0)
|
||||||
|
result << fallback.mid(sep + 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (QWindowsContext::verboseFonts)
|
if (QWindowsContext::verboseFonts)
|
||||||
qDebug() << __FUNCTION__ << family << style << styleHint
|
qDebug() << __FUNCTION__ << family << style << styleHint
|
||||||
<< script << result << m_families;
|
<< script << result << m_families;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user