diff options
Diffstat (limited to 'src/widgets/platforms/win/qrawfont_win.cpp')
-rw-r--r-- | src/widgets/platforms/win/qrawfont_win.cpp | 709 |
1 files changed, 0 insertions, 709 deletions
diff --git a/src/widgets/platforms/win/qrawfont_win.cpp b/src/widgets/platforms/win/qrawfont_win.cpp deleted file mode 100644 index d8aa557975..0000000000 --- a/src/widgets/platforms/win/qrawfont_win.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qrawfont_p.h" -#include <private/qsystemlibrary_p.h> - -#if !defined(QT_NO_DIRECTWRITE) -# include "qfontenginedirectwrite_p.h" -# include <dwrite.h> -#endif - -#if !defined(QT_NO_RAWFONT) - -QT_BEGIN_NAMESPACE - -namespace { - - template<typename T> - struct BigEndian - { - quint8 data[sizeof(T)]; - - operator T() const - { - T littleEndian = 0; - for (int i=0; i<sizeof(T); ++i) { - littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8); - } - - return littleEndian; - } - - BigEndian<T> &operator=(const T &t) - { - for (int i=0; i<sizeof(T); ++i) { - data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff); - } - - return *this; - } - }; - -# pragma pack(1) - - // Common structure for all formats of the "name" table - struct NameTable - { - BigEndian<quint16> format; - BigEndian<quint16> count; - BigEndian<quint16> stringOffset; - }; - - struct NameRecord - { - BigEndian<quint16> platformID; - BigEndian<quint16> encodingID; - BigEndian<quint16> languageID; - BigEndian<quint16> nameID; - BigEndian<quint16> length; - BigEndian<quint16> offset; - }; - - struct OffsetSubTable - { - BigEndian<quint32> scalerType; - BigEndian<quint16> numTables; - BigEndian<quint16> searchRange; - BigEndian<quint16> entrySelector; - BigEndian<quint16> rangeShift; - }; - - struct TableDirectory - { - BigEndian<quint32> identifier; - BigEndian<quint32> checkSum; - BigEndian<quint32> offset; - BigEndian<quint32> length; - }; - - struct OS2Table - { - BigEndian<quint16> version; - BigEndian<qint16> avgCharWidth; - BigEndian<quint16> weightClass; - BigEndian<quint16> widthClass; - BigEndian<quint16> type; - BigEndian<qint16> subscriptXSize; - BigEndian<qint16> subscriptYSize; - BigEndian<qint16> subscriptXOffset; - BigEndian<qint16> subscriptYOffset; - BigEndian<qint16> superscriptXSize; - BigEndian<qint16> superscriptYSize; - BigEndian<qint16> superscriptXOffset; - BigEndian<qint16> superscriptYOffset; - BigEndian<qint16> strikeOutSize; - BigEndian<qint16> strikeOutPosition; - BigEndian<qint16> familyClass; - quint8 panose[10]; - BigEndian<quint32> unicodeRanges[4]; - quint8 vendorID[4]; - BigEndian<quint16> selection; - BigEndian<quint16> firstCharIndex; - BigEndian<quint16> lastCharIndex; - BigEndian<qint16> typoAscender; - BigEndian<qint16> typoDescender; - BigEndian<qint16> typoLineGap; - BigEndian<quint16> winAscent; - BigEndian<quint16> winDescent; - BigEndian<quint32> codepageRanges[2]; - BigEndian<qint16> height; - BigEndian<qint16> capHeight; - BigEndian<quint16> defaultChar; - BigEndian<quint16> breakChar; - BigEndian<quint16> maxContext; - }; - -# pragma pack() - - class EmbeddedFont - { - public: - EmbeddedFont(const QByteArray &fontData); - - QString changeFamilyName(const QString &newFamilyName); - QByteArray data() const { return m_fontData; } - TableDirectory *tableDirectoryEntry(const QByteArray &tagName); - QString familyName(TableDirectory *nameTableDirectory = 0); - - private: - QByteArray m_fontData; - }; - - EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) - { - } - - TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName) - { - Q_ASSERT(tagName.size() == 4); - - const BigEndian<quint32> *tagIdPtr = - reinterpret_cast<const BigEndian<quint32> *>(tagName.constData()); - quint32 tagId = *tagIdPtr; - - OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data()); - TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1); - - TableDirectory *nameTableDirectoryEntry = 0; - for (int i=0; i<offsetSubTable->numTables; ++i, ++tableDirectory) { - if (tableDirectory->identifier == tagId) { - nameTableDirectoryEntry = tableDirectory; - break; - } - } - - return nameTableDirectoryEntry; - } - - QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry) - { - QString name; - - if (nameTableDirectoryEntry == 0) - nameTableDirectoryEntry = tableDirectoryEntry("name"); - - if (nameTableDirectoryEntry != 0) { - NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() - + nameTableDirectoryEntry->offset); - NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1); - for (int i=0; i<nameTable->count; ++i, ++nameRecord) { - if (nameRecord->nameID == 1 - && nameRecord->platformID == 3 // Windows - && nameRecord->languageID == 0x0409) { // US English - const void *ptr = reinterpret_cast<const quint8 *>(nameTable) - + nameTable->stringOffset - + nameRecord->offset; - - const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr); - for (int j=0; j<nameRecord->length / sizeof(quint16); ++j) - name += QChar(s[j]); - - break; - } - } - } - - return name; - } - - QString EmbeddedFont::changeFamilyName(const QString &newFamilyName) - { - TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name"); - if (nameTableDirectoryEntry == 0) - return QString(); - - QString oldFamilyName = familyName(nameTableDirectoryEntry); - - // Reserve size for name table header, five required name records and string - const int requiredRecordCount = 5; - quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; - - int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; - int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); - - const QString regularString = QString::fromLatin1("Regular"); - int regularStringSize = regularString.size() * sizeof(quint16); - - // Align table size of table to 32 bits (pad with 0) - int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4; - - QByteArray newNameTable(fullSize, char(0)); - - { - NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data()); - nameTable->count = requiredRecordCount; - nameTable->stringOffset = sizeOfHeader; - - NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1); - for (int i=0; i<requiredRecordCount; ++i, nameRecord++) { - nameRecord->nameID = nameIds[i]; - nameRecord->encodingID = 1; - nameRecord->languageID = 0x0409; - nameRecord->platformID = 3; - nameRecord->length = newFamilyNameSize; - - // Special case for sub-family - if (nameIds[i] == 4) { - nameRecord->offset = newFamilyNameSize; - nameRecord->length = regularStringSize; - } - } - - // nameRecord now points to string data - BigEndian<quint16> *stringStorage = reinterpret_cast<BigEndian<quint16> *>(nameRecord); - const quint16 *sourceString = newFamilyName.utf16(); - for (int i=0; i<newFamilyName.size(); ++i) - stringStorage[i] = sourceString[i]; - stringStorage += newFamilyName.size(); - - sourceString = regularString.utf16(); - for (int i=0; i<regularString.size(); ++i) - stringStorage[i] = sourceString[i]; - } - - quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data()); - quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize); - - quint32 checkSum = 0; - while (p < tableEnd) - checkSum += *(p++); - - nameTableDirectoryEntry->checkSum = checkSum; - nameTableDirectoryEntry->offset = m_fontData.size(); - nameTableDirectoryEntry->length = fullSize; - - m_fontData.append(newNameTable); - - return oldFamilyName; - } - -#if !defined(QT_NO_DIRECTWRITE) - - class DirectWriteFontFileStream: public IDWriteFontFileStream - { - public: - DirectWriteFontFileStream(const QByteArray &fontData) - : m_fontData(fontData) - , m_referenceCount(0) - { - } - - ~DirectWriteFontFileStream() - { - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset, - UINT64 fragmentSize, OUT void **fragmentContext); - void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext); - HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize); - HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime); - - private: - QByteArray m_fontData; - ULONG m_referenceCount; - }; - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object) - { - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { - *object = this; - AddRef(); - return S_OK; - } else { - *object = NULL; - return E_NOINTERFACE; - } - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef() - { - return InterlockedIncrement(&m_referenceCount); - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release() - { - ULONG newCount = InterlockedDecrement(&m_referenceCount); - if (newCount == 0) - delete this; - return newCount; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment( - const void **fragmentStart, - UINT64 fileOffset, - UINT64 fragmentSize, - OUT void **fragmentContext) - { - *fragmentContext = NULL; - if (fragmentSize + fileOffset <= m_fontData.size()) { - *fragmentStart = m_fontData.data() + fileOffset; - return S_OK; - } else { - *fragmentStart = NULL; - return E_FAIL; - } - } - - void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *) - { - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize) - { - *fileSize = m_fontData.size(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime) - { - *lastWriteTime = 0; - return E_NOTIMPL; - } - - class DirectWriteFontFileLoader: public IDWriteFontFileLoader - { - public: - DirectWriteFontFileLoader() : m_referenceCount(0) {} - - ~DirectWriteFontFileLoader() - { - } - - inline void addKey(const void *key, const QByteArray &fontData) - { - Q_ASSERT(!m_fontDatas.contains(key)); - m_fontDatas.insert(key, fontData); - } - - inline void removeKey(const void *key) - { - m_fontDatas.remove(key); - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey, - UINT32 fontFileReferenceKeySize, - OUT IDWriteFontFileStream **fontFileStream); - - private: - ULONG m_referenceCount; - QHash<const void *, QByteArray> m_fontDatas; - }; - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, - void **object) - { - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { - *object = this; - AddRef(); - return S_OK; - } else { - *object = NULL; - return E_NOINTERFACE; - } - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef() - { - return InterlockedIncrement(&m_referenceCount); - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release() - { - ULONG newCount = InterlockedDecrement(&m_referenceCount); - if (newCount == 0) - delete this; - return newCount; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey( - void const *fontFileReferenceKey, - UINT32 fontFileReferenceKeySize, - IDWriteFontFileStream **fontFileStream) - { - Q_UNUSED(fontFileReferenceKeySize); - - if (fontFileReferenceKeySize != sizeof(const void *)) { - qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size"); - return E_FAIL; - } - - const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey); - *fontFileStream = NULL; - if (!m_fontDatas.contains(key)) - return E_FAIL; - - QByteArray fontData = m_fontDatas.value(key); - DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); - stream->AddRef(); - *fontFileStream = stream; - - return S_OK; - } - - class CustomFontFileLoader - { - public: - CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0) - { - HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&m_directWriteFactory)); - if (FAILED(hres)) { - qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: " - "DWriteCreateFactory failed."); - } else { - m_directWriteFontFileLoader = new DirectWriteFontFileLoader(); - m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader); - } - } - - ~CustomFontFileLoader() - { - if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0) - m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader); - - if (m_directWriteFactory != 0) - m_directWriteFactory->Release(); - } - - void addKey(const void *key, const QByteArray &fontData) - { - if (m_directWriteFontFileLoader != 0) - m_directWriteFontFileLoader->addKey(key, fontData); - } - - void removeKey(const void *key) - { - if (m_directWriteFontFileLoader != 0) - m_directWriteFontFileLoader->removeKey(key); - } - - IDWriteFontFileLoader *loader() const - { - return m_directWriteFontFileLoader; - } - - private: - IDWriteFactory *m_directWriteFactory; - DirectWriteFontFileLoader *m_directWriteFontFileLoader; - }; - -#endif - -} // Anonymous namespace - - -// From qfontdatabase_win.cpp -extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); -// From qfontdatabase.cpp -extern QFont::Weight weightFromInteger(int weight); - -void QRawFontPrivate::platformCleanUp() -{ - if (fontHandle != NULL) { - if (ptrRemoveFontMemResourceEx == NULL) { - QFunctionPointer func = - QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); - } - - if (ptrRemoveFontMemResourceEx == NULL) { - qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32"); - fontHandle = NULL; - } else { - ptrRemoveFontMemResourceEx(fontHandle); - fontHandle = NULL; - } - } -} - -void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, - qreal pixelSize, - QFont::HintingPreference hintingPreference) -{ - QByteArray fontData(_fontData); - EmbeddedFont font(fontData); - -#if !defined(QT_NO_DIRECTWRITE) - if (hintingPreference == QFont::PreferDefaultHinting - || hintingPreference == QFont::PreferFullHinting) -#endif - { - GUID guid; - CoCreateGuid(&guid); - - QString uniqueFamilyName = QString::fromLatin1("f") - + QString::number(guid.Data1, 36) + QLatin1Char('-') - + QString::number(guid.Data2, 36) + QLatin1Char('-') - + QString::number(guid.Data3, 36) + QLatin1Char('-') - + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36); - - QString actualFontName = font.changeFamilyName(uniqueFamilyName); - if (actualFontName.isEmpty()) { - qWarning("QRawFont::platformLoadFromData: Can't change family name of font"); - return; - } - - if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) { - QFunctionPointer func = - QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); - - func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx"); - ptrAddFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func); - } - - Q_ASSERT(fontHandle == NULL); - if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) { - DWORD count = 0; - fontData = font.data(); - fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count); - - if (count == 0 && fontHandle != NULL) { - ptrRemoveFontMemResourceEx(fontHandle); - fontHandle = NULL; - } - } - - if (fontHandle == NULL) { - qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed"); - } else { - QFontDef request; - request.family = uniqueFamilyName; - request.pixelSize = pixelSize; - request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; - request.hintingPreference = hintingPreference; - - fontEngine = qt_load_font_engine_win(request); - if (request.family != fontEngine->fontDef.family) { - qWarning("QRawFont::platformLoadFromData: Failed to load font. " - "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family)); - if (fontEngine->cache_count == 0 && fontEngine->ref == 0) - delete fontEngine; - fontEngine = 0; - } else { - Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0); - - // Override the generated font name - static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName; - fontEngine->fontDef.family = actualFontName; - fontEngine->ref.ref(); - } - } - } -#if !defined(QT_NO_DIRECTWRITE) - else { - CustomFontFileLoader fontFileLoader; - fontFileLoader.addKey(this, fontData); - - IDWriteFactory *factory = NULL; - HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&factory)); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed"); - return; - } - - IDWriteFontFile *fontFile = NULL; - void *key = this; - - hres = factory->CreateCustomFontFileReference(&key, sizeof(void *), - fontFileLoader.loader(), &fontFile); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: " - "CreateCustomFontFileReference failed"); - factory->Release(); - return; - } - - BOOL isSupportedFontType; - DWRITE_FONT_FILE_TYPE fontFileType; - DWRITE_FONT_FACE_TYPE fontFaceType; - UINT32 numberOfFaces; - fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces); - if (!isSupportedFontType) { - fontFile->Release(); - factory->Release(); - return; - } - - IDWriteFontFace *directWriteFontFace = NULL; - hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, - &directWriteFontFace); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed"); - fontFile->Release(); - factory->Release(); - return; - } - - fontFile->Release(); - - fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize); - - // Get font family from font data - fontEngine->fontDef.family = font.familyName(); - fontEngine->ref.ref(); - - directWriteFontFace->Release(); - factory->Release(); - } -#endif - - // Get style and weight info - if (fontEngine != 0) { - TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2"); - if (os2TableEntry != 0) { - const OS2Table *os2Table = - reinterpret_cast<const OS2Table *>(fontData.constData() - + os2TableEntry->offset); - - bool italic = os2Table->selection & 1; - bool oblique = os2Table->selection & 128; - - if (italic) - fontEngine->fontDef.style = QFont::StyleItalic; - else if (oblique) - fontEngine->fontDef.style = QFont::StyleOblique; - else - fontEngine->fontDef.style = QFont::StyleNormal; - - fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass); - } - } -} - -QT_END_NAMESPACE - -#endif // QT_NO_RAWFONT |