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