1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/fontutil.cpp
3 // Purpose:     font-related helper functions for wxMSW
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     05.11.99
7 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 #ifdef __BORLANDC__
23     #pragma hdrstop
24 #endif
25 
26 #include "wx/fontutil.h"
27 
28 #ifndef WX_PRECOMP
29     #include "wx/string.h"
30     #include "wx/log.h"
31     #include "wx/intl.h"
32     #include "wx/wxcrtvararg.h"
33     #include "wx/msw/private.h"
34 #endif //WX_PRECOMP
35 
36 #include "wx/encinfo.h"
37 #include "wx/fontmap.h"
38 #include "wx/tokenzr.h"
39 
40 // for MSVC5 and old w32api
41 #ifndef HANGUL_CHARSET
42 #    define HANGUL_CHARSET  129
43 #endif
44 
45 // ============================================================================
46 // implementation
47 // ============================================================================
48 
49 // ----------------------------------------------------------------------------
50 // wxNativeEncodingInfo
51 // ----------------------------------------------------------------------------
52 
53 // convert to/from the string representation: format is
54 //      encodingid;facename[;charset]
55 
FromString(const wxString & s)56 bool wxNativeEncodingInfo::FromString(const wxString& s)
57 {
58     wxStringTokenizer tokenizer(s, wxT(";"));
59 
60     wxString encid = tokenizer.GetNextToken();
61 
62     // we support 2 formats: the old one (and still used if !wxUSE_FONTMAP)
63     // used the raw encoding values but the new one uses the encoding names
64     long enc;
65     if ( encid.ToLong(&enc) )
66     {
67         // old format, intepret as encoding -- but after minimal checks
68         if ( enc < 0 || enc >= wxFONTENCODING_MAX )
69             return false;
70 
71         encoding = (wxFontEncoding)enc;
72     }
73     else // not a number, interpret as an encoding name
74     {
75 #if wxUSE_FONTMAP
76         encoding = wxFontMapper::GetEncodingFromName(encid);
77         if ( encoding == wxFONTENCODING_MAX )
78 #endif // wxUSE_FONTMAP
79         {
80             // failed to parse the name (or couldn't even try...)
81             return false;
82         }
83     }
84 
85     facename = tokenizer.GetNextToken();
86 
87     wxString tmp = tokenizer.GetNextToken();
88     if ( tmp.empty() )
89     {
90         // default charset: but don't use DEFAULT_CHARSET here because it might
91         // be different from the machine on which the file we had read this
92         // encoding desc from was created
93         charset = ANSI_CHARSET;
94     }
95     else
96     {
97         if ( wxSscanf(tmp, wxT("%u"), &charset) != 1 )
98         {
99             // should be a number!
100             return false;
101         }
102     }
103 
104     return true;
105 }
106 
ToString() const107 wxString wxNativeEncodingInfo::ToString() const
108 {
109     wxString s;
110 
111     s
112 #if wxUSE_FONTMAP
113       // use the encoding names as this is safer than using the numerical
114       // values which may change with time (because new encodings are
115       // inserted...)
116       << wxFontMapper::GetEncodingName(encoding)
117 #else // !wxUSE_FONTMAP
118       // we don't have any choice but to use the raw value
119       << (long)encoding
120 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
121       << wxT(';') << facename;
122 
123     // ANSI_CHARSET is assumed anyhow
124     if ( charset != ANSI_CHARSET )
125     {
126          s << wxT(';') << charset;
127     }
128 
129     return s;
130 }
131 
132 // ----------------------------------------------------------------------------
133 // helper functions
134 // ----------------------------------------------------------------------------
135 
wxGetNativeFontEncoding(wxFontEncoding encoding,wxNativeEncodingInfo * info)136 bool wxGetNativeFontEncoding(wxFontEncoding encoding,
137                              wxNativeEncodingInfo *info)
138 {
139     wxCHECK_MSG( info, false, wxT("bad pointer in wxGetNativeFontEncoding") );
140 
141     if ( encoding == wxFONTENCODING_DEFAULT )
142     {
143         encoding = wxFont::GetDefaultEncoding();
144     }
145 
146     extern WXDLLIMPEXP_BASE long wxEncodingToCharset(wxFontEncoding encoding);
147     info->charset = wxEncodingToCharset(encoding);
148     if ( info->charset == -1 )
149         return false;
150 
151     info->encoding = encoding;
152 
153     return true;
154 }
155 
wxTestFontEncoding(const wxNativeEncodingInfo & info)156 bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
157 {
158     // try to create such font
159     LOGFONT lf;
160     wxZeroMemory(lf);       // all default values
161 
162     lf.lfCharSet = (BYTE)info.charset;
163     wxStrlcpy(lf.lfFaceName, info.facename.c_str(), WXSIZEOF(lf.lfFaceName));
164 
165     HFONT hfont = ::CreateFontIndirect(&lf);
166     if ( !hfont )
167     {
168         // no such font
169         return false;
170     }
171 
172     ::DeleteObject((HGDIOBJ)hfont);
173 
174     return true;
175 }
176 
177 // ----------------------------------------------------------------------------
178 // wxFontEncoding <-> CHARSET_XXX
179 // ----------------------------------------------------------------------------
180 
wxGetFontEncFromCharSet(int cs)181 wxFontEncoding wxGetFontEncFromCharSet(int cs)
182 {
183     wxFontEncoding fontEncoding;
184 
185     switch ( cs )
186     {
187         default:
188             wxFAIL_MSG( wxT("unexpected Win32 charset") );
189             // fall through and assume the system charset
190 
191         case DEFAULT_CHARSET:
192             fontEncoding = wxFONTENCODING_SYSTEM;
193             break;
194 
195         case ANSI_CHARSET:
196             fontEncoding = wxFONTENCODING_CP1252;
197             break;
198 
199         case SYMBOL_CHARSET:
200             // what can we do here?
201             fontEncoding = wxFONTENCODING_MAX;
202             break;
203 
204 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
205         case EASTEUROPE_CHARSET:
206             fontEncoding = wxFONTENCODING_CP1250;
207             break;
208 
209         case BALTIC_CHARSET:
210             fontEncoding = wxFONTENCODING_CP1257;
211             break;
212 
213         case RUSSIAN_CHARSET:
214             fontEncoding = wxFONTENCODING_CP1251;
215             break;
216 
217         case ARABIC_CHARSET:
218             fontEncoding = wxFONTENCODING_CP1256;
219             break;
220 
221         case GREEK_CHARSET:
222             fontEncoding = wxFONTENCODING_CP1253;
223             break;
224 
225         case HEBREW_CHARSET:
226             fontEncoding = wxFONTENCODING_CP1255;
227             break;
228 
229         case TURKISH_CHARSET:
230             fontEncoding = wxFONTENCODING_CP1254;
231             break;
232 
233         case THAI_CHARSET:
234             fontEncoding = wxFONTENCODING_CP874;
235             break;
236 
237         case SHIFTJIS_CHARSET:
238             fontEncoding = wxFONTENCODING_CP932;
239             break;
240 
241         case GB2312_CHARSET:
242             fontEncoding = wxFONTENCODING_CP936;
243             break;
244 
245         case HANGUL_CHARSET:
246             fontEncoding = wxFONTENCODING_CP949;
247             break;
248 
249         case CHINESEBIG5_CHARSET:
250             fontEncoding = wxFONTENCODING_CP950;
251             break;
252 
253         case VIETNAMESE_CHARSET:
254             fontEncoding = wxFONTENCODING_CP1258;
255             break;
256 
257         case JOHAB_CHARSET:
258             fontEncoding = wxFONTENCODING_CP1361;
259             break;
260 
261         case MAC_CHARSET:
262             fontEncoding = wxFONTENCODING_MACROMAN;
263             break;
264 
265 #endif // Win32
266 
267         case OEM_CHARSET:
268             fontEncoding = wxFONTENCODING_CP437;
269             break;
270     }
271 
272     return fontEncoding;
273 }
274 
275 // ----------------------------------------------------------------------------
276 // wxFont <-> LOGFONT conversion
277 // ----------------------------------------------------------------------------
278 
wxFillLogFont(LOGFONT * logFont,const wxFont * font)279 void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
280 {
281     wxNativeFontInfo fi;
282 
283     // maybe we already have LOGFONT for this font?
284     const wxNativeFontInfo *pFI = font->GetNativeFontInfo();
285     if ( !pFI )
286     {
287         // use wxNativeFontInfo methods to build a LOGFONT for this font
288         fi.InitFromFont(*font);
289 
290         pFI = &fi;
291     }
292 
293     // transfer all the data to LOGFONT
294     *logFont = pFI->lf;
295 }
296 
wxCreateFontFromLogFont(const LOGFONT * logFont)297 wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
298 {
299     wxNativeFontInfo info;
300 
301     info.lf = *logFont;
302 
303     return wxFont(info);
304 }
305 
306