17daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta// Copyright 2014 PDFium Authors. All rights reserved. 27daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta// Use of this source code is governed by a BSD-style license that can be 37daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta// found in the LICENSE file. 47daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 57daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 67daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 77daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta#include "../../../include/fxge/fx_ge.h" 87daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ 97daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta#include "../../../include/fxge/fx_ge_win32.h" 107daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta#include "dwrite_int.h" 117daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta#include "../Microsoft SDK/include/DWrite.h" 127daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptatypedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **); 137daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptatemplate <typename InterfaceType> 147daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptainline void SafeRelease(InterfaceType** currentObject) 157daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 167daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (*currentObject != NULL) { 177daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta (*currentObject)->Release(); 187daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta *currentObject = NULL; 197daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 207daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 217daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptatemplate <typename InterfaceType> 227daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptainline InterfaceType* SafeAcquire(InterfaceType* newObject) 237daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 247daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (newObject != NULL) { 257daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta newObject->AddRef(); 267daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 277daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return newObject; 287daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 297daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaclass CDwFontFileStream : public IDWriteFontFileStream, public CFX_Object 307daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 317daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptapublic: 327daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize); 337daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); 347daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual ULONG STDMETHODCALLTYPE AddRef(); 357daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual ULONG STDMETHODCALLTYPE Release(); 367daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext); 377daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext); 387daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); 397daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); 407daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta bool IsInitialized() 417daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta { 427daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return resourcePtr_ != NULL; 437daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 447daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaprivate: 457daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ULONG refCount_; 467daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta void const* resourcePtr_; 477daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWORD resourceSize_; 487daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta}; 497daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaclass CDwFontFileLoader : public IDWriteFontFileLoader, public CFX_Object 507daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 517daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptapublic: 527daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); 537daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual ULONG STDMETHODCALLTYPE AddRef(); 547daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual ULONG STDMETHODCALLTYPE Release(); 557daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream); 567daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 577daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta static IDWriteFontFileLoader* GetLoader() 587daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta { 597daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (instance_ == NULL) { 607daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta instance_ = FX_NEW CDwFontFileLoader(); 617daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return instance_; 627daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 637daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return instance_; 647daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 657daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta static bool IsLoaderInitialized() 667daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta { 677daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return instance_ != NULL; 687daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 697daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaprivate: 707daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwFontFileLoader(); 717daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ULONG refCount_; 727daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta static IDWriteFontFileLoader* instance_; 737daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta}; 747daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaclass CDwFontContext : public CFX_Object 757daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 767daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptapublic: 777daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwFontContext(IDWriteFactory* dwriteFactory); 787daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ~CDwFontContext(); 797daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta HRESULT Initialize(); 807daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaprivate: 817daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwFontContext(CDwFontContext const&); 827daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta void operator=(CDwFontContext const&); 837daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta HRESULT hr_; 847daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteFactory* dwriteFactory_; 857daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta}; 867daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaclass CDwGdiTextRenderer : public CFX_Object 877daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 887daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptapublic: 897daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwGdiTextRenderer( 907daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CFX_DIBitmap* pBitmap, 917daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteBitmapRenderTarget* bitmapRenderTarget, 927daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteRenderingParams* renderingParams 937daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 94549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin CDwGdiTextRenderer::~CDwGdiTextRenderer(); 95549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin HRESULT STDMETHODCALLTYPE DrawGlyphRun( 967daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta const FX_RECT& text_bbox, 977daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta __in_opt CFX_ClipRgn* pClipRgn, 987daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta __in_opt DWRITE_MATRIX const* pMatrix, 997daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta FLOAT baselineOriginX, 1007daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta FLOAT baselineOriginY, 1017daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_MEASURING_MODE measuringMode, 1027daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta __in DWRITE_GLYPH_RUN const* glyphRun, 1037daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta const COLORREF& textColor 1047daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 1057daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptaprivate: 1067daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CFX_DIBitmap* pBitmap_; 1077daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteBitmapRenderTarget* pRenderTarget_; 1087daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteRenderingParams* pRenderingParams_; 1097daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta}; 1107daacbbbe7349677476a3d2fbf174dcf86f171beVineet GuptaCDWriteExt::CDWriteExt() 1117daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1127daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta m_hModule = NULL; 1137daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta m_pDWriteFactory = NULL; 1147daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta m_pDwFontContext = NULL; 1157daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta m_pDwTextRenderer = NULL; 1167daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 1177daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptavoid CDWriteExt::Load() 1187daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1197daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 1207daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptavoid CDWriteExt::Unload() 1217daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1227daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (m_pDwFontContext) { 1237daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta delete (CDwFontContext*)m_pDwFontContext; 1247daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta m_pDwFontContext = NULL; 1257daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1267daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta SafeRelease((IDWriteFactory**)&m_pDWriteFactory); 1277daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 1287daacbbbe7349677476a3d2fbf174dcf86f171beVineet GuptaCDWriteExt::~CDWriteExt() 1297daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1307daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta Unload(); 1317daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 1327daacbbbe7349677476a3d2fbf174dcf86f171beVineet GuptaLPVOID CDWriteExt::DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style) 1337daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1347daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; 1357daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteFontFile* pDwFontFile = NULL; 1367daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteFontFace* pDwFontFace = NULL; 1377daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta BOOL isSupportedFontType = FALSE; 1387daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_FONT_FILE_TYPE fontFileType; 1397daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_FONT_FACE_TYPE fontFaceType; 1407daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta UINT32 numberOfFaces; 1417daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); 1427daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta HRESULT hr = S_OK; 1437daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pDwFactory->CreateCustomFontFileReference( 1447daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta (void const*)pData, 1457daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta (UINT32)size, 1467daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwFontFileLoader::GetLoader(), 1477daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &pDwFontFile 1487daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 1497daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 1507daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 1517daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1527daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pDwFontFile->Analyze( 1537daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &isSupportedFontType, 1547daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &fontFileType, 1557daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &fontFaceType, 1567daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &numberOfFaces 1577daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 1587daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { 1597daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 1607daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1617daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pDwFactory->CreateFontFace( 1627daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta fontFaceType, 1637daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 1, 1647daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &pDwFontFile, 1657daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 0, 1667daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta fontStyle, 1677daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &pDwFontFace 1687daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 1697daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 1707daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 1717daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1727daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta SafeRelease(&pDwFontFile); 1737daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return pDwFontFace; 1747daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptafailed: 1757daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta SafeRelease(&pDwFontFile); 1767daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return NULL; 1777daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 1787daacbbbe7349677476a3d2fbf174dcf86f171beVineet GuptaFX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget) 1797daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 1807daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (pBitmap->GetFormat() > FXDIB_Argb) { 1817daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return FALSE; 1827daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1837daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; 1847daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteGdiInterop* pGdiInterop = NULL; 1857daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; 1867daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta IDWriteRenderingParams* pRenderingParams = NULL; 1877daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta HRESULT hr = S_OK; 1887daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pDwFactory->GetGdiInterop(&pGdiInterop); 1897daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 1907daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 1917daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 1927daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), 1937daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &pBitmapRenderTarget); 1947daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 1957daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 1967daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 197549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin hr = pDwFactory->CreateCustomRenderingParams( 198549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin 1.0f, 1997daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 0.0f, 2007daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta 1.0f, 2017daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_PIXEL_GEOMETRY_RGB, 2027daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_RENDERING_MODE_DEFAULT, 2037daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &pRenderingParams 2047daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 2057daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 2067daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 2077daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 2087daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); 2097daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (FAILED(hr)) { 2107daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 2117daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 2127daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); 2137daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (*(CDwGdiTextRenderer**)renderTarget == NULL) { 2147daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta goto failed; 215549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin } 216549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin SafeRelease(&pGdiInterop); 217549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin SafeRelease(&pBitmapRenderTarget); 2187daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta SafeRelease(&pRenderingParams); 2197daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return TRUE; 2207daacbbbe7349677476a3d2fbf174dcf86f171beVineet Guptafailed: 2217daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta SafeRelease(&pGdiInterop); 222549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin SafeRelease(&pBitmapRenderTarget); 223549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin SafeRelease(&pRenderingParams); 2247daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return FALSE; 2257daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta} 2267daacbbbe7349677476a3d2fbf174dcf86f171beVineet GuptaFX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix, 227549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin void *font, FX_FLOAT font_size, FX_ARGB text_color, 2287daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta int glyph_count, unsigned short* glyph_indices, 2297daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY, 2307daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta void* glyph_offsets, 2317daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta FX_FLOAT* glyph_advances) 2327daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta{ 2337daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (renderTarget == NULL) { 2347daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta return TRUE; 235549e2c4a9858a380b03eb6e2ff4861d2c6687d6aDmitry V. Levin } 2367daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; 2377daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_MATRIX transform; 2387daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_GLYPH_RUN glyphRun; 2397daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta HRESULT hr = S_OK; 2407daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta if (pMatrix) { 2417daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.m11 = pMatrix->a; 2427daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.m12 = pMatrix->b; 2437daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.m21 = pMatrix->c; 2447daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.m22 = pMatrix->d; 2457daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.dx = pMatrix->e; 2467daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta transform.dy = pMatrix->f; 2477daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta } 2487daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.fontFace = (IDWriteFontFace*)font; 2497daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.fontEmSize = font_size; 2507daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.glyphCount = glyph_count; 2517daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.glyphIndices = glyph_indices; 2527daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.glyphAdvances = glyph_advances; 2537daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; 2547daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.isSideways = FALSE; 2557daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta glyphRun.bidiLevel = 0; 2567daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta hr = pTextRenderer->DrawGlyphRun( 2577daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta stringRect, 2587daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta pClipRgn, 2597daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta pMatrix ? &transform : NULL, 2607daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta baselineOriginX, baselineOriginY, 2617daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta DWRITE_MEASURING_MODE_NATURAL, 2627daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta &glyphRun, 2637daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color)) 2647daacbbbe7349677476a3d2fbf174dcf86f171beVineet Gupta ); 265 return SUCCEEDED(hr) ? TRUE : FALSE; 266} 267void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) 268{ 269 if (renderTarget) { 270 delete (CDwGdiTextRenderer*)renderTarget; 271 } 272} 273void CDWriteExt::DwDeleteFont(void* pFont) 274{ 275 if (pFont) { 276 SafeRelease((IDWriteFontFace**)&pFont); 277 } 278} 279CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize) 280{ 281 refCount_ = 0; 282 resourcePtr_ = fontFileReferenceKey; 283 resourceSize_ = fontFileReferenceKeySize; 284} 285HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject) 286{ 287 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { 288 *ppvObject = this; 289 AddRef(); 290 return S_OK; 291 } else { 292 *ppvObject = NULL; 293 return E_NOINTERFACE; 294 } 295} 296ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() 297{ 298 return InterlockedIncrement((long*)(&refCount_)); 299} 300ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() 301{ 302 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); 303 if (newCount == 0) { 304 delete this; 305 } 306 return newCount; 307} 308HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment( 309 void const** fragmentStart, 310 UINT64 fileOffset, 311 UINT64 fragmentSize, 312 OUT void** fragmentContext 313) 314{ 315 if (fileOffset <= resourceSize_ && 316 fragmentSize <= resourceSize_ - fileOffset) { 317 *fragmentStart = static_cast<FX_BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset); 318 *fragmentContext = NULL; 319 return S_OK; 320 } else { 321 *fragmentStart = NULL; 322 *fragmentContext = NULL; 323 return E_FAIL; 324 } 325} 326void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) 327{ 328} 329HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) 330{ 331 *fileSize = resourceSize_; 332 return S_OK; 333} 334HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) 335{ 336 *lastWriteTime = 0; 337 return E_NOTIMPL; 338} 339IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; 340CDwFontFileLoader::CDwFontFileLoader() : 341 refCount_(0) 342{ 343} 344HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) 345{ 346 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { 347 *ppvObject = this; 348 AddRef(); 349 return S_OK; 350 } else { 351 *ppvObject = NULL; 352 return E_NOINTERFACE; 353 } 354} 355ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() 356{ 357 return InterlockedIncrement((long*)(&refCount_)); 358} 359ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() 360{ 361 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); 362 if (newCount == 0) { 363 instance_ = NULL; 364 delete this; 365 } 366 return newCount; 367} 368HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( 369 void const* fontFileReferenceKey, 370 UINT32 fontFileReferenceKeySize, 371 OUT IDWriteFontFileStream** fontFileStream 372) 373{ 374 *fontFileStream = NULL; 375 CDwFontFileStream* stream = FX_NEW CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize); 376 if (stream == NULL) { 377 return E_OUTOFMEMORY; 378 } 379 if (!stream->IsInitialized()) { 380 delete stream; 381 return E_FAIL; 382 } 383 *fontFileStream = SafeAcquire(stream); 384 return S_OK; 385} 386CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) : 387 hr_(S_FALSE), 388 dwriteFactory_(SafeAcquire(dwriteFactory)) 389{ 390} 391CDwFontContext::~CDwFontContext() 392{ 393 if(dwriteFactory_ && hr_ == S_OK) { 394 dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader()); 395 } 396 SafeRelease(&dwriteFactory_); 397} 398HRESULT CDwFontContext::Initialize() 399{ 400 if (hr_ == S_FALSE) { 401 return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader()); 402 } 403 return hr_; 404} 405CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams): 406 pBitmap_(pBitmap), 407 pRenderTarget_(SafeAcquire(bitmapRenderTarget)), 408 pRenderingParams_(SafeAcquire(renderingParams)) 409{ 410} 411CDwGdiTextRenderer::~CDwGdiTextRenderer() 412{ 413 SafeRelease(&pRenderTarget_); 414 SafeRelease(&pRenderingParams_); 415} 416STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( 417 const FX_RECT& text_bbox, 418 __in_opt CFX_ClipRgn* pClipRgn, 419 __in_opt DWRITE_MATRIX const* pMatrix, 420 FLOAT baselineOriginX, 421 FLOAT baselineOriginY, 422 DWRITE_MEASURING_MODE measuringMode, 423 __in DWRITE_GLYPH_RUN const* glyphRun, 424 const COLORREF& textColor 425) 426{ 427 HRESULT hr = S_OK; 428 if (pMatrix) { 429 hr = pRenderTarget_->SetCurrentTransform(pMatrix); 430 if (FAILED(hr)) { 431 return hr; 432 } 433 } 434 HDC hDC = pRenderTarget_->GetMemoryDC(); 435 HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); 436 BITMAP bitmap; 437 GetObject(hBitmap, sizeof bitmap, &bitmap); 438 CFX_DIBitmap dib; 439 dib.Create( 440 bitmap.bmWidth, 441 bitmap.bmHeight, 442 bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, 443 (FX_LPBYTE)bitmap.bmBits 444 ); 445 dib.CompositeBitmap( 446 text_bbox.left, 447 text_bbox.top, 448 text_bbox.Width(), 449 text_bbox.Height(), 450 pBitmap_, 451 text_bbox.left, 452 text_bbox.top, 453 FXDIB_BLEND_NORMAL, 454 NULL 455 ); 456 hr = pRenderTarget_->DrawGlyphRun( 457 baselineOriginX, 458 baselineOriginY, 459 measuringMode, 460 glyphRun, 461 pRenderingParams_, 462 textColor 463 ); 464 if (FAILED(hr)) { 465 return hr; 466 } 467 pBitmap_->CompositeBitmap( 468 text_bbox.left, 469 text_bbox.top, 470 text_bbox.Width(), 471 text_bbox.Height(), 472 &dib, 473 text_bbox.left, 474 text_bbox.top, 475 FXDIB_BLEND_NORMAL, 476 pClipRgn 477 ); 478 return hr; 479} 480#endif 481