From 40d522134a11867adb95f77c0b7891932e0739a2 Mon Sep 17 00:00:00 2001 From: Nicolas Pena Date: Thu, 16 Nov 2017 21:41:47 +0000 Subject: Refactor CFGAS_FontMgr's Windows implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL unifies a bit the public methods of CFGAS_FontMgr. It does so by replacing the multiple maps on the Windows implementation to a single map from hash to font. Also, cloning CFX_Fonts is avoided with the use of SetLogicalFontStyle. These Windows changes are just mimicking other OS's. As a side-effect, some members of CFX_Fonts are now owned so the raw pointers are replaced with unique_ptrs. Change-Id: I576d438572ccbe6c48f8f5cc434d66fc6adba372 Reviewed-on: https://pdfium-review.googlesource.com/18131 Reviewed-by: dsinclair Commit-Queue: Nicolás Peña Moreno --- core/fxge/cfx_font.cpp | 47 +--- core/fxge/cfx_font.h | 12 +- xfa/fgas/font/cfgas_fontmgr.cpp | 500 ++++++++++++++++------------------------ xfa/fgas/font/cfgas_fontmgr.h | 18 +- xfa/fgas/font/cfgas_gefont.cpp | 42 ---- xfa/fgas/font/cfgas_gefont.h | 7 - 6 files changed, 206 insertions(+), 420 deletions(-) diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp index 3f4f1356f8..bca711f0bb 100644 --- a/core/fxge/cfx_font.cpp +++ b/core/fxge/cfx_font.cpp @@ -211,10 +211,6 @@ const uint8_t CFX_Font::s_WeightPow_SHIFTJIS[] = { CFX_Font::CFX_Font() : -#ifdef PDF_ENABLE_XFA - m_bShallowCopy(false), - m_pOwnedStream(nullptr), -#endif // PDF_ENABLE_XFA m_Face(nullptr), m_FaceCache(nullptr), m_pFontData(nullptr), @@ -228,48 +224,13 @@ CFX_Font::CFX_Font() } #ifdef PDF_ENABLE_XFA -bool CFX_Font::LoadClone(const CFX_Font* pFont) { - if (!pFont) - return false; - - m_bShallowCopy = true; - if (pFont->m_pSubstFont) { - m_pSubstFont = pdfium::MakeUnique(); - m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset; - m_pSubstFont->m_bFlagMM = pFont->m_pSubstFont->m_bFlagMM; -#ifdef PDF_ENABLE_XFA - m_pSubstFont->m_bFlagItalic = pFont->m_pSubstFont->m_bFlagItalic; -#endif // PDF_ENABLE_XFA - m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight; - m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family; - m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle; - } - m_Face = pFont->m_Face; - m_bEmbedded = pFont->m_bEmbedded; - m_bVertical = pFont->m_bVertical; - m_dwSize = pFont->m_dwSize; - m_pFontData = pFont->m_pFontData; - m_pGsubData = pFont->m_pGsubData; -#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ - m_pPlatformFont = pFont->m_pPlatformFont; -#endif - m_pOwnedStream = pFont->m_pOwnedStream; - m_FaceCache = pFont->GetFaceCache(); - return true; -} - void CFX_Font::SetFace(FXFT_Face face) { ClearFaceCache(); m_Face = face; } - #endif // PDF_ENABLE_XFA CFX_Font::~CFX_Font() { -#ifdef PDF_ENABLE_XFA - if (m_bShallowCopy) - return; -#endif // PDF_ENABLE_XFA if (m_Face) { #ifndef PDF_ENABLE_XFA if (FXFT_Get_Face_External_Stream(m_Face)) { @@ -278,11 +239,7 @@ CFX_Font::~CFX_Font() { #endif // PDF_ENABLE_XFA DeleteFace(); } -#ifdef PDF_ENABLE_XFA - delete m_pOwnedStream; -#endif // PDF_ENABLE_XFA - FX_Free(m_pGsubData); -#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ && !defined _SKIA_SUPPORT_ +#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ ReleasePlatformResource(); #endif } @@ -328,7 +285,7 @@ bool CFX_Font::LoadFile(const RetainPtr& pFile, if (!LoadFileImp(library, &m_Face, pFile, nFaceIndex, &stream)) return false; - m_pOwnedStream = stream.release(); + m_pOwnedStream = std::move(stream); FXFT_Set_Pixel_Sizes(m_Face, 0, 64); return true; } diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h index ecb64e5009..13cb892c19 100644 --- a/core/fxge/cfx_font.h +++ b/core/fxge/cfx_font.h @@ -46,7 +46,6 @@ class CFX_Font { #ifdef PDF_ENABLE_XFA bool LoadFile(const RetainPtr& pFile, int nFaceIndex); - bool LoadClone(const CFX_Font* pFont); void SetFace(FXFT_Face face); void SetSubstFont(std::unique_ptr subst) { m_pSubstFont = std::move(subst); @@ -79,8 +78,8 @@ class CFX_Font { bool IsTTFont() const; bool GetBBox(FX_RECT& bbox); bool IsEmbedded() const { return m_bEmbedded; } - uint8_t* GetSubData() const { return m_pGsubData; } - void SetSubData(uint8_t* data) { m_pGsubData = data; } + uint8_t* GetSubData() const { return m_pGsubData.get(); } + void SetSubData(uint8_t* data) { m_pGsubData.reset(data); } #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ void* GetPlatformFont() const { return m_pPlatformFont; } void SetPlatformFont(void* font) { m_pPlatformFont = font; } @@ -100,13 +99,14 @@ class CFX_Font { #ifdef PDF_ENABLE_XFA protected: - bool m_bShallowCopy; - FXFT_StreamRec* m_pOwnedStream; + std::unique_ptr m_pOwnedStream; #endif // PDF_ENABLE_XFA private: CFX_FaceCache* GetFaceCache() const; +#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ void ReleasePlatformResource(); +#endif // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ void DeleteFace(); void ClearFaceCache(); @@ -115,7 +115,7 @@ class CFX_Font { std::unique_ptr m_pSubstFont; std::vector m_pFontDataAllocation; uint8_t* m_pFontData; - uint8_t* m_pGsubData; + std::unique_ptr m_pGsubData; uint32_t m_dwSize; #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ void* m_pPlatformFont; diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp index 3838434a51..1e829e5e4c 100644 --- a/xfa/fgas/font/cfgas_fontmgr.cpp +++ b/xfa/fgas/font/cfgas_fontmgr.cpp @@ -150,36 +150,6 @@ const FX_FONTDESCRIPTOR* MatchDefaultFont( return iBestSimilar < 1 ? nullptr : pBestFont; } -uint32_t GetFontHashCode(uint16_t wCodePage, uint32_t dwFontStyles) { - uint32_t dwHash = wCodePage; - if (FontStyleIsFixedPitch(dwFontStyles)) - dwHash |= 0x00010000; - if (FontStyleIsSerif(dwFontStyles)) - dwHash |= 0x00020000; - if (FontStyleIsSymbolic(dwFontStyles)) - dwHash |= 0x00040000; - if (FontStyleIsScript(dwFontStyles)) - dwHash |= 0x00080000; - if (FontStyleIsItalic(dwFontStyles)) - dwHash |= 0x00100000; - if (FontStyleIsBold(dwFontStyles)) - dwHash |= 0x00200000; - return dwHash; -} - -uint32_t GetFontFamilyHash(const wchar_t* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage) { - WideString wsFont(pszFontFamily); - if (FontStyleIsBold(dwFontStyles)) - wsFont += L"Bold"; - if (FontStyleIsItalic(dwFontStyles)) - wsFont += L"Italic"; - - wsFont += wCodePage; - return FX_HashCode_GetW(wsFont.AsStringView(), false); -} - uint32_t GetGdiFontStyles(const LOGFONTW& lf) { uint32_t dwStyles = 0; if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH) @@ -245,155 +215,6 @@ bool CFGAS_FontMgr::EnumFonts() { return true; } -RetainPtr CFGAS_FontMgr::GetFontByCodePage( - uint16_t wCodePage, - uint32_t dwFontStyles, - const wchar_t* pszFontFamily) { - uint32_t dwHash = GetFontHashCode(wCodePage, dwFontStyles); - 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, 999, 0); - if (!pFD) - pFD = FindFont(nullptr, dwFontStyles, true, wCodePage, 999, 0); - if (!pFD) - pFD = FindFont(nullptr, dwFontStyles, false, wCodePage, 999, 0); - if (!pFD) - return nullptr; - - RetainPtr pFont = - CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); - if (!pFont) - return nullptr; - - m_Fonts.push_back(pFont); - m_CPFonts[dwHash] = pFont; - dwHash = GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage); - m_FamilyFonts[dwHash] = pFont; - return LoadFont(pFont, dwFontStyles, wCodePage); -} - -RetainPtr CFGAS_FontMgr::GetFontByUnicode( - wchar_t wUnicode, - uint32_t dwFontStyles, - const wchar_t* pszFontFamily) { - const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode); - if (pRet->wBitField == 999) - return nullptr; - - uint32_t dwHash = - GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField); - 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) { - pFD = FindFont(nullptr, dwFontStyles, false, pRet->wCodePage, - pRet->wBitField, wUnicode); - } - if (!pFD) - return nullptr; - - uint16_t wCodePage = GetCodePageFromCharset(pFD->uCharSet); - const wchar_t* pFontFace = pFD->wsFontFace; - RetainPtr pFont = - CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this); - if (!pFont) - return nullptr; - - m_Fonts.push_back(pFont); - m_UnicodeFonts[dwHash] = pFont; - m_CPFonts[GetFontHashCode(wCodePage, dwFontStyles)] = pFont; - m_FamilyFonts[GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage)] = pFont; - return LoadFont(pFont, dwFontStyles, wCodePage); -} - -RetainPtr CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage) { - RetainPtr pFont; - uint32_t dwHash = GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage); - 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, 999, 0); - if (!pFD) - pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage, 999, 0); - if (!pFD) - return nullptr; - - if (wCodePage == 0xFFFF) - wCodePage = GetCodePageFromCharset(pFD->uCharSet); - - pFont = - CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); - if (!pFont) - return nullptr; - - m_Fonts.push_back(pFont); - m_FamilyFonts[dwHash] = pFont; - dwHash = GetFontHashCode(wCodePage, dwFontStyles); - m_CPFonts[dwHash] = pFont; - return LoadFont(pFont, dwFontStyles, wCodePage); -} - -RetainPtr CFGAS_FontMgr::LoadFont( - const RetainPtr& pSrcFont, - uint32_t dwFontStyles, - uint16_t wCodePage) { - if (pSrcFont->GetFontStyles() == dwFontStyles) - return pSrcFont; - - void* buffer[3] = {pSrcFont.Get(), (void*)(uintptr_t)dwFontStyles, - (void*)(uintptr_t)wCodePage}; - uint32_t dwHash = - FX_HashCode_GetA(ByteStringView((uint8_t*)buffer, sizeof(buffer)), false); - auto it = m_DeriveFonts.find(dwHash); - if (it != m_DeriveFonts.end() && it->second) - return it->second; - - RetainPtr pFont = pSrcFont->Derive(dwFontStyles, wCodePage); - if (!pFont) - return nullptr; - - 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( - std::map>* pFontMap, - const RetainPtr& 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(const RetainPtr& 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); -} - const FX_FONTDESCRIPTOR* CFGAS_FontMgr::FindFont(const wchar_t* pszFontFamily, uint32_t dwFontStyles, bool matchParagraphStyle, @@ -753,95 +574,6 @@ bool CFGAS_FontMgr::EnumFonts() { return EnumFontsFromFontMapper() || EnumFontsFromFiles(); } -RetainPtr CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily, - uint32_t dwFontStyles, - uint16_t wCodePage) { - return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); -} - -RetainPtr CFGAS_FontMgr::GetFontByCodePage( - uint16_t wCodePage, - uint32_t dwFontStyles, - const wchar_t* pszFontFamily) { - ByteString bsHash; - bsHash.Format("%d, %d", wCodePage, dwFontStyles); - bsHash += FX_UTF8Encode(WideStringView(pszFontFamily)); - uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringView(), false); - std::vector>* pFontArray = &m_Hash2Fonts[dwHash]; - if (!pFontArray->empty()) - return (*pFontArray)[0]; - - std::vector* sortedFontInfos = - m_Hash2CandidateList[dwHash].get(); - if (!sortedFontInfos) { - auto pNewFonts = pdfium::MakeUnique>(); - sortedFontInfos = pNewFonts.get(); - MatchFonts(sortedFontInfos, wCodePage, dwFontStyles, - WideString(pszFontFamily), 0); - m_Hash2CandidateList[dwHash] = std::move(pNewFonts); - } - if (sortedFontInfos->empty()) - return nullptr; - - CFX_FontDescriptor* pDesc = (*sortedFontInfos)[0].pFont; - RetainPtr pFont = - LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); - if (!pFont) - return nullptr; - - pFont->SetLogicalFontStyle(dwFontStyles); - pFontArray->push_back(pFont); - return pFont; -} - -RetainPtr CFGAS_FontMgr::GetFontByUnicode( - wchar_t wUnicode, - uint32_t dwFontStyles, - const wchar_t* 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; - ByteString bsHash; - if (wCodePage == 0xFFFF) - bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles); - else - bsHash.Format("%d, %d", wCodePage, dwFontStyles); - bsHash += FX_UTF8Encode(WideStringView(pszFontFamily)); - uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringView(), false); - std::vector>* pFonts = &m_Hash2Fonts[dwHash]; - for (size_t i = 0; i < pFonts->size(); ++i) { - if (VerifyUnicode((*pFonts)[i], wUnicode)) - return (*pFonts)[i]; - } - std::vector* sortedFontInfos = - m_Hash2CandidateList[dwHash].get(); - if (!sortedFontInfos) { - auto pNewFonts = pdfium::MakeUnique>(); - sortedFontInfos = pNewFonts.get(); - MatchFonts(sortedFontInfos, wCodePage, dwFontStyles, - WideString(pszFontFamily), wUnicode); - m_Hash2CandidateList[dwHash] = std::move(pNewFonts); - } - for (const auto& info : *sortedFontInfos) { - CFX_FontDescriptor* pDesc = info.pFont; - if (!VerifyUnicode(pDesc, wUnicode)) - continue; - RetainPtr pFont = - LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); - if (!pFont) - continue; - pFont->SetLogicalFontStyle(dwFontStyles); - pFonts->push_back(pFont); - return pFont; - } - if (!pszFontFamily) - m_FailedUnicodesSet.insert(wUnicode); - return nullptr; -} - bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc, wchar_t wcUnicode) { RetainPtr pFileRead = @@ -862,23 +594,6 @@ bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc, return !retCharmap && retIndex; } -bool CFGAS_FontMgr::VerifyUnicode(const RetainPtr& pFont, - wchar_t wcUnicode) { - if (!pFont) - return false; - - FXFT_Face pFace = pFont->GetDevFont()->GetFace(); - FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace); - if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0) - return false; - - if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) { - FXFT_Set_Charmap(pFace, charmap); - return false; - } - return true; -} - RetainPtr CFGAS_FontMgr::LoadFont(const WideString& wsFaceName, int32_t iFaceIndex, int32_t* pFaceCount) { @@ -1081,27 +796,6 @@ int32_t CFGAS_FontMgr::CalcPenalty(CFX_FontDescriptor* pInstalled, return nPenalty; } -void CFGAS_FontMgr::RemoveFont(const RetainPtr& pEFont) { - if (!pEFont) - return; - - m_IFXFont2FileRead.erase(pEFont); - - 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); - } -} - void CFGAS_FontMgr::RegisterFace(FXFT_Face pFace, const WideString* pFaceName) { if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0) return; @@ -1253,3 +947,197 @@ int32_t CFGAS_FontMgr::IsPartName(const WideString& Name1, } #endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + +RetainPtr CFGAS_FontMgr::GetFontByCodePage( + uint16_t wCodePage, + uint32_t dwFontStyles, + const wchar_t* pszFontFamily) { + ByteString bsHash; + bsHash.Format("%d, %d", wCodePage, dwFontStyles); + bsHash += FX_UTF8Encode(WideStringView(pszFontFamily)); + uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringView(), false); + std::vector>* pFontArray = &m_Hash2Fonts[dwHash]; + if (!pFontArray->empty()) + return (*pFontArray)[0]; + +#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + const FX_FONTDESCRIPTOR* pFD = + FindFont(pszFontFamily, dwFontStyles, true, wCodePage, 999, 0); + if (!pFD) + pFD = FindFont(nullptr, dwFontStyles, true, wCodePage, 999, 0); + if (!pFD) + pFD = FindFont(nullptr, dwFontStyles, false, wCodePage, 999, 0); + if (!pFD) + return nullptr; + + RetainPtr pFont = + CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); +#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + std::vector* sortedFontInfos = + m_Hash2CandidateList[dwHash].get(); + if (!sortedFontInfos) { + auto pNewFonts = pdfium::MakeUnique>(); + sortedFontInfos = pNewFonts.get(); + MatchFonts(sortedFontInfos, wCodePage, dwFontStyles, + WideString(pszFontFamily), 0); + m_Hash2CandidateList[dwHash] = std::move(pNewFonts); + } + if (sortedFontInfos->empty()) + return nullptr; + + CFX_FontDescriptor* pDesc = (*sortedFontInfos)[0].pFont; + RetainPtr pFont = + LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); +#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + + if (!pFont) + return nullptr; + + pFont->SetLogicalFontStyle(dwFontStyles); + pFontArray->push_back(pFont); + return pFont; +} + +RetainPtr CFGAS_FontMgr::GetFontByUnicode( + wchar_t wUnicode, + uint32_t dwFontStyles, + const wchar_t* pszFontFamily) { +#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ + if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode)) + return nullptr; +#endif // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ + + const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode); + uint16_t wCodePage = x ? x->wCodePage : 0xFFFF; + uint16_t wBitField = x ? x->wBitField : 0x03E7; + ByteString bsHash; + if (wCodePage == 0xFFFF) + bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles); + else + bsHash.Format("%d, %d", wCodePage, dwFontStyles); + bsHash += FX_UTF8Encode(WideStringView(pszFontFamily)); + uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringView(), false); + std::vector>* pFonts = &m_Hash2Fonts[dwHash]; + for (size_t i = 0; i < pFonts->size(); ++i) { + if (VerifyUnicode((*pFonts)[i], wUnicode)) + return (*pFonts)[i]; + } +#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + const FX_FONTDESCRIPTOR* pFD = FindFont(pszFontFamily, dwFontStyles, false, + wCodePage, wBitField, wUnicode); + if (!pFD && pszFontFamily) { + pFD = + FindFont(nullptr, dwFontStyles, false, wCodePage, wBitField, wUnicode); + } + if (!pFD) + return nullptr; + + uint16_t newCodePage = GetCodePageFromCharset(pFD->uCharSet); + const wchar_t* pFontFace = pFD->wsFontFace; + RetainPtr pFont = + CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, newCodePage, this); + if (!pFont) + return nullptr; + + pFont->SetLogicalFontStyle(dwFontStyles); + pFonts->push_back(pFont); + return pFont; +#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + std::vector* sortedFontInfos = + m_Hash2CandidateList[dwHash].get(); + if (!sortedFontInfos) { + auto pNewFonts = pdfium::MakeUnique>(); + sortedFontInfos = pNewFonts.get(); + MatchFonts(sortedFontInfos, wCodePage, dwFontStyles, + WideString(pszFontFamily), wUnicode); + m_Hash2CandidateList[dwHash] = std::move(pNewFonts); + } + for (const auto& info : *sortedFontInfos) { + CFX_FontDescriptor* pDesc = info.pFont; + if (!VerifyUnicode(pDesc, wUnicode)) + continue; + RetainPtr pFont = + LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); + if (!pFont) + continue; + pFont->SetLogicalFontStyle(dwFontStyles); + pFonts->push_back(pFont); + return pFont; + } + if (!pszFontFamily) + m_FailedUnicodesSet.insert(wUnicode); + return nullptr; +#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ +} + +bool CFGAS_FontMgr::VerifyUnicode(const RetainPtr& pFont, + wchar_t wcUnicode) { + if (!pFont) + return false; + + FXFT_Face pFace = pFont->GetDevFont()->GetFace(); + FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace); + if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0) + return false; + + if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) { + FXFT_Set_Charmap(pFace, charmap); + return false; + } + return true; +} + +RetainPtr CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily, + uint32_t dwFontStyles, + uint16_t wCodePage) { +#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + ByteString bsHash; + bsHash.Format("%d, %d", wCodePage, dwFontStyles); + bsHash += FX_UTF8Encode(WideStringView(pszFontFamily)); + uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringView(), false); + std::vector>* pFontArray = &m_Hash2Fonts[dwHash]; + if (!pFontArray->empty()) + return (*pFontArray)[0]; + + const FX_FONTDESCRIPTOR* pFD = + FindFont(pszFontFamily, dwFontStyles, true, wCodePage, 999, 0); + if (!pFD) + pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage, 999, 0); + if (!pFD) + return nullptr; + + RetainPtr pFont = + CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); + if (!pFont) + return nullptr; + + pFont->SetLogicalFontStyle(dwFontStyles); + pFontArray->push_back(pFont); + return pFont; +#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); +#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ +} + +void CFGAS_FontMgr::RemoveFont(const RetainPtr& pEFont) { + if (!pEFont) + return; + +#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ + m_IFXFont2FileRead.erase(pEFont); +#endif // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ + + 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 351b5d624c..42171de804 100644 --- a/xfa/fgas/font/cfgas_fontmgr.h +++ b/xfa/fgas/font/cfgas_fontmgr.h @@ -146,11 +146,6 @@ class CFGAS_FontMgr : public Observable { private: #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ - RetainPtr LoadFont(const RetainPtr& pSrcFont, - uint32_t dwFontStyles, - uint16_t wCodePage); - void RemoveFont(std::map>* pFontMap, - const RetainPtr& pFont); const FX_FONTDESCRIPTOR* FindFont(const wchar_t* pszFontFamily, uint32_t dwFontStyles, bool matchParagraphStyle, @@ -160,13 +155,6 @@ class CFGAS_FontMgr : public Observable { FX_LPEnumAllFonts m_pEnumerator; std::deque m_FontFaces; - std::vector> m_Fonts; - std::map> m_CPFonts; - std::map> m_FamilyFonts; - std::map> m_UnicodeFonts; - std::map> m_BufferFonts; - std::map> m_StreamFonts; - std::map> m_DeriveFonts; #else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ bool EnumFontsFromFontMapper(); bool EnumFontsFromFiles(); @@ -178,7 +166,6 @@ class CFGAS_FontMgr : public Observable { void GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB); uint32_t GetFlags(FXFT_Face pFace); bool VerifyUnicode(CFX_FontDescriptor* pDesc, wchar_t wcUnicode); - bool VerifyUnicode(const RetainPtr& pFont, wchar_t wcUnicode); int32_t IsPartName(const WideString& Name1, const WideString& Name2); void MatchFonts(std::vector* MatchedFonts, uint16_t wCodePage, @@ -206,11 +193,14 @@ class CFGAS_FontMgr : public Observable { std::vector> m_InstalledFonts; std::map>> m_Hash2CandidateList; - std::map>> m_Hash2Fonts; std::map, RetainPtr> m_IFXFont2FileRead; std::set m_FailedUnicodesSet; #endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + + bool VerifyUnicode(const RetainPtr& pFont, wchar_t wcUnicode); + + std::map>> m_Hash2Fonts; }; #endif // XFA_FGAS_FONT_CFGAS_FONTMGR_H_ diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp index 43d019f0f5..83b7ad68d7 100644 --- a/xfa/fgas/font/cfgas_gefont.cpp +++ b/xfa/fgas/font/cfgas_gefont.cpp @@ -56,43 +56,13 @@ RetainPtr CFGAS_GEFont::LoadFont( CFGAS_GEFont::CFGAS_GEFont(CFGAS_FontMgr* pFontMgr) : -#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ m_bUseLogFontStyle(false), m_dwLogFontStyle(0), -#endif m_pFont(nullptr), m_bExternalFont(false), m_pFontMgr(pFontMgr) { } -CFGAS_GEFont::CFGAS_GEFont(const RetainPtr& src, - uint32_t dwFontStyles) - : -#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ - m_bUseLogFontStyle(false), - m_dwLogFontStyle(0), -#endif - m_pFont(nullptr), - m_bExternalFont(false), - m_pSrcFont(src), - m_pFontMgr(src->m_pFontMgr) { - ASSERT(m_pSrcFont->m_pFont); - m_pFont = new CFX_Font; - m_pFont->LoadClone(m_pSrcFont->m_pFont); - - CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); - if (!pSubst) { - pSubst = new CFX_SubstFont; - m_pFont->SetSubstFont(std::unique_ptr(pSubst)); - } - pSubst->m_Weight = - FontStyleIsBold(dwFontStyles) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; - if (FontStyleIsItalic(dwFontStyles)) - pSubst->m_bFlagItalic = true; - - InitFont(); -} - CFGAS_GEFont::~CFGAS_GEFont() { if (!m_bExternalFont) delete m_pFont; @@ -155,16 +125,6 @@ bool CFGAS_GEFont::InitFont() { return !!m_pFontEncoding; } -#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ -RetainPtr CFGAS_GEFont::Derive(uint32_t dwFontStyles, - uint16_t wCodePage) { - RetainPtr pFont(this); - if (GetFontStyles() == dwFontStyles) - return pFont; - return pdfium::MakeRetain(pFont, dwFontStyles); -} -#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ - WideString CFGAS_GEFont::GetFamilyName() const { if (!m_pFont->GetSubstFont() || m_pFont->GetSubstFont()->m_Family.GetLength() == 0) { @@ -176,10 +136,8 @@ WideString CFGAS_GEFont::GetFamilyName() const { uint32_t CFGAS_GEFont::GetFontStyles() const { ASSERT(m_pFont); -#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ if (m_bUseLogFontStyle) return m_dwLogFontStyle; -#endif uint32_t dwStyles = 0; auto* pSubstFont = m_pFont->GetSubstFont(); diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h index 2e63ee5367..d14554758b 100644 --- a/xfa/fgas/font/cfgas_gefont.h +++ b/xfa/fgas/font/cfgas_gefont.h @@ -54,18 +54,13 @@ class CFGAS_GEFont : public Retainable { m_pProvider.Reset(pProvider); } -#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ - RetainPtr Derive(uint32_t dwFontStyles, uint16_t wCodePage); -#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ void SetLogicalFontStyle(uint32_t dwLogFontStyle) { m_bUseLogFontStyle = true; m_dwLogFontStyle = dwLogFontStyle; } -#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ private: explicit CFGAS_GEFont(CFGAS_FontMgr* pFontMgr); - CFGAS_GEFont(const RetainPtr& src, uint32_t dwFontStyles); ~CFGAS_GEFont() override; #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ @@ -84,10 +79,8 @@ class CFGAS_GEFont : public Retainable { bool bRecursive); WideString GetFamilyName() const; -#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_ bool m_bUseLogFontStyle; uint32_t m_dwLogFontStyle; -#endif CFX_Font* m_pFont; bool m_bExternalFont; RetainPtr m_pSrcFont; // Only set by ctor, so no cycles. -- cgit v1.2.3