1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fxge/cfx_fontmgr.h" 8 9 #include <memory> 10 #include <utility> 11 12 #include "core/fxge/cfx_fontmapper.h" 13 #include "core/fxge/cfx_substfont.h" 14 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h" 15 #include "core/fxge/fx_font.h" 16 #include "core/fxge/ge/cttfontdesc.h" 17 #include "core/fxge/ifx_systemfontinfo.h" 18 #include "third_party/base/ptr_util.h" 19 20 namespace { 21 22 struct BuiltinFont { 23 const uint8_t* m_pFontData; 24 uint32_t m_dwSize; 25 }; 26 27 const BuiltinFont g_FoxitFonts[14] = { 28 {g_FoxitFixedFontData, 17597}, 29 {g_FoxitFixedBoldFontData, 18055}, 30 {g_FoxitFixedBoldItalicFontData, 19151}, 31 {g_FoxitFixedItalicFontData, 18746}, 32 {g_FoxitSansFontData, 15025}, 33 {g_FoxitSansBoldFontData, 16344}, 34 {g_FoxitSansBoldItalicFontData, 16418}, 35 {g_FoxitSansItalicFontData, 16339}, 36 {g_FoxitSerifFontData, 19469}, 37 {g_FoxitSerifBoldFontData, 19395}, 38 {g_FoxitSerifBoldItalicFontData, 20733}, 39 {g_FoxitSerifItalicFontData, 21227}, 40 {g_FoxitSymbolFontData, 16729}, 41 {g_FoxitDingbatsFontData, 29513}, 42 }; 43 44 const BuiltinFont g_MMFonts[2] = { 45 {g_FoxitSerifMMFontData, 113417}, 46 {g_FoxitSansMMFontData, 66919}, 47 }; 48 49 CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name, 50 int weight, 51 bool bItalic) { 52 CFX_ByteString key(face_name); 53 key += ','; 54 key += CFX_ByteString::FormatInteger(weight); 55 key += bItalic ? 'I' : 'N'; 56 return key; 57 } 58 59 CFX_ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) { 60 CFX_ByteString key; 61 key.Format("%d:%d", ttc_size, checksum); 62 return key; 63 } 64 65 int GetTTCIndex(const uint8_t* pFontData, 66 uint32_t ttc_size, 67 uint32_t font_offset) { 68 int face_index = 0; 69 const uint8_t* p = pFontData + 8; 70 uint32_t nfont = GET_TT_LONG(p); 71 uint32_t index; 72 for (index = 0; index < nfont; index++) { 73 p = pFontData + 12 + index * 4; 74 if (GET_TT_LONG(p) == font_offset) 75 break; 76 } 77 if (index >= nfont) 78 face_index = 0; 79 else 80 face_index = index; 81 return face_index; 82 } 83 84 } // namespace 85 86 CFX_FontMgr::CFX_FontMgr() 87 : m_FTLibrary(nullptr), m_FTLibrarySupportsHinting(false) { 88 m_pBuiltinMapper = pdfium::MakeUnique<CFX_FontMapper>(this); 89 } 90 91 CFX_FontMgr::~CFX_FontMgr() { 92 for (const auto& pair : m_FaceMap) 93 delete pair.second; 94 95 // |m_pBuiltinMapper| references |m_FTLibrary|, so it has to be destroyed 96 // first. 97 m_pBuiltinMapper.reset(); 98 FXFT_Done_FreeType(m_FTLibrary); 99 } 100 101 void CFX_FontMgr::InitFTLibrary() { 102 if (m_FTLibrary) 103 return; 104 FXFT_Init_FreeType(&m_FTLibrary); 105 m_FTLibrarySupportsHinting = 106 FXFT_Library_SetLcdFilter(m_FTLibrary, FT_LCD_FILTER_DEFAULT) != 107 FT_Err_Unimplemented_Feature; 108 } 109 110 void CFX_FontMgr::SetSystemFontInfo( 111 std::unique_ptr<IFX_SystemFontInfo> pFontInfo) { 112 m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo)); 113 } 114 115 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, 116 bool bTrueType, 117 uint32_t flags, 118 int weight, 119 int italic_angle, 120 int CharsetCP, 121 CFX_SubstFont* pSubstFont) { 122 InitFTLibrary(); 123 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, 124 italic_angle, CharsetCP, pSubstFont); 125 } 126 127 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, 128 int weight, 129 bool bItalic, 130 uint8_t*& pFontData) { 131 auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic)); 132 if (it == m_FaceMap.end()) 133 return nullptr; 134 135 CTTFontDesc* pFontDesc = it->second; 136 pFontData = pFontDesc->m_pFontData; 137 pFontDesc->m_RefCount++; 138 return pFontDesc->m_SingleFace; 139 } 140 141 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, 142 int weight, 143 bool bItalic, 144 uint8_t* pData, 145 uint32_t size, 146 int face_index) { 147 CTTFontDesc* pFontDesc = new CTTFontDesc; 148 pFontDesc->m_Type = 1; 149 pFontDesc->m_SingleFace = nullptr; 150 pFontDesc->m_pFontData = pData; 151 pFontDesc->m_RefCount = 1; 152 153 InitFTLibrary(); 154 FXFT_Library library = m_FTLibrary; 155 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, 156 &pFontDesc->m_SingleFace); 157 if (ret) { 158 delete pFontDesc; 159 return nullptr; 160 } 161 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace, 64, 64); 162 if (ret) { 163 delete pFontDesc; 164 return nullptr; 165 } 166 m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc; 167 return pFontDesc->m_SingleFace; 168 } 169 170 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, 171 uint32_t checksum, 172 int font_offset, 173 uint8_t*& pFontData) { 174 auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum)); 175 if (it == m_FaceMap.end()) 176 return nullptr; 177 178 CTTFontDesc* pFontDesc = it->second; 179 pFontData = pFontDesc->m_pFontData; 180 pFontDesc->m_RefCount++; 181 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); 182 if (!pFontDesc->m_TTCFaces[face_index]) { 183 pFontDesc->m_TTCFaces[face_index] = 184 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); 185 } 186 return pFontDesc->m_TTCFaces[face_index]; 187 } 188 189 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, 190 uint32_t checksum, 191 uint8_t* pData, 192 uint32_t size, 193 int font_offset) { 194 CTTFontDesc* pFontDesc = new CTTFontDesc; 195 pFontDesc->m_Type = 2; 196 pFontDesc->m_pFontData = pData; 197 for (int i = 0; i < 16; i++) 198 pFontDesc->m_TTCFaces[i] = nullptr; 199 pFontDesc->m_RefCount++; 200 m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = pFontDesc; 201 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); 202 pFontDesc->m_TTCFaces[face_index] = 203 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); 204 return pFontDesc->m_TTCFaces[face_index]; 205 } 206 207 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData, 208 uint32_t size, 209 int face_index) { 210 InitFTLibrary(); 211 FXFT_Library library = m_FTLibrary; 212 FXFT_Face face = nullptr; 213 if (FXFT_New_Memory_Face(library, pData, size, face_index, &face)) 214 return nullptr; 215 return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face; 216 } 217 218 FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) { 219 InitFTLibrary(); 220 FXFT_Library library = m_FTLibrary; 221 FXFT_Face face = nullptr; 222 if (FXFT_New_Face(library, filename, face_index, &face)) 223 return nullptr; 224 return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face; 225 } 226 227 void CFX_FontMgr::ReleaseFace(FXFT_Face face) { 228 if (!face) 229 return; 230 bool bNeedFaceDone = true; 231 auto it = m_FaceMap.begin(); 232 while (it != m_FaceMap.end()) { 233 auto temp = it++; 234 int nRet = temp->second->ReleaseFace(face); 235 if (nRet == -1) 236 continue; 237 bNeedFaceDone = false; 238 if (nRet == 0) 239 m_FaceMap.erase(temp); 240 break; 241 } 242 if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face)) 243 FXFT_Done_Face(face); 244 } 245 246 bool CFX_FontMgr::GetBuiltinFont(size_t index, 247 const uint8_t** pFontData, 248 uint32_t* size) { 249 if (index < FX_ArraySize(g_FoxitFonts)) { 250 *pFontData = g_FoxitFonts[index].m_pFontData; 251 *size = g_FoxitFonts[index].m_dwSize; 252 return true; 253 } 254 index -= FX_ArraySize(g_FoxitFonts); 255 if (index < FX_ArraySize(g_MMFonts)) { 256 *pFontData = g_MMFonts[index].m_pFontData; 257 *size = g_MMFonts[index].m_dwSize; 258 return true; 259 } 260 return false; 261 } 262