| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: font.cpp |
| 3 | // Purpose: wxFont demo |
| 4 | // Author: Vadim Zeitlin |
| 5 | // Modified by: |
| 6 | // Created: 30.09.99 |
| 7 | // RCS-ID: $Id$ |
| 8 | // Copyright: (c) 1999 Vadim Zeitlin |
| 9 | // Licence: wxWindows licence |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | // For compilers that support precompilation, includes "wx/wx.h". |
| 13 | #include "wx/wxprec.h" |
| 14 | |
| 15 | #ifdef __BORLANDC__ |
| 16 | #pragma hdrstop |
| 17 | #endif |
| 18 | |
| 19 | // for all others, include the necessary headers (this file is usually all you |
| 20 | // need because it includes almost all standard wxWindows headers |
| 21 | #ifndef WX_PRECOMP |
| 22 | #include "wx/wx.h" |
| 23 | |
| 24 | #include "wx/log.h" |
| 25 | #endif |
| 26 | |
| 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" |
| 34 | |
| 35 | // ---------------------------------------------------------------------------- |
| 36 | // private classes |
| 37 | // ---------------------------------------------------------------------------- |
| 38 | |
| 39 | // Define a new application type, each program should derive a class from wxApp |
| 40 | class MyApp : public wxApp |
| 41 | { |
| 42 | public: |
| 43 | // override base class virtuals |
| 44 | // ---------------------------- |
| 45 | |
| 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(); |
| 50 | }; |
| 51 | |
| 52 | // MyCanvas is a canvas on which we show the font sample |
| 53 | class MyCanvas: public wxWindow |
| 54 | { |
| 55 | public: |
| 56 | MyCanvas( wxWindow *parent ); |
| 57 | virtual ~MyCanvas(); |
| 58 | |
| 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; } |
| 64 | |
| 65 | // event handlers |
| 66 | void OnPaint( wxPaintEvent &event ); |
| 67 | |
| 68 | private: |
| 69 | wxColour m_colour; |
| 70 | wxFont m_font; |
| 71 | |
| 72 | DECLARE_EVENT_TABLE() |
| 73 | }; |
| 74 | |
| 75 | // Define a new frame type: this is going to be our main frame |
| 76 | class MyFrame : public wxFrame |
| 77 | { |
| 78 | public: |
| 79 | // ctor(s) |
| 80 | MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); |
| 81 | |
| 82 | // accessors |
| 83 | MyCanvas *GetCanvas() const { return m_canvas; } |
| 84 | |
| 85 | // event handlers (these functions should _not_ be virtual) |
| 86 | void OnQuit(wxCommandEvent& event); |
| 87 | void OnAbout(wxCommandEvent& event); |
| 88 | |
| 89 | void OnIncFont(wxCommandEvent& event) { DoResizeFont(+2); } |
| 90 | void OnDecFont(wxCommandEvent& event) { DoResizeFont(-2); } |
| 91 | |
| 92 | void OnBold(wxCommandEvent& event); |
| 93 | void OnItalic(wxCommandEvent& event); |
| 94 | void OnUnderline(wxCommandEvent& event); |
| 95 | |
| 96 | void OnwxPointerFont(wxCommandEvent& event); |
| 97 | |
| 98 | void OnViewMsg(wxCommandEvent& event); |
| 99 | void OnSelectFont(wxCommandEvent& event); |
| 100 | void OnEnumerateFamiliesForEncoding(wxCommandEvent& event); |
| 101 | void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event)) |
| 102 | { DoEnumerateFamilies(FALSE); } |
| 103 | void OnEnumerateFixedFamilies(wxCommandEvent& WXUNUSED(event)) |
| 104 | { DoEnumerateFamilies(TRUE); } |
| 105 | void OnEnumerateEncodings(wxCommandEvent& event); |
| 106 | |
| 107 | void OnCheckNativeToFromString(wxCommandEvent& event); |
| 108 | |
| 109 | protected: |
| 110 | bool DoEnumerateFamilies(bool fixedWidthOnly, |
| 111 | wxFontEncoding encoding = wxFONTENCODING_SYSTEM, |
| 112 | bool silent = FALSE); |
| 113 | |
| 114 | void DoResizeFont(int diff); |
| 115 | void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour); |
| 116 | |
| 117 | size_t m_fontSize; // in points |
| 118 | |
| 119 | wxTextCtrl *m_textctrl; |
| 120 | MyCanvas *m_canvas; |
| 121 | |
| 122 | private: |
| 123 | // any class wishing to process wxWindows events must use this macro |
| 124 | DECLARE_EVENT_TABLE() |
| 125 | }; |
| 126 | |
| 127 | // ---------------------------------------------------------------------------- |
| 128 | // constants |
| 129 | // ---------------------------------------------------------------------------- |
| 130 | |
| 131 | // IDs for the controls and the menu commands |
| 132 | enum |
| 133 | { |
| 134 | // menu items |
| 135 | Font_Quit = 1, |
| 136 | Font_About, |
| 137 | Font_ViewMsg, |
| 138 | Font_IncSize, |
| 139 | Font_DecSize, |
| 140 | Font_Bold, |
| 141 | Font_Italic, |
| 142 | Font_Underlined, |
| 143 | Font_wxNORMAL_FONT, |
| 144 | Font_wxSMALL_FONT, |
| 145 | Font_wxITALIC_FONT, |
| 146 | Font_wxSWISS_FONT, |
| 147 | |
| 148 | Font_Choose = 100, |
| 149 | Font_EnumFamiliesForEncoding, |
| 150 | Font_EnumFamilies, |
| 151 | Font_EnumFixedFamilies, |
| 152 | Font_EnumEncodings, |
| 153 | Font_CheckNativeToFromString, |
| 154 | Font_Max |
| 155 | }; |
| 156 | |
| 157 | // ---------------------------------------------------------------------------- |
| 158 | // event tables and other macros for wxWindows |
| 159 | // ---------------------------------------------------------------------------- |
| 160 | |
| 161 | // the event tables connect the wxWindows events with the functions (event |
| 162 | // handlers) which process them. It can be also done at run-time, but for the |
| 163 | // simple menu events like this the static method is much simpler. |
| 164 | BEGIN_EVENT_TABLE(MyFrame, wxFrame) |
| 165 | EVT_MENU(Font_Quit, MyFrame::OnQuit) |
| 166 | EVT_MENU(Font_ViewMsg, MyFrame::OnViewMsg) |
| 167 | EVT_MENU(Font_About, MyFrame::OnAbout) |
| 168 | |
| 169 | EVT_MENU(Font_IncSize, MyFrame::OnIncFont) |
| 170 | EVT_MENU(Font_DecSize, MyFrame::OnDecFont) |
| 171 | EVT_MENU(Font_Bold, MyFrame::OnBold) |
| 172 | EVT_MENU(Font_Italic, MyFrame::OnItalic) |
| 173 | EVT_MENU(Font_Underlined, MyFrame::OnUnderline) |
| 174 | |
| 175 | EVT_MENU(Font_wxNORMAL_FONT, MyFrame::OnwxPointerFont) |
| 176 | EVT_MENU(Font_wxSMALL_FONT, MyFrame::OnwxPointerFont) |
| 177 | EVT_MENU(Font_wxITALIC_FONT, MyFrame::OnwxPointerFont) |
| 178 | EVT_MENU(Font_wxSWISS_FONT, MyFrame::OnwxPointerFont) |
| 179 | |
| 180 | EVT_MENU(Font_CheckNativeToFromString, MyFrame::OnCheckNativeToFromString) |
| 181 | |
| 182 | EVT_MENU(Font_Choose, MyFrame::OnSelectFont) |
| 183 | EVT_MENU(Font_EnumFamiliesForEncoding, MyFrame::OnEnumerateFamiliesForEncoding) |
| 184 | EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies) |
| 185 | EVT_MENU(Font_EnumFixedFamilies, MyFrame::OnEnumerateFixedFamilies) |
| 186 | EVT_MENU(Font_EnumEncodings, MyFrame::OnEnumerateEncodings) |
| 187 | END_EVENT_TABLE() |
| 188 | |
| 189 | // Create a new application object: this macro will allow wxWindows to create |
| 190 | // the application object during program execution (it's better than using a |
| 191 | // static object for many reasons) and also declares the accessor function |
| 192 | // wxGetApp() which will return the reference of the right type (i.e. MyApp and |
| 193 | // not wxApp) |
| 194 | IMPLEMENT_APP(MyApp) |
| 195 | |
| 196 | // ============================================================================ |
| 197 | // implementation |
| 198 | // ============================================================================ |
| 199 | |
| 200 | // ---------------------------------------------------------------------------- |
| 201 | // the application class |
| 202 | // ---------------------------------------------------------------------------- |
| 203 | |
| 204 | // `Main program' equivalent: the program execution "starts" here |
| 205 | bool MyApp::OnInit() |
| 206 | { |
| 207 | // Create the main application window |
| 208 | MyFrame *frame = new MyFrame(wxT("Font wxWindows demo"), |
| 209 | wxPoint(50, 50), wxSize(600, 400)); |
| 210 | |
| 211 | // Show it and tell the application that it's our main window |
| 212 | frame->Show(TRUE); |
| 213 | SetTopWindow(frame); |
| 214 | |
| 215 | // success: wxApp::OnRun() will be called which will enter the main message |
| 216 | // loop and the application will run. If we returned FALSE here, the |
| 217 | // application would exit immediately. |
| 218 | return TRUE; |
| 219 | } |
| 220 | |
| 221 | // ---------------------------------------------------------------------------- |
| 222 | // main frame |
| 223 | // ---------------------------------------------------------------------------- |
| 224 | |
| 225 | // frame constructor |
| 226 | MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) |
| 227 | : wxFrame((wxFrame *)NULL, -1, title, pos, size), m_textctrl(NULL) |
| 228 | { |
| 229 | m_fontSize = 12; |
| 230 | |
| 231 | // create a menu bar |
| 232 | wxMenu *menuFile = new wxMenu; |
| 233 | |
| 234 | menuFile->Append(Font_ViewMsg, wxT("&View...\tCtrl-V"), |
| 235 | wxT("View an email message file")); |
| 236 | menuFile->AppendSeparator(); |
| 237 | menuFile->Append(Font_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog")); |
| 238 | menuFile->AppendSeparator(); |
| 239 | menuFile->Append(Font_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program")); |
| 240 | |
| 241 | wxMenu *menuFont = new wxMenu; |
| 242 | menuFont->Append(Font_IncSize, wxT("&Increase font size by 2 points\tCtrl-I")); |
| 243 | menuFont->Append(Font_DecSize, wxT("&Decrease font size by 2 points\tCtrl-D")); |
| 244 | menuFont->AppendSeparator(); |
| 245 | menuFont->Append(Font_Bold, wxT("&Bold\tCtrl-B"), wxT("Toggle bold state"), TRUE); |
| 246 | menuFont->Append(Font_Italic, wxT("&Oblique\tCtrl-O"), wxT("Toggle italic state"), TRUE); |
| 247 | menuFont->Append(Font_Underlined, wxT("&Underlined\tCtrl-U"), |
| 248 | wxT("Toggle underlined state"), TRUE); |
| 249 | |
| 250 | menuFont->AppendSeparator(); |
| 251 | menuFont->Append(Font_CheckNativeToFromString, |
| 252 | wxT("Check Native Font Info To/From String")); |
| 253 | |
| 254 | wxMenu *menuSelect = new wxMenu; |
| 255 | menuSelect->Append(Font_Choose, wxT("&Select font...\tCtrl-S"), |
| 256 | wxT("Select a standard font")); |
| 257 | |
| 258 | wxMenu *menuStdFonts = new wxMenu; |
| 259 | menuStdFonts->Append(Font_wxNORMAL_FONT, wxT("wxNORMAL_FONT"), wxT("Normal font used by wxWindows")); |
| 260 | menuStdFonts->Append(Font_wxSMALL_FONT, wxT("wxSMALL_FONT"), wxT("Small font used by wxWindows")); |
| 261 | menuStdFonts->Append(Font_wxITALIC_FONT, wxT("wxITALIC_FONT"), wxT("Italic font used by wxWindows")); |
| 262 | menuStdFonts->Append(Font_wxSWISS_FONT, wxT("wxSWISS_FONT"), wxT("Swiss font used by wxWindows")); |
| 263 | menuSelect->Append(-2, wxT("Standar&d fonts"), menuStdFonts); |
| 264 | |
| 265 | menuSelect->AppendSeparator(); |
| 266 | menuSelect->Append(Font_EnumFamilies, wxT("Enumerate font &families\tCtrl-F")); |
| 267 | menuSelect->Append(Font_EnumFixedFamilies, |
| 268 | wxT("Enumerate fi&xed font families\tCtrl-X")); |
| 269 | menuSelect->Append(Font_EnumEncodings, |
| 270 | wxT("Enumerate &encodings\tCtrl-E")); |
| 271 | menuSelect->Append(Font_EnumFamiliesForEncoding, |
| 272 | wxT("Find font for en&coding...\tCtrl-C"), |
| 273 | wxT("Find font families for given encoding")); |
| 274 | |
| 275 | // now append the freshly created menu to the menu bar... |
| 276 | wxMenuBar *menuBar = new wxMenuBar; |
| 277 | menuBar->Append(menuFile, wxT("&File")); |
| 278 | menuBar->Append(menuFont, wxT("F&ont")); |
| 279 | menuBar->Append(menuSelect, wxT("&Select")); |
| 280 | |
| 281 | // ... and attach this menu bar to the frame |
| 282 | SetMenuBar(menuBar); |
| 283 | |
| 284 | wxSplitterWindow *splitter = new wxSplitterWindow(this); |
| 285 | |
| 286 | m_textctrl = new wxTextCtrl(splitter, -1, |
| 287 | wxT("Paste text here to see how it looks\nlike in the given font"), |
| 288 | wxDefaultPosition, wxDefaultSize, |
| 289 | wxTE_MULTILINE); |
| 290 | |
| 291 | m_canvas = new MyCanvas(splitter); |
| 292 | |
| 293 | splitter->SplitHorizontally(m_textctrl, m_canvas, 100); |
| 294 | |
| 295 | // create a status bar just for fun (by default with 1 pane only) |
| 296 | CreateStatusBar(); |
| 297 | SetStatusText(wxT("Welcome to wxWindows font demo!")); |
| 298 | } |
| 299 | |
| 300 | // -------------------------------------------------------- |
| 301 | |
| 302 | class MyEncodingEnumerator : public wxFontEnumerator |
| 303 | { |
| 304 | public: |
| 305 | MyEncodingEnumerator() |
| 306 | { m_n = 0; } |
| 307 | |
| 308 | const wxString& GetText() const |
| 309 | { return m_text; } |
| 310 | |
| 311 | protected: |
| 312 | virtual bool OnFontEncoding(const wxString& facename, |
| 313 | const wxString& encoding) |
| 314 | { |
| 315 | wxString text; |
| 316 | text.Printf(wxT("Encoding %d: %s (available in facename '%s')\n"), |
| 317 | ++m_n, encoding.c_str(), facename.c_str()); |
| 318 | m_text += text; |
| 319 | return TRUE; |
| 320 | } |
| 321 | |
| 322 | private: |
| 323 | size_t m_n; |
| 324 | wxString m_text; |
| 325 | }; |
| 326 | |
| 327 | void MyFrame::OnEnumerateEncodings(wxCommandEvent& WXUNUSED(event)) |
| 328 | { |
| 329 | MyEncodingEnumerator fontEnumerator; |
| 330 | |
| 331 | fontEnumerator.EnumerateEncodings(); |
| 332 | |
| 333 | wxLogMessage(wxT("Enumerating all available encodings:\n%s"), |
| 334 | fontEnumerator.GetText().c_str()); |
| 335 | } |
| 336 | |
| 337 | // ------------------------------------------------------------- |
| 338 | |
| 339 | class MyFontEnumerator : public wxFontEnumerator |
| 340 | { |
| 341 | public: |
| 342 | bool GotAny() const |
| 343 | { return !m_facenames.IsEmpty(); } |
| 344 | |
| 345 | const wxArrayString& GetFacenames() const |
| 346 | { return m_facenames; } |
| 347 | |
| 348 | protected: |
| 349 | virtual bool OnFacename(const wxString& facename) |
| 350 | { |
| 351 | m_facenames.Add(facename); |
| 352 | return TRUE; |
| 353 | } |
| 354 | |
| 355 | private: |
| 356 | wxArrayString m_facenames; |
| 357 | } fontEnumerator; |
| 358 | |
| 359 | bool MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, |
| 360 | wxFontEncoding encoding, |
| 361 | bool silent) |
| 362 | { |
| 363 | MyFontEnumerator fontEnumerator; |
| 364 | |
| 365 | fontEnumerator.EnumerateFacenames(encoding, fixedWidthOnly); |
| 366 | |
| 367 | if ( fontEnumerator.GotAny() ) |
| 368 | { |
| 369 | int nFacenames = fontEnumerator.GetFacenames().GetCount(); |
| 370 | if ( !silent ) |
| 371 | { |
| 372 | wxLogStatus(this, wxT("Found %d %sfonts"), |
| 373 | nFacenames, fixedWidthOnly ? wxT("fixed width ") : wxT("")); |
| 374 | } |
| 375 | |
| 376 | wxString facename; |
| 377 | if ( silent ) |
| 378 | { |
| 379 | // choose the first |
| 380 | facename = fontEnumerator.GetFacenames().Item(0); |
| 381 | } |
| 382 | else |
| 383 | { |
| 384 | // let the user choose |
| 385 | wxString *facenames = new wxString[nFacenames]; |
| 386 | int n; |
| 387 | for ( n = 0; n < nFacenames; n++ ) |
| 388 | facenames[n] = fontEnumerator.GetFacenames().Item(n); |
| 389 | |
| 390 | n = wxGetSingleChoiceIndex(wxT("Choose a facename"), wxT("Font demo"), |
| 391 | nFacenames, facenames, this); |
| 392 | |
| 393 | if ( n != -1 ) |
| 394 | facename = facenames[n]; |
| 395 | |
| 396 | delete [] facenames; |
| 397 | } |
| 398 | |
| 399 | if ( !facename.IsEmpty() ) |
| 400 | { |
| 401 | wxFont font(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, |
| 402 | wxFONTWEIGHT_NORMAL, FALSE, facename, encoding); |
| 403 | |
| 404 | DoChangeFont(font); |
| 405 | } |
| 406 | |
| 407 | return TRUE; |
| 408 | } |
| 409 | else if ( !silent ) |
| 410 | { |
| 411 | wxLogWarning(wxT("No such fonts found.")); |
| 412 | } |
| 413 | |
| 414 | return FALSE; |
| 415 | } |
| 416 | |
| 417 | void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event)) |
| 418 | { |
| 419 | static wxFontEncoding encodings[] = |
| 420 | { |
| 421 | wxFONTENCODING_ISO8859_1, |
| 422 | wxFONTENCODING_ISO8859_2, |
| 423 | wxFONTENCODING_ISO8859_5, |
| 424 | wxFONTENCODING_ISO8859_7, |
| 425 | wxFONTENCODING_ISO8859_15, |
| 426 | wxFONTENCODING_KOI8, |
| 427 | wxFONTENCODING_CP1250, |
| 428 | wxFONTENCODING_CP1251, |
| 429 | wxFONTENCODING_CP1252, |
| 430 | }; |
| 431 | |
| 432 | static const wxString encodingNames[] = |
| 433 | { |
| 434 | wxT("Western European (ISO-8859-1)"), |
| 435 | wxT("Central European (ISO-8859-2)"), |
| 436 | wxT("Cyrillic (ISO-8859-5)"), |
| 437 | wxT("Greek (ISO-8859-7)"), |
| 438 | wxT("Western European with Euro (ISO-8859-15)"), |
| 439 | wxT("KOI8-R"), |
| 440 | wxT("Windows Central European (CP 1250)"), |
| 441 | wxT("Windows Cyrillic (CP 1251)"), |
| 442 | wxT("Windows Western European (CP 1252)"), |
| 443 | }; |
| 444 | |
| 445 | int n = wxGetSingleChoiceIndex(wxT("Choose an encoding"), wxT("Font demo"), |
| 446 | WXSIZEOF(encodingNames), |
| 447 | encodingNames, |
| 448 | this); |
| 449 | |
| 450 | if ( n != -1 ) |
| 451 | { |
| 452 | DoEnumerateFamilies(FALSE, encodings[n]); |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | void MyFrame::OnCheckNativeToFromString(wxCommandEvent& WXUNUSED(event)) |
| 457 | { |
| 458 | wxString fontInfo = m_canvas->GetTextFont().GetNativeFontInfoDesc(); |
| 459 | |
| 460 | if ( fontInfo.IsEmpty() ) |
| 461 | { |
| 462 | wxLogError(wxT("Native font info string is empty!")); |
| 463 | } |
| 464 | else |
| 465 | { |
| 466 | wxFont *font = wxFont::New(fontInfo); |
| 467 | if ( fontInfo != font->GetNativeFontInfoDesc() ) |
| 468 | wxLogError(wxT("wxNativeFontInfo ToString()/FromString() broken!")); |
| 469 | else |
| 470 | wxLogMessage(wxT("wxNativeFontInfo works: %s"), fontInfo.c_str()); |
| 471 | |
| 472 | delete font; |
| 473 | } |
| 474 | } |
| 475 | |
| 476 | void MyFrame::DoResizeFont(int diff) |
| 477 | { |
| 478 | wxFont font = m_canvas->GetTextFont(); |
| 479 | |
| 480 | font.SetPointSize(font.GetPointSize() + diff); |
| 481 | DoChangeFont(font); |
| 482 | } |
| 483 | |
| 484 | void MyFrame::OnBold(wxCommandEvent& event) |
| 485 | { |
| 486 | wxFont font = m_canvas->GetTextFont(); |
| 487 | |
| 488 | font.SetWeight(event.IsChecked() ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL); |
| 489 | DoChangeFont(font); |
| 490 | } |
| 491 | |
| 492 | void MyFrame::OnItalic(wxCommandEvent& event) |
| 493 | { |
| 494 | wxFont font = m_canvas->GetTextFont(); |
| 495 | |
| 496 | font.SetStyle(event.IsChecked() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL); |
| 497 | DoChangeFont(font); |
| 498 | } |
| 499 | |
| 500 | void MyFrame::OnUnderline(wxCommandEvent& event) |
| 501 | { |
| 502 | wxFont font = m_canvas->GetTextFont(); |
| 503 | |
| 504 | font.SetUnderlined(event.IsChecked()); |
| 505 | DoChangeFont(font); |
| 506 | } |
| 507 | |
| 508 | void MyFrame::OnwxPointerFont(wxCommandEvent& event) |
| 509 | { |
| 510 | wxFont font; |
| 511 | |
| 512 | switch (event.GetId()) |
| 513 | { |
| 514 | case Font_wxNORMAL_FONT : font = wxFont(*wxNORMAL_FONT); break; |
| 515 | case Font_wxSMALL_FONT : font = wxFont(*wxSMALL_FONT); break; |
| 516 | case Font_wxITALIC_FONT : font = wxFont(*wxITALIC_FONT); break; |
| 517 | case Font_wxSWISS_FONT : font = wxFont(*wxSWISS_FONT); break; |
| 518 | default : font = wxFont(*wxNORMAL_FONT); break; |
| 519 | } |
| 520 | |
| 521 | GetMenuBar()->Check(Font_Bold, FALSE); |
| 522 | GetMenuBar()->Check(Font_Italic, FALSE); |
| 523 | GetMenuBar()->Check(Font_Underlined, FALSE); |
| 524 | |
| 525 | DoChangeFont(font); |
| 526 | } |
| 527 | |
| 528 | void MyFrame::DoChangeFont(const wxFont& font, const wxColour& col) |
| 529 | { |
| 530 | m_canvas->SetTextFont(font); |
| 531 | if ( col.Ok() ) |
| 532 | m_canvas->SetColour(col); |
| 533 | m_canvas->Refresh(); |
| 534 | |
| 535 | m_textctrl->SetFont(font); |
| 536 | if ( col.Ok() ) |
| 537 | m_textctrl->SetForegroundColour(col); |
| 538 | } |
| 539 | |
| 540 | void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event)) |
| 541 | { |
| 542 | wxFontData data; |
| 543 | data.SetInitialFont(m_canvas->GetTextFont()); |
| 544 | data.SetColour(m_canvas->GetColour()); |
| 545 | |
| 546 | wxFontDialog dialog(this, data); |
| 547 | if ( dialog.ShowModal() == wxID_OK ) |
| 548 | { |
| 549 | wxFontData retData = dialog.GetFontData(); |
| 550 | wxFont font = retData.GetChosenFont(); |
| 551 | wxColour colour = retData.GetColour(); |
| 552 | |
| 553 | DoChangeFont(font, colour); |
| 554 | |
| 555 | // update the state of the bold/italic/underlined menu items |
| 556 | wxMenuBar *mbar = GetMenuBar(); |
| 557 | if ( mbar ) |
| 558 | { |
| 559 | mbar->Check(Font_Bold, font.GetWeight() == wxFONTWEIGHT_BOLD); |
| 560 | mbar->Check(Font_Italic, font.GetStyle() == wxFONTSTYLE_ITALIC); |
| 561 | mbar->Check(Font_Underlined, font.GetUnderlined()); |
| 562 | } |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) |
| 567 | { |
| 568 | // TRUE is to force the frame to close |
| 569 | Close(TRUE); |
| 570 | } |
| 571 | |
| 572 | void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event)) |
| 573 | { |
| 574 | // first, choose the file |
| 575 | static wxString s_dir, s_file; |
| 576 | wxFileDialog dialog(this, wxT("Open an email message file"), |
| 577 | s_dir, s_file); |
| 578 | if ( dialog.ShowModal() != wxID_OK ) |
| 579 | return; |
| 580 | |
| 581 | // save for the next time |
| 582 | s_dir = dialog.GetDirectory(); |
| 583 | s_file = dialog.GetFilename(); |
| 584 | |
| 585 | wxString filename = dialog.GetPath(); |
| 586 | |
| 587 | // load it and search for Content-Type header |
| 588 | wxTextFile file(filename); |
| 589 | if ( !file.Open() ) |
| 590 | return; |
| 591 | |
| 592 | wxString charset; |
| 593 | |
| 594 | static const wxChar *prefix = wxT("Content-Type: text/plain; charset="); |
| 595 | const size_t len = wxStrlen(prefix); |
| 596 | |
| 597 | size_t n, count = file.GetLineCount(); |
| 598 | for ( n = 0; n < count; n++ ) |
| 599 | { |
| 600 | wxString line = file[n]; |
| 601 | |
| 602 | if ( !line ) |
| 603 | { |
| 604 | // if it is an email message, headers are over, no need to parse |
| 605 | // all the file |
| 606 | break; |
| 607 | } |
| 608 | |
| 609 | if ( line.Left(len) == prefix ) |
| 610 | { |
| 611 | // found! |
| 612 | const wxChar *pc = line.c_str() + len; |
| 613 | if ( *pc == wxT('"') ) |
| 614 | pc++; |
| 615 | |
| 616 | while ( *pc && *pc != wxT('"') ) |
| 617 | { |
| 618 | charset += *pc++; |
| 619 | } |
| 620 | |
| 621 | break; |
| 622 | } |
| 623 | } |
| 624 | |
| 625 | if ( !charset ) |
| 626 | { |
| 627 | wxLogError(wxT("The file '%s' doesn't contain charset information."), |
| 628 | filename.c_str()); |
| 629 | |
| 630 | return; |
| 631 | } |
| 632 | |
| 633 | // ok, now get the corresponding encoding |
| 634 | wxFontEncoding fontenc = wxFontMapper::Get()->CharsetToEncoding(charset); |
| 635 | if ( fontenc == wxFONTENCODING_SYSTEM ) |
| 636 | { |
| 637 | wxLogError(wxT("Charset '%s' is unsupported."), charset.c_str()); |
| 638 | return; |
| 639 | } |
| 640 | |
| 641 | m_textctrl->LoadFile(filename); |
| 642 | |
| 643 | if ( fontenc == wxFONTENCODING_UTF8 || |
| 644 | !wxFontMapper::Get()->IsEncodingAvailable(fontenc) ) |
| 645 | { |
| 646 | // try to find some similar encoding: |
| 647 | wxFontEncoding encAlt; |
| 648 | if ( wxFontMapper::Get()->GetAltForEncoding(fontenc, &encAlt) ) |
| 649 | { |
| 650 | wxEncodingConverter conv; |
| 651 | |
| 652 | if (conv.Init(fontenc, encAlt)) |
| 653 | { |
| 654 | fontenc = encAlt; |
| 655 | m_textctrl -> SetValue(conv.Convert(m_textctrl -> GetValue())); |
| 656 | } |
| 657 | else |
| 658 | { |
| 659 | wxLogWarning(wxT("Cannot convert from '%s' to '%s'."), |
| 660 | wxFontMapper::GetEncodingDescription(fontenc).c_str(), |
| 661 | wxFontMapper::GetEncodingDescription(encAlt).c_str()); |
| 662 | } |
| 663 | } |
| 664 | else |
| 665 | wxLogWarning(wxT("No fonts for encoding '%s' on this system."), |
| 666 | wxFontMapper::GetEncodingDescription(fontenc).c_str()); |
| 667 | } |
| 668 | |
| 669 | // and now create the correct font |
| 670 | if ( !DoEnumerateFamilies(FALSE, fontenc, TRUE /* silent */) ) |
| 671 | { |
| 672 | wxFont font(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, |
| 673 | wxFONTWEIGHT_NORMAL, FALSE /* !underlined */, |
| 674 | wxEmptyString /* facename */, fontenc); |
| 675 | if ( font.Ok() ) |
| 676 | { |
| 677 | DoChangeFont(font); |
| 678 | } |
| 679 | else |
| 680 | { |
| 681 | wxLogWarning(wxT("No fonts for encoding '%s' on this system."), |
| 682 | wxFontMapper::GetEncodingDescription(fontenc).c_str()); |
| 683 | } |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) |
| 688 | { |
| 689 | wxMessageBox(wxT("wxWindows font demo\n") |
| 690 | wxT("(c) 1999 Vadim Zeitlin"), |
| 691 | wxT("About Font"), |
| 692 | wxOK | wxICON_INFORMATION, this); |
| 693 | } |
| 694 | |
| 695 | // ---------------------------------------------------------------------------- |
| 696 | // MyCanvas |
| 697 | // ---------------------------------------------------------------------------- |
| 698 | |
| 699 | BEGIN_EVENT_TABLE(MyCanvas, wxWindow) |
| 700 | EVT_PAINT(MyCanvas::OnPaint) |
| 701 | END_EVENT_TABLE() |
| 702 | |
| 703 | MyCanvas::MyCanvas( wxWindow *parent ) |
| 704 | : wxWindow( parent, -1 ), |
| 705 | m_colour(*wxRED), m_font(*wxNORMAL_FONT) |
| 706 | { |
| 707 | } |
| 708 | |
| 709 | MyCanvas::~MyCanvas() |
| 710 | { |
| 711 | } |
| 712 | |
| 713 | void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) |
| 714 | { |
| 715 | wxPaintDC dc(this); |
| 716 | PrepareDC(dc); |
| 717 | |
| 718 | // set background |
| 719 | dc.SetBackground(wxBrush(wxT("white"), wxSOLID)); |
| 720 | dc.Clear(); |
| 721 | |
| 722 | // one text line height |
| 723 | wxCoord hLine = dc.GetCharHeight(); |
| 724 | |
| 725 | // the current text origin |
| 726 | wxCoord x = 5, |
| 727 | y = 5; |
| 728 | |
| 729 | // output the font name/info |
| 730 | wxString fontInfo; |
| 731 | fontInfo.Printf(wxT("Font size is %d points, family: %s, encoding: %s"), |
| 732 | m_font.GetPointSize(), |
| 733 | m_font.GetFamilyString().c_str(), |
| 734 | wxFontMapper::Get()-> |
| 735 | GetEncodingDescription(m_font.GetEncoding()).c_str()); |
| 736 | |
| 737 | dc.DrawText(fontInfo, x, y); |
| 738 | y += hLine; |
| 739 | |
| 740 | fontInfo.Printf(wxT("Style: %s, weight: %s, fixed width: %s"), |
| 741 | m_font.GetStyleString().c_str(), |
| 742 | m_font.GetWeightString().c_str(), |
| 743 | m_font.IsFixedWidth() ? _T("yes") : _T("no")); |
| 744 | |
| 745 | dc.DrawText(fontInfo, x, y); |
| 746 | y += hLine; |
| 747 | |
| 748 | if ( m_font.Ok() ) |
| 749 | { |
| 750 | wxNativeFontInfo *info = m_font.GetNativeFontInfo(); |
| 751 | if ( info ) |
| 752 | { |
| 753 | delete info; |
| 754 | |
| 755 | wxString fontDesc = m_font.GetNativeFontInfoUserDesc(); |
| 756 | fontInfo.Printf(wxT("Native font info: %s"), fontDesc.c_str()); |
| 757 | |
| 758 | dc.DrawText(fontInfo, x, y); |
| 759 | y += hLine; |
| 760 | } |
| 761 | } |
| 762 | |
| 763 | y += hLine; |
| 764 | |
| 765 | // prepare to draw the font |
| 766 | dc.SetFont(m_font); |
| 767 | dc.SetTextForeground(m_colour); |
| 768 | |
| 769 | // the size of one cell (Normally biggest char + small margin) |
| 770 | long maxCharWidth, maxCharHeight; |
| 771 | dc.GetTextExtent(wxT("W"), &maxCharWidth, &maxCharHeight); |
| 772 | int w = maxCharWidth + 5, |
| 773 | h = maxCharHeight + 4; |
| 774 | |
| 775 | |
| 776 | // print all font symbols from 32 to 256 in 7 rows of 32 chars each |
| 777 | for ( int i = 0; i < 7; i++ ) |
| 778 | { |
| 779 | for ( int j = 0; j < 32; j++ ) |
| 780 | { |
| 781 | wxChar c = 32 * (i + 1) + j; |
| 782 | |
| 783 | long charWidth, charHeight; |
| 784 | dc.GetTextExtent(c, &charWidth, &charHeight); |
| 785 | dc.DrawText |
| 786 | ( |
| 787 | c, |
| 788 | x + w*j + (maxCharWidth - charWidth) / 2 + 1, |
| 789 | y + h*i + (maxCharHeight - charHeight) / 2 |
| 790 | ); |
| 791 | } |
| 792 | } |
| 793 | |
| 794 | // draw the lines between them |
| 795 | dc.SetPen(wxPen(wxColour(_T("blue")), 1, wxSOLID)); |
| 796 | int l; |
| 797 | |
| 798 | // horizontal |
| 799 | for ( l = 0; l < 8; l++ ) |
| 800 | { |
| 801 | int yl = y + h*l - 2; |
| 802 | dc.DrawLine(x - 2, yl, x + 32*w - 1, yl); |
| 803 | } |
| 804 | |
| 805 | // and vertical |
| 806 | for ( l = 0; l < 33; l++ ) |
| 807 | { |
| 808 | int xl = x + w*l - 2; |
| 809 | dc.DrawLine(xl, y - 2, xl, y + 7*h - 1); |
| 810 | } |
| 811 | } |