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