~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/msw/font.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/msw/font.cpp
 
3
// Purpose:     wxFont class
 
4
// Author:      Julian Smart
 
5
// Modified by:
 
6
// Created:     01/02/97
 
7
// Copyright:   (c) wxWidgets team
 
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/font.h"
 
27
 
 
28
#ifndef WX_PRECOMP
 
29
    #include "wx/list.h"
 
30
    #include "wx/utils.h"
 
31
    #include "wx/app.h"
 
32
    #include "wx/log.h"
 
33
    #include "wx/msw/private.h"
 
34
#endif // WX_PRECOMP
 
35
 
 
36
#include "wx/encinfo.h"
 
37
#include "wx/fontutil.h"
 
38
#include "wx/fontmap.h"
 
39
 
 
40
#ifndef __WXWINCE__
 
41
    #include "wx/sysopt.h"
 
42
#endif
 
43
 
 
44
#include "wx/scopeguard.h"
 
45
#include "wx/tokenzr.h"
 
46
 
 
47
// ----------------------------------------------------------------------------
 
48
// constants
 
49
// ----------------------------------------------------------------------------
 
50
 
 
51
// the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
 
52
static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
 
53
 
 
54
// ----------------------------------------------------------------------------
 
55
// wxFontRefData - the internal description of the font
 
56
// ----------------------------------------------------------------------------
 
57
 
 
58
class WXDLLEXPORT wxFontRefData: public wxGDIRefData
 
59
{
 
60
public:
 
61
    // constructors
 
62
    wxFontRefData()
 
63
    {
 
64
        Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
 
65
             wxFONTWEIGHT_NORMAL, false, false, wxEmptyString,
 
66
             wxFONTENCODING_DEFAULT);
 
67
    }
 
68
 
 
69
    wxFontRefData(int size,
 
70
                  const wxSize& pixelSize,
 
71
                  bool sizeUsingPixels,
 
72
                  wxFontFamily family,
 
73
                  wxFontStyle style,
 
74
                  wxFontWeight weight,
 
75
                  bool underlined,
 
76
                  bool strikethrough,
 
77
                  const wxString& faceName,
 
78
                  wxFontEncoding encoding)
 
79
    {
 
80
        Init(size, pixelSize, sizeUsingPixels, family, style, weight,
 
81
             underlined, strikethrough, faceName, encoding);
 
82
    }
 
83
 
 
84
    wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
 
85
    {
 
86
        Init(info, hFont);
 
87
    }
 
88
 
 
89
    wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
 
90
    {
 
91
        Init(data.m_nativeFontInfo);
 
92
    }
 
93
 
 
94
    virtual ~wxFontRefData();
 
95
 
 
96
    // operations
 
97
    bool Alloc();
 
98
 
 
99
    void Free();
 
100
 
 
101
    // all wxFont accessors
 
102
    int GetPointSize() const
 
103
    {
 
104
        return m_nativeFontInfo.GetPointSize();
 
105
    }
 
106
 
 
107
    wxSize GetPixelSize() const
 
108
    {
 
109
        return m_nativeFontInfo.GetPixelSize();
 
110
    }
 
111
 
 
112
    bool IsUsingSizeInPixels() const
 
113
    {
 
114
        return m_sizeUsingPixels;
 
115
    }
 
116
 
 
117
    wxFontFamily GetFamily() const
 
118
    {
 
119
        return m_nativeFontInfo.GetFamily();
 
120
    }
 
121
 
 
122
    wxFontStyle GetStyle() const
 
123
    {
 
124
        return m_nativeFontInfo.GetStyle();
 
125
    }
 
126
 
 
127
    wxFontWeight GetWeight() const
 
128
    {
 
129
        return m_nativeFontInfo.GetWeight();
 
130
    }
 
131
 
 
132
    bool GetUnderlined() const
 
133
    {
 
134
        return m_nativeFontInfo.GetUnderlined();
 
135
    }
 
136
 
 
137
    bool GetStrikethrough() const
 
138
    {
 
139
        return m_nativeFontInfo.GetStrikethrough();
 
140
    }
 
141
 
 
142
    wxString GetFaceName() const
 
143
    {
 
144
        wxString facename = m_nativeFontInfo.GetFaceName();
 
145
        if ( facename.empty() )
 
146
        {
 
147
            facename = GetMSWFaceName();
 
148
            if ( !facename.empty() )
 
149
            {
 
150
                // cache the face name, it shouldn't change unless the family
 
151
                // does and wxNativeFontInfo::SetFamily() resets the face name
 
152
                const_cast<wxFontRefData *>(this)->SetFaceName(facename);
 
153
            }
 
154
        }
 
155
 
 
156
        return facename;
 
157
    }
 
158
 
 
159
    wxFontEncoding GetEncoding() const
 
