diff options
author | tsepez <tsepez@chromium.org> | 2017-01-05 12:57:00 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2017-01-05 12:57:00 -0800 |
commit | e647799f6a2f7f747c9f55d9f0ce08dcdfbd53f4 (patch) | |
tree | 282c502bd9f807f385d0cbcc1692bb475c8a4df1 /xfa/fgas | |
parent | 6bb3b894488fd6f38c096b708980a9f08286ac5c (diff) | |
download | pdfium-e647799f6a2f7f747c9f55d9f0ce08dcdfbd53f4.tar.xz |
Properly ref-count CFGAS_GEFont with CFX_RetainPtr.
We worry about cyclical references, but no leaks found.
Review-Url: https://codereview.chromium.org/2609423003
Diffstat (limited to 'xfa/fgas')
-rw-r--r-- | xfa/fgas/font/cfgas_fontmgr.cpp | 299 | ||||
-rw-r--r-- | xfa/fgas/font/cfgas_fontmgr.h | 100 | ||||
-rw-r--r-- | xfa/fgas/font/cfgas_gefont.cpp | 162 | ||||
-rw-r--r-- | xfa/fgas/font/cfgas_gefont.h | 58 | ||||
-rw-r--r-- | xfa/fgas/layout/fgas_rtfbreak.cpp | 28 | ||||
-rw-r--r-- | xfa/fgas/layout/fgas_rtfbreak.h | 7 | ||||
-rw-r--r-- | xfa/fgas/layout/fgas_textbreak.cpp | 25 | ||||
-rw-r--r-- | xfa/fgas/layout/fgas_textbreak.h | 6 | ||||
-rw-r--r-- | xfa/fgas/layout/fgas_unicode.h | 13 |
9 files changed, 324 insertions, 374 deletions
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp index 5cf5a46d0e..1849441a16 100644 --- a/xfa/fgas/font/cfgas_fontmgr.cpp +++ b/xfa/fgas/font/cfgas_fontmgr.cpp @@ -15,6 +15,7 @@ #include "core/fxge/cfx_gemodule.h" #include "core/fxge/ifx_systemfontinfo.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fgas/crt/fgas_codepage.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fgas/font/fgas_fontutils.h" @@ -101,38 +102,25 @@ std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create( } CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator) - : m_pEnumerator(pEnumerator), - m_FontFaces(100), - m_CPFonts(8), - m_FamilyFonts(16), - m_UnicodeFonts(16), - m_BufferFonts(4), - m_StreamFonts(4), - m_DeriveFonts(4) { + : m_pEnumerator(pEnumerator), m_FontFaces(100) { if (m_pEnumerator) m_pEnumerator(m_FontFaces, nullptr, 0xFEFF); } CFGAS_FontMgr::~CFGAS_FontMgr() { m_FontFaces.RemoveAll(false); - m_CPFonts.RemoveAll(); - m_FamilyFonts.RemoveAll(); - m_UnicodeFonts.RemoveAll(); - m_BufferFonts.RemoveAll(); - m_StreamFonts.RemoveAll(); - m_DeriveFonts.RemoveAll(); - for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--) - m_Fonts[i]->Release(); } -CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( + uint16_t wCodePage, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily) { uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); - CFGAS_GEFont* pFont = nullptr; - if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) - return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr; - FX_FONTDESCRIPTOR const* pFD = + auto it = m_CPFonts.find(dwHash); + if (it != m_CPFonts.end()) { + return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr; + } + const FX_FONTDESCRIPTOR* pFD = FindFont(pszFontFamily, dwFontStyles, true, wCodePage); if (!pFD) pFD = FindFont(nullptr, dwFontStyles, true, wCodePage); @@ -141,32 +129,34 @@ CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, if (!pFD) return nullptr; - pFont = + CFX_RetainPtr<CFGAS_GEFont> pFont = CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); if (!pFont) return nullptr; - m_Fonts.Add(pFont); - m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + m_Fonts.push_back(pFont); + m_CPFonts[dwHash] = pFont; dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage); - m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + m_FamilyFonts[dwHash] = pFont; return LoadFont(pFont, dwFontStyles, wCodePage); } -CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode( + FX_WCHAR wUnicode, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily) { const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode); if (pRet->wBitField == 999) return nullptr; uint32_t dwHash = FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField); - CFGAS_GEFont* pFont = nullptr; - if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) - return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : nullptr; - - FX_FONTDESCRIPTOR const* pFD = + auto it = m_UnicodeFonts.find(dwHash); + if (it != m_UnicodeFonts.end()) { + return it->second ? LoadFont(it->second, dwFontStyles, pRet->wCodePage) + : nullptr; + } + const FX_FONTDESCRIPTOR* pFD = FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage, pRet->wBitField, wUnicode); if (!pFD && pszFontFamily) { @@ -178,28 +168,31 @@ CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); const FX_WCHAR* pFontFace = pFD->wsFontFace; - pFont = CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this); + CFX_RetainPtr<CFGAS_GEFont> pFont = + CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this); if (!pFont) return nullptr; - m_Fonts.Add(pFont); - m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); - dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); - m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); - dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage); - m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + m_Fonts.push_back(pFont); + m_UnicodeFonts[dwHash] = pFont; + m_CPFonts[FGAS_GetFontHashCode(wCodePage, dwFontStyles)] = pFont; + m_FamilyFonts[FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage)] = + pFont; return LoadFont(pFont, dwFontStyles, wCodePage); } -CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const FX_WCHAR* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( + const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage) { + CFX_RetainPtr<CFGAS_GEFont> pFont; uint32_t dwHash = FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage); - CFGAS_GEFont* pFont = nullptr; - if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) - return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr; - FX_FONTDESCRIPTOR const* pFD = + auto it = m_FamilyFonts.find(dwHash); + if (it != m_FamilyFonts.end()) + return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr; + + const FX_FONTDESCRIPTOR* pFD = FindFont(pszFontFamily, dwFontStyles, true, wCodePage); if (!pFD) pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage); @@ -208,71 +201,66 @@ CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const FX_WCHAR* pszFontFamily, if (wCodePage == 0xFFFF) wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); + pFont = CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); if (!pFont) return nullptr; - m_Fonts.Add(pFont); - m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + m_Fonts.push_back(pFont); + m_FamilyFonts[dwHash] = pFont; dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); - m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + m_CPFonts[dwHash] = pFont; return LoadFont(pFont, dwFontStyles, wCodePage); } -CFGAS_GEFont* CFGAS_FontMgr::LoadFont(CFGAS_GEFont* pSrcFont, - uint32_t dwFontStyles, - uint16_t wCodePage) { - ASSERT(pSrcFont); +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( + const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont, + uint32_t dwFontStyles, + uint16_t wCodePage) { if (pSrcFont->GetFontStyles() == dwFontStyles) - return pSrcFont->Retain(); - void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles, + return pSrcFont; + + void* buffer[3] = {pSrcFont.Get(), (void*)(uintptr_t)dwFontStyles, (void*)(uintptr_t)wCodePage}; uint32_t dwHash = FX_HashCode_GetA( CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false); - CFGAS_GEFont* pFont = nullptr; - if (m_DeriveFonts.GetCount() > 0) { - m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont); - if (pFont) - return pFont->Retain(); - } - pFont = pSrcFont->Derive(dwFontStyles, wCodePage); + auto it = m_DeriveFonts.find(dwHash); + if (it != m_DeriveFonts.end() && it->second) + return it->second; + + CFX_RetainPtr<CFGAS_GEFont> pFont = pSrcFont->Derive(dwFontStyles, wCodePage); if (!pFont) return nullptr; - m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); - int32_t index = m_Fonts.Find(pFont); - if (index < 0) { - m_Fonts.Add(pFont); - pFont->Retain(); - } + m_DeriveFonts[dwHash] = pFont; + auto iter = std::find(m_Fonts.begin(), m_Fonts.end(), pFont); + if (iter == m_Fonts.end()) + m_Fonts.push_back(pFont); return pFont; } -void CFGAS_FontMgr::RemoveFont(CFX_MapPtrToPtr& fontMap, CFGAS_GEFont* pFont) { - FX_POSITION pos = fontMap.GetStartPosition(); - void* pKey; - void* pFind; - while (pos) { - pFind = nullptr; - fontMap.GetNextAssoc(pos, pKey, pFind); - if (pFind != (void*)pFont) - continue; - fontMap.RemoveKey(pKey); - break; +void CFGAS_FontMgr::RemoveFont( + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap, + const CFX_RetainPtr<CFGAS_GEFont>& pFont) { + auto iter = pFontMap->begin(); + while (iter != pFontMap->end()) { + auto old_iter = iter++; + if (old_iter->second == pFont) + pFontMap->erase(old_iter); } } -void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pFont) { - RemoveFont(m_CPFonts, pFont); - RemoveFont(m_FamilyFonts, pFont); - RemoveFont(m_UnicodeFonts, pFont); - RemoveFont(m_BufferFonts, pFont); - RemoveFont(m_StreamFonts, pFont); - RemoveFont(m_DeriveFonts, pFont); - int32_t iFind = m_Fonts.Find(pFont); - if (iFind > -1) - m_Fonts.RemoveAt(iFind, 1); +void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { + RemoveFont(&m_CPFonts, pFont); + RemoveFont(&m_FamilyFonts, pFont); + RemoveFont(&m_UnicodeFonts, pFont); + RemoveFont(&m_BufferFonts, pFont); + RemoveFont(&m_StreamFonts, pFont); + RemoveFont(&m_DeriveFonts, pFont); + auto it = std::find(m_Fonts.begin(), m_Fonts.end(), pFont); + if (it != m_Fonts.end()) + m_Fonts.erase(it); } FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, @@ -594,16 +582,7 @@ CFGAS_FontMgr::~CFGAS_FontMgr() { m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs); delete pDescs; } - pos = m_Hash2Fonts.GetStartPosition(); - while (pos) { - uint32_t dwHash; - CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts; - m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts); - for (int32_t i = 0; i < pFonts->GetSize(); i++) - delete pFonts->GetAt(i); - delete pFonts; - } - m_Hash2Fonts.RemoveAll(); + m_Hash2Fonts.clear(); } bool CFGAS_FontMgr::EnumFontsFromFontMapper() { @@ -644,31 +623,28 @@ bool CFGAS_FontMgr::EnumFontsFromFiles() { } bool CFGAS_FontMgr::EnumFonts() { - if (EnumFontsFromFontMapper()) - return true; - return EnumFontsFromFiles(); + return EnumFontsFromFontMapper() || EnumFontsFromFiles(); } -CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( + const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage) { + return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); +} + +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( + uint16_t wCodePage, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily) { CFX_ByteString bsHash; bsHash.Format("%d, %d", wCodePage, dwFontStyles); bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); - CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr; - if (m_Hash2Fonts.Lookup(dwHash, pFonts)) { - if (!pFonts) - return nullptr; - - if (pFonts->GetSize() != 0) - return pFonts->GetAt(0)->Retain(); - } + std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash]; + if (!pFontArray->empty()) + return (*pFontArray)[0]; - if (!pFonts) - pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>; - - m_Hash2Fonts.SetAt(dwHash, pFonts); CFX_FontDescriptorInfos* sortedFonts = nullptr; if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { sortedFonts = new CFX_FontDescriptorInfos; @@ -680,21 +656,23 @@ CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, return nullptr; CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont; - CFGAS_GEFont* pFont = + CFX_RetainPtr<CFGAS_GEFont> pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); - if (pFont) - pFont->SetLogicalFontStyle(dwFontStyles); + if (!pFont) + return nullptr; - pFonts->Add(pFont); + pFont->SetLogicalFontStyle(dwFontStyles); + pFontArray->push_back(pFont); return pFont; } -CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily) { - CFGAS_GEFont* pFont = nullptr; - if (m_FailedUnicodes2Nullptr.Lookup(wUnicode, pFont)) +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode( + FX_WCHAR wUnicode, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily) { + if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode)) return nullptr; + const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode); uint16_t wCodePage = x ? x->wCodePage : 0xFFFF; uint16_t wBitField = x ? x->wBitField : 0x03E7; @@ -705,19 +683,11 @@ CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, bsHash.Format("%d, %d", wCodePage, dwFontStyles); bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); - CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr; - if (m_Hash2Fonts.Lookup(dwHash, pFonts)) { - if (!pFonts) - return nullptr; - - for (int32_t i = 0; i < pFonts->GetSize(); ++i) { - if (VerifyUnicode(pFonts->GetAt(i), wUnicode)) - return pFonts->GetAt(i)->Retain(); - } + std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash]; + for (size_t i = 0; i < pFonts->size(); ++i) { + if (VerifyUnicode((*pFonts)[i], wUnicode)) + return (*pFonts)[i]; } - if (!pFonts) - pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>; - m_Hash2Fonts.SetAt(dwHash, pFonts); CFX_FontDescriptorInfos* sortedFonts = nullptr; if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { sortedFonts = new CFX_FontDescriptorInfos; @@ -729,15 +699,16 @@ CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont; if (!VerifyUnicode(pDesc, wUnicode)) continue; - pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); + CFX_RetainPtr<CFGAS_GEFont> pFont = + LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); if (!pFont) continue; pFont->SetLogicalFontStyle(dwFontStyles); - pFonts->Add(pFont); + pFonts->push_back(pFont); return pFont; } if (!pszFontFamily) - m_FailedUnicodes2Nullptr.SetAt(wUnicode, nullptr); + m_FailedUnicodesSet.insert(wUnicode); return nullptr; } @@ -761,7 +732,8 @@ bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc, return !retCharmap && retIndex; } -bool CFGAS_FontMgr::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) { +bool CFGAS_FontMgr::VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont, + FX_WCHAR wcUnicode) { if (!pFont) return false; @@ -777,9 +749,10 @@ bool CFGAS_FontMgr::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) { return true; } -CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const CFX_WideString& wsFaceName, - int32_t iFaceIndex, - int32_t* pFaceCount) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( + const CFX_WideString& wsFaceName, + int32_t iFaceIndex, + int32_t* pFaceCount) { CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr(); CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper(); if (!pFontMapper) @@ -798,14 +771,14 @@ CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const CFX_WideString& wsFaceName, if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) return nullptr; - CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this); + CFX_RetainPtr<CFGAS_GEFont> pFont = + CFGAS_GEFont::LoadFont(std::move(pInternalFont), this); if (!pFont) return nullptr; m_IFXFont2FileRead[pFont] = pFontStream; if (pFaceCount) *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces; - return pFont; } @@ -1010,26 +983,24 @@ int32_t CFGAS_FontMgr::CalcPenalty(CFX_FontDescriptor* pInstalled, return nPenalty; } -void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pEFont) { +void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pEFont) { if (!pEFont) return; m_IFXFont2FileRead.erase(pEFont); - FX_POSITION pos; - pos = m_Hash2Fonts.GetStartPosition(); - while (pos) { - uint32_t dwHash; - CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts; - m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts); - if (pFonts) { - for (int32_t i = 0; i < pFonts->GetSize(); i++) { - if (pFonts->GetAt(i) == pEFont) - pFonts->SetAt(i, nullptr); - } - } else { - m_Hash2Fonts.RemoveKey(dwHash); + auto iter = m_Hash2Fonts.begin(); + while (iter != m_Hash2Fonts.end()) { + auto old_iter = iter++; + bool all_empty = true; + for (size_t i = 0; i < old_iter->second.size(); i++) { + if (old_iter->second[i] == pEFont) + old_iter->second[i].Reset(); + else if (old_iter->second[i]) + all_empty = false; } + if (all_empty) + m_Hash2Fonts.erase(old_iter); } } diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h index 0da84fd6e9..c4030e76ee 100644 --- a/xfa/fgas/font/cfgas_fontmgr.h +++ b/xfa/fgas/font/cfgas_fontmgr.h @@ -9,15 +9,16 @@ #include <map> #include <memory> +#include <set> #include <vector> +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_ext.h" #include "core/fxge/cfx_fontmapper.h" #include "core/fxge/fx_freetype.h" #include "core/fxge/ifx_systemfontinfo.h" #include "third_party/freetype/include/freetype/fttypes.h" #include "xfa/fgas/crt/fgas_stream.h" -#include "xfa/fgas/font/cfgas_fontmgr.h" #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ #include "xfa/fgas/crt/fgas_memory.h" @@ -35,9 +36,9 @@ #define FX_FONTSTYLE_ExactMatch 0x80000000 class CFX_FontSourceEnum_File; -class CFGAS_GEFont; class CXFA_PDFFontMgr; class CFGAS_FontMgr; +class CFGAS_GEFont; #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ #define FX_FONTMATCHPARA_MatchStyle 0x01 @@ -90,28 +91,30 @@ FX_LPEnumAllFonts FX_GetDefFontEnumerator(); class CFGAS_FontMgr { public: + static std::unique_ptr<CFGAS_FontMgr> Create(FX_LPEnumAllFonts pEnumerator); + explicit CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator); ~CFGAS_FontMgr(); - static std::unique_ptr<CFGAS_FontMgr> Create(FX_LPEnumAllFonts pEnumerator); - - CFGAS_GEFont* GetFontByCodePage(uint16_t wCodePage, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily); - CFGAS_GEFont* GetFontByUnicode(FX_WCHAR wUnicode, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily); - CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage); - void RemoveFont(CFGAS_GEFont* pFont); + CFX_RetainPtr<CFGAS_GEFont> GetFontByCodePage(uint16_t wCodePage, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily); + CFX_RetainPtr<CFGAS_GEFont> GetFontByUnicode(FX_WCHAR wUnicode, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily); + CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage); + void RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); private: - CFGAS_GEFont* LoadFont(CFGAS_GEFont* pSrcFont, - uint32_t dwFontStyles, - uint16_t wCodePage); - void RemoveFont(CFX_MapPtrToPtr& fontMap, CFGAS_GEFont* pFont); - FX_FONTDESCRIPTOR const* FindFont(const FX_WCHAR* pszFontFamily, + CFX_RetainPtr<CFGAS_GEFont> LoadFont( + const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont, + uint32_t dwFontStyles, + uint16_t wCodePage); + void RemoveFont(std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap, + const CFX_RetainPtr<CFGAS_GEFont>& pFont); + const FX_FONTDESCRIPTOR* FindFont(const FX_WCHAR* pszFontFamily, uint32_t dwFontStyles, uint32_t dwMatchFlags, uint16_t wCodePage, @@ -120,13 +123,13 @@ class CFGAS_FontMgr { FX_LPEnumAllFonts m_pEnumerator; CFX_FontDescriptors m_FontFaces; - CFX_ArrayTemplate<CFGAS_GEFont*> m_Fonts; - CFX_MapPtrToPtr m_CPFonts; - CFX_MapPtrToPtr m_FamilyFonts; - CFX_MapPtrToPtr m_UnicodeFonts; - CFX_MapPtrToPtr m_BufferFonts; - CFX_MapPtrToPtr m_StreamFonts; - CFX_MapPtrToPtr m_DeriveFonts; + std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_Fonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_CPFonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_FamilyFonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_UnicodeFonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_BufferFonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_StreamFonts; + std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_DeriveFonts; }; #else // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ @@ -191,24 +194,22 @@ class CFX_FontSourceEnum_File { class CFGAS_FontMgr { public: - explicit CFGAS_FontMgr(CFX_FontSourceEnum_File* pFontEnum); - ~CFGAS_FontMgr(); static std::unique_ptr<CFGAS_FontMgr> Create( CFX_FontSourceEnum_File* pFontEnum); - CFGAS_GEFont* GetFontByCodePage(uint16_t wCodePage, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily); - CFGAS_GEFont* GetFontByUnicode(FX_WCHAR wUnicode, - uint32_t dwFontStyles, - const FX_WCHAR* pszFontFamily); - void RemoveFont(CFGAS_GEFont* pFont); - - inline CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage) { - return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); - } + explicit CFGAS_FontMgr(CFX_FontSourceEnum_File* pFontEnum); + ~CFGAS_FontMgr(); + + CFX_RetainPtr<CFGAS_GEFont> GetFontByCodePage(uint16_t wCodePage, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily); + CFX_RetainPtr<CFGAS_GEFont> GetFontByUnicode(FX_WCHAR wUnicode, + uint32_t dwFontStyles, + const FX_WCHAR* pszFontFamily); + CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage); + void RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); private: bool EnumFonts(); @@ -222,7 +223,8 @@ class CFGAS_FontMgr { void GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB); uint32_t GetFlags(FXFT_Face pFace); bool VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode); - bool VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode); + bool VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont, + FX_WCHAR wcUnicode); int32_t IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2); int32_t MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, uint16_t wCodePage, @@ -234,9 +236,9 @@ class CFGAS_FontMgr { uint32_t dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode = 0xFFFE); - CFGAS_GEFont* LoadFont(const CFX_WideString& wsFaceName, - int32_t iFaceIndex, - int32_t* pFaceCount); + CFX_RetainPtr<CFGAS_GEFont> LoadFont(const CFX_WideString& wsFaceName, + int32_t iFaceIndex, + int32_t* pFaceCount); FXFT_Face LoadFace(const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream, int32_t iFaceIndex); CFX_RetainPtr<IFX_SeekableReadStream> CreateFontStream( @@ -248,12 +250,12 @@ class CFGAS_FontMgr { CFX_FontDescriptors m_InstalledFonts; CFX_MapPtrTemplate<uint32_t, CFX_FontDescriptorInfos*> m_Hash2CandidateList; - CFX_MapPtrTemplate<uint32_t, CFX_ArrayTemplate<CFGAS_GEFont*>*> m_Hash2Fonts; - std::map<CFGAS_GEFont*, CFX_RetainPtr<IFX_SeekableReadStream> > + std::map<uint32_t, std::vector<CFX_RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts; + std::map<CFX_RetainPtr<CFGAS_GEFont>, CFX_RetainPtr<IFX_SeekableReadStream>> m_IFXFont2FileRead; - CFX_MapPtrTemplate<FX_WCHAR, CFGAS_GEFont*> m_FailedUnicodes2Nullptr; + std::set<FX_WCHAR> m_FailedUnicodesSet; CFX_FontSourceEnum_File* const m_pFontSource; }; -#endif +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ #endif // XFA_FGAS_FONT_CFGAS_FONTMGR_H_ diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp index bc971f6294..fc202f6bc3 100644 --- a/xfa/fgas/font/cfgas_gefont.cpp +++ b/xfa/fgas/font/cfgas_gefont.cpp @@ -18,69 +18,63 @@ #include "xfa/fxfa/xfa_fontmgr.h" // static -CFGAS_GEFont* CFGAS_GEFont::LoadFont(const FX_WCHAR* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage, - CFGAS_FontMgr* pFontMgr) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( + const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage, + CFGAS_FontMgr* pFontMgr) { #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ - if (pFontMgr) - return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); - return nullptr; + if (!pFontMgr) + return nullptr; + + return CFX_RetainPtr<CFGAS_GEFont>( + pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily)); #else - CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); - if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) { - pFont->Release(); + auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); + if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) return nullptr; - } return pFont; #endif } // static -CFGAS_GEFont* CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont, - CFGAS_FontMgr* pFontMgr) { - CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); - if (!pFont->LoadFontInternal(pExternalFont)) { - pFont->Release(); +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont, + CFGAS_FontMgr* pFontMgr) { + auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); + if (!pFont->LoadFontInternal(pExternalFont)) return nullptr; - } return pFont; } // static -CFGAS_GEFont* CFGAS_GEFont::LoadFont(std::unique_ptr<CFX_Font> pInternalFont, - CFGAS_FontMgr* pFontMgr) { - CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); - if (!pFont->LoadFontInternal(std::move(pInternalFont))) { - pFont->Release(); +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( + std::unique_ptr<CFX_Font> pInternalFont, + CFGAS_FontMgr* pFontMgr) { + auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); + if (!pFont->LoadFontInternal(std::move(pInternalFont))) return nullptr; - } return pFont; } #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ // static -CFGAS_GEFont* CFGAS_GEFont::LoadFont(const uint8_t* pBuffer, - int32_t iLength, - CFGAS_FontMgr* pFontMgr) { - CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); - if (!pFont->LoadFontInternal(pBuffer, iLength)) { - pFont->Release(); +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(const uint8_t* pBuffer, + int32_t iLength, + CFGAS_FontMgr* pFontMgr) { + auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); + if (pFont->LoadFontInternal(pBuffer, iLength)) return nullptr; - } return pFont; } // static -CFGAS_GEFont* CFGAS_GEFont::LoadFont( +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( const CFX_RetainPtr<IFGAS_Stream>& pFontStream, CFGAS_FontMgr* pFontMgr, bool bSaveStream) { - CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr); - if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) { - pFont->Release(); + auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); + if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) return nullptr; - } return pFont; } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ @@ -92,14 +86,13 @@ CFGAS_GEFont::CFGAS_GEFont(CFGAS_FontMgr* pFontMgr) m_dwLogFontStyle(0), #endif m_pFont(nullptr), - m_pSrcFont(nullptr), m_pFontMgr(pFontMgr), - m_iRefCount(1), m_bExternalFont(false), m_pProvider(nullptr) { } -CFGAS_GEFont::CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles) +CFGAS_GEFont::CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src, + uint32_t dwFontStyles) : #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ m_bUseLogFontStyle(false), @@ -108,11 +101,9 @@ CFGAS_GEFont::CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles) m_pFont(nullptr), m_pSrcFont(src), m_pFontMgr(src->m_pFontMgr), - m_iRefCount(1), m_bExternalFont(false), m_pProvider(nullptr) { ASSERT(m_pSrcFont->m_pFont); - m_pSrcFont->Retain(); m_pFont = new CFX_Font; m_pFont->LoadClone(m_pSrcFont->m_pFont); CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); @@ -128,31 +119,11 @@ CFGAS_GEFont::CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles) } CFGAS_GEFont::~CFGAS_GEFont() { - for (int32_t i = 0; i < m_SubstFonts.GetSize(); i++) - m_SubstFonts[i]->Release(); - - m_SubstFonts.RemoveAll(); - m_FontMapper.clear(); + if (m_pFontMgr) + m_pFontMgr->RemoveFont(CFX_RetainPtr<CFGAS_GEFont>(this)); if (!m_bExternalFont) delete m_pFont; - - // If it is a shallow copy of another source font, - // decrease the refcount of the source font. - if (m_pSrcFont) - m_pSrcFont->Release(); -} - -void CFGAS_GEFont::Release() { - if (--m_iRefCount < 1) { - if (m_pFontMgr) - m_pFontMgr->RemoveFont(this); - delete this; - } -} -CFGAS_GEFont* CFGAS_GEFont::Retain() { - ++m_iRefCount; - return this; } #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ @@ -260,10 +231,12 @@ bool CFGAS_GEFont::InitFont() { return true; } -CFGAS_GEFont* CFGAS_GEFont::Derive(uint32_t dwFontStyles, uint16_t wCodePage) { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::Derive(uint32_t dwFontStyles, + uint16_t wCodePage) { + CFX_RetainPtr<CFGAS_GEFont> pFont(this); if (GetFontStyles() == dwFontStyles) - return Retain(); - return new CFGAS_GEFont(this, dwFontStyles); + return pFont; + return pdfium::MakeRetain<CFGAS_GEFont>(pFont, dwFontStyles); } CFX_WideString CFGAS_GEFont::GetFamilyName() const { @@ -317,11 +290,12 @@ bool CFGAS_GEFont::GetCharWidthInternal(FX_WCHAR wUnicode, return true; if (!m_pProvider || - !m_pProvider->GetCharWidth(this, wUnicode, bCharCode, &iWidth)) { - CFGAS_GEFont* pFont = nullptr; + !m_pProvider->GetCharWidth(CFX_RetainPtr<CFGAS_GEFont>(this), wUnicode, + bCharCode, &iWidth)) { + CFX_RetainPtr<CFGAS_GEFont> pFont; int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); if (iGlyph != 0xFFFF && pFont) { - if (pFont == this) { + if (pFont.Get() == this) { iWidth = m_pFont->GetGlyphWidth(iGlyph); if (iWidth < 0) iWidth = -1; @@ -351,10 +325,10 @@ bool CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode, ASSERT(m_pBBoxMap); void* pRect = nullptr; if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) { - CFGAS_GEFont* pFont = nullptr; + CFX_RetainPtr<CFGAS_GEFont> pFont; int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); if (iGlyph != 0xFFFF && pFont) { - if (pFont == this) { + if (pFont.Get() == this) { FX_RECT rtBBox; if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) { CFX_Rect rt; @@ -392,13 +366,12 @@ int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode) { int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, bool bRecursive, - CFGAS_GEFont** ppFont, + CFX_RetainPtr<CFGAS_GEFont>* ppFont, bool bCharCode) { - ASSERT(m_pFontEncoding); int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode); if (iGlyphIndex > 0) { if (ppFont) - *ppFont = this; + ppFont->Reset(this); return iGlyphIndex; } const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode); @@ -410,44 +383,41 @@ int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, return 0xFFFF; auto it = m_FontMapper.find(wUnicode); - CFGAS_GEFont* pFont = it != m_FontMapper.end() ? it->second : nullptr; - if (pFont && pFont != this) { - iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); + if (it != m_FontMapper.end() && it->second && it->second.Get() != this) { + iGlyphIndex = + it->second->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); if (iGlyphIndex != 0xFFFF) { - int32_t i = m_SubstFonts.Find(pFont); - if (i > -1) { - iGlyphIndex |= ((i + 1) << 24); - if (ppFont) - *ppFont = pFont; - return iGlyphIndex; + for (size_t i = 0; i < m_SubstFonts.size(); ++i) { + if (m_SubstFonts[i] == it->second) { + if (ppFont) + *ppFont = it->second; + return (iGlyphIndex | ((i + 1) << 24)); + } } } } if (!m_pFontMgr || !bRecursive) return 0xFFFF; + CFX_WideString wsFamily = GetFamilyName(); - pFont = + CFX_RetainPtr<CFGAS_GEFont> pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), wsFamily.c_str()); #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ if (!pFont) pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr); #endif - if (!pFont) - return 0xFFFF; - if (pFont == this) { - pFont->Release(); + if (!pFont || pFont.Get() == this) // Avoids direct cycles below. return 0xFFFF; - } + m_FontMapper[wUnicode] = pFont; - int32_t i = m_SubstFonts.GetSize(); - m_SubstFonts.Add(pFont); + m_SubstFonts.push_back(pFont); iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); if (iGlyphIndex == 0xFFFF) return 0xFFFF; - iGlyphIndex |= ((i + 1) << 24); + if (ppFont) *ppFont = pFont; - return iGlyphIndex; + return (iGlyphIndex | (m_SubstFonts.size() << 24)); } int32_t CFGAS_GEFont::GetAscent() const { @@ -458,8 +428,10 @@ int32_t CFGAS_GEFont::GetDescent() const { return m_pFont->GetDescent(); } -CFGAS_GEFont* CFGAS_GEFont::GetSubstFont(int32_t iGlyphIndex) const { +CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::GetSubstFont( + int32_t iGlyphIndex) const { iGlyphIndex = static_cast<uint32_t>(iGlyphIndex) >> 24; - return iGlyphIndex == 0 ? const_cast<CFGAS_GEFont*>(this) - : m_SubstFonts[iGlyphIndex - 1]; + if (iGlyphIndex == 0) + return CFX_RetainPtr<CFGAS_GEFont>(const_cast<CFGAS_GEFont*>(this)); + return m_SubstFonts[iGlyphIndex - 1]; } diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h index 86e5e4c955..962b93fbb5 100644 --- a/xfa/fgas/font/cfgas_gefont.h +++ b/xfa/fgas/font/cfgas_gefont.h @@ -9,40 +9,47 @@ #include <map> #include <memory> +#include <vector> +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_memory.h" #include "xfa/fgas/crt/fgas_utils.h" #include "xfa/fgas/font/cfgas_fontmgr.h" #define FXFONT_SUBST_ITALIC 0x02 +class CFGAS_FontMgr; class CFX_UnicodeEncoding; class CXFA_PDFFontMgr; -class CFGAS_GEFont { +class CFGAS_GEFont : public CFX_Retainable { public: - static CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage, - CFGAS_FontMgr* pFontMgr); - static CFGAS_GEFont* LoadFont(CFX_Font* pExternalFont, - CFGAS_FontMgr* pFontMgr); - static CFGAS_GEFont* LoadFont(std::unique_ptr<CFX_Font> pInternalFont, - CFGAS_FontMgr* pFontMgr); + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); + + static CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage, + CFGAS_FontMgr* pFontMgr); + static CFX_RetainPtr<CFGAS_GEFont> LoadFont(CFX_Font* pExternalFont, + CFGAS_FontMgr* pFontMgr); + static CFX_RetainPtr<CFGAS_GEFont> LoadFont( + std::unique_ptr<CFX_Font> pInternalFont, + CFGAS_FontMgr* pFontMgr); #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - static CFGAS_GEFont* LoadFont(const uint8_t* pBuffer, - int32_t iLength, - CFGAS_FontMgr* pFontMgr); - static CFGAS_GEFont* LoadFont(const CFX_RetainPtr<IFGAS_Stream>& pFontStream, - CFGAS_FontMgr* pFontMgr, - bool bSaveStream); + static CFX_RetainPtr<CFGAS_GEFont> LoadFont(const uint8_t* pBuffer, + int32_t iLength, + CFGAS_FontMgr* pFontMgr); + static CFX_RetainPtr<CFGAS_GEFont> LoadFont( + const CFX_RetainPtr<IFGAS_Stream>& pFontStream, + CFGAS_FontMgr* pFontMgr, + bool bSaveStream); #endif - ~CFGAS_GEFont(); + ~CFGAS_GEFont() override; - void Release(); - CFGAS_GEFont* Retain(); - CFGAS_GEFont* Derive(uint32_t dwFontStyles, uint16_t wCodePage = 0); + CFX_RetainPtr<CFGAS_GEFont> Derive(uint32_t dwFontStyles, + uint16_t wCodePage = 0); uint32_t GetFontStyles() const; bool GetCharWidth(FX_WCHAR wUnicode, int32_t& iWidth, bool bCharCode); int32_t GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode = false); @@ -50,7 +57,7 @@ class CFGAS_GEFont { int32_t GetDescent() const; bool GetCharBBox(FX_WCHAR wUnicode, CFX_Rect& bbox, bool bCharCode = false); bool GetBBox(CFX_Rect& bbox); - CFGAS_GEFont* GetSubstFont(int32_t iGlyphIndex) const; + CFX_RetainPtr<CFGAS_GEFont> GetSubstFont(int32_t iGlyphIndex) const; CFX_Font* GetDevFont() const { return m_pFont; } void SetFontProvider(CXFA_PDFFontMgr* pProvider) { m_pProvider = pProvider; } #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ @@ -62,7 +69,7 @@ class CFGAS_GEFont { private: explicit CFGAS_GEFont(CFGAS_FontMgr* pFontMgr); - CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles); + CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src, uint32_t dwFontStyles); #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ bool LoadFontInternal(const FX_WCHAR* pszFontFamily, @@ -85,7 +92,7 @@ class CFGAS_GEFont { bool bCharCode); int32_t GetGlyphIndex(FX_WCHAR wUnicode, bool bRecursive, - CFGAS_GEFont** ppFont, + CFX_RetainPtr<CFGAS_GEFont>* ppFont, bool bCharCode = false); CFX_WideString GetFamilyName() const; @@ -94,9 +101,8 @@ class CFGAS_GEFont { uint32_t m_dwLogFontStyle; #endif CFX_Font* m_pFont; - CFGAS_GEFont* const m_pSrcFont; + CFX_RetainPtr<CFGAS_GEFont> m_pSrcFont; // Only set by ctor, so no cycles. CFGAS_FontMgr* const m_pFontMgr; - int32_t m_iRefCount; bool m_bExternalFont; CFX_RetainPtr<IFGAS_Stream> m_pStream; CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead; @@ -105,8 +111,8 @@ class CFGAS_GEFont { std::unique_ptr<CFX_MassArrayTemplate<CFX_Rect>> m_pRectArray; std::unique_ptr<CFX_MapPtrToPtr> m_pBBoxMap; CXFA_PDFFontMgr* m_pProvider; // not owned. - CFX_ArrayTemplate<CFGAS_GEFont*> m_SubstFonts; - std::map<FX_WCHAR, CFGAS_GEFont*> m_FontMapper; + std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_SubstFonts; + std::map<FX_WCHAR, CFX_RetainPtr<CFGAS_GEFont>> m_FontMapper; }; #endif // XFA_FGAS_FONT_CFGAS_GEFONT_H_ diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp index 8e4fbf7969..cacb77fcf8 100644 --- a/xfa/fgas/layout/fgas_rtfbreak.cpp +++ b/xfa/fgas/layout/fgas_rtfbreak.cpp @@ -93,13 +93,10 @@ void CFX_RTFBreak::SetLayoutStyles(uint32_t dwLayoutStyles) { m_iRotation %= 4; } -void CFX_RTFBreak::SetFont(CFGAS_GEFont* pFont) { - if (!pFont) { +void CFX_RTFBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { + if (!pFont || pFont == m_pFont) return; - } - if (m_pFont == pFont) { - return; - } + SetBreakStatus(); m_pFont = pFont; m_iDefChar = 0; @@ -111,6 +108,7 @@ void CFX_RTFBreak::SetFont(CFGAS_GEFont* pFont) { } } } + void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize) { int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); if (m_iFontSize == iFontSize) { @@ -1184,7 +1182,7 @@ int32_t CFX_RTFBreak::GetDisplayPos(const FX_RTFTEXTOBJ* pText, const FX_WCHAR* pStr = pText->pStr; int32_t* pWidths = pText->pWidths; int32_t iLength = pText->iLength - 1; - CFGAS_GEFont* pFont = pText->pFont; + CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont; uint32_t dwStyles = pText->dwLayoutStyles; CFX_RectF rtText(*pText->pRect); bool bRTLPiece = FX_IsOdd(pText->iBidiLevel); @@ -1419,9 +1417,9 @@ int32_t CFX_RTFBreak::GetDisplayPos(const FX_RTFTEXTOBJ* pText, int32_t CFX_RTFBreak::GetCharRects(const FX_RTFTEXTOBJ* pText, CFX_RectFArray& rtArray, bool bCharBBox) const { - if (!pText || pText->iLength < 1) { + if (!pText || pText->iLength < 1) return 0; - } + ASSERT(pText->pStr && pText->pWidths && pText->pFont && pText->pRect); const FX_WCHAR* pStr = pText->pStr; int32_t* pWidths = pText->pWidths; @@ -1431,15 +1429,15 @@ int32_t CFX_RTFBreak::GetCharRects(const FX_RTFTEXTOBJ* pText, FX_FLOAT fFontSize = pText->fFontSize; int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); FX_FLOAT fScale = fFontSize / 1000.0f; - CFGAS_GEFont* pFont = pText->pFont; - if (!pFont) { + CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont; + if (!pFont) bCharBBox = false; - } + CFX_Rect bbox; bbox.Set(0, 0, 0, 0); - if (bCharBBox) { + if (bCharBBox) bCharBBox = pFont->GetBBox(bbox); - } + FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale); FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale); rtArray.RemoveAll(); @@ -1566,3 +1564,5 @@ FX_RTFTEXTOBJ::FX_RTFTEXTOBJ() wLineBreakChar(L'\n'), iHorizontalScale(100), iVerticalScale(100) {} + +FX_RTFTEXTOBJ::~FX_RTFTEXTOBJ() {} diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h index de2497ed1d..c281192553 100644 --- a/xfa/fgas/layout/fgas_rtfbreak.h +++ b/xfa/fgas/layout/fgas_rtfbreak.h @@ -67,11 +67,12 @@ class CFGAS_GEFont; struct FX_RTFTEXTOBJ { FX_RTFTEXTOBJ(); + ~FX_RTFTEXTOBJ(); const FX_WCHAR* pStr; int32_t* pWidths; int32_t iLength; - CFGAS_GEFont* pFont; + CFX_RetainPtr<CFGAS_GEFont> pFont; FX_FLOAT fFontSize; uint32_t dwLayoutStyles; int32_t iCharRotation; @@ -222,7 +223,7 @@ class CFX_RTFBreak { void SetLineStartPos(FX_FLOAT fLinePos); uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; } void SetLayoutStyles(uint32_t dwLayoutStyles); - void SetFont(CFGAS_GEFont* pFont); + void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); void SetFontSize(FX_FLOAT fFontSize); void SetTabWidth(FX_FLOAT fTabWidth); void AddPositionedTab(FX_FLOAT fTabPos); @@ -294,7 +295,7 @@ class CFX_RTFBreak { bool m_bVertical; bool m_bSingleLine; bool m_bCharCode; - CFGAS_GEFont* m_pFont; + CFX_RetainPtr<CFGAS_GEFont> m_pFont; int32_t m_iFontHeight; int32_t m_iFontSize; int32_t m_iTabWidth; diff --git a/xfa/fgas/layout/fgas_textbreak.cpp b/xfa/fgas/layout/fgas_textbreak.cpp index a3f8e9841d..a9d35a3cd7 100644 --- a/xfa/fgas/layout/fgas_textbreak.cpp +++ b/xfa/fgas/layout/fgas_textbreak.cpp @@ -112,13 +112,10 @@ void CFX_TxtBreak::SetLayoutStyles(uint32_t dwLayoutStyles) { m_iRotation %= 4; } -void CFX_TxtBreak::SetFont(CFGAS_GEFont* pFont) { - if (!pFont) { +void CFX_TxtBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { + if (!pFont || pFont == m_pFont) return; - } - if (m_pFont == pFont) { - return; - } + SetBreakStatus(); m_pFont = pFont; m_iDefChar = 0; @@ -1214,7 +1211,7 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, const FX_WCHAR* pStr = pTxtRun->wsStr.c_str(); int32_t* pWidths = pTxtRun->pWidths; int32_t iLength = pTxtRun->iLength - 1; - CFGAS_GEFont* pFont = pTxtRun->pFont; + CFX_RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont; uint32_t dwStyles = pTxtRun->dwStyles; CFX_RectF rtText(*pTxtRun->pRect); bool bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0; @@ -1593,9 +1590,9 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, CFX_RectFArray& rtArray, bool bCharBBox) const { - if (!pTxtRun || pTxtRun->iLength < 1) { + if (!pTxtRun || pTxtRun->iLength < 1) return 0; - } + IFX_TxtAccess* pAccess = pTxtRun->pAccess; const FDE_TEXTEDITPIECE* pIdentity = pTxtRun->pIdentity; const FX_WCHAR* pStr = pTxtRun->wsStr.c_str(); @@ -1606,15 +1603,15 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, FX_FLOAT fFontSize = pTxtRun->fFontSize; int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); FX_FLOAT fScale = fFontSize / 1000.0f; - CFGAS_GEFont* pFont = pTxtRun->pFont; - if (!pFont) { + CFX_RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont; + if (!pFont) bCharBBox = false; - } + CFX_Rect bbox; bbox.Set(0, 0, 0, 0); - if (bCharBBox) { + if (bCharBBox) bCharBBox = pFont->GetBBox(bbox); - } + FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale); FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale); rtArray.RemoveAll(); diff --git a/xfa/fgas/layout/fgas_textbreak.h b/xfa/fgas/layout/fgas_textbreak.h index 7bae6cd46e..36602749c7 100644 --- a/xfa/fgas/layout/fgas_textbreak.h +++ b/xfa/fgas/layout/fgas_textbreak.h @@ -93,7 +93,7 @@ struct FX_TXTRUN { CFX_WideString wsStr; int32_t* pWidths; int32_t iLength; - CFGAS_GEFont* pFont; + CFX_RetainPtr<CFGAS_GEFont> pFont; FX_FLOAT fFontSize; uint32_t dwStyles; int32_t iHorizontalScale; @@ -206,7 +206,7 @@ class CFX_TxtBreak { void SetLinePos(FX_FLOAT fLinePos); uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; } void SetLayoutStyles(uint32_t dwLayoutStyles); - void SetFont(CFGAS_GEFont* pFont); + void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); void SetFontSize(FX_FLOAT fFontSize); void SetTabWidth(FX_FLOAT fTabWidth, bool bEquidistant); void SetDefaultChar(FX_WCHAR wch); @@ -280,7 +280,7 @@ class CFX_TxtBreak { bool m_bCombText; int32_t m_iArabicContext; int32_t m_iCurArabicContext; - CFGAS_GEFont* m_pFont; + CFX_RetainPtr<CFGAS_GEFont> m_pFont; int32_t m_iFontSize; bool m_bEquidistant; int32_t m_iTabWidth; diff --git a/xfa/fgas/layout/fgas_unicode.h b/xfa/fgas/layout/fgas_unicode.h index f7a0d201d9..b404d6728a 100644 --- a/xfa/fgas/layout/fgas_unicode.h +++ b/xfa/fgas/layout/fgas_unicode.h @@ -18,11 +18,12 @@ typedef CFX_MassArrayTemplate<FX_TPO> CFX_TPOArray; void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd); -typedef bool (*FX_AdjustCharDisplayPos)(FX_WCHAR wch, - bool bMBCSCode, - CFGAS_GEFont* pFont, - FX_FLOAT fFontSize, - bool bVertical, - CFX_PointF& ptOffset); +typedef bool (*FX_AdjustCharDisplayPos)( + FX_WCHAR wch, + bool bMBCSCode, + const CFX_RetainPtr<CFGAS_GEFont>& pFont, + FX_FLOAT fFontSize, + bool bVertical, + CFX_PointF& ptOffset); #endif // XFA_FGAS_LAYOUT_FGAS_UNICODE_H_ |