7#include "core/fxge/android/cfpf_skiafontmgr.h"
13#include "core/fxcrt/fx_codepage.h"
14#include "core/fxcrt/fx_extension.h"
15#include "core/fxcrt/fx_folder.h"
16#include "core/fxcrt/fx_system.h"
17#include "core/fxge/android/cfpf_skiafont.h"
18#include "core/fxge/android/cfpf_skiapathfont.h"
19#include "core/fxge/freetype/fx_freetype.h"
20#include "core/fxge/fx_font.h"
21#include "third_party/base/containers/adapters.h"
25constexpr int FPF_SKIAMATCHWEIGHT_NAME1 = 62;
26constexpr int FPF_SKIAMATCHWEIGHT_NAME2 = 60;
27constexpr int FPF_SKIAMATCHWEIGHT_1 = 16;
28constexpr int FPF_SKIAMATCHWEIGHT_2 = 8;
30struct FPF_SKIAFONTMAP {
35const FPF_SKIAFONTMAP kSkiaFontmap[] = {
36 {0x58c5083, 0xc8d2e345}, {0x5dfade2, 0xe1633081},
37 {0x684317d, 0xe1633081}, {0x14ee2d13, 0xc8d2e345},
38 {0x3918fe2d, 0xbbeeec72}, {0x3b98b31c, 0xe1633081},
39 {0x3d49f40e, 0xe1633081}, {0x432c41c5, 0xe1633081},
40 {0x491b6ad0, 0xe1633081}, {0x5612cab1, 0x59b9f8f1},
41 {0x779ce19d, 0xc8d2e345}, {0x7cc9510b, 0x59b9f8f1},
42 {0x83746053, 0xbbeeec72}, {0xaaa60c03, 0xbbeeec72},
43 {0xbf85ff26, 0xe1633081}, {0xc04fe601, 0xbbeeec72},
44 {0xca3812d5, 0x59b9f8f1}, {0xca383e15, 0x59b9f8f1},
45 {0xcad5eaf6, 0x59b9f8f1}, {0xcb7a04c8, 0xc8d2e345},
46 {0xfb4ce0de, 0xe1633081},
49const FPF_SKIAFONTMAP kSkiaSansFontMap[] = {
50 {0x58c5083, 0xd5b8d10f}, {0x14ee2d13, 0xd5b8d10f},
51 {0x779ce19d, 0xd5b8d10f}, {0xcb7a04c8, 0xd5b8d10f},
52 {0xfb4ce0de, 0xd5b8d10f},
55uint32_t FPF_SkiaGetSubstFont(uint32_t dwHash,
56 const FPF_SKIAFONTMAP* skFontMap,
58 const FPF_SKIAFONTMAP* pEnd = skFontMap + length;
59 const FPF_SKIAFONTMAP* pFontMap =
std::lower_bound(
60 skFontMap, pEnd, dwHash, [](
const FPF_SKIAFONTMAP& item, uint32_t hash) {
61 return item.dwFamily < hash;
63 if (pFontMap < pEnd && pFontMap->dwFamily == dwHash)
64 return pFontMap->dwSubSt;
69 FPF_SKIACHARSET_Ansi = 1 << 0,
70 FPF_SKIACHARSET_Default = 1 << 1,
71 FPF_SKIACHARSET_Symbol = 1 << 2,
72 FPF_SKIACHARSET_ShiftJIS = 1 << 3,
73 FPF_SKIACHARSET_Korean = 1 << 4,
74 FPF_SKIACHARSET_Johab = 1 << 5,
75 FPF_SKIACHARSET_GB2312 = 1 << 6,
76 FPF_SKIACHARSET_BIG5 = 1 << 7,
77 FPF_SKIACHARSET_Greek = 1 << 8,
78 FPF_SKIACHARSET_Turkish = 1 << 9,
79 FPF_SKIACHARSET_Vietnamese = 1 << 10,
80 FPF_SKIACHARSET_Hebrew = 1 << 11,
81 FPF_SKIACHARSET_Arabic = 1 << 12,
82 FPF_SKIACHARSET_Baltic = 1 << 13,
83 FPF_SKIACHARSET_Cyrillic = 1 << 14,
84 FPF_SKIACHARSET_Thai = 1 << 15,
85 FPF_SKIACHARSET_EeasternEuropean = 1 << 16,
86 FPF_SKIACHARSET_PC = 1 << 17,
87 FPF_SKIACHARSET_OEM = 1 << 18,
90uint32_t FPF_SkiaGetCharset(
FX_Charset uCharset) {
93 return FPF_SKIACHARSET_Ansi;
95 return FPF_SKIACHARSET_Default;
97 return FPF_SKIACHARSET_Symbol;
99 return FPF_SKIACHARSET_ShiftJIS;
101 return FPF_SKIACHARSET_Korean;
103 return FPF_SKIACHARSET_GB2312;
105 return FPF_SKIACHARSET_BIG5;
107 return FPF_SKIACHARSET_Greek;
109 return FPF_SKIACHARSET_Turkish;
111 return FPF_SKIACHARSET_Hebrew;
113 return FPF_SKIACHARSET_Arabic;
115 return FPF_SKIACHARSET_Baltic;
117 return FPF_SKIACHARSET_Cyrillic;
119 return FPF_SKIACHARSET_Thai;
121 return FPF_SKIACHARSET_EeasternEuropean;
123 return FPF_SKIACHARSET_Default;
127uint32_t FPF_SKIANormalizeFontName(ByteStringView bsFamily) {
128 uint32_t uHashCode = 0;
129 for (
unsigned char ch : bsFamily) {
130 if (ch ==
' ' || ch ==
'-' || ch ==
',')
132 uHashCode = 31 * uHashCode + tolower(ch);
137uint32_t FPF_SKIAGetFamilyHash(ByteStringView bsFamily,
140 ByteString bsFont(bsFamily);
147 bsFont
+= static_cast<uint8_t>(uCharset);
148 return FX_HashCode_GetA(bsFont.AsStringView());
155bool FPF_SkiaMaybeSymbol(ByteStringView bsFacename) {
156 ByteString bsName(bsFacename);
158 return bsName.Contains(
"symbol");
161bool FPF_SkiaMaybeArabic(ByteStringView bsFacename) {
162 ByteString bsName(bsFacename);
164 return bsName.Contains(
"arabic");
167const uint32_t kFPFSkiaFontCharsets[] = {
168 FPF_SKIACHARSET_Ansi,
169 FPF_SKIACHARSET_EeasternEuropean,
170 FPF_SKIACHARSET_Cyrillic,
171 FPF_SKIACHARSET_Greek,
172 FPF_SKIACHARSET_Turkish,
173 FPF_SKIACHARSET_Hebrew,
174 FPF_SKIACHARSET_Arabic,
175 FPF_SKIACHARSET_Baltic,
184 FPF_SKIACHARSET_Thai,
185 FPF_SKIACHARSET_ShiftJIS,
186 FPF_SKIACHARSET_GB2312,
187 FPF_SKIACHARSET_Korean,
188 FPF_SKIACHARSET_BIG5,
189 FPF_SKIACHARSET_Johab,
199 FPF_SKIACHARSET_Symbol,
202uint32_t FPF_SkiaGetFaceCharset(uint32_t code_range) {
203 uint32_t charset = 0;
204 for (int32_t i = 0; i < 32; i++) {
205 if (code_range & (1 << i)) {
206 charset |= kFPFSkiaFontCharsets[i];
217 m_FamilyFonts.clear();
225 FXFT_LibraryRec* pLibrary =
nullptr;
226 FT_Init_FreeType(&pLibrary);
230 m_FTLibrary.reset(pLibrary);
237 ScanPath(
"/system/fonts");
244 uint32_t dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset);
245 auto family_iter = m_FamilyFonts.find(dwHash);
246 if (family_iter != m_FamilyFonts.end())
247 return family_iter->second.get();
249 uint32_t dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname);
251 FPF_SkiaGetSubstFont(dwFaceName, kSkiaFontmap, std::size(kSkiaFontmap));
252 uint32_t dwSubstSans = FPF_SkiaGetSubstFont(dwFaceName, kSkiaSansFontMap,
253 std::size(kSkiaSansFontMap));
254 bool bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname);
256 FPF_SkiaMaybeArabic(bsFamilyname)) {
261 int32_t nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 +
262 FPF_SKIAMATCHWEIGHT_2 * 2;
265 int32_t nGlyphNum = 0;
266 for (
const std::unique_ptr<CFPF_SkiaPathFont>& font :
267 pdfium::base::Reversed(m_FontFaces)) {
268 if (!(font->charsets() & FPF_SkiaGetCharset(uCharset)))
271 uint32_t dwSysFontName = FPF_SKIANormalizeFontName(font->family());
272 if (dwFaceName == dwSysFontName)
273 nFind += FPF_SKIAMATCHWEIGHT_NAME1;
274 bool bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1);
275 if (FontStyleIsForceBold(dwStyle) == FontStyleIsForceBold(font->style()))
276 nFind += FPF_SKIAMATCHWEIGHT_1;
277 if (FontStyleIsItalic(dwStyle) == FontStyleIsItalic(font->style()))
278 nFind += FPF_SKIAMATCHWEIGHT_1;
279 if (FontStyleIsFixedPitch(dwStyle) ==
280 FontStyleIsFixedPitch(font->style())) {
281 nFind += FPF_SKIAMATCHWEIGHT_2;
283 if (FontStyleIsSerif(dwStyle) == FontStyleIsSerif(font->style()))
284 nFind += FPF_SKIAMATCHWEIGHT_1;
285 if (FontStyleIsScript(dwStyle) == FontStyleIsScript(font->style()))
286 nFind += FPF_SKIAMATCHWEIGHT_2;
287 if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) {
288 nFind += FPF_SKIAMATCHWEIGHT_NAME2;
291 if (uCharset == FX_Charset::kDefault || bMaybeSymbol) {
292 if (nFind > nMax && bMatchedName) {
294 pBestFont = font.get();
296 }
else if (FPF_SkiaIsCJK(uCharset)) {
297 if (bMatchedName || font->glyph_num() > nGlyphNum) {
298 pBestFont = font.get();
299 nGlyphNum = font->glyph_num();
301 }
else if (nFind > nMax) {
303 pBestFont = font.get();
305 if (nExpectVal <= nFind) {
306 pBestFont = font.get();
314 if (!font->IsValid())
318 m_FamilyFonts[dwHash] = std::move(font);
323 int32_t iFaceIndex) {
324 if (bsFile.IsEmpty())
331 args.flags = FT_OPEN_PATHNAME;
332 args.pathname =
const_cast<FT_String*>(bsFile.unterminated_c_str());
334 CFX_Face::Open(m_FTLibrary.get(), &args, iFaceIndex);
338 FT_Set_Pixel_Sizes(face->GetRec(), 0, 64);
343 std::unique_ptr<FX_Folder> handle = FX_Folder::OpenFolder(path);
348 bool bFolder =
false;
349 while (handle->GetNextFile(&filename, &bFolder)) {
351 if (filename
== "." || filename
== "..")
354 ByteString ext = filename.Last(4);
356 if (ext
!= ".ttf" && ext
!= ".ttc" && ext
!= ".otf")
359 ByteString fullpath
(path
);
361 fullpath
+= filename;
370 RetainPtr<CFX_Face> face = GetFontFace(file.AsStringView(), 0);
374 m_FontFaces.push_back(ReportFace(face, file));
379 const ByteString& file) {
380 uint32_t dwStyle = 0;
381 if (face->IsBold()) {
384 if (face->IsItalic()) {
387 if (face->IsFixedWidth()) {
391 uint32_t charset = FPF_SKIACHARSET_Default;
392 absl::optional<std::array<uint32_t, 2>> code_page_range =
393 face->GetOs2CodePageRange();
394 if (code_page_range.has_value()) {
395 if (code_page_range.value()[0] & (1 << 31)) {
398 charset |= FPF_SkiaGetFaceCharset(code_page_range.value()[0]);
401 absl::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
402 if (panose.has_value() && panose.value()[0] == 2) {
403 uint8_t serif = panose.value()[1];
404 if ((serif > 1 && serif < 10) || serif > 13) {
410 file, face->GetFamilyName(), dwStyle, face->GetRec()->face_index, charset,
411 face->GetGlyphCount());
RetainPtr< CFX_Face > GetFontFace(ByteStringView bsFile, int32_t iFaceIndex)
CFPF_SkiaFont * CreateFont(ByteStringView bsFamilyname, FX_Charset uCharset, uint32_t dwStyle)
ByteString & operator+=(const ByteString &str)
ByteString & operator+=(char ch)
bool operator==(const char *ptr) const
ByteString(const ByteString &other)
ByteString & operator+=(const char *str)
bool operator!=(const char *ptr) const
bool FX_CharSetIsCJK(FX_Charset uCharset)
bool FontStyleIsSerif(uint32_t style)
bool FontStyleIsItalic(uint32_t style)
#define FXFONT_FORCE_BOLD
bool FontStyleIsForceBold(uint32_t style)
#define FXFONT_FIXED_PITCH