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