Revert "Allow external font-path configuration from pdfium_test."
[pdfium.git] / core / src / fxge / ge / fx_ge_linux.cpp
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 "../../../include/fxge/fx_ge.h"
8 #include "../agg/include/fx_agg_driver.h"
9 #include "text_int.h"
10
11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
12 static const struct {
13   const FX_CHAR* m_pName;
14   const FX_CHAR* m_pSubstName;
15 } Base14Substs[] = {
16     {"Courier", "Courier New"},
17     {"Courier-Bold", "Courier New Bold"},
18     {"Courier-BoldOblique", "Courier New Bold Italic"},
19     {"Courier-Oblique", "Courier New Italic"},
20     {"Helvetica", "Arial"},
21     {"Helvetica-Bold", "Arial Bold"},
22     {"Helvetica-BoldOblique", "Arial Bold Italic"},
23     {"Helvetica-Oblique", "Arial Italic"},
24     {"Times-Roman", "Times New Roman"},
25     {"Times-Bold", "Times New Roman Bold"},
26     {"Times-BoldItalic", "Times New Roman Bold Italic"},
27     {"Times-Italic", "Times New Roman Italic"},
28 };
29 class CFX_LinuxFontInfo : public CFX_FolderFontInfo {
30  public:
31   void* MapFont(int weight,
32                 FX_BOOL bItalic,
33                 int charset,
34                 int pitch_family,
35                 const FX_CHAR* family,
36                 int& iExact) override;
37   FX_BOOL ParseFontCfg();
38   void* FindFont(int weight,
39                  FX_BOOL bItalic,
40                  int charset,
41                  int pitch_family,
42                  const FX_CHAR* family,
43                  FX_BOOL bMatchName);
44 };
45 #define LINUX_GPNAMESIZE 6
46 static const struct {
47   const FX_CHAR* NameArr[LINUX_GPNAMESIZE];
48 } LinuxGpFontList[] = {
49     {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic",
50       "VL Gothic regular"}},
51     {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL,
52       "VL Gothic regular"}},
53     {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL,
54       "VL Gothic regular"}},
55     {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL,
56       "VL Gothic regular"}},
57 };
58 static const FX_CHAR* const g_LinuxGbFontList[] = {
59     "AR PL UMing CN Light", "WenQuanYi Micro Hei", "AR PL UKai CN",
60 };
61 static const FX_CHAR* const g_LinuxB5FontList[] = {
62     "AR PL UMing TW Light", "WenQuanYi Micro Hei", "AR PL UKai TW",
63 };
64 static const FX_CHAR* const g_LinuxHGFontList[] = {
65     "UnDotum",
66 };
67 static int32_t GetJapanesePreference(const FX_CHAR* facearr,
68                                      int weight,
69                                      int picth_family) {
70   CFX_ByteString face = facearr;
71   if (face.Find("Gothic") >= 0 ||
72       face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
73     if (face.Find("PGothic") >= 0 ||
74         face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
75       return 0;
76     }
77     return 1;
78   }
79   if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
80     if (face.Find("PMincho") >= 0 ||
81         face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
82       return 2;
83     }
84     return 3;
85   }
86   if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
87     return 0;
88   }
89   return 2;
90 }
91 void* CFX_LinuxFontInfo::MapFont(int weight,
92                                  FX_BOOL bItalic,
93                                  int charset,
94                                  int pitch_family,
95                                  const FX_CHAR* cstr_face,
96                                  int& iExact) {
97   CFX_ByteString face = cstr_face;
98   int iBaseFont;
99   for (iBaseFont = 0; iBaseFont < 12; iBaseFont++)
100     if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
101       face = Base14Substs[iBaseFont].m_pSubstName;
102       iExact = 1;
103       break;
104     }
105   if (iBaseFont < 12) {
106     return GetFont(face);
107   }
108   void* p = NULL;
109   FX_BOOL bCJK = TRUE;
110   switch (charset) {
111     case FXFONT_SHIFTJIS_CHARSET: {
112       int32_t index = GetJapanesePreference(cstr_face, weight, pitch_family);
113       if (index < 0) {
114         break;
115       }
116       for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++)
117         if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) {
118           return p;
119         }
120     } break;
121     case FXFONT_GB2312_CHARSET: {
122       static int32_t s_gbCount =
123           sizeof(g_LinuxGbFontList) / sizeof(const FX_CHAR*);
124       for (int32_t i = 0; i < s_gbCount; i++)
125         if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) {
126           return p;
127         }
128     } break;
129     case FXFONT_CHINESEBIG5_CHARSET: {
130       static int32_t s_b5Count =
131           sizeof(g_LinuxB5FontList) / sizeof(const FX_CHAR*);
132       for (int32_t i = 0; i < s_b5Count; i++)
133         if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) {
134           return p;
135         }
136     } break;
137     case FXFONT_HANGEUL_CHARSET: {
138       static int32_t s_hgCount =
139           sizeof(g_LinuxHGFontList) / sizeof(const FX_CHAR*);
140       for (int32_t i = 0; i < s_hgCount; i++)
141         if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) {
142           return p;
143         }
144     } break;
145     default:
146       bCJK = FALSE;
147       break;
148   }
149   if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
150     return GetFont("Courier New");
151   }
152   return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
153 }
154 static FX_DWORD _LinuxGetCharset(int charset) {
155   switch (charset) {
156     case FXFONT_SHIFTJIS_CHARSET:
157       return CHARSET_FLAG_SHIFTJIS;
158     case FXFONT_GB2312_CHARSET:
159       return CHARSET_FLAG_GB;
160     case FXFONT_CHINESEBIG5_CHARSET:
161       return CHARSET_FLAG_BIG5;
162     case FXFONT_HANGEUL_CHARSET:
163       return CHARSET_FLAG_KOREAN;
164     case FXFONT_SYMBOL_CHARSET:
165       return CHARSET_FLAG_SYMBOL;
166     case FXFONT_ANSI_CHARSET:
167       return CHARSET_FLAG_ANSI;
168     default:
169       break;
170   }
171   return 0;
172 }
173 static int32_t _LinuxGetSimilarValue(int weight,
174                                      FX_BOOL bItalic,
175                                      int pitch_family,
176                                      FX_DWORD style) {
177   int32_t iSimilarValue = 0;
178   if ((style & FXFONT_BOLD) == (weight > 400)) {
179     iSimilarValue += 16;
180   }
181   if ((style & FXFONT_ITALIC) == bItalic) {
182     iSimilarValue += 16;
183   }
184   if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) {
185     iSimilarValue += 16;
186   }
187   if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) {
188     iSimilarValue += 8;
189   }
190   if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) {
191     iSimilarValue += 8;
192   }
193   return iSimilarValue;
194 }
195 void* CFX_LinuxFontInfo::FindFont(int weight,
196                                   FX_BOOL bItalic,
197                                   int charset,
198                                   int pitch_family,
199                                   const FX_CHAR* family,
200                                   FX_BOOL bMatchName) {
201   CFX_FontFaceInfo* pFind = NULL;
202   FX_DWORD charset_flag = _LinuxGetCharset(charset);
203   int32_t iBestSimilar = 0;
204   FX_POSITION pos = m_FontList.GetStartPosition();
205   while (pos) {
206     CFX_ByteString bsName;
207     CFX_FontFaceInfo* pFont = NULL;
208     m_FontList.GetNextAssoc(pos, bsName, (void*&)pFont);
209     if (!(pFont->m_Charsets & charset_flag) &&
210         charset != FXFONT_DEFAULT_CHARSET) {
211       continue;
212     }
213     int32_t iSimilarValue = 0;
214     int32_t index = bsName.Find(family);
215     if (bMatchName && index < 0) {
216       continue;
217     }
218     if (!bMatchName && index > 0) {
219       iSimilarValue += 64;
220     }
221     iSimilarValue =
222         _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
223     if (iSimilarValue > iBestSimilar) {
224       iBestSimilar = iSimilarValue;
225       pFind = pFont;
226     }
227   }
228   return pFind;
229 }
230 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() {
231   CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo;
232   if (!pInfo->ParseFontCfg()) {
233     pInfo->AddPath("/usr/share/fonts");
234     pInfo->AddPath("/usr/share/X11/fonts/Type1");
235     pInfo->AddPath("/usr/share/X11/fonts/TTF");
236     pInfo->AddPath("/usr/local/share/fonts");
237   }
238   return pInfo;
239 }
240 FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() {
241   return FALSE;
242 }
243 void CFX_GEModule::InitPlatform() {
244   m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
245 }
246 void CFX_GEModule::DestroyPlatform() {}
247 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_