Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: xfa/fgas/font/fgas_stdfontmgr.cpp

Issue 2494883002: Remove IFGAS_FontMgr and clean up (the renamed) CFGAS_FontMgr a little. (Closed)
Patch Set: Nits Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fgas/font/fgas_stdfontmgr.h ('k') | xfa/fgas/layout/fgas_unicode.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "xfa/fgas/font/fgas_stdfontmgr.h"
8
9 #include "core/fxcrt/fx_stream.h"
10 #include "core/fxge/cfx_fontmapper.h"
11 #include "core/fxge/cfx_fontmgr.h"
12 #include "core/fxge/cfx_gemodule.h"
13 #include "core/fxge/ifx_systemfontinfo.h"
14 #include "xfa/fgas/crt/fgas_codepage.h"
15 #include "xfa/fgas/font/fgas_fontutils.h"
16 #include "xfa/fgas/font/fgas_gefont.h"
17
18 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
19
20 std::unique_ptr<IFGAS_FontMgr> IFGAS_FontMgr::Create(
21 FX_LPEnumAllFonts pEnumerator) {
22 return std::unique_ptr<IFGAS_FontMgr>(new CFGAS_StdFontMgrImp(pEnumerator));
23 }
24
25 CFGAS_StdFontMgrImp::CFGAS_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator)
26 : m_pEnumerator(pEnumerator),
27 m_FontFaces(100),
28 m_CPFonts(8),
29 m_FamilyFonts(16),
30 m_UnicodeFonts(16),
31 m_BufferFonts(4),
32 m_StreamFonts(4),
33 m_DeriveFonts(4) {
34 if (m_pEnumerator) {
35 m_pEnumerator(m_FontFaces, nullptr, 0xFEFF);
36 }
37 }
38
39 CFGAS_StdFontMgrImp::~CFGAS_StdFontMgrImp() {
40 m_FontFaces.RemoveAll(false);
41 m_CPFonts.RemoveAll();
42 m_FamilyFonts.RemoveAll();
43 m_UnicodeFonts.RemoveAll();
44 m_BufferFonts.RemoveAll();
45 m_StreamFonts.RemoveAll();
46 m_DeriveFonts.RemoveAll();
47 for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--)
48 m_Fonts[i]->Release();
49 }
50
51 CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByCodePage(
52 uint16_t wCodePage,
53 uint32_t dwFontStyles,
54 const FX_WCHAR* pszFontFamily) {
55 uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
56 CFGAS_GEFont* pFont = nullptr;
57 if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
58 return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
59 }
60 FX_FONTDESCRIPTOR const* pFD =
61 FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
62 if (!pFD)
63 pFD = FindFont(nullptr, dwFontStyles, true, wCodePage);
64 if (!pFD)
65 pFD = FindFont(nullptr, dwFontStyles, false, wCodePage);
66 if (!pFD)
67 return nullptr;
68
69 pFont =
70 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
71 if (pFont) {
72 m_Fonts.Add(pFont);
73 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
74 dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
75 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
76 return LoadFont(pFont, dwFontStyles, wCodePage);
77 }
78 return nullptr;
79 }
80
81 CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByCharset(
82 uint8_t nCharset,
83 uint32_t dwFontStyles,
84 const FX_WCHAR* pszFontFamily) {
85 return GetDefFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
86 pszFontFamily);
87 }
88
89 CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByUnicode(
90 FX_WCHAR wUnicode,
91 uint32_t dwFontStyles,
92 const FX_WCHAR* pszFontFamily) {
93 const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode);
94 if (pRet->wBitField == 999)
95 return nullptr;
96
97 uint32_t dwHash =
98 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
99 CFGAS_GEFont* pFont = nullptr;
100 if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
101 return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : nullptr;
102
103 FX_FONTDESCRIPTOR const* pFD =
104 FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage,
105 pRet->wBitField, wUnicode);
106 if (!pFD && pszFontFamily) {
107 pFD = FindFont(nullptr, dwFontStyles, false, pRet->wCodePage,
108 pRet->wBitField, wUnicode);
109 }
110 if (!pFD)
111 return nullptr;
112
113 uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
114 const FX_WCHAR* pFontFace = pFD->wsFontFace;
115 pFont = CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
116 if (pFont) {
117 m_Fonts.Add(pFont);
118 m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
119 dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
120 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
121 dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
122 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
123 return LoadFont(pFont, dwFontStyles, wCodePage);
124 }
125 return nullptr;
126 }
127
128 CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByLanguage(
129 uint16_t wLanguage,
130 uint32_t dwFontStyles,
131 const FX_WCHAR* pszFontFamily) {
132 return GetDefFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage),
133 dwFontStyles, pszFontFamily);
134 }
135
136 CFGAS_GEFont* CFGAS_StdFontMgrImp::LoadFont(const FX_WCHAR* pszFontFamily,
137 uint32_t dwFontStyles,
138 uint16_t wCodePage) {
139 uint32_t dwHash =
140 FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
141 CFGAS_GEFont* pFont = nullptr;
142 if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
143 return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
144 }
145 FX_FONTDESCRIPTOR const* pFD =
146 FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
147 if (!pFD)
148 pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage);
149 if (!pFD)
150 return nullptr;
151
152 if (wCodePage == 0xFFFF) {
153 wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
154 }
155 pFont =
156 CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
157 if (pFont) {
158 m_Fonts.Add(pFont);
159 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
160 dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
161 m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
162 return LoadFont(pFont, dwFontStyles, wCodePage);
163 }
164 return nullptr;
165 }
166
167 CFGAS_GEFont* CFGAS_StdFontMgrImp::LoadFont(const uint8_t* pBuffer,
168 int32_t iLength) {
169 ASSERT(pBuffer && iLength > 0);
170 CFGAS_GEFont* pFont = nullptr;
171 if (m_BufferFonts.Lookup((void*)pBuffer, (void*&)pFont)) {
172 if (pFont) {
173 return pFont->Retain();
174 }
175 }
176 pFont = CFGAS_GEFont::LoadFont(pBuffer, iLength, this);
177 if (pFont) {
178 m_Fonts.Add(pFont);
179 m_BufferFonts.SetAt((void*)pBuffer, pFont);
180 return pFont->Retain();
181 }
182 return nullptr;
183 }
184
185 CFGAS_GEFont* CFGAS_StdFontMgrImp::LoadFont(IFX_Stream* pFontStream,
186 const FX_WCHAR* pszFontAlias,
187 uint32_t dwFontStyles,
188 uint16_t wCodePage,
189 bool bSaveStream) {
190 ASSERT(pFontStream && pFontStream->GetLength() > 0);
191 CFGAS_GEFont* pFont = nullptr;
192 if (m_StreamFonts.Lookup((void*)pFontStream, (void*&)pFont)) {
193 if (pFont) {
194 if (pszFontAlias) {
195 uint32_t dwHash =
196 FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
197 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
198 }
199 return LoadFont(pFont, dwFontStyles, wCodePage);
200 }
201 }
202 pFont = CFGAS_GEFont::LoadFont(pFontStream, this, bSaveStream);
203 if (pFont) {
204 m_Fonts.Add(pFont);
205 m_StreamFonts.SetAt((void*)pFontStream, (void*)pFont);
206 if (pszFontAlias) {
207 uint32_t dwHash =
208 FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
209 m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
210 }
211 return LoadFont(pFont, dwFontStyles, wCodePage);
212 }
213 return nullptr;
214 }
215
216 CFGAS_GEFont* CFGAS_StdFontMgrImp::LoadFont(CFGAS_GEFont* pSrcFont,
217 uint32_t dwFontStyles,
218 uint16_t wCodePage) {
219 ASSERT(pSrcFont);
220 if (pSrcFont->GetFontStyles() == dwFontStyles) {
221 return pSrcFont->Retain();
222 }
223 void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles,
224 (void*)(uintptr_t)wCodePage};
225 uint32_t dwHash = FX_HashCode_GetA(
226 CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false);
227 CFGAS_GEFont* pFont = nullptr;
228 if (m_DeriveFonts.GetCount() > 0) {
229 m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont);
230 if (pFont) {
231 return pFont->Retain();
232 }
233 }
234 pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
235 if (pFont) {
236 m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
237 int32_t index = m_Fonts.Find(pFont);
238 if (index < 0) {
239 m_Fonts.Add(pFont);
240 pFont->Retain();
241 }
242 return pFont;
243 }
244 return nullptr;
245 }
246
247 void CFGAS_StdFontMgrImp::ClearFontCache() {
248 for (int32_t i = 0; i < m_Fonts.GetSize(); i++)
249 m_Fonts[i]->Reset();
250 }
251
252 void CFGAS_StdFontMgrImp::RemoveFont(CFX_MapPtrToPtr& fontMap,
253 CFGAS_GEFont* pFont) {
254 FX_POSITION pos = fontMap.GetStartPosition();
255 void* pKey;
256 void* pFind;
257 while (pos) {
258 pFind = nullptr;
259 fontMap.GetNextAssoc(pos, pKey, pFind);
260 if (pFind != (void*)pFont) {
261 continue;
262 }
263 fontMap.RemoveKey(pKey);
264 break;
265 }
266 }
267
268 void CFGAS_StdFontMgrImp::RemoveFont(CFGAS_GEFont* pFont) {
269 RemoveFont(m_CPFonts, pFont);
270 RemoveFont(m_FamilyFonts, pFont);
271 RemoveFont(m_UnicodeFonts, pFont);
272 RemoveFont(m_BufferFonts, pFont);
273 RemoveFont(m_StreamFonts, pFont);
274 RemoveFont(m_DeriveFonts, pFont);
275 int32_t iFind = m_Fonts.Find(pFont);
276 if (iFind > -1) {
277 m_Fonts.RemoveAt(iFind, 1);
278 }
279 }
280
281 FX_FONTDESCRIPTOR const* CFGAS_StdFontMgrImp::FindFont(
282 const FX_WCHAR* pszFontFamily,
283 uint32_t dwFontStyles,
284 uint32_t dwMatchFlags,
285 uint16_t wCodePage,
286 uint32_t dwUSB,
287 FX_WCHAR wUnicode) {
288 FX_FONTMATCHPARAMS params;
289 FXSYS_memset(&params, 0, sizeof(params));
290 params.dwUSB = dwUSB;
291 params.wUnicode = wUnicode;
292 params.wCodePage = wCodePage;
293 params.pwsFamily = pszFontFamily;
294 params.dwFontStyles = dwFontStyles;
295 params.dwMatchFlags = dwMatchFlags;
296 FX_FONTDESCRIPTOR const* pDesc = FX_DefFontMatcher(&params, m_FontFaces);
297 if (pDesc) {
298 return pDesc;
299 }
300 if (pszFontFamily && m_pEnumerator) {
301 CFX_FontDescriptors namedFonts(100);
302 m_pEnumerator(namedFonts, pszFontFamily, wUnicode);
303 params.pwsFamily = nullptr;
304 pDesc = FX_DefFontMatcher(&params, namedFonts);
305 if (!pDesc) {
306 return nullptr;
307 }
308 for (int32_t i = m_FontFaces.GetSize() - 1; i >= 0; i--) {
309 FX_FONTDESCRIPTOR const* pMatch = m_FontFaces.GetPtrAt(i);
310 if (*pMatch == *pDesc) {
311 return pMatch;
312 }
313 }
314 int index = m_FontFaces.Add(*pDesc);
315 return m_FontFaces.GetPtrAt(index);
316 }
317 return nullptr;
318 }
319
320 FX_FONTDESCRIPTOR const* FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams,
321 const CFX_FontDescriptors& fonts) {
322 FX_FONTDESCRIPTOR const* pBestFont = nullptr;
323 int32_t iBestSimilar = 0;
324 bool bMatchStyle = (pParams->dwMatchFlags & FX_FONTMATCHPARA_MacthStyle) > 0;
325 int32_t iCount = fonts.GetSize();
326 for (int32_t i = 0; i < iCount; ++i) {
327 FX_FONTDESCRIPTOR const* pFont = fonts.GetPtrAt(i);
328 if ((pFont->dwFontStyles & FX_FONTSTYLE_BoldItalic) ==
329 FX_FONTSTYLE_BoldItalic) {
330 continue;
331 }
332 if (pParams->pwsFamily) {
333 if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace)) {
334 continue;
335 }
336 if (pFont->uCharSet == FX_CHARSET_Symbol) {
337 return pFont;
338 }
339 }
340 if (pFont->uCharSet == FX_CHARSET_Symbol) {
341 continue;
342 }
343 if (pParams->wCodePage != 0xFFFF) {
344 if (FX_GetCodePageFromCharset(pFont->uCharSet) != pParams->wCodePage) {
345 continue;
346 }
347 } else {
348 if (pParams->dwUSB < 128) {
349 uint32_t dwByte = pParams->dwUSB / 32;
350 uint32_t dwUSB = 1 << (pParams->dwUSB % 32);
351 if ((pFont->FontSignature.fsUsb[dwByte] & dwUSB) == 0) {
352 continue;
353 }
354 }
355 }
356 if (bMatchStyle) {
357 if ((pFont->dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F))
358 return pFont;
359 continue;
360 }
361 if (pParams->pwsFamily) {
362 if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace) == 0) {
363 return pFont;
364 }
365 }
366 int32_t iSimilarValue = FX_GetSimilarValue(pFont, pParams->dwFontStyles);
367 if (iBestSimilar < iSimilarValue) {
368 iBestSimilar = iSimilarValue;
369 pBestFont = pFont;
370 }
371 }
372 return iBestSimilar < 1 ? nullptr : pBestFont;
373 }
374
375 int32_t FX_GetSimilarValue(FX_FONTDESCRIPTOR const* pFont,
376 uint32_t dwFontStyles) {
377 int32_t iValue = 0;
378 if ((dwFontStyles & FX_FONTSTYLE_Symbolic) ==
379 (pFont->dwFontStyles & FX_FONTSTYLE_Symbolic)) {
380 iValue += 64;
381 }
382 if ((dwFontStyles & FX_FONTSTYLE_FixedPitch) ==
383 (pFont->dwFontStyles & FX_FONTSTYLE_FixedPitch)) {
384 iValue += 32;
385 }
386 if ((dwFontStyles & FX_FONTSTYLE_Serif) ==
387 (pFont->dwFontStyles & FX_FONTSTYLE_Serif)) {
388 iValue += 16;
389 }
390 if ((dwFontStyles & FX_FONTSTYLE_Script) ==
391 (pFont->dwFontStyles & FX_FONTSTYLE_Script)) {
392 iValue += 8;
393 }
394 return iValue;
395 }
396
397 FX_LPMatchFont FX_GetDefFontMatchor() {
398 return FX_DefFontMatcher;
399 }
400
401 uint32_t FX_GetGdiFontStyles(const LOGFONTW& lf) {
402 uint32_t dwStyles = 0;
403 if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH) {
404 dwStyles |= FX_FONTSTYLE_FixedPitch;
405 }
406 uint8_t nFamilies = lf.lfPitchAndFamily & 0xF0;
407 if (nFamilies == FF_ROMAN) {
408 dwStyles |= FX_FONTSTYLE_Serif;
409 }
410 if (nFamilies == FF_SCRIPT) {
411 dwStyles |= FX_FONTSTYLE_Script;
412 }
413 if (lf.lfCharSet == SYMBOL_CHARSET) {
414 dwStyles |= FX_FONTSTYLE_Symbolic;
415 }
416 return dwStyles;
417 }
418
419 static int32_t CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX* lpelfe,
420 NEWTEXTMETRICEX* lpntme,
421 DWORD dwFontType,
422 LPARAM lParam) {
423 if (dwFontType != TRUETYPE_FONTTYPE) {
424 return 1;
425 }
426 const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
427 if (lf.lfFaceName[0] == L'@') {
428 return 1;
429 }
430 FX_FONTDESCRIPTOR* pFont = FX_Alloc(FX_FONTDESCRIPTOR, 1);
431 FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR));
432 pFont->uCharSet = lf.lfCharSet;
433 pFont->dwFontStyles = FX_GetGdiFontStyles(lf);
434 FXSYS_wcsncpy(pFont->wsFontFace, (const FX_WCHAR*)lf.lfFaceName, 31);
435 pFont->wsFontFace[31] = 0;
436 FXSYS_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig,
437 sizeof(lpntme->ntmFontSig));
438 ((CFX_FontDescriptors*)lParam)->Add(*pFont);
439 FX_Free(pFont);
440 return 1;
441 }
442
443 static void FX_EnumGdiFonts(CFX_FontDescriptors& fonts,
444 const FX_WCHAR* pwsFaceName,
445 FX_WCHAR wUnicode) {
446 HDC hDC = ::GetDC(nullptr);
447 LOGFONTW lfFind;
448 FXSYS_memset(&lfFind, 0, sizeof(lfFind));
449 lfFind.lfCharSet = DEFAULT_CHARSET;
450 if (pwsFaceName) {
451 FXSYS_wcsncpy(lfFind.lfFaceName, pwsFaceName, 31);
452 lfFind.lfFaceName[31] = 0;
453 }
454 EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind,
455 (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)&fonts, 0);
456 ::ReleaseDC(nullptr, hDC);
457 }
458
459 FX_LPEnumAllFonts FX_GetDefFontEnumerator() {
460 return FX_EnumGdiFonts;
461 }
462
463 #else
464 const FX_CHAR* g_FontFolders[] = {
465 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
466 "/usr/share/fonts", "/usr/share/X11/fonts/Type1",
467 "/usr/share/X11/fonts/TTF", "/usr/local/share/fonts",
468 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
469 "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts",
470 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
471 "/system/fonts",
472 #endif
473 };
474
475 CFX_FontDescriptor::CFX_FontDescriptor()
476 : m_nFaceIndex(0), m_dwFontStyles(0), m_dwUsb(), m_dwCsb() {}
477
478 CFX_FontDescriptor::~CFX_FontDescriptor() {}
479
480 CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
481 for (size_t i = 0; i < FX_ArraySize(g_FontFolders); ++i)
482 m_FolderPaths.Add(g_FontFolders[i]);
483 }
484
485 CFX_FontSourceEnum_File::~CFX_FontSourceEnum_File() {}
486
487 CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() {
488 FX_FileHandle* pCurHandle =
489 m_FolderQueue.GetSize() != 0
490 ? m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle
491 : nullptr;
492 if (!pCurHandle) {
493 if (m_FolderPaths.GetSize() < 1)
494 return "";
495 pCurHandle =
496 FX_OpenFolder(m_FolderPaths[m_FolderPaths.GetSize() - 1].c_str());
497 FX_HandleParentPath hpp;
498 hpp.pFileHandle = pCurHandle;
499 hpp.bsParentPath = m_FolderPaths[m_FolderPaths.GetSize() - 1];
500 m_FolderQueue.Add(hpp);
501 }
502 CFX_ByteString bsName;
503 bool bFolder;
504 CFX_ByteString bsFolderSpearator =
505 CFX_ByteString::FromUnicode(CFX_WideString(FX_GetFolderSeparator()));
506 while (true) {
507 if (!FX_GetNextFile(pCurHandle, &bsName, &bFolder)) {
508 FX_CloseFolder(pCurHandle);
509 m_FolderQueue.RemoveAt(m_FolderQueue.GetSize() - 1);
510 if (m_FolderQueue.GetSize() == 0) {
511 m_FolderPaths.RemoveAt(m_FolderPaths.GetSize() - 1);
512 return m_FolderPaths.GetSize() != 0 ? GetNextFile() : "";
513 }
514 pCurHandle =
515 m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
516 continue;
517 }
518 if (bsName == "." || bsName == "..")
519 continue;
520 if (bFolder) {
521 FX_HandleParentPath hpp;
522 hpp.bsParentPath =
523 m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
524 bsFolderSpearator + bsName;
525 hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath.c_str());
526 if (!hpp.pFileHandle)
527 continue;
528 m_FolderQueue.Add(hpp);
529 pCurHandle = hpp.pFileHandle;
530 continue;
531 }
532 bsName =
533 m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
534 bsFolderSpearator + bsName;
535 break;
536 }
537 return bsName;
538 }
539
540 FX_POSITION CFX_FontSourceEnum_File::GetStartPosition() {
541 m_wsNext = GetNextFile().UTF8Decode();
542 if (m_wsNext.GetLength() == 0) {
543 return (FX_POSITION)0;
544 }
545 return (FX_POSITION)-1;
546 }
547
548 IFX_FileAccess* CFX_FontSourceEnum_File::GetNext(FX_POSITION& pos) {
549 IFX_FileAccess* pAccess = FX_CreateDefaultFileAccess(m_wsNext.AsStringC());
550 m_wsNext = GetNextFile().UTF8Decode();
551 pos = m_wsNext.GetLength() != 0 ? pAccess : nullptr;
552 return pAccess;
553 }
554
555 std::unique_ptr<IFGAS_FontMgr> IFGAS_FontMgr::Create(
556 CFX_FontSourceEnum_File* pFontEnum) {
557 if (!pFontEnum)
558 return nullptr;
559
560 std::unique_ptr<CFGAS_FontMgrImp> pFontMgr(new CFGAS_FontMgrImp(pFontEnum));
561 if (!pFontMgr->EnumFonts())
562 return nullptr;
563 return std::move(pFontMgr);
564 }
565
566 CFGAS_FontMgrImp::CFGAS_FontMgrImp(CFX_FontSourceEnum_File* pFontEnum)
567 : m_pFontSource(pFontEnum) {}
568
569 CFGAS_FontMgrImp::~CFGAS_FontMgrImp() {
570 for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) {
571 delete m_InstalledFonts[i];
572 }
573 FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
574 while (pos) {
575 uint32_t dwHash;
576 CFX_FontDescriptorInfos* pDescs;
577 m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
578 delete pDescs;
579 }
580 pos = m_Hash2Fonts.GetStartPosition();
581 while (pos) {
582 uint32_t dwHash;
583 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts;
584 m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
585 for (int32_t i = 0; i < pFonts->GetSize(); i++)
586 delete pFonts->GetAt(i);
587 delete pFonts;
588 }
589 m_Hash2Fonts.RemoveAll();
590 pos = m_IFXFont2FileRead.GetStartPosition();
591 while (pos) {
592 CFGAS_GEFont* pFont;
593 IFX_SeekableReadStream* pFileRead;
594 m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
595 pFileRead->Release();
596 }
597 }
598
599 bool CFGAS_FontMgrImp::EnumFontsFromFontMapper() {
600 CFX_FontMapper* pFontMapper =
601 CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
602 if (!pFontMapper)
603 return false;
604
605 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
606 if (!pSystemFontInfo)
607 return false;
608
609 pSystemFontInfo->EnumFontList(pFontMapper);
610 for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
611 IFX_SeekableReadStream* pFontStream =
612 CreateFontStream(pFontMapper, pSystemFontInfo, i);
613 if (!pFontStream)
614 continue;
615
616 CFX_WideString wsFaceName =
617 CFX_WideString::FromLocal(pFontMapper->GetFaceName(i).c_str());
618 RegisterFaces(pFontStream, &wsFaceName);
619 pFontStream->Release();
620 }
621 if (m_InstalledFonts.GetSize() == 0)
622 return false;
623
624 return true;
625 }
626
627 bool CFGAS_FontMgrImp::EnumFontsFromFiles() {
628 CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
629 FX_POSITION pos = m_pFontSource->GetStartPosition();
630 IFX_FileAccess* pFontSource = nullptr;
631 IFX_SeekableReadStream* pFontStream = nullptr;
632 while (pos) {
633 pFontSource = m_pFontSource->GetNext(pos);
634 pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
635 if (!pFontStream) {
636 pFontSource->Release();
637 continue;
638 }
639 RegisterFaces(pFontStream, nullptr);
640 pFontStream->Release();
641 pFontSource->Release();
642 }
643 if (m_InstalledFonts.GetSize() == 0)
644 return false;
645 return true;
646 }
647
648 bool CFGAS_FontMgrImp::EnumFonts() {
649 if (EnumFontsFromFontMapper())
650 return true;
651 return EnumFontsFromFiles();
652 }
653
654 CFGAS_GEFont* CFGAS_FontMgrImp::GetDefFontByCodePage(
655 uint16_t wCodePage,
656 uint32_t dwFontStyles,
657 const FX_WCHAR* pszFontFamily) {
658 return nullptr;
659 }
660
661 CFGAS_GEFont* CFGAS_FontMgrImp::GetDefFontByCharset(
662 uint8_t nCharset,
663 uint32_t dwFontStyles,
664 const FX_WCHAR* pszFontFamily) {
665 return nullptr;
666 }
667
668 CFGAS_GEFont* CFGAS_FontMgrImp::GetDefFontByUnicode(
669 FX_WCHAR wUnicode,
670 uint32_t dwFontStyles,
671 const FX_WCHAR* pszFontFamily) {
672 return nullptr;
673 }
674
675 CFGAS_GEFont* CFGAS_FontMgrImp::GetDefFontByLanguage(
676 uint16_t wLanguage,
677 uint32_t dwFontStyles,
678 const FX_WCHAR* pszFontFamily) {
679 return nullptr;
680 }
681
682 CFGAS_GEFont* CFGAS_FontMgrImp::GetFontByCodePage(
683 uint16_t wCodePage,
684 uint32_t dwFontStyles,
685 const FX_WCHAR* pszFontFamily) {
686 CFX_ByteString bsHash;
687 bsHash.Format("%d, %d", wCodePage, dwFontStyles);
688 bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
689 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
690 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
691 if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
692 if (!pFonts)
693 return nullptr;
694
695 if (pFonts->GetSize() != 0)
696 return pFonts->GetAt(0)->Retain();
697 }
698
699 if (!pFonts)
700 pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;
701
702 m_Hash2Fonts.SetAt(dwHash, pFonts);
703 CFX_FontDescriptorInfos* sortedFonts = nullptr;
704 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
705 sortedFonts = new CFX_FontDescriptorInfos;
706 MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
707 CFX_WideString(pszFontFamily), 0);
708 m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
709 }
710 if (sortedFonts->GetSize() == 0)
711 return nullptr;
712
713 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
714 CFGAS_GEFont* pFont =
715 LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
716 if (pFont)
717 pFont->SetLogicalFontStyle(dwFontStyles);
718
719 pFonts->Add(pFont);
720 return pFont;
721 }
722
723 CFGAS_GEFont* CFGAS_FontMgrImp::GetFontByCharset(
724 uint8_t nCharset,
725 uint32_t dwFontStyles,
726 const FX_WCHAR* pszFontFamily) {
727 return GetFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
728 pszFontFamily);
729 }
730
731 CFGAS_GEFont* CFGAS_FontMgrImp::GetFontByUnicode(
732 FX_WCHAR wUnicode,
733 uint32_t dwFontStyles,
734 const FX_WCHAR* pszFontFamily) {
735 CFGAS_GEFont* pFont = nullptr;
736 if (m_FailedUnicodes2Nullptr.Lookup(wUnicode, pFont))
737 return nullptr;
738 const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
739 uint16_t wCodePage = x ? x->wCodePage : 0xFFFF;
740 uint16_t wBitField = x ? x->wBitField : 0x03E7;
741 CFX_ByteString bsHash;
742 if (wCodePage == 0xFFFF)
743 bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
744 else
745 bsHash.Format("%d, %d", wCodePage, dwFontStyles);
746 bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
747 uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
748 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
749 if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
750 if (!pFonts)
751 return nullptr;
752 for (int32_t i = 0; i < pFonts->GetSize(); ++i) {
753 if (VerifyUnicode(pFonts->GetAt(i), wUnicode))
754 return pFonts->GetAt(i)->Retain();
755 }
756 }
757 if (!pFonts)
758 pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;
759 m_Hash2Fonts.SetAt(dwHash, pFonts);
760 CFX_FontDescriptorInfos* sortedFonts = nullptr;
761 if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
762 sortedFonts = new CFX_FontDescriptorInfos;
763 MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
764 CFX_WideString(pszFontFamily), wUnicode);
765 m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
766 }
767 for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) {
768 CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
769 if (!VerifyUnicode(pDesc, wUnicode))
770 continue;
771 pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
772 if (!pFont)
773 continue;
774 pFont->SetLogicalFontStyle(dwFontStyles);
775 pFonts->Add(pFont);
776 return pFont;
777 }
778 if (!pszFontFamily)
779 m_FailedUnicodes2Nullptr.SetAt(wUnicode, nullptr);
780 return nullptr;
781 }
782
783 bool CFGAS_FontMgrImp::VerifyUnicode(CFX_FontDescriptor* pDesc,
784 FX_WCHAR wcUnicode) {
785 IFX_SeekableReadStream* pFileRead =
786 CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
787 if (!pFileRead)
788 return false;
789 FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
790 FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
791 FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
792 pFileRead->Release();
793 if (!pFace)
794 return false;
795 if (FXFT_Get_Face_External_Stream(pFace))
796 FXFT_Clear_Face_External_Stream(pFace);
797 FXFT_Done_Face(pFace);
798 return !retCharmap && retIndex;
799 }
800
801 bool CFGAS_FontMgrImp::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) {
802 if (!pFont)
803 return false;
804
805 FXFT_Face pFace = pFont->GetDevFont()->GetFace();
806 FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
807 if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
808 return false;
809
810 if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
811 FXFT_Set_Charmap(pFace, charmap);
812 return false;
813 }
814 return true;
815 }
816
817 CFGAS_GEFont* CFGAS_FontMgrImp::GetFontByLanguage(
818 uint16_t wLanguage,
819 uint32_t dwFontStyles,
820 const FX_WCHAR* pszFontFamily) {
821 return GetFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles,
822 pszFontFamily);
823 }
824
825 CFGAS_GEFont* CFGAS_FontMgrImp::LoadFont(const CFX_WideString& wsFaceName,
826 int32_t iFaceIndex,
827 int32_t* pFaceCount) {
828 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
829 CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
830 if (!pFontMapper)
831 return nullptr;
832
833 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
834 if (!pSystemFontInfo)
835 return nullptr;
836
837 IFX_SeekableReadStream* pFontStream =
838 CreateFontStream(wsFaceName.UTF8Encode());
839 if (!pFontStream)
840 return nullptr;
841
842 std::unique_ptr<CFX_Font> pInternalFont(new CFX_Font());
843 if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
844 pFontStream->Release();
845 return nullptr;
846 }
847
848 CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
849 if (!pFont) {
850 pFontStream->Release();
851 return nullptr;
852 }
853
854 m_IFXFont2FileRead.SetAt(pFont, pFontStream);
855 if (pFaceCount)
856 *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;
857
858 return pFont;
859 }
860
861 extern "C" {
862
863 unsigned long _ftStreamRead(FXFT_Stream stream,
864 unsigned long offset,
865 unsigned char* buffer,
866 unsigned long count) {
867 if (count == 0)
868 return 0;
869
870 IFX_SeekableReadStream* pFile =
871 (IFX_SeekableReadStream*)stream->descriptor.pointer;
872 int res = pFile->ReadBlock(buffer, offset, count);
873 if (res)
874 return count;
875 return 0;
876 }
877
878 void _ftStreamClose(FXFT_Stream stream) {}
879
880 }; // extern "C"
881
882 FXFT_Face CFGAS_FontMgrImp::LoadFace(IFX_SeekableReadStream* pFontStream,
883 int32_t iFaceIndex) {
884 if (!pFontStream)
885 return nullptr;
886
887 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
888 pFontMgr->InitFTLibrary();
889 FXFT_Library library = pFontMgr->GetFTLibrary();
890 if (!library)
891 return nullptr;
892
893 FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
894 FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
895 ftStream->base = nullptr;
896 ftStream->descriptor.pointer = pFontStream;
897 ftStream->pos = 0;
898 ftStream->size = (unsigned long)pFontStream->GetSize();
899 ftStream->read = _ftStreamRead;
900 ftStream->close = _ftStreamClose;
901
902 FXFT_Open_Args ftArgs;
903 FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args));
904 ftArgs.flags |= FT_OPEN_STREAM;
905 ftArgs.stream = ftStream;
906
907 FXFT_Face pFace = nullptr;
908 if (FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) {
909 FX_Free(ftStream);
910 return nullptr;
911 }
912
913 FXFT_Set_Pixel_Sizes(pFace, 0, 64);
914 return pFace;
915 }
916
917 IFX_SeekableReadStream* CFGAS_FontMgrImp::CreateFontStream(
918 CFX_FontMapper* pFontMapper,
919 IFX_SystemFontInfo* pSystemFontInfo,
920 uint32_t index) {
921 int iExact = 0;
922 void* hFont =
923 pSystemFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0,
924 pFontMapper->GetFaceName(index).c_str(), iExact);
925 if (!hFont)
926 return nullptr;
927
928 uint32_t dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
929 if (dwFileSize == 0)
930 return nullptr;
931
932 uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1);
933 dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize);
934
935 return FX_CreateMemoryStream(pBuffer, dwFileSize, true);
936 }
937
938 IFX_SeekableReadStream* CFGAS_FontMgrImp::CreateFontStream(
939 const CFX_ByteString& bsFaceName) {
940 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
941 CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
942
943 if (!pFontMapper)
944 return nullptr;
945
946 IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
947 if (!pSystemFontInfo)
948 return nullptr;
949
950 pSystemFontInfo->EnumFontList(pFontMapper);
951 for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
952 if (pFontMapper->GetFaceName(i) == bsFaceName)
953 return CreateFontStream(pFontMapper, pSystemFontInfo, i);
954 }
955 return nullptr;
956 }
957
958 int32_t CFGAS_FontMgrImp::MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
959 uint16_t wCodePage,
960 uint32_t dwFontStyles,
961 const CFX_WideString& FontName,
962 FX_WCHAR wcUnicode) {
963 MatchedFonts.RemoveAll();
964 CFX_WideString wsNormalizedFontName = FontName;
965
966 CFX_FontDescriptor* pFont = nullptr;
967 int32_t nCount = m_InstalledFonts.GetSize();
968 for (int32_t i = 0; i < nCount; i++) {
969 pFont = m_InstalledFonts[i];
970 int32_t nPenalty = CalcPenalty(pFont, wCodePage, dwFontStyles,
971 wsNormalizedFontName, wcUnicode);
972 if (nPenalty >= 0xffff)
973 continue;
974
975 FX_FontDescriptorInfo FontInfo;
976 FontInfo.pFont = pFont;
977 FontInfo.nPenalty = nPenalty;
978 MatchedFonts.Add(FontInfo);
979 if (MatchedFonts.GetSize() == 0xffff)
980 break;
981 }
982 if (MatchedFonts.GetSize() == 0)
983 return 0;
984
985 CFX_SSortTemplate<FX_FontDescriptorInfo> ssort;
986 ssort.ShellSort(MatchedFonts.GetData(), MatchedFonts.GetSize());
987 return MatchedFonts.GetSize();
988 }
989
990 struct FX_BitCodePage {
991 uint16_t wBit;
992 uint16_t wCodePage;
993 };
994 static const FX_BitCodePage g_Bit2CodePage[] = {
995 {0, 1252}, {1, 1250}, {2, 1251}, {3, 1253}, {4, 1254}, {5, 1255},
996 {6, 1256}, {7, 1257}, {8, 1258}, {9, 0}, {10, 0}, {11, 0},
997 {12, 0}, {13, 0}, {14, 0}, {15, 0}, {16, 874}, {17, 932},
998 {18, 936}, {19, 949}, {20, 950}, {21, 1361}, {22, 0}, {23, 0},
999 {24, 0}, {25, 0}, {26, 0}, {27, 0}, {28, 0}, {29, 0},
1000 {30, 0}, {31, 0}, {32, 0}, {33, 0}, {34, 0}, {35, 0},
1001 {36, 0}, {37, 0}, {38, 0}, {39, 0}, {40, 0}, {41, 0},
1002 {42, 0}, {43, 0}, {44, 0}, {45, 0}, {46, 0}, {47, 0},
1003 {48, 869}, {49, 866}, {50, 865}, {51, 864}, {52, 863}, {53, 862},
1004 {54, 861}, {55, 860}, {56, 857}, {57, 855}, {58, 852}, {59, 775},
1005 {60, 737}, {61, 708}, {62, 850}, {63, 437},
1006 };
1007
1008 uint16_t FX_GetCodePageBit(uint16_t wCodePage) {
1009 for (size_t i = 0; i < FX_ArraySize(g_Bit2CodePage); ++i) {
1010 if (g_Bit2CodePage[i].wCodePage == wCodePage)
1011 return g_Bit2CodePage[i].wBit;
1012 }
1013 return (uint16_t)-1;
1014 }
1015
1016 uint16_t FX_GetUnicodeBit(FX_WCHAR wcUnicode) {
1017 const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wcUnicode);
1018 return x ? x->wBitField : 999;
1019 }
1020
1021 int32_t CFGAS_FontMgrImp::CalcPenalty(CFX_FontDescriptor* pInstalled,
1022 uint16_t wCodePage,
1023 uint32_t dwFontStyles,
1024 const CFX_WideString& FontName,
1025 FX_WCHAR wcUnicode) {
1026 int32_t nPenalty = 30000;
1027 if (0 != FontName.GetLength()) {
1028 if (FontName != pInstalled->m_wsFaceName) {
1029 int32_t i;
1030 for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
1031 if (pInstalled->m_wsFamilyNames[i] == FontName) {
1032 break;
1033 }
1034 }
1035 if (i == pInstalled->m_wsFamilyNames.GetSize()) {
1036 nPenalty += 0xFFFF;
1037 } else {
1038 nPenalty -= 28000;
1039 }
1040 } else {
1041 nPenalty -= 30000;
1042 }
1043 if (30000 == nPenalty &&
1044 0 == IsPartName(pInstalled->m_wsFaceName, FontName)) {
1045 int32_t i;
1046 for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
1047 if (0 != IsPartName(pInstalled->m_wsFamilyNames[i], FontName)) {
1048 break;
1049 }
1050 }
1051 if (i == pInstalled->m_wsFamilyNames.GetSize()) {
1052 nPenalty += 0xFFFF;
1053 } else {
1054 nPenalty -= 26000;
1055 }
1056 } else {
1057 nPenalty -= 27000;
1058 }
1059 }
1060 uint32_t dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
1061 if (dwStyleMask & FX_FONTSTYLE_Bold) {
1062 nPenalty += 4500;
1063 }
1064 if (dwStyleMask & FX_FONTSTYLE_FixedPitch) {
1065 nPenalty += 10000;
1066 }
1067 if (dwStyleMask & FX_FONTSTYLE_Italic) {
1068 nPenalty += 10000;
1069 }
1070 if (dwStyleMask & FX_FONTSTYLE_Serif) {
1071 nPenalty += 500;
1072 }
1073 if (dwStyleMask & FX_FONTSTYLE_Symbolic) {
1074 nPenalty += 0xFFFF;
1075 }
1076 if (nPenalty >= 0xFFFF) {
1077 return 0xFFFF;
1078 }
1079 uint16_t wBit =
1080 ((0 == wCodePage || 0xFFFF == wCodePage) ? (uint16_t)-1
1081 : FX_GetCodePageBit(wCodePage));
1082 if (wBit != (uint16_t)-1) {
1083 ASSERT(wBit < 64);
1084 if (0 == (pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32)))) {
1085 nPenalty += 0xFFFF;
1086 } else {
1087 nPenalty -= 60000;
1088 }
1089 }
1090 wBit =
1091 ((0 == wcUnicode || 0xFFFE == wcUnicode) ? (uint16_t)999
1092 : FX_GetUnicodeBit(wcUnicode));
1093 if (wBit != (uint16_t)999) {
1094 ASSERT(wBit < 128);
1095 if (0 == (pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32)))) {
1096 nPenalty += 0xFFFF;
1097 } else {
1098 nPenalty -= 60000;
1099 }
1100 }
1101 return nPenalty;
1102 }
1103
1104 void CFGAS_FontMgrImp::ClearFontCache() {
1105 FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
1106 while (pos) {
1107 uint32_t dwHash;
1108 CFX_FontDescriptorInfos* pDescs;
1109 m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
1110 delete pDescs;
1111 }
1112 pos = m_IFXFont2FileRead.GetStartPosition();
1113 while (pos) {
1114 CFGAS_GEFont* pFont;
1115 IFX_SeekableReadStream* pFileRead;
1116 m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
1117 pFileRead->Release();
1118 }
1119 }
1120
1121 void CFGAS_FontMgrImp::RemoveFont(CFGAS_GEFont* pEFont) {
1122 if (!pEFont) {
1123 return;
1124 }
1125 IFX_SeekableReadStream* pFileRead;
1126 if (m_IFXFont2FileRead.Lookup(pEFont, pFileRead)) {
1127 pFileRead->Release();
1128 m_IFXFont2FileRead.RemoveKey(pEFont);
1129 }
1130 FX_POSITION pos;
1131 pos = m_Hash2Fonts.GetStartPosition();
1132 while (pos) {
1133 uint32_t dwHash;
1134 CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts;
1135 m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
1136 if (pFonts) {
1137 for (int32_t i = 0; i < pFonts->GetSize(); i++) {
1138 if (pFonts->GetAt(i) == pEFont) {
1139 pFonts->SetAt(i, nullptr);
1140 }
1141 }
1142 } else {
1143 m_Hash2Fonts.RemoveKey(dwHash);
1144 }
1145 }
1146 }
1147
1148 void CFGAS_FontMgrImp::RegisterFace(FXFT_Face pFace,
1149 const CFX_WideString* pFaceName) {
1150 if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
1151 return;
1152
1153 std::unique_ptr<CFX_FontDescriptor> pFont(new CFX_FontDescriptor);
1154 pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0;
1155 pFont->m_dwFontStyles |= FXFT_Is_Face_Italic(pFace) ? FX_FONTSTYLE_Italic : 0;
1156 pFont->m_dwFontStyles |= GetFlags(pFace);
1157
1158 std::vector<uint16_t> charsets = GetCharsets(pFace);
1159 GetUSBCSB(pFace, pFont->m_dwUsb, pFont->m_dwCsb);
1160
1161 FT_ULong dwTag;
1162 FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
1163
1164 std::vector<uint8_t> table;
1165 unsigned long nLength = 0;
1166 unsigned int error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, nullptr, &nLength);
1167 if (error == 0 && nLength != 0) {
1168 table.resize(nLength);
1169 if (FXFT_Load_Sfnt_Table(pFace, dwTag, 0, table.data(), nullptr))
1170 table.clear();
1171 }
1172 GetNames(table.empty() ? nullptr : table.data(), pFont->m_wsFamilyNames);
1173
1174 pFont->m_wsFamilyNames.Add(CFX_ByteString(pFace->family_name).UTF8Decode());
1175 pFont->m_wsFaceName =
1176 pFaceName ? *pFaceName
1177 : CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace));
1178 pFont->m_nFaceIndex = pFace->face_index;
1179
1180 m_InstalledFonts.Add(pFont.release());
1181 }
1182
1183 void CFGAS_FontMgrImp::RegisterFaces(IFX_SeekableReadStream* pFontStream,
1184 const CFX_WideString* pFaceName) {
1185 int32_t index = 0;
1186 int32_t num_faces = 0;
1187 do {
1188 FXFT_Face pFace = LoadFace(pFontStream, index++);
1189 if (!pFace)
1190 continue;
1191 // All faces keep number of faces. It can be retrieved from any one face.
1192 if (num_faces == 0)
1193 num_faces = pFace->num_faces;
1194 RegisterFace(pFace, pFaceName);
1195 if (FXFT_Get_Face_External_Stream(pFace))
1196 FXFT_Clear_Face_External_Stream(pFace);
1197 FXFT_Done_Face(pFace);
1198 } while (index < num_faces);
1199 }
1200
1201 uint32_t CFGAS_FontMgrImp::GetFlags(FXFT_Face pFace) {
1202 uint32_t flag = 0;
1203 if (FT_IS_FIXED_WIDTH(pFace)) {
1204 flag |= FX_FONTSTYLE_FixedPitch;
1205 }
1206 TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
1207 if (!pOS2) {
1208 return flag;
1209 }
1210 if (pOS2->ulCodePageRange1 & (1 << 31)) {
1211 flag |= FX_FONTSTYLE_Symbolic;
1212 }
1213 if (pOS2->panose[0] == 2) {
1214 uint8_t uSerif = pOS2->panose[1];
1215 if ((uSerif > 1 && uSerif < 10) || uSerif > 13) {
1216 flag |= FX_FONTSTYLE_Serif;
1217 }
1218 }
1219 return flag;
1220 }
1221
1222 #define GetUInt8(p) ((uint8_t)((p)[0]))
1223 #define GetUInt16(p) ((uint16_t)((p)[0] << 8 | (p)[1]))
1224 #define GetUInt32(p) \
1225 ((uint32_t)((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3]))
1226
1227 void CFGAS_FontMgrImp::GetNames(const uint8_t* name_table,
1228 CFX_WideStringArray& Names) {
1229 if (!name_table) {
1230 return;
1231 }
1232 uint8_t* lpTable = (uint8_t*)name_table;
1233 CFX_WideString wsFamily;
1234 uint8_t* sp = lpTable + 2;
1235 uint8_t* lpNameRecord = lpTable + 6;
1236 uint16_t nNameCount = GetUInt16(sp);
1237 uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
1238 for (uint16_t j = 0; j < nNameCount; j++) {
1239 uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
1240 if (nNameID != 1) {
1241 continue;
1242 }
1243 uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
1244 uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
1245 uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
1246 wsFamily.clear();
1247 if (nPlatformID != 1) {
1248 for (uint16_t k = 0; k < nNameLength / 2; k++) {
1249 FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
1250 wsFamily += wcTemp;
1251 }
1252 Names.Add(wsFamily);
1253 } else {
1254 for (uint16_t k = 0; k < nNameLength; k++) {
1255 FX_WCHAR wcTemp = GetUInt8(lpStr + nNameOffset + k);
1256 wsFamily += wcTemp;
1257 }
1258 Names.Add(wsFamily);
1259 }
1260 }
1261 }
1262 #undef GetUInt8
1263 #undef GetUInt16
1264 #undef GetUInt32
1265 struct FX_BIT2CHARSET {
1266 uint16_t wBit;
1267 uint16_t wCharset;
1268 };
1269
1270 FX_BIT2CHARSET g_FX_Bit2Charset1[16] = {
1271 {1 << 0, FX_CHARSET_ANSI},
1272 {1 << 1, FX_CHARSET_MSWin_EasterEuropean},
1273 {1 << 2, FX_CHARSET_MSWin_Cyrillic},
1274 {1 << 3, FX_CHARSET_MSWin_Greek},
1275 {1 << 4, FX_CHARSET_MSWin_Turkish},
1276 {1 << 5, FX_CHARSET_MSWin_Hebrew},
1277 {1 << 6, FX_CHARSET_MSWin_Arabic},
1278 {1 << 7, FX_CHARSET_MSWin_Baltic},
1279 {1 << 8, FX_CHARSET_MSWin_Vietnamese},
1280 {1 << 9, FX_CHARSET_Default},
1281 {1 << 10, FX_CHARSET_Default},
1282 {1 << 11, FX_CHARSET_Default},
1283 {1 << 12, FX_CHARSET_Default},
1284 {1 << 13, FX_CHARSET_Default},
1285 {1 << 14, FX_CHARSET_Default},
1286 {1 << 15, FX_CHARSET_Default},
1287 };
1288
1289 FX_BIT2CHARSET g_FX_Bit2Charset2[16] = {
1290 {1 << 0, FX_CHARSET_Thai},
1291 {1 << 1, FX_CHARSET_ShiftJIS},
1292 {1 << 2, FX_CHARSET_ChineseSimplified},
1293 {1 << 3, FX_CHARSET_Korean},
1294 {1 << 4, FX_CHARSET_ChineseTriditional},
1295 {1 << 5, FX_CHARSET_Johab},
1296 {1 << 6, FX_CHARSET_Default},
1297 {1 << 7, FX_CHARSET_Default},
1298 {1 << 8, FX_CHARSET_Default},
1299 {1 << 9, FX_CHARSET_Default},
1300 {1 << 10, FX_CHARSET_Default},
1301 {1 << 11, FX_CHARSET_Default},
1302 {1 << 12, FX_CHARSET_Default},
1303 {1 << 13, FX_CHARSET_Default},
1304 {1 << 14, FX_CHARSET_OEM},
1305 {1 << 15, FX_CHARSET_Symbol},
1306 };
1307
1308 FX_BIT2CHARSET g_FX_Bit2Charset3[16] = {
1309 {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
1310 {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
1311 {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
1312 {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
1313 {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
1314 {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
1315 {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
1316 {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_Default},
1317 };
1318
1319 FX_BIT2CHARSET g_FX_Bit2Charset4[16] = {
1320 {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
1321 {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
1322 {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
1323 {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
1324 {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
1325 {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
1326 {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
1327 {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_US},
1328 };
1329
1330 #define CODEPAGERANGE_IMPLEMENT(n) \
1331 for (int32_t i = 0; i < 16; i++) { \
1332 if ((a##n & g_FX_Bit2Charset##n[i].wBit) != 0) \
1333 charsets.push_back(g_FX_Bit2Charset##n[i].wCharset); \
1334 }
1335
1336 std::vector<uint16_t> CFGAS_FontMgrImp::GetCharsets(FXFT_Face pFace) const {
1337 std::vector<uint16_t> charsets;
1338 TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
1339 if (pOS2) {
1340 uint16_t a1 = pOS2->ulCodePageRange1 & 0xffff;
1341 CODEPAGERANGE_IMPLEMENT(1);
1342 uint16_t a2 = (pOS2->ulCodePageRange1 >> 16) & 0xffff;
1343 CODEPAGERANGE_IMPLEMENT(2);
1344 uint16_t a3 = pOS2->ulCodePageRange2 & 0xffff;
1345 CODEPAGERANGE_IMPLEMENT(3);
1346 uint16_t a4 = (pOS2->ulCodePageRange2 >> 16) & 0xffff;
1347 CODEPAGERANGE_IMPLEMENT(4);
1348 } else {
1349 charsets.push_back(FX_CHARSET_Default);
1350 }
1351 return charsets;
1352 }
1353
1354 #undef CODEPAGERANGE_IMPLEMENT
1355 void CFGAS_FontMgrImp::GetUSBCSB(FXFT_Face pFace,
1356 uint32_t* USB,
1357 uint32_t* CSB) {
1358 TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
1359 if (pOS2) {
1360 USB[0] = pOS2->ulUnicodeRange1;
1361 USB[1] = pOS2->ulUnicodeRange2;
1362 USB[2] = pOS2->ulUnicodeRange3;
1363 USB[3] = pOS2->ulUnicodeRange4;
1364 CSB[0] = pOS2->ulCodePageRange1;
1365 CSB[1] = pOS2->ulCodePageRange2;
1366 } else {
1367 USB[0] = 0;
1368 USB[1] = 0;
1369 USB[2] = 0;
1370 USB[3] = 0;
1371 CSB[0] = 0;
1372 CSB[1] = 0;
1373 }
1374 }
1375
1376 int32_t CFGAS_FontMgrImp::IsPartName(const CFX_WideString& Name1,
1377 const CFX_WideString& Name2) {
1378 if (Name1.Find(Name2.c_str()) != -1) {
1379 return 1;
1380 }
1381 return 0;
1382 }
1383
1384 #endif
OLDNEW
« no previous file with comments | « xfa/fgas/font/fgas_stdfontmgr.h ('k') | xfa/fgas/layout/fgas_unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698