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 "core/include/fxge/fx_ge.h"
8 #include "core/src/fxge/agg/include/fx_agg_driver.h"
9 #include "text_int.h"
10 
11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
12 class CFX_LinuxFontInfo : public CFX_FolderFontInfo {
13  public:
14   void* MapFont(int weight,
15                 FX_BOOL bItalic,
16                 int charset,
17                 int pitch_family,
18                 const FX_CHAR* family,
19                 int& iExact) override;
20   FX_BOOL ParseFontCfg(const char** pUserPaths);
21 };
22 #define LINUX_GPNAMESIZE 6
23 static const struct {
24   const FX_CHAR* NameArr[LINUX_GPNAMESIZE];
25 } LinuxGpFontList[] = {
26     {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic",
27       "VL Gothic regular"}},
28     {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL,
29       "VL Gothic regular"}},
30     {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL,
31       "VL Gothic regular"}},
32     {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL,
33       "VL Gothic regular"}},
34 };
35 static const FX_CHAR* const g_LinuxGbFontList[] = {
36     "AR PL UMing CN Light", "WenQuanYi Micro Hei", "AR PL UKai CN",
37 };
38 static const FX_CHAR* const g_LinuxB5FontList[] = {
39     "AR PL UMing TW Light", "WenQuanYi Micro Hei", "AR PL UKai TW",
40 };
41 static const FX_CHAR* const g_LinuxHGFontList[] = {
42     "UnDotum",
43 };
GetJapanesePreference(const FX_CHAR * facearr,int weight,int picth_family)44 static int32_t GetJapanesePreference(const FX_CHAR* facearr,
45                                      int weight,
46                                      int picth_family) {
47   CFX_ByteString face = facearr;
48   if (face.Find("Gothic") >= 0 ||
49       face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
50     if (face.Find("PGothic") >= 0 ||
51         face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
52       return 0;
53     }
54     return 1;
55   }
56   if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
57     if (face.Find("PMincho") >= 0 ||
58         face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
59       return 2;
60     }
61     return 3;
62   }
63   if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
64     return 0;
65   }
66   return 2;
67 }
MapFont(int weight,FX_BOOL bItalic,int charset,int pitch_family,const FX_CHAR * cstr_face,int & iExact)68 void* CFX_LinuxFontInfo::MapFont(int weight,
69                                  FX_BOOL bItalic,
70                                  int charset,
71                                  int pitch_family,
72                                  const FX_CHAR* cstr_face,
73                                  int& iExact) {
74   void* font = GetSubstFont(cstr_face);
75   if (font) {
76     iExact = 1;
77     return font;
78   }
79   FX_BOOL bCJK = TRUE;
80   switch (charset) {
81     case FXFONT_SHIFTJIS_CHARSET: {
82       int32_t index = GetJapanesePreference(cstr_face, weight, pitch_family);
83       if (index < 0) {
84         break;
85       }
86       for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++) {
87         auto it = m_FontList.find(LinuxGpFontList[index].NameArr[i]);
88         if (it != m_FontList.end()) {
89           return it->second;
90         }
91       }
92     } break;
93     case FXFONT_GB2312_CHARSET: {
94       for (size_t i = 0; i < FX_ArraySize(g_LinuxGbFontList); ++i) {
95         auto it = m_FontList.find(g_LinuxGbFontList[i]);
96         if (it != m_FontList.end()) {
97           return it->second;
98         }
99       }
100     } break;
101     case FXFONT_CHINESEBIG5_CHARSET: {
102       for (size_t i = 0; i < FX_ArraySize(g_LinuxB5FontList); ++i) {
103         auto it = m_FontList.find(g_LinuxB5FontList[i]);
104         if (it != m_FontList.end()) {
105           return it->second;
106         }
107       }
108     } break;
109     case FXFONT_HANGEUL_CHARSET: {
110       for (size_t i = 0; i < FX_ArraySize(g_LinuxHGFontList); ++i) {
111         auto it = m_FontList.find(g_LinuxHGFontList[i]);
112         if (it != m_FontList.end()) {
113           return it->second;
114         }
115       }
116     } break;
117     default:
118       bCJK = FALSE;
119       break;
120   }
121   return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
122 }
CreateDefault(const char ** pUserPaths)123 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUserPaths) {
124   CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo;
125   if (!pInfo->ParseFontCfg(pUserPaths)) {
126     pInfo->AddPath("/usr/share/fonts");
127     pInfo->AddPath("/usr/share/X11/fonts/Type1");
128     pInfo->AddPath("/usr/share/X11/fonts/TTF");
129     pInfo->AddPath("/usr/local/share/fonts");
130   }
131   return pInfo;
132 }
ParseFontCfg(const char ** pUserPaths)133 FX_BOOL CFX_LinuxFontInfo::ParseFontCfg(const char** pUserPaths) {
134   if (!pUserPaths) {
135     return FALSE;
136   }
137   for (const char** pPath = pUserPaths; *pPath; ++pPath) {
138     AddPath(*pPath);
139   }
140   return TRUE;
141 }
InitPlatform()142 void CFX_GEModule::InitPlatform() {
143   m_pFontMgr->SetSystemFontInfo(
144       IFX_SystemFontInfo::CreateDefault(m_pUserFontPaths));
145 }
DestroyPlatform()146 void CFX_GEModule::DestroyPlatform() {}
147 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
148