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