160
    {
 
161
        return m_nativeFontInfo.GetEncoding();
 
162
    }
 
163
 
 
164
    WXHFONT GetHFONT() const
 
165
    {
 
166
        AllocIfNeeded();
 
167
 
 
168
        return (WXHFONT)m_hFont;
 
169
    }
 
170
 
 
171
    bool HasHFONT() const
 
172
    {
 
173
        return m_hFont != 0;
 
174
    }
 
175
 
 
176
    // ... and setters: notice that all of them invalidate the currently
 
177
    // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
 
178
    // new one
 
179
    void SetPointSize(int pointSize)
 
180
    {
 
181
        Free();
 
182
 
 
183
        m_nativeFontInfo.SetPointSize(pointSize);
 
184
        m_sizeUsingPixels = false;
 
185
    }
 
186
 
 
187
    void SetPixelSize(const wxSize& pixelSize)
 
188
    {
 
189
        wxCHECK_RET( pixelSize.GetWidth() >= 0, "negative font width" );
 
190
        wxCHECK_RET( pixelSize.GetHeight() != 0, "zero font height" );
 
191
 
 
192
        Free();
 
193
 
 
194
        m_nativeFontInfo.SetPixelSize(pixelSize);
 
195
        m_sizeUsingPixels = true;
 
196
    }
 
197
 
 
198
    void SetFamily(wxFontFamily family)
 
199
    {
 
200
        Free();
 
201
 
 
202
        m_nativeFontInfo.SetFamily(family);
 
203
    }
 
204
 
 
205
    void SetStyle(wxFontStyle style)
 
206
    {
 
207
        Free();
 
208
 
 
209
        m_nativeFontInfo.SetStyle(style);
 
210
    }
 
211
 
 
212
    void SetWeight(wxFontWeight weight)
 
213
    {
 
214
        Free();
 
215
 
 
216
        m_nativeFontInfo.SetWeight(weight);
 
217
    }
 
218
 
 
219
    bool SetFaceName(const wxString& faceName)
 
220
    {
 
221
        Free();
 
222
 
 
223
        return m_nativeFontInfo.SetFaceName(faceName);
 
224
    }
 
225
 
 
226
    void SetUnderlined(bool underlined)
 
227
    {
 
228
        Free();
 
229
 
 
230
        m_nativeFontInfo.SetUnderlined(underlined);
 
231
    }
 
232
 
 
233
    void SetStrikethrough(bool strikethrough)
 
234
    {
 
235
        Free();
 
236
 
 
237
        m_nativeFontInfo.SetStrikethrough(strikethrough);
 
238
    }
 
239
 
 
240
    void SetEncoding(wxFontEncoding encoding)
 
241
    {
 
242
        Free();
 
243
 
 
244
        m_nativeFontInfo.SetEncoding(encoding);
 
245
    }
 
246
 
 
247
    const wxNativeFontInfo& GetNativeFontInfo() const
 
248
    {
 
249
        // we need to create the font now to get the corresponding LOGFONT if
 
250
        // it hadn't been done yet
 
251
        AllocIfNeeded();
 
252
 
 
253
        // ensure that we have a valid face name in our font information:
 
254
        // GetFaceName() will try to retrieve it from our HFONT and save it if
 
255
        // it was successful
 
256
        (void)GetFaceName();
 
257
 
 
258
        return m_nativeFontInfo;
 
259
    }
 
260
 
 
261
    void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
 
262
    {
 
263
        Free();
 
264
 
 
265
        m_nativeFontInfo = nativeFontInfo;
 
266
    }
 
267
 
 
268
protected:
 
269
    // common part of all ctors
 
270
    void Init(int size,
 
271
              const wxSize& pixelSize,
 
272
              bool sizeUsingPixels,
 
273
              wxFontFamily family,
 
274
              wxFontStyle style,
 
275
              wxFontWeight weight,
 
276
              bool underlined,
 
277
              bool strikethrough,
 
278
              const wxString& faceName,
 
279
              wxFontEncoding encoding);
 
280
 
 
281
    void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
 
282
 
 
283
    void AllocIfNeeded() const
 
284
    {
 
285
        if ( !m_hFont )
 
286
            const_cast<wxFontRefData *>(this)->Alloc();
 
287
    }
 
288
 
 
289
    // retrieve the face name really being used by the font: this is used to
 
290
    // get the face name selected by the system when we don't specify it (but
 
291
    // use just the family for example)
 
292
    wxString GetMSWFaceName() const
 
