PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/ExtLibs/wxWidgets/src/common/fontcmn.cpp

https://bitbucket.org/lennonchan/cafu
C++ | 1095 lines | 796 code | 178 blank | 121 comment | 125 complexity | f7e11b2f539eb17f986ea303a9201300 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/common/fontcmn.cpp
  3. // Purpose: implementation of wxFontBase methods
  4. // Author: Vadim Zeitlin
  5. // Modified by:
  6. // Created: 20.09.99
  7. // RCS-ID: $Id$
  8. // Copyright: (c) wxWidgets team
  9. // Licence: wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11. // ============================================================================
  12. // declarations
  13. // ============================================================================
  14. // ----------------------------------------------------------------------------
  15. // headers
  16. // ----------------------------------------------------------------------------
  17. // For compilers that support precompilation, includes "wx.h".
  18. #include "wx/wxprec.h"
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22. #include "wx/font.h"
  23. #ifndef WX_PRECOMP
  24. #include "wx/dc.h"
  25. #include "wx/intl.h"
  26. #include "wx/math.h"
  27. #include "wx/dcscreen.h"
  28. #include "wx/log.h"
  29. #include "wx/gdicmn.h"
  30. #endif // WX_PRECOMP
  31. #if defined(__WXMSW__)
  32. #include "wx/msw/private.h" // includes windows.h for LOGFONT
  33. #include "wx/msw/winundef.h"
  34. #endif
  35. #include "wx/fontutil.h" // for wxNativeFontInfo
  36. #include "wx/fontmap.h"
  37. #include "wx/fontenum.h"
  38. #include "wx/tokenzr.h"
  39. // debugger helper: this function can be called from a debugger to show what
  40. // the date really is
  41. extern const char *wxDumpFont(const wxFont *font)
  42. {
  43. static char buf[256];
  44. const wxFontWeight weight = font->GetWeight();
  45. wxString s;
  46. s.Printf(wxS("%s-%s-%s-%d-%d"),
  47. font->GetFaceName(),
  48. weight == wxFONTWEIGHT_NORMAL
  49. ? wxT("normal")
  50. : weight == wxFONTWEIGHT_BOLD
  51. ? wxT("bold")
  52. : wxT("light"),
  53. font->GetStyle() == wxFONTSTYLE_NORMAL
  54. ? wxT("regular")
  55. : wxT("italic"),
  56. font->GetPointSize(),
  57. font->GetEncoding());
  58. wxStrlcpy(buf, s.mb_str(), WXSIZEOF(buf));
  59. return buf;
  60. }
  61. // ----------------------------------------------------------------------------
  62. // XTI
  63. // ----------------------------------------------------------------------------
  64. wxBEGIN_ENUM( wxFontFamily )
  65. wxENUM_MEMBER( wxFONTFAMILY_DEFAULT )
  66. wxENUM_MEMBER( wxFONTFAMILY_DECORATIVE )
  67. wxENUM_MEMBER( wxFONTFAMILY_ROMAN )
  68. wxENUM_MEMBER( wxFONTFAMILY_SCRIPT )
  69. wxENUM_MEMBER( wxFONTFAMILY_SWISS )
  70. wxENUM_MEMBER( wxFONTFAMILY_MODERN )
  71. wxENUM_MEMBER( wxFONTFAMILY_TELETYPE )
  72. wxEND_ENUM( wxFontFamily )
  73. wxBEGIN_ENUM( wxFontStyle )
  74. wxENUM_MEMBER( wxFONTSTYLE_NORMAL )
  75. wxENUM_MEMBER( wxFONTSTYLE_ITALIC )
  76. wxENUM_MEMBER( wxFONTSTYLE_SLANT )
  77. wxEND_ENUM( wxFontStyle )
  78. wxBEGIN_ENUM( wxFontWeight )
  79. wxENUM_MEMBER( wxFONTWEIGHT_NORMAL )
  80. wxENUM_MEMBER( wxFONTWEIGHT_LIGHT )
  81. wxENUM_MEMBER( wxFONTWEIGHT_BOLD )
  82. wxEND_ENUM( wxFontWeight )
  83. wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject, "wx/font.h")
  84. //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxFont>)
  85. wxBEGIN_PROPERTIES_TABLE(wxFont)
  86. wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12, 0 /*flags*/, \
  87. wxT("Helpstring"), wxT("group"))
  88. wxPROPERTY( Family, wxFontFamily , SetFamily, GetFamily, (wxFontFamily)wxDEFAULT, \
  89. 0 /*flags*/, wxT("Helpstring"), wxT("group")) // wxFontFamily
  90. wxPROPERTY( Style, wxFontStyle, SetStyle, GetStyle, (wxFontStyle)wxNORMAL, 0 /*flags*/, \
  91. wxT("Helpstring"), wxT("group")) // wxFontStyle
  92. wxPROPERTY( Weight, wxFontWeight, SetWeight, GetWeight, (wxFontWeight)wxNORMAL, 0 /*flags*/, \
  93. wxT("Helpstring"), wxT("group")) // wxFontWeight
  94. wxPROPERTY( Underlined, bool, SetUnderlined, GetUnderlined, false, 0 /*flags*/, \
  95. wxT("Helpstring"), wxT("group"))
  96. wxPROPERTY( Face, wxString, SetFaceName, GetFaceName, wxEMPTY_PARAMETER_VALUE, \
  97. 0 /*flags*/, wxT("Helpstring"), wxT("group"))
  98. wxPROPERTY( Encoding, wxFontEncoding, SetEncoding, GetEncoding, \
  99. wxFONTENCODING_DEFAULT, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
  100. wxEND_PROPERTIES_TABLE()
  101. wxCONSTRUCTOR_6( wxFont, int, Size, wxFontFamily, Family, wxFontStyle, Style, wxFontWeight, Weight, \
  102. bool, Underlined, wxString, Face )
  103. wxEMPTY_HANDLERS_TABLE(wxFont)
  104. // ============================================================================
  105. // implementation
  106. // ============================================================================
  107. // ----------------------------------------------------------------------------
  108. // helper functions
  109. // ----------------------------------------------------------------------------
  110. static inline int flags2Style(int flags)
  111. {
  112. return flags & wxFONTFLAG_ITALIC
  113. ? wxFONTSTYLE_ITALIC
  114. : flags & wxFONTFLAG_SLANT
  115. ? wxFONTSTYLE_SLANT
  116. : wxFONTSTYLE_NORMAL;
  117. }
  118. static inline int flags2Weight(int flags)
  119. {
  120. return flags & wxFONTFLAG_LIGHT
  121. ? wxFONTWEIGHT_LIGHT
  122. : flags & wxFONTFLAG_BOLD
  123. ? wxFONTWEIGHT_BOLD
  124. : wxFONTWEIGHT_NORMAL;
  125. }
  126. static inline bool flags2Underlined(int flags)
  127. {
  128. return (flags & wxFONTFLAG_UNDERLINED) != 0;
  129. }
  130. // ----------------------------------------------------------------------------
  131. // wxFontBase
  132. // ----------------------------------------------------------------------------
  133. wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
  134. /* static */
  135. void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
  136. {
  137. // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
  138. // and, besides, using this value here doesn't make any sense
  139. wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
  140. wxT("can't set default encoding to wxFONTENCODING_DEFAULT") );
  141. ms_encodingDefault = encoding;
  142. }
  143. wxFontBase::~wxFontBase()
  144. {
  145. // this destructor is required for Darwin
  146. }
  147. /* static */
  148. wxFont *wxFontBase::New(int size,
  149. wxFontFamily family,
  150. wxFontStyle style,
  151. wxFontWeight weight,
  152. bool underlined,
  153. const wxString& face,
  154. wxFontEncoding encoding)
  155. {
  156. return new wxFont(size, family, style, weight, underlined, face, encoding);
  157. }
  158. /* static */
  159. wxFont *wxFontBase::New(const wxSize& pixelSize,
  160. wxFontFamily family,
  161. wxFontStyle style,
  162. wxFontWeight weight,
  163. bool underlined,
  164. const wxString& face,
  165. wxFontEncoding encoding)
  166. {
  167. return new wxFont(pixelSize, family, style, weight, underlined,
  168. face, encoding);
  169. }
  170. /* static */
  171. wxFont *wxFontBase::New(int pointSize,
  172. wxFontFamily family,
  173. int flags,
  174. const wxString& face,
  175. wxFontEncoding encoding)
  176. {
  177. return New(pointSize, family, flags2Style(flags), flags2Weight(flags),
  178. flags2Underlined(flags), face, encoding);
  179. }
  180. /* static */
  181. wxFont *wxFontBase::New(const wxSize& pixelSize,
  182. wxFontFamily family,
  183. int flags,
  184. const wxString& face,
  185. wxFontEncoding encoding)
  186. {
  187. return New(pixelSize, family, flags2Style(flags), flags2Weight(flags),
  188. flags2Underlined(flags), face, encoding);
  189. }
  190. /* static */
  191. wxFont *wxFontBase::New(const wxNativeFontInfo& info)
  192. {
  193. return new wxFont(info);
  194. }
  195. /* static */
  196. wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
  197. {
  198. wxNativeFontInfo fontInfo;
  199. if ( !fontInfo.FromString(strNativeFontDesc) )
  200. return new wxFont(*wxNORMAL_FONT);
  201. return New(fontInfo);
  202. }
  203. bool wxFontBase::IsFixedWidth() const
  204. {
  205. return GetFamily() == wxFONTFAMILY_TELETYPE;
  206. }
  207. wxSize wxFontBase::GetPixelSize() const
  208. {
  209. wxScreenDC dc;
  210. dc.SetFont(*(wxFont *)this);
  211. return wxSize(dc.GetCharWidth(), dc.GetCharHeight());
  212. }
  213. bool wxFontBase::IsUsingSizeInPixels() const
  214. {
  215. return false;
  216. }
  217. void wxFontBase::SetPixelSize( const wxSize& pixelSize )
  218. {
  219. wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
  220. "Negative values for the pixel size or zero pixel height are not allowed" );
  221. wxScreenDC dc;
  222. // NOTE: this algorithm for adjusting the font size is used by all
  223. // implementations of wxFont except under wxMSW and wxGTK where
  224. // native support to font creation using pixel-size is provided.
  225. int largestGood = 0;
  226. int smallestBad = 0;
  227. bool initialGoodFound = false;
  228. bool initialBadFound = false;
  229. // NB: this assignment was separated from the variable definition
  230. // in order to fix a gcc v3.3.3 compiler crash
  231. int currentSize = GetPointSize();
  232. while (currentSize > 0)
  233. {
  234. dc.SetFont(*static_cast<wxFont*>(this));
  235. // if currentSize (in points) results in a font that is smaller
  236. // than required by pixelSize it is considered a good size
  237. // NOTE: the pixel size width may be zero
  238. if (dc.GetCharHeight() <= pixelSize.GetHeight() &&
  239. (pixelSize.GetWidth() == 0 ||
  240. dc.GetCharWidth() <= pixelSize.GetWidth()))
  241. {
  242. largestGood = currentSize;
  243. initialGoodFound = true;
  244. }
  245. else
  246. {
  247. smallestBad = currentSize;
  248. initialBadFound = true;
  249. }
  250. if (!initialGoodFound)
  251. {
  252. currentSize /= 2;
  253. }
  254. else if (!initialBadFound)
  255. {
  256. currentSize *= 2;
  257. }
  258. else
  259. {
  260. int distance = smallestBad - largestGood;
  261. if (distance == 1)
  262. break;
  263. currentSize = largestGood + distance / 2;
  264. }
  265. SetPointSize(currentSize);
  266. }
  267. if (currentSize != largestGood)
  268. SetPointSize(largestGood);
  269. }
  270. void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
  271. {
  272. #ifdef wxNO_NATIVE_FONTINFO
  273. SetPointSize(info.pointSize);
  274. SetFamily(info.family);
  275. SetStyle(info.style);
  276. SetWeight(info.weight);
  277. SetUnderlined(info.underlined);
  278. SetFaceName(info.faceName);
  279. SetEncoding(info.encoding);
  280. #else
  281. (void)info;
  282. #endif
  283. }
  284. wxString wxFontBase::GetNativeFontInfoDesc() const
  285. {
  286. wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
  287. wxString fontDesc;
  288. const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
  289. if ( fontInfo )
  290. {
  291. fontDesc = fontInfo->ToString();
  292. wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
  293. }
  294. else
  295. {
  296. wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
  297. }
  298. return fontDesc;
  299. }
  300. wxString wxFontBase::GetNativeFontInfoUserDesc() const
  301. {
  302. wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
  303. wxString fontDesc;
  304. const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
  305. if ( fontInfo )
  306. {
  307. fontDesc = fontInfo->ToUserString();
  308. wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
  309. }
  310. else
  311. {
  312. wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
  313. }
  314. return fontDesc;
  315. }
  316. bool wxFontBase::SetNativeFontInfo(const wxString& info)
  317. {
  318. wxNativeFontInfo fontInfo;
  319. if ( !info.empty() && fontInfo.FromString(info) )
  320. {
  321. SetNativeFontInfo(fontInfo);
  322. return true;
  323. }
  324. return false;
  325. }
  326. bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
  327. {
  328. wxNativeFontInfo fontInfo;
  329. if ( !info.empty() && fontInfo.FromUserString(info) )
  330. {
  331. SetNativeFontInfo(fontInfo);
  332. return true;
  333. }
  334. return false;
  335. }
  336. bool wxFontBase::operator==(const wxFont& font) const
  337. {
  338. // either it is the same font, i.e. they share the same common data or they
  339. // have different ref datas but still describe the same font
  340. return IsSameAs(font) ||
  341. (
  342. IsOk() == font.IsOk() &&
  343. GetPointSize() == font.GetPointSize() &&
  344. // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
  345. // operator==() resulting in infinite recursion so we can't use it
  346. // in that port
  347. #if !defined(__WXGTK__) || defined(__WXGTK20__)
  348. GetPixelSize() == font.GetPixelSize() &&
  349. #endif
  350. GetFamily() == font.GetFamily() &&
  351. GetStyle() == font.GetStyle() &&
  352. GetWeight() == font.GetWeight() &&
  353. GetUnderlined() == font.GetUnderlined() &&
  354. GetFaceName().IsSameAs(font.GetFaceName(), false) &&
  355. GetEncoding() == font.GetEncoding()
  356. );
  357. }
  358. wxFontFamily wxFontBase::GetFamily() const
  359. {
  360. wxCHECK_MSG( IsOk(), wxFONTFAMILY_UNKNOWN, wxS("invalid font") );
  361. // Don't return wxFONTFAMILY_UNKNOWN from here because it prevents the code
  362. // like wxFont(size, wxNORMAL_FONT->GetFamily(), ...) from working (see
  363. // #12330). This is really just a hack but it allows to keep compatibility
  364. // and doesn't really have any bad drawbacks so do this until someone comes
  365. // up with a better idea.
  366. const wxFontFamily family = DoGetFamily();
  367. return family == wxFONTFAMILY_UNKNOWN ? wxFONTFAMILY_DEFAULT : family;
  368. }
  369. wxString wxFontBase::GetFamilyString() const
  370. {
  371. wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
  372. switch ( GetFamily() )
  373. {
  374. case wxFONTFAMILY_DECORATIVE: return "wxFONTFAMILY_DECORATIVE";
  375. case wxFONTFAMILY_ROMAN: return "wxFONTFAMILY_ROMAN";
  376. case wxFONTFAMILY_SCRIPT: return "wxFONTFAMILY_SCRIPT";
  377. case wxFONTFAMILY_SWISS: return "wxFONTFAMILY_SWISS";
  378. case wxFONTFAMILY_MODERN: return "wxFONTFAMILY_MODERN";
  379. case wxFONTFAMILY_TELETYPE: return "wxFONTFAMILY_TELETYPE";
  380. case wxFONTFAMILY_UNKNOWN: return "wxFONTFAMILY_UNKNOWN";
  381. default: return "wxFONTFAMILY_DEFAULT";
  382. }
  383. }
  384. wxString wxFontBase::GetStyleString() const
  385. {
  386. wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" );
  387. switch ( GetStyle() )
  388. {
  389. case wxFONTSTYLE_NORMAL: return "wxFONTSTYLE_NORMAL";
  390. case wxFONTSTYLE_SLANT: return "wxFONTSTYLE_SLANT";
  391. case wxFONTSTYLE_ITALIC: return "wxFONTSTYLE_ITALIC";
  392. default: return "wxFONTSTYLE_DEFAULT";
  393. }
  394. }
  395. wxString wxFontBase::GetWeightString() const
  396. {
  397. wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" );
  398. switch ( GetWeight() )
  399. {
  400. case wxFONTWEIGHT_NORMAL: return "wxFONTWEIGHT_NORMAL";
  401. case wxFONTWEIGHT_BOLD: return "wxFONTWEIGHT_BOLD";
  402. case wxFONTWEIGHT_LIGHT: return "wxFONTWEIGHT_LIGHT";
  403. default: return "wxFONTWEIGHT_DEFAULT";
  404. }
  405. }
  406. bool wxFontBase::SetFaceName(const wxString& facename)
  407. {
  408. #if wxUSE_FONTENUM
  409. if (!wxFontEnumerator::IsValidFacename(facename))
  410. {
  411. UnRef(); // make IsOk() return false
  412. return false;
  413. }
  414. #else // !wxUSE_FONTENUM
  415. wxUnusedVar(facename);
  416. #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
  417. return true;
  418. }
  419. void wxFontBase::SetSymbolicSize(wxFontSymbolicSize size)
  420. {
  421. SetSymbolicSizeRelativeTo(size, wxNORMAL_FONT->GetPointSize());
  422. }
  423. /* static */
  424. int wxFontBase::AdjustToSymbolicSize(wxFontSymbolicSize size, int base)
  425. {
  426. // Using a fixed factor (1.2, from CSS2) is a bad idea as explained at
  427. // http://www.w3.org/TR/CSS21/fonts.html#font-size-props so use the values
  428. // from http://style.cleverchimp.com/font_size_intervals/altintervals.html
  429. // instead.
  430. static const float factors[] = { 0.60f, 0.75f, 0.89f, 1.f, 1.2f, 1.5f, 2.f };
  431. wxCOMPILE_TIME_ASSERT
  432. (
  433. WXSIZEOF(factors) == wxFONTSIZE_XX_LARGE - wxFONTSIZE_XX_SMALL + 1,
  434. WrongFontSizeFactorsSize
  435. );
  436. return wxRound(factors[size - wxFONTSIZE_XX_SMALL]*base);
  437. }
  438. wxFont& wxFont::MakeBold()
  439. {
  440. SetWeight(wxFONTWEIGHT_BOLD);
  441. return *this;
  442. }
  443. wxFont wxFont::Bold() const
  444. {
  445. wxFont font(*this);
  446. font.MakeBold();
  447. return font;
  448. }
  449. wxFont& wxFont::MakeItalic()
  450. {
  451. SetStyle(wxFONTSTYLE_ITALIC);
  452. return *this;
  453. }
  454. wxFont wxFont::Italic() const
  455. {
  456. wxFont font(*this);
  457. font.MakeItalic();
  458. return font;
  459. }
  460. wxFont& wxFont::MakeUnderlined()
  461. {
  462. SetUnderlined(true);
  463. return *this;
  464. }
  465. wxFont wxFont::Underlined() const
  466. {
  467. wxFont font(*this);
  468. font.MakeUnderlined();
  469. return font;
  470. }
  471. wxFont& wxFont::Scale(float x)
  472. {
  473. SetPointSize(int(x*GetPointSize() + 0.5));
  474. return *this;
  475. }
  476. wxFont wxFont::Scaled(float x) const
  477. {
  478. wxFont font(*this);
  479. font.Scale(x);
  480. return font;
  481. }
  482. // ----------------------------------------------------------------------------
  483. // wxNativeFontInfo
  484. // ----------------------------------------------------------------------------
  485. // Up to now, there are no native implementations of this function:
  486. void wxNativeFontInfo::SetFaceName(const wxArrayString& facenames)
  487. {
  488. #if wxUSE_FONTENUM
  489. for (size_t i=0; i < facenames.GetCount(); i++)
  490. {
  491. if (wxFontEnumerator::IsValidFacename(facenames[i]))
  492. {
  493. SetFaceName(facenames[i]);
  494. return;
  495. }
  496. }
  497. // set the first valid facename we can find on this system
  498. wxString validfacename = wxFontEnumerator::GetFacenames().Item(0);
  499. wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename.c_str());
  500. SetFaceName(validfacename);
  501. #else // !wxUSE_FONTENUM
  502. SetFaceName(facenames[0]);
  503. #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
  504. }
  505. #ifdef wxNO_NATIVE_FONTINFO
  506. // These are the generic forms of FromString()/ToString.
  507. //
  508. // convert to/from the string representation: format is
  509. // version;pointsize;family;style;weight;underlined;facename;encoding
  510. bool wxNativeFontInfo::FromString(const wxString& s)
  511. {
  512. long l;
  513. wxStringTokenizer tokenizer(s, wxT(";"));
  514. wxString token = tokenizer.GetNextToken();
  515. //
  516. // Ignore the version for now
  517. //
  518. token = tokenizer.GetNextToken();
  519. if ( !token.ToLong(&l) )
  520. return false;
  521. pointSize = (int)l;
  522. token = tokenizer.GetNextToken();
  523. if ( !token.ToLong(&l) )
  524. return false;
  525. family = (wxFontFamily)l;
  526. token = tokenizer.GetNextToken();
  527. if ( !token.ToLong(&l) )
  528. return false;
  529. style = (wxFontStyle)l;
  530. token = tokenizer.GetNextToken();
  531. if ( !token.ToLong(&l) )
  532. return false;
  533. weight = (wxFontWeight)l;
  534. token = tokenizer.GetNextToken();
  535. if ( !token.ToLong(&l) )
  536. return false;
  537. underlined = l != 0;
  538. faceName = tokenizer.GetNextToken();
  539. #ifndef __WXMAC__
  540. if( !faceName )
  541. return false;
  542. #endif
  543. token = tokenizer.GetNextToken();
  544. if ( !token.ToLong(&l) )
  545. return false;
  546. encoding = (wxFontEncoding)l;
  547. return true;
  548. }
  549. wxString wxNativeFontInfo::ToString() const
  550. {
  551. wxString s;
  552. s.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
  553. 0, // version
  554. pointSize,
  555. family,
  556. (int)style,
  557. (int)weight,
  558. underlined,
  559. faceName.GetData(),
  560. (int)encoding);
  561. return s;
  562. }
  563. void wxNativeFontInfo::Init()
  564. {
  565. pointSize = 0;
  566. family = wxFONTFAMILY_DEFAULT;
  567. style = wxFONTSTYLE_NORMAL;
  568. weight = wxFONTWEIGHT_NORMAL;
  569. underlined = false;
  570. faceName.clear();
  571. encoding = wxFONTENCODING_DEFAULT;
  572. }
  573. int wxNativeFontInfo::GetPointSize() const
  574. {
  575. return pointSize;
  576. }
  577. wxFontStyle wxNativeFontInfo::GetStyle() const
  578. {
  579. return style;
  580. }
  581. wxFontWeight wxNativeFontInfo::GetWeight() const
  582. {
  583. return weight;
  584. }
  585. bool wxNativeFontInfo::GetUnderlined() const
  586. {
  587. return underlined;
  588. }
  589. wxString wxNativeFontInfo::GetFaceName() const
  590. {
  591. return faceName;
  592. }
  593. wxFontFamily wxNativeFontInfo::GetFamily() const
  594. {
  595. return family;
  596. }
  597. wxFontEncoding wxNativeFontInfo::GetEncoding() const
  598. {
  599. return encoding;
  600. }
  601. void wxNativeFontInfo::SetPointSize(int pointsize)
  602. {
  603. pointSize = pointsize;
  604. }
  605. void wxNativeFontInfo::SetStyle(wxFontStyle style_)
  606. {
  607. style = style_;
  608. }
  609. void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
  610. {
  611. weight = weight_;
  612. }
  613. void wxNativeFontInfo::SetUnderlined(bool underlined_)
  614. {
  615. underlined = underlined_;
  616. }
  617. bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
  618. {
  619. faceName = facename_;
  620. return true;
  621. }
  622. void wxNativeFontInfo::SetFamily(wxFontFamily family_)
  623. {
  624. family = family_;
  625. }
  626. void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
  627. {
  628. encoding = encoding_;
  629. }
  630. #endif // generic wxNativeFontInfo implementation
  631. // conversion to/from user-readable string: this is used in the generic
  632. // versions and under MSW as well because there is no standard font description
  633. // format there anyhow (but there is a well-defined standard for X11 fonts used
  634. // by wxGTK and wxMotif)
  635. #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__) || defined(__WXOSX__)
  636. wxString wxNativeFontInfo::ToUserString() const
  637. {
  638. wxString desc;
  639. // first put the adjectives, if any - this is English-centric, of course,
  640. // but what else can we do?
  641. if ( GetUnderlined() )
  642. {
  643. desc << _("underlined");
  644. }
  645. switch ( GetWeight() )
  646. {
  647. default:
  648. wxFAIL_MSG( wxT("unknown font weight") );
  649. // fall through
  650. case wxFONTWEIGHT_NORMAL:
  651. break;
  652. case wxFONTWEIGHT_LIGHT:
  653. desc << _(" light");
  654. break;
  655. case wxFONTWEIGHT_BOLD:
  656. desc << _(" bold");
  657. break;
  658. }
  659. switch ( GetStyle() )
  660. {
  661. default:
  662. wxFAIL_MSG( wxT("unknown font style") );
  663. // fall through
  664. case wxFONTSTYLE_NORMAL:
  665. break;
  666. // we don't distinguish between the two for now anyhow...
  667. case wxFONTSTYLE_ITALIC:
  668. case wxFONTSTYLE_SLANT:
  669. desc << _(" italic");
  670. break;
  671. }
  672. wxString face = GetFaceName();
  673. if ( !face.empty() )
  674. {
  675. if (face.Contains(' ') || face.Contains(';') || face.Contains(','))
  676. {
  677. face.Replace("'", "");
  678. // eventually remove quote characters: most systems do not
  679. // allow them in a facename anyway so this usually does nothing
  680. // make it possible for FromUserString() function to understand
  681. // that the different words which compose this facename are
  682. // not different adjectives or other data but rather all parts
  683. // of the facename
  684. desc << wxT(" '") << face << _("'");
  685. }
  686. else
  687. desc << wxT(' ') << face;
  688. }
  689. else // no face name specified
  690. {
  691. // use the family
  692. wxString familyStr;
  693. switch ( GetFamily() )
  694. {
  695. case wxFONTFAMILY_DECORATIVE:
  696. familyStr = "decorative";
  697. break;
  698. case wxFONTFAMILY_ROMAN:
  699. familyStr = "roman";
  700. break;
  701. case wxFONTFAMILY_SCRIPT:
  702. familyStr = "script";
  703. break;
  704. case wxFONTFAMILY_SWISS:
  705. familyStr = "swiss";
  706. break;
  707. case wxFONTFAMILY_MODERN:
  708. familyStr = "modern";
  709. break;
  710. case wxFONTFAMILY_TELETYPE:
  711. familyStr = "teletype";
  712. break;
  713. case wxFONTFAMILY_DEFAULT:
  714. case wxFONTFAMILY_UNKNOWN:
  715. break;
  716. default:
  717. wxFAIL_MSG( "unknown font family" );
  718. }
  719. if ( !familyStr.empty() )
  720. desc << " '" << familyStr << " family'";
  721. }
  722. int size = GetPointSize();
  723. if ( size != wxNORMAL_FONT->GetPointSize() )
  724. {
  725. desc << wxT(' ') << size;
  726. }
  727. #if wxUSE_FONTMAP
  728. wxFontEncoding enc = GetEncoding();
  729. if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
  730. {
  731. desc << wxT(' ') << wxFontMapper::GetEncodingName(enc);
  732. }
  733. #endif // wxUSE_FONTMAP
  734. return desc.Strip(wxString::both).MakeLower();
  735. }
  736. bool wxNativeFontInfo::FromUserString(const wxString& s)
  737. {
  738. // reset to the default state
  739. Init();
  740. // ToUserString() will quote the facename if it contains spaces, commas
  741. // or semicolons: we must be able to understand that quoted text is
  742. // a single token:
  743. wxString toparse(s);
  744. // parse a more or less free form string
  745. wxStringTokenizer tokenizer(toparse, wxT(";, "), wxTOKEN_STRTOK);
  746. wxString face;
  747. unsigned long size;
  748. bool weightfound = false, pointsizefound = false;
  749. #if wxUSE_FONTMAP
  750. bool encodingfound = false;
  751. #endif
  752. bool insideQuotes = false;
  753. while ( tokenizer.HasMoreTokens() )
  754. {
  755. wxString token = tokenizer.GetNextToken();
  756. // normalize it
  757. token.Trim(true).Trim(false).MakeLower();
  758. if (insideQuotes)
  759. {
  760. if (token.StartsWith("'") ||
  761. token.EndsWith("'"))
  762. {
  763. insideQuotes = false;
  764. // add this last token to the facename:
  765. face += " " + token;
  766. // normalize facename:
  767. face = face.Trim(true).Trim(false);
  768. face.Replace("'", "");
  769. continue;
  770. }
  771. }
  772. else
  773. {
  774. if (token.StartsWith("'"))
  775. insideQuotes = true;
  776. }
  777. // look for the known tokens
  778. if ( insideQuotes )
  779. {
  780. // only the facename may be quoted:
  781. face += " " + token;
  782. continue;
  783. }
  784. if ( token == wxT("underlined") || token == _("underlined") )
  785. {
  786. SetUnderlined(true);
  787. }
  788. else if ( token == wxT("light") || token == _("light") )
  789. {
  790. SetWeight(wxFONTWEIGHT_LIGHT);
  791. weightfound = true;
  792. }
  793. else if ( token == wxT("bold") || token == _("bold") )
  794. {
  795. SetWeight(wxFONTWEIGHT_BOLD);
  796. weightfound = true;
  797. }
  798. else if ( token == wxT("italic") || token == _("italic") )
  799. {
  800. SetStyle(wxFONTSTYLE_ITALIC);
  801. }
  802. else if ( token.ToULong(&size) )
  803. {
  804. SetPointSize(size);
  805. pointsizefound = true;
  806. }
  807. else
  808. {
  809. #if wxUSE_FONTMAP
  810. // try to interpret this as an encoding
  811. wxFontEncoding encoding = wxFontMapper::Get()->CharsetToEncoding(token, false);
  812. if ( encoding != wxFONTENCODING_DEFAULT &&
  813. encoding != wxFONTENCODING_SYSTEM ) // returned when the recognition failed
  814. {
  815. SetEncoding(encoding);
  816. encodingfound = true;
  817. }
  818. else
  819. {
  820. #endif // wxUSE_FONTMAP
  821. // assume it is the face name
  822. if ( !face.empty() )
  823. {
  824. face += wxT(' ');
  825. }
  826. face += token;
  827. // skip the code which resets face below
  828. continue;
  829. #if wxUSE_FONTMAP
  830. }
  831. #endif // wxUSE_FONTMAP
  832. }
  833. // if we had had the facename, we shouldn't continue appending tokens
  834. // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
  835. // bar")
  836. if ( !face.empty() )
  837. {
  838. wxString familyStr;
  839. if ( face.EndsWith(" family", &familyStr) )
  840. {
  841. // it's not a facename but rather a font family
  842. wxFontFamily family;
  843. if ( familyStr == "decorative" )
  844. family = wxFONTFAMILY_DECORATIVE;
  845. else if ( familyStr == "roman" )
  846. family = wxFONTFAMILY_ROMAN;
  847. else if ( familyStr == "script" )
  848. family = wxFONTFAMILY_SCRIPT;
  849. else if ( familyStr == "swiss" )
  850. family = wxFONTFAMILY_SWISS;
  851. else if ( familyStr == "modern" )
  852. family = wxFONTFAMILY_MODERN;
  853. else if ( familyStr == "teletype" )
  854. family = wxFONTFAMILY_TELETYPE;
  855. else
  856. return false;
  857. SetFamily(family);
  858. }
  859. // NB: the check on the facename is implemented in wxFontBase::SetFaceName
  860. // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
  861. // call here wxFontEnumerator::IsValidFacename
  862. else if (
  863. #if wxUSE_FONTENUM
  864. !wxFontEnumerator::IsValidFacename(face) ||
  865. #endif // wxUSE_FONTENUM
  866. !SetFaceName(face) )
  867. {
  868. SetFaceName(wxNORMAL_FONT->GetFaceName());
  869. }
  870. face.clear();
  871. }
  872. }
  873. // we might not have flushed it inside the loop
  874. if ( !face.empty() )
  875. {
  876. // NB: the check on the facename is implemented in wxFontBase::SetFaceName
  877. // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
  878. // call here wxFontEnumerator::IsValidFacename
  879. if (
  880. #if wxUSE_FONTENUM
  881. !wxFontEnumerator::IsValidFacename(face) ||
  882. #endif // wxUSE_FONTENUM
  883. !SetFaceName(face) )
  884. {
  885. SetFaceName(wxNORMAL_FONT->GetFaceName());
  886. }
  887. }
  888. // set point size to default value if size was not given
  889. if ( !pointsizefound )
  890. SetPointSize(wxNORMAL_FONT->GetPointSize());
  891. // set font weight to default value if weight was not given
  892. if ( !weightfound )
  893. SetWeight(wxFONTWEIGHT_NORMAL);
  894. #if wxUSE_FONTMAP
  895. // set font encoding to default value if encoding was not given
  896. if ( !encodingfound )
  897. SetEncoding(wxFONTENCODING_SYSTEM);
  898. #endif // wxUSE_FONTMAP
  899. return true;
  900. }
  901. #endif // generic or wxMSW or wxOS2
  902. // wxFont <-> wxString utilities, used by wxConfig
  903. wxString wxToString(const wxFontBase& font)
  904. {
  905. return font.IsOk() ? font.GetNativeFontInfoDesc()
  906. : wxString();
  907. }
  908. bool wxFromString(const wxString& str, wxFontBase *font)
  909. {
  910. wxCHECK_MSG( font, false, wxT("NULL output parameter") );
  911. if ( str.empty() )
  912. {
  913. *font = wxNullFont;
  914. return true;
  915. }
  916. return font->SetNativeFontInfo(str);
  917. }