home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / fontcmn.cpp < prev    next >
C/C++ Source or Header  |  2002-12-10  |  15KB  |  574 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        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: fontcmn.cpp,v 1.30.2.1 2002/12/10 16:10:02 JS Exp $
  8. // Copyright:   (c) wxWindows team
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21. #pragma implementation "fontbase.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28. #pragma hdrstop
  29. #endif
  30.  
  31. #ifndef WX_PRECOMP
  32. #include "wx/font.h"
  33. #include "wx/intl.h"
  34. #endif // WX_PRECOMP
  35.  
  36. #include "wx/gdicmn.h"
  37. #include "wx/fontutil.h" // for wxNativeFontInfo
  38. #include "wx/fontmap.h"
  39.  
  40. #include "wx/tokenzr.h"
  41.  
  42. // ============================================================================
  43. // implementation
  44. // ============================================================================
  45.  
  46. // ----------------------------------------------------------------------------
  47. // wxFontBase
  48. // ----------------------------------------------------------------------------
  49.  
  50. wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
  51.  
  52. /* static */
  53. void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
  54. {
  55.     // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
  56.     // and, besides, using this value here doesn't make any sense
  57.     wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
  58.                  _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
  59.  
  60.     ms_encodingDefault = encoding;
  61. }
  62.  
  63. wxFontBase::~wxFontBase()
  64. {
  65.     // this destructor is required for Darwin
  66. }
  67.  
  68. /* static */
  69. wxFont *wxFontBase::New(int size,
  70.                         int family,
  71.                         int style,
  72.                         int weight,
  73.                         bool underlined,
  74.                         const wxString& face,
  75.                         wxFontEncoding encoding)
  76. {
  77.     return new wxFont(size, family, style, weight, underlined, face, encoding);
  78. }
  79.  
  80. /* static */
  81. wxFont *wxFontBase::New(const wxNativeFontInfo& info)
  82. {
  83.     return new wxFont(info);
  84. }
  85.  
  86. /* static */
  87. wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
  88. {
  89.     wxNativeFontInfo fontInfo;
  90.     if ( !fontInfo.FromString(strNativeFontDesc) )
  91.         return new wxFont(*wxNORMAL_FONT);
  92.  
  93.     return New(fontInfo);
  94. }
  95.  
  96. bool wxFontBase::IsFixedWidth() const
  97. {
  98.     return GetFamily() == wxFONTFAMILY_TELETYPE;
  99. }
  100.  
  101. wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
  102. {
  103. #ifdef wxNO_NATIVE_FONTINFO
  104.     wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
  105.  
  106.     fontInfo->SetPointSize(GetPointSize());
  107.     fontInfo->SetFamily((wxFontFamily)GetFamily());
  108.     fontInfo->SetStyle((wxFontStyle)GetStyle());
  109.     fontInfo->SetWeight((wxFontWeight)GetWeight());
  110.     fontInfo->SetUnderlined(GetUnderlined());
  111.     fontInfo->SetFaceName(GetFaceName());
  112.     fontInfo->SetEncoding(GetEncoding());
  113.  
  114.     return fontInfo;
  115. #else
  116.     return (wxNativeFontInfo *)NULL;
  117. #endif
  118. }
  119.  
  120. void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
  121. {
  122. #ifdef wxNO_NATIVE_FONTINFO
  123.     SetPointSize(info.pointSize);
  124.     SetFamily(info.family);
  125.     SetStyle(info.style);
  126.     SetWeight(info.weight);
  127.     SetUnderlined(info.underlined);
  128.     SetFaceName(info.faceName);
  129.     SetEncoding(info.encoding);
  130. #else
  131.     (void)info;
  132. #endif
  133. }
  134.  
  135. wxString wxFontBase::GetNativeFontInfoDesc() const
  136. {
  137.     wxString fontDesc;
  138.     wxNativeFontInfo *fontInfo = GetNativeFontInfo();
  139.     if ( fontInfo )
  140.     {
  141.         fontDesc = fontInfo->ToString();
  142.         delete fontInfo;
  143.     }
  144.  
  145.     return fontDesc;
  146. }
  147.  
  148. wxString wxFontBase::GetNativeFontInfoUserDesc() const
  149. {
  150.     wxString fontDesc;
  151.     wxNativeFontInfo *fontInfo = GetNativeFontInfo();
  152.     if ( fontInfo )
  153.     {
  154.         fontDesc = fontInfo->ToUserString();
  155.         delete fontInfo;
  156.     }
  157.  
  158.     return fontDesc;
  159. }
  160.  
  161. void wxFontBase::SetNativeFontInfo(const wxString& info)
  162. {
  163.     wxNativeFontInfo fontInfo;
  164.     if ( !info.empty() && fontInfo.FromString(info) )
  165.     {
  166.         SetNativeFontInfo(fontInfo);
  167.     }
  168. }
  169.  
  170. void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
  171. {
  172.     wxNativeFontInfo fontInfo;
  173.     if ( !info.empty() && fontInfo.FromUserString(info) )
  174.     {
  175.         SetNativeFontInfo(fontInfo);
  176.     }
  177. }
  178.  
  179. wxFont& wxFont::operator=(const wxFont& font)
  180. {
  181.     if ( this != &font )
  182.         Ref(font);
  183.  
  184.     return (wxFont &)*this;
  185. }
  186.  
  187. bool wxFontBase::operator==(const wxFont& font) const
  188. {
  189.     // either it is the same font, i.e. they share the same common data or they
  190.     // have different ref datas but still describe the same font
  191.     return GetFontData() == font.GetFontData() ||
  192.            (
  193.             Ok() == font.Ok() &&
  194.             GetPointSize() == font.GetPointSize() &&
  195.             GetFamily() == font.GetFamily() &&
  196.             GetStyle() == font.GetStyle() &&
  197.             GetWeight() == font.GetWeight() &&
  198.             GetUnderlined() == font.GetUnderlined() &&
  199.             GetFaceName() == font.GetFaceName() &&
  200.             GetEncoding() == font.GetEncoding()
  201.            );
  202. }
  203.  
  204. bool wxFontBase::operator!=(const wxFont& font) const
  205. {
  206.     return !(*this == font);
  207. }
  208.  
  209. wxString wxFontBase::GetFamilyString() const
  210. {
  211.     wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
  212.  
  213.     switch ( GetFamily() )
  214.     {
  215.         case wxDECORATIVE:   return wxT("wxDECORATIVE");
  216.         case wxROMAN:        return wxT("wxROMAN");
  217.         case wxSCRIPT:       return wxT("wxSCRIPT");
  218.         case wxSWISS:        return wxT("wxSWISS");
  219.         case wxMODERN:       return wxT("wxMODERN");
  220.         case wxTELETYPE:     return wxT("wxTELETYPE");
  221.         default:             return wxT("wxDEFAULT");
  222.     }
  223. }
  224.  
  225. wxString wxFontBase::GetStyleString() const
  226. {
  227.     wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
  228.  
  229.     switch ( GetStyle() )
  230.     {
  231.         case wxNORMAL:   return wxT("wxNORMAL");
  232.         case wxSLANT:    return wxT("wxSLANT");
  233.         case wxITALIC:   return wxT("wxITALIC");
  234.         default:         return wxT("wxDEFAULT");
  235.     }
  236. }
  237.  
  238. wxString wxFontBase::GetWeightString() const
  239. {
  240.     wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
  241.  
  242.     switch ( GetWeight() )
  243.     {
  244.         case wxNORMAL:   return wxT("wxNORMAL");
  245.         case wxBOLD:     return wxT("wxBOLD");
  246.         case wxLIGHT:    return wxT("wxLIGHT");
  247.         default:         return wxT("wxDEFAULT");
  248.     }
  249. }
  250.  
  251. // ----------------------------------------------------------------------------
  252. // wxNativeFontInfo
  253. // ----------------------------------------------------------------------------
  254.  
  255. #ifdef wxNO_NATIVE_FONTINFO
  256.  
  257. // These are the generic forms of FromString()/ToString.
  258. //
  259. // convert to/from the string representation: format is
  260. //      version;pointsize;family;style;weight;underlined;facename;encoding
  261.  
  262. bool wxNativeFontInfo::FromString(const wxString& s)
  263. {
  264.     long l;
  265.  
  266.     wxStringTokenizer tokenizer(s, _T(";"));
  267.  
  268.     wxString token = tokenizer.GetNextToken();
  269.     //
  270.     //  Ignore the version for now
  271.     //
  272.  
  273.     token = tokenizer.GetNextToken();
  274.     if ( !token.ToLong(&l) )
  275.         return FALSE;
  276.     pointSize = (int)l;
  277.  
  278.     token = tokenizer.GetNextToken();
  279.     if ( !token.ToLong(&l) )
  280.         return FALSE;
  281.     family = (wxFontFamily)l;
  282.  
  283.     token = tokenizer.GetNextToken();
  284.     if ( !token.ToLong(&l) )
  285.         return FALSE;
  286.     style = (wxFontStyle)l;
  287.  
  288.     token = tokenizer.GetNextToken();
  289.     if ( !token.ToLong(&l) )
  290.         return FALSE;
  291.     weight = (wxFontWeight)l;
  292.  
  293.     token = tokenizer.GetNextToken();
  294.     if ( !token.ToLong(&l) )
  295.         return FALSE;
  296.     underlined = l != 0;
  297.  
  298.     faceName = tokenizer.GetNextToken();
  299.  
  300. #ifndef __WXMAC__
  301.     if( !faceName )
  302.         return FALSE;
  303. #endif
  304.  
  305.     token = tokenizer.GetNextToken();
  306.     if ( !token.ToLong(&l) )
  307.         return FALSE;
  308.     encoding = (wxFontEncoding)l;
  309.  
  310.     return TRUE;
  311. }
  312.  
  313. wxString wxNativeFontInfo::ToString() const
  314. {
  315.     wxString s;
  316.  
  317.     s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
  318.              0,                                 // version
  319.              pointSize,
  320.              family,
  321.              (int)style,
  322.              (int)weight,
  323.              underlined,
  324.              faceName.GetData(),
  325.              (int)encoding);
  326.  
  327.     return s;
  328. }
  329.  
  330. void wxNativeFontInfo::Init()
  331. {
  332.     pointSize = wxNORMAL_FONT->GetPointSize();
  333.     family = wxFONTFAMILY_DEFAULT;
  334.     style = wxFONTSTYLE_NORMAL;
  335.     weight = wxFONTWEIGHT_NORMAL;
  336.     underlined = FALSE;
  337.     faceName.clear();
  338.     encoding = wxFONTENCODING_DEFAULT;
  339. }
  340.  
  341. int wxNativeFontInfo::GetPointSize() const
  342. {
  343.     return pointSize;
  344. }
  345.  
  346. wxFontStyle wxNativeFontInfo::GetStyle() const
  347. {
  348.     return style;
  349. }
  350.  
  351. wxFontWeight wxNativeFontInfo::GetWeight() const
  352. {
  353.     return weight;
  354. }
  355.  
  356. bool wxNativeFontInfo::GetUnderlined() const
  357. {
  358.     return underlined;
  359. }
  360.  
  361. wxString wxNativeFontInfo::GetFaceName() const
  362. {
  363.     return faceName;
  364. }
  365.  
  366. wxFontFamily wxNativeFontInfo::GetFamily() const
  367. {
  368.     return family;
  369. }
  370.  
  371. wxFontEncoding wxNativeFontInfo::GetEncoding() const
  372. {
  373.     return encoding;
  374. }
  375.  
  376. void wxNativeFontInfo::SetPointSize(int pointsize)
  377. {
  378.     pointSize = pointsize;
  379. }
  380.  
  381. void wxNativeFontInfo::SetStyle(wxFontStyle style_)
  382. {
  383.     style = style_;
  384. }
  385.  
  386. void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
  387. {
  388.     weight = weight_;
  389. }
  390.  
  391. void wxNativeFontInfo::SetUnderlined(bool underlined_)
  392. {
  393.     underlined = underlined_;
  394. }
  395.  
  396. void wxNativeFontInfo::SetFaceName(wxString facename_)
  397. {
  398.     faceName = facename_;
  399. }
  400.  
  401. void wxNativeFontInfo::SetFamily(wxFontFamily family_)
  402. {
  403.     family = family_;
  404. }
  405.  
  406. void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
  407. {
  408.     encoding = encoding_;
  409. }
  410.  
  411. #endif // generic wxNativeFontInfo implementation
  412.  
  413. // conversion to/from user-readable string: this is used in the generic
  414. // versions and under MSW as well because there is no standard font description
  415. // format there anyhow (but there is a well-defined standard for X11 fonts used
  416. // by wxGTK and wxMotif)
  417.  
  418. #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
  419.  
  420. wxString wxNativeFontInfo::ToUserString() const
  421. {
  422.     wxString desc;
  423.  
  424.     // first put the adjectives, if any - this is English-centric, of course,
  425.     // but what else can we do?
  426.     if ( GetUnderlined() )
  427.     {
  428.         desc << _("underlined ");
  429.     }
  430.  
  431.     switch ( GetWeight() )
  432.     {
  433.         default:
  434.             wxFAIL_MSG( _T("unknown font weight") );
  435.             // fall through
  436.  
  437.         case wxFONTWEIGHT_NORMAL:
  438.             break;
  439.  
  440.         case wxFONTWEIGHT_LIGHT:
  441.             desc << _("light ");
  442.             break;
  443.  
  444.         case wxFONTWEIGHT_BOLD:
  445.             desc << _("bold ");
  446.             break;
  447.     }
  448.  
  449.     switch ( GetStyle() )
  450.     {
  451.         default:
  452.             wxFAIL_MSG( _T("unknown font style") );
  453.             // fall through
  454.  
  455.         case wxFONTSTYLE_NORMAL:
  456.             break;
  457.  
  458.             // we don't distinguish between the two for now anyhow...
  459.         case wxFONTSTYLE_ITALIC:
  460.         case wxFONTSTYLE_SLANT:
  461.             desc << _("italic");
  462.             break;
  463.     }
  464.  
  465.     wxString face = GetFaceName();
  466.     if ( !face.empty() )
  467.     {
  468.         desc << _T(' ') << face;
  469.     }
  470.  
  471.     int size = GetPointSize();
  472.     if ( size != wxNORMAL_FONT->GetPointSize() )
  473.     {
  474.         desc << _T(' ') << size;
  475.     }
  476.  
  477. #if wxUSE_FONTMAP
  478.     wxFontEncoding enc = GetEncoding();
  479.     if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
  480.     {
  481.         desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
  482.     }
  483. #endif // wxUSE_FONTMAP
  484.  
  485.     return desc;
  486. }
  487.  
  488. bool wxNativeFontInfo::FromUserString(const wxString& s)
  489. {
  490.     // reset to the default state
  491.     Init();
  492.  
  493.     // parse a more or less free form string
  494.     //
  495.     // TODO: we should handle at least the quoted facenames
  496.     wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
  497.  
  498.     wxString face;
  499.     unsigned long size;
  500.  
  501. #if wxUSE_FONTMAP
  502.     wxFontEncoding encoding;
  503. #endif // wxUSE_FONTMAP
  504.  
  505.     while ( tokenizer.HasMoreTokens() )
  506.     {
  507.         wxString token = tokenizer.GetNextToken();
  508.  
  509.         // normalize it
  510.         token.Trim(TRUE).Trim(FALSE).MakeLower();
  511.  
  512.         // look for the known tokens
  513.         if ( token == _T("underlined") || token == _("underlined") )
  514.         {
  515.             SetUnderlined(TRUE);
  516.         }
  517.         else if ( token == _T("light") || token == _("light") )
  518.         {
  519.             SetWeight(wxFONTWEIGHT_LIGHT);
  520.         }
  521.         else if ( token == _T("bold") || token == _("bold") )
  522.         {
  523.             SetWeight(wxFONTWEIGHT_BOLD);
  524.         }
  525.         else if ( token == _T("italic") || token == _("italic") )
  526.         {
  527.             SetStyle(wxFONTSTYLE_ITALIC);
  528.         }
  529.         else if ( token.ToULong(&size) )
  530.         {
  531.             SetPointSize(size);
  532.         }
  533. #if wxUSE_FONTMAP
  534.         else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, FALSE))
  535.                     != wxFONTENCODING_DEFAULT )
  536.         {
  537.             SetEncoding(encoding);
  538.         }
  539. #endif // wxUSE_FONTMAP
  540.         else // assume it is the face name
  541.         {
  542.             if ( !face.empty() )
  543.             {
  544.                 face += _T(' ');
  545.             }
  546.  
  547.             face += token;
  548.  
  549.             // skip the code which resets face below
  550.             continue;
  551.         }
  552.  
  553.         // if we had had the facename, we shouldn't continue appending tokens
  554.         // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
  555.         // bar")
  556.         if ( !face.empty() )
  557.         {
  558.             SetFaceName(face);
  559.             face.clear();
  560.         }
  561.     }
  562.  
  563.     // we might not have flushed it inside the loop
  564.     if ( !face.empty() )
  565.     {
  566.         SetFaceName(face);
  567.     }
  568.  
  569.     return TRUE;
  570. }
  571.  
  572. #endif // generic or wxMSW or wxOS2
  573.  
  574.