std::string FontRendererImpl::GetFontKey(ComPtr<IDWriteFontFace> fontFace, float emSize) { // get the file reference key uint32_t reqFiles = 1; IDWriteFontFile* file; fontFace->GetFiles(&reqFiles, &file); const void* referenceKey; uint32_t referenceKeySize; file->GetReferenceKey(&referenceKey, &referenceKeySize); // store in a buffer and append the size uint32_t referenceKeySizeTarget = min(referenceKeySize, 128); char refKeyBuffer[256]; memcpy(refKeyBuffer, referenceKey, referenceKeySizeTarget); *(float*)&refKeyBuffer[referenceKeySizeTarget] = emSize; // release the file file->Release(); return std::string(refKeyBuffer, referenceKeySizeTarget + 4); }
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); const void *referenceKey; quint32 referenceKeySize; HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize); if (FAILED(hr)) { qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr))); return 0; } ComPtr<IDWriteFontFileLoader> loader; hr = fontFile->GetLoader(&loader); if (FAILED(hr)) { qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr))); return 0; } ComPtr<IDWriteFontFileStream> stream; hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream); if (FAILED(hr)) { qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr))); return 0; } quint64 fileSize; hr = stream->GetFileSize(&fileSize); if (FAILED(hr)) { qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr))); return 0; } const void *data; void *context; hr = stream->ReadFileFragment(&data, 0, fileSize, &context); if (FAILED(hr)) { qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr))); return 0; } const QByteArray fontData((const char *)data, fileSize); stream->ReleaseFileFragment(context); QFontEngine::FaceId faceId; const FontDescription description = m_fonts.value(fontFile); faceId.uuid = description.uuid; faceId.index = description.index; const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; QFontEngineFT *engine = new QFontEngineFT(fontDef); if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) { delete engine; return 0; } return engine; }