1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        font.cpp
3 // Purpose:     wxFont demo
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     30.09.99
7 // Copyright:   (c) 1999 Vadim Zeitlin
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13 
14 
15 // for all others, include the necessary headers (this file is usually all you
16 // need because it includes almost all standard wxWidgets headers
17 #ifndef WX_PRECOMP
18     #include "wx/wx.h"
19 
20     #include "wx/log.h"
21 #endif
22 
23 #include "wx/checkbox.h"
24 #include "wx/choicdlg.h"
25 #include "wx/fontdlg.h"
26 #include "wx/fontenum.h"
27 #include "wx/fontmap.h"
28 #include "wx/encconv.h"
29 #include "wx/sizer.h"
30 #include "wx/spinctrl.h"
31 #include "wx/splitter.h"
32 #include "wx/statline.h"
33 #include "wx/stdpaths.h"
34 #include "wx/textfile.h"
35 #include "wx/settings.h"
36 
37 #include "../sample.xpm"
38 
39 #ifdef __WXMAC__
40     #undef wxFontDialog
41     #include "wx/osx/fontdlg.h"
42 #endif
43 
44 // used as title for several dialog boxes
GetSampleTitle()45 static wxString GetSampleTitle()
46 {
47     return "wxWidgets Font Sample";
48 }
49 
50 // ----------------------------------------------------------------------------
51 // private classes
52 // ----------------------------------------------------------------------------
53 
54 // Define a new application type, each program should derive a class from wxApp
55 class MyApp : public wxApp
56 {
57 public:
58     // override base class virtuals
59     // ----------------------------
60 
61     // this one is called on application startup and is a good place for the app
62     // initialization (doing it here and not in the ctor allows to have an error
63     // return: if OnInit() returns false, the application terminates)
64     virtual bool OnInit() wxOVERRIDE;
65 };
66 
67 // FontPanel contains controls allowing to specify the font properties
68 class FontPanel : public wxPanel
69 {
70 public:
71     explicit FontPanel(wxWindow* parent);
72 
ShowFont(const wxFont & font)73     void ShowFont(const wxFont& font) { m_font = font; DoUpdate(); }
74 
75     wxFontInfo GetFontInfo() const;
76 
77 private:
78     // Update m_useXXX flags depending on which control was changed last.
OnFacename(wxCommandEvent & e)79     void OnFacename(wxCommandEvent& e) { m_useFamily = false; e.Skip(); }
OnFamily(wxCommandEvent & e)80     void OnFamily(wxCommandEvent& e) { m_useFamily = true; e.Skip(); }
81 
OnWeightChoice(wxCommandEvent & e)82     void OnWeightChoice(wxCommandEvent& e) { m_useNumericWeight = false; e.Skip(); }
OnWeightSpin(wxCommandEvent & e)83     void OnWeightSpin(wxCommandEvent& e) { m_useNumericWeight = true; e.Skip(); }
84 
85 
86     // Unlike wxFontXXX, the elements of these enum are consecutive, which is
87     // more convenient here.
88     enum Family
89     {
90         Family_Default,
91         Family_Decorative,
92         Family_Roman,
93         Family_Script,
94         Family_Swiss,
95         Family_Modern,
96         Family_Teletype
97     };
98 
99     enum Style
100     {
101         Style_Normal,
102         Style_Italic,
103         Style_Slant
104     };
105 
106     enum Weight
107     {
108         Weight_Thin,
109         Weight_Extralight,
110         Weight_Light,
111         Weight_Normal,
112         Weight_Medium,
113         Weight_Semibold,
114         Weight_Bold,
115         Weight_Extrabold,
116         Weight_Heavy,
117         Weight_Extraheavy
118     };
119 
120     void DoUpdate();
121 
122     wxFont m_font;
123 
124     wxTextCtrl* m_textFaceName;
125     wxChoice* m_choiceFamily;
126     wxSpinCtrlDouble* m_spinPointSize;
127     wxChoice* m_choiceStyle;
128     wxChoice* m_choiceWeight;
129     wxSpinCtrl* m_spinWeight;
130     wxCheckBox* m_checkUnderlined;
131     wxCheckBox* m_checkStrikethrough;
132     wxCheckBox* m_checkFixedWidth;
133     wxStaticText* m_labelInfo;
134 
135     bool m_useFamily;
136     bool m_useNumericWeight;
137 };
138 
139 // FontCanvas shows the font characters.
140 class FontCanvas : public wxWindow
141 {
142 public:
143     explicit FontCanvas( wxWindow *parent );
144 
145     // accessors for FontWindow
GetTextFont() const146     const wxFont& GetTextFont() const { return m_font; }
GetColour() const147     const wxColour& GetColour() const { return m_colour; }
SetTextFont(const wxFont & font)148     void SetTextFont(const wxFont& font) { m_font = font; }
SetColour(const wxColour & colour)149     void SetColour(const wxColour& colour) { m_colour = colour; }
150 
151     // event handlers
152     void OnPaint( wxPaintEvent &event );
153 
154 protected:
DoGetBestClientSize() const155     virtual wxSize DoGetBestClientSize() const wxOVERRIDE
156     {
157         return wxSize(80*GetCharWidth(), 15*GetCharHeight());
158     }
159 
160 private:
161     wxColour m_colour;
162     wxFont   m_font;
163 
164     wxDECLARE_EVENT_TABLE();
165 };
166 
167 // FontWindow contains both FontPanel and FontCanvas
168 class FontWindow : public wxWindow
169 {
170 public:
171     explicit FontWindow(wxWindow *parent);
172 
GetTextFont() const173     const wxFont& GetTextFont() const { return m_canvas->GetTextFont(); }
GetColour() const174     const wxColour& GetColour() const { return m_canvas->GetColour(); }
175 
MakeNewFont() const176     wxFont MakeNewFont() const { return m_panel->GetFontInfo(); }
177 
178     void UpdateFont(const wxFont& font, const wxColour& colour);
179 
180 private:
181     FontPanel* const m_panel;
182     FontCanvas* const m_canvas;
183 };
184 
185 // Define a new frame type: this is going to be our main frame
186 class MyFrame : public wxFrame
187 {
188 public:
189     // ctor(s)
190     MyFrame();
191 
192     // event handlers (these functions should _not_ be virtual)
193     void OnQuit(wxCommandEvent& event);
194     void OnAbout(wxCommandEvent& event);
195 
OnGetBaseFont(wxCommandEvent & WXUNUSED (event))196     void OnGetBaseFont(wxCommandEvent& WXUNUSED(event))
197         { DoChangeFont(m_fontWindow->GetTextFont().GetBaseFont()); }
OnIncFont(wxCommandEvent & WXUNUSED (event))198     void OnIncFont(wxCommandEvent& WXUNUSED(event)) { DoResizeFont(+2); }
OnDecFont(wxCommandEvent & WXUNUSED (event))199     void OnDecFont(wxCommandEvent& WXUNUSED(event)) { DoResizeFont(-2); }
200 
201     void OnBold(wxCommandEvent& event);
202     void OnLight(wxCommandEvent& event);
203 
204     void OnItalic(wxCommandEvent& event);
205     void OnSlant(wxCommandEvent& event);
206 
207     void OnUnderline(wxCommandEvent& event);
208     void OnStrikethrough(wxCommandEvent& event);
209 
210     void OnwxPointerFont(wxCommandEvent& event);
211     void OnFontDefault(wxCommandEvent& event);
212     void OnwxSystemSettingsFont(wxCommandEvent& event);
213 
214     void OnTestTextValue(wxCommandEvent& event);
215     void OnViewMsg(wxCommandEvent& event);
216     void OnSelectFont(wxCommandEvent& event);
217     void OnEnumerateFamiliesForEncoding(wxCommandEvent& event);
OnEnumerateFamilies(wxCommandEvent & WXUNUSED (event))218     void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event))
219         { DoEnumerateFamilies(false); }
OnEnumerateFixedFamilies(wxCommandEvent & WXUNUSED (event))220     void OnEnumerateFixedFamilies(wxCommandEvent& WXUNUSED(event))
221         { DoEnumerateFamilies(true); }
222     void OnEnumerateEncodings(wxCommandEvent& event);
223 
224     void OnSetNativeDesc(wxCommandEvent& event);
225     void OnSetNativeUserDesc(wxCommandEvent& event);
226 
227     void OnSetFamily(wxCommandEvent& event);
228     void OnSetFaceName(wxCommandEvent& event);
229     void OnSetEncoding(wxCommandEvent& event);
230     void OnPrivateFont(wxCommandEvent& event);
231 
OnFontPanelApply(wxCommandEvent & WXUNUSED (event))232     void OnFontPanelApply(wxCommandEvent& WXUNUSED(event))
233         { DoChangeFont(m_fontWindow->MakeNewFont()); }
234 
235 protected:
236     bool DoEnumerateFamilies(bool fixedWidthOnly,
237                              wxFontEncoding encoding = wxFONTENCODING_SYSTEM,
238                              bool silent = false);
239 
240     void DoResizeFont(int diff);
241     void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour);
242 
243     // ask the user to choose an encoding and return it or
244     // wxFONTENCODING_SYSTEM if the dialog was cancelled
245     wxFontEncoding GetEncodingFromUser();
246 
247     // ask the user to choose a font family and return it or
248     // wxFONTFAMILY_DEFAULT if the dialog was cancelled
249     wxFontFamily GetFamilyFromUser();
250 
251     wxTextCtrl *m_textctrl;
252     FontWindow *m_fontWindow;
253 
254 private:
255     // any class wishing to process wxWidgets events must use this macro
256     wxDECLARE_EVENT_TABLE();
257 };
258 
259 // ----------------------------------------------------------------------------
260 // constants
261 // ----------------------------------------------------------------------------
262 
263 // IDs for the controls and the menu commands
264 enum
265 {
266     // menu items
267     Font_Quit = wxID_EXIT,
268     Font_About = wxID_ABOUT,
269 
270     Font_ViewMsg = wxID_HIGHEST+1,
271     Font_TestTextValue,
272 
273     Font_IncSize,
274     Font_DecSize,
275 
276     Font_GetBaseFont,
277 
278     Font_Bold,
279     Font_Light,
280 
281     Font_Italic,
282     Font_Slant,
283 
284     Font_Underlined,
285     Font_Strikethrough,
286 
287     // standard global wxFont objects:
288     Font_wxNORMAL_FONT,
289     Font_wxSMALL_FONT,
290     Font_wxITALIC_FONT,
291     Font_wxSWISS_FONT,
292     Font_wxFont_Default,
293     Font_Standard,
294 
295     // wxSystemSettings::GetFont possible objects:
296     Font_wxSYS_OEM_FIXED_FONT,
297     Font_wxSYS_ANSI_FIXED_FONT,
298     Font_wxSYS_ANSI_VAR_FONT,
299     Font_wxSYS_SYSTEM_FONT,
300     Font_wxSYS_DEVICE_DEFAULT_FONT,
301     Font_wxSYS_DEFAULT_GUI_FONT,
302     Font_SystemSettings,
303 
304     Font_Choose = 100,
305     Font_EnumFamiliesForEncoding,
306     Font_EnumFamilies,
307     Font_EnumFixedFamilies,
308     Font_EnumEncodings,
309     Font_SetNativeDesc,
310     Font_SetNativeUserDesc,
311     Font_SetFamily,
312     Font_SetFaceName,
313     Font_SetEncoding,
314 
315     Font_Private,
316     Font_Max
317 };
318 
319 // ----------------------------------------------------------------------------
320 // event tables and other macros for wxWidgets
321 // ----------------------------------------------------------------------------
322 
323 // the event tables connect the wxWidgets events with the functions (event
324 // handlers) which process them. It can be also done at run-time, but for the
325 // simple menu events like this the static method is much simpler.
326 wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
327     EVT_MENU(Font_Quit,  MyFrame::OnQuit)
328     EVT_MENU(Font_TestTextValue, MyFrame::OnTestTextValue)
329     EVT_MENU(Font_ViewMsg, MyFrame::OnViewMsg)
330     EVT_MENU(Font_About, MyFrame::OnAbout)
331 
332     EVT_MENU(Font_GetBaseFont, MyFrame::OnGetBaseFont)
333     EVT_MENU(Font_IncSize, MyFrame::OnIncFont)
334     EVT_MENU(Font_DecSize, MyFrame::OnDecFont)
335 
336     EVT_MENU(Font_Bold, MyFrame::OnBold)
337     EVT_MENU(Font_Light, MyFrame::OnLight)
338 
339     EVT_MENU(Font_Italic, MyFrame::OnItalic)
340     EVT_MENU(Font_Slant, MyFrame::OnSlant)
341 
342     EVT_MENU(Font_Underlined, MyFrame::OnUnderline)
343     EVT_MENU(Font_Strikethrough, MyFrame::OnStrikethrough)
344 
345     EVT_MENU(Font_wxNORMAL_FONT, MyFrame::OnwxPointerFont)
346     EVT_MENU(Font_wxSMALL_FONT, MyFrame::OnwxPointerFont)
347     EVT_MENU(Font_wxITALIC_FONT, MyFrame::OnwxPointerFont)
348     EVT_MENU(Font_wxSWISS_FONT, MyFrame::OnwxPointerFont)
349     EVT_MENU(Font_wxFont_Default, MyFrame::OnFontDefault)
350 
351     EVT_MENU(Font_wxSYS_OEM_FIXED_FONT, MyFrame::OnwxSystemSettingsFont)
352     EVT_MENU(Font_wxSYS_ANSI_FIXED_FONT, MyFrame::OnwxSystemSettingsFont)
353     EVT_MENU(Font_wxSYS_ANSI_VAR_FONT, MyFrame::OnwxSystemSettingsFont)
354     EVT_MENU(Font_wxSYS_SYSTEM_FONT, MyFrame::OnwxSystemSettingsFont)
355     EVT_MENU(Font_wxSYS_DEVICE_DEFAULT_FONT, MyFrame::OnwxSystemSettingsFont)
356     EVT_MENU(Font_wxSYS_DEFAULT_GUI_FONT, MyFrame::OnwxSystemSettingsFont)
357 
358     EVT_MENU(Font_SetNativeDesc, MyFrame::OnSetNativeDesc)
359     EVT_MENU(Font_SetNativeUserDesc, MyFrame::OnSetNativeUserDesc)
360     EVT_MENU(Font_SetFamily, MyFrame::OnSetFamily)
361     EVT_MENU(Font_SetFaceName, MyFrame::OnSetFaceName)
362     EVT_MENU(Font_SetEncoding, MyFrame::OnSetEncoding)
363 
364     EVT_MENU(Font_Choose, MyFrame::OnSelectFont)
365     EVT_MENU(Font_EnumFamiliesForEncoding, MyFrame::OnEnumerateFamiliesForEncoding)
366     EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies)
367     EVT_MENU(Font_EnumFixedFamilies, MyFrame::OnEnumerateFixedFamilies)
368     EVT_MENU(Font_EnumEncodings, MyFrame::OnEnumerateEncodings)
369     EVT_MENU(Font_Private, MyFrame::OnPrivateFont)
370 wxEND_EVENT_TABLE()
371 
372 // Create a new application object: this macro will allow wxWidgets to create
373 // the application object during program execution (it's better than using a
374 // static object for many reasons) and also declares the accessor function
375 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
376 // not wxApp)
377 wxIMPLEMENT_APP(MyApp);
378 
379 // ============================================================================
380 // implementation
381 // ============================================================================
382 
383 // ----------------------------------------------------------------------------
384 // the application class
385 // ----------------------------------------------------------------------------
386 
387 // `Main program' equivalent: the program execution "starts" here
OnInit()388 bool MyApp::OnInit()
389 {
390     if ( !wxApp::OnInit() )
391         return false;
392 
393     // Create the main application window
394     MyFrame *frame = new MyFrame();
395 
396     // Show it
397     frame->Show(true);
398 
399     // success: wxApp::OnRun() will be called which will enter the main message
400     // loop and the application will run. If we returned 'false' here, the
401     // application would exit immediately.
402     return true;
403 }
404 
405 // ----------------------------------------------------------------------------
406 // main frame
407 // ----------------------------------------------------------------------------
408 
409 // frame constructor
MyFrame()410 MyFrame::MyFrame()
411        : wxFrame(NULL, wxID_ANY, "wxWidgets font sample")
412 {
413     SetIcon(wxICON(sample));
414 
415     // create a menu bar
416     wxMenu *menuFile = new wxMenu;
417 
418     menuFile->Append(Font_TestTextValue, "&Test text value",
419                      "Verify that getting and setting text value doesn't change it");
420     menuFile->Append(Font_ViewMsg, "&View...\tCtrl-V",
421                      "View an email message file");
422     menuFile->AppendSeparator();
423     menuFile->Append(Font_About, "&About\tCtrl-A", "Show about dialog");
424     menuFile->AppendSeparator();
425     menuFile->Append(Font_Quit, "E&xit\tAlt-X", "Quit this program");
426 
427     wxMenu *menuFont = new wxMenu;
428     menuFont->Append(Font_IncSize, "&Increase font size by 2 points\tCtrl-I");
429     menuFont->Append(Font_DecSize, "&Decrease font size by 2 points\tCtrl-D");
430     menuFont->Append(Font_GetBaseFont, "Use &base version of the font\tCtrl-0");
431     menuFont->AppendSeparator();
432     menuFont->AppendCheckItem(Font_Bold, "&Bold\tCtrl-B", "Toggle bold state");
433     menuFont->AppendCheckItem(Font_Light, "&Light\tCtrl-L", "Toggle light state");
434     menuFont->AppendSeparator();
435     menuFont->AppendCheckItem(Font_Italic, "&Oblique\tCtrl-O", "Toggle italic state");
436 #ifndef __WXMSW__
437     // under wxMSW slant == italic so there's no reason to provide another menu item for the same thing
438     menuFont->AppendCheckItem(Font_Slant, "&Slant\tCtrl-S", "Toggle slant state");
439 #endif
440     menuFont->AppendSeparator();
441     menuFont->AppendCheckItem(Font_Underlined, "&Underlined\tCtrl-U",
442                               "Toggle underlined state");
443     menuFont->AppendCheckItem(Font_Strikethrough, "&Strikethrough",
444                               "Toggle strikethrough state");
445 
446     menuFont->AppendSeparator();
447     menuFont->Append(Font_SetNativeDesc,
448                      "Set native font &description\tShift-Ctrl-D");
449     menuFont->Append(Font_SetNativeUserDesc,
450                      "Set &user font description\tShift-Ctrl-U");
451     menuFont->AppendSeparator();
452     menuFont->Append(Font_SetFamily, "Set font family");
453     menuFont->Append(Font_SetFaceName, "Set font face name");
454     menuFont->Append(Font_SetEncoding, "Set font &encoding\tShift-Ctrl-E");
455 
456     wxMenu *menuSelect = new wxMenu;
457     menuSelect->Append(Font_Choose, "&Select font...\tCtrl-S",
458                        "Select a standard font");
459 
460     wxMenu *menuStdFonts = new wxMenu;
461     menuStdFonts->Append(Font_wxNORMAL_FONT, "wxNORMAL_FONT", "Normal font used by wxWidgets");
462     menuStdFonts->Append(Font_wxSMALL_FONT,  "wxSMALL_FONT",  "Small font used by wxWidgets");
463     menuStdFonts->Append(Font_wxITALIC_FONT, "wxITALIC_FONT", "Italic font used by wxWidgets");
464     menuStdFonts->Append(Font_wxSWISS_FONT,  "wxSWISS_FONT",  "Swiss font used by wxWidgets");
465     menuStdFonts->Append(Font_wxFont_Default,  "wxFont()",  "wxFont constructed from default wxFontInfo");
466     menuSelect->Append(Font_Standard, "Standar&d fonts", menuStdFonts);
467 
468     wxMenu *menuSettingFonts = new wxMenu;
469     menuSettingFonts->Append(Font_wxSYS_OEM_FIXED_FONT, "wxSYS_OEM_FIXED_FONT",
470                          "Original equipment manufacturer dependent fixed-pitch font.");
471     menuSettingFonts->Append(Font_wxSYS_ANSI_FIXED_FONT,  "wxSYS_ANSI_FIXED_FONT",
472                          "Windows fixed-pitch (monospaced) font. ");
473     menuSettingFonts->Append(Font_wxSYS_ANSI_VAR_FONT, "wxSYS_ANSI_VAR_FONT",
474                          "Windows variable-pitch (proportional) font.");
475     menuSettingFonts->Append(Font_wxSYS_SYSTEM_FONT,  "wxSYS_SYSTEM_FONT",
476                          "System font.");
477     menuSettingFonts->Append(Font_wxSYS_DEVICE_DEFAULT_FONT,  "wxSYS_DEVICE_DEFAULT_FONT",
478                          "Device-dependent font.");
479     menuSettingFonts->Append(Font_wxSYS_DEFAULT_GUI_FONT,  "wxSYS_DEFAULT_GUI_FONT",
480                          "Default font for user interface objects such as menus and dialog boxes. ");
481     menuSelect->Append(Font_SystemSettings, "System fonts", menuSettingFonts);
482 
483     menuSelect->AppendSeparator();
484     menuSelect->Append(Font_EnumFamilies, "Enumerate font &families\tCtrl-F");
485     menuSelect->Append(Font_EnumFixedFamilies,
486                      "Enumerate fi&xed font families\tCtrl-X");
487     menuSelect->Append(Font_EnumEncodings,
488                      "Enumerate &encodings\tCtrl-E");
489     menuSelect->Append(Font_EnumFamiliesForEncoding,
490                      "Find font for en&coding...\tCtrl-C",
491                      "Find font families for given encoding");
492 
493 #if wxUSE_PRIVATE_FONTS
494     // Try to use a private font, under most platforms we just look for it in
495     // the current directory but under OS X it must be in a specific location
496     // so look for it there.
497     //
498     // For OS X you also need to ensure that you actually do put wxprivate.ttf
499     // in font.app/Contents/Resources/Fonts and add the following snippet
500     //
501     //     <plist version="0.9">
502     //       <dict>
503     //         ...
504     //         <key>ATSApplicationFontsPath</key>
505     //         <string>Fonts</string>
506     //         ...
507     //       </dict>
508     //     </plist>
509     //
510     // to your font.app/Contents/Info.plist.
511 
512     wxString privfont;
513 #ifdef __WXOSX__
514     privfont << wxStandardPaths::Get().GetResourcesDir() << "/Fonts/";
515 #endif
516     privfont << "wxprivate.ttf";
517 
518     if ( !wxFont::AddPrivateFont(privfont) )
519     {
520         wxLogWarning("Failed to add private font from \"%s\"", privfont);
521     }
522     else
523     {
524         menuSelect->AppendSeparator();
525         menuSelect->Append(Font_Private,
526                            "Select private font",
527                            "Select a font available only in this application");
528     }
529 #endif // wxUSE_PRIVATE_FONTS
530 
531 
532     // now append the freshly created menu to the menu bar...
533     wxMenuBar *menuBar = new wxMenuBar;
534     menuBar->Append(menuFile, "&File");
535     menuBar->Append(menuFont, "F&ont");
536     menuBar->Append(menuSelect, "&Select");
537 
538     // ... and attach this menu bar to the frame
539     SetMenuBar(menuBar);
540 
541     wxSplitterWindow *splitter = new wxSplitterWindow(this);
542 
543     m_fontWindow = new FontWindow(splitter);
544 
545     m_fontWindow->Bind(wxEVT_BUTTON, &MyFrame::OnFontPanelApply, this);
546 
547     m_textctrl = new wxTextCtrl(splitter, wxID_ANY,
548                                 "Paste text here to see how it looks\nlike in the given font",
549                                 wxDefaultPosition,
550                                 wxSize(-1, 6*GetCharHeight()),
551                                 wxTE_MULTILINE);
552 
553     splitter->SplitHorizontally(m_fontWindow, m_textctrl, 0);
554 
555 #if wxUSE_STATUSBAR
556     // create a status bar just for fun (by default with 1 pane only)
557     CreateStatusBar();
558     SetStatusText("Welcome to wxWidgets font demo!");
559 #endif // wxUSE_STATUSBAR
560 
561     SetClientSize(splitter->GetBestSize());
562     splitter->SetSashPosition(m_fontWindow->GetBestSize().y);
563 }
564 
565 // --------------------------------------------------------
566 
567 class MyEncodingEnumerator : public wxFontEnumerator
568 {
569 public:
MyEncodingEnumerator()570     MyEncodingEnumerator()
571         { m_n = 0; }
572 
GetText() const573     const wxString& GetText() const
574         { return m_text; }
575 
576 protected:
OnFontEncoding(const wxString & facename,const wxString & encoding)577     virtual bool OnFontEncoding(const wxString& facename,
578                                 const wxString& encoding) wxOVERRIDE
579     {
580         wxString text;
581         text.Printf("Encoding %u: %s (available in facename '%s')\n",
582                     (unsigned int) ++m_n, encoding, facename);
583         m_text += text;
584         return true;
585     }
586 
587 private:
588     size_t m_n;
589     wxString m_text;
590 };
591 
OnEnumerateEncodings(wxCommandEvent & WXUNUSED (event))592 void MyFrame::OnEnumerateEncodings(wxCommandEvent& WXUNUSED(event))
593 {
594     MyEncodingEnumerator fontEnumerator;
595 
596     fontEnumerator.EnumerateEncodings();
597 
598     wxLogMessage("Enumerating all available encodings:\n%s",
599                  fontEnumerator.GetText());
600 }
601 
602 // -------------------------------------------------------------
603 
604 class MyFontEnumerator : public wxFontEnumerator
605 {
606 public:
GotAny() const607     bool GotAny() const
608         { return !m_facenames.IsEmpty(); }
609 
GetFacenames() const610     const wxArrayString& GetFacenames() const
611         { return m_facenames; }
612 
613 protected:
OnFacename(const wxString & facename)614     virtual bool OnFacename(const wxString& facename) wxOVERRIDE
615     {
616         m_facenames.Add(facename);
617         return true;
618     }
619 
620     private:
621         wxArrayString m_facenames;
622 };
623 
DoEnumerateFamilies(bool fixedWidthOnly,wxFontEncoding encoding,bool silent)624 bool MyFrame::DoEnumerateFamilies(bool fixedWidthOnly,
625                                   wxFontEncoding encoding,
626                                   bool silent)
627 {
628     MyFontEnumerator fontEnumerator;
629 
630     fontEnumerator.EnumerateFacenames(encoding, fixedWidthOnly);
631 
632     if ( fontEnumerator.GotAny() )
633     {
634         int nFacenames = fontEnumerator.GetFacenames().GetCount();
635         if ( !silent )
636         {
637             wxLogStatus(this, "Found %d %sfonts",
638                         nFacenames, fixedWidthOnly ? "fixed width " : "");
639         }
640 
641         wxString facename;
642 
643         if ( silent )
644         {
645             // choose the first
646             facename = fontEnumerator.GetFacenames().Item(0);
647         }
648         else
649         {
650             // let the user choose
651             wxString *facenames = new wxString[nFacenames];
652             int n;
653             for ( n = 0; n < nFacenames; n++ )
654                 facenames[n] = fontEnumerator.GetFacenames().Item(n);
655 
656             n = wxGetSingleChoiceIndex
657                 (
658                     "Choose a facename",
659                     GetSampleTitle(),
660                     nFacenames,
661                     facenames,
662                     this
663                 );
664 
665             if ( n != -1 )
666                 facename = facenames[n];
667 
668             delete [] facenames;
669         }
670 
671         if ( !facename.empty() )
672         {
673             wxFont font(wxFontInfo().FaceName(facename).Encoding(encoding));
674 
675             DoChangeFont(font);
676         }
677 
678         return true;
679     }
680     else if ( !silent )
681     {
682         wxLogWarning("No such fonts found.");
683     }
684 
685     return false;
686 }
687 
OnEnumerateFamiliesForEncoding(wxCommandEvent & WXUNUSED (event))688 void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event))
689 {
690     wxFontEncoding enc = GetEncodingFromUser();
691     if ( enc != wxFONTENCODING_SYSTEM )
692     {
693         DoEnumerateFamilies(false, enc);
694     }
695 }
696 
OnSetNativeDesc(wxCommandEvent & WXUNUSED (event))697 void MyFrame::OnSetNativeDesc(wxCommandEvent& WXUNUSED(event))
698 {
699     wxString fontInfo = wxGetTextFromUser
700                         (
701                             "Enter native font string",
702                             "Input font description",
703                             m_fontWindow->GetTextFont().GetNativeFontInfoDesc(),
704                             this
705                         );
706     if ( fontInfo.empty() )
707         return;     // user clicked "Cancel" - do nothing
708 
709     wxFont font;
710     font.SetNativeFontInfo(fontInfo);
711     if ( !font.IsOk() )
712     {
713         wxLogError("Font info string \"%s\" is invalid.",
714                    fontInfo);
715         return;
716     }
717 
718     DoChangeFont(font);
719 }
720 
OnSetNativeUserDesc(wxCommandEvent & WXUNUSED (event))721 void MyFrame::OnSetNativeUserDesc(wxCommandEvent& WXUNUSED(event))
722 {
723     wxString fontdesc = m_fontWindow->GetTextFont().GetNativeFontInfoUserDesc();
724     wxString fontUserInfo = wxGetTextFromUser(
725             "Here you can edit current font description",
726             "Input font description", fontdesc,
727             this);
728     if (fontUserInfo.IsEmpty())
729         return;     // user clicked "Cancel" - do nothing
730 
731     wxFont font;
732     if (font.SetNativeFontInfoUserDesc(fontUserInfo))
733     {
734         wxASSERT_MSG(font.IsOk(), "The font should now be valid");
735         DoChangeFont(font);
736     }
737     else
738     {
739         wxASSERT_MSG(!font.IsOk(), "The font should now be invalid");
740         wxMessageBox("Error trying to create a font with such description...");
741     }
742 }
743 
OnSetFamily(wxCommandEvent & WXUNUSED (event))744 void MyFrame::OnSetFamily(wxCommandEvent& WXUNUSED(event))
745 {
746     wxFontFamily f = GetFamilyFromUser();
747 
748     wxFont font = m_fontWindow->GetTextFont();
749     font.SetFamily(f);
750     DoChangeFont(font);
751 }
752 
OnSetFaceName(wxCommandEvent & WXUNUSED (event))753 void MyFrame::OnSetFaceName(wxCommandEvent& WXUNUSED(event))
754 {
755     wxString facename = m_fontWindow->GetTextFont().GetFaceName();
756     wxString newFaceName = wxGetTextFromUser(
757             "Here you can edit current font face name.",
758             "Input font facename", facename,
759             this);
760     if (newFaceName.IsEmpty())
761         return;     // user clicked "Cancel" - do nothing
762 
763     wxFont font(m_fontWindow->GetTextFont());
764     if (font.SetFaceName(newFaceName))      // change facename only
765     {
766         wxASSERT_MSG(font.IsOk(), "The font should now be valid");
767         DoChangeFont(font);
768     }
769     else
770     {
771         wxASSERT_MSG(!font.IsOk(), "The font should now be invalid");
772         wxMessageBox("There is no font with such face name...",
773                      "Invalid face name", wxOK|wxICON_ERROR, this);
774     }
775 }
776 
OnSetEncoding(wxCommandEvent & WXUNUSED (event))777 void MyFrame::OnSetEncoding(wxCommandEvent& WXUNUSED(event))
778 {
779     wxFontEncoding enc = GetEncodingFromUser();
780     if ( enc == wxFONTENCODING_SYSTEM )
781         return;
782 
783     wxFont font = m_fontWindow->GetTextFont();
784     font.SetEncoding(enc);
785     DoChangeFont(font);
786 }
787 
GetEncodingFromUser()788 wxFontEncoding MyFrame::GetEncodingFromUser()
789 {
790     wxArrayString names;
791     wxArrayInt encodings;
792 
793     const size_t count = wxFontMapper::GetSupportedEncodingsCount();
794     names.reserve(count);
795     encodings.reserve(count);
796 
797     for ( size_t n = 0; n < count; n++ )
798     {
799         wxFontEncoding enc = wxFontMapper::GetEncoding(n);
800         encodings.push_back(enc);
801         names.push_back(wxFontMapper::GetEncodingName(enc));
802     }
803 
804     int i = wxGetSingleChoiceIndex
805             (
806                 "Choose the encoding",
807                 GetSampleTitle(),
808                 names,
809                 this
810             );
811 
812     return i == -1 ? wxFONTENCODING_SYSTEM : (wxFontEncoding)encodings[i];
813 }
814 
GetFamilyFromUser()815 wxFontFamily MyFrame::GetFamilyFromUser()
816 {
817     wxArrayString names;
818     wxArrayInt families;
819 
820     families.push_back(wxFONTFAMILY_DECORATIVE);
821     families.push_back(wxFONTFAMILY_ROMAN);
822     families.push_back(wxFONTFAMILY_SCRIPT);
823     families.push_back(wxFONTFAMILY_SWISS);
824     families.push_back(wxFONTFAMILY_MODERN);
825     families.push_back(wxFONTFAMILY_TELETYPE);
826 
827     names.push_back("DECORATIVE");
828     names.push_back("ROMAN");
829     names.push_back("SCRIPT");
830     names.push_back("SWISS");
831     names.push_back("MODERN");
832     names.push_back("TELETYPE");
833 
834     int i = wxGetSingleChoiceIndex
835             (
836                 "Choose the family",
837                 GetSampleTitle(),
838                 names,
839                 this
840             );
841 
842     return i == -1 ? wxFONTFAMILY_DEFAULT : (wxFontFamily)families[i];
843 }
844 
DoResizeFont(int diff)845 void MyFrame::DoResizeFont(int diff)
846 {
847     wxFont font = m_fontWindow->GetTextFont();
848 
849     font.SetPointSize(font.GetPointSize() + diff);
850     DoChangeFont(font);
851 }
852 
OnBold(wxCommandEvent & event)853 void MyFrame::OnBold(wxCommandEvent& event)
854 {
855     wxFont font = m_fontWindow->GetTextFont();
856 
857     font.SetWeight(event.IsChecked() ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
858     DoChangeFont(font);
859 }
860 
OnLight(wxCommandEvent & event)861 void MyFrame::OnLight(wxCommandEvent& event)
862 {
863     wxFont font = m_fontWindow->GetTextFont();
864 
865     font.SetWeight(event.IsChecked() ? wxFONTWEIGHT_LIGHT : wxFONTWEIGHT_NORMAL);
866     DoChangeFont(font);
867 }
868 
OnItalic(wxCommandEvent & event)869 void MyFrame::OnItalic(wxCommandEvent& event)
870 {
871     wxFont font = m_fontWindow->GetTextFont();
872 
873     font.SetStyle(event.IsChecked() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL);
874     DoChangeFont(font);
875 }
876 
OnSlant(wxCommandEvent & event)877 void MyFrame::OnSlant(wxCommandEvent& event)
878 {
879     wxFont font = m_fontWindow->GetTextFont();
880 
881     font.SetStyle(event.IsChecked() ? wxFONTSTYLE_SLANT : wxFONTSTYLE_NORMAL);
882     DoChangeFont(font);
883 }
884 
OnUnderline(wxCommandEvent & event)885 void MyFrame::OnUnderline(wxCommandEvent& event)
886 {
887     wxFont font = m_fontWindow->GetTextFont();
888 
889     font.SetUnderlined(event.IsChecked());
890     DoChangeFont(font);
891 }
892 
OnStrikethrough(wxCommandEvent & event)893 void MyFrame::OnStrikethrough(wxCommandEvent& event)
894 {
895     wxFont font = m_fontWindow->GetTextFont();
896     font.SetStrikethrough(event.IsChecked());
897     DoChangeFont(font);
898 }
899 
OnwxPointerFont(wxCommandEvent & event)900 void MyFrame::OnwxPointerFont(wxCommandEvent& event)
901 {
902     wxFont font;
903 
904     switch ( event.GetId() )
905     {
906         case Font_wxNORMAL_FONT:
907             font = *wxNORMAL_FONT;
908             break;
909 
910         case Font_wxSMALL_FONT:
911             font = *wxSMALL_FONT;
912             break;
913 
914         case Font_wxITALIC_FONT:
915             font = *wxITALIC_FONT;
916             break;
917 
918         case Font_wxSWISS_FONT:
919             font = *wxSWISS_FONT;
920             break;
921 
922         default:
923             wxFAIL_MSG( "unknown standard font" );
924             return;
925     }
926 
927     DoChangeFont(font);
928 }
929 
OnFontDefault(wxCommandEvent & WXUNUSED (event))930 void MyFrame::OnFontDefault(wxCommandEvent& WXUNUSED(event))
931 {
932     DoChangeFont(wxFont(wxFontInfo()));
933 }
934 
OnwxSystemSettingsFont(wxCommandEvent & event)935 void MyFrame::OnwxSystemSettingsFont(wxCommandEvent& event)
936 {
937     wxFont font;
938 
939     switch ( event.GetId() )
940     {
941         case Font_wxSYS_OEM_FIXED_FONT:
942             font = wxSystemSettings::GetFont(wxSYS_OEM_FIXED_FONT);
943             break;
944 
945         case Font_wxSYS_ANSI_FIXED_FONT:
946             font = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT);
947             break;
948 
949         case Font_wxSYS_ANSI_VAR_FONT:
950             font = wxSystemSettings::GetFont(wxSYS_ANSI_VAR_FONT);
951             break;
952 
953         case Font_wxSYS_SYSTEM_FONT:
954             font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
955             break;
956 
957         case Font_wxSYS_DEVICE_DEFAULT_FONT:
958             font = wxSystemSettings::GetFont(wxSYS_DEVICE_DEFAULT_FONT);
959             break;
960 
961         case Font_wxSYS_DEFAULT_GUI_FONT:
962             font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
963             break;
964 
965         default:
966             wxFAIL_MSG( "unknown standard font" );
967             return;
968     }
969 
970     DoChangeFont(font);
971 }
972 
DoChangeFont(const wxFont & font,const wxColour & col)973 void MyFrame::DoChangeFont(const wxFont& font, const wxColour& col)
974 {
975     m_fontWindow->UpdateFont(font, col);
976 
977     m_textctrl->SetFont(font);
978     if ( col.IsOk() )
979         m_textctrl->SetForegroundColour(col);
980     m_textctrl->Refresh();
981 
982     // update the state of the bold/italic/underlined menu items
983     wxMenuBar *mbar = GetMenuBar();
984     if ( mbar )
985     {
986         mbar->Check(Font_Light, font.GetWeight() == wxFONTWEIGHT_LIGHT);
987         mbar->Check(Font_Bold, font.GetWeight() == wxFONTWEIGHT_BOLD);
988 
989         mbar->Check(Font_Italic, font.GetStyle() == wxFONTSTYLE_ITALIC);
990 #ifndef __WXMSW__
991         mbar->Check(Font_Slant, font.GetStyle() == wxFONTSTYLE_SLANT);
992 #endif
993 
994         mbar->Check(Font_Underlined, font.GetUnderlined());
995         mbar->Check(Font_Strikethrough, font.GetStrikethrough());
996     }
997 }
998 
OnSelectFont(wxCommandEvent & WXUNUSED (event))999 void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event))
1000 {
1001     wxFontData data;
1002     data.SetInitialFont(m_fontWindow->GetTextFont());
1003     data.SetColour(m_fontWindow->GetColour());
1004 
1005     wxFontDialog dialog(this, data);
1006     if ( dialog.ShowModal() == wxID_OK )
1007     {
1008         wxFontData retData = dialog.GetFontData();
1009         wxFont font = retData.GetChosenFont();
1010         wxColour colour = retData.GetColour();
1011 
1012         DoChangeFont(font, colour);
1013     }
1014 }
1015 
OnPrivateFont(wxCommandEvent & WXUNUSED (event))1016 void MyFrame::OnPrivateFont(wxCommandEvent& WXUNUSED(event))
1017 {
1018     wxFont font(m_fontWindow->GetTextFont());
1019     if (font.SetFaceName("wxprivate"))
1020     {
1021         wxASSERT_MSG( font.IsOk(), "The font should now be valid") ;
1022         DoChangeFont(font);
1023     }
1024     else
1025     {
1026         wxLogError("Failed to use private font.");
1027     }
1028 }
1029 
OnQuit(wxCommandEvent & WXUNUSED (event))1030 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1031 {
1032     // true is to force the frame to close
1033     Close(true);
1034 }
1035 
OnTestTextValue(wxCommandEvent & WXUNUSED (event))1036 void MyFrame::OnTestTextValue(wxCommandEvent& WXUNUSED(event))
1037 {
1038     wxString value = m_textctrl->GetValue();
1039     m_textctrl->SetValue(value);
1040     if ( m_textctrl->GetValue() != value )
1041     {
1042         wxLogError("Text value changed after getting and setting it");
1043     }
1044 }
1045 
OnViewMsg(wxCommandEvent & WXUNUSED (event))1046 void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event))
1047 {
1048 #if wxUSE_FILEDLG
1049     // first, choose the file
1050     static wxString s_dir, s_file;
1051     wxFileDialog dialog(this, "Open an email message file",
1052                         s_dir, s_file);
1053     if ( dialog.ShowModal() != wxID_OK )
1054         return;
1055 
1056     // save for the next time
1057     s_dir = dialog.GetDirectory();
1058     s_file = dialog.GetFilename();
1059 
1060     wxString filename = dialog.GetPath();
1061 
1062     // load it and search for Content-Type header
1063     wxTextFile file(filename);
1064     if ( !file.Open() )
1065         return;
1066 
1067     wxString charset;
1068 
1069     wxString prefix = "Content-Type: text/plain; charset=";
1070     const size_t len = wxStrlen(prefix);
1071 
1072     size_t n, count = file.GetLineCount();
1073     for ( n = 0; n < count; n++ )
1074     {
1075         wxString line = file[n];
1076 
1077         if ( !line )
1078         {
1079             // if it is an email message, headers are over, no need to parse
1080             // all the file
1081             break;
1082         }
1083 
1084         if ( line.Left(len) == prefix )
1085         {
1086             // found!
1087             const wxChar *pc = line.c_str() + len;
1088             if ( *pc == '"')
1089                 pc++;
1090 
1091             while ( *pc && *pc != '"')
1092             {
1093                 charset += *pc++;
1094             }
1095 
1096             break;
1097         }
1098     }
1099 
1100     if ( !charset )
1101     {
1102         wxLogError("The file '%s' doesn't contain charset information.",
1103                    filename);
1104 
1105         return;
1106     }
1107 
1108     // ok, now get the corresponding encoding
1109     wxFontEncoding fontenc = wxFontMapper::Get()->CharsetToEncoding(charset);
1110     if ( fontenc == wxFONTENCODING_SYSTEM )
1111     {
1112         wxLogError("Charset '%s' is unsupported.", charset);
1113         return;
1114     }
1115 
1116     m_textctrl->LoadFile(filename);
1117 
1118     if ( fontenc == wxFONTENCODING_UTF8 ||
1119             !wxFontMapper::Get()->IsEncodingAvailable(fontenc) )
1120     {
1121         // try to find some similar encoding:
1122         wxFontEncoding encAlt;
1123         if ( wxFontMapper::Get()->GetAltForEncoding(fontenc, &encAlt) )
1124         {
1125             wxEncodingConverter conv;
1126 
1127             if (conv.Init(fontenc, encAlt))
1128             {
1129                 fontenc = encAlt;
1130                 m_textctrl -> SetValue(conv.Convert(m_textctrl -> GetValue()));
1131             }
1132             else
1133             {
1134                 wxLogWarning("Cannot convert from '%s' to '%s'.",
1135                              wxFontMapper::GetEncodingDescription(fontenc),
1136                              wxFontMapper::GetEncodingDescription(encAlt));
1137             }
1138         }
1139         else
1140             wxLogWarning("No fonts for encoding '%s' on this system.",
1141                          wxFontMapper::GetEncodingDescription(fontenc));
1142     }
1143 
1144     // and now create the correct font
1145     if ( !DoEnumerateFamilies(false, fontenc, true /* silent */) )
1146     {
1147         wxFont font(wxFontInfo(wxNORMAL_FONT->GetPointSize()).Encoding(fontenc));
1148         if ( font.IsOk() )
1149         {
1150             DoChangeFont(font);
1151         }
1152         else
1153         {
1154             wxLogWarning("No fonts for encoding '%s' on this system.",
1155                          wxFontMapper::GetEncodingDescription(fontenc));
1156         }
1157     }
1158 #endif // wxUSE_FILEDLG
1159 }
1160 
OnAbout(wxCommandEvent & WXUNUSED (event))1161 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1162 {
1163     wxMessageBox("wxWidgets font sample\n"
1164                  "(c) 1999-2006 Vadim Zeitlin",
1165                  wxString("About ") + GetSampleTitle(),
1166                  wxOK | wxICON_INFORMATION, this);
1167 }
1168 
1169 // ----------------------------------------------------------------------------
1170 // FontWindow
1171 // ----------------------------------------------------------------------------
1172 
FontWindow(wxWindow * parent)1173 FontWindow::FontWindow(wxWindow *parent)
1174           : wxWindow(parent, wxID_ANY),
1175             m_panel(new FontPanel(this)),
1176             m_canvas(new FontCanvas(this))
1177 {
1178     wxSizer* const sizer = new wxBoxSizer(wxVERTICAL);
1179     sizer->Add(m_panel, wxSizerFlags().Expand().Border());
1180     sizer->Add(new wxStaticLine(this), wxSizerFlags().Expand());
1181     sizer->Add(m_canvas, wxSizerFlags(1).Expand());
1182     SetSizer(sizer);
1183 }
1184 
UpdateFont(const wxFont & font,const wxColour & colour)1185 void FontWindow::UpdateFont(const wxFont& font, const wxColour& colour)
1186 {
1187     m_panel->ShowFont(font);
1188 
1189     m_canvas->SetTextFont(font);
1190     if ( colour.IsOk() )
1191         m_canvas->SetColour(colour);
1192     m_canvas->Refresh();
1193 }
1194 
1195 // ----------------------------------------------------------------------------
1196 // FontPanel
1197 // ----------------------------------------------------------------------------
1198 
FontPanel(wxWindow * parent)1199 FontPanel::FontPanel(wxWindow* parent)
1200          : wxPanel(parent)
1201 {
1202     m_useFamily =
1203     m_useNumericWeight = false;
1204 
1205     m_textFaceName = new wxTextCtrl(this, wxID_ANY, wxString(),
1206                                     wxDefaultPosition, wxDefaultSize,
1207                                     wxTE_PROCESS_ENTER);
1208     m_textFaceName->Bind(wxEVT_TEXT, &FontPanel::OnFacename, this);
1209 
1210     // Must be in sync with the Family enum.
1211     const wxString familiesNames[] =
1212     {
1213         "Default",
1214         "Decorative",
1215         "Roman",
1216         "Script",
1217         "Swiss",
1218         "Modern",
1219         "Teletype",
1220     };
1221     m_choiceFamily = new wxChoice(this, wxID_ANY,
1222                                   wxDefaultPosition, wxDefaultSize,
1223                                   WXSIZEOF(familiesNames), familiesNames);
1224     m_choiceFamily->Bind(wxEVT_CHOICE, &FontPanel::OnFamily, this);
1225 
1226     m_spinPointSize = new wxSpinCtrlDouble(this, wxID_ANY, wxString(),
1227                                            wxDefaultPosition, wxDefaultSize,
1228                                            wxSP_ARROW_KEYS,
1229                                            1.0, 100.0, 10.0, 0.1);
1230 
1231     m_spinPointSize->SetInitialSize
1232         (
1233          m_spinPointSize->GetSizeFromTextSize(GetTextExtent("999.9").x)
1234         );
1235 
1236     // Must be in sync with the Style enum.
1237     const wxString stylesNames[] =
1238     {
1239         "Normal",
1240         "Italic",
1241         "Slant",
1242     };
1243 
1244     m_choiceStyle = new wxChoice(this, wxID_ANY,
1245                                  wxDefaultPosition, wxDefaultSize,
1246                                  WXSIZEOF(stylesNames), stylesNames);
1247 
1248     // Must be in sync with the Weight enum.
1249     const wxString weightsNames[] =
1250     {
1251         "Thin",
1252         "Extra light",
1253         "Light",
1254         "Normal",
1255         "Medium",
1256         "Semi-bold",
1257         "Bold",
1258         "Extra bold",
1259         "Heavy",
1260         "Extra heavy",
1261     };
1262 
1263     m_choiceWeight = new wxChoice(this, wxID_ANY,
1264                                  wxDefaultPosition, wxDefaultSize,
1265                                  WXSIZEOF(weightsNames), weightsNames);
1266     m_choiceWeight->Bind(wxEVT_CHOICE, &FontPanel::OnWeightChoice, this);
1267 
1268     m_spinWeight = new wxSpinCtrl(this, wxID_ANY, wxString(),
1269                                   wxDefaultPosition, wxDefaultSize,
1270                                   wxSP_ARROW_KEYS,
1271                                   1, wxFONTWEIGHT_MAX);
1272     m_spinWeight->SetInitialSize
1273         (
1274          m_spinWeight->GetSizeFromTextSize(GetTextExtent("9999").x)
1275         );
1276     m_spinWeight->Bind(wxEVT_SPINCTRL, &FontPanel::OnWeightSpin, this);
1277 
1278     m_checkUnderlined = new wxCheckBox(this, wxID_ANY, wxString());
1279     m_checkStrikethrough = new wxCheckBox(this, wxID_ANY, wxString());
1280     m_checkFixedWidth = new wxCheckBox(this, wxID_ANY, wxString());
1281     m_checkFixedWidth->Disable(); // Can't be changed by the user.
1282 
1283     m_labelInfo = new wxStaticText(this, wxID_ANY, "\n\n\n");
1284 
1285 
1286     const int border = wxSizerFlags::GetDefaultBorder();
1287 
1288     // Columns are: label, control, gap, label, control, label, control (there
1289     // is no second gap column because we don't want any gap in the weight row).
1290     wxFlexGridSizer* const sizer = new wxFlexGridSizer(7, wxSize(border, border));
1291 
1292     const wxSizerFlags flagsLabel = wxSizerFlags().CentreVertical();
1293     const wxSizerFlags flagsValue = wxSizerFlags().Expand().CentreVertical();
1294 
1295     sizer->Add(new wxStaticText(this, wxID_ANY, "Face &name:"), flagsLabel);
1296     sizer->Add(m_textFaceName, flagsValue);
1297 
1298     sizer->AddSpacer(2*border);
1299 
1300     sizer->Add(new wxStaticText(this, wxID_ANY, "&Family:"), flagsLabel);
1301     sizer->Add(m_choiceFamily, flagsValue);
1302 
1303     sizer->Add(new wxStaticText(this, wxID_ANY, "&Point size:"),
1304                wxSizerFlags().DoubleBorder(wxLEFT).CentreVertical());
1305     sizer->Add(m_spinPointSize, flagsValue);
1306 
1307 
1308     sizer->Add(new wxStaticText(this, wxID_ANY, "&Style:"), flagsLabel);
1309     sizer->Add(m_choiceStyle, flagsValue);
1310 
1311     sizer->AddSpacer(0);
1312 
1313     sizer->Add(new wxStaticText(this, wxID_ANY, "&Weight:"), flagsLabel);
1314     sizer->Add(m_choiceWeight, flagsValue);
1315 
1316     sizer->Add(new wxStaticText(this, wxID_ANY, "or &raw value:"), flagsLabel);
1317     sizer->Add(m_spinWeight, flagsValue);
1318 
1319 
1320     sizer->Add(new wxStaticText(this, wxID_ANY, "&Underlined:"), flagsLabel);
1321     sizer->Add(m_checkUnderlined, flagsValue);
1322 
1323     sizer->AddSpacer(0);
1324 
1325     sizer->Add(new wxStaticText(this, wxID_ANY, "&Strike through:"), flagsLabel);
1326     sizer->Add(m_checkStrikethrough, flagsValue);
1327 
1328     sizer->Add(new wxStaticText(this, wxID_ANY, "Fixed width:"), flagsLabel);
1329     sizer->Add(m_checkFixedWidth, flagsValue);
1330 
1331     wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL);
1332     sizerTop->Add(sizer, wxSizerFlags().Expand().Border(wxBOTTOM));
1333     sizerTop->Add(new wxButton(this, wxID_APPLY, "&Apply changes"),
1334                   wxSizerFlags().Border(wxBOTTOM).Centre());
1335     sizerTop->Add(m_labelInfo, wxSizerFlags().Expand().Border(wxTOP));
1336     SetSizer(sizerTop);
1337 
1338     ShowFont(*wxNORMAL_FONT);
1339 }
1340 
DoUpdate()1341 void FontPanel::DoUpdate()
1342 {
1343     m_textFaceName->ChangeValue(m_font.GetFaceName());
1344 
1345     Family family = Family_Default;
1346     switch ( m_font.GetFamily() )
1347     {
1348         case wxFONTFAMILY_DECORATIVE: family = Family_Decorative; break;
1349         case wxFONTFAMILY_ROMAN:      family = Family_Roman;      break;
1350         case wxFONTFAMILY_SCRIPT:     family = Family_Script;     break;
1351         case wxFONTFAMILY_SWISS:      family = Family_Swiss;      break;
1352         case wxFONTFAMILY_MODERN:     family = Family_Modern;     break;
1353         case wxFONTFAMILY_TELETYPE:   family = Family_Teletype;   break;
1354 
1355         case wxFONTFAMILY_DEFAULT:
1356         case wxFONTFAMILY_UNKNOWN:
1357             // Leave family as Family_Default, what else can we do.
1358             break;
1359     }
1360     m_choiceFamily->SetSelection(family);
1361 
1362     m_spinPointSize->SetValue(m_font.GetFractionalPointSize());
1363 
1364     Style style = Style_Normal;
1365     switch ( m_font.GetStyle() )
1366     {
1367         case wxFONTSTYLE_ITALIC: style = Style_Italic; break;
1368         case wxFONTSTYLE_SLANT:  style = Style_Slant;  break;
1369 
1370         case wxFONTSTYLE_NORMAL:
1371         case wxFONTSTYLE_MAX:
1372             break;
1373     }
1374     m_choiceStyle->SetSelection(style);
1375 
1376     Weight weight = Weight_Normal;
1377     switch ( m_font.GetWeight() )
1378     {
1379         case wxFONTWEIGHT_THIN:         weight = Weight_Thin;       break;
1380         case wxFONTWEIGHT_EXTRALIGHT:   weight = Weight_Extralight; break;
1381         case wxFONTWEIGHT_LIGHT:        weight = Weight_Light;      break;
1382         case wxFONTWEIGHT_MEDIUM:       weight = Weight_Medium;     break;
1383         case wxFONTWEIGHT_SEMIBOLD:     weight = Weight_Semibold;   break;
1384         case wxFONTWEIGHT_BOLD:         weight = Weight_Bold;       break;
1385         case wxFONTWEIGHT_EXTRABOLD:    weight = Weight_Extrabold;  break;
1386         case wxFONTWEIGHT_HEAVY:        weight = Weight_Heavy;      break;
1387         case wxFONTWEIGHT_EXTRAHEAVY:   weight = Weight_Extraheavy; break;
1388 
1389         case wxFONTWEIGHT_NORMAL:
1390         case wxFONTWEIGHT_INVALID:
1391             break;
1392     }
1393     m_choiceWeight->SetSelection(weight);
1394     m_spinWeight->SetValue(m_font.GetNumericWeight());
1395 
1396     m_checkUnderlined->SetValue(m_font.GetUnderlined());
1397     m_checkStrikethrough->SetValue(m_font.GetStrikethrough());
1398     m_checkFixedWidth->SetValue(m_font.IsFixedWidth());
1399 
1400     const wxSize pixelSize = m_font.GetPixelSize();
1401     wxClientDC dc(this);
1402     dc.SetFont(m_font);
1403 
1404     m_labelInfo->SetLabelText
1405         (
1406             wxString::Format
1407             (
1408                 "Font info string: %s\n"
1409                 "Size in pixels: %d*%d, "
1410                 "average char size: %d*%d",
1411                 m_font.GetNativeFontInfoDesc(),
1412                 pixelSize.x, pixelSize.y,
1413                 dc.GetCharWidth(), dc.GetCharHeight()
1414             )
1415         );
1416 }
1417 
GetFontInfo() const1418 wxFontInfo FontPanel::GetFontInfo() const
1419 {
1420     wxFontInfo info(m_spinPointSize->GetValue());
1421 
1422     if ( m_useFamily )
1423     {
1424         const wxFontFamily families[] =
1425         {
1426             wxFONTFAMILY_DEFAULT,
1427             wxFONTFAMILY_DECORATIVE,
1428             wxFONTFAMILY_ROMAN,
1429             wxFONTFAMILY_SCRIPT,
1430             wxFONTFAMILY_SWISS,
1431             wxFONTFAMILY_MODERN,
1432             wxFONTFAMILY_TELETYPE,
1433         };
1434         info.Family(families[m_choiceFamily->GetSelection()]);
1435     }
1436     else
1437     {
1438         info.FaceName(m_textFaceName->GetValue());
1439     }
1440 
1441     switch ( m_choiceStyle->GetSelection() )
1442     {
1443         case Style_Normal:
1444             break;
1445 
1446         case Style_Italic:
1447             info.Italic();
1448             break;
1449 
1450         case Style_Slant:
1451             info.Slant();
1452             break;
1453     }
1454 
1455     info.Weight(m_useNumericWeight ? m_spinWeight->GetValue()
1456                                    : (m_choiceWeight->GetSelection() + 1)*100);
1457 
1458     if ( m_checkUnderlined->GetValue() )
1459         info.Underlined();
1460     if ( m_checkStrikethrough->GetValue() )
1461         info.Strikethrough();
1462 
1463     return info;
1464 }
1465 
1466 // ----------------------------------------------------------------------------
1467 // FontCanvas
1468 // ----------------------------------------------------------------------------
1469 
wxBEGIN_EVENT_TABLE(FontCanvas,wxWindow)1470 wxBEGIN_EVENT_TABLE(FontCanvas, wxWindow)
1471     EVT_PAINT(FontCanvas::OnPaint)
1472 wxEND_EVENT_TABLE()
1473 
1474 FontCanvas::FontCanvas( wxWindow *parent )
1475           : wxWindow( parent, wxID_ANY ),
1476             m_colour(*wxRED), m_font(*wxNORMAL_FONT)
1477 {
1478 }
1479 
OnPaint(wxPaintEvent & WXUNUSED (event))1480 void FontCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
1481 {
1482     wxPaintDC dc(this);
1483     PrepareDC(dc);
1484 
1485     // set background
1486     dc.SetBackground(*wxWHITE_BRUSH);
1487     dc.Clear();
1488     dc.SetFont(m_font);
1489 
1490     // the current text origin
1491     wxCoord x = 5,
1492             y = 5;
1493 
1494     // prepare to draw the font
1495     dc.SetTextForeground(m_colour);
1496 
1497     // the size of one cell (Normally biggest char + small margin)
1498     wxCoord maxCharWidth, maxCharHeight;
1499     dc.GetTextExtent("W", &maxCharWidth, &maxCharHeight);
1500     int w = maxCharWidth + 5,
1501         h = maxCharHeight + 4;
1502 
1503 
1504     // print all font symbols from 32 to 256 in 7 rows of 32 chars each
1505     for ( int i = 0; i < 7; i++ )
1506     {
1507         for ( int j = 0; j < 32; j++ )
1508         {
1509             wxChar c = (wxChar)(32 * (i + 1) + j);
1510 
1511             wxCoord charWidth, charHeight;
1512             dc.GetTextExtent(c, &charWidth, &charHeight);
1513             dc.DrawText
1514             (
1515                 c,
1516                 x + w*j + (maxCharWidth - charWidth) / 2 + 1,
1517                 y + h*i + (maxCharHeight - charHeight) / 2
1518             );
1519         }
1520     }
1521 
1522     // draw the lines between them
1523     dc.SetPen(*wxBLUE_PEN);
1524     int l;
1525 
1526     // horizontal
1527     for ( l = 0; l < 8; l++ )
1528     {
1529         int yl = y + h*l - 2;
1530         dc.DrawLine(x - 2, yl, x + 32*w - 1, yl);
1531     }
1532 
1533     // and vertical
1534     for ( l = 0; l < 33; l++ )
1535     {
1536         int xl = x + w*l - 2;
1537         dc.DrawLine(xl, y - 2, xl, y + 7*h - 1);
1538     }
1539 }
1540