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