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