summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-11-16 21:41:47 +0000
committerChromium commit bot <commit-bot@chromium.org>2017-11-16 21:41:47 +0000
commit40d522134a11867adb95f77c0b7891932e0739a2 (patch)
tree07164d786b15348783d10cccc9babb9427ff1abe
parent3f9549e7f00b649471c4d658bbfb6bf031b8f53e (diff)
downloadpdfium-40d522134a11867adb95f77c0b7891932e0739a2.tar.xz
Refactor CFGAS_FontMgr's Windows implementation
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 <dsinclair@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
-rw-r--r--core/fxge/cfx_font.cpp47
-rw-r--r--core/fxge/cfx_font.h12
-rw-r--r--xfa/fgas/font/cfgas_fontmgr.cpp500
-rw-r--r--xfa/fgas/font/cfgas_fontmgr.h18
-rw-r--r--xfa/fgas/font/cfgas_gefont.cpp42
-rw-r--r--xfa/fgas/font/cfgas_gefont.h7
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<CFX_SubstFont>();
- 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<IFX_SeekableReadStream>& 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<IFX_SeekableReadStream>& pFile, int nFaceIndex);
- bool LoadClone(const CFX_Font* pFont);
void SetFace(FXFT_Face face);
void SetSubstFont(std::unique_ptr<CFX_SubstFont> 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<FXFT_StreamRec> 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<CFX_SubstFont> m_pSubstFont;
std::vector<uint8_t> m_pFontDataAllocation;
uint8_t* m_pFontData;
- uint8_t* m_pGsubData;
+ std::unique_ptr<uint8_t, FxFreeDeleter> 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_GEFont> 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<CFGAS_GEFont> 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_GEFont> 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<CFGAS_GEFont> 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_GEFont> CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily,
- uint32_t dwFontStyles,
- uint16_t wCodePage) {
- RetainPtr<CFGAS_GEFont> 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_GEFont> CFGAS_FontMgr::LoadFont(
- const RetainPtr<CFGAS_GEFont>& 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<CFGAS_GEFont> 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<uint32_t, RetainPtr<CFGAS_GEFont>>* pFontMap,
- const 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(const 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);
-}
-
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_GEFont> CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily,
- uint32_t dwFontStyles,
- uint16_t wCodePage) {
- return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
-}
-
-RetainPtr<CFGAS_GEFont> 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<RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash];
- if (!pFontArray->empty())
- return (*pFontArray)[0];
-
- std::vector<CFX_FontDescriptorInfo>* sortedFontInfos =
- m_Hash2CandidateList[dwHash].get();
- if (!sortedFontInfos) {
- auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
- 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<CFGAS_GEFont> pFont =
- LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
- if (!pFont)
- return nullptr;
-
- pFont->SetLogicalFontStyle(dwFontStyles);
- pFontArray->push_back(pFont);
- return pFont;
-}
-
-RetainPtr<CFGAS_GEFont> 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<RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash];
- for (size_t i = 0; i < pFonts->size(); ++i) {
- if (VerifyUnicode((*pFonts)[i], wUnicode))
- return (*pFonts)[i];
- }
- std::vector<CFX_FontDescriptorInfo>* sortedFontInfos =
- m_Hash2CandidateList[dwHash].get();
- if (!sortedFontInfos) {
- auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
- 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<CFGAS_GEFont> 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<IFX_SeekableReadStream> pFileRead =
@@ -862,23 +594,6 @@ bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc,
return !retCharmap && retIndex;
}
-bool CFGAS_FontMgr::VerifyUnicode(const RetainPtr<CFGAS_GEFont>& 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_GEFont> 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<CFGAS_GEFont>& 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_GEFont> 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<RetainPtr<CFGAS_GEFont>>* 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<CFGAS_GEFont> pFont =
+ CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
+#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+ std::vector<CFX_FontDescriptorInfo>* sortedFontInfos =
+ m_Hash2CandidateList[dwHash].get();
+ if (!sortedFontInfos) {
+ auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
+ 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<CFGAS_GEFont> 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_GEFont> 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<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 _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<CFGAS_GEFont> 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<CFX_FontDescriptorInfo>* sortedFontInfos =
+ m_Hash2CandidateList[dwHash].get();
+ if (!sortedFontInfos) {
+ auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
+ 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<CFGAS_GEFont> 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<CFGAS_GEFont>& 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_GEFont> 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<RetainPtr<CFGAS_GEFont>>* 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<CFGAS_GEFont> 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<CFGAS_GEFont>& 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<CFGAS_FontMgr> {
private:
#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
- RetainPtr<CFGAS_GEFont> LoadFont(const RetainPtr<CFGAS_GEFont>& pSrcFont,
- uint32_t dwFontStyles,
- uint16_t wCodePage);
- void RemoveFont(std::map<uint32_t, RetainPtr<CFGAS_GEFont>>* pFontMap,
- const RetainPtr<CFGAS_GEFont>& pFont);
const FX_FONTDESCRIPTOR* FindFont(const wchar_t* pszFontFamily,
uint32_t dwFontStyles,
bool matchParagraphStyle,
@@ -160,13 +155,6 @@ class CFGAS_FontMgr : public Observable<CFGAS_FontMgr> {
FX_LPEnumAllFonts m_pEnumerator;
std::deque<FX_FONTDESCRIPTOR> m_FontFaces;
- std::vector<RetainPtr<CFGAS_GEFont>> m_Fonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_CPFonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_FamilyFonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_UnicodeFonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_BufferFonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_StreamFonts;
- std::map<uint32_t, RetainPtr<CFGAS_GEFont>> m_DeriveFonts;
#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
bool EnumFontsFromFontMapper();
bool EnumFontsFromFiles();
@@ -178,7 +166,6 @@ class CFGAS_FontMgr : public Observable<CFGAS_FontMgr> {
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<CFGAS_GEFont>& pFont, wchar_t wcUnicode);
int32_t IsPartName(const WideString& Name1, const WideString& Name2);
void MatchFonts(std::vector<CFX_FontDescriptorInfo>* MatchedFonts,
uint16_t wCodePage,
@@ -206,11 +193,14 @@ class CFGAS_FontMgr : public Observable<CFGAS_FontMgr> {
std::vector<std::unique_ptr<CFX_FontDescriptor>> m_InstalledFonts;
std::map<uint32_t, std::unique_ptr<std::vector<CFX_FontDescriptorInfo>>>
m_Hash2CandidateList;
- std::map<uint32_t, std::vector<RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts;
std::map<RetainPtr<CFGAS_GEFont>, RetainPtr<IFX_SeekableReadStream>>
m_IFXFont2FileRead;
std::set<wchar_t> m_FailedUnicodesSet;
#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+
+ bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode);
+
+ std::map<uint32_t, std::vector<RetainPtr<CFGAS_GEFont>>> 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> 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<CFGAS_GEFont>& 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<CFX_SubstFont>(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> CFGAS_GEFont::Derive(uint32_t dwFontStyles,
- uint16_t wCodePage) {
- RetainPtr<CFGAS_GEFont> pFont(this);
- if (GetFontStyles() == dwFontStyles)
- return pFont;
- return pdfium::MakeRetain<CFGAS_GEFont>(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<CFGAS_GEFont> 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<CFGAS_GEFont>& 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<CFGAS_GEFont> m_pSrcFont; // Only set by ctor, so no cycles.