293
    {
 
294
        ScreenHDC hdc;
 
295
        SelectInHDC selectFont(hdc, (HFONT)GetHFONT());
 
296
 
 
297
        UINT otmSize = GetOutlineTextMetrics(hdc, 0, NULL);
 
298
        if ( !otmSize )
 
299
        {
 
300
            wxLogLastError("GetOutlineTextMetrics(NULL)");
 
301
            return wxString();
 
302
        }
 
303
 
 
304
        OUTLINETEXTMETRIC * const
 
305
            otm = static_cast<OUTLINETEXTMETRIC *>(malloc(otmSize));
 
306
        wxON_BLOCK_EXIT1( free, otm );
 
307
 
 
308
        otm->otmSize = otmSize;
 
309
        if ( !GetOutlineTextMetrics(hdc, otmSize, otm) )
 
310
        {
 
311
            wxLogLastError("GetOutlineTextMetrics()");
 
312
            return wxString();
 
313
        }
 
314
 
 
315
        // in spite of its type, the otmpFamilyName field of OUTLINETEXTMETRIC
 
316
        // gives an offset in _bytes_ of the face (not family!) name from the
 
317
        // struct start while the name itself is an array of TCHARs
 
318
        //
 
319
        // FWIW otmpFaceName contains the same thing as otmpFamilyName followed
 
320
        // by a possible " Italic" or " Bold" or something else suffix
 
321
        return reinterpret_cast<wxChar *>(otm) +
 
322
                    wxPtrToUInt(otm->otmpFamilyName)/sizeof(wxChar);
 
323
    }
 
324
 
 
325
    // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size?
 
326
    bool             m_sizeUsingPixels;
 
327
 
 
328
    // Windows font handle, created on demand in GetHFONT()
 
329
    HFONT            m_hFont;
 
330
 
 
331
    // Native font info
 
332
    wxNativeFontInfo m_nativeFontInfo;
 
333
};
 
334
 
 
335
#define M_FONTDATA ((wxFontRefData*)m_refData)
 
336
 
 
337
// ============================================================================
 
338
// implementation
 
339
// ============================================================================
 
340
 
 
341
// ----------------------------------------------------------------------------
 
342
// wxFontRefData
 
343
// ----------------------------------------------------------------------------
 
344
 
 
345
void wxFontRefData::Init(int pointSize,
 
346
                         const wxSize& pixelSize,
 
347
                         bool sizeUsingPixels,
 
348
                         wxFontFamily family,
 
349
                         wxFontStyle style,
 
350
                         wxFontWeight weight,
 
351
                         bool underlined,
 
352
                         bool strikethrough,
 
353
                         const wxString& faceName,
 
354
                         wxFontEncoding encoding)
 
355
{
 
356
    m_hFont = NULL;
 
357
 
 
358
    m_sizeUsingPixels = sizeUsingPixels;
 
359
    if ( m_sizeUsingPixels )
 
360
        SetPixelSize(pixelSize);
 
361
    else
 
362
        SetPointSize(pointSize);
 
363
 
 
364
    SetStyle(style);
 
365
    SetWeight(weight);
 
366
    SetUnderlined(underlined);
 
367
    SetStrikethrough(strikethrough);
 
368
 
 
369
    // set the family/facename
 
370
    SetFamily(family);
 
371
    if ( !faceName.empty() )
 
372
        SetFaceName(faceName);
 
373
 
 
374
    // deal with encoding now (it may override the font family and facename
 
375
    // so do it after setting them)
 
376
    SetEncoding(encoding);
 
377
}
 
378
 
 
379
void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
 
380
{
 
381
    // hFont may be zero, or it be passed in case we really want to
 
382
    // use the exact font created in the underlying system
 
383
    // (for example where we can't guarantee conversion from HFONT
 
384
    // to LOGFONT back to HFONT)
 
385
    m_hFont = (HFONT)hFont;
 
386
    m_nativeFontInfo = info;
 
387
 
 
388
    // TODO: m_sizeUsingPixels?
 
389
}
 
390
 
 
391
wxFontRefData::~wxFontRefData()
 
392
{
 
393
    Free();
 
394
}
 
395
 
 
396
bool wxFontRefData::Alloc()
 
397
{
 
398
    m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
 
399
    if ( !m_hFont )
 
400
    {
 
401
        wxLogLastError(wxT("CreateFont"));
 
402
        return false;
 
403
    }
 
404
 
 
405
    return true;
 
406
}
 
407
 
 
408
void wxFontRefData::Free()
 
409
{
 
410
    if ( m_hFont )
 
411
    {
 
412
        if ( !::DeleteObject(m_hFont) )
 
413
        {
 
414
            wxLogLastError(wxT("DeleteObject(font)"));
 
415
        }
 
416
 
 
417
        m_hFont = 0;
 
418
    }
 
419
}
 
420
 
 
421
// ----------------------------------------------------------------------------
 
422
// wxNativeFontInfo
 
423
// ----------------------------------------------------------------------------
 
424
 
 
425
void wxNativeFontInfo::Init()
 
