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 "xfa/fgas/font/cfgas_gefont.h" | 7 #include "xfa/fgas/font/cfgas_gefont.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "core/fxge/cfx_substfont.h" | 12 #include "core/fxge/cfx_substfont.h" |
13 #include "core/fxge/cfx_unicodeencoding.h" | 13 #include "core/fxge/cfx_unicodeencoding.h" |
14 #include "core/fxge/cfx_unicodeencodingex.h" | 14 #include "core/fxge/cfx_unicodeencodingex.h" |
15 #include "third_party/base/ptr_util.h" | 15 #include "third_party/base/ptr_util.h" |
16 #include "xfa/fgas/crt/fgas_codepage.h" | 16 #include "xfa/fgas/crt/fgas_codepage.h" |
17 #include "xfa/fgas/font/fgas_fontutils.h" | 17 #include "xfa/fgas/font/fgas_fontutils.h" |
18 #include "xfa/fxfa/xfa_fontmgr.h" | 18 #include "xfa/fxfa/xfa_fontmgr.h" |
19 | 19 |
20 // static | 20 // static |
21 CFGAS_GEFont* CFGAS_GEFont::LoadFont(const FX_WCHAR* pszFontFamily, | 21 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( |
22 uint32_t dwFontStyles, | 22 const FX_WCHAR* pszFontFamily, |
23 uint16_t wCodePage, | 23 uint32_t dwFontStyles, |
24 CFGAS_FontMgr* pFontMgr) { | 24 uint16_t wCodePage, |
| 25 CFGAS_FontMgr* pFontMgr) { |
25 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 26 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
26 if (pFontMgr) | 27 if (!pFontMgr) |
27 return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); | 28 return nullptr; |
28 return nullptr; | 29 |
| 30 return CFX_RetainPtr<CFGAS_GEFont>( |
| 31 pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily)); |
29 #else | 32 #else |
30 CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); | 33 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); |
31 if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) { | 34 if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) |
32 pFont->Release(); | |
33 return nullptr; | 35 return nullptr; |
34 } | |
35 return pFont; | 36 return pFont; |
36 #endif | 37 #endif |
37 } | 38 } |
38 | 39 |
39 // static | 40 // static |
40 CFGAS_GEFont* CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont, | 41 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont, |
41 CFGAS_FontMgr* pFontMgr) { | 42 CFGAS_FontMgr* pFontMgr) { |
42 CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); | 43 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); |
43 if (!pFont->LoadFontInternal(pExternalFont)) { | 44 if (!pFont->LoadFontInternal(pExternalFont)) |
44 pFont->Release(); | |
45 return nullptr; | 45 return nullptr; |
46 } | |
47 return pFont; | 46 return pFont; |
48 } | 47 } |
49 | 48 |
50 // static | 49 // static |
51 CFGAS_GEFont* CFGAS_GEFont::LoadFont(std::unique_ptr<CFX_Font> pInternalFont, | 50 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( |
52 CFGAS_FontMgr* pFontMgr) { | 51 std::unique_ptr<CFX_Font> pInternalFont, |
53 CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); | 52 CFGAS_FontMgr* pFontMgr) { |
54 if (!pFont->LoadFontInternal(std::move(pInternalFont))) { | 53 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); |
55 pFont->Release(); | 54 if (!pFont->LoadFontInternal(std::move(pInternalFont))) |
56 return nullptr; | 55 return nullptr; |
57 } | |
58 return pFont; | 56 return pFont; |
59 } | 57 } |
60 | 58 |
61 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 59 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
62 // static | 60 // static |
63 CFGAS_GEFont* CFGAS_GEFont::LoadFont(const uint8_t* pBuffer, | 61 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(const uint8_t* pBuffer, |
64 int32_t iLength, | 62 int32_t iLength, |
65 CFGAS_FontMgr* pFontMgr) { | 63 CFGAS_FontMgr* pFontMgr) { |
66 CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); | 64 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); |
67 if (!pFont->LoadFontInternal(pBuffer, iLength)) { | 65 if (pFont->LoadFontInternal(pBuffer, iLength)) |
68 pFont->Release(); | |
69 return nullptr; | 66 return nullptr; |
70 } | |
71 return pFont; | 67 return pFont; |
72 } | 68 } |
73 | 69 |
74 // static | 70 // static |
75 CFGAS_GEFont* CFGAS_GEFont::LoadFont( | 71 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( |
76 const CFX_RetainPtr<IFGAS_Stream>& pFontStream, | 72 const CFX_RetainPtr<IFGAS_Stream>& pFontStream, |
77 CFGAS_FontMgr* pFontMgr, | 73 CFGAS_FontMgr* pFontMgr, |
78 bool bSaveStream) { | 74 bool bSaveStream) { |
79 CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); | 75 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); |
80 if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) { | 76 if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) |
81 pFont->Release(); | |
82 return nullptr; | 77 return nullptr; |
83 } | |
84 return pFont; | 78 return pFont; |
85 } | 79 } |
86 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 80 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
87 | 81 |
88 CFGAS_GEFont::CFGAS_GEFont(CFGAS_FontMgr* pFontMgr) | 82 CFGAS_GEFont::CFGAS_GEFont(CFGAS_FontMgr* pFontMgr) |
89 : | 83 : |
90 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 84 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
91 m_bUseLogFontStyle(false), | 85 m_bUseLogFontStyle(false), |
92 m_dwLogFontStyle(0), | 86 m_dwLogFontStyle(0), |
93 #endif | 87 #endif |
94 m_pFont(nullptr), | 88 m_pFont(nullptr), |
95 m_pSrcFont(nullptr), | |
96 m_pFontMgr(pFontMgr), | 89 m_pFontMgr(pFontMgr), |
97 m_iRefCount(1), | |
98 m_bExternalFont(false), | 90 m_bExternalFont(false), |
99 m_pProvider(nullptr) { | 91 m_pProvider(nullptr) { |
100 } | 92 } |
101 | 93 |
102 CFGAS_GEFont::CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles) | 94 CFGAS_GEFont::CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src, |
| 95 uint32_t dwFontStyles) |
103 : | 96 : |
104 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 97 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
105 m_bUseLogFontStyle(false), | 98 m_bUseLogFontStyle(false), |
106 m_dwLogFontStyle(0), | 99 m_dwLogFontStyle(0), |
107 #endif | 100 #endif |
108 m_pFont(nullptr), | 101 m_pFont(nullptr), |
109 m_pSrcFont(src), | 102 m_pSrcFont(src), |
110 m_pFontMgr(src->m_pFontMgr), | 103 m_pFontMgr(src->m_pFontMgr), |
111 m_iRefCount(1), | |
112 m_bExternalFont(false), | 104 m_bExternalFont(false), |
113 m_pProvider(nullptr) { | 105 m_pProvider(nullptr) { |
114 ASSERT(m_pSrcFont->m_pFont); | 106 ASSERT(m_pSrcFont->m_pFont); |
115 m_pSrcFont->Retain(); | |
116 m_pFont = new CFX_Font; | 107 m_pFont = new CFX_Font; |
117 m_pFont->LoadClone(m_pSrcFont->m_pFont); | 108 m_pFont->LoadClone(m_pSrcFont->m_pFont); |
118 CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); | 109 CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); |
119 if (!pSubst) { | 110 if (!pSubst) { |
120 pSubst = new CFX_SubstFont; | 111 pSubst = new CFX_SubstFont; |
121 m_pFont->SetSubstFont(std::unique_ptr<CFX_SubstFont>(pSubst)); | 112 m_pFont->SetSubstFont(std::unique_ptr<CFX_SubstFont>(pSubst)); |
122 } | 113 } |
123 pSubst->m_Weight = | 114 pSubst->m_Weight = |
124 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; | 115 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; |
125 if (dwFontStyles & FX_FONTSTYLE_Italic) | 116 if (dwFontStyles & FX_FONTSTYLE_Italic) |
126 pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC; | 117 pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC; |
127 InitFont(); | 118 InitFont(); |
128 } | 119 } |
129 | 120 |
130 CFGAS_GEFont::~CFGAS_GEFont() { | 121 CFGAS_GEFont::~CFGAS_GEFont() { |
131 for (int32_t i = 0; i < m_SubstFonts.GetSize(); i++) | 122 if (m_pFontMgr) |
132 m_SubstFonts[i]->Release(); | 123 m_pFontMgr->RemoveFont(CFX_RetainPtr<CFGAS_GEFont>(this)); |
133 | |
134 m_SubstFonts.RemoveAll(); | |
135 m_FontMapper.clear(); | |
136 | 124 |
137 if (!m_bExternalFont) | 125 if (!m_bExternalFont) |
138 delete m_pFont; | 126 delete m_pFont; |
139 | |
140 // If it is a shallow copy of another source font, | |
141 // decrease the refcount of the source font. | |
142 if (m_pSrcFont) | |
143 m_pSrcFont->Release(); | |
144 } | |
145 | |
146 void CFGAS_GEFont::Release() { | |
147 if (--m_iRefCount < 1) { | |
148 if (m_pFontMgr) | |
149 m_pFontMgr->RemoveFont(this); | |
150 delete this; | |
151 } | |
152 } | |
153 CFGAS_GEFont* CFGAS_GEFont::Retain() { | |
154 ++m_iRefCount; | |
155 return this; | |
156 } | 127 } |
157 | 128 |
158 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 129 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
159 bool CFGAS_GEFont::LoadFontInternal(const FX_WCHAR* pszFontFamily, | 130 bool CFGAS_GEFont::LoadFontInternal(const FX_WCHAR* pszFontFamily, |
160 uint32_t dwFontStyles, | 131 uint32_t dwFontStyles, |
161 uint16_t wCodePage) { | 132 uint16_t wCodePage) { |
162 if (m_pFont) | 133 if (m_pFont) |
163 return false; | 134 return false; |
164 CFX_ByteString csFontFamily; | 135 CFX_ByteString csFontFamily; |
165 if (pszFontFamily) | 136 if (pszFontFamily) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 pdfium::MakeUnique<CFX_DiscreteArrayTemplate<uint16_t>>(1024); | 224 pdfium::MakeUnique<CFX_DiscreteArrayTemplate<uint16_t>>(1024); |
254 } | 225 } |
255 if (!m_pRectArray) | 226 if (!m_pRectArray) |
256 m_pRectArray = pdfium::MakeUnique<CFX_MassArrayTemplate<CFX_Rect>>(16); | 227 m_pRectArray = pdfium::MakeUnique<CFX_MassArrayTemplate<CFX_Rect>>(16); |
257 if (!m_pBBoxMap) | 228 if (!m_pBBoxMap) |
258 m_pBBoxMap = pdfium::MakeUnique<CFX_MapPtrToPtr>(16); | 229 m_pBBoxMap = pdfium::MakeUnique<CFX_MapPtrToPtr>(16); |
259 | 230 |
260 return true; | 231 return true; |
261 } | 232 } |
262 | 233 |
263 CFGAS_GEFont* CFGAS_GEFont::Derive(uint32_t dwFontStyles, uint16_t wCodePage) { | 234 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::Derive(uint32_t dwFontStyles, |
| 235 uint16_t wCodePage) { |
| 236 CFX_RetainPtr<CFGAS_GEFont> pFont(this); |
264 if (GetFontStyles() == dwFontStyles) | 237 if (GetFontStyles() == dwFontStyles) |
265 return Retain(); | 238 return pFont; |
266 return new CFGAS_GEFont(this, dwFontStyles); | 239 return pdfium::MakeRetain<CFGAS_GEFont>(pFont, dwFontStyles); |
267 } | 240 } |
268 | 241 |
269 CFX_WideString CFGAS_GEFont::GetFamilyName() const { | 242 CFX_WideString CFGAS_GEFont::GetFamilyName() const { |
270 if (!m_pFont->GetSubstFont() || | 243 if (!m_pFont->GetSubstFont() || |
271 m_pFont->GetSubstFont()->m_Family.GetLength() == 0) { | 244 m_pFont->GetSubstFont()->m_Family.GetLength() == 0) { |
272 return CFX_WideString::FromLocal(m_pFont->GetFamilyName().AsStringC()); | 245 return CFX_WideString::FromLocal(m_pFont->GetFamilyName().AsStringC()); |
273 } | 246 } |
274 return CFX_WideString::FromLocal( | 247 return CFX_WideString::FromLocal( |
275 m_pFont->GetSubstFont()->m_Family.AsStringC()); | 248 m_pFont->GetSubstFont()->m_Family.AsStringC()); |
276 } | 249 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 bool bCharCode) { | 283 bool bCharCode) { |
311 ASSERT(m_pCharWidthMap); | 284 ASSERT(m_pCharWidthMap); |
312 iWidth = m_pCharWidthMap->GetAt(wUnicode, 0); | 285 iWidth = m_pCharWidthMap->GetAt(wUnicode, 0); |
313 if (iWidth == 65535) | 286 if (iWidth == 65535) |
314 return false; | 287 return false; |
315 | 288 |
316 if (iWidth > 0) | 289 if (iWidth > 0) |
317 return true; | 290 return true; |
318 | 291 |
319 if (!m_pProvider || | 292 if (!m_pProvider || |
320 !m_pProvider->GetCharWidth(this, wUnicode, bCharCode, &iWidth)) { | 293 !m_pProvider->GetCharWidth(CFX_RetainPtr<CFGAS_GEFont>(this), wUnicode, |
321 CFGAS_GEFont* pFont = nullptr; | 294 bCharCode, &iWidth)) { |
| 295 CFX_RetainPtr<CFGAS_GEFont> pFont; |
322 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); | 296 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); |
323 if (iGlyph != 0xFFFF && pFont) { | 297 if (iGlyph != 0xFFFF && pFont) { |
324 if (pFont == this) { | 298 if (pFont.Get() == this) { |
325 iWidth = m_pFont->GetGlyphWidth(iGlyph); | 299 iWidth = m_pFont->GetGlyphWidth(iGlyph); |
326 if (iWidth < 0) | 300 if (iWidth < 0) |
327 iWidth = -1; | 301 iWidth = -1; |
328 } else if (pFont->GetCharWidthInternal(wUnicode, iWidth, false, | 302 } else if (pFont->GetCharWidthInternal(wUnicode, iWidth, false, |
329 bCharCode)) { | 303 bCharCode)) { |
330 return true; | 304 return true; |
331 } | 305 } |
332 } else { | 306 } else { |
333 iWidth = -1; | 307 iWidth = -1; |
334 } | 308 } |
335 } | 309 } |
336 m_pCharWidthMap->SetAtGrow(wUnicode, iWidth); | 310 m_pCharWidthMap->SetAtGrow(wUnicode, iWidth); |
337 return iWidth > 0; | 311 return iWidth > 0; |
338 } | 312 } |
339 | 313 |
340 bool CFGAS_GEFont::GetCharBBox(FX_WCHAR wUnicode, | 314 bool CFGAS_GEFont::GetCharBBox(FX_WCHAR wUnicode, |
341 CFX_Rect& bbox, | 315 CFX_Rect& bbox, |
342 bool bCharCode) { | 316 bool bCharCode) { |
343 return GetCharBBoxInternal(wUnicode, bbox, true, bCharCode); | 317 return GetCharBBoxInternal(wUnicode, bbox, true, bCharCode); |
344 } | 318 } |
345 | 319 |
346 bool CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode, | 320 bool CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode, |
347 CFX_Rect& bbox, | 321 CFX_Rect& bbox, |
348 bool bRecursive, | 322 bool bRecursive, |
349 bool bCharCode) { | 323 bool bCharCode) { |
350 ASSERT(m_pRectArray); | 324 ASSERT(m_pRectArray); |
351 ASSERT(m_pBBoxMap); | 325 ASSERT(m_pBBoxMap); |
352 void* pRect = nullptr; | 326 void* pRect = nullptr; |
353 if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) { | 327 if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) { |
354 CFGAS_GEFont* pFont = nullptr; | 328 CFX_RetainPtr<CFGAS_GEFont> pFont; |
355 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); | 329 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); |
356 if (iGlyph != 0xFFFF && pFont) { | 330 if (iGlyph != 0xFFFF && pFont) { |
357 if (pFont == this) { | 331 if (pFont.Get() == this) { |
358 FX_RECT rtBBox; | 332 FX_RECT rtBBox; |
359 if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) { | 333 if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) { |
360 CFX_Rect rt; | 334 CFX_Rect rt; |
361 rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); | 335 rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); |
362 int32_t index = m_pRectArray->Add(rt); | 336 int32_t index = m_pRectArray->Add(rt); |
363 pRect = m_pRectArray->GetPtrAt(index); | 337 pRect = m_pRectArray->GetPtrAt(index); |
364 m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect); | 338 m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect); |
365 } | 339 } |
366 } else if (pFont->GetCharBBoxInternal(wUnicode, bbox, false, bCharCode)) { | 340 } else if (pFont->GetCharBBoxInternal(wUnicode, bbox, false, bCharCode)) { |
367 return true; | 341 return true; |
(...skipping 17 matching lines...) Expand all Loading... |
385 bbox.height = -rt.Height(); | 359 bbox.height = -rt.Height(); |
386 return true; | 360 return true; |
387 } | 361 } |
388 | 362 |
389 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode) { | 363 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode) { |
390 return GetGlyphIndex(wUnicode, true, nullptr, bCharCode); | 364 return GetGlyphIndex(wUnicode, true, nullptr, bCharCode); |
391 } | 365 } |
392 | 366 |
393 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, | 367 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, |
394 bool bRecursive, | 368 bool bRecursive, |
395 CFGAS_GEFont** ppFont, | 369 CFX_RetainPtr<CFGAS_GEFont>* ppFont, |
396 bool bCharCode) { | 370 bool bCharCode) { |
397 ASSERT(m_pFontEncoding); | |
398 int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode); | 371 int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode); |
399 if (iGlyphIndex > 0) { | 372 if (iGlyphIndex > 0) { |
400 if (ppFont) | 373 if (ppFont) |
401 *ppFont = this; | 374 ppFont->Reset(this); |
402 return iGlyphIndex; | 375 return iGlyphIndex; |
403 } | 376 } |
404 const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode); | 377 const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode); |
405 if (!pFontUSB) | 378 if (!pFontUSB) |
406 return 0xFFFF; | 379 return 0xFFFF; |
407 | 380 |
408 uint16_t wBitField = pFontUSB->wBitField; | 381 uint16_t wBitField = pFontUSB->wBitField; |
409 if (wBitField >= 128) | 382 if (wBitField >= 128) |
410 return 0xFFFF; | 383 return 0xFFFF; |
411 | 384 |
412 auto it = m_FontMapper.find(wUnicode); | 385 auto it = m_FontMapper.find(wUnicode); |
413 CFGAS_GEFont* pFont = it != m_FontMapper.end() ? it->second : nullptr; | 386 if (it != m_FontMapper.end() && it->second && it->second.Get() != this) { |
414 if (pFont && pFont != this) { | 387 iGlyphIndex = |
415 iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); | 388 it->second->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); |
416 if (iGlyphIndex != 0xFFFF) { | 389 if (iGlyphIndex != 0xFFFF) { |
417 int32_t i = m_SubstFonts.Find(pFont); | 390 for (size_t i = 0; i < m_SubstFonts.size(); ++i) { |
418 if (i > -1) { | 391 if (m_SubstFonts[i] == it->second) { |
419 iGlyphIndex |= ((i + 1) << 24); | 392 if (ppFont) |
420 if (ppFont) | 393 *ppFont = it->second; |
421 *ppFont = pFont; | 394 return (iGlyphIndex | ((i + 1) << 24)); |
422 return iGlyphIndex; | 395 } |
423 } | 396 } |
424 } | 397 } |
425 } | 398 } |
426 if (!m_pFontMgr || !bRecursive) | 399 if (!m_pFontMgr || !bRecursive) |
427 return 0xFFFF; | 400 return 0xFFFF; |
| 401 |
428 CFX_WideString wsFamily = GetFamilyName(); | 402 CFX_WideString wsFamily = GetFamilyName(); |
429 pFont = | 403 CFX_RetainPtr<CFGAS_GEFont> pFont = |
430 m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), wsFamily.c_str()); | 404 m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), wsFamily.c_str()); |
431 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 405 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
432 if (!pFont) | 406 if (!pFont) |
433 pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr); | 407 pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr); |
434 #endif | 408 #endif |
435 if (!pFont) | 409 if (!pFont || pFont.Get() == this) // Avoids direct cycles below. |
436 return 0xFFFF; | 410 return 0xFFFF; |
437 if (pFont == this) { | 411 |
438 pFont->Release(); | |
439 return 0xFFFF; | |
440 } | |
441 m_FontMapper[wUnicode] = pFont; | 412 m_FontMapper[wUnicode] = pFont; |
442 int32_t i = m_SubstFonts.GetSize(); | 413 m_SubstFonts.push_back(pFont); |
443 m_SubstFonts.Add(pFont); | |
444 iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); | 414 iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); |
445 if (iGlyphIndex == 0xFFFF) | 415 if (iGlyphIndex == 0xFFFF) |
446 return 0xFFFF; | 416 return 0xFFFF; |
447 iGlyphIndex |= ((i + 1) << 24); | 417 |
448 if (ppFont) | 418 if (ppFont) |
449 *ppFont = pFont; | 419 *ppFont = pFont; |
450 return iGlyphIndex; | 420 return (iGlyphIndex | (m_SubstFonts.size() << 24)); |
451 } | 421 } |
452 | 422 |
453 int32_t CFGAS_GEFont::GetAscent() const { | 423 int32_t CFGAS_GEFont::GetAscent() const { |
454 return m_pFont->GetAscent(); | 424 return m_pFont->GetAscent(); |
455 } | 425 } |
456 | 426 |
457 int32_t CFGAS_GEFont::GetDescent() const { | 427 int32_t CFGAS_GEFont::GetDescent() const { |
458 return m_pFont->GetDescent(); | 428 return m_pFont->GetDescent(); |
459 } | 429 } |
460 | 430 |
461 CFGAS_GEFont* CFGAS_GEFont::GetSubstFont(int32_t iGlyphIndex) const { | 431 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::GetSubstFont( |
| 432 int32_t iGlyphIndex) const { |
462 iGlyphIndex = static_cast<uint32_t>(iGlyphIndex) >> 24; | 433 iGlyphIndex = static_cast<uint32_t>(iGlyphIndex) >> 24; |
463 return iGlyphIndex == 0 ? const_cast<CFGAS_GEFont*>(this) | 434 if (iGlyphIndex == 0) |
464 : m_SubstFonts[iGlyphIndex - 1]; | 435 return CFX_RetainPtr<CFGAS_GEFont>(const_cast<CFGAS_GEFont*>(this)); |
| 436 return m_SubstFonts[iGlyphIndex - 1]; |
465 } | 437 } |
OLD | NEW |