From f2fabf77f9bc18448aed0e99a6d7d1d6c5c9c736 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Mon, 20 Aug 2012 11:25:41 +0200 Subject: Fix freetype font rendering for Windows CE Windows CE does not have support for GetGlyphOutline. So addGlyphToPath will not work. QML uses it for their distance field rendering. One option to bypass this issue is to use freetype as rendering backend. Change-Id: I965254344945cbdad771a5d505fb61c1cc2087df Reviewed-by: Friedemann Kleint --- .../fontdatabases/basic/qbasicfontdatabase.cpp | 120 +++++++++++++++++++++ .../fontdatabases/basic/qbasicfontdatabase_p.h | 1 + 2 files changed, 121 insertions(+) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp index e96659d4f6..68aafd8838 100644 --- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #undef QT_NO_FREETYPE #include @@ -135,6 +136,37 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { { 14, 127 }, }; +typedef struct { + quint16 majorVersion; + quint16 minorVersion; + quint16 numTables; + quint16 searchRange; + quint16 entrySelector; + quint16 rangeShift; +} OFFSET_TABLE; + +typedef struct { + quint32 tag; + quint32 checkSum; + quint32 offset; + quint32 length; +} TABLE_DIRECTORY; + +typedef struct { + quint16 fontSelector; + quint16 nrCount; + quint16 storageOffset; +} NAME_TABLE_HEADER; + +typedef struct { + quint16 platformID; + quint16 encodingID; + quint16 languageID; + quint16 nameID; + quint16 stringLength; + quint16 stringOffset; +} NAME_RECORD; + QSupportedWritingSystems QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]) { QSupportedWritingSystems writingSystems; @@ -430,4 +462,92 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt return families; } +QString QBasicFontDatabase::fontNameFromTTFile(const QString &filename) +{ + QFile f(filename); + QString retVal; + qint64 bytesRead; + qint64 bytesToRead; + + if (f.open(QIODevice::ReadOnly)) { + OFFSET_TABLE ttOffsetTable; + bytesToRead = sizeof(OFFSET_TABLE); + bytesRead = f.read((char*)&ttOffsetTable, bytesToRead); + if (bytesToRead != bytesRead) + return retVal; + ttOffsetTable.numTables = qFromBigEndian(ttOffsetTable.numTables); + ttOffsetTable.majorVersion = qFromBigEndian(ttOffsetTable.majorVersion); + ttOffsetTable.minorVersion = qFromBigEndian(ttOffsetTable.minorVersion); + + if (ttOffsetTable.majorVersion != 1 || ttOffsetTable.minorVersion != 0) + return retVal; + + TABLE_DIRECTORY tblDir; + bool found = false; + + for (int i = 0; i < ttOffsetTable.numTables; i++) { + bytesToRead = sizeof(TABLE_DIRECTORY); + bytesRead = f.read((char*)&tblDir, bytesToRead); + if (bytesToRead != bytesRead) + return retVal; + if (qFromBigEndian(tblDir.tag) == MAKE_TAG('n', 'a', 'm', 'e')) { + found = true; + tblDir.length = qFromBigEndian(tblDir.length); + tblDir.offset = qFromBigEndian(tblDir.offset); + break; + } + } + + if (found) { + f.seek(tblDir.offset); + NAME_TABLE_HEADER ttNTHeader; + bytesToRead = sizeof(NAME_TABLE_HEADER); + bytesRead = f.read((char*)&ttNTHeader, bytesToRead); + if (bytesToRead != bytesRead) + return retVal; + ttNTHeader.nrCount = qFromBigEndian(ttNTHeader.nrCount); + ttNTHeader.storageOffset = qFromBigEndian(ttNTHeader.storageOffset); + NAME_RECORD ttRecord; + found = false; + + for (int i = 0; i < ttNTHeader.nrCount; i++) { + bytesToRead = sizeof(NAME_RECORD); + bytesRead = f.read((char*)&ttRecord, bytesToRead); + if (bytesToRead != bytesRead) + return retVal; + ttRecord.nameID = qFromBigEndian(ttRecord.nameID); + if (ttRecord.nameID == 1) { + ttRecord.stringLength = qFromBigEndian(ttRecord.stringLength); + ttRecord.stringOffset = qFromBigEndian(ttRecord.stringOffset); + int nPos = f.pos(); + f.seek(tblDir.offset + ttRecord.stringOffset + ttNTHeader.storageOffset); + + QByteArray nameByteArray = f.read(ttRecord.stringLength); + if (!nameByteArray.isEmpty()) { + if (ttRecord.encodingID == 256 || ttRecord.encodingID == 768) { + //This is UTF-16 in big endian + int stringLength = ttRecord.stringLength / 2; + retVal.resize(stringLength); + QChar *data = retVal.data(); + const ushort *srcData = (const ushort *)nameByteArray.data(); + for (int i = 0; i < stringLength; ++i) + data[i] = qFromBigEndian(srcData[i]); + return retVal; + } else if (ttRecord.encodingID == 0) { + //This is Latin1 + retVal = QString::fromLatin1(nameByteArray); + } else { + qWarning("Could not retrieve Font name from file: %s", qPrintable(QDir::toNativeSeparators(filename))); + } + break; + } + f.seek(nPos); + } + } + } + f.close(); + } + return retVal; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h index eb4b11ca97..832acd9b44 100644 --- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h @@ -66,6 +66,7 @@ public: static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file); static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]); + static QString fontNameFromTTFile(const QString &filename); }; QT_END_NAMESPACE -- cgit v1.2.3