426
{
 
427
    wxZeroMemory(lf);
 
428
 
 
429
    // we get better font quality if we use PROOF_QUALITY instead of
 
430
    // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
 
431
    // then so we allow to set a global option to choose between quality and
 
432
    // wider font selection
 
433
#ifdef __WXWINCE__
 
434
    lf.lfQuality = CLEARTYPE_QUALITY;
 
435
#else
 
436
    lf.lfQuality = wxSystemOptions::GetOptionInt("msw.font.no-proof-quality")
 
437
                    ? DEFAULT_QUALITY
 
438
                    : PROOF_QUALITY;
 
439
#endif
 
440
}
 
441
 
 
442
int wxNativeFontInfo::GetPointSize() const
 
443
{
 
444
    // FIXME: using the screen here results in incorrect font size calculation
 
445
    //        for printing!
 
446
    const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
 
447
 
 
448
    // BC++ 2007 doesn't provide abs(long) overload, hence the cast
 
449
    return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5);
 
450
}
 
451
 
 
452
wxSize wxNativeFontInfo::GetPixelSize() const
 
453
{
 
454
    wxSize ret;
 
455
    ret.SetHeight(abs((int)lf.lfHeight));
 
456
    ret.SetWidth(lf.lfWidth);
 
457
    return ret;
 
458
}
 
459
 
 
460
wxFontStyle wxNativeFontInfo::GetStyle() const
 
461
{
 
462
    return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
 
463
}
 
464
 
 
465
wxFontWeight wxNativeFontInfo::GetWeight() const
 
466
{
 
467
    if ( lf.lfWeight <= 300 )
 
468
        return wxFONTWEIGHT_LIGHT;
 
469
 
 
470
    if ( lf.lfWeight >= 600 )
 
471
        return wxFONTWEIGHT_BOLD;
 
472
 
 
473
    return wxFONTWEIGHT_NORMAL;
 
474
}
 
475
 
 
476
bool wxNativeFontInfo::GetUnderlined() const
 
477
{
 
478
    return lf.lfUnderline != 0;
 
479
}
 
480
 
 
481
bool wxNativeFontInfo::GetStrikethrough() const
 
482
{
 
483
    return lf.lfStrikeOut != 0;
 
484
}
 
485
 
 
486
wxString wxNativeFontInfo::GetFaceName() const
 
487
{
 
488
    return lf.lfFaceName;
 
489
}
 
490
 
 
491
wxFontFamily wxNativeFontInfo::GetFamily() const
 
492
{
 
493
    wxFontFamily family;
 
494
 
 
495
    // extract family from pitch-and-family
 
496
    switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
 
497
    {
 
498
        case 0:
 
499
            family = wxFONTFAMILY_UNKNOWN;
 
500
            break;
 
501
 
 
502
        case FF_ROMAN:
 
503
            family = wxFONTFAMILY_ROMAN;
 
504
            break;
 
505
 
 
506
        case FF_SWISS:
 
507
            family = wxFONTFAMILY_SWISS;
 
508
            break;
 
509
 
 
510
        case FF_SCRIPT:
 
511
            family = wxFONTFAMILY_SCRIPT;
 
512
            break;
 
513
 
 
514
        case FF_MODERN:
 
515
            family = wxFONTFAMILY_MODERN;
 
516
            break;
 
517
 
 
518
        case FF_DECORATIVE:
 
519
            family = wxFONTFAMILY_DECORATIVE;
 
520
            break;
 
521
 
 
522
        default:
 
523
            wxFAIL_MSG( "unknown LOGFONT::lfFamily value" );
 
524
            family = wxFONTFAMILY_UNKNOWN;
 
525
                // just to avoid a warning
 
526
    }
 
527
 
 
528
    return family;
 
529
}
 
530
 
 
531
wxFontEncoding wxNativeFontInfo::GetEncoding() const
 
532
{
 
533
    return wxGetFontEncFromCharSet(lf.lfCharSet);
 
534
}
 
535
 
 
536
void wxNativeFontInfo::SetPointSize(int pointsize)
 
537
{
 
538
    // FIXME: using the screen here results in incorrect font size calculation
 
539
    //        for printing!
 
540
    const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
 
541
 
 
542
    lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
 
543
}
 
544
 
 
545
void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
 
546
{
 
547
    // MSW accepts both positive and negative heights here but they mean
 
548
    // different things: positive specifies the cell height while negative
 
549
    // specifies the character height. We used to just pass the value to MSW
 
550
    // unchanged but changed the behaviour for positive values in 2.9.1 to
 
551
    // match other ports and, more importantly, the expected behaviour. So now
 
552
    // passing the negative height doesn't make sense at all any more but we
 
553
    // still accept it for compatibility with the existing code which worked
 
554
    // around the wrong interpretation of the height argument in older wxMSW
 
555
    // versions by passing a negative value explicitly itself.
 
556
    lf.lfHeight = -abs(pixelSize.GetHeight());
 
557
    lf.lfWidth = pixelSize.GetWidth();
 
558
}
 
