fixed another 2 instances of wxStrncpy bug
[wxWidgets.git] / src / msw / fontutil.cpp
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$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "fontutil.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/string.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35 #endif //WX_PRECOMP
36
37 #include "wx/msw/private.h"
38
39 #include "wx/fontutil.h"
40 #include "wx/fontmap.h"
41
42 #include "wx/tokenzr.h"
43
44 // for MSVC5 and old w32api
45 #ifndef HANGUL_CHARSET
46 # define HANGUL_CHARSET 129
47 #endif
48
49 // ============================================================================
50 // implementation
51 // ============================================================================
52
53 // ----------------------------------------------------------------------------
54 // wxNativeEncodingInfo
55 // ----------------------------------------------------------------------------
56
57 // convert to/from the string representation: format is
58 // encodingid;facename[;charset]
59
60 bool wxNativeEncodingInfo::FromString(const wxString& s)
61 {
62 wxStringTokenizer tokenizer(s, _T(";"));
63
64 wxString encid = tokenizer.GetNextToken();
65 long enc;
66 if ( !encid.ToLong(&enc) )
67 return FALSE;
68 encoding = (wxFontEncoding)enc;
69
70 facename = tokenizer.GetNextToken();
71
72 wxString tmp = tokenizer.GetNextToken();
73 if ( !tmp )
74 {
75 // default charset (don't use DEFAULT_CHARSET though because of subtle
76 // Windows 9x/NT differences in handling it)
77 charset = ANSI_CHARSET;
78 }
79 else
80 {
81 if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
82 {
83 // should be a number!
84 return FALSE;
85 }
86 }
87
88 return TRUE;
89 }
90
91 wxString wxNativeEncodingInfo::ToString() const
92 {
93 wxString s;
94
95 s << (long)encoding << _T(';') << facename;
96 if ( charset != ANSI_CHARSET )
97 {
98 s << _T(';') << charset;
99 }
100
101 return s;
102 }
103
104 // ----------------------------------------------------------------------------
105 // helper functions
106 // ----------------------------------------------------------------------------
107
108 bool wxGetNativeFontEncoding(wxFontEncoding encoding,
109 wxNativeEncodingInfo *info)
110 {
111 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
112
113 if ( encoding == wxFONTENCODING_DEFAULT )
114 {
115 encoding = wxFont::GetDefaultEncoding();
116 }
117
118 switch ( encoding )
119 {
120 // although this function is supposed to return an exact match, do do
121 // some mappings here for the most common case of "standard" encoding
122 case wxFONTENCODING_SYSTEM:
123 case wxFONTENCODING_ISO8859_1:
124 case wxFONTENCODING_ISO8859_15:
125 case wxFONTENCODING_CP1252:
126 info->charset = ANSI_CHARSET;
127 break;
128
129 #if !defined(__WIN16__) && !defined(__WXMICROWIN__)
130
131 // The following four fonts are multi-byte charsets
132 case wxFONTENCODING_CP932:
133 info->charset = SHIFTJIS_CHARSET;
134 break;
135
136 case wxFONTENCODING_CP936:
137 info->charset = GB2312_CHARSET;
138 break;
139
140 case wxFONTENCODING_CP949:
141 info->charset = HANGUL_CHARSET;
142 break;
143
144 case wxFONTENCODING_CP950:
145 info->charset = CHINESEBIG5_CHARSET;
146 break;
147
148 // The rest are single byte encodings
149 case wxFONTENCODING_CP1250:
150 info->charset = EASTEUROPE_CHARSET;
151 break;
152
153 case wxFONTENCODING_CP1251:
154 info->charset = RUSSIAN_CHARSET;
155 break;
156
157 case wxFONTENCODING_CP1253:
158 info->charset = GREEK_CHARSET;
159 break;
160
161 case wxFONTENCODING_CP1254:
162 info->charset = TURKISH_CHARSET;
163 break;
164
165 case wxFONTENCODING_CP1255:
166 info->charset = HEBREW_CHARSET;
167 break;
168
169 case wxFONTENCODING_CP1256:
170 info->charset = ARABIC_CHARSET;
171 break;
172
173 case wxFONTENCODING_CP1257:
174 info->charset = BALTIC_CHARSET;
175 break;
176
177 case wxFONTENCODING_CP874:
178 info->charset = THAI_CHARSET;
179 break;
180
181
182 #endif // !Win16
183
184 case wxFONTENCODING_CP437:
185 info->charset = OEM_CHARSET;
186 break;
187
188 default:
189 // no way to translate this encoding into a Windows charset
190 return FALSE;
191 }
192
193 info->encoding = encoding;
194
195 return TRUE;
196 }
197
198 bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
199 {
200 // try to create such font
201 LOGFONT lf;
202 wxZeroMemory(lf); // all default values
203
204 lf.lfCharSet = info.charset;
205 wxStrncpy(lf.lfFaceName, info.facename, WXSIZEOF(lf.lfFaceName));
206
207 HFONT hfont = ::CreateFontIndirect(&lf);
208 if ( !hfont )
209 {
210 // no such font
211 return FALSE;
212 }
213
214 ::DeleteObject((HGDIOBJ)hfont);
215
216 return TRUE;
217 }
218
219 // ----------------------------------------------------------------------------
220 // wxFontEncoding <-> CHARSET_XXX
221 // ----------------------------------------------------------------------------
222
223 wxFontEncoding wxGetFontEncFromCharSet(int cs)
224 {
225 wxFontEncoding fontEncoding;
226
227 switch ( cs )
228 {
229 default:
230 // JACS: Silently using ANSI_CHARSET
231 // apparently works for Chinese Windows. Assume it works
232 // for all/most other languages.
233 //wxFAIL_MSG(wxT("unsupported charset"));
234 // fall through
235
236 case ANSI_CHARSET:
237 fontEncoding = wxFONTENCODING_CP1252;
238 break;
239
240 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
241 case EASTEUROPE_CHARSET:
242 fontEncoding = wxFONTENCODING_CP1250;
243 break;
244
245 case BALTIC_CHARSET:
246 fontEncoding = wxFONTENCODING_CP1257;
247 break;
248
249 case RUSSIAN_CHARSET:
250 fontEncoding = wxFONTENCODING_CP1251;
251 break;
252
253 case ARABIC_CHARSET:
254 fontEncoding = wxFONTENCODING_CP1256;
255 break;
256
257 case GREEK_CHARSET:
258 fontEncoding = wxFONTENCODING_CP1253;
259 break;
260
261 case HEBREW_CHARSET:
262 fontEncoding = wxFONTENCODING_CP1255;
263 break;
264
265 case TURKISH_CHARSET:
266 fontEncoding = wxFONTENCODING_CP1254;
267 break;
268
269 case THAI_CHARSET:
270 fontEncoding = wxFONTENCODING_CP437;
271 break;
272
273 case SHIFTJIS_CHARSET:
274 fontEncoding = wxFONTENCODING_CP932;
275 break;
276
277 case GB2312_CHARSET:
278 fontEncoding = wxFONTENCODING_CP936;
279 break;
280
281 case HANGUL_CHARSET:
282 fontEncoding = wxFONTENCODING_CP949;
283 break;
284
285 case CHINESEBIG5_CHARSET:
286 fontEncoding = wxFONTENCODING_CP950;
287 break;
288
289 #endif // Win32
290
291 case OEM_CHARSET:
292 fontEncoding = wxFONTENCODING_CP437;
293 break;
294 }
295
296 return fontEncoding;
297 }
298
299 // ----------------------------------------------------------------------------
300 // wxFont <-> LOGFONT conversion
301 // ----------------------------------------------------------------------------
302
303 void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
304 {
305 // maybe we already have LOGFONT for this font?
306 wxNativeFontInfo *fontinfo = font->GetNativeFontInfo();
307 if ( !fontinfo )
308 {
309 // use wxNativeFontInfo methods to build a LOGFONT for this font
310 fontinfo = new wxNativeFontInfo;
311
312 // translate all font parameters
313 fontinfo->SetStyle((wxFontStyle)font->GetStyle());
314 fontinfo->SetWeight((wxFontWeight)font->GetWeight());
315 fontinfo->SetUnderlined(font->GetUnderlined());
316 fontinfo->SetPointSize(font->GetPointSize());
317
318 // set the family/facename
319 fontinfo->SetFamily((wxFontFamily)font->GetFamily());
320 wxString facename = font->GetFaceName();
321 if ( !facename.empty() )
322 {
323 fontinfo->SetFaceName(facename);
324 }
325
326 // deal with encoding now (it may override the font family and facename
327 // so do it after setting them)
328 fontinfo->SetEncoding(font->GetEncoding());
329 }
330
331 // transfer all the data to LOGFONT
332 *logFont = fontinfo->lf;
333
334 delete fontinfo;
335 }
336
337 wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
338 {
339 wxNativeFontInfo info;
340
341 info.lf = *logFont;
342
343 return wxFont(info);
344 }
345