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); }
HRESULT STDMETHODCALLTYPE DWriteFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) { IDWriteFontFile* currentFontFile = m_FontFiles[m_CurrentFontFileIndex]; currentFontFile->AddRef(); *fontFile = currentFontFile; return S_OK; }
void QWinRTFontDatabase::releaseHandle(void *handle) { if (!handle) return; IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle); if (m_fonts.contains(fontFile)) { m_fonts.remove(fontFile); fontFile->Release(); return; } QBasicFontDatabase::releaseHandle(handle); }
LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, FX_DWORD size, int simulation_style) { IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; IDWriteFontFile* pDwFontFile = NULL; IDWriteFontFace* pDwFontFace = NULL; BOOL isSupportedFontType = FALSE; DWRITE_FONT_FILE_TYPE fontFileType; DWRITE_FONT_FACE_TYPE fontFaceType; UINT32 numberOfFaces; DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); HRESULT hr = S_OK; hr = pDwFactory->CreateCustomFontFileReference( (void const*)pData, (UINT32)size, CDwFontFileLoader::GetLoader(), &pDwFontFile ); if (FAILED(hr)) { goto failed; } hr = pDwFontFile->Analyze( &isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces ); if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { goto failed; } hr = pDwFactory->CreateFontFace( fontFaceType, 1, &pDwFontFile, 0, fontStyle, &pDwFontFace ); if (FAILED(hr)) { goto failed; } SafeRelease(&pDwFontFile); return pDwFontFace; failed: SafeRelease(&pDwFontFile); return NULL; }
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; }