559
 
 
560
void wxNativeFontInfo::SetStyle(wxFontStyle style)
 
561
{
 
562
    switch ( style )
 
563
    {
 
564
        default:
 
565
            wxFAIL_MSG( "unknown font style" );
 
566
            // fall through
 
567
 
 
568
        case wxFONTSTYLE_NORMAL:
 
569
            lf.lfItalic = FALSE;
 
570
            break;
 
571
 
 
572
        case wxFONTSTYLE_ITALIC:
 
573
        case wxFONTSTYLE_SLANT:
 
574
            lf.lfItalic = TRUE;
 
575
            break;
 
576
    }
 
577
}
 
578
 
 
579
void wxNativeFontInfo::SetWeight(wxFontWeight weight)
 
580
{
 
581
    switch ( weight )
 
582
    {
 
583
        default:
 
584
            wxFAIL_MSG( "unknown font weight" );
 
585
            // fall through
 
586
 
 
587
        case wxFONTWEIGHT_NORMAL:
 
588
            lf.lfWeight = FW_NORMAL;
 
589
            break;
 
590
 
 
591
        case wxFONTWEIGHT_LIGHT:
 
592
            lf.lfWeight = FW_LIGHT;
 
593
            break;
 
594
 
 
595
        case wxFONTWEIGHT_BOLD:
 
596
            lf.lfWeight = FW_BOLD;
 
597
            break;
 
598
    }
 
599
}
 
600
 
 
601
void wxNativeFontInfo::SetUnderlined(bool underlined)
 
602
{
 
603
    lf.lfUnderline = underlined;
 
604
}
 
605
 
 
606
void wxNativeFontInfo::SetStrikethrough(bool strikethrough)
 
607
{
 
608
    lf.lfStrikeOut = strikethrough;
 
609
}
 
610
 
 
611
bool wxNativeFontInfo::SetFaceName(const wxString& facename)
 
612
{
 
613
    wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
 
614
    return true;
 
615
}
 
616
 
 
617
void wxNativeFontInfo::SetFamily(wxFontFamily family)
 
618
{
 
619
    BYTE ff_family = FF_DONTCARE;
 
620
 
 
621
    switch ( family )
 
622
    {
 
623
        case wxFONTFAMILY_SCRIPT:
 
624
            ff_family = FF_SCRIPT;
 
625
            break;
 
626
 
 
627
        case wxFONTFAMILY_DECORATIVE:
 
628
            ff_family = FF_DECORATIVE;
 
629
            break;
 
630
 
 
631
        case wxFONTFAMILY_ROMAN:
 
632
            ff_family = FF_ROMAN;
 
633
            break;
 
634
 
 
635
        case wxFONTFAMILY_TELETYPE:
 
636
        case wxFONTFAMILY_MODERN:
 
637
            ff_family = FF_MODERN;
 
638
            break;
 
639
 
 
640
        case wxFONTFAMILY_SWISS:
 
641
        case wxFONTFAMILY_DEFAULT:
 
642
            ff_family = FF_SWISS;
 
643
            break;
 
644
 
 
645
        case wxFONTFAMILY_UNKNOWN:
 
646
            wxFAIL_MSG( "invalid font family" );
 
647
            return;
 
648
    }
 
649
 
 
650
    wxCHECK_RET( ff_family != FF_DONTCARE, "unknown wxFontFamily" );
 
651
 
 
652
    lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
 
653
 
 
654
    // reset the facename so that CreateFontIndirect() will automatically choose a
 
655
    // face name based only on the font family.
 
656
    lf.lfFaceName[0] = '\0';
 
657
}
 
658
 
 
659
void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
 
660
{
 
661
    wxNativeEncodingInfo info;
 
662
    if ( !wxGetNativeFontEncoding(encoding, &info) )
 
663
    {
 
664
#if wxUSE_FONTMAP
 
665
        if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
 
666
        {
 
667
            if ( !info.facename.empty() )
 
668
            {
 
669
                // if we have this encoding only in some particular facename, use
 
670
                // the facename - it is better to show the correct characters in a
 
671
                // wrong facename than unreadable text in a correct one
 
672
                SetFaceName(info.facename);
 
673
            }
 
674
        }
 
675
        else
 
676
#endif // wxUSE_FONTMAP
 
677
        {
 
678
            // unsupported encoding, replace with the default
 
679
            info.charset = DEFAULT_CHARSET;
 
680
        }
 
681
    }
 
682
 
 
683
    lf.lfCharSet = (BYTE)info.charset;
 
684
}
 
