OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fxge/fx_ge.h" | 7 #include "../../../include/fxge/fx_ge.h" |
8 #include "../agg/include/fx_agg_driver.h" | 8 #include "../agg/include/fx_agg_driver.h" |
9 #include "text_int.h" | 9 #include "text_int.h" |
10 | 10 |
11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ | 11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ |
12 static const struct { | 12 static const struct { |
13 const FX_CHAR*» m_pName; | 13 const FX_CHAR* m_pName; |
14 const FX_CHAR*» m_pSubstName; | 14 const FX_CHAR* m_pSubstName; |
15 } | 15 } Base14Substs[] = { |
16 Base14Substs[] = { | |
17 {"Courier", "Courier New"}, | 16 {"Courier", "Courier New"}, |
18 {"Courier-Bold", "Courier New Bold"}, | 17 {"Courier-Bold", "Courier New Bold"}, |
19 {"Courier-BoldOblique", "Courier New Bold Italic"}, | 18 {"Courier-BoldOblique", "Courier New Bold Italic"}, |
20 {"Courier-Oblique", "Courier New Italic"}, | 19 {"Courier-Oblique", "Courier New Italic"}, |
21 {"Helvetica", "Arial"}, | 20 {"Helvetica", "Arial"}, |
22 {"Helvetica-Bold", "Arial Bold"}, | 21 {"Helvetica-Bold", "Arial Bold"}, |
23 {"Helvetica-BoldOblique", "Arial Bold Italic"}, | 22 {"Helvetica-BoldOblique", "Arial Bold Italic"}, |
24 {"Helvetica-Oblique", "Arial Italic"}, | 23 {"Helvetica-Oblique", "Arial Italic"}, |
25 {"Times-Roman", "Times New Roman"}, | 24 {"Times-Roman", "Times New Roman"}, |
26 {"Times-Bold", "Times New Roman Bold"}, | 25 {"Times-Bold", "Times New Roman Bold"}, |
27 {"Times-BoldItalic", "Times New Roman Bold Italic"}, | 26 {"Times-BoldItalic", "Times New Roman Bold Italic"}, |
28 {"Times-Italic", "Times New Roman Italic"}, | 27 {"Times-Italic", "Times New Roman Italic"}, |
29 }; | 28 }; |
30 class CFX_LinuxFontInfo : public CFX_FolderFontInfo | 29 class CFX_LinuxFontInfo : public CFX_FolderFontInfo { |
31 { | 30 public: |
32 public: | 31 void* MapFont(int weight, |
33 void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, co
nst FX_CHAR* family, int& iExact) override; | 32 FX_BOOL bItalic, |
34 FX_BOOL» » » » ParseFontCfg(); | 33 int charset, |
35 void*» » » » FindFont(int weight, FX_BOOL bItalic, in
t charset, int pitch_family, const FX_CHAR* family, FX_BOOL bMatchName); | 34 int pitch_family, |
36 }; | 35 const FX_CHAR* family, |
37 #define LINUX_GPNAMESIZE» 6 | 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 |
38 static const struct { | 46 static const struct { |
39 const FX_CHAR* NameArr[LINUX_GPNAMESIZE]; | 47 const FX_CHAR* NameArr[LINUX_GPNAMESIZE]; |
40 } | 48 } LinuxGpFontList[] = { |
41 LinuxGpFontList[] = { | 49 {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", |
42 {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "
VL Gothic regular"}}, | 50 "VL Gothic regular"}}, |
43 {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic
regular"}}, | 51 {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, |
44 {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothi
c regular"}}, | 52 "VL Gothic regular"}}, |
45 {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "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"}}, |
46 }; | 57 }; |
47 static const FX_CHAR* const g_LinuxGbFontList[] = { | 58 static const FX_CHAR* const g_LinuxGbFontList[] = { |
48 "AR PL UMing CN Light", | 59 "AR PL UMing CN Light", "WenQuanYi Micro Hei", "AR PL UKai CN", |
49 "WenQuanYi Micro Hei", | |
50 "AR PL UKai CN", | |
51 }; | 60 }; |
52 static const FX_CHAR* const g_LinuxB5FontList[] = { | 61 static const FX_CHAR* const g_LinuxB5FontList[] = { |
53 "AR PL UMing TW Light", | 62 "AR PL UMing TW Light", "WenQuanYi Micro Hei", "AR PL UKai TW", |
54 "WenQuanYi Micro Hei", | |
55 "AR PL UKai TW", | |
56 }; | 63 }; |
57 static const FX_CHAR* const g_LinuxHGFontList[] = { | 64 static const FX_CHAR* const g_LinuxHGFontList[] = { |
58 "UnDotum", | 65 "UnDotum", |
59 }; | 66 }; |
60 static int32_t GetJapanesePreference(const FX_CHAR* facearr, int weight, int pic
th_family) | 67 static int32_t GetJapanesePreference(const FX_CHAR* facearr, |
61 { | 68 int weight, |
62 CFX_ByteString face = facearr; | 69 int picth_family) { |
63 if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e"
) >= 0) { | 70 CFX_ByteString face = facearr; |
64 if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83
\x62\x83\x4e") >= 0) { | 71 if (face.Find("Gothic") >= 0 || |
65 return 0; | 72 face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { |
66 } | 73 if (face.Find("PGothic") >= 0 || |
67 return 1; | 74 face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { |
68 } | 75 return 0; |
69 if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { | 76 } |
70 if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >
= 0) { | 77 return 1; |
71 return 2; | 78 } |
72 } | 79 if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { |
73 return 3; | 80 if (face.Find("PMincho") >= 0 || |
74 } | 81 face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { |
75 if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { | 82 return 2; |
76 return 0; | 83 } |
77 } | 84 return 3; |
78 return 2; | 85 } |
79 } | 86 if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { |
80 void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int p
itch_family, const FX_CHAR* cstr_face, int& iExact) | |
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 iExact = 1; | |
88 break; | |
89 } | |
90 if (iBaseFont < 12) { | |
91 return GetFont(face); | |
92 } | |
93 void* p = NULL; | |
94 FX_BOOL bCJK = TRUE; | |
95 switch (charset) { | |
96 case FXFONT_SHIFTJIS_CHARSET: { | |
97 int32_t index = GetJapanesePreference(cstr_face, weight, pitch_f
amily); | |
98 if (index < 0) { | |
99 break; | |
100 } | |
101 for (int32_t 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 int32_t s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(co
nst FX_CHAR*); | |
109 for (int32_t 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 int32_t s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(co
nst FX_CHAR*); | |
117 for (int32_t 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 int32_t s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(co
nst FX_CHAR*); | |
125 for (int32_t 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; | 87 return 0; |
159 } | 88 } |
160 static int32_t _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_fami
ly, FX_DWORD style) | 89 return 2; |
161 { | 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 CFontFaceInfo* 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 CFontFaceInfo* 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 } |
162 int32_t iSimilarValue = 0; | 213 int32_t iSimilarValue = 0; |
163 if ((style & FXFONT_BOLD) == (weight > 400)) { | 214 int32_t index = bsName.Find(family); |
164 iSimilarValue += 16; | 215 if (bMatchName && index < 0) { |
165 } | 216 continue; |
166 if ((style & FXFONT_ITALIC) == bItalic) { | 217 } |
167 iSimilarValue += 16; | 218 if (!bMatchName && index > 0) { |
168 } | 219 iSimilarValue += 64; |
169 if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { | 220 } |
170 iSimilarValue += 16; | 221 iSimilarValue = |
171 } | 222 _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); |
172 if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { | 223 if (iSimilarValue > iBestSimilar) { |
173 iSimilarValue += 8; | 224 iBestSimilar = iSimilarValue; |
174 } | 225 pFind = pFont; |
175 if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { | 226 } |
176 iSimilarValue += 8; | 227 } |
177 } | 228 return pFind; |
178 return iSimilarValue; | 229 } |
179 } | 230 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { |
180 void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int
pitch_family, const FX_CHAR* family, FX_BOOL bMatchName) | 231 CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo; |
181 { | 232 if (!pInfo->ParseFontCfg()) { |
182 CFontFaceInfo* pFind = NULL; | 233 pInfo->AddPath("/usr/share/fonts"); |
183 FX_DWORD charset_flag = _LinuxGetCharset(charset); | 234 pInfo->AddPath("/usr/share/X11/fonts/Type1"); |
184 int32_t iBestSimilar = 0; | 235 pInfo->AddPath("/usr/share/X11/fonts/TTF"); |
185 FX_POSITION pos = m_FontList.GetStartPosition(); | 236 pInfo->AddPath("/usr/local/share/fonts"); |
186 while (pos) { | 237 } |
187 CFX_ByteString bsName; | 238 return pInfo; |
188 CFontFaceInfo* pFont = NULL; | 239 } |
189 m_FontList.GetNextAssoc(pos, bsName, (void*&)pFont); | 240 FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() { |
190 if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHA
RSET) { | 241 return FALSE; |
191 continue; | 242 } |
192 } | 243 void CFX_GEModule::InitPlatform() { |
193 int32_t iSimilarValue = 0; | 244 m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); |
194 int32_t index = bsName.Find(family); | 245 } |
195 if (bMatchName && index < 0) { | 246 void CFX_GEModule::DestroyPlatform() {} |
196 continue; | |
197 } | |
198 if (!bMatchName && index > 0) { | |
199 iSimilarValue += 64; | |
200 } | |
201 iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFo
nt->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 // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ | 247 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ |
OLD | NEW |