1///////////////////////////////////////////////////////////////////////////// 2// Name: src/os2/font.cpp 3// Purpose: wxFont class 4// Author: David Webster 5// Modified by: 6// Created: 10/06/99 7// RCS-ID: $Id: font.cpp 43545 2006-11-20 16:21:08Z VS $ 8// Copyright: (c) David Webster 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15// ============================================================================ 16// declarations 17// ============================================================================ 18 19// ---------------------------------------------------------------------------- 20// headers 21// ---------------------------------------------------------------------------- 22 23#include "wx/font.h" 24 25#ifndef WX_PRECOMP 26 #include <stdio.h> 27 #include "wx/list.h" 28 #include "wx/utils.h" 29 #include "wx/app.h" 30 #include "wx/log.h" 31#endif // WX_PRECOMP 32 33#include "wx/os2/private.h" 34 35#include "wx/fontutil.h" 36#include "wx/fontmap.h" 37#include "wx/encinfo.h" 38 39#include "wx/tokenzr.h" 40 41#include <malloc.h> 42 43IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) 44 45// ---------------------------------------------------------------------------- 46// wxFontRefData - the internal description of the font 47// ---------------------------------------------------------------------------- 48 49class WXDLLEXPORT wxFontRefData: public wxGDIRefData 50{ 51public: 52 wxFontRefData() 53 { 54 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, 55 wxEmptyString, wxFONTENCODING_DEFAULT); 56 } 57 58 wxFontRefData( int nSize 59 ,int nFamily 60 ,int nStyle 61 ,int nWeight 62 ,bool bUnderlined 63 ,const wxString& sFaceName 64 ,wxFontEncoding vEncoding 65 ) 66 { 67 Init( nSize 68 ,nFamily 69 ,nStyle 70 ,nWeight 71 ,bUnderlined 72 ,sFaceName 73 ,vEncoding 74 ); 75 } 76 77 wxFontRefData( const wxNativeFontInfo& rInfo 78 ,WXHFONT hFont = 0 79 ,WXHANDLE hPS = 0 80 ) 81 { 82 Init( rInfo 83 ,hFont 84 ,hPS 85 ); 86 } 87 88 wxFontRefData(const wxFontRefData& rData) 89 { 90 Init( rData.m_nPointSize 91 ,rData.m_nFamily 92 ,rData.m_nStyle 93 ,rData.m_nWeight 94 ,rData.m_bUnderlined 95 ,rData.m_sFaceName 96 ,rData.m_vEncoding 97 ); 98 m_nFontId = rData.m_nFontId; 99 } 100 101 virtual ~wxFontRefData(); 102 103 // 104 // Operations 105 // 106 bool Alloc(wxFont* pFont); 107 void Free(void); 108 109 // 110 // All wxFont accessors 111 // 112 inline int GetPointSize(void) const 113 { 114 // 115 // We don't use the actual native font point size since it is 116 // the chosen physical font, which is usually only and approximation 117 // of the desired outline font. The actual displayable point size 118 // is the one stored in the refData 119 // 120 return m_nPointSize; 121 } 122 123 inline int GetFamily(void) const 124 { 125 return m_nFamily; 126 } 127 128 inline int GetStyle(void) const 129 { 130 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle() 131 : m_nStyle; 132 } 133 134 inline int GetWeight(void) const 135 { 136 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight() 137 : m_nWeight; 138 } 139 140 inline bool GetUnderlined(void) const 141 { 142 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetUnderlined() 143 : m_bUnderlined; 144 } 145 146 inline wxString GetFaceName(void) const 147 { 148 wxString sFaceName; 149 150 if (m_bNativeFontInfoOk) 151 sFaceName = m_vNativeFontInfo.GetFaceName(); 152 else 153 sFaceName = m_sFaceName; 154 155 return sFaceName; 156 } 157 158 inline wxFontEncoding GetEncoding(void) const 159 { 160 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetEncoding() 161 : m_vEncoding; 162 } 163 164 inline WXHFONT GetHFONT(void) const { return m_hFont; } 165 inline HPS GetPS(void) const { return m_hPS; } 166 inline PFONTMETRICS GetFM(void) const { return m_pFM; } 167 inline int GetNumFonts(void) const { return m_nNumFonts; } 168 169 // ... and setters 170 inline void SetPointSize(int nPointSize) 171 { 172 if (m_bNativeFontInfoOk) 173 m_vNativeFontInfo.SetPointSize(nPointSize); 174 else 175 m_nPointSize = nPointSize; 176 } 177 178 inline void SetFamily(int nFamily) 179 { 180 m_nFamily = nFamily; 181 } 182 183 inline void SetStyle(int nStyle) 184 { 185 if (m_bNativeFontInfoOk) 186 m_vNativeFontInfo.SetStyle((wxFontStyle)nStyle); 187 else 188 m_nStyle = nStyle; 189 } 190 191 inline void SetWeight(int nWeight) 192 { 193 if (m_bNativeFontInfoOk) 194 m_vNativeFontInfo.SetWeight((wxFontWeight)nWeight); 195 else 196 m_nWeight = nWeight; 197 } 198 199 inline bool SetFaceName(const wxString& sFaceName) 200 { 201 if (m_bNativeFontInfoOk) 202 return m_vNativeFontInfo.SetFaceName(sFaceName); 203 else 204 m_sFaceName = sFaceName; 205 return true; 206 } 207 208 inline void SetUnderlined(bool bUnderlined) 209 { 210 if (m_bNativeFontInfoOk) 211 m_vNativeFontInfo.SetUnderlined(bUnderlined); 212 else 213 m_bUnderlined = bUnderlined; 214 } 215 216 inline void SetEncoding(wxFontEncoding vEncoding) 217 { 218 if (m_bNativeFontInfoOk) 219 m_vNativeFontInfo.SetEncoding(vEncoding); 220 else 221 m_vEncoding = vEncoding; 222 } 223 224 inline void SetPS(HPS hPS) 225 { 226 m_hPS = hPS; 227 } 228 229 inline void SetFM(PFONTMETRICS pFM) 230 { 231 m_pFM = pFM; 232 } 233 234 inline void SetNumFonts(int nNumFonts) 235 { 236 m_nNumFonts = nNumFonts; 237 } 238 239 // 240 // Native font info tests 241 // 242 bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; } 243 244 const wxNativeFontInfo& GetNativeFontInfo() const 245 { return m_vNativeFontInfo; } 246 247protected: 248 // 249 // Common part of all ctors 250 // 251 void Init( int nSize 252 ,int nFamily 253 ,int nStyle 254 ,int nWeight 255 ,bool bUnderlined 256 ,const wxString& rsFaceName 257 ,wxFontEncoding vEncoding 258 ); 259 260 void Init( const wxNativeFontInfo& rInfo 261 ,WXHFONT hFont = 0 262 ,WXHANDLE hPS = 0 263 ); 264 // 265 // If true, the pointer to the actual font is temporary and SHOULD NOT BE 266 // DELETED by destructor 267 // 268 bool m_bTemporary; 269 int m_nFontId; 270 271 // 272 // Font characterstics 273 // 274 int m_nPointSize; 275 int m_nFamily; 276 int m_nStyle; 277 int m_nWeight; 278 bool m_bUnderlined; 279 wxString m_sFaceName; 280 wxFontEncoding m_vEncoding; 281 WXHFONT m_hFont; 282 283 // 284 // Native font info 285 // 286 wxNativeFontInfo m_vNativeFontInfo; 287 bool m_bNativeFontInfoOk; 288 289 // 290 // Some PM specific stuff 291 // 292 PFONTMETRICS m_pFM; // array of FONTMETRICS structs 293 int m_nNumFonts; // number of fonts in array 294 HPS m_hPS; // PS handle this font belongs to 295 FATTRS m_vFattrs; // Current fattrs struct 296 FACENAMEDESC m_vFname; // Current facename struct 297 bool m_bInternalPS; // Internally generated PS? 298}; // end of CLASS wxFontRefData 299 300#define M_FONTDATA ((wxFontRefData*)m_refData) 301 302// ============================================================================ 303// implementation 304// ============================================================================ 305 306// ---------------------------------------------------------------------------- 307// wxFontRefData 308// ---------------------------------------------------------------------------- 309 310void wxFontRefData::Init( 311 int nPointSize 312, int nFamily 313, int nStyle 314, int nWeight 315, bool bUnderlined 316, const wxString& rsFaceName 317, wxFontEncoding vEncoding 318) 319{ 320 m_nStyle = nStyle; 321 m_nPointSize = nPointSize; 322 m_nFamily = nFamily; 323 m_nStyle = nStyle; 324 m_nWeight = nWeight; 325 m_bUnderlined = bUnderlined; 326 m_sFaceName = rsFaceName; 327 m_vEncoding = vEncoding; 328 m_hFont = 0; 329 330 m_bNativeFontInfoOk = false; 331 332 m_nFontId = 0; 333 m_bTemporary = false; 334 m_pFM = (PFONTMETRICS)NULL; 335 m_hPS = NULLHANDLE; 336 m_nNumFonts = 0; 337} // end of wxFontRefData::Init 338 339void wxFontRefData::Init( 340 const wxNativeFontInfo& rInfo 341, WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2 342, WXHANDLE hPS // Presentation Space we are using 343) 344{ 345 // 346 // hFont may be zero, or it be passed in case we really want to 347 // use the exact font created in the underlying system 348 // (for example where we can't guarantee conversion from HFONT 349 // to LOGFONT back to HFONT) 350 // 351 m_hFont = hFont; 352 m_nFontId = (int)hFont; 353 354 m_bNativeFontInfoOk = true; 355 m_vNativeFontInfo = rInfo; 356 357 if (hPS == NULLHANDLE) 358 { 359 m_hPS = ::WinGetPS(HWND_DESKTOP); 360 m_bInternalPS = true; 361 } 362 else 363 m_hPS = (HPS)hPS; 364 365 m_nFontId = 0; 366 m_bTemporary = false; 367 m_pFM = (PFONTMETRICS)NULL; 368 m_nNumFonts = 0; 369} // end of wxFontRefData::Init 370 371wxFontRefData::~wxFontRefData() 372{ 373 Free(); 374} 375 376bool wxFontRefData::Alloc( wxFont* pFont ) 377{ 378 wxString sFaceName; 379 long flId = m_hFont; 380 long lRc; 381 ERRORID vError; 382 wxString sError; 383 384 if (!m_bNativeFontInfoOk) 385 { 386 wxFillLogFont( &m_vNativeFontInfo.fa 387 ,&m_vNativeFontInfo.fn 388 ,&m_hPS 389 ,&m_bInternalPS 390 ,&flId 391 ,sFaceName 392 ,pFont 393 ); 394 m_bNativeFontInfoOk = true; 395 } 396 else 397 { 398 if (flId == 0L) 399 flId = 1L; 400 else 401 flId++; 402 if (flId > 254) 403 flId = 1L; 404 } 405 if((lRc = ::GpiCreateLogFont( m_hPS 406 ,NULL 407 ,flId 408 ,&m_vNativeFontInfo.fa 409 )) != GPI_ERROR) 410 { 411 m_hFont = (WXHFONT)flId; 412 m_nFontId = flId; 413 } 414 if (!m_hFont) 415 { 416 vError = ::WinGetLastError(vHabmain); 417 sError = wxPMErrorToStr(vError); 418 wxLogLastError(wxT("CreateFont")); 419 } 420 421 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space 422 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm); 423 424 // 425 // Set refData members with the results 426 // 427 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs)); 428 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname)); 429 // 430 // Going to leave the point size alone. Mostly we use outline fonts 431 // that can be set to any point size inside of Presentation Parameters, 432 // regardless of whether or not the actual font is registered in the system. 433 // The GpiCreateLogFont will do enough by selecting the right family, 434 // and face name. 435 // 436 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0) 437 m_nFamily = wxROMAN; 438 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0) 439 m_nFamily = wxROMAN; 440 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0) 441 m_nFamily = wxROMAN; 442 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0) 443 m_nFamily = wxROMAN; 444 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0) 445 m_nFamily = wxDECORATIVE; 446 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0) 447 m_nFamily = wxSWISS; 448 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0) 449 m_nFamily = wxSWISS; 450 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0) 451 m_nFamily = wxSCRIPT; 452 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0) 453 m_nFamily = wxTELETYPE; 454 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0) 455 m_nFamily = wxTELETYPE; 456 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0) 457 m_nFamily = wxTELETYPE; 458 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0) 459 m_nFamily = wxMODERN; 460 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0) 461 m_nFamily = wxMODERN; 462 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0) 463 m_nFamily = wxSWISS; 464 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0) 465 m_nFamily = wxSWISS; 466 else 467 m_nFamily = wxSWISS; 468 469 if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC) 470 m_nStyle = wxFONTSTYLE_ITALIC; 471 else 472 m_nStyle = wxFONTSTYLE_NORMAL; 473 switch(m_vNativeFontInfo.fn.usWeightClass) 474 { 475 case FWEIGHT_DONT_CARE: 476 m_nWeight = wxFONTWEIGHT_NORMAL; 477 break; 478 479 case FWEIGHT_NORMAL: 480 m_nWeight = wxFONTWEIGHT_NORMAL; 481 break; 482 483 case FWEIGHT_LIGHT: 484 m_nWeight = wxFONTWEIGHT_LIGHT; 485 break; 486 487 case FWEIGHT_BOLD: 488 m_nWeight = wxFONTWEIGHT_BOLD; 489 break; 490 491 case FWEIGHT_ULTRA_BOLD: 492 m_nWeight = wxFONTWEIGHT_MAX; 493 break; 494 495 default: 496 m_nWeight = wxFONTWEIGHT_NORMAL; 497 } 498 m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0); 499 m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename; 500 m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage); 501 502 // 503 // We don't actuall keep the font around if using a temporary PS 504 // 505 if (m_bInternalPS) 506 { 507 if(m_hFont) 508 ::GpiDeleteSetId( m_hPS 509 ,flId 510 ); 511 512 ::WinReleasePS(m_hPS); 513 } 514 else 515 // 516 // Select the font into the Presentation space 517 // 518 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space 519 return true; 520} // end of wxFontRefData::Alloc 521 522void wxFontRefData::Free() 523{ 524 if (m_pFM) 525 delete [] m_pFM; 526 m_pFM = (PFONTMETRICS)NULL; 527 528 if ( m_hFont ) 529 { 530 ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */ 531 m_nFontId = 0; 532 m_hFont = 0; 533 } 534 if (m_bInternalPS) 535 ::WinReleasePS(m_hPS); 536 m_hPS = NULLHANDLE; 537} // end of wxFontRefData::Free 538 539// ---------------------------------------------------------------------------- 540// wxNativeFontInfo 541// ---------------------------------------------------------------------------- 542 543void wxNativeFontInfo::Init() 544{ 545 memset(&fa, '\0', sizeof(FATTRS)); 546} // end of wxNativeFontInfo::Init 547 548int wxNativeFontInfo::GetPointSize() const 549{ 550 return fm.lEmHeight; 551} // end of wxNativeFontInfo::GetPointSize 552 553wxFontStyle wxNativeFontInfo::GetStyle() const 554{ 555 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL; 556} // end of wxNativeFontInfo::GetStyle 557 558wxFontWeight wxNativeFontInfo::GetWeight() const 559{ 560 switch(fn.usWeightClass) 561 { 562 case FWEIGHT_DONT_CARE: 563 return wxFONTWEIGHT_NORMAL; 564 565 case FWEIGHT_NORMAL: 566 return wxFONTWEIGHT_NORMAL; 567 568 case FWEIGHT_LIGHT: 569 return wxFONTWEIGHT_LIGHT; 570 571 case FWEIGHT_BOLD: 572 return wxFONTWEIGHT_BOLD; 573 574 case FWEIGHT_ULTRA_BOLD: 575 return wxFONTWEIGHT_MAX; 576 } 577 return wxFONTWEIGHT_NORMAL; 578} // end of wxNativeFontInfo::GetWeight 579 580bool wxNativeFontInfo::GetUnderlined() const 581{ 582 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0); 583} // end of wxNativeFontInfo::GetUnderlined 584 585wxString wxNativeFontInfo::GetFaceName() const 586{ 587 return (wxChar*)fm.szFacename; 588} // end of wxNativeFontInfo::GetFaceName 589 590wxFontFamily wxNativeFontInfo::GetFamily() const 591{ 592 int nFamily; 593 594 // 595 // Extract family from facename 596 // 597 if (strcmp(fm.szFamilyname, "Times New Roman") == 0) 598 nFamily = wxROMAN; 599 else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0) 600 nFamily = wxROMAN; 601 else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0) 602 nFamily = wxROMAN; 603 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0) 604 nFamily = wxROMAN; 605 else if (strcmp(fm.szFamilyname, "WarpSans") == 0) 606 nFamily = wxDECORATIVE; 607 else if (strcmp(fm.szFamilyname, "Helvetica") == 0) 608 nFamily = wxSWISS; 609 else if (strcmp(fm.szFamilyname, "Helv") == 0) 610 nFamily = wxSWISS; 611 else if (strcmp(fm.szFamilyname, "Script") == 0) 612 nFamily = wxSCRIPT; 613 else if (strcmp(fm.szFamilyname, "Courier New") == 0) 614 nFamily = wxTELETYPE; 615 else if (strcmp(fm.szFamilyname, "Courier") == 0) 616 nFamily = wxTELETYPE; 617 else if (strcmp(fm.szFamilyname, "System Monospaced") == 0) 618 nFamily = wxTELETYPE; 619 else if (strcmp(fm.szFamilyname, "System VIO") == 0) 620 nFamily = wxMODERN; 621 else if (strcmp(fm.szFamilyname, "System Proportional") == 0) 622 nFamily = wxMODERN; 623 else if (strcmp(fm.szFamilyname, "Arial") == 0) 624 nFamily = wxSWISS; 625 else if (strcmp(fm.szFamilyname, "Swiss") == 0) 626 nFamily = wxSWISS; 627 else 628 nFamily = wxSWISS; 629 return (wxFontFamily)nFamily; 630} // end of wxNativeFontInfo::GetFamily 631 632wxFontEncoding wxNativeFontInfo::GetEncoding() const 633{ 634 return wxGetFontEncFromCharSet(fa.usCodePage); 635} // end of wxNativeFontInfo::GetEncoding 636 637void wxNativeFontInfo::SetPointSize( 638 int nPointsize 639) 640{ 641 fm.lEmHeight = (LONG)nPointsize; 642} // end of wxNativeFontInfo::SetPointSize 643 644void wxNativeFontInfo::SetStyle( 645 wxFontStyle eStyle 646) 647{ 648 switch (eStyle) 649 { 650 default: 651 wxFAIL_MSG( _T("unknown font style") ); 652 // fall through 653 654 case wxFONTSTYLE_NORMAL: 655 break; 656 657 case wxFONTSTYLE_ITALIC: 658 case wxFONTSTYLE_SLANT: 659 fa.fsSelection |= FATTR_SEL_ITALIC; 660 break; 661 } 662} // end of wxNativeFontInfo::SetStyle 663 664void wxNativeFontInfo::SetWeight( 665 wxFontWeight eWeight 666) 667{ 668 switch (eWeight) 669 { 670 default: 671 wxFAIL_MSG( _T("unknown font weight") ); 672 // fall through 673 674 case wxFONTWEIGHT_NORMAL: 675 fn.usWeightClass = FWEIGHT_NORMAL; 676 break; 677 678 case wxFONTWEIGHT_LIGHT: 679 fn.usWeightClass = FWEIGHT_LIGHT; 680 break; 681 682 case wxFONTWEIGHT_BOLD: 683 fn.usWeightClass = FWEIGHT_BOLD; 684 break; 685 } 686} // end of wxNativeFontInfo::SetWeight 687 688void wxNativeFontInfo::SetUnderlined( 689 bool bUnderlined 690) 691{ 692 if(bUnderlined) 693 fa.fsSelection |= FATTR_SEL_UNDERSCORE; 694} // end of wxNativeFontInfo::SetUnderlined 695 696bool wxNativeFontInfo::SetFaceName( 697 const wxString& sFacename 698) 699{ 700 wxStrncpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename)); 701 return true; 702} // end of wxNativeFontInfo::SetFaceName 703 704void wxNativeFontInfo::SetFamily( 705 wxFontFamily eFamily 706) 707{ 708 wxString sFacename; 709 710 switch (eFamily) 711 { 712 case wxSCRIPT: 713 sFacename = wxT("Tms Rmn"); 714 break; 715 716 case wxDECORATIVE: 717 sFacename = wxT("WarpSans"); 718 break; 719 720 case wxROMAN: 721 sFacename = wxT("Tms Rmn"); 722 break; 723 724 case wxTELETYPE: 725 sFacename = wxT("Courier") ; 726 break; 727 728 case wxMODERN: 729 sFacename = wxT("System VIO") ; 730 break; 731 732 case wxSWISS: 733 sFacename = wxT("Helv") ; 734 break; 735 736 case wxDEFAULT: 737 default: 738 sFacename = wxT("System VIO") ; 739 } 740 741 if (!wxStrlen((wxChar*)fa.szFacename) ) 742 { 743 SetFaceName(sFacename); 744 } 745} // end of wxNativeFontInfo::SetFamily 746 747void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding ) 748{ 749 wxNativeEncodingInfo vInfo; 750 751 if ( !wxGetNativeFontEncoding( eEncoding 752 ,&vInfo 753 )) 754 { 755 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding 756 ,&vInfo 757 )) 758 { 759 if (!vInfo.facename.empty()) 760 { 761 // 762 // If we have this encoding only in some particular facename, use 763 // the facename - it is better to show the correct characters in a 764 // wrong facename than unreadable text in a correct one 765 // 766 SetFaceName(vInfo.facename); 767 } 768 } 769 else 770 { 771 // unsupported encoding, replace with the default 772 vInfo.charset = 850; 773 } 774 } 775 fa.usCodePage = (USHORT)vInfo.charset; 776} // end of wxNativeFontInfo::SetFaceName 777 778bool wxNativeFontInfo::FromString( const wxString& rsStr ) 779{ 780 long lVal; 781 782 wxStringTokenizer vTokenizer(rsStr, _T(";")); 783 784 // 785 // First the version 786 // 787 wxString sToken = vTokenizer.GetNextToken(); 788 789 if (sToken != _T('0')) 790 return false; 791 792 sToken = vTokenizer.GetNextToken(); 793 if (!sToken.ToLong(&lVal)) 794 return false; 795 fm.lEmHeight = lVal; 796 797 sToken = vTokenizer.GetNextToken(); 798 if (!sToken.ToLong(&lVal)) 799 return false; 800 fa.lAveCharWidth = lVal; 801 802 sToken = vTokenizer.GetNextToken(); 803 if (!sToken.ToLong(&lVal)) 804 return false; 805 fa.fsSelection = (USHORT)lVal; 806 807 sToken = vTokenizer.GetNextToken(); 808 if (!sToken.ToLong(&lVal)) 809 return false; 810 fa.fsType = (USHORT)lVal; 811 812 sToken = vTokenizer.GetNextToken(); 813 if (!sToken.ToLong(&lVal)) 814 return false; 815 fa.fsFontUse = (USHORT)lVal; 816 817 sToken = vTokenizer.GetNextToken(); 818 if (!sToken.ToLong(&lVal)) 819 return false; 820 fa.idRegistry = (USHORT)lVal; 821 822 sToken = vTokenizer.GetNextToken(); 823 if (!sToken.ToLong(&lVal)) 824 return false; 825 fa.usCodePage = (USHORT)lVal; 826 827 sToken = vTokenizer.GetNextToken(); 828 if (!sToken.ToLong(&lVal)) 829 return false; 830 fa.lMatch = lVal; 831 832 sToken = vTokenizer.GetNextToken(); 833 if (!sToken.ToLong(&lVal)) 834 return false; 835 fn.usWeightClass = (USHORT)lVal; 836 837 sToken = vTokenizer.GetNextToken(); 838 if(!sToken) 839 return false; 840 wxStrcpy((wxChar*)fa.szFacename, sToken.c_str()); 841 return true; 842} // end of wxNativeFontInfo::FromString 843 844wxString wxNativeFontInfo::ToString() const 845{ 846 wxString sStr; 847 848 sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"), 849 0, // version, in case we want to change the format later 850 fm.lEmHeight, 851 fa.lAveCharWidth, 852 fa.lMaxBaselineExt, 853 fa.fsSelection, 854 fa.fsType, 855 fa.fsFontUse, 856 fa.idRegistry, 857 fa.usCodePage, 858 fa.lMatch, 859 fn.usWeightClass, 860 fa.szFacename); 861 return sStr; 862} // end of wxNativeFontInfo::ToString 863 864// ---------------------------------------------------------------------------- 865// wxFont 866// ---------------------------------------------------------------------------- 867 868bool wxFont::Create( const wxNativeFontInfo& rInfo, 869 WXHFONT hFont ) 870{ 871 UnRef(); 872 m_refData = new wxFontRefData( rInfo 873 ,hFont 874 ); 875 RealizeResource(); 876 return true; 877} // end of wxFont::Create 878 879wxFont::wxFont( 880 const wxString& rsFontdesc 881) 882{ 883 wxNativeFontInfo vInfo; 884 885 if (vInfo.FromString(rsFontdesc)) 886 (void)Create(vInfo); 887} // end of wxFont::wxFont 888 889// ---------------------------------------------------------------------------- 890// Constructor for a font. Note that the real construction is done 891// in wxDC::SetFont, when information is available about scaling etc. 892// ---------------------------------------------------------------------------- 893bool wxFont::Create( int nPointSize, 894 int nFamily, 895 int nStyle, 896 int nWeight, 897 bool bUnderlined, 898 const wxString& rsFaceName, 899 wxFontEncoding vEncoding ) 900{ 901 UnRef(); 902 903 // 904 // wxDEFAULT is a valid value for the font size too so we must treat it 905 // specially here (otherwise the size would be 70 == wxDEFAULT value) 906 // 907 if (nPointSize == wxDEFAULT) 908 { 909 nPointSize = wxNORMAL_FONT->GetPointSize(); 910 } 911 m_refData = new wxFontRefData( nPointSize 912 ,nFamily 913 ,nStyle 914 ,nWeight 915 ,bUnderlined 916 ,rsFaceName 917 ,vEncoding 918 ); 919 RealizeResource(); 920 return true; 921} // end of wxFont::Create 922 923wxFont::~wxFont() 924{ 925} // end of wxFont::~wxFont 926 927// ---------------------------------------------------------------------------- 928// real implementation 929// Boris' Kovalenko comments: 930// Because OS/2 fonts are associated with PS we can not create the font 931// here, but we may check that font definition is true 932// ---------------------------------------------------------------------------- 933 934bool wxFont::RealizeResource() 935{ 936 if ( GetResourceHandle() ) 937 { 938 return true; 939 } 940 return M_FONTDATA->Alloc(this); 941} // end of wxFont::RealizeResource 942 943bool wxFont::FreeResource( bool WXUNUSED(bForce) ) 944{ 945 if (GetResourceHandle()) 946 { 947 M_FONTDATA->Free(); 948 return true; 949 } 950 return false; 951} // end of wxFont::FreeResource 952 953WXHANDLE wxFont::GetResourceHandle() const 954{ 955 return GetHFONT(); 956} // end of wxFont::GetResourceHandle 957 958WXHFONT wxFont::GetHFONT() const 959{ 960 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0; 961} // end of wxFont::GetHFONT 962 963bool wxFont::IsFree() const 964{ 965 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0); 966} // end of wxFont::IsFree 967 968void wxFont::Unshare() 969{ 970 // Don't change shared data 971 if ( !m_refData ) 972 { 973 m_refData = new wxFontRefData(); 974 } 975 else 976 { 977 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA); 978 UnRef(); 979 m_refData = ref; 980 } 981} // end of wxFont::Unshare 982 983// ---------------------------------------------------------------------------- 984// change font attribute: we recreate font when doing it 985// ---------------------------------------------------------------------------- 986 987void wxFont::SetPointSize( 988 int nPointSize 989) 990{ 991 Unshare(); 992 993 M_FONTDATA->SetPointSize(nPointSize); 994 995 RealizeResource(); 996} // end of wxFont::SetPointSize 997 998void wxFont::SetFamily( 999 int nFamily 1000) 1001{ 1002 Unshare(); 1003 1004 M_FONTDATA->SetFamily(nFamily); 1005 1006 RealizeResource(); 1007} // end of wxFont::SetFamily 1008 1009void wxFont::SetStyle( 1010 int nStyle 1011) 1012{ 1013 Unshare(); 1014 1015 M_FONTDATA->SetStyle(nStyle); 1016 1017 RealizeResource(); 1018} // end of wxFont::SetStyle 1019 1020void wxFont::SetWeight( 1021 int nWeight 1022) 1023{ 1024 Unshare(); 1025 1026 M_FONTDATA->SetWeight(nWeight); 1027 1028 RealizeResource(); 1029} // end of wxFont::SetWeight 1030 1031bool wxFont::SetFaceName( 1032 const wxString& rsFaceName 1033) 1034{ 1035 Unshare(); 1036 1037 bool refdataok = M_FONTDATA->SetFaceName(rsFaceName); 1038 1039 RealizeResource(); 1040 1041 return refdataok && wxFontBase::SetFaceName(rsFaceName); 1042} // end of wxFont::SetFaceName 1043 1044void wxFont::SetUnderlined( 1045 bool bUnderlined 1046) 1047{ 1048 Unshare(); 1049 1050 M_FONTDATA->SetUnderlined(bUnderlined); 1051 1052 RealizeResource(); 1053} // end of wxFont::SetUnderlined 1054 1055void wxFont::SetEncoding( 1056 wxFontEncoding vEncoding 1057) 1058{ 1059 Unshare(); 1060 1061 M_FONTDATA->SetEncoding(vEncoding); 1062 1063 RealizeResource(); 1064} // end of wxFont::SetEncoding 1065 1066void wxFont::DoSetNativeFontInfo( 1067 const wxNativeFontInfo& rInfo 1068) 1069{ 1070 Unshare(); 1071 1072 FreeResource(); 1073 1074 *M_FONTDATA = wxFontRefData(rInfo); 1075 1076 RealizeResource(); 1077} 1078 1079// ---------------------------------------------------------------------------- 1080// accessors 1081// ---------------------------------------------------------------------------- 1082 1083int wxFont::GetPointSize() const 1084{ 1085 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1086 1087 return M_FONTDATA->GetPointSize(); 1088} // end of wxFont::GetPointSize 1089 1090int wxFont::GetFamily() const 1091{ 1092 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1093 1094 return M_FONTDATA->GetFamily(); 1095} // end of wxFont::GetFamily 1096 1097int wxFont::GetStyle() const 1098{ 1099 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1100 1101 return M_FONTDATA->GetStyle(); 1102} // end of wxFont::GetStyle 1103 1104int wxFont::GetWeight() const 1105{ 1106 wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 1107 1108 return M_FONTDATA->GetWeight(); 1109} 1110 1111bool wxFont::GetUnderlined() const 1112{ 1113 wxCHECK_MSG( Ok(), false, wxT("invalid font") ); 1114 1115 return M_FONTDATA->GetUnderlined(); 1116} // end of wxFont::GetUnderlined 1117 1118wxString wxFont::GetFaceName() const 1119{ 1120 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") ); 1121 1122 return M_FONTDATA->GetFaceName(); 1123} // end of wxFont::GetFaceName 1124 1125wxFontEncoding wxFont::GetEncoding() const 1126{ 1127 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); 1128 1129 return M_FONTDATA->GetEncoding(); 1130} // end of wxFont::GetEncoding 1131 1132const wxNativeFontInfo* wxFont::GetNativeFontInfo() const 1133{ 1134 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo()) 1135 : NULL; 1136} // end of wxFont::GetNativeFontInfo 1137 1138// 1139// Internal use only method to set the FONTMETRICS array 1140// 1141void wxFont::SetFM( PFONTMETRICS pFM, int nNumFonts ) 1142{ 1143 M_FONTDATA->SetFM(pFM); 1144 M_FONTDATA->SetNumFonts(nNumFonts); 1145} // end of wxFont::SetFM 1146 1147 1148void wxFont::SetPS( HPS hPS ) 1149{ 1150 Unshare(); 1151 1152 M_FONTDATA->SetPS(hPS); 1153 1154 RealizeResource(); 1155} // end of wxFont::SetPS 1156