From fe73e7849b8b4ce49408d2f52f3fc29b370b82b5 Mon Sep 17 00:00:00 2001 From: Jun Fang Date: Tue, 19 Jan 2016 17:13:50 -0800 Subject: Fix an assertion failure in CXFA_FWLTheme::Initialize() BUG=pdfium:350 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1608593003 . --- core/include/fxge/fx_font.h | 2 + xfa/src/fgas/src/font/fx_stdfontmgr.cpp | 146 +++++++++++++++++++++++--------- xfa/src/fgas/src/font/fx_stdfontmgr.h | 10 ++- 3 files changed, 119 insertions(+), 39 deletions(-) diff --git a/core/include/fxge/fx_font.h b/core/include/fxge/fx_font.h index 954824e728..f2db4a1dc0 100644 --- a/core/include/fxge/fx_font.h +++ b/core/include/fxge/fx_font.h @@ -325,6 +325,8 @@ class CFX_FontMapper { int italic_angle); #endif // PDF_ENABLE_XFA FX_BOOL IsBuiltinFace(const FXFT_Face face) const; + int GetFaceSize() const { return m_FaceArray.GetSize(); } + CFX_ByteString GetFaceName(int index) const { return m_FaceArray[index]; } private: static const size_t MM_FACE_COUNT = 2; diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.cpp b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp index 6201022323..96214685f0 100644 --- a/xfa/src/fgas/src/font/fx_stdfontmgr.cpp +++ b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp @@ -4,6 +4,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/src/fxcrt/extension.h" #include "xfa/src/fgas/src/fgas_base.h" #include "fx_stdfontmgr.h" #include "fx_fontutils.h" @@ -608,45 +609,53 @@ CFX_FontMgrImp::CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum, m_pDelegate(pDelegate), m_pUserData(pUserData) {} -FX_BOOL CFX_FontMgrImp::EnumFonts() { +FX_BOOL CFX_FontMgrImp::EnumFontsFromFontMapper() { + CFX_FontMapper* pFontMapper = + CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper(); + if (!pFontMapper) + return FALSE; + IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); + if (!pSystemFontInfo) + return FALSE; + pSystemFontInfo->EnumFontList(pFontMapper); + for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) { + IFX_FileRead* pFontStream = + CreateFontStream(pFontMapper, pSystemFontInfo, i); + if (!pFontStream) + continue; + ReportFaces(pFontStream); + pFontStream->Release(); + } + if (m_InstalledFonts.GetSize() == 0) + return FALSE; + return TRUE; +} +FX_BOOL CFX_FontMgrImp::EnumFontsFromFiles() { CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary(); - FXFT_Face pFace = NULL; + FXFT_Face pFace = nullptr; FX_POSITION pos = m_pFontSource->GetStartPosition(); - IFX_FileAccess* pFontSource = NULL; - IFX_FileRead* pFontStream = NULL; + IFX_FileAccess* pFontSource = nullptr; + IFX_FileRead* pFontStream = nullptr; while (pos) { pFontSource = m_pFontSource->GetNext(pos); pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly); - if (NULL == pFontStream) { + if (!pFontStream) { pFontSource->Release(); continue; } - if (NULL == (pFace = LoadFace(pFontStream, 0))) { - pFontStream->Release(); - pFontSource->Release(); - continue; - } - int32_t nFaceCount = pFace->num_faces; - ReportFace(pFace, m_InstalledFonts, pFontSource); - if (FXFT_Get_Face_External_Stream(pFace)) { - FXFT_Clear_Face_External_Stream(pFace); - } - FXFT_Done_Face(pFace); - for (int32_t i = 1; i < nFaceCount; i++) { - if (NULL == (pFace = LoadFace(pFontStream, i))) { - continue; - } - ReportFace(pFace, m_InstalledFonts, pFontSource); - if (FXFT_Get_Face_External_Stream(pFace)) { - FXFT_Clear_Face_External_Stream(pFace); - } - FXFT_Done_Face(pFace); - } + ReportFaces(pFontStream); pFontStream->Release(); pFontSource->Release(); } + if (m_InstalledFonts.GetSize() == 0) + return FALSE; return TRUE; } +FX_BOOL CFX_FontMgrImp::EnumFonts() { + if (EnumFontsFromFontMapper()) + return TRUE; + return EnumFontsFromFiles(); +} void CFX_FontMgrImp::Release() { for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) { delete m_InstalledFonts[i]; @@ -756,7 +765,10 @@ IFX_Font* CFX_FontMgrImp::GetFontByCodePage(FX_WORD wCodePage, return NULL; } CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont; - pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, NULL); + if (pDesc->m_pFileAccess) + pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, nullptr); + else + pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); if (NULL != pFont) { pFont->SetLogicalFontStyle(dwFontStyles); } @@ -978,6 +990,39 @@ IFX_Font* CFX_FontMgrImp::LoadFont(IFX_FileAccess* pFontAccess, } return pFont; } +IFX_Font* CFX_FontMgrImp::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) + return nullptr; + IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); + if (!pSystemFontInfo) + return nullptr; + IFX_FileRead* pFontStream = + CreateFontStream(pFontMapper, pSystemFontInfo, iFaceIndex); + if (!pFontStream) + return nullptr; + if (!LoadFace(pFontStream, 0)) { + pFontStream->Release(); + return nullptr; + } + CFX_Font* pInternalFont = new CFX_Font(); + if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) { + pFontStream->Release(); + return nullptr; + } + IFX_Font* pFont = IFX_Font::LoadFont(pInternalFont, this, FALSE); + if (!pFont) { + pFontStream->Release(); + return nullptr; + } + m_IFXFont2FileRead.SetAt(pFont, pFontStream); + if (pFaceCount) + *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces; + return pFont; +} extern "C" { unsigned long _ftStreamRead(FXFT_Stream stream, unsigned long offset, @@ -1030,6 +1075,22 @@ FXFT_Face CFX_FontMgrImp::LoadFace(IFX_FileRead* pFontStream, FXFT_Set_Pixel_Sizes(pFace, 0, 64); return pFace; } +IFX_FileRead* CFX_FontMgrImp::CreateFontStream( + CFX_FontMapper* pFontMapper, + IFX_SystemFontInfo* pSystemFontInfo, + FX_DWORD index) { + int iExact = 0; + void* hFont = pSystemFontInfo->MapFont( + 0, 0, FXFONT_DEFAULT_CHARSET, 0, pFontMapper->GetFaceName(index), iExact); + if (!hFont) + return nullptr; + FX_DWORD dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0); + if (dwFileSize == 0) + return nullptr; + uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1); + dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize); + return new CFX_MemoryStream(pBuffer, dwFileSize, TRUE); +} int32_t CFX_FontMgrImp::MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, FX_WORD wCodePage, @@ -1038,7 +1099,6 @@ int32_t CFX_FontMgrImp::MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, FX_WCHAR wcUnicode) { MatchedFonts.RemoveAll(); CFX_WideString wsNormalizedFontName = FontName; - NormalizeFontName(wsNormalizedFontName); static const int32_t nMax = 0xffff; CFX_FontDescriptor* pFont = NULL; int32_t nCount = m_InstalledFonts.GetSize(); @@ -1276,13 +1336,28 @@ void CFX_FontMgrImp::ReportFace(FXFT_Face pFace, pFont->m_wsFaceName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace)); pFont->m_nFaceIndex = pFace->face_index; - pFont->m_pFileAccess = pFontAccess->Retain(); - NormalizeFontName(pFont->m_wsFaceName); - for (int32_t i = 0; i < pFont->m_wsFamilyNames.GetSize(); i++) { - NormalizeFontName(pFont->m_wsFamilyNames[i]); - } + if (pFontAccess) + pFont->m_pFileAccess = pFontAccess->Retain(); + else + pFont->m_pFileAccess = nullptr; Fonts.Add(pFont); } +void CFX_FontMgrImp::ReportFaces(IFX_FileRead* pFontStream) { + int32_t index = 0; + int32_t num_faces = 0; + do { + FXFT_Face pFace = LoadFace(pFontStream, index++); + if (!pFace) + continue; + // All faces keep number of faces. It can be retrieved from any one face. + if (!num_faces) + num_faces = pFace->num_faces; + ReportFace(pFace, m_InstalledFonts, nullptr); + if (FXFT_Get_Face_External_Stream(pFace)) + FXFT_Clear_Face_External_Stream(pFace); + FXFT_Done_Face(pFace); + } while (index < num_faces); +} FX_DWORD CFX_FontMgrImp::GetFlags(FXFT_Face pFace) { FX_DWORD flag = 0; if (FT_IS_FIXED_WIDTH(pFace)) { @@ -1447,11 +1522,6 @@ void CFX_FontMgrImp::GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB) { CSB[1] = 0; } } -void CFX_FontMgrImp::NormalizeFontName(CFX_WideString& FontName) { - FontName.MakeLower(); - FontName.Remove(' '); - FontName.Remove('-'); -} int32_t CFX_FontMgrImp::IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2) { if (Name1.Find((const FX_WCHAR*)Name2) != -1) { diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.h b/xfa/src/fgas/src/font/fx_stdfontmgr.h index 3ab984fc79..603a0f5d3c 100644 --- a/xfa/src/fgas/src/font/fx_stdfontmgr.h +++ b/xfa/src/fgas/src/font/fx_stdfontmgr.h @@ -179,14 +179,20 @@ class CFX_FontMgrImp : public IFX_FontMgr { int32_t iFaceIndex, int32_t* pFaceCount, FX_BOOL bSaveStream = FALSE); + virtual IFX_Font* LoadFont(const CFX_WideString& wsFaceName, + int32_t iFaceIndex, + int32_t* pFaceCount); virtual void ClearFontCache(); virtual void RemoveFont(IFX_Font* pFont); FX_BOOL EnumFonts(); + FX_BOOL EnumFontsFromFontMapper(); + FX_BOOL EnumFontsFromFiles(); protected: void ReportFace(FXFT_Face pFace, CFX_FontDescriptors& Fonts, IFX_FileAccess* pFontAccess); + void ReportFaces(IFX_FileRead* pFontStream); void GetNames(const uint8_t* name_table, CFX_WideStringArray& Names); void GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets); void GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB); @@ -194,7 +200,6 @@ class CFX_FontMgrImp : public IFX_FontMgr { CFX_FontDescriptors m_InstalledFonts; FX_BOOL VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode); FX_BOOL VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode); - void NormalizeFontName(CFX_WideString& FontName); int32_t IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2); int32_t MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, FX_WORD wCodePage, @@ -211,6 +216,9 @@ class CFX_FontMgrImp : public IFX_FontMgr { int32_t* pFaceCount, FX_BOOL bWantCache = FALSE); FXFT_Face LoadFace(IFX_FileRead* pFontStream, int32_t iFaceIndex); + IFX_FileRead* CreateFontStream(CFX_FontMapper* pFontMapper, + IFX_SystemFontInfo* pSystemFontInfo, + FX_DWORD index); CFX_HashFontDescsMap m_Hash2CandidateList; CFX_HashFontsMap m_Hash2Fonts; CFX_HashFileMap m_Hash2FileAccess; -- cgit v1.2.3