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