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 |