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

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

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

Powered by Google App Engine
This is Rietveld 408576698