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