OLD | NEW |
1 // Copyright 2015 PDFium Authors. All rights reserved. | 1 // Copyright 2015 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "xfa/fgas/font/cfgas_fontmgr.h" | 7 #include "xfa/fgas/font/cfgas_fontmgr.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "core/fxcrt/fx_stream.h" | 12 #include "core/fxcrt/fx_stream.h" |
13 #include "core/fxge/cfx_fontmapper.h" | 13 #include "core/fxge/cfx_fontmapper.h" |
14 #include "core/fxge/cfx_fontmgr.h" | 14 #include "core/fxge/cfx_fontmgr.h" |
15 #include "core/fxge/cfx_gemodule.h" | 15 #include "core/fxge/cfx_gemodule.h" |
16 #include "core/fxge/ifx_systemfontinfo.h" | 16 #include "core/fxge/ifx_systemfontinfo.h" |
17 #include "third_party/base/ptr_util.h" | 17 #include "third_party/base/ptr_util.h" |
| 18 #include "third_party/base/stl_util.h" |
18 #include "xfa/fgas/crt/fgas_codepage.h" | 19 #include "xfa/fgas/crt/fgas_codepage.h" |
19 #include "xfa/fgas/font/cfgas_gefont.h" | 20 #include "xfa/fgas/font/cfgas_gefont.h" |
20 #include "xfa/fgas/font/fgas_fontutils.h" | 21 #include "xfa/fgas/font/fgas_fontutils.h" |
21 | 22 |
22 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 23 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 int32_t GetSimilarityScore(FX_FONTDESCRIPTOR const* pFont, | 27 int32_t GetSimilarityScore(FX_FONTDESCRIPTOR const* pFont, |
27 uint32_t dwFontStyles) { | 28 uint32_t dwFontStyles) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 } | 95 } |
95 | 96 |
96 } // namespace | 97 } // namespace |
97 | 98 |
98 std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create( | 99 std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create( |
99 FX_LPEnumAllFonts pEnumerator) { | 100 FX_LPEnumAllFonts pEnumerator) { |
100 return pdfium::MakeUnique<CFGAS_FontMgr>(pEnumerator); | 101 return pdfium::MakeUnique<CFGAS_FontMgr>(pEnumerator); |
101 } | 102 } |
102 | 103 |
103 CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator) | 104 CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator) |
104 : m_pEnumerator(pEnumerator), | 105 : m_pEnumerator(pEnumerator), m_FontFaces(100) { |
105 m_FontFaces(100), | |
106 m_CPFonts(8), | |
107 m_FamilyFonts(16), | |
108 m_UnicodeFonts(16), | |
109 m_BufferFonts(4), | |
110 m_StreamFonts(4), | |
111 m_DeriveFonts(4) { | |
112 if (m_pEnumerator) | 106 if (m_pEnumerator) |
113 m_pEnumerator(m_FontFaces, nullptr, 0xFEFF); | 107 m_pEnumerator(m_FontFaces, nullptr, 0xFEFF); |
114 } | 108 } |
115 | 109 |
116 CFGAS_FontMgr::~CFGAS_FontMgr() { | 110 CFGAS_FontMgr::~CFGAS_FontMgr() { |
117 m_FontFaces.RemoveAll(false); | 111 m_FontFaces.RemoveAll(false); |
118 m_CPFonts.RemoveAll(); | |
119 m_FamilyFonts.RemoveAll(); | |
120 m_UnicodeFonts.RemoveAll(); | |
121 m_BufferFonts.RemoveAll(); | |
122 m_StreamFonts.RemoveAll(); | |
123 m_DeriveFonts.RemoveAll(); | |
124 for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--) | |
125 m_Fonts[i]->Release(); | |
126 } | 112 } |
127 | 113 |
128 CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, | 114 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( |
129 uint32_t dwFontStyles, | 115 uint16_t wCodePage, |
130 const FX_WCHAR* pszFontFamily) { | 116 uint32_t dwFontStyles, |
| 117 const FX_WCHAR* pszFontFamily) { |
131 uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); | 118 uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); |
132 CFGAS_GEFont* pFont = nullptr; | 119 auto it = m_CPFonts.find(dwHash); |
133 if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) | 120 if (it != m_CPFonts.end()) { |
134 return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr; | 121 return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr; |
135 FX_FONTDESCRIPTOR const* pFD = | 122 } |
| 123 const FX_FONTDESCRIPTOR* pFD = |
136 FindFont(pszFontFamily, dwFontStyles, true, wCodePage); | 124 FindFont(pszFontFamily, dwFontStyles, true, wCodePage); |
137 if (!pFD) | 125 if (!pFD) |
138 pFD = FindFont(nullptr, dwFontStyles, true, wCodePage); | 126 pFD = FindFont(nullptr, dwFontStyles, true, wCodePage); |
139 if (!pFD) | 127 if (!pFD) |
140 pFD = FindFont(nullptr, dwFontStyles, false, wCodePage); | 128 pFD = FindFont(nullptr, dwFontStyles, false, wCodePage); |
141 if (!pFD) | 129 if (!pFD) |
142 return nullptr; | 130 return nullptr; |
143 | 131 |
144 pFont = | 132 CFX_RetainPtr<CFGAS_GEFont> pFont = |
145 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); | 133 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); |
146 if (!pFont) | 134 if (!pFont) |
147 return nullptr; | 135 return nullptr; |
148 | 136 |
149 m_Fonts.Add(pFont); | 137 m_Fonts.push_back(pFont); |
150 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 138 m_CPFonts[dwHash] = pFont; |
151 dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage); | 139 dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage); |
152 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 140 m_FamilyFonts[dwHash] = pFont; |
153 return LoadFont(pFont, dwFontStyles, wCodePage); | 141 return LoadFont(pFont, dwFontStyles, wCodePage); |
154 } | 142 } |
155 | 143 |
156 CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, | 144 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode( |
157 uint32_t dwFontStyles, | 145 FX_WCHAR wUnicode, |
158 const FX_WCHAR* pszFontFamily) { | 146 uint32_t dwFontStyles, |
| 147 const FX_WCHAR* pszFontFamily) { |
159 const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode); | 148 const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode); |
160 if (pRet->wBitField == 999) | 149 if (pRet->wBitField == 999) |
161 return nullptr; | 150 return nullptr; |
162 | 151 |
163 uint32_t dwHash = | 152 uint32_t dwHash = |
164 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField); | 153 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField); |
165 CFGAS_GEFont* pFont = nullptr; | 154 auto it = m_UnicodeFonts.find(dwHash); |
166 if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) | 155 if (it != m_UnicodeFonts.end()) { |
167 return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : nullptr; | 156 return it->second ? LoadFont(it->second, dwFontStyles, pRet->wCodePage) |
168 | 157 : nullptr; |
169 FX_FONTDESCRIPTOR const* pFD = | 158 } |
| 159 const FX_FONTDESCRIPTOR* pFD = |
170 FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage, | 160 FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage, |
171 pRet->wBitField, wUnicode); | 161 pRet->wBitField, wUnicode); |
172 if (!pFD && pszFontFamily) { | 162 if (!pFD && pszFontFamily) { |
173 pFD = FindFont(nullptr, dwFontStyles, false, pRet->wCodePage, | 163 pFD = FindFont(nullptr, dwFontStyles, false, pRet->wCodePage, |
174 pRet->wBitField, wUnicode); | 164 pRet->wBitField, wUnicode); |
175 } | 165 } |
176 if (!pFD) | 166 if (!pFD) |
177 return nullptr; | 167 return nullptr; |
178 | 168 |
179 uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); | 169 uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); |
180 const FX_WCHAR* pFontFace = pFD->wsFontFace; | 170 const FX_WCHAR* pFontFace = pFD->wsFontFace; |
181 pFont = CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this); | 171 CFX_RetainPtr<CFGAS_GEFont> pFont = |
| 172 CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this); |
182 if (!pFont) | 173 if (!pFont) |
183 return nullptr; | 174 return nullptr; |
184 | 175 |
185 m_Fonts.Add(pFont); | 176 m_Fonts.push_back(pFont); |
186 m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 177 m_UnicodeFonts[dwHash] = pFont; |
187 dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); | 178 m_CPFonts[FGAS_GetFontHashCode(wCodePage, dwFontStyles)] = pFont; |
188 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 179 m_FamilyFonts[FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage)] = |
189 dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage); | 180 pFont; |
190 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | |
191 return LoadFont(pFont, dwFontStyles, wCodePage); | 181 return LoadFont(pFont, dwFontStyles, wCodePage); |
192 } | 182 } |
193 | 183 |
194 CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const FX_WCHAR* pszFontFamily, | 184 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( |
195 uint32_t dwFontStyles, | 185 const FX_WCHAR* pszFontFamily, |
196 uint16_t wCodePage) { | 186 uint32_t dwFontStyles, |
| 187 uint16_t wCodePage) { |
| 188 CFX_RetainPtr<CFGAS_GEFont> pFont; |
197 uint32_t dwHash = | 189 uint32_t dwHash = |
198 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage); | 190 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage); |
199 CFGAS_GEFont* pFont = nullptr; | 191 auto it = m_FamilyFonts.find(dwHash); |
200 if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) | 192 if (it != m_FamilyFonts.end()) |
201 return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr; | 193 return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr; |
202 FX_FONTDESCRIPTOR const* pFD = | 194 |
| 195 const FX_FONTDESCRIPTOR* pFD = |
203 FindFont(pszFontFamily, dwFontStyles, true, wCodePage); | 196 FindFont(pszFontFamily, dwFontStyles, true, wCodePage); |
204 if (!pFD) | 197 if (!pFD) |
205 pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage); | 198 pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage); |
206 if (!pFD) | 199 if (!pFD) |
207 return nullptr; | 200 return nullptr; |
208 | 201 |
209 if (wCodePage == 0xFFFF) | 202 if (wCodePage == 0xFFFF) |
210 wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); | 203 wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet); |
| 204 |
211 pFont = | 205 pFont = |
212 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); | 206 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this); |
213 if (!pFont) | 207 if (!pFont) |
214 return nullptr; | 208 return nullptr; |
215 | 209 |
216 m_Fonts.Add(pFont); | 210 m_Fonts.push_back(pFont); |
217 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 211 m_FamilyFonts[dwHash] = pFont; |
218 dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); | 212 dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); |
219 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 213 m_CPFonts[dwHash] = pFont; |
220 return LoadFont(pFont, dwFontStyles, wCodePage); | 214 return LoadFont(pFont, dwFontStyles, wCodePage); |
221 } | 215 } |
222 | 216 |
223 CFGAS_GEFont* CFGAS_FontMgr::LoadFont(CFGAS_GEFont* pSrcFont, | 217 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( |
224 uint32_t dwFontStyles, | 218 const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont, |
225 uint16_t wCodePage) { | 219 uint32_t dwFontStyles, |
226 ASSERT(pSrcFont); | 220 uint16_t wCodePage) { |
227 if (pSrcFont->GetFontStyles() == dwFontStyles) | 221 if (pSrcFont->GetFontStyles() == dwFontStyles) |
228 return pSrcFont->Retain(); | 222 return pSrcFont; |
229 void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles, | 223 |
| 224 void* buffer[3] = {pSrcFont.Get(), (void*)(uintptr_t)dwFontStyles, |
230 (void*)(uintptr_t)wCodePage}; | 225 (void*)(uintptr_t)wCodePage}; |
231 uint32_t dwHash = FX_HashCode_GetA( | 226 uint32_t dwHash = FX_HashCode_GetA( |
232 CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false); | 227 CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false); |
233 CFGAS_GEFont* pFont = nullptr; | 228 auto it = m_DeriveFonts.find(dwHash); |
234 if (m_DeriveFonts.GetCount() > 0) { | 229 if (it != m_DeriveFonts.end() && it->second) |
235 m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont); | 230 return it->second; |
236 if (pFont) | 231 |
237 return pFont->Retain(); | 232 CFX_RetainPtr<CFGAS_GEFont> pFont = pSrcFont->Derive(dwFontStyles, wCodePage); |
238 } | |
239 pFont = pSrcFont->Derive(dwFontStyles, wCodePage); | |
240 if (!pFont) | 233 if (!pFont) |
241 return nullptr; | 234 return nullptr; |
242 | 235 |
243 m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); | 236 m_DeriveFonts[dwHash] = pFont; |
244 int32_t index = m_Fonts.Find(pFont); | 237 auto iter = std::find(m_Fonts.begin(), m_Fonts.end(), pFont); |
245 if (index < 0) { | 238 if (iter == m_Fonts.end()) |
246 m_Fonts.Add(pFont); | 239 m_Fonts.push_back(pFont); |
247 pFont->Retain(); | |
248 } | |
249 return pFont; | 240 return pFont; |
250 } | 241 } |
251 | 242 |
252 void CFGAS_FontMgr::RemoveFont(CFX_MapPtrToPtr& fontMap, CFGAS_GEFont* pFont) { | 243 void CFGAS_FontMgr::RemoveFont( |
253 FX_POSITION pos = fontMap.GetStartPosition(); | 244 std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap, |
254 void* pKey; | 245 const CFX_RetainPtr<CFGAS_GEFont>& pFont) { |
255 void* pFind; | 246 auto iter = pFontMap->begin(); |
256 while (pos) { | 247 while (iter != pFontMap->end()) { |
257 pFind = nullptr; | 248 auto old_iter = iter++; |
258 fontMap.GetNextAssoc(pos, pKey, pFind); | 249 if (old_iter->second == pFont) |
259 if (pFind != (void*)pFont) | 250 pFontMap->erase(old_iter); |
260 continue; | |
261 fontMap.RemoveKey(pKey); | |
262 break; | |
263 } | 251 } |
264 } | 252 } |
265 | 253 |
266 void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pFont) { | 254 void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { |
267 RemoveFont(m_CPFonts, pFont); | 255 RemoveFont(&m_CPFonts, pFont); |
268 RemoveFont(m_FamilyFonts, pFont); | 256 RemoveFont(&m_FamilyFonts, pFont); |
269 RemoveFont(m_UnicodeFonts, pFont); | 257 RemoveFont(&m_UnicodeFonts, pFont); |
270 RemoveFont(m_BufferFonts, pFont); | 258 RemoveFont(&m_BufferFonts, pFont); |
271 RemoveFont(m_StreamFonts, pFont); | 259 RemoveFont(&m_StreamFonts, pFont); |
272 RemoveFont(m_DeriveFonts, pFont); | 260 RemoveFont(&m_DeriveFonts, pFont); |
273 int32_t iFind = m_Fonts.Find(pFont); | 261 auto it = std::find(m_Fonts.begin(), m_Fonts.end(), pFont); |
274 if (iFind > -1) | 262 if (it != m_Fonts.end()) |
275 m_Fonts.RemoveAt(iFind, 1); | 263 m_Fonts.erase(it); |
276 } | 264 } |
277 | 265 |
278 FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, | 266 FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, |
279 uint32_t dwFontStyles, | 267 uint32_t dwFontStyles, |
280 uint32_t dwMatchFlags, | 268 uint32_t dwMatchFlags, |
281 uint16_t wCodePage, | 269 uint16_t wCodePage, |
282 uint32_t dwUSB, | 270 uint32_t dwUSB, |
283 FX_WCHAR wUnicode) { | 271 FX_WCHAR wUnicode) { |
284 FX_FONTMATCHPARAMS params; | 272 FX_FONTMATCHPARAMS params; |
285 FXSYS_memset(¶ms, 0, sizeof(params)); | 273 FXSYS_memset(¶ms, 0, sizeof(params)); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 CFGAS_FontMgr::~CFGAS_FontMgr() { | 575 CFGAS_FontMgr::~CFGAS_FontMgr() { |
588 for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) | 576 for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) |
589 delete m_InstalledFonts[i]; | 577 delete m_InstalledFonts[i]; |
590 FX_POSITION pos = m_Hash2CandidateList.GetStartPosition(); | 578 FX_POSITION pos = m_Hash2CandidateList.GetStartPosition(); |
591 while (pos) { | 579 while (pos) { |
592 uint32_t dwHash; | 580 uint32_t dwHash; |
593 CFX_FontDescriptorInfos* pDescs; | 581 CFX_FontDescriptorInfos* pDescs; |
594 m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs); | 582 m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs); |
595 delete pDescs; | 583 delete pDescs; |
596 } | 584 } |
597 pos = m_Hash2Fonts.GetStartPosition(); | 585 m_Hash2Fonts.clear(); |
598 while (pos) { | |
599 uint32_t dwHash; | |
600 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts; | |
601 m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts); | |
602 for (int32_t i = 0; i < pFonts->GetSize(); i++) | |
603 delete pFonts->GetAt(i); | |
604 delete pFonts; | |
605 } | |
606 m_Hash2Fonts.RemoveAll(); | |
607 } | 586 } |
608 | 587 |
609 bool CFGAS_FontMgr::EnumFontsFromFontMapper() { | 588 bool CFGAS_FontMgr::EnumFontsFromFontMapper() { |
610 CFX_FontMapper* pFontMapper = | 589 CFX_FontMapper* pFontMapper = |
611 CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper(); | 590 CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper(); |
612 if (!pFontMapper) | 591 if (!pFontMapper) |
613 return false; | 592 return false; |
614 | 593 |
615 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); | 594 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); |
616 if (!pSystemFontInfo) | 595 if (!pSystemFontInfo) |
(...skipping 20 matching lines...) Expand all Loading... |
637 CFX_RetainPtr<IFX_FileAccess> pFontSource = m_pFontSource->GetNext(pos); | 616 CFX_RetainPtr<IFX_FileAccess> pFontSource = m_pFontSource->GetNext(pos); |
638 CFX_RetainPtr<IFX_SeekableReadStream> pFontStream = | 617 CFX_RetainPtr<IFX_SeekableReadStream> pFontStream = |
639 pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly); | 618 pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly); |
640 if (pFontStream) | 619 if (pFontStream) |
641 RegisterFaces(pFontStream, nullptr); | 620 RegisterFaces(pFontStream, nullptr); |
642 } | 621 } |
643 return m_InstalledFonts.GetSize() != 0; | 622 return m_InstalledFonts.GetSize() != 0; |
644 } | 623 } |
645 | 624 |
646 bool CFGAS_FontMgr::EnumFonts() { | 625 bool CFGAS_FontMgr::EnumFonts() { |
647 if (EnumFontsFromFontMapper()) | 626 return EnumFontsFromFontMapper() || EnumFontsFromFiles(); |
648 return true; | |
649 return EnumFontsFromFiles(); | |
650 } | 627 } |
651 | 628 |
652 CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage, | 629 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( |
653 uint32_t dwFontStyles, | 630 const FX_WCHAR* pszFontFamily, |
654 const FX_WCHAR* pszFontFamily) { | 631 uint32_t dwFontStyles, |
| 632 uint16_t wCodePage) { |
| 633 return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); |
| 634 } |
| 635 |
| 636 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( |
| 637 uint16_t wCodePage, |
| 638 uint32_t dwFontStyles, |
| 639 const FX_WCHAR* pszFontFamily) { |
655 CFX_ByteString bsHash; | 640 CFX_ByteString bsHash; |
656 bsHash.Format("%d, %d", wCodePage, dwFontStyles); | 641 bsHash.Format("%d, %d", wCodePage, dwFontStyles); |
657 bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); | 642 bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); |
658 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); | 643 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); |
659 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr; | 644 std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash]; |
660 if (m_Hash2Fonts.Lookup(dwHash, pFonts)) { | 645 if (!pFontArray->empty()) |
661 if (!pFonts) | 646 return (*pFontArray)[0]; |
662 return nullptr; | |
663 | 647 |
664 if (pFonts->GetSize() != 0) | |
665 return pFonts->GetAt(0)->Retain(); | |
666 } | |
667 | |
668 if (!pFonts) | |
669 pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>; | |
670 | |
671 m_Hash2Fonts.SetAt(dwHash, pFonts); | |
672 CFX_FontDescriptorInfos* sortedFonts = nullptr; | 648 CFX_FontDescriptorInfos* sortedFonts = nullptr; |
673 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { | 649 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { |
674 sortedFonts = new CFX_FontDescriptorInfos; | 650 sortedFonts = new CFX_FontDescriptorInfos; |
675 MatchFonts(*sortedFonts, wCodePage, dwFontStyles, | 651 MatchFonts(*sortedFonts, wCodePage, dwFontStyles, |
676 CFX_WideString(pszFontFamily), 0); | 652 CFX_WideString(pszFontFamily), 0); |
677 m_Hash2CandidateList.SetAt(dwHash, sortedFonts); | 653 m_Hash2CandidateList.SetAt(dwHash, sortedFonts); |
678 } | 654 } |
679 if (sortedFonts->GetSize() == 0) | 655 if (sortedFonts->GetSize() == 0) |
680 return nullptr; | 656 return nullptr; |
681 | 657 |
682 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont; | 658 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont; |
683 CFGAS_GEFont* pFont = | 659 CFX_RetainPtr<CFGAS_GEFont> pFont = |
684 LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); | 660 LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); |
685 if (pFont) | 661 if (!pFont) |
686 pFont->SetLogicalFontStyle(dwFontStyles); | 662 return nullptr; |
687 | 663 |
688 pFonts->Add(pFont); | 664 pFont->SetLogicalFontStyle(dwFontStyles); |
| 665 pFontArray->push_back(pFont); |
689 return pFont; | 666 return pFont; |
690 } | 667 } |
691 | 668 |
692 CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode, | 669 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode( |
693 uint32_t dwFontStyles, | 670 FX_WCHAR wUnicode, |
694 const FX_WCHAR* pszFontFamily) { | 671 uint32_t dwFontStyles, |
695 CFGAS_GEFont* pFont = nullptr; | 672 const FX_WCHAR* pszFontFamily) { |
696 if (m_FailedUnicodes2Nullptr.Lookup(wUnicode, pFont)) | 673 if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode)) |
697 return nullptr; | 674 return nullptr; |
| 675 |
698 const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode); | 676 const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode); |
699 uint16_t wCodePage = x ? x->wCodePage : 0xFFFF; | 677 uint16_t wCodePage = x ? x->wCodePage : 0xFFFF; |
700 uint16_t wBitField = x ? x->wBitField : 0x03E7; | 678 uint16_t wBitField = x ? x->wBitField : 0x03E7; |
701 CFX_ByteString bsHash; | 679 CFX_ByteString bsHash; |
702 if (wCodePage == 0xFFFF) | 680 if (wCodePage == 0xFFFF) |
703 bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles); | 681 bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles); |
704 else | 682 else |
705 bsHash.Format("%d, %d", wCodePage, dwFontStyles); | 683 bsHash.Format("%d, %d", wCodePage, dwFontStyles); |
706 bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); | 684 bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); |
707 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); | 685 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); |
708 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr; | 686 std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash]; |
709 if (m_Hash2Fonts.Lookup(dwHash, pFonts)) { | 687 for (size_t i = 0; i < pFonts->size(); ++i) { |
710 if (!pFonts) | 688 if (VerifyUnicode((*pFonts)[i], wUnicode)) |
711 return nullptr; | 689 return (*pFonts)[i]; |
712 | |
713 for (int32_t i = 0; i < pFonts->GetSize(); ++i) { | |
714 if (VerifyUnicode(pFonts->GetAt(i), wUnicode)) | |
715 return pFonts->GetAt(i)->Retain(); | |
716 } | |
717 } | 690 } |
718 if (!pFonts) | |
719 pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>; | |
720 m_Hash2Fonts.SetAt(dwHash, pFonts); | |
721 CFX_FontDescriptorInfos* sortedFonts = nullptr; | 691 CFX_FontDescriptorInfos* sortedFonts = nullptr; |
722 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { | 692 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { |
723 sortedFonts = new CFX_FontDescriptorInfos; | 693 sortedFonts = new CFX_FontDescriptorInfos; |
724 MatchFonts(*sortedFonts, wCodePage, dwFontStyles, | 694 MatchFonts(*sortedFonts, wCodePage, dwFontStyles, |
725 CFX_WideString(pszFontFamily), wUnicode); | 695 CFX_WideString(pszFontFamily), wUnicode); |
726 m_Hash2CandidateList.SetAt(dwHash, sortedFonts); | 696 m_Hash2CandidateList.SetAt(dwHash, sortedFonts); |
727 } | 697 } |
728 for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) { | 698 for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) { |
729 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont; | 699 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont; |
730 if (!VerifyUnicode(pDesc, wUnicode)) | 700 if (!VerifyUnicode(pDesc, wUnicode)) |
731 continue; | 701 continue; |
732 pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); | 702 CFX_RetainPtr<CFGAS_GEFont> pFont = |
| 703 LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr); |
733 if (!pFont) | 704 if (!pFont) |
734 continue; | 705 continue; |
735 pFont->SetLogicalFontStyle(dwFontStyles); | 706 pFont->SetLogicalFontStyle(dwFontStyles); |
736 pFonts->Add(pFont); | 707 pFonts->push_back(pFont); |
737 return pFont; | 708 return pFont; |
738 } | 709 } |
739 if (!pszFontFamily) | 710 if (!pszFontFamily) |
740 m_FailedUnicodes2Nullptr.SetAt(wUnicode, nullptr); | 711 m_FailedUnicodesSet.insert(wUnicode); |
741 return nullptr; | 712 return nullptr; |
742 } | 713 } |
743 | 714 |
744 bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc, | 715 bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc, |
745 FX_WCHAR wcUnicode) { | 716 FX_WCHAR wcUnicode) { |
746 CFX_RetainPtr<IFX_SeekableReadStream> pFileRead = | 717 CFX_RetainPtr<IFX_SeekableReadStream> pFileRead = |
747 CreateFontStream(pDesc->m_wsFaceName.UTF8Encode()); | 718 CreateFontStream(pDesc->m_wsFaceName.UTF8Encode()); |
748 if (!pFileRead) | 719 if (!pFileRead) |
749 return false; | 720 return false; |
750 | 721 |
751 FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex); | 722 FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex); |
752 FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE); | 723 FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE); |
753 FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode); | 724 FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode); |
754 if (!pFace) | 725 if (!pFace) |
755 return false; | 726 return false; |
756 | 727 |
757 if (FXFT_Get_Face_External_Stream(pFace)) | 728 if (FXFT_Get_Face_External_Stream(pFace)) |
758 FXFT_Clear_Face_External_Stream(pFace); | 729 FXFT_Clear_Face_External_Stream(pFace); |
759 | 730 |
760 FXFT_Done_Face(pFace); | 731 FXFT_Done_Face(pFace); |
761 return !retCharmap && retIndex; | 732 return !retCharmap && retIndex; |
762 } | 733 } |
763 | 734 |
764 bool CFGAS_FontMgr::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) { | 735 bool CFGAS_FontMgr::VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont, |
| 736 FX_WCHAR wcUnicode) { |
765 if (!pFont) | 737 if (!pFont) |
766 return false; | 738 return false; |
767 | 739 |
768 FXFT_Face pFace = pFont->GetDevFont()->GetFace(); | 740 FXFT_Face pFace = pFont->GetDevFont()->GetFace(); |
769 FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace); | 741 FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace); |
770 if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0) | 742 if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0) |
771 return false; | 743 return false; |
772 | 744 |
773 if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) { | 745 if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) { |
774 FXFT_Set_Charmap(pFace, charmap); | 746 FXFT_Set_Charmap(pFace, charmap); |
775 return false; | 747 return false; |
776 } | 748 } |
777 return true; | 749 return true; |
778 } | 750 } |
779 | 751 |
780 CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const CFX_WideString& wsFaceName, | 752 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont( |
781 int32_t iFaceIndex, | 753 const CFX_WideString& wsFaceName, |
782 int32_t* pFaceCount) { | 754 int32_t iFaceIndex, |
| 755 int32_t* pFaceCount) { |
783 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr(); | 756 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr(); |
784 CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper(); | 757 CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper(); |
785 if (!pFontMapper) | 758 if (!pFontMapper) |
786 return nullptr; | 759 return nullptr; |
787 | 760 |
788 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); | 761 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo(); |
789 if (!pSystemFontInfo) | 762 if (!pSystemFontInfo) |
790 return nullptr; | 763 return nullptr; |
791 | 764 |
792 CFX_RetainPtr<IFX_SeekableReadStream> pFontStream = | 765 CFX_RetainPtr<IFX_SeekableReadStream> pFontStream = |
793 CreateFontStream(wsFaceName.UTF8Encode()); | 766 CreateFontStream(wsFaceName.UTF8Encode()); |
794 if (!pFontStream) | 767 if (!pFontStream) |
795 return nullptr; | 768 return nullptr; |
796 | 769 |
797 auto pInternalFont = pdfium::MakeUnique<CFX_Font>(); | 770 auto pInternalFont = pdfium::MakeUnique<CFX_Font>(); |
798 if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) | 771 if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) |
799 return nullptr; | 772 return nullptr; |
800 | 773 |
801 CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this); | 774 CFX_RetainPtr<CFGAS_GEFont> pFont = |
| 775 CFGAS_GEFont::LoadFont(std::move(pInternalFont), this); |
802 if (!pFont) | 776 if (!pFont) |
803 return nullptr; | 777 return nullptr; |
804 | 778 |
805 m_IFXFont2FileRead[pFont] = pFontStream; | 779 m_IFXFont2FileRead[pFont] = pFontStream; |
806 if (pFaceCount) | 780 if (pFaceCount) |
807 *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces; | 781 *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces; |
808 | |
809 return pFont; | 782 return pFont; |
810 } | 783 } |
811 | 784 |
812 extern "C" { | 785 extern "C" { |
813 | 786 |
814 unsigned long _ftStreamRead(FXFT_Stream stream, | 787 unsigned long _ftStreamRead(FXFT_Stream stream, |
815 unsigned long offset, | 788 unsigned long offset, |
816 unsigned char* buffer, | 789 unsigned char* buffer, |
817 unsigned long count) { | 790 unsigned long count) { |
818 if (count == 0) | 791 if (count == 0) |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 if (wBit != static_cast<uint16_t>(999)) { | 976 if (wBit != static_cast<uint16_t>(999)) { |
1004 ASSERT(wBit < 128); | 977 ASSERT(wBit < 128); |
1005 if ((pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32))) == 0) | 978 if ((pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32))) == 0) |
1006 nPenalty += 0xFFFF; | 979 nPenalty += 0xFFFF; |
1007 else | 980 else |
1008 nPenalty -= 60000; | 981 nPenalty -= 60000; |
1009 } | 982 } |
1010 return nPenalty; | 983 return nPenalty; |
1011 } | 984 } |
1012 | 985 |
1013 void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pEFont) { | 986 void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pEFont) { |
1014 if (!pEFont) | 987 if (!pEFont) |
1015 return; | 988 return; |
1016 | 989 |
1017 m_IFXFont2FileRead.erase(pEFont); | 990 m_IFXFont2FileRead.erase(pEFont); |
1018 | 991 |
1019 FX_POSITION pos; | 992 auto iter = m_Hash2Fonts.begin(); |
1020 pos = m_Hash2Fonts.GetStartPosition(); | 993 while (iter != m_Hash2Fonts.end()) { |
1021 while (pos) { | 994 auto old_iter = iter++; |
1022 uint32_t dwHash; | 995 bool all_empty = true; |
1023 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts; | 996 for (size_t i = 0; i < old_iter->second.size(); i++) { |
1024 m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts); | 997 if (old_iter->second[i] == pEFont) |
1025 if (pFonts) { | 998 old_iter->second[i].Reset(); |
1026 for (int32_t i = 0; i < pFonts->GetSize(); i++) { | 999 else if (old_iter->second[i]) |
1027 if (pFonts->GetAt(i) == pEFont) | 1000 all_empty = false; |
1028 pFonts->SetAt(i, nullptr); | |
1029 } | |
1030 } else { | |
1031 m_Hash2Fonts.RemoveKey(dwHash); | |
1032 } | 1001 } |
| 1002 if (all_empty) |
| 1003 m_Hash2Fonts.erase(old_iter); |
1033 } | 1004 } |
1034 } | 1005 } |
1035 | 1006 |
1036 void CFGAS_FontMgr::RegisterFace(FXFT_Face pFace, | 1007 void CFGAS_FontMgr::RegisterFace(FXFT_Face pFace, |
1037 const CFX_WideString* pFaceName) { | 1008 const CFX_WideString* pFaceName) { |
1038 if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0) | 1009 if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0) |
1039 return; | 1010 return; |
1040 | 1011 |
1041 std::unique_ptr<CFX_FontDescriptor> pFont(new CFX_FontDescriptor); | 1012 std::unique_ptr<CFX_FontDescriptor> pFont(new CFX_FontDescriptor); |
1042 pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0; | 1013 pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 } | 1150 } |
1180 | 1151 |
1181 int32_t CFGAS_FontMgr::IsPartName(const CFX_WideString& Name1, | 1152 int32_t CFGAS_FontMgr::IsPartName(const CFX_WideString& Name1, |
1182 const CFX_WideString& Name2) { | 1153 const CFX_WideString& Name2) { |
1183 if (Name1.Find(Name2.c_str()) != -1) | 1154 if (Name1.Find(Name2.c_str()) != -1) |
1184 return 1; | 1155 return 1; |
1185 return 0; | 1156 return 0; |
1186 } | 1157 } |
1187 | 1158 |
1188 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1159 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
OLD | NEW |