| 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 |