• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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