| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../include/fxge/fx_ge.h" | 7 #include "../../../include/fxge/fx_ge.h" |
| 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ | 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ |
| 9 #include "../../../include/fxge/fx_ge_win32.h" | 9 #include "../../../include/fxge/fx_ge_win32.h" |
| 10 #include "dwrite_int.h" | 10 #include "dwrite_int.h" |
| 11 #include <dwrite.h> | 11 #include <dwrite.h> |
| 12 typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_T
YPE, __in REFIID, __out IUnknown **); | 12 typedef HRESULT(__stdcall* FuncType_DWriteCreateFactory)( |
| 13 __in DWRITE_FACTORY_TYPE, |
| 14 __in REFIID, |
| 15 __out IUnknown**); |
| 13 template <typename InterfaceType> | 16 template <typename InterfaceType> |
| 14 inline void SafeRelease(InterfaceType** currentObject) | 17 inline void SafeRelease(InterfaceType** currentObject) { |
| 15 { | 18 if (*currentObject != NULL) { |
| 16 if (*currentObject != NULL) { | 19 (*currentObject)->Release(); |
| 17 (*currentObject)->Release(); | 20 *currentObject = NULL; |
| 18 *currentObject = NULL; | 21 } |
| 22 } |
| 23 template <typename InterfaceType> |
| 24 inline InterfaceType* SafeAcquire(InterfaceType* newObject) { |
| 25 if (newObject != NULL) { |
| 26 newObject->AddRef(); |
| 27 } |
| 28 return newObject; |
| 29 } |
| 30 class CDwFontFileStream final : public IDWriteFontFileStream { |
| 31 public: |
| 32 explicit CDwFontFileStream(void const* fontFileReferenceKey, |
| 33 UINT32 fontFileReferenceKeySize); |
| 34 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, |
| 35 void** ppvObject); |
| 36 virtual ULONG STDMETHODCALLTYPE AddRef(); |
| 37 virtual ULONG STDMETHODCALLTYPE Release(); |
| 38 virtual HRESULT STDMETHODCALLTYPE |
| 39 ReadFileFragment(void const** fragmentStart, |
| 40 UINT64 fileOffset, |
| 41 UINT64 fragmentSize, |
| 42 OUT void** fragmentContext); |
| 43 virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext); |
| 44 virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); |
| 45 virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); |
| 46 bool IsInitialized() { return resourcePtr_ != NULL; } |
| 47 |
| 48 private: |
| 49 ULONG refCount_; |
| 50 void const* resourcePtr_; |
| 51 DWORD resourceSize_; |
| 52 }; |
| 53 class CDwFontFileLoader final : public IDWriteFontFileLoader { |
| 54 public: |
| 55 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, |
| 56 void** ppvObject); |
| 57 virtual ULONG STDMETHODCALLTYPE AddRef(); |
| 58 virtual ULONG STDMETHODCALLTYPE Release(); |
| 59 virtual HRESULT STDMETHODCALLTYPE |
| 60 CreateStreamFromKey(void const* fontFileReferenceKey, |
| 61 UINT32 fontFileReferenceKeySize, |
| 62 OUT IDWriteFontFileStream** fontFileStream); |
| 63 |
| 64 static IDWriteFontFileLoader* GetLoader() { |
| 65 if (instance_ == NULL) { |
| 66 instance_ = new CDwFontFileLoader(); |
| 19 } | 67 } |
| 20 } | 68 return instance_; |
| 21 template <typename InterfaceType> | 69 } |
| 22 inline InterfaceType* SafeAcquire(InterfaceType* newObject) | 70 static bool IsLoaderInitialized() { return instance_ != NULL; } |
| 23 { | 71 |
| 24 if (newObject != NULL) { | 72 private: |
| 25 newObject->AddRef(); | 73 CDwFontFileLoader(); |
| 26 } | 74 ULONG refCount_; |
| 27 return newObject; | 75 static IDWriteFontFileLoader* instance_; |
| 28 } | |
| 29 class CDwFontFileStream final : public IDWriteFontFileStream | |
| 30 { | |
| 31 public: | |
| 32 explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFile
ReferenceKeySize); | |
| 33 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | |
| 34 virtual ULONG STDMETHODCALLTYPE AddRef(); | |
| 35 virtual ULONG STDMETHODCALLTYPE Release(); | |
| 36 virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStar
t, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext); | |
| 37 virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext)
; | |
| 38 virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); | |
| 39 virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime
); | |
| 40 bool IsInitialized() | |
| 41 { | |
| 42 return resourcePtr_ != NULL; | |
| 43 } | |
| 44 private: | |
| 45 ULONG refCount_; | |
| 46 void const* resourcePtr_; | |
| 47 DWORD resourceSize_; | |
| 48 }; | 76 }; |
| 49 class CDwFontFileLoader final : public IDWriteFontFileLoader | 77 class CDwFontContext { |
| 50 { | 78 public: |
| 51 public: | 79 CDwFontContext(IDWriteFactory* dwriteFactory); |
| 52 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | 80 ~CDwFontContext(); |
| 53 virtual ULONG STDMETHODCALLTYPE AddRef(); | 81 HRESULT Initialize(); |
| 54 virtual ULONG STDMETHODCALLTYPE Release(); | 82 |
| 55 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileRe
ferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFil
eStream); | 83 private: |
| 56 | 84 CDwFontContext(CDwFontContext const&); |
| 57 static IDWriteFontFileLoader* GetLoader() | 85 void operator=(CDwFontContext const&); |
| 58 { | 86 HRESULT hr_; |
| 59 if (instance_ == NULL) { | 87 IDWriteFactory* dwriteFactory_; |
| 60 instance_ = new CDwFontFileLoader(); | |
| 61 } | |
| 62 return instance_; | |
| 63 } | |
| 64 static bool IsLoaderInitialized() | |
| 65 { | |
| 66 return instance_ != NULL; | |
| 67 } | |
| 68 private: | |
| 69 CDwFontFileLoader(); | |
| 70 ULONG refCount_; | |
| 71 static IDWriteFontFileLoader* instance_; | |
| 72 }; | 88 }; |
| 73 class CDwFontContext | 89 class CDwGdiTextRenderer { |
| 74 { | 90 public: |
| 75 public: | 91 CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, |
| 76 CDwFontContext(IDWriteFactory* dwriteFactory); | 92 IDWriteBitmapRenderTarget* bitmapRenderTarget, |
| 77 ~CDwFontContext(); | 93 IDWriteRenderingParams* renderingParams); |
| 78 HRESULT Initialize(); | 94 ~CDwGdiTextRenderer(); |
| 79 private: | 95 HRESULT STDMETHODCALLTYPE DrawGlyphRun(const FX_RECT& text_bbox, |
| 80 CDwFontContext(CDwFontContext const&); | 96 __in_opt CFX_ClipRgn* pClipRgn, |
| 81 void operator=(CDwFontContext const&); | 97 __in_opt DWRITE_MATRIX const* pMatrix, |
| 82 HRESULT hr_; | 98 FLOAT baselineOriginX, |
| 83 IDWriteFactory* dwriteFactory_; | 99 FLOAT baselineOriginY, |
| 100 DWRITE_MEASURING_MODE measuringMode, |
| 101 __in DWRITE_GLYPH_RUN const* glyphRun, |
| 102 const COLORREF& textColor); |
| 103 |
| 104 private: |
| 105 CFX_DIBitmap* pBitmap_; |
| 106 IDWriteBitmapRenderTarget* pRenderTarget_; |
| 107 IDWriteRenderingParams* pRenderingParams_; |
| 84 }; | 108 }; |
| 85 class CDwGdiTextRenderer | 109 CDWriteExt::CDWriteExt() { |
| 86 { | 110 m_hModule = NULL; |
| 87 public: | 111 m_pDWriteFactory = NULL; |
| 88 CDwGdiTextRenderer( | 112 m_pDwFontContext = NULL; |
| 89 CFX_DIBitmap* pBitmap, | 113 m_pDwTextRenderer = NULL; |
| 90 IDWriteBitmapRenderTarget* bitmapRenderTarget, | 114 } |
| 91 IDWriteRenderingParams* renderingParams | 115 void CDWriteExt::Load() {} |
| 92 ); | 116 void CDWriteExt::Unload() { |
| 93 ~CDwGdiTextRenderer(); | 117 if (m_pDwFontContext) { |
| 94 HRESULT STDMETHODCALLTYPE DrawGlyphRun( | 118 delete (CDwFontContext*)m_pDwFontContext; |
| 95 const FX_RECT& text_bbox, | |
| 96 __in_opt CFX_ClipRgn* pClipRgn, | |
| 97 __in_opt DWRITE_MATRIX const* pMatrix, | |
| 98 FLOAT baselineOriginX, | |
| 99 FLOAT baselineOriginY, | |
| 100 DWRITE_MEASURING_MODE measuringMode, | |
| 101 __in DWRITE_GLYPH_RUN const* glyphRun, | |
| 102 const COLORREF& textColor | |
| 103 ); | |
| 104 private: | |
| 105 CFX_DIBitmap* pBitmap_; | |
| 106 IDWriteBitmapRenderTarget* pRenderTarget_; | |
| 107 IDWriteRenderingParams* pRenderingParams_; | |
| 108 }; | |
| 109 CDWriteExt::CDWriteExt() | |
| 110 { | |
| 111 m_hModule = NULL; | |
| 112 m_pDWriteFactory = NULL; | |
| 113 m_pDwFontContext = NULL; | 119 m_pDwFontContext = NULL; |
| 114 m_pDwTextRenderer = NULL; | 120 } |
| 115 } | 121 SafeRelease((IDWriteFactory**)&m_pDWriteFactory); |
| 116 void CDWriteExt::Load() | 122 } |
| 117 { | 123 CDWriteExt::~CDWriteExt() { |
| 118 } | 124 Unload(); |
| 119 void CDWriteExt::Unload() | 125 } |
| 120 { | 126 LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, |
| 121 if (m_pDwFontContext) { | 127 FX_DWORD size, |
| 122 delete (CDwFontContext*)m_pDwFontContext; | 128 int simulation_style) { |
| 123 m_pDwFontContext = NULL; | 129 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; |
| 124 } | 130 IDWriteFontFile* pDwFontFile = NULL; |
| 125 SafeRelease((IDWriteFactory**)&m_pDWriteFactory); | 131 IDWriteFontFace* pDwFontFace = NULL; |
| 126 } | 132 BOOL isSupportedFontType = FALSE; |
| 127 CDWriteExt::~CDWriteExt() | 133 DWRITE_FONT_FILE_TYPE fontFileType; |
| 128 { | 134 DWRITE_FONT_FACE_TYPE fontFaceType; |
| 129 Unload(); | 135 UINT32 numberOfFaces; |
| 130 } | 136 DWRITE_FONT_SIMULATIONS fontStyle = |
| 131 LPVOID» CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, FX_DWORD size, in
t simulation_style) | 137 (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); |
| 132 { | 138 HRESULT hr = S_OK; |
| 133 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; | 139 hr = pDwFactory->CreateCustomFontFileReference( |
| 134 IDWriteFontFile* pDwFontFile = NULL; | 140 (void const*)pData, (UINT32)size, CDwFontFileLoader::GetLoader(), |
| 135 IDWriteFontFace* pDwFontFace = NULL; | 141 &pDwFontFile); |
| 136 BOOL isSupportedFontType = FALSE; | 142 if (FAILED(hr)) { |
| 137 DWRITE_FONT_FILE_TYPE fontFileType; | 143 goto failed; |
| 138 DWRITE_FONT_FACE_TYPE fontFaceType; | 144 } |
| 139 UINT32 numberOfFaces; | 145 hr = pDwFontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, |
| 140 DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_sty
le & 3); | 146 &numberOfFaces); |
| 141 HRESULT hr = S_OK; | 147 if (FAILED(hr) || !isSupportedFontType || |
| 142 hr = pDwFactory->CreateCustomFontFileReference( | 148 fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { |
| 143 (void const*)pData, | 149 goto failed; |
| 144 (UINT32)size, | 150 } |
| 145 CDwFontFileLoader::GetLoader(), | 151 hr = pDwFactory->CreateFontFace(fontFaceType, 1, &pDwFontFile, 0, fontStyle, |
| 146 &pDwFontFile | 152 &pDwFontFace); |
| 147 ); | 153 if (FAILED(hr)) { |
| 148 if (FAILED(hr)) { | 154 goto failed; |
| 149 goto failed; | 155 } |
| 150 } | 156 SafeRelease(&pDwFontFile); |
| 151 hr = pDwFontFile->Analyze( | 157 return pDwFontFace; |
| 152 &isSupportedFontType, | |
| 153 &fontFileType, | |
| 154 &fontFaceType, | |
| 155 &numberOfFaces | |
| 156 ); | |
| 157 if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_T
YPE_UNKNOWN) { | |
| 158 goto failed; | |
| 159 } | |
| 160 hr = pDwFactory->CreateFontFace( | |
| 161 fontFaceType, | |
| 162 1, | |
| 163 &pDwFontFile, | |
| 164 0, | |
| 165 fontStyle, | |
| 166 &pDwFontFace | |
| 167 ); | |
| 168 if (FAILED(hr)) { | |
| 169 goto failed; | |
| 170 } | |
| 171 SafeRelease(&pDwFontFile); | |
| 172 return pDwFontFace; | |
| 173 failed: | 158 failed: |
| 174 SafeRelease(&pDwFontFile); | 159 SafeRelease(&pDwFontFile); |
| 175 return NULL; | 160 return NULL; |
| 176 } | 161 } |
| 177 FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** render
Target) | 162 FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, |
| 178 { | 163 void** renderTarget) { |
| 179 if (pBitmap->GetFormat() > FXDIB_Argb) { | 164 if (pBitmap->GetFormat() > FXDIB_Argb) { |
| 180 return FALSE; | 165 return FALSE; |
| 181 } | 166 } |
| 182 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; | 167 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; |
| 183 IDWriteGdiInterop* pGdiInterop = NULL; | 168 IDWriteGdiInterop* pGdiInterop = NULL; |
| 184 IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; | 169 IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; |
| 185 IDWriteRenderingParams* pRenderingParams = NULL; | 170 IDWriteRenderingParams* pRenderingParams = NULL; |
| 186 HRESULT hr = S_OK; | 171 HRESULT hr = S_OK; |
| 187 hr = pDwFactory->GetGdiInterop(&pGdiInterop); | 172 hr = pDwFactory->GetGdiInterop(&pGdiInterop); |
| 188 if (FAILED(hr)) { | 173 if (FAILED(hr)) { |
| 189 goto failed; | 174 goto failed; |
| 190 } | 175 } |
| 191 hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitma
p->GetHeight(), | 176 hr = pGdiInterop->CreateBitmapRenderTarget( |
| 192 &pBitmapRenderTarget); | 177 NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), &pBitmapRenderTarget); |
| 193 if (FAILED(hr)) { | 178 if (FAILED(hr)) { |
| 194 goto failed; | 179 goto failed; |
| 195 } | 180 } |
| 196 hr = pDwFactory->CreateCustomRenderingParams( | 181 hr = pDwFactory->CreateCustomRenderingParams( |
| 197 1.0f, | 182 1.0f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_RGB, |
| 198 0.0f, | 183 DWRITE_RENDERING_MODE_DEFAULT, &pRenderingParams); |
| 199 1.0f, | 184 if (FAILED(hr)) { |
| 200 DWRITE_PIXEL_GEOMETRY_RGB, | 185 goto failed; |
| 201 DWRITE_RENDERING_MODE_DEFAULT, | 186 } |
| 202 &pRenderingParams | 187 hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); |
| 203 ); | 188 if (FAILED(hr)) { |
| 204 if (FAILED(hr)) { | 189 goto failed; |
| 205 goto failed; | 190 } |
| 206 } | 191 *(CDwGdiTextRenderer**)renderTarget = |
| 207 hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); | 192 new CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); |
| 208 if (FAILED(hr)) { | 193 SafeRelease(&pGdiInterop); |
| 209 goto failed; | 194 SafeRelease(&pBitmapRenderTarget); |
| 210 } | 195 SafeRelease(&pRenderingParams); |
| 211 *(CDwGdiTextRenderer**)renderTarget = new CDwGdiTextRenderer(pBitmap, pBitma
pRenderTarget, pRenderingParams); | 196 return TRUE; |
| 212 SafeRelease(&pGdiInterop); | 197 failed: |
| 213 SafeRelease(&pBitmapRenderTarget); | 198 SafeRelease(&pGdiInterop); |
| 214 SafeRelease(&pRenderingParams); | 199 SafeRelease(&pBitmapRenderTarget); |
| 200 SafeRelease(&pRenderingParams); |
| 201 return FALSE; |
| 202 } |
| 203 FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, |
| 204 CFX_ClipRgn* pClipRgn, |
| 205 FX_RECT& stringRect, |
| 206 CFX_AffineMatrix* pMatrix, |
| 207 void* font, |
| 208 FX_FLOAT font_size, |
| 209 FX_ARGB text_color, |
| 210 int glyph_count, |
| 211 unsigned short* glyph_indices, |
| 212 FX_FLOAT baselineOriginX, |
| 213 FX_FLOAT baselineOriginY, |
| 214 void* glyph_offsets, |
| 215 FX_FLOAT* glyph_advances) { |
| 216 if (renderTarget == NULL) { |
| 215 return TRUE; | 217 return TRUE; |
| 216 failed: | 218 } |
| 217 SafeRelease(&pGdiInterop); | 219 CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; |
| 218 SafeRelease(&pBitmapRenderTarget); | 220 DWRITE_MATRIX transform; |
| 219 SafeRelease(&pRenderingParams); | 221 DWRITE_GLYPH_RUN glyphRun; |
| 220 return FALSE; | 222 HRESULT hr = S_OK; |
| 221 } | 223 if (pMatrix) { |
| 222 FX_BOOL»CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, F
X_RECT& stringRect, CFX_AffineMatrix* pMatrix, | 224 transform.m11 = pMatrix->a; |
| 223 void *font, FX_FLOAT font_size, FX_ARGB text
_color, | 225 transform.m12 = pMatrix->b; |
| 224 int glyph_count, unsigned short* glyph_indic
es, | 226 transform.m21 = pMatrix->c; |
| 225 FX_FLOAT baselineOriginX, FX_FLOAT baselineO
riginY, | 227 transform.m22 = pMatrix->d; |
| 226 void* glyph_offsets, | 228 transform.dx = pMatrix->e; |
| 227 FX_FLOAT* glyph_advances) | 229 transform.dy = pMatrix->f; |
| 228 { | 230 } |
| 229 if (renderTarget == NULL) { | 231 glyphRun.fontFace = (IDWriteFontFace*)font; |
| 230 return TRUE; | 232 glyphRun.fontEmSize = font_size; |
| 231 } | 233 glyphRun.glyphCount = glyph_count; |
| 232 CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; | 234 glyphRun.glyphIndices = glyph_indices; |
| 233 DWRITE_MATRIX transform; | 235 glyphRun.glyphAdvances = glyph_advances; |
| 234 DWRITE_GLYPH_RUN glyphRun; | 236 glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; |
| 235 HRESULT hr = S_OK; | 237 glyphRun.isSideways = FALSE; |
| 236 if (pMatrix) { | 238 glyphRun.bidiLevel = 0; |
| 237 transform.m11 = pMatrix->a; | 239 hr = pTextRenderer->DrawGlyphRun( |
| 238 transform.m12 = pMatrix->b; | 240 stringRect, pClipRgn, pMatrix ? &transform : NULL, baselineOriginX, |
| 239 transform.m21 = pMatrix->c; | 241 baselineOriginY, DWRITE_MEASURING_MODE_NATURAL, &glyphRun, |
| 240 transform.m22 = pMatrix->d; | 242 RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))); |
| 241 transform.dx = pMatrix->e; | 243 return SUCCEEDED(hr) ? TRUE : FALSE; |
| 242 transform.dy = pMatrix->f; | 244 } |
| 243 } | 245 void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) { |
| 244 glyphRun.fontFace = (IDWriteFontFace*)font; | 246 delete (CDwGdiTextRenderer*)renderTarget; |
| 245 glyphRun.fontEmSize = font_size; | 247 } |
| 246 glyphRun.glyphCount = glyph_count; | 248 void CDWriteExt::DwDeleteFont(void* pFont) { |
| 247 glyphRun.glyphIndices = glyph_indices; | 249 if (pFont) { |
| 248 glyphRun.glyphAdvances = glyph_advances; | 250 SafeRelease((IDWriteFontFace**)&pFont); |
| 249 glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; | 251 } |
| 250 glyphRun.isSideways = FALSE; | 252 } |
| 251 glyphRun.bidiLevel = 0; | 253 CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, |
| 252 hr = pTextRenderer->DrawGlyphRun( | 254 UINT32 fontFileReferenceKeySize) { |
| 253 stringRect, | 255 refCount_ = 0; |
| 254 pClipRgn, | 256 resourcePtr_ = fontFileReferenceKey; |
| 255 pMatrix ? &transform : NULL, | 257 resourceSize_ = fontFileReferenceKeySize; |
| 256 baselineOriginX, baselineOriginY, | 258 } |
| 257 DWRITE_MEASURING_MODE_NATURAL, | 259 HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, |
| 258 &glyphRun, | 260 void** ppvObject) { |
| 259 RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color
)) | 261 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { |
| 260 ); | 262 *ppvObject = this; |
| 261 return SUCCEEDED(hr) ? TRUE : FALSE; | 263 AddRef(); |
| 262 } | 264 return S_OK; |
| 263 void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) | 265 } |
| 264 { | 266 *ppvObject = NULL; |
| 265 delete (CDwGdiTextRenderer*)renderTarget; | 267 return E_NOINTERFACE; |
| 266 } | 268 } |
| 267 void CDWriteExt::DwDeleteFont(void* pFont) | 269 ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() { |
| 268 { | 270 return InterlockedIncrement((long*)(&refCount_)); |
| 269 if (pFont) { | 271 } |
| 270 SafeRelease((IDWriteFontFace**)&pFont); | 272 ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() { |
| 271 } | 273 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); |
| 272 } | 274 if (newCount == 0) { |
| 273 CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fo
ntFileReferenceKeySize) | 275 delete this; |
| 274 { | 276 } |
| 275 refCount_ = 0; | 277 return newCount; |
| 276 resourcePtr_ = fontFileReferenceKey; | 278 } |
| 277 resourceSize_ = fontFileReferenceKeySize; | 279 HRESULT STDMETHODCALLTYPE |
| 278 } | 280 CDwFontFileStream::ReadFileFragment(void const** fragmentStart, |
| 279 HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** p
pvObject) | 281 UINT64 fileOffset, |
| 280 { | 282 UINT64 fragmentSize, |
| 281 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { | 283 OUT void** fragmentContext) { |
| 282 *ppvObject = this; | 284 if (fileOffset <= resourceSize_ && |
| 283 AddRef(); | 285 fragmentSize <= resourceSize_ - fileOffset) { |
| 284 return S_OK; | 286 *fragmentStart = static_cast<uint8_t const*>(resourcePtr_) + |
| 285 } | 287 static_cast<size_t>(fileOffset); |
| 286 *ppvObject = NULL; | |
| 287 return E_NOINTERFACE; | |
| 288 } | |
| 289 ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() | |
| 290 { | |
| 291 return InterlockedIncrement((long*)(&refCount_)); | |
| 292 } | |
| 293 ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() | |
| 294 { | |
| 295 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); | |
| 296 if (newCount == 0) { | |
| 297 delete this; | |
| 298 } | |
| 299 return newCount; | |
| 300 } | |
| 301 HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment( | |
| 302 void const** fragmentStart, | |
| 303 UINT64 fileOffset, | |
| 304 UINT64 fragmentSize, | |
| 305 OUT void** fragmentContext | |
| 306 ) | |
| 307 { | |
| 308 if (fileOffset <= resourceSize_ && fragmentSize <= resourceSize_ - fileOffse
t) { | |
| 309 *fragmentStart = static_cast<uint8_t const*>(resourcePtr_) + static_cast
<size_t>(fileOffset); | |
| 310 *fragmentContext = NULL; | |
| 311 return S_OK; | |
| 312 } | |
| 313 *fragmentStart = NULL; | |
| 314 *fragmentContext = NULL; | 288 *fragmentContext = NULL; |
| 315 return E_FAIL; | |
| 316 } | |
| 317 void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentCont
ext) | |
| 318 { | |
| 319 } | |
| 320 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) | |
| 321 { | |
| 322 *fileSize = resourceSize_; | |
| 323 return S_OK; | 289 return S_OK; |
| 324 } | 290 } |
| 325 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWr
iteTime) | 291 *fragmentStart = NULL; |
| 326 { | 292 *fragmentContext = NULL; |
| 327 *lastWriteTime = 0; | 293 return E_FAIL; |
| 328 return E_NOTIMPL; | 294 } |
| 295 void STDMETHODCALLTYPE |
| 296 CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) {} |
| 297 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) { |
| 298 *fileSize = resourceSize_; |
| 299 return S_OK; |
| 300 } |
| 301 HRESULT STDMETHODCALLTYPE |
| 302 CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) { |
| 303 *lastWriteTime = 0; |
| 304 return E_NOTIMPL; |
| 329 } | 305 } |
| 330 IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; | 306 IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; |
| 331 CDwFontFileLoader::CDwFontFileLoader() : | 307 CDwFontFileLoader::CDwFontFileLoader() : refCount_(0) {} |
| 332 refCount_(0) | 308 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, |
| 333 { | 309 void** ppvObject) { |
| 334 } | 310 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { |
| 335 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** p
pvObject) | 311 *ppvObject = this; |
| 336 { | 312 AddRef(); |
| 337 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { | 313 return S_OK; |
| 338 *ppvObject = this; | 314 } |
| 339 AddRef(); | 315 *ppvObject = NULL; |
| 340 return S_OK; | 316 return E_NOINTERFACE; |
| 341 } | 317 } |
| 342 *ppvObject = NULL; | 318 ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() { |
| 343 return E_NOINTERFACE; | 319 return InterlockedIncrement((long*)(&refCount_)); |
| 344 } | 320 } |
| 345 ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() | 321 ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() { |
| 346 { | 322 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); |
| 347 return InterlockedIncrement((long*)(&refCount_)); | 323 if (newCount == 0) { |
| 348 } | 324 instance_ = NULL; |
| 349 ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() | 325 delete this; |
| 350 { | 326 } |
| 351 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); | 327 return newCount; |
| 352 if (newCount == 0) { | |
| 353 instance_ = NULL; | |
| 354 delete this; | |
| 355 } | |
| 356 return newCount; | |
| 357 } | 328 } |
| 358 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( | 329 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( |
| 359 void const* fontFileReferenceKey, | 330 void const* fontFileReferenceKey, |
| 360 UINT32 fontFileReferenceKeySize, | 331 UINT32 fontFileReferenceKeySize, |
| 361 OUT IDWriteFontFileStream** fontFileStream | 332 OUT IDWriteFontFileStream** fontFileStream) { |
| 362 ) | 333 *fontFileStream = NULL; |
| 363 { | 334 CDwFontFileStream* stream = |
| 364 *fontFileStream = NULL; | 335 new CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize); |
| 365 CDwFontFileStream* stream = new CDwFontFileStream(fontFileReferenceKey, font
FileReferenceKeySize); | 336 if (!stream->IsInitialized()) { |
| 366 if (!stream->IsInitialized()) { | 337 delete stream; |
| 367 delete stream; | 338 return E_FAIL; |
| 368 return E_FAIL; | 339 } |
| 369 } | 340 *fontFileStream = SafeAcquire(stream); |
| 370 *fontFileStream = SafeAcquire(stream); | 341 return S_OK; |
| 371 return S_OK; | 342 } |
| 372 } | 343 CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) |
| 373 CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) : | 344 : hr_(S_FALSE), dwriteFactory_(SafeAcquire(dwriteFactory)) {} |
| 374 hr_(S_FALSE), | 345 CDwFontContext::~CDwFontContext() { |
| 375 dwriteFactory_(SafeAcquire(dwriteFactory)) | 346 if (dwriteFactory_ && hr_ == S_OK) { |
| 376 { | 347 dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader()); |
| 377 } | 348 } |
| 378 CDwFontContext::~CDwFontContext() | 349 SafeRelease(&dwriteFactory_); |
| 379 { | 350 } |
| 380 if(dwriteFactory_ && hr_ == S_OK) { | 351 HRESULT CDwFontContext::Initialize() { |
| 381 dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader())
; | 352 if (hr_ == S_FALSE) { |
| 382 } | 353 return hr_ = dwriteFactory_->RegisterFontFileLoader( |
| 383 SafeRelease(&dwriteFactory_); | 354 CDwFontFileLoader::GetLoader()); |
| 384 } | 355 } |
| 385 HRESULT CDwFontContext::Initialize() | 356 return hr_; |
| 386 { | 357 } |
| 387 if (hr_ == S_FALSE) { | 358 CDwGdiTextRenderer::CDwGdiTextRenderer( |
| 388 return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::G
etLoader()); | 359 CFX_DIBitmap* pBitmap, |
| 389 } | 360 IDWriteBitmapRenderTarget* bitmapRenderTarget, |
| 390 return hr_; | 361 IDWriteRenderingParams* renderingParams) |
| 391 } | 362 : pBitmap_(pBitmap), |
| 392 CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRende
rTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams): | 363 pRenderTarget_(SafeAcquire(bitmapRenderTarget)), |
| 393 pBitmap_(pBitmap), | 364 pRenderingParams_(SafeAcquire(renderingParams)) {} |
| 394 pRenderTarget_(SafeAcquire(bitmapRenderTarget)), | 365 CDwGdiTextRenderer::~CDwGdiTextRenderer() { |
| 395 pRenderingParams_(SafeAcquire(renderingParams)) | 366 SafeRelease(&pRenderTarget_); |
| 396 { | 367 SafeRelease(&pRenderingParams_); |
| 397 } | |
| 398 CDwGdiTextRenderer::~CDwGdiTextRenderer() | |
| 399 { | |
| 400 SafeRelease(&pRenderTarget_); | |
| 401 SafeRelease(&pRenderingParams_); | |
| 402 } | 368 } |
| 403 STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( | 369 STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( |
| 404 const FX_RECT& text_bbox, | 370 const FX_RECT& text_bbox, |
| 405 __in_opt CFX_ClipRgn* pClipRgn, | 371 __in_opt CFX_ClipRgn* pClipRgn, |
| 406 __in_opt DWRITE_MATRIX const* pMatrix, | 372 __in_opt DWRITE_MATRIX const* pMatrix, |
| 407 FLOAT baselineOriginX, | 373 FLOAT baselineOriginX, |
| 408 FLOAT baselineOriginY, | 374 FLOAT baselineOriginY, |
| 409 DWRITE_MEASURING_MODE measuringMode, | 375 DWRITE_MEASURING_MODE measuringMode, |
| 410 __in DWRITE_GLYPH_RUN const* glyphRun, | 376 __in DWRITE_GLYPH_RUN const* glyphRun, |
| 411 const COLORREF& textColor | 377 const COLORREF& textColor) { |
| 412 ) | 378 HRESULT hr = S_OK; |
| 413 { | 379 if (pMatrix) { |
| 414 HRESULT hr = S_OK; | 380 hr = pRenderTarget_->SetCurrentTransform(pMatrix); |
| 415 if (pMatrix) { | 381 if (FAILED(hr)) { |
| 416 hr = pRenderTarget_->SetCurrentTransform(pMatrix); | 382 return hr; |
| 417 if (FAILED(hr)) { | |
| 418 return hr; | |
| 419 } | |
| 420 } | 383 } |
| 421 HDC hDC = pRenderTarget_->GetMemoryDC(); | 384 } |
| 422 HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); | 385 HDC hDC = pRenderTarget_->GetMemoryDC(); |
| 423 BITMAP bitmap; | 386 HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); |
| 424 GetObject(hBitmap, sizeof bitmap, &bitmap); | 387 BITMAP bitmap; |
| 425 CFX_DIBitmap dib; | 388 GetObject(hBitmap, sizeof bitmap, &bitmap); |
| 426 dib.Create( | 389 CFX_DIBitmap dib; |
| 427 bitmap.bmWidth, | 390 dib.Create(bitmap.bmWidth, bitmap.bmHeight, |
| 428 bitmap.bmHeight, | 391 bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, |
| 429 bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, | 392 (uint8_t*)bitmap.bmBits); |
| 430 (uint8_t*)bitmap.bmBits | 393 dib.CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), |
| 431 ); | 394 text_bbox.Height(), pBitmap_, text_bbox.left, |
| 432 dib.CompositeBitmap( | 395 text_bbox.top, FXDIB_BLEND_NORMAL, NULL); |
| 433 text_bbox.left, | 396 hr = pRenderTarget_->DrawGlyphRun(baselineOriginX, baselineOriginY, |
| 434 text_bbox.top, | 397 measuringMode, glyphRun, pRenderingParams_, |
| 435 text_bbox.Width(), | 398 textColor); |
| 436 text_bbox.Height(), | 399 if (FAILED(hr)) { |
| 437 pBitmap_, | |
| 438 text_bbox.left, | |
| 439 text_bbox.top, | |
| 440 FXDIB_BLEND_NORMAL, | |
| 441 NULL | |
| 442 ); | |
| 443 hr = pRenderTarget_->DrawGlyphRun( | |
| 444 baselineOriginX, | |
| 445 baselineOriginY, | |
| 446 measuringMode, | |
| 447 glyphRun, | |
| 448 pRenderingParams_, | |
| 449 textColor | |
| 450 ); | |
| 451 if (FAILED(hr)) { | |
| 452 return hr; | |
| 453 } | |
| 454 pBitmap_->CompositeBitmap( | |
| 455 text_bbox.left, | |
| 456 text_bbox.top, | |
| 457 text_bbox.Width(), | |
| 458 text_bbox.Height(), | |
| 459 &dib, | |
| 460 text_bbox.left, | |
| 461 text_bbox.top, | |
| 462 FXDIB_BLEND_NORMAL, | |
| 463 pClipRgn | |
| 464 ); | |
| 465 return hr; | 400 return hr; |
| 401 } |
| 402 pBitmap_->CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), |
| 403 text_bbox.Height(), &dib, text_bbox.left, |
| 404 text_bbox.top, FXDIB_BLEND_NORMAL, pClipRgn); |
| 405 return hr; |
| 466 } | 406 } |
| 467 #endif | 407 #endif |
| OLD | NEW |