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