Clean up CPDF_AnnotList.
[pdfium.git] / core / src / fxge / android / fpf_skiafontmgr.cpp
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 "../../../include/fxcrt/fx_ext.h"
8 #include "fx_fpf.h"
9 #if _FX_OS_ == _FX_ANDROID_
10 #define FPF_SKIAMATCHWEIGHT_NAME1 62
11 #define FPF_SKIAMATCHWEIGHT_NAME2 60
12 #define FPF_SKIAMATCHWEIGHT_1 16
13 #define FPF_SKIAMATCHWEIGHT_2 8
14 #include "fpf_skiafontmgr.h"
15 #include "fpf_skiafont.h"
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream,
20                                          unsigned long offset,
21                                          unsigned char* buffer,
22                                          unsigned long count) {
23   IFX_FileRead* pFileRead = (IFX_FileRead*)stream->descriptor.pointer;
24   if (!pFileRead) {
25     return 0;
26   }
27   if (count > 0) {
28     if (pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count) !=
29         count) {
30       return 0;
31     }
32   }
33   return count;
34 }
35 static void FPF_SkiaStream_Close(FXFT_Stream stream) {}
36 #ifdef __cplusplus
37 };
38 #endif
39 typedef struct _FPF_SKIAFONTMAP {
40   FX_DWORD dwFamily;
41   FX_DWORD dwSubSt;
42 } FPF_SKIAFONTMAP, *FPF_LPSKIAFONTMAP;
43 typedef FPF_SKIAFONTMAP const* FPF_LPCSKIAFONTMAP;
44 static const FPF_SKIAFONTMAP g_SkiaFontmap[] = {
45     {0x58c5083, 0xc8d2e345},  {0x5dfade2, 0xe1633081},
46     {0x684317d, 0xe1633081},  {0x14ee2d13, 0xc8d2e345},
47     {0x3918fe2d, 0xbbeeec72}, {0x3b98b31c, 0xe1633081},
48     {0x3d49f40e, 0xe1633081}, {0x432c41c5, 0xe1633081},
49     {0x491b6ad0, 0xe1633081}, {0x5612cab1, 0x59b9f8f1},
50     {0x779ce19d, 0xc8d2e345}, {0x7cc9510b, 0x59b9f8f1},
51     {0x83746053, 0xbbeeec72}, {0xaaa60c03, 0xbbeeec72},
52     {0xbf85ff26, 0xe1633081}, {0xc04fe601, 0xbbeeec72},
53     {0xca3812d5, 0x59b9f8f1}, {0xca383e15, 0x59b9f8f1},
54     {0xcad5eaf6, 0x59b9f8f1}, {0xcb7a04c8, 0xc8d2e345},
55     {0xfb4ce0de, 0xe1633081},
56 };
57 FX_DWORD FPF_SkiaGetSubstFont(FX_DWORD dwHash) {
58   int32_t iStart = 0;
59   int32_t iEnd = sizeof(g_SkiaFontmap) / sizeof(FPF_SKIAFONTMAP);
60   while (iStart <= iEnd) {
61     int32_t iMid = (iStart + iEnd) / 2;
62     FPF_LPCSKIAFONTMAP pItem = &g_SkiaFontmap[iMid];
63     if (dwHash < pItem->dwFamily) {
64       iEnd = iMid - 1;
65     } else if (dwHash > pItem->dwFamily) {
66       iStart = iMid + 1;
67     } else {
68       return pItem->dwSubSt;
69     }
70   }
71   return 0;
72 }
73 static const FPF_SKIAFONTMAP g_SkiaSansFontMap[] = {
74     {0x58c5083, 0xd5b8d10f},  {0x14ee2d13, 0xd5b8d10f},
75     {0x779ce19d, 0xd5b8d10f}, {0xcb7a04c8, 0xd5b8d10f},
76     {0xfb4ce0de, 0xd5b8d10f},
77 };
78 FX_DWORD FPF_SkiaGetSansFont(FX_DWORD dwHash) {
79   int32_t iStart = 0;
80   int32_t iEnd = sizeof(g_SkiaSansFontMap) / sizeof(FPF_SKIAFONTMAP);
81   while (iStart <= iEnd) {
82     int32_t iMid = (iStart + iEnd) / 2;
83     FPF_LPCSKIAFONTMAP pItem = &g_SkiaSansFontMap[iMid];
84     if (dwHash < pItem->dwFamily) {
85       iEnd = iMid - 1;
86     } else if (dwHash > pItem->dwFamily) {
87       iStart = iMid + 1;
88     } else {
89       return pItem->dwSubSt;
90     }
91   }
92   return 0;
93 }
94 static uint32_t FPF_GetHashCode_StringA(const FX_CHAR* pStr,
95                                         int32_t iLength,
96                                         FX_BOOL bIgnoreCase = FALSE) {
97   if (!pStr) {
98     return 0;
99   }
100   if (iLength < 0) {
101     iLength = FXSYS_strlen(pStr);
102   }
103   const FX_CHAR* pStrEnd = pStr + iLength;
104   uint32_t uHashCode = 0;
105   if (bIgnoreCase) {
106     while (pStr < pStrEnd) {
107       uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++);
108     }
109   } else {
110     while (pStr < pStrEnd) {
111       uHashCode = 31 * uHashCode + *pStr++;
112     }
113   }
114   return uHashCode;
115 }
116 enum FPF_SKIACHARSET {
117   FPF_SKIACHARSET_Ansi = 1 << 0,
118   FPF_SKIACHARSET_Default = 1 << 1,
119   FPF_SKIACHARSET_Symbol = 1 << 2,
120   FPF_SKIACHARSET_ShiftJIS = 1 << 3,
121   FPF_SKIACHARSET_Korean = 1 << 4,
122   FPF_SKIACHARSET_Johab = 1 << 5,
123   FPF_SKIACHARSET_GB2312 = 1 << 6,
124   FPF_SKIACHARSET_BIG5 = 1 << 7,
125   FPF_SKIACHARSET_Greek = 1 << 8,
126   FPF_SKIACHARSET_Turkish = 1 << 9,
127   FPF_SKIACHARSET_Vietnamese = 1 << 10,
128   FPF_SKIACHARSET_Hebrew = 1 << 11,
129   FPF_SKIACHARSET_Arabic = 1 << 12,
130   FPF_SKIACHARSET_Baltic = 1 << 13,
131   FPF_SKIACHARSET_Cyrillic = 1 << 14,
132   FPF_SKIACHARSET_Thai = 1 << 15,
133   FPF_SKIACHARSET_EeasternEuropean = 1 << 16,
134   FPF_SKIACHARSET_PC = 1 << 17,
135   FPF_SKIACHARSET_OEM = 1 << 18,
136 };
137 static FX_DWORD FPF_SkiaGetCharset(uint8_t uCharset) {
138   switch (uCharset) {
139     case FXFONT_ANSI_CHARSET:
140       return FPF_SKIACHARSET_Ansi;
141     case FXFONT_DEFAULT_CHARSET:
142       return FPF_SKIACHARSET_Default;
143     case FXFONT_SYMBOL_CHARSET:
144       return FPF_SKIACHARSET_Symbol;
145     case FXFONT_SHIFTJIS_CHARSET:
146       return FPF_SKIACHARSET_ShiftJIS;
147     case FXFONT_HANGEUL_CHARSET:
148       return FPF_SKIACHARSET_Korean;
149     case FXFONT_GB2312_CHARSET:
150       return FPF_SKIACHARSET_GB2312;
151     case FXFONT_CHINESEBIG5_CHARSET:
152       return FPF_SKIACHARSET_BIG5;
153     case FXFONT_GREEK_CHARSET:
154       return FPF_SKIACHARSET_Greek;
155     case FXFONT_TURKISH_CHARSET:
156       return FPF_SKIACHARSET_Turkish;
157     case FXFONT_HEBREW_CHARSET:
158       return FPF_SKIACHARSET_Hebrew;
159     case FXFONT_ARABIC_CHARSET:
160       return FPF_SKIACHARSET_Arabic;
161     case FXFONT_BALTIC_CHARSET:
162       return FPF_SKIACHARSET_Baltic;
163     case FXFONT_RUSSIAN_CHARSET:
164       return FPF_SKIACHARSET_Cyrillic;
165     case FXFONT_THAI_CHARSET:
166       return FPF_SKIACHARSET_Thai;
167     case FXFONT_EASTEUROPE_CHARSET:
168       return FPF_SKIACHARSET_EeasternEuropean;
169   }
170   return FPF_SKIACHARSET_Default;
171 }
172 static FX_DWORD FPF_SKIANormalizeFontName(const CFX_ByteStringC& bsfamily) {
173   FX_DWORD dwHash = 0;
174   int32_t iLength = bsfamily.GetLength();
175   const FX_CHAR* pBuffer = bsfamily.GetCStr();
176   for (int32_t i = 0; i < iLength; i++) {
177     FX_CHAR ch = pBuffer[i];
178     if (ch == ' ' || ch == '-' || ch == ',') {
179       continue;
180     }
181     dwHash = 31 * dwHash + FXSYS_tolower(ch);
182   }
183   return dwHash;
184 }
185 static FX_DWORD FPF_SKIAGetFamilyHash(const CFX_ByteStringC& bsFamily,
186                                       FX_DWORD dwStyle,
187                                       uint8_t uCharset) {
188   CFX_ByteString bsFont(bsFamily);
189   if (dwStyle & FXFONT_BOLD) {
190     bsFont += "Bold";
191   }
192   if (dwStyle & FXFONT_ITALIC) {
193     bsFont += "Italic";
194   }
195   if (dwStyle & FXFONT_SERIF) {
196     bsFont += "Serif";
197   }
198   bsFont += uCharset;
199   return FPF_GetHashCode_StringA(bsFont.c_str(), bsFont.GetLength(), TRUE);
200 }
201 static FX_BOOL FPF_SkiaIsCJK(uint8_t uCharset) {
202   return (uCharset == FXFONT_GB2312_CHARSET) ||
203          (uCharset == FXFONT_CHINESEBIG5_CHARSET) ||
204          (uCharset == FXFONT_HANGEUL_CHARSET) ||
205          (uCharset == FXFONT_SHIFTJIS_CHARSET);
206 }
207 static FX_BOOL FPF_SkiaMaybeSymbol(const CFX_ByteStringC& bsFacename) {
208   CFX_ByteString bsName = bsFacename;
209   bsName.MakeLower();
210   return bsName.Find("symbol") > -1;
211 }
212 static FX_BOOL FPF_SkiaMaybeArabic(const CFX_ByteStringC& bsFacename) {
213   CFX_ByteString bsName = bsFacename;
214   bsName.MakeLower();
215   return bsName.Find("arabic") > -1;
216 }
217 CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() : m_bLoaded(FALSE), m_FTLibrary(NULL) {}
218 CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() {
219   void* pkey = NULL;
220   CFPF_SkiaFont* pValue = NULL;
221   FX_POSITION pos = m_FamilyFonts.GetStartPosition();
222   while (pos) {
223     m_FamilyFonts.GetNextAssoc(pos, pkey, (void*&)pValue);
224     if (pValue) {
225       pValue->Release();
226     }
227   }
228   m_FamilyFonts.RemoveAll();
229   for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) {
230     CFPF_SkiaFontDescriptor* pFont =
231         (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(i);
232     delete pFont;
233   }
234   m_FontFaces.RemoveAll();
235   if (m_FTLibrary) {
236     FXFT_Done_FreeType(m_FTLibrary);
237   }
238 }
239 FX_BOOL CFPF_SkiaFontMgr::InitFTLibrary() {
240   if (m_FTLibrary == NULL) {
241     FXFT_Init_FreeType(&m_FTLibrary);
242   }
243   return m_FTLibrary != NULL;
244 }
245 void CFPF_SkiaFontMgr::LoadSystemFonts() {
246   if (m_bLoaded) {
247     return;
248   }
249   ScanPath(FX_BSTRC("/system/fonts"));
250   OutputSystemFonts();
251   m_bLoaded = TRUE;
252 }
253 void CFPF_SkiaFontMgr::LoadPrivateFont(IFX_FileRead* pFontFile) {}
254 void CFPF_SkiaFontMgr::LoadPrivateFont(const CFX_ByteStringC& bsFileName) {}
255 void CFPF_SkiaFontMgr::LoadPrivateFont(void* pBuffer, size_t szBuffer) {}
256 IFPF_Font* CFPF_SkiaFontMgr::CreateFont(const CFX_ByteStringC& bsFamilyname,
257                                         uint8_t uCharset,
258                                         FX_DWORD dwStyle,
259                                         FX_DWORD dwMatch) {
260   FX_DWORD dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset);
261   IFPF_Font* pFont = NULL;
262   if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
263     if (pFont) {
264       return pFont->Retain();
265     }
266   }
267   FX_DWORD dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname);
268   FX_DWORD dwSubst = FPF_SkiaGetSubstFont(dwFaceName);
269   FX_DWORD dwSubstSans = FPF_SkiaGetSansFont(dwFaceName);
270   FX_BOOL bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname);
271   if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname)) {
272     uCharset = FXFONT_ARABIC_CHARSET;
273   } else if (uCharset == FXFONT_ANSI_CHARSET &&
274              (dwMatch & FPF_MATCHFONT_REPLACEANSI)) {
275     uCharset = FXFONT_DEFAULT_CHARSET;
276   }
277   int32_t nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 +
278                        FPF_SKIAMATCHWEIGHT_2 * 2;
279   int32_t nItem = -1;
280   int32_t nMax = -1;
281   int32_t nGlyphNum = 0;
282   for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) {
283     CFPF_SkiaPathFont* pFontDes = (CFPF_SkiaPathFont*)m_FontFaces.ElementAt(i);
284     if (!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset))) {
285       continue;
286     }
287     int32_t nFind = 0;
288     FX_DWORD dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily);
289     if (dwFaceName == dwSysFontName) {
290       nFind += FPF_SKIAMATCHWEIGHT_NAME1;
291     }
292     FX_BOOL bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1);
293     if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD)) {
294       nFind += FPF_SKIAMATCHWEIGHT_1;
295     }
296     if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC)) {
297       nFind += FPF_SKIAMATCHWEIGHT_1;
298     }
299     if ((dwStyle & FXFONT_FIXED_PITCH) ==
300         (pFontDes->m_dwStyle & FXFONT_FIXED_PITCH)) {
301       nFind += FPF_SKIAMATCHWEIGHT_2;
302     }
303     if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF)) {
304       nFind += FPF_SKIAMATCHWEIGHT_1;
305     }
306     if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT)) {
307       nFind += FPF_SKIAMATCHWEIGHT_2;
308     }
309     if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) {
310       nFind += FPF_SKIAMATCHWEIGHT_NAME2;
311       bMatchedName = TRUE;
312     }
313     if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) {
314       if (nFind > nMax && bMatchedName) {
315         nMax = nFind;
316         nItem = i;
317       }
318     } else if (FPF_SkiaIsCJK(uCharset)) {
319       if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) {
320         nItem = i;
321         nGlyphNum = pFontDes->m_iGlyphNum;
322       }
323     } else if (nFind > nMax) {
324       nMax = nFind;
325       nItem = i;
326     }
327     if (nExpectVal <= nFind) {
328       nItem = i;
329       break;
330     }
331   }
332   if (nItem > -1) {
333     CFPF_SkiaFontDescriptor* pFontDes =
334         (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(nItem);
335     CFPF_SkiaFont* pFont = new CFPF_SkiaFont;
336     if (pFont->InitFont(this, pFontDes, bsFamilyname, dwStyle, uCharset)) {
337       m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
338       return pFont->Retain();
339     }
340     pFont->Release();
341   }
342   return NULL;
343 }
344 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead* pFileRead,
345                                         int32_t iFaceIndex) {
346   if (!pFileRead) {
347     return NULL;
348   }
349   if (pFileRead->GetSize() == 0) {
350     return NULL;
351   }
352   if (iFaceIndex < 0) {
353     return NULL;
354   }
355   FXFT_StreamRec streamRec;
356   FXSYS_memset(&streamRec, 0, sizeof(FXFT_StreamRec));
357   streamRec.size = pFileRead->GetSize();
358   streamRec.descriptor.pointer = pFileRead;
359   streamRec.read = FPF_SkiaStream_Read;
360   streamRec.close = FPF_SkiaStream_Close;
361   FXFT_Open_Args args;
362   args.flags = FT_OPEN_STREAM;
363   args.stream = &streamRec;
364   FXFT_Face face;
365   if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) {
366     return NULL;
367   }
368   FXFT_Set_Pixel_Sizes(face, 0, 64);
369   return face;
370 }
371 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const CFX_ByteStringC& bsFile,
372                                         int32_t iFaceIndex) {
373   if (bsFile.IsEmpty()) {
374     return NULL;
375   }
376   if (iFaceIndex < 0) {
377     return NULL;
378   }
379   FXFT_Open_Args args;
380   args.flags = FT_OPEN_PATHNAME;
381   args.pathname = (FT_String*)bsFile.GetCStr();
382   FXFT_Face face;
383   if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) {
384     return FALSE;
385   }
386   FXFT_Set_Pixel_Sizes(face, 0, 64);
387   return face;
388 }
389 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const uint8_t* pBuffer,
390                                         size_t szBuffer,
391                                         int32_t iFaceIndex) {
392   if (!pBuffer || szBuffer < 1) {
393     return NULL;
394   }
395   if (iFaceIndex < 0) {
396     return NULL;
397   }
398   FXFT_Open_Args args;
399   args.flags = FT_OPEN_MEMORY;
400   args.memory_base = pBuffer;
401   args.memory_size = szBuffer;
402   FXFT_Face face;
403   if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) {
404     return FALSE;
405   }
406   FXFT_Set_Pixel_Sizes(face, 0, 64);
407   return face;
408 }
409 void CFPF_SkiaFontMgr::ScanPath(const CFX_ByteStringC& path) {
410   void* handle = FX_OpenFolder(path.GetCStr());
411   if (!handle) {
412     return;
413   }
414   CFX_ByteString filename;
415   FX_BOOL bFolder = FALSE;
416   while (FX_GetNextFile(handle, filename, bFolder)) {
417     if (bFolder) {
418       if (filename == FX_BSTRC(".") || filename == FX_BSTRC("..")) {
419         continue;
420       }
421     } else {
422       CFX_ByteString ext = filename.Right(4);
423       ext.MakeLower();
424       if (ext != FX_BSTRC(".ttf") && ext != FX_BSTRC(".ttc")) {
425         continue;
426       }
427     }
428     CFX_ByteString fullpath = path;
429     fullpath += "/";
430     fullpath += filename;
431     if (bFolder) {
432       ScanPath(fullpath);
433     } else {
434       ScanFile(fullpath);
435     }
436   }
437   FX_CloseFolder(handle);
438 }
439 void CFPF_SkiaFontMgr::ScanFile(const CFX_ByteStringC& file) {
440   FXFT_Face face = GetFontFace(file);
441   if (face) {
442     CFPF_SkiaPathFont* pFontDesc = new CFPF_SkiaPathFont;
443     pFontDesc->SetPath(file.GetCStr());
444     ReportFace(face, pFontDesc);
445     m_FontFaces.Add(pFontDesc);
446     FXFT_Done_Face(face);
447   }
448 }
449 static const FX_DWORD g_FPFSkiaFontCharsets[] = {
450     FPF_SKIACHARSET_Ansi,
451     FPF_SKIACHARSET_EeasternEuropean,
452     FPF_SKIACHARSET_Cyrillic,
453     FPF_SKIACHARSET_Greek,
454     FPF_SKIACHARSET_Turkish,
455     FPF_SKIACHARSET_Hebrew,
456     FPF_SKIACHARSET_Arabic,
457     FPF_SKIACHARSET_Baltic,
458     0,
459     0,
460     0,
461     0,
462     0,
463     0,
464     0,
465     0,
466     FPF_SKIACHARSET_Thai,
467     FPF_SKIACHARSET_ShiftJIS,
468     FPF_SKIACHARSET_GB2312,
469     FPF_SKIACHARSET_Korean,
470     FPF_SKIACHARSET_BIG5,
471     FPF_SKIACHARSET_Johab,
472     0,
473     0,
474     0,
475     0,
476     0,
477     0,
478     0,
479     0,
480     FPF_SKIACHARSET_OEM,
481     FPF_SKIACHARSET_Symbol,
482 };
483 static FX_DWORD FPF_SkiaGetFaceCharset(TT_OS2* pOS2) {
484   FX_DWORD dwCharset = 0;
485   if (pOS2) {
486     for (int32_t i = 0; i < 32; i++) {
487       if (pOS2->ulCodePageRange1 & (1 << i)) {
488         dwCharset |= g_FPFSkiaFontCharsets[i];
489       }
490     }
491   }
492   dwCharset |= FPF_SKIACHARSET_Default;
493   return dwCharset;
494 }
495 void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face,
496                                   CFPF_SkiaFontDescriptor* pFontDesc) {
497   if (!face || !pFontDesc) {
498     return;
499   }
500   pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face));
501   if (FXFT_Is_Face_Bold(face)) {
502     pFontDesc->m_dwStyle |= FXFONT_BOLD;
503   }
504   if (FXFT_Is_Face_Italic(face)) {
505     pFontDesc->m_dwStyle |= FXFONT_ITALIC;
506   }
507   if (FT_IS_FIXED_WIDTH(face)) {
508     pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH;
509   }
510   TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
511   if (pOS2) {
512     if (pOS2->ulCodePageRange1 & (1 << 31)) {
513       pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC;
514     }
515     if (pOS2->panose[0] == 2) {
516       uint8_t uSerif = pOS2->panose[1];
517       if ((uSerif > 1 && uSerif < 10) || uSerif > 13) {
518         pFontDesc->m_dwStyle |= FXFONT_SERIF;
519       }
520     }
521   }
522   if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31))) {
523     pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC;
524   }
525   pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2);
526   pFontDesc->m_iFaceIndex = face->face_index;
527   pFontDesc->m_iGlyphNum = face->num_glyphs;
528 }
529 void CFPF_SkiaFontMgr::OutputSystemFonts() {}
530 #endif