1///////////////////////////////////////////////////////////////////////////// 2// Name: src/msw/font.cpp 3// Purpose: wxFont class 4// Author: Julian Smart 5// Modified by: 6// Created: 01/02/97 7// RCS-ID: $Id: font.cpp 48064 2007-08-14 08:51:44Z JS $ 8// Copyright: (c) wxWidgets team 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20// For compilers that support precompilation, includes "wx.h". 21#include "wx/wxprec.h" 22 23#ifdef __BORLANDC__ 24 #pragma hdrstop 25#endif 26 27#include "wx/font.h" 28 29#ifndef WX_PRECOMP 30 #include "wx/list.h" 31 #include "wx/utils.h" 32 #include "wx/app.h" 33 #include "wx/log.h" 34 #include "wx/encinfo.h" 35#endif // WX_PRECOMP 36 37#include "wx/msw/private.h" 38 39#include "wx/fontutil.h" 40#include "wx/fontmap.h" 41 42#ifndef __WXWINCE__ 43 #include "wx/sysopt.h" 44#endif 45 46#include "wx/tokenzr.h" 47 48#if wxUSE_EXTENDED_RTTI 49 50wxBEGIN_ENUM( wxFontFamily ) 51 wxENUM_MEMBER( wxDEFAULT ) 52 wxENUM_MEMBER( wxDECORATIVE ) 53 wxENUM_MEMBER( wxROMAN ) 54 wxENUM_MEMBER( wxSCRIPT ) 55 wxENUM_MEMBER( wxSWISS ) 56 wxENUM_MEMBER( wxMODERN ) 57 wxENUM_MEMBER( wxTELETYPE ) 58wxEND_ENUM( wxFontFamily ) 59 60wxBEGIN_ENUM( wxFontStyle ) 61 wxENUM_MEMBER( wxNORMAL ) 62 wxENUM_MEMBER( wxITALIC ) 63 wxENUM_MEMBER( wxSLANT ) 64wxEND_ENUM( wxFontStyle ) 65 66wxBEGIN_ENUM( wxFontWeight ) 67 wxENUM_MEMBER( wxNORMAL ) 68 wxENUM_MEMBER( wxLIGHT ) 69 wxENUM_MEMBER( wxBOLD ) 70wxEND_ENUM( wxFontWeight ) 71 72IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h") 73 74wxBEGIN_PROPERTIES_TABLE(wxFont) 75 wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 76 wxPROPERTY( Family, int , SetFamily, GetFamily, (int)wxDEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontFamily 77 wxPROPERTY( Style, int , SetStyle, GetStyle, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontStyle 78 wxPROPERTY( Weight, int , SetWeight, GetWeight, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontWeight 79 wxPROPERTY( Underlined, bool , SetUnderlined, GetUnderlined, false , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 80 wxPROPERTY( Face, wxString , SetFaceName, GetFaceName, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 81 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 82wxEND_PROPERTIES_TABLE() 83 84wxCONSTRUCTOR_6( wxFont , int , Size , int , Family , int , Style , int , Weight , bool , Underlined , wxString , Face ) 85 86wxBEGIN_HANDLERS_TABLE(wxFont) 87wxEND_HANDLERS_TABLE() 88 89#else 90 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) 91#endif 92 93 94// ---------------------------------------------------------------------------- 95// constants 96// ---------------------------------------------------------------------------- 97 98// the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field 99static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH; 100 101// ---------------------------------------------------------------------------- 102// wxFontRefData - the internal description of the font 103// ---------------------------------------------------------------------------- 104 105class WXDLLEXPORT wxFontRefData: public wxGDIRefData 106{ 107public: 108 // constructors 109 wxFontRefData() 110 { 111 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, 112 wxFONTWEIGHT_NORMAL, false, wxEmptyString, 113 wxFONTENCODING_DEFAULT); 114 } 115 116 wxFontRefData(int size, 117 const wxSize& pixelSize, 118 bool sizeUsingPixels, 119 int family, 120 int style, 121 int weight, 122 bool underlined, 123 const wxString& faceName, 124 wxFontEncoding encoding) 125 { 126 Init(size, pixelSize, sizeUsingPixels, family, style, weight, 127 underlined, faceName, encoding); 128 } 129 130 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0) 131 { 132 Init(info, hFont); 133 } 134 135 wxFontRefData(const wxFontRefData& data) : wxGDIRefData() 136 { 137 if ( data.m_nativeFontInfoOk ) 138 { 139 Init(data.m_nativeFontInfo); 140 } 141 else 142 { 143 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels, 144 data.m_family, data.m_style, data.m_weight, 145 data.m_underlined, data.m_faceName, data.m_encoding); 146 } 147 } 148 149 virtual ~wxFontRefData(); 150 151 // operations 152 bool Alloc(wxFont *font); 153 154 void Free(); 155 156 // all wxFont accessors 157 int GetPointSize() const 158 { 159 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize() 160 : m_pointSize; 161 } 162 163 wxSize GetPixelSize() const 164 { 165 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize() 166 : m_pixelSize; 167 } 168 169 bool IsUsingSizeInPixels() const 170 { 171 return m_nativeFontInfoOk ? true : m_sizeUsingPixels; 172 } 173 174 int GetFamily() const 175 { 176 return m_family; 177 } 178 179 int GetStyle() const 180 { 181 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle() 182 : m_style; 183 } 184 185 int GetWeight() const 186 { 187 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight() 188 : m_weight; 189 } 190 191 bool GetUnderlined() const 192 { 193 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined() 194 : m_underlined; 195 } 196 197 wxString GetFaceName() const 198 { 199 wxString s; 200 if ( m_nativeFontInfoOk ) 201 s = m_nativeFontInfo.GetFaceName(); 202 else 203 s = m_faceName; 204 205 return s; 206 } 207 208 wxFontEncoding GetEncoding() const 209 { 210 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding() 211 : m_encoding; 212 } 213 214 WXHFONT GetHFONT() const { return m_hFont; } 215 216 // ... and setters 217 void SetPointSize(int pointSize) 218 { 219 if ( m_nativeFontInfoOk ) 220 { 221 m_nativeFontInfo.SetPointSize(pointSize); 222 } 223 else 224 { 225 m_pointSize = pointSize; 226 m_sizeUsingPixels = false; 227 } 228 } 229 230 void SetPixelSize(const wxSize& pixelSize) 231 { 232 if ( m_nativeFontInfoOk ) 233 { 234 m_nativeFontInfo.SetPixelSize(pixelSize); 235 } 236 else 237 { 238 m_pixelSize = pixelSize; 239 m_sizeUsingPixels = true; 240 } 241 } 242 243 void SetFamily(int family) 244 { 245 m_family = family; 246 } 247 248 void SetStyle(int style) 249 { 250 if ( m_nativeFontInfoOk ) 251 m_nativeFontInfo.SetStyle((wxFontStyle)style); 252 else 253 m_style = style; 254 } 255 256 void SetWeight(int weight) 257 { 258 if ( m_nativeFontInfoOk ) 259 m_nativeFontInfo.SetWeight((wxFontWeight)weight); 260 else 261 m_weight = weight; 262 } 263 264 bool SetFaceName(const wxString& faceName) 265 { 266 if ( m_nativeFontInfoOk ) 267 return m_nativeFontInfo.SetFaceName(faceName); 268 269 m_faceName = faceName; 270 return true; 271 } 272 273 void SetUnderlined(bool underlined) 274 { 275 if ( m_nativeFontInfoOk ) 276 m_nativeFontInfo.SetUnderlined(underlined); 277 else 278 m_underlined = underlined; 279 } 280 281 void SetEncoding(wxFontEncoding encoding) 282 { 283 if ( m_nativeFontInfoOk ) 284 m_nativeFontInfo.SetEncoding(encoding); 285 else 286 m_encoding = encoding; 287 } 288 289 // native font info tests 290 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; } 291 292 const wxNativeFontInfo& GetNativeFontInfo() const 293 { return m_nativeFontInfo; } 294 295protected: 296 // common part of all ctors 297 void Init(int size, 298 const wxSize& pixelSize, 299 bool sizeUsingPixels, 300 int family, 301 int style, 302 int weight, 303 bool underlined, 304 const wxString& faceName, 305 wxFontEncoding encoding); 306 307 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0); 308 309 // font characterstics 310 int m_pointSize; 311 wxSize m_pixelSize; 312 bool m_sizeUsingPixels; 313 int m_family; 314 int m_style; 315 int m_weight; 316 bool m_underlined; 317 wxString m_faceName; 318 wxFontEncoding m_encoding; 319 320 // Windows font handle 321 WXHFONT m_hFont; 322 323 // Native font info 324 wxNativeFontInfo m_nativeFontInfo; 325 bool m_nativeFontInfoOk; 326}; 327 328#define M_FONTDATA ((wxFontRefData*)m_refData) 329 330// ============================================================================ 331// implementation 332// ============================================================================ 333 334// ---------------------------------------------------------------------------- 335// wxFontRefData 336// ---------------------------------------------------------------------------- 337 338void wxFontRefData::Init(int pointSize, 339 const wxSize& pixelSize, 340 bool sizeUsingPixels, 341 int family, 342 int style, 343 int weight, 344 bool underlined, 345 const wxString& faceName, 346 wxFontEncoding encoding) 347{ 348 m_style = style; 349 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize; 350 m_pixelSize = pixelSize; 351 m_sizeUsingPixels = sizeUsingPixels; 352 m_family = family; 353 m_style = style; 354 m_weight = weight; 355 m_underlined = underlined; 356 m_faceName = faceName; 357 m_encoding = encoding; 358 359 m_hFont = 0; 360 361 m_nativeFontInfoOk = false; 362} 363 364void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont) 365{ 366 // hFont may be zero, or it be passed in case we really want to 367 // use the exact font created in the underlying system 368 // (for example where we can't guarantee conversion from HFONT 369 // to LOGFONT back to HFONT) 370 m_hFont = hFont; 371 372 m_nativeFontInfoOk = true; 373 m_nativeFontInfo = info; 374 // This is the best we can do since we don't have the 375 // correct information at this point. 376 m_family = wxSWISS; 377} 378 379wxFontRefData::~wxFontRefData() 380{ 381 Free(); 382} 383 384bool wxFontRefData::Alloc(wxFont *font) 385{ 386 if ( !m_nativeFontInfoOk ) 387 { 388 wxFillLogFont(&m_nativeFontInfo.lf, font); 389 m_nativeFontInfoOk = true; 390 } 391 392 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf); 393 if ( !hfont ) 394 { 395 wxLogLastError(wxT("CreateFont")); 396 return false; 397 } 398 399 m_hFont = (WXHFONT)hfont; 400 return true; 401} 402 403void wxFontRefData::Free() 404{ 405 if ( m_hFont ) 406 { 407 if ( !::DeleteObject((HFONT) m_hFont) ) 408 { 409 wxLogLastError(wxT("DeleteObject(font)")); 410 } 411 412 m_hFont = 0; 413 } 414} 415 416// ---------------------------------------------------------------------------- 417// wxNativeFontInfo 418// ---------------------------------------------------------------------------- 419 420void wxNativeFontInfo::Init() 421{ 422 wxZeroMemory(lf); 423 424 // we get better font quality if we use PROOF_QUALITY instead of 425 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available 426 // then so we allow to set a global option to choose between quality and 427 // wider font selection 428#ifdef __WXWINCE__ 429 lf.lfQuality = CLEARTYPE_QUALITY; 430#else 431 lf.lfQuality = wxSystemOptions::GetOptionInt(_T("msw.font.no-proof-quality")) 432 ? DEFAULT_QUALITY 433 : PROOF_QUALITY; 434#endif 435} 436 437int wxNativeFontInfo::GetPointSize() const 438{ 439 // FIXME: using the screen here results in incorrect font size calculation 440 // for printing! 441 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); 442 443 return (int) (((72.0*(double)abs((int) lf.lfHeight)) / (double) ppInch) + 0.5); 444} 445 446wxSize wxNativeFontInfo::GetPixelSize() const 447{ 448 wxSize ret; 449 ret.SetHeight(lf.lfHeight); 450 ret.SetWidth(lf.lfWidth); 451 return ret; 452} 453 454wxFontStyle wxNativeFontInfo::GetStyle() const 455{ 456 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL; 457} 458 459wxFontWeight wxNativeFontInfo::GetWeight() const 460{ 461 if ( lf.lfWeight <= 300 ) 462 return wxFONTWEIGHT_LIGHT; 463 464 if ( lf.lfWeight >= 600 ) 465 return wxFONTWEIGHT_BOLD; 466 467 return wxFONTWEIGHT_NORMAL; 468} 469 470bool wxNativeFontInfo::GetUnderlined() const 471{ 472 return lf.lfUnderline != 0; 473} 474 475wxString wxNativeFontInfo::GetFaceName() const 476{ 477 return lf.lfFaceName; 478} 479 480wxFontFamily wxNativeFontInfo::GetFamily() const 481{ 482 wxFontFamily family; 483 484 // extract family from pitch-and-family 485 switch ( lf.lfPitchAndFamily & ~PITCH_MASK ) 486 { 487 case FF_ROMAN: 488 family = wxFONTFAMILY_ROMAN; 489 break; 490 491 default: 492 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") ); 493 // fall through 494 495 case FF_SWISS: 496 family = wxFONTFAMILY_SWISS; 497 break; 498 499 case FF_SCRIPT: 500 family = wxFONTFAMILY_SCRIPT; 501 break; 502 503 case FF_MODERN: 504 family = wxFONTFAMILY_MODERN; 505 break; 506 507 case FF_DECORATIVE: 508 family = wxFONTFAMILY_DECORATIVE; 509 break; 510 } 511 512 return family; 513} 514 515wxFontEncoding wxNativeFontInfo::GetEncoding() const 516{ 517 return wxGetFontEncFromCharSet(lf.lfCharSet); 518} 519 520void wxNativeFontInfo::SetPointSize(int pointsize) 521{ 522 // FIXME: using the screen here results in incorrect font size calculation 523 // for printing! 524 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); 525 526 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5); 527} 528 529void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize) 530{ 531 lf.lfHeight = pixelSize.GetHeight(); 532 lf.lfWidth = pixelSize.GetWidth(); 533} 534 535 536void wxNativeFontInfo::SetStyle(wxFontStyle style) 537{ 538 switch ( style ) 539 { 540 default: 541 wxFAIL_MSG( _T("unknown font style") ); 542 // fall through 543 544 case wxFONTSTYLE_NORMAL: 545 lf.lfItalic = FALSE; 546 break; 547 548 case wxFONTSTYLE_ITALIC: 549 case wxFONTSTYLE_SLANT: 550 lf.lfItalic = TRUE; 551 break; 552 } 553} 554 555void wxNativeFontInfo::SetWeight(wxFontWeight weight) 556{ 557 switch ( weight ) 558 { 559 default: 560 wxFAIL_MSG( _T("unknown font weight") ); 561 // fall through 562 563 case wxFONTWEIGHT_NORMAL: 564 lf.lfWeight = FW_NORMAL; 565 break; 566 567 case wxFONTWEIGHT_LIGHT: 568 lf.lfWeight = FW_LIGHT; 569 break; 570 571 case wxFONTWEIGHT_BOLD: 572 lf.lfWeight = FW_BOLD; 573 break; 574 } 575} 576 577void wxNativeFontInfo::SetUnderlined(bool underlined) 578{ 579 lf.lfUnderline = underlined; 580} 581 582bool wxNativeFontInfo::SetFaceName(const wxString& facename) 583{ 584 size_t len = WXSIZEOF(lf.lfFaceName); 585 wxStrncpy(lf.lfFaceName, facename, len); 586 lf.lfFaceName[len - 1] = '\0'; // truncate the face name 587 return true; 588} 589 590void wxNativeFontInfo::SetFamily(wxFontFamily family) 591{ 592 BYTE ff_family; 593 wxArrayString facename; 594 595 // the list of fonts associated with a family was partially 596 // taken from http://www.codestyle.org/css/font-family 597 598 switch ( family ) 599 { 600 case wxSCRIPT: 601 ff_family = FF_SCRIPT; 602 facename.Add(_T("Script")); 603 facename.Add(_T("Brush Script MT")); 604 facename.Add(_T("Comic Sans MS")); 605 facename.Add(_T("Lucida Handwriting")); 606 break; 607 608 case wxDECORATIVE: 609 ff_family = FF_DECORATIVE; 610 facename.Add(_T("Old English Text MT")); 611 facename.Add(_T("Comic Sans MS")); 612 facename.Add(_T("Lucida Handwriting")); 613 break; 614 615 case wxROMAN: 616 ff_family = FF_ROMAN; 617 facename.Add(_T("Times New Roman")); 618 facename.Add(_T("Georgia")); 619 facename.Add(_T("Garamond")); 620 facename.Add(_T("Bookman Old Style")); 621 facename.Add(_T("Book Antiqua")); 622 break; 623 624 case wxTELETYPE: 625 case wxMODERN: 626 ff_family = FF_MODERN; 627 facename.Add(_T("Courier New")); 628 facename.Add(_T("Lucida Console")); 629 facename.Add(_T("Andale Mono")); 630 facename.Add(_T("OCR A Extended")); 631 facename.Add(_T("Terminal")); 632 break; 633 634 case wxSWISS: 635 ff_family = FF_SWISS; 636 facename.Add(_T("Arial")); 637 facename.Add(_T("Century Gothic")); 638 facename.Add(_T("Lucida Sans Unicode")); 639 facename.Add(_T("Tahoma")); 640 facename.Add(_T("Trebuchet MS")); 641 facename.Add(_T("Verdana")); 642 break; 643 644 case wxDEFAULT: 645 default: 646 { 647 // We want Windows 2000 or later to have new fonts even MS Shell Dlg 648 // is returned as default GUI font for compatibility 649 int verMaj; 650 ff_family = FF_SWISS; 651 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5) 652 facename.Add(_T("MS Shell Dlg 2")); 653 else 654 facename.Add(_T("MS Shell Dlg")); 655 656 // Quoting the MSDN: 657 // "MS Shell Dlg is a mapping mechanism that enables 658 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to 659 // support locales that have characters that are not contained in code 660 // page 1252. It is not a font but a face name for a nonexistent font." 661 } 662 } 663 664 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family; 665 666 if ( !wxStrlen(lf.lfFaceName) ) 667 { 668 SetFaceName(facename); 669 } 670} 671 672void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding) 673{ 674 wxNativeEncodingInfo info; 675 if ( !wxGetNativeFontEncoding(encoding, &info) ) 676 { 677#if wxUSE_FONTMAP 678 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) ) 679 { 680 if ( !info.facename.empty() ) 681 { 682 // if we have this encoding only in some particular facename, use 683 // the facename - it is better to show the correct characters in a 684 // wrong facename than unreadable text in a correct one 685 SetFaceName(info.facename); 686 } 687 } 688 else 689#endif // wxUSE_FONTMAP 690 { 691 // unsupported encoding, replace with the default 692 info.charset = DEFAULT_CHARSET; 693 } 694 } 695 696 lf.lfCharSet = (BYTE)info.charset; 697} 698 699bool wxNativeFontInfo::FromString(const wxString& s) 700{ 701 long l; 702 703 wxStringTokenizer tokenizer(s, _T(";")); 704 705 // first the version 706 wxString token = tokenizer.GetNextToken(); 707 if ( token != _T('0') ) 708 return false; 709 710 token = tokenizer.GetNextToken(); 711 if ( !token.ToLong(&l) ) 712 return false; 713 lf.lfHeight = l; 714 715 token = tokenizer.GetNextToken(); 716 if ( !token.ToLong(&l) ) 717 return false; 718 lf.lfWidth = l; 719 720 token = tokenizer.GetNextToken(); 721 if ( !token.ToLong(&l) ) 722 return false; 723 lf.lfEscapement = l; 724 725 token = tokenizer.GetNextToken(); 726 if ( !token.ToLong(&l) ) 727 return false; 728 lf.lfOrientation = l; 729 730 token = tokenizer.GetNextToken(); 731 if ( !token.ToLong(&l) ) 732 return false; 733 lf.lfWeight = l; 734 735 token = tokenizer.GetNextToken(); 736 if ( !token.ToLong(&l) ) 737 return false; 738 lf.lfItalic = (BYTE)l; 739 740 token = tokenizer.GetNextToken(); 741 if ( !token.ToLong(&l) ) 742 return false; 743 lf.lfUnderline = (BYTE)l; 744 745 token = tokenizer.GetNextToken(); 746 if ( !token.ToLong(&l) ) 747 return false; 748 lf.lfStrikeOut = (BYTE)l; 749 750 token = tokenizer.GetNextToken(); 751 if ( !token.ToLong(&l) ) 752 return false; 753 lf.lfCharSet = (BYTE)l; 754 755 token = tokenizer.GetNextToken(); 756 if ( !token.ToLong(&l) ) 757 return false; 758 lf.lfOutPrecision = (BYTE)l; 759 760 token = tokenizer.GetNextToken(); 761 if ( !token.ToLong(&l) ) 762 return false; 763 lf.lfClipPrecision = (BYTE)l; 764 765 token = tokenizer.GetNextToken(); 766 if ( !token.ToLong(&l) ) 767 return false; 768 lf.lfQuality = (BYTE)l; 769 770 token = tokenizer.GetNextToken(); 771 if ( !token.ToLong(&l) ) 772 return false; 773 lf.lfPitchAndFamily = (BYTE)l; 774 775 token = tokenizer.GetNextToken(); 776 if(!token) 777 return false; 778 wxStrcpy(lf.lfFaceName, token.c_str()); 779 780 return true; 781} 782 783wxString wxNativeFontInfo::ToString() const 784{ 785 wxString s; 786 787 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"), 788 0, // version, in case we want to change the format later 789 lf.lfHeight, 790 lf.lfWidth, 791 lf.lfEscapement, 792 lf.lfOrientation, 793 lf.lfWeight, 794 lf.lfItalic, 795 lf.lfUnderline, 796 lf.lfStrikeOut, 797 lf.lfCharSet, 798 lf.lfOutPrecision, 799 lf.lfClipPrecision, 800 lf.lfQuality, 801 lf.lfPitchAndFamily, 802 lf.lfFaceName); 803 804 return s; 805} 806 807// ---------------------------------------------------------------------------- 808// wxFont 809// ---------------------------------------------------------------------------- 810 811bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont) 812{ 813 UnRef(); 814 815 m_refData = new wxFontRefData(info, hFont); 816 817 RealizeResource(); 818 819 return true; 820} 821 822wxFont::wxFont(const wxString& fontdesc) 823{ 824 wxNativeFontInfo info; 825 if ( info.FromString(fontdesc) ) 826 (void)Create(info); 827} 828 829/* Constructor for a font. Note that the real construction is done 830 * in wxDC::SetFont, when information is available about scaling etc. 831 */ 832bool wxFont::DoCreate(int pointSize, 833 const wxSize& pixelSize, 834 bool sizeUsingPixels, 835 int family, 836 int style, 837 int weight, 838 bool underlined, 839 const wxString& faceName, 840 wxFontEncoding encoding) 841{ 842 UnRef(); 843 844 // wxDEFAULT is a valid value for the font size too so we must treat it 845 // specially here (otherwise the size would be 70 == wxDEFAULT value) 846 if ( pointSize == wxDEFAULT ) 847 { 848 pointSize = wxNORMAL_FONT->GetPointSize(); 849 } 850 851 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels, 852 family, style, weight, 853 underlined, faceName, encoding); 854 855 RealizeResource(); 856 857 return true; 858} 859 860wxFont::~wxFont() 861{ 862} 863 864// ---------------------------------------------------------------------------- 865// real implementation 866// ---------------------------------------------------------------------------- 867 868bool wxFont::RealizeResource() 869{ 870 if ( GetResourceHandle() ) 871 { 872 // VZ: the old code returned false in this case, but it doesn't seem 873 // to make sense because the font _was_ created 874 return true; 875 } 876 877 return M_FONTDATA->Alloc(this); 878} 879 880bool wxFont::FreeResource(bool WXUNUSED(force)) 881{ 882 if ( GetResourceHandle() ) 883 { 884 M_FONTDATA->Free(); 885 886 return true; 887 } 888 889 return false; 890} 891 892WXHANDLE wxFont::GetResourceHandle() const 893{ 894 return (WXHANDLE)GetHFONT(); 895} 896 897WXHFONT wxFont::GetHFONT() const 898{ 899 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0; 900} 901 902bool wxFont::IsFree() const 903{ 904 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0); 905} 906 907void wxFont::Unshare() 908{ 909 // Don't change shared data 910 if ( !m_refData ) 911 { 912 m_refData = new wxFontRefData(); 913 } 914 else 915 { 916 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA); 917 UnRef(); 918 m_refData = ref; 919 } 920} 921 922// ---------------------------------------------------------------------------- 923// change font attribute: we recreate font when doing it 924// ---------------------------------------------------------------------------- 925 926void wxFont::SetPointSize(int pointSize) 927{ 928 Unshare(); 929 930 M_FONTDATA->SetPointSize(pointSize); 931 932 RealizeResource(); 933} 934 935void wxFont::SetPixelSize(const wxSize& pixelSize) 936{ 937 Unshare(); 938 939 M_FONTDATA->SetPixelSize(pixelSize); 940 941 RealizeResource(); 942} 943 944void wxFont::SetFamily(int family) 945{ 946 Unshare(); 947 948 M_FONTDATA->SetFamily(family); 949 950 RealizeResource(); 951} 952 953void wxFont::SetStyle(int style) 954{ 955 Unshare(); 956 957 M_FONTDATA->SetStyle(style); 958 959 RealizeResource(); 960} 961 962void wxFont::SetWeight(int weight) 963{ 964 Unshare(); 965 966 M_FONTDATA->SetWeight(weight); 967 968 RealizeResource(); 969} 970 971bool wxFont::SetFaceName(const wxString& faceName) 972{ 973 Unshare(); 974 975 bool refdataok = M_FONTDATA->SetFaceName(faceName); 976 977 RealizeResource(); 978 979 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT() 980 // to retrieve a LOGFONT and then compare lf.lfFaceName 981 // with given facename is not reliable at all: 982 // Windows copies the facename given to ::CreateFontIndirect() 983 // without any validity check. 984 // Thus we use wxFontBase::SetFaceName to check if facename 985 // is valid... 986 return refdataok && wxFontBase::SetFaceName(faceName); 987} 988 989void wxFont::SetUnderlined(bool underlined) 990{ 991 Unshare(); 992 993 M_FONTDATA->SetUnderlined(underlined); 994 995 RealizeResource(); 996} 997 998void wxFont::SetEncoding(wxFontEncoding encoding) 999{ 1000 Unshare(); 1001 1002 M_FONTDATA->SetEncoding(encoding); 1003 1004 RealizeResource(); 1005} 1006 1007void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info) 1008{ 1009 Unshare(); 1010 1011 FreeResource(); 1012 1013 *M_FONTDATA = wxFontRefData(info); 1014 1015 RealizeResource(); 1016} 1017 1018// ---------------------------------------------------------------------------- 1019// accessors 1020// ---------------------------------------------------------------------------- 1021 1022int wxFont::GetPointSize() const 1023{ 1024 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1025 1026 return M_FONTDATA->GetPointSize(); 1027} 1028 1029wxSize wxFont::GetPixelSize() const 1030{ 1031 wxCHECK_MSG( Ok(), wxDefaultSize, wxT("invalid font") ); 1032 1033 return M_FONTDATA->GetPixelSize(); 1034} 1035 1036bool wxFont::IsUsingSizeInPixels() const 1037{ 1038 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1039 1040 return M_FONTDATA->IsUsingSizeInPixels(); 1041} 1042 1043int wxFont::GetFamily() const 1044{ 1045 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1046 1047 return M_FONTDATA->GetFamily(); 1048} 1049 1050int wxFont::GetStyle() const 1051{ 1052 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1053 1054 return M_FONTDATA->GetStyle(); 1055} 1056 1057int wxFont::GetWeight() const 1058{ 1059 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1060 1061 return M_FONTDATA->GetWeight(); 1062} 1063 1064bool wxFont::GetUnderlined() const 1065{ 1066 wxCHECK_MSG( Ok(), false, wxT("invalid font") ); 1067 1068 return M_FONTDATA->GetUnderlined(); 1069} 1070 1071wxString wxFont::GetFaceName() const 1072{ 1073 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") ); 1074 1075 return M_FONTDATA->GetFaceName(); 1076} 1077 1078wxFontEncoding wxFont::GetEncoding() const 1079{ 1080 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); 1081 1082 return M_FONTDATA->GetEncoding(); 1083} 1084 1085const wxNativeFontInfo *wxFont::GetNativeFontInfo() const 1086{ 1087 return Ok() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo()) 1088 : NULL; 1089} 1090 1091wxString wxFont::GetNativeFontInfoDesc() const 1092{ 1093 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") ); 1094 1095 // be sure we have an HFONT associated... 1096 wxConstCast(this, wxFont)->RealizeResource(); 1097 return wxFontBase::GetNativeFontInfoDesc(); 1098} 1099 1100wxString wxFont::GetNativeFontInfoUserDesc() const 1101{ 1102 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") ); 1103 1104 // be sure we have an HFONT associated... 1105 wxConstCast(this, wxFont)->RealizeResource(); 1106 return wxFontBase::GetNativeFontInfoUserDesc(); 1107} 1108 1109bool wxFont::IsFixedWidth() const 1110{ 1111 if ( M_FONTDATA->HasNativeFontInfo() ) 1112 { 1113 // the two low-order bits specify the pitch of the font, the rest is 1114 // family 1115 BYTE pitch = 1116 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK); 1117 1118 return pitch == FIXED_PITCH; 1119 } 1120 1121 return wxFontBase::IsFixedWidth(); 1122} 1123