1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFont demo
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
19 // for all others, include the necessary headers (this file is usually all you
20 // need because it includes almost all <standard< wxWindows headers
27 #include "wx/choicdlg.h"
28 #include "wx/fontdlg.h"
29 #include "wx/fontenum.h"
30 #include "wx/fontmap.h"
31 #include "wx/encconv.h"
32 #include "wx/splitter.h"
33 #include "wx/textfile.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // Define a new application type, each program should derive a class from wxApp
40 class MyApp
: public wxApp
43 // override base class virtuals
44 // ----------------------------
46 // this one is called on application startup and is a good place for the app
47 // initialization (doing it here and not in the ctor allows to have an error
48 // return: if OnInit() returns false, the application terminates)
49 virtual bool OnInit();
52 // MyCanvas is a canvas on which we show the font sample
53 class MyCanvas
: public wxWindow
56 MyCanvas( wxWindow
*parent
);
59 // accessors for the frame
60 const wxFont
& GetTextFont() const { return m_font
; }
61 const wxColour
& GetColour() const { return m_colour
; }
62 void SetTextFont(const wxFont
& font
) { m_font
= font
; }
63 void SetColour(const wxColour
& colour
) { m_colour
= colour
; }
66 void OnPaint( wxPaintEvent
&event
);
75 // Define a new frame type: this is going to be our main frame
76 class MyFrame
: public wxFrame
80 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
83 MyCanvas
*GetCanvas() const { return m_canvas
; }
85 // event handlers (these functions should _not_ be virtual)
86 void OnQuit(wxCommandEvent
& event
);
87 void OnAbout(wxCommandEvent
& event
);
89 void OnIncFont(wxCommandEvent
& event
) { DoResizeFont(+2); }
90 void OnDecFont(wxCommandEvent
& event
) { DoResizeFont(-2); }
92 void OnBold(wxCommandEvent
& event
);
93 void OnItalic(wxCommandEvent
& event
);
94 void OnUnderline(wxCommandEvent
& event
);
96 void OnViewMsg(wxCommandEvent
& event
);
97 void OnSelectFont(wxCommandEvent
& event
);
98 void OnEnumerateFamiliesForEncoding(wxCommandEvent
& event
);
99 void OnEnumerateFamilies(wxCommandEvent
& WXUNUSED(event
))
100 { DoEnumerateFamilies(FALSE
); }
101 void OnEnumerateFixedFamilies(wxCommandEvent
& WXUNUSED(event
))
102 { DoEnumerateFamilies(TRUE
); }
103 void OnEnumerateEncodings(wxCommandEvent
& event
);
105 void OnCheckNativeToFromString(wxCommandEvent
& event
);
108 bool DoEnumerateFamilies(bool fixedWidthOnly
,
109 wxFontEncoding encoding
= wxFONTENCODING_SYSTEM
,
110 bool silent
= FALSE
);
112 void DoResizeFont(int diff
);
113 void DoChangeFont(const wxFont
& font
, const wxColour
& col
= wxNullColour
);
115 size_t m_fontSize
; // in points
117 wxTextCtrl
*m_textctrl
;
121 // any class wishing to process wxWindows events must use this macro
122 DECLARE_EVENT_TABLE()
125 // ----------------------------------------------------------------------------
127 // ----------------------------------------------------------------------------
129 // IDs for the controls and the menu commands
142 Font_EnumFamiliesForEncoding
,
144 Font_EnumFixedFamilies
,
146 Font_CheckNativeToFromString
,
150 // ----------------------------------------------------------------------------
151 // event tables and other macros for wxWindows
152 // ----------------------------------------------------------------------------
154 // the event tables connect the wxWindows events with the functions (event
155 // handlers) which process them. It can be also done at run-time, but for the
156 // simple menu events like this the static method is much simpler.
157 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
158 EVT_MENU(Font_Quit
, MyFrame::OnQuit
)
159 EVT_MENU(Font_ViewMsg
, MyFrame::OnViewMsg
)
160 EVT_MENU(Font_About
, MyFrame::OnAbout
)
162 EVT_MENU(Font_IncSize
, MyFrame::OnIncFont
)
163 EVT_MENU(Font_DecSize
, MyFrame::OnDecFont
)
164 EVT_MENU(Font_Bold
, MyFrame::OnBold
)
165 EVT_MENU(Font_Italic
, MyFrame::OnItalic
)
166 EVT_MENU(Font_Underlined
, MyFrame::OnUnderline
)
167 EVT_MENU(Font_CheckNativeToFromString
, MyFrame::OnCheckNativeToFromString
)
169 EVT_MENU(Font_Choose
, MyFrame::OnSelectFont
)
170 EVT_MENU(Font_EnumFamiliesForEncoding
, MyFrame::OnEnumerateFamiliesForEncoding
)
171 EVT_MENU(Font_EnumFamilies
, MyFrame::OnEnumerateFamilies
)
172 EVT_MENU(Font_EnumFixedFamilies
, MyFrame::OnEnumerateFixedFamilies
)
173 EVT_MENU(Font_EnumEncodings
, MyFrame::OnEnumerateEncodings
)
176 // Create a new application object: this macro will allow wxWindows to create
177 // the application object during program execution (it's better than using a
178 // static object for many reasons) and also declares the accessor function
179 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
183 // ============================================================================
185 // ============================================================================
187 // ----------------------------------------------------------------------------
188 // the application class
189 // ----------------------------------------------------------------------------
191 // `Main program' equivalent: the program execution "starts" here
194 // Create the main application window
195 MyFrame
*frame
= new MyFrame("Font wxWindows demo",
196 wxPoint(50, 50), wxSize(600, 400));
198 // Show it and tell the application that it's our main window
202 // success: wxApp::OnRun() will be called which will enter the main message
203 // loop and the application will run. If we returned FALSE here, the
204 // application would exit immediately.
208 // ----------------------------------------------------------------------------
210 // ----------------------------------------------------------------------------
213 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
214 : wxFrame((wxFrame
*)NULL
, -1, title
, pos
, size
), m_textctrl(NULL
)
219 wxMenu
*menuFile
= new wxMenu
;
221 menuFile
->Append(Font_ViewMsg
, "&View...\tCtrl-V",
222 "View an email message file");
223 menuFile
->AppendSeparator();
224 menuFile
->Append(Font_About
, "&About...\tCtrl-A", "Show about dialog");
225 menuFile
->AppendSeparator();
226 menuFile
->Append(Font_Quit
, "E&xit\tAlt-X", "Quit this program");
228 wxMenu
*menuFont
= new wxMenu
;
229 menuFont
->Append(Font_IncSize
, "&Increase font size by 2 points\tCtrl-I");
230 menuFont
->Append(Font_DecSize
, "&Decrease font size by 2 points\tCtrl-D");
231 menuFont
->AppendSeparator();
232 menuFont
->Append(Font_Bold
, "&Bold\tCtrl-B", "Toggle bold state", TRUE
);
233 menuFont
->Append(Font_Italic
, "&Oblique\tCtrl-O", "Toggle italic state", TRUE
);
234 menuFont
->Append(Font_Underlined
, "&Underlined\tCtrl-U",
235 "Toggle underlined state", TRUE
);
236 menuFont
->AppendSeparator();
237 menuFont
->Append(Font_CheckNativeToFromString
,
238 "Check Native Font Info To/From String");
240 wxMenu
*menuSelect
= new wxMenu
;
241 menuSelect
->Append(Font_Choose
, "&Select font...\tCtrl-S",
242 "Select a standard font");
243 menuSelect
->AppendSeparator();
244 menuSelect
->Append(Font_EnumFamilies
, "Enumerate font &families\tCtrl-F");
245 menuSelect
->Append(Font_EnumFixedFamilies
,
246 "Enumerate fi&xed font families\tCtrl-X");
247 menuSelect
->Append(Font_EnumEncodings
,
248 "Enumerate &encodings\tCtrl-E");
249 menuSelect
->Append(Font_EnumFamiliesForEncoding
,
250 "Find font for en&coding...\tCtrl-C",
251 "Find font families for given encoding");
253 // now append the freshly created menu to the menu bar...
254 wxMenuBar
*menuBar
= new wxMenuBar
;
255 menuBar
->Append(menuFile
, "&File");
256 menuBar
->Append(menuFont
, "F&ont");
257 menuBar
->Append(menuSelect
, "&Select");
259 // ... and attach this menu bar to the frame
262 wxSplitterWindow
*splitter
= new wxSplitterWindow(this);
264 m_textctrl
= new wxTextCtrl(splitter
, -1,
265 "Paste text here to see how it looks\n"
266 "like in the given font",
267 wxDefaultPosition
, wxDefaultSize
,
270 m_canvas
= new MyCanvas(splitter
);
272 splitter
->SplitHorizontally(m_textctrl
, m_canvas
, 100);
274 // create a status bar just for fun (by default with 1 pane only)
276 SetStatusText("Welcome to wxWindows font demo!");
279 // --------------------------------------------------------
281 class MyEncodingEnumerator
: public wxFontEnumerator
284 MyEncodingEnumerator()
287 const wxString
& GetText() const
291 virtual bool OnFontEncoding(const wxString
& facename
,
292 const wxString
& encoding
)
295 text
.Printf(wxT("Encoding %d: %s (available in facename '%s')\n"),
296 ++m_n
, encoding
.c_str(), facename
.c_str());
306 void MyFrame::OnEnumerateEncodings(wxCommandEvent
& WXUNUSED(event
))
308 MyEncodingEnumerator fontEnumerator
;
310 fontEnumerator
.EnumerateEncodings();
312 wxLogMessage(wxT("Enumerating all available encodings:\n%s"),
313 fontEnumerator
.GetText().c_str());
316 // -------------------------------------------------------------
318 class MyFontEnumerator
: public wxFontEnumerator
322 { return !m_facenames
.IsEmpty(); }
324 const wxArrayString
& GetFacenames() const
325 { return m_facenames
; }
328 virtual bool OnFacename(const wxString
& facename
)
330 m_facenames
.Add(facename
);
335 wxArrayString m_facenames
;
338 bool MyFrame::DoEnumerateFamilies(bool fixedWidthOnly
,
339 wxFontEncoding encoding
,
342 MyFontEnumerator fontEnumerator
;
344 fontEnumerator
.EnumerateFacenames(encoding
, fixedWidthOnly
);
346 if ( fontEnumerator
.GotAny() )
348 int nFacenames
= fontEnumerator
.GetFacenames().GetCount();
351 wxLogStatus(this, wxT("Found %d %sfonts"),
352 nFacenames
, fixedWidthOnly
? wxT("fixed width ") : wxT(""));
359 facename
= fontEnumerator
.GetFacenames().Item(0);
363 // let the user choose
364 wxString
*facenames
= new wxString
[nFacenames
];
366 for ( n
= 0; n
< nFacenames
; n
++ )
367 facenames
[n
] = fontEnumerator
.GetFacenames().Item(n
);
369 n
= wxGetSingleChoiceIndex("Choose a facename", "Font demo",
370 nFacenames
, facenames
, this);
373 facename
= facenames
[n
];
378 if ( !facename
.IsEmpty() )
380 wxFont
font(12, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
,
381 wxFONTWEIGHT_NORMAL
, FALSE
, facename
, encoding
);
390 wxLogWarning(wxT("No such fonts found."));
396 void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent
& WXUNUSED(event
))
398 static wxFontEncoding encodings
[] =
400 wxFONTENCODING_ISO8859_1
,
401 wxFONTENCODING_ISO8859_2
,
402 wxFONTENCODING_ISO8859_5
,
403 wxFONTENCODING_ISO8859_7
,
404 wxFONTENCODING_ISO8859_15
,
406 wxFONTENCODING_CP1250
,
407 wxFONTENCODING_CP1251
,
408 wxFONTENCODING_CP1252
,
411 static const wxString encodingNames
[] =
413 "Western European (ISO-8859-1)",
414 "Central European (ISO-8859-2)",
415 "Cyrillic (ISO-8859-5)",
416 "Greek (ISO-8859-7)",
417 "Western European with Euro (ISO-8859-15)",
419 "Windows Central European (CP 1250)",
420 "Windows Cyrillic (CP 1251)",
421 "Windows Western European (CP 1252)",
424 int n
= wxGetSingleChoiceIndex("Choose an encoding", "Font demo",
425 WXSIZEOF(encodingNames
),
431 DoEnumerateFamilies(FALSE
, encodings
[n
]);
435 void MyFrame::OnCheckNativeToFromString(wxCommandEvent
& WXUNUSED(event
))
437 wxString fontInfo
= m_canvas
->GetTextFont().GetNativeFontInfoDesc();
439 if ( fontInfo
.IsEmpty() )
441 wxLogError(wxT("Native font info string is empty!"));
445 wxFont
*font
= wxFont::New(fontInfo
);
446 if ( fontInfo
!= font
->GetNativeFontInfoDesc() )
447 wxLogError(wxT("wxNativeFontInfo ToString()/FromString() broken!"));
449 wxLogMessage(wxT("wxNativeFontInfo works: %s"), fontInfo
.c_str());
455 void MyFrame::DoResizeFont(int diff
)
457 wxFont font
= m_canvas
->GetTextFont();
459 font
.SetPointSize(font
.GetPointSize() + diff
);
463 void MyFrame::OnBold(wxCommandEvent
& event
)
465 wxFont font
= m_canvas
->GetTextFont();
467 font
.SetWeight(event
.IsChecked() ? wxFONTWEIGHT_BOLD
: wxFONTWEIGHT_NORMAL
);
471 void MyFrame::OnItalic(wxCommandEvent
& event
)
473 wxFont font
= m_canvas
->GetTextFont();
475 font
.SetStyle(event
.IsChecked() ? wxFONTSTYLE_ITALIC
: wxFONTSTYLE_NORMAL
);
479 void MyFrame::OnUnderline(wxCommandEvent
& event
)
481 wxFont font
= m_canvas
->GetTextFont();
483 font
.SetUnderlined(event
.IsChecked());
487 void MyFrame::DoChangeFont(const wxFont
& font
, const wxColour
& col
)
489 m_canvas
->SetTextFont(font
);
491 m_canvas
->SetColour(col
);
494 m_textctrl
->SetFont(font
);
496 m_textctrl
->SetForegroundColour(col
);
499 void MyFrame::OnSelectFont(wxCommandEvent
& WXUNUSED(event
))
502 data
.SetInitialFont(m_canvas
->GetTextFont());
503 data
.SetColour(m_canvas
->GetColour());
505 wxFontDialog
dialog(this, &data
);
506 if ( dialog
.ShowModal() == wxID_OK
)
508 wxFontData retData
= dialog
.GetFontData();
509 wxFont font
= retData
.GetChosenFont();
510 wxColour colour
= retData
.GetColour();
512 DoChangeFont(font
, colour
);
514 // update the state of the bold/italic/underlined menu items
515 wxMenuBar
*mbar
= GetMenuBar();
518 mbar
->Check(Font_Bold
, font
.GetWeight() == wxFONTWEIGHT_BOLD
);
519 mbar
->Check(Font_Italic
, font
.GetStyle() == wxFONTSTYLE_ITALIC
);
520 mbar
->Check(Font_Underlined
, font
.GetUnderlined());
525 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
527 // TRUE is to force the frame to close
531 void MyFrame::OnViewMsg(wxCommandEvent
& WXUNUSED(event
))
533 // first, choose the file
534 static wxString s_dir
, s_file
;
535 wxFileDialog
dialog(this, "Open an email message file",
537 if ( dialog
.ShowModal() != wxID_OK
)
540 // save for the next time
541 s_dir
= dialog
.GetDirectory();
542 s_file
= dialog
.GetFilename();
544 wxString filename
= dialog
.GetPath();
546 // load it and search for Content-Type header
547 wxTextFile
file(filename
);
553 static const char *prefix
= "Content-Type: text/plain; charset=";
554 const size_t len
= strlen(prefix
);
556 size_t n
, count
= file
.GetLineCount();
557 for ( n
= 0; n
< count
; n
++ )
559 wxString line
= file
[n
];
563 // if it is an email message, headers are over, no need to parse
568 if ( line
.Left(len
) == prefix
)
571 const wxChar
*pc
= line
.c_str() + len
;
575 while ( *pc
&& *pc
!= '"' )
586 wxLogError(wxT("The file '%s' doesn't contain charset information."),
592 // ok, now get the corresponding encoding
593 wxFontEncoding fontenc
= wxTheFontMapper
->CharsetToEncoding(charset
);
594 if ( fontenc
== wxFONTENCODING_SYSTEM
)
596 wxLogError(wxT("Charset '%s' is unsupported."), charset
.c_str());
600 m_textctrl
->LoadFile(filename
);
602 if ( fontenc
== wxFONTENCODING_UTF8
||
603 !wxTheFontMapper
->IsEncodingAvailable(fontenc
) )
605 // try to find some similar encoding:
606 wxFontEncoding encAlt
;
607 if ( wxTheFontMapper
->GetAltForEncoding(fontenc
, &encAlt
) )
609 wxEncodingConverter conv
;
611 if (conv
.Init(fontenc
, encAlt
))
614 m_textctrl
-> SetValue(conv
.Convert(m_textctrl
-> GetValue()));
618 wxLogWarning(wxT("Cannot convert from '%s' to '%s'."),
619 wxFontMapper::GetEncodingDescription(fontenc
).c_str(),
620 wxFontMapper::GetEncodingDescription(encAlt
).c_str());
624 wxLogWarning(wxT("No fonts for encoding '%s' on this system."),
625 wxFontMapper::GetEncodingDescription(fontenc
).c_str());
628 // and now create the correct font
629 if ( !DoEnumerateFamilies(FALSE
, fontenc
, TRUE
/* silent */) )
631 wxFont
font(12, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
,
632 wxFONTWEIGHT_NORMAL
, FALSE
/* !underlined */,
633 wxEmptyString
/* facename */, fontenc
);
640 wxLogWarning(wxT("No fonts for encoding '%s' on this system."),
641 wxFontMapper::GetEncodingDescription(fontenc
).c_str());
646 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
648 wxMessageBox("wxWindows font demo\n"
649 "(c) 1999 Vadim Zeitlin",
651 wxOK
| wxICON_INFORMATION
, this);
654 // ----------------------------------------------------------------------------
656 // ----------------------------------------------------------------------------
658 BEGIN_EVENT_TABLE(MyCanvas
, wxWindow
)
659 EVT_PAINT(MyCanvas::OnPaint
)
662 MyCanvas::MyCanvas( wxWindow
*parent
)
663 : wxWindow( parent
, -1 ),
664 m_colour(*wxRED
), m_font(*wxNORMAL_FONT
)
668 MyCanvas::~MyCanvas()
672 void MyCanvas::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
678 dc
.SetBackground(wxBrush(wxT("white"), wxSOLID
));
681 // one text line height
682 wxCoord hLine
= dc
.GetCharHeight();
684 // the current text origin
688 // output the font name/info
690 fontInfo
.Printf(wxT("Font size is %d points, family: %s, encoding: %s"),
691 m_font
.GetPointSize(),
692 m_font
.GetFamilyString().c_str(),
694 GetEncodingDescription(m_font
.GetEncoding()).c_str());
696 dc
.DrawText(fontInfo
, x
, y
);
699 fontInfo
.Printf(wxT("Style: %s, weight: %s, fixed width: %s"),
700 m_font
.GetStyleString().c_str(),
701 m_font
.GetWeightString().c_str(),
702 m_font
.IsFixedWidth() ? _T("yes") : _T("no"));
704 dc
.DrawText(fontInfo
, x
, y
);
709 wxNativeFontInfo
*info
= m_font
.GetNativeFontInfo();
714 wxString fontDesc
= m_font
.GetNativeFontInfoUserDesc();
715 fontInfo
.Printf(wxT("Native font info: %s"), fontDesc
.c_str());
717 dc
.DrawText(fontInfo
, x
, y
);
724 // prepare to draw the font
726 dc
.SetTextForeground(m_colour
);
728 // the size of one cell (Normally biggest char + small margin)
729 long maxCharWidth
, maxCharHeight
;
730 dc
.GetTextExtent(wxT("W"), &maxCharWidth
, &maxCharHeight
);
731 int w
= maxCharWidth
+ 5,
732 h
= maxCharHeight
+ 4;
735 // print all font symbols from 32 to 256 in 7 rows of 32 chars each
736 for ( int i
= 0; i
< 7; i
++ )
738 for ( int j
= 0; j
< 32; j
++ )
740 wxChar c
= 32 * (i
+ 1) + j
;
742 long charWidth
, charHeight
;
743 dc
.GetTextExtent(c
, &charWidth
, &charHeight
);
747 x
+ w
*j
+ (maxCharWidth
- charWidth
) / 2 + 1,
748 y
+ h
*i
+ (maxCharHeight
- charHeight
) / 2
753 // draw the lines between them
754 dc
.SetPen(wxPen(wxColour("blue"), 1, wxSOLID
));
758 for ( l
= 0; l
< 8; l
++ )
760 int yl
= y
+ h
*l
- 2;
761 dc
.DrawLine(x
- 2, yl
, x
+ 32*w
- 1, yl
);
765 for ( l
= 0; l
< 33; l
++ )
767 int xl
= x
+ w
*l
- 2;
768 dc
.DrawLine(xl
, y
- 2, xl
, y
+ 7*h
- 1);