685
 
 
686
bool wxNativeFontInfo::FromString(const wxString& s)
 
687
{
 
688
    long l;
 
689
 
 
690
    wxStringTokenizer tokenizer(s, wxS(";"), wxTOKEN_RET_EMPTY_ALL);
 
691
 
 
692
    // first the version
 
693
    wxString token = tokenizer.GetNextToken();
 
694
    if ( token != wxS('0') )
 
695
        return false;
 
696
 
 
697
    token = tokenizer.GetNextToken();
 
698
    if ( !token.ToLong(&l) )
 
699
        return false;
 
700
    lf.lfHeight = l;
 
701
 
 
702
    token = tokenizer.GetNextToken();
 
703
    if ( !token.ToLong(&l) )
 
704
        return false;
 
705
    lf.lfWidth = l;
 
706
 
 
707
    token = tokenizer.GetNextToken();
 
708
    if ( !token.ToLong(&l) )
 
709
        return false;
 
710
    lf.lfEscapement = l;
 
711
 
 
712
    token = tokenizer.GetNextToken();
 
713
    if ( !token.ToLong(&l) )
 
714
        return false;
 
715
    lf.lfOrientation = l;
 
716
 
 
717
    token = tokenizer.GetNextToken();
 
718
    if ( !token.ToLong(&l) )
 
719
        return false;
 
720
    lf.lfWeight = l;
 
721
 
 
722
    token = tokenizer.GetNextToken();
 
723
    if ( !token.ToLong(&l) )
 
724
        return false;
 
725
    lf.lfItalic = (BYTE)l;
 
726
 
 
727
    token = tokenizer.GetNextToken();
 
728
    if ( !token.ToLong(&l) )
 
729
        return false;
 
730
    lf.lfUnderline = (BYTE)l;
 
731
 
 
732
    token = tokenizer.GetNextToken();
 
733
    if ( !token.ToLong(&l) )
 
734
        return false;
 
735
    lf.lfStrikeOut = (BYTE)l;
 
736
 
 
737
    token = tokenizer.GetNextToken();
 
738
    if ( !token.ToLong(&l) )
 
739
        return false;
 
740
    lf.lfCharSet = (BYTE)l;
 
741
 
 
742
    token = tokenizer.GetNextToken();
 
743
    if ( !token.ToLong(&l) )
 
744
        return false;
 
745
    lf.lfOutPrecision = (BYTE)l;
 
746
 
 
747
    token = tokenizer.GetNextToken();
 
748
    if ( !token.ToLong(&l) )
 
749
        return false;
 
750
    lf.lfClipPrecision = (BYTE)l;
 
751
 
 
752
    token = tokenizer.GetNextToken();
 
753
    if ( !token.ToLong(&l) )
 
754
        return false;
 
755
    lf.lfQuality = (BYTE)l;
 
756
 
 
757
    token = tokenizer.GetNextToken();
 
758
    if ( !token.ToLong(&l) )
 
759
        return false;
 
760
    lf.lfPitchAndFamily = (BYTE)l;
 
761
 
 
762
    if ( !tokenizer.HasMoreTokens() )
 
763
        return false;
 
764
 
 
765
    // the face name may be empty
 
766
    SetFaceName(tokenizer.GetNextToken());
 
767
 
 
768
    return true;
 
769
}
 
770
 
 
771
wxString wxNativeFontInfo::ToString() const
 
772
{
 
773
    wxString s;
 
774
 
 
775
    s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
 
776
             0, // version, in case we want to change the format later
 
777
             lf.lfHeight,
 
778
             lf.lfWidth,
 
779
             lf.lfEscapement,
 
780
             lf.lfOrientation,
 
781
             lf.lfWeight,
 
782
             lf.lfItalic,
 
783
             lf.lfUnderline,
 
784
             lf.lfStrikeOut,
 
785
             lf.lfCharSet,
 
786
             lf.lfOutPrecision,
 
787
             lf.lfClipPrecision,
 
788
             lf.lfQuality,
 
789
             lf.lfPitchAndFamily,
 
790
             lf.lfFaceName);
 
791
 
 
792
    return s;
 
793
}
 
794
 
 
795
// ----------------------------------------------------------------------------
 
796
// wxFont
 
797
// ----------------------------------------------------------------------------
 
798
 
 
799
wxFont::wxFont(const wxString& fontdesc)
 
800
{
 
801
    wxNativeFontInfo info;
 
802
    if ( info.FromString(fontdesc) )
 
803
        (void)Create(info);
 
804
}
 
805
 
 
806
wxFont::wxFont(const wxFontInfo& info)
 
807
{
 
808
    m_refData = new wxFontRefData(info.GetPointSize(),
 
809
                                  info.GetPixelSize(),
 
810
                                  info.IsUsingSizeInPixels(),
 
811
                                  info.GetFamily(),
 
812
                                  info.GetStyle(),
 
813
                                  info.GetWeight(),
 
814
                                  info.IsUnderlined(),
 
815
                                  info.IsStrikethrough(),
 
816
                                  info.GetFaceName(),
 
817
                                  info.GetEncoding());
 
818
}
 
819
 
 
820
bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
 
821
{
 
822
    UnRef();
 
823
 
 
824
    m_refData = new wxFontRefData(info, hFont);
 
825
 
 
826
    return RealizeResource();
 
827
}
 
828
 
 
829
bool wxFont::DoCreate(int pointSize,
 
830
                      const wxSize& pixelSize,
 
831
                      bool sizeUsingPixels,
 
832
                      wxFontFamily family,
 
833
                      wxFontStyle style,
 
834
                      wxFontWeight weight,
 
835
                      bool underlined,
 
836
                      const wxString& faceName,
 
837
                      wxFontEncoding encoding)
 
838
{
 
839
    UnRef();
 
840
 
 
841
    // wxDEFAULT is a valid value for the font size too so we must treat it
 
842
    // specially here (otherwise the size would be 70 == wxDEFAULT value)
 
843
    if ( pointSize == wxDEFAULT || pointSize == -1 )
 
844
    {
 
845
        pointSize = wxNORMAL_FONT->GetPointSize();
 
846
    }
 
847
 
 
848
    m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
 
849
                                  family, style, weight,
 
850
                                  underlined, false, faceName, encoding);
 
851
 
 
852
    return RealizeResource();
 
853
}
 
854
 
 
855
wxFont::~wxFont()
 
856
{
 
857
}
 
858
 
 
859
// ----------------------------------------------------------------------------
 
860
// real implementation
 
861
// ----------------------------------------------------------------------------
 
862
 
 
863
wxGDIRefData *wxFont::CreateGDIRefData() const
 
864
{
 
865
    return new wxFontRefData();
 
866
}
 
867
 
 
868
wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
 
869
{
 
870
    return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
 
871
}
 
872
 
 
873
bool wxFont::RealizeResource()
 
874
{
 
875
    // NOTE: the GetHFONT() call automatically triggers a reallocation of
 
876
    //       the HFONT if necessary (will do nothing if we already have the resource);
 
877
    //       it returns NULL only if there is a failure in wxFontRefData::Alloc()...
 
878
    return GetHFONT() != NULL;
 
879
}
 
880
 
 
881
bool wxFont::FreeResource(bool WXUNUSED(force))
 
882
{
 
883
    if ( !M_FONTDATA )
 
884
        return false;
 
885
 
 
886
    M_FONTDATA->Free();
 
887
 
 
888
    return true;
 
889
}
 
890
 
 
891
WXHANDLE wxFont::GetResourceHandle() const
 
892
{
 
893
    return (WXHANDLE)GetHFONT();
 
894
}
 
895
 
 
896
WXHFONT wxFont::GetHFONT() const
 
897
{
 
898
    // NOTE: wxFontRefData::GetHFONT() will automatically call
 
899
    //       wxFontRefData::Alloc() if necessary
 
900
    return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
 
901
}
 
902
 
 
903
bool wxFont::IsFree() const
 
904
{
 
905
    return M_FONTDATA && !M_FONTDATA->HasHFONT();
 
906
}
 
907
 
 
908
// ----------------------------------------------------------------------------
 
909
// change font attribute: we recreate font when doing it
 
910
// ----------------------------------------------------------------------------
 
911
 
 
912
void wxFont::SetPointSize(int pointSize)
 
913
{
 
914
    AllocExclusive();
 
915
 
 
916
    M_FONTDATA->Free();
 
917
    M_FONTDATA->SetPointSize(pointSize);
 
918
}
 
919
 
 
920
void wxFont::SetPixelSize(const wxSize& pixelSize)
 
921
{
 
922
    AllocExclusive();
 
923
 
 
924
    M_FONTDATA->SetPixelSize(pixelSize);
 
925
}
 
926
 
 
927
void wxFont::SetFamily(wxFontFamily family)
 
928
{
 
929
    AllocExclusive();
 
930
 
 
931
    M_FONTDATA->SetFamily(family);
 
932
}
 
933
 
 
934
void wxFont::SetStyle(wxFontStyle style)
 
935
{
 
936
    AllocExclusive();
 
937
 
 
938
    M_FONTDATA->SetStyle(style);
 
939
}
 
940
 
 
941
void wxFont::SetWeight(wxFontWeight weight)
 
942
{
 
943
    AllocExclusive();
 
944
 
 
945
    M_FONTDATA->SetWeight(weight);
 
946
}
 
947
 
 
948
bool wxFont::SetFaceName(const wxString& faceName)
 
949
{
 
950
    AllocExclusive();
 
951
 
 
952
    if ( !M_FONTDATA->SetFaceName(faceName) )
 
953
        return false;
 
954
 
 
955
    // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
 
956
    //     to retrieve a LOGFONT and then compare lf.lfFaceName
 
957
    //     with given facename is not reliable at all:
 
958
    //     Windows copies the facename given to ::CreateFontIndirect()
 
959
    //     without any validity check.
 
960
    //     Thus we use wxFontBase::SetFaceName to check if facename
 
961
    //     is valid...
 
962
    return wxFontBase::SetFaceName(faceName);
 
963
}
 
964
 
 
965
void wxFont::SetUnderlined(bool underlined)
 
966
{
 
967
    AllocExclusive();
 
968
 
 
969
    M_FONTDATA->SetUnderlined(underlined);
 
970
}
 
971
 
 
972
void wxFont::SetStrikethrough(bool strikethrough)
 
973
{
 
974
    AllocExclusive();
 
975
 
 
976
    M_FONTDATA->SetStrikethrough(strikethrough);
 
977
}
 
978
 
 
979
void wxFont::SetEncoding(wxFontEncoding encoding)
 
980
{
 
981
    AllocExclusive();
 
982
 
 
983
    M_FONTDATA->SetEncoding(encoding);
 
984
}
 
985
 
 
986
void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
 
987
{
 
988
    AllocExclusive();
 
989
 
 
990
    M_FONTDATA->SetNativeFontInfo(info);
 
991
}
 
992
 
 
993
// ----------------------------------------------------------------------------
 
994
// accessors
 
995
// ----------------------------------------------------------------------------
 
996
 
 
997
int wxFont::GetPointSize() const
 
998
{
 
999
    wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
 
1000
 
 
1001
    return M_FONTDATA->GetPointSize();
 
1002
}
 
1003
 
 
1004
wxSize wxFont::GetPixelSize() const
 
1005
{
 
1006
    wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
 
1007
 
 
1008
    return M_FONTDATA->GetPixelSize();
 
1009
}
 
1010
 
 
1011
bool wxFont::IsUsingSizeInPixels() const
 
1012
{
 
1013
    wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
 
1014
 
 
1015
    return M_FONTDATA->IsUsingSizeInPixels();
 
1016
}
 
1017
 
 
1018
wxFontFamily wxFont::DoGetFamily() const
 
1019
{
 
1020
    return M_FONTDATA->GetFamily();
 
1021
}
 
1022
 
 
1023
wxFontStyle wxFont::GetStyle() const
 
1024
{
 
1025
    wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
 
1026
 
 
1027
    return M_FONTDATA->GetStyle();
 
1028
}
 
1029
 
 
1030
wxFontWeight wxFont::GetWeight() const
 
1031
{
 
1032
    wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
 
1033
 
 
1034
    return M_FONTDATA->GetWeight();
 
1035
}
 
1036
 
 
1037
bool wxFont::GetUnderlined() const
 
1038
{
 
1039
    wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
 
1040
 
 
1041
    return M_FONTDATA->GetUnderlined();
 
1042
}
 
1043
 
 
1044
bool wxFont::GetStrikethrough() const
 
1045
{
 
1046
    wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
 
1047
 
 
1048
    return M_FONTDATA->GetStrikethrough();
 
1049
}
 
1050
 
 
1051
wxString wxFont::GetFaceName() const
 
1052
{
 
1053
    wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
 
1054
 
 
1055
    return M_FONTDATA->GetFaceName();
 
1056
}
 
1057
 
 
1058
wxFontEncoding wxFont::GetEncoding() const
 
1059
{
 
1060
    wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
 
1061
 
 
1062
    return M_FONTDATA->GetEncoding();
 
1063
}
 
1064
 
 
1065
const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
 
1066
{
 
1067
    return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL;
 
1068
}
 
1069
 
 
1070
bool wxFont::IsFixedWidth() const
 
1071
{
 
1072
    wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
 
1073
 
 
1074
    // LOGFONT doesn't contain the correct pitch information so we need to call
 
1075
    // GetTextMetrics() to get it
 
1076
    ScreenHDC hdc;
 
1077
    SelectInHDC selectFont(hdc, M_FONTDATA->GetHFONT());
 
1078
 
 
1079
    TEXTMETRIC tm;
 
1080
    if ( !::GetTextMetrics(hdc, &tm) )
 
1081
    {
 
1082
        wxLogLastError(wxT("GetTextMetrics"));
 
1083
        return false;
 
1084
    }
 
1085
 
 
1086
    // Quoting MSDN description of TMPF_FIXED_PITCH: "Note very carefully that
 
1087
    // those meanings are the opposite of what the constant name implies."
 
1088
    return !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
 
1089
}