• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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 <array>
8 #include <iterator>
9 #include <memory>
10 #include <utility>
11 
12 #include "build/build_config.h"
13 #include "core/fxcrt/check.h"
14 #include "core/fxcrt/compiler_specific.h"
15 #include "core/fxcrt/fx_codepage.h"
16 #include "core/fxcrt/stl_util.h"
17 #include "core/fxge/cfx_folderfontinfo.h"
18 #include "core/fxge/cfx_fontmgr.h"
19 #include "core/fxge/cfx_gemodule.h"
20 #include "core/fxge/fx_font.h"
21 #include "core/fxge/systemfontinfo_iface.h"
22 
23 #if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !defined(OS_ASMJS)
24 #error "Included on the wrong platform"
25 #endif
26 
27 namespace {
28 
29 enum JpFontFamilyRowIndex : uint8_t {
30   kJpFontPGothic,
31   kJpFontGothic,
32   kJpFontPMincho,
33   kJpFontMincho,
34 };
35 
36 constexpr size_t kJpFontFamilyColumnCount = 5;
37 using JpFontFamilyRow = std::array<const char*, kJpFontFamilyColumnCount>;
38 constexpr auto kJpFontTable = fxcrt::ToArray<const JpFontFamilyRow>({
39     {{"MS PGothic", "TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic"}},
40     {{"MS Gothic", "TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic"}},
41     {{"MS PMincho", "TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho"}},
42     {{"MS Mincho", "TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho"}},
43 });
44 
45 const char* const kGbFontList[] = {
46     "AR PL UMing CN Light",
47     "WenQuanYi Micro Hei",
48     "AR PL UKai CN",
49 };
50 
51 const char* const kB5FontList[] = {
52     "AR PL UMing TW Light",
53     "WenQuanYi Micro Hei",
54     "AR PL UKai TW",
55 };
56 
57 const char* const kHGFontList[] = {
58     "UnDotum",
59 };
60 
GetJapanesePreference(const ByteString & face,int weight,int pitch_family)61 JpFontFamilyRowIndex GetJapanesePreference(const ByteString& face,
62                                            int weight,
63                                            int pitch_family) {
64   if (face.Contains("Gothic") ||
65       face.Contains("\x83\x53\x83\x56\x83\x62\x83\x4e")) {
66     if (face.Contains("PGothic") ||
67         face.Contains("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e")) {
68       return kJpFontPGothic;
69     }
70     return kJpFontGothic;
71   }
72   if (face.Contains("Mincho") || face.Contains("\x96\xbe\x92\xa9")) {
73     if (face.Contains("PMincho") || face.Contains("\x82\x6f\x96\xbe\x92\xa9")) {
74       return kJpFontPMincho;
75     }
76     return kJpFontMincho;
77   }
78   if (!FontFamilyIsRoman(pitch_family) && weight > 400)
79     return kJpFontPGothic;
80 
81   return kJpFontPMincho;
82 }
83 
84 class CFX_LinuxFontInfo final : public CFX_FolderFontInfo {
85  public:
86   CFX_LinuxFontInfo() = default;
87   ~CFX_LinuxFontInfo() override = default;
88 
89   // CFX_FolderFontInfo:
90   void* MapFont(int weight,
91                 bool bItalic,
92                 FX_Charset charset,
93                 int pitch_family,
94                 const ByteString& face) override;
95 
96   bool ParseFontCfg(const char** pUserPaths);
97 };
98 
MapFont(int weight,bool bItalic,FX_Charset charset,int pitch_family,const ByteString & face)99 void* CFX_LinuxFontInfo::MapFont(int weight,
100                                  bool bItalic,
101                                  FX_Charset charset,
102                                  int pitch_family,
103                                  const ByteString& face) {
104   void* font = GetSubstFont(face);
105   if (font)
106     return font;
107 
108   bool bCJK = true;
109   switch (charset) {
110     case FX_Charset::kShiftJIS: {
111       JpFontFamilyRowIndex index =
112           GetJapanesePreference(face, weight, pitch_family);
113       for (const char* name : kJpFontTable[index]) {
114         auto it = m_FontList.find(name);
115         if (it != m_FontList.end())
116           return it->second.get();
117       }
118       break;
119     }
120     case FX_Charset::kChineseSimplified: {
121       for (const char* name : kGbFontList) {
122         auto it = m_FontList.find(name);
123         if (it != m_FontList.end())
124           return it->second.get();
125       }
126       break;
127     }
128     case FX_Charset::kChineseTraditional: {
129       for (const char* name : kB5FontList) {
130         auto it = m_FontList.find(name);
131         if (it != m_FontList.end())
132           return it->second.get();
133       }
134       break;
135     }
136     case FX_Charset::kHangul: {
137       for (const char* name : kHGFontList) {
138         auto it = m_FontList.find(name);
139         if (it != m_FontList.end())
140           return it->second.get();
141       }
142       break;
143     }
144     default:
145       bCJK = false;
146       break;
147   }
148   return FindFont(weight, bItalic, charset, pitch_family, face, !bCJK);
149 }
150 
ParseFontCfg(const char ** pUserPaths)151 bool CFX_LinuxFontInfo::ParseFontCfg(const char** pUserPaths) {
152   if (!pUserPaths)
153     return false;
154 
155   // SAFETY: nullptr-terminated array required from caller.
156   UNSAFE_BUFFERS({
157     for (const char** pPath = pUserPaths; *pPath; ++pPath) {
158       AddPath(*pPath);
159     }
160   });
161   return true;
162 }
163 
164 }  // namespace
165 
166 class CLinuxPlatform : public CFX_GEModule::PlatformIface {
167  public:
168   CLinuxPlatform() = default;
169   ~CLinuxPlatform() override = default;
170 
Init()171   void Init() override {}
172 
CreateDefaultSystemFontInfo()173   std::unique_ptr<SystemFontInfoIface> CreateDefaultSystemFontInfo() override {
174     auto pInfo = std::make_unique<CFX_LinuxFontInfo>();
175     if (!pInfo->ParseFontCfg(CFX_GEModule::Get()->GetUserFontPaths())) {
176       pInfo->AddPath("/usr/share/fonts");
177       pInfo->AddPath("/usr/share/X11/fonts/Type1");
178       pInfo->AddPath("/usr/share/X11/fonts/TTF");
179       pInfo->AddPath("/usr/local/share/fonts");
180     }
181     return pInfo;
182   }
183 };
184 
185 // static
186 std::unique_ptr<CFX_GEModule::PlatformIface>
Create()187 CFX_GEModule::PlatformIface::Create() {
188   return std::make_unique<CLinuxPlatform>();
189 }
190