home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / common / fontcmn.cpp < prev    next >
C/C++ Source or Header  |  2002-04-07  |  15KB  |  571 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 2002/04/06 14:57:25 VS 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.     if( !faceName )
  300.         return FALSE;
  301.  
  302.     token = tokenizer.GetNextToken();
  303.     if ( !token.ToLong(&l) )
  304.         return FALSE;
  305.     encoding = (wxFontEncoding)l;
  306.  
  307.     return TRUE;
  308. }
  309.  
  310. wxString wxNativeFontInfo::ToString() const
  311. {
  312.     wxString s;
  313.  
  314.     s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
  315.              0,                                 // version
  316.              pointSize,
  317.              family,
  318.              (int)style,
  319.              (int)weight,
  320.              underlined,
  321.              faceName.GetData(),
  322.              (int)encoding);
  323.  
  324.     return s;
  325. }
  326.  
  327. void wxNativeFontInfo::Init()
  328. {
  329.     pointSize = wxNORMAL_FONT->GetPointSize();
  330.     family = wxFONTFAMILY_DEFAULT;
  331.     style = wxFONTSTYLE_NORMAL;
  332.     weight = wxFONTWEIGHT_NORMAL;
  333.     underlined = FALSE;
  334.     faceName.clear();
  335.     encoding = wxFONTENCODING_DEFAULT;
  336. }
  337.  
  338. int wxNativeFontInfo::GetPointSize() const
  339. {
  340.     return pointSize;
  341. }
  342.  
  343. wxFontStyle wxNativeFontInfo::GetStyle() const
  344. {
  345.     return style;
  346. }
  347.  
  348. wxFontWeight wxNativeFontInfo::GetWeight() const
  349. {
  350.     return weight;
  351. }
  352.  
  353. bool wxNativeFontInfo::GetUnderlined() const
  354. {
  355.     return underlined;
  356. }
  357.  
  358. wxString wxNativeFontInfo::GetFaceName() const
  359. {
  360.     return faceName;
  361. }
  362.  
  363. wxFontFamily wxNativeFontInfo::GetFamily() const
  364. {
  365.     return family;
  366. }
  367.  
  368. wxFontEncoding wxNativeFontInfo::GetEncoding() const
  369. {
  370.     return encoding;
  371. }
  372.  
  373. void wxNativeFontInfo::SetPointSize(int pointsize)
  374. {
  375.     pointSize = pointsize;
  376. }
  377.  
  378. void wxNativeFontInfo::SetStyle(wxFontStyle style_)
  379. {
  380.     style = style_;
  381. }
  382.  
  383. void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
  384. {
  385.     weight = weight_;
  386. }
  387.  
  388. void wxNativeFontInfo::SetUnderlined(bool underlined_)
  389. {
  390.     underlined = underlined_;
  391. }
  392.  
  393. void wxNativeFontInfo::SetFaceName(wxString facename_)
  394. {
  395.     faceName = facename_;
  396. }
  397.  
  398. void wxNativeFontInfo::SetFamily(wxFontFamily family_)
  399. {
  400.     family = family_;
  401. }
  402.  
  403. void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
  404. {
  405.     encoding = encoding_;
  406. }
  407.  
  408. #endif // generic wxNativeFontInfo implementation
  409.  
  410. // conversion to/from user-readable string: this is used in the generic
  411. // versions and under MSW as well because there is no standard font description
  412. // format there anyhow (but there is a well-defined standard for X11 fonts used
  413. // by wxGTK and wxMotif)
  414.  
  415. #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
  416.  
  417. wxString wxNativeFontInfo::ToUserString() const
  418. {
  419.     wxString desc;
  420.  
  421.     // first put the adjectives, if any - this is English-centric, of course,
  422.     // but what else can we do?
  423.     if ( GetUnderlined() )
  424.     {
  425.         desc << _("underlined ");
  426.     }
  427.  
  428.     switch ( GetWeight() )
  429.     {
  430.         default:
  431.             wxFAIL_MSG( _T("unknown font weight") );
  432.             // fall through
  433.  
  434.         case wxFONTWEIGHT_NORMAL:
  435.             break;
  436.  
  437.         case wxFONTWEIGHT_LIGHT:
  438.             desc << _("light ");
  439.             break;
  440.  
  441.         case wxFONTWEIGHT_BOLD:
  442.             desc << _("bold ");
  443.             break;
  444.     }
  445.  
  446.     switch ( GetStyle() )
  447.     {
  448.         default:
  449.             wxFAIL_MSG( _T("unknown font style") );
  450.             // fall through
  451.  
  452.         case wxFONTSTYLE_NORMAL:
  453.             break;
  454.  
  455.             // we don't distinguish between the two for now anyhow...
  456.         case wxFONTSTYLE_ITALIC:
  457.         case wxFONTSTYLE_SLANT:
  458.             desc << _("italic");
  459.             break;
  460.     }
  461.  
  462.     wxString face = GetFaceName();
  463.     if ( !face.empty() )
  464.     {
  465.         desc << _T(' ') << face;
  466.     }
  467.  
  468.     int size = GetPointSize();
  469.     if ( size != wxNORMAL_FONT->GetPointSize() )
  470.     {
  471.         desc << _T(' ') << size;
  472.     }
  473.  
  474. #if wxUSE_FONTMAP
  475.     wxFontEncoding enc = GetEncoding();
  476.     if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
  477.     {
  478.         desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
  479.     }
  480. #endif // wxUSE_FONTMAP
  481.  
  482.     return desc;
  483. }
  484.  
  485. bool wxNativeFontInfo::FromUserString(const wxString& s)
  486. {
  487.     // reset to the default state
  488.     Init();
  489.  
  490.     // parse a more or less free form string
  491.     //
  492.     // TODO: we should handle at least the quoted facenames
  493.     wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
  494.  
  495.     wxString face;
  496.     unsigned long size;
  497.  
  498. #if wxUSE_FONTMAP
  499.     wxFontEncoding encoding;
  500. #endif // wxUSE_FONTMAP
  501.  
  502.     while ( tokenizer.HasMoreTokens() )
  503.     {
  504.         wxString token = tokenizer.GetNextToken();
  505.  
  506.         // normalize it
  507.         token.Trim(TRUE).Trim(FALSE).MakeLower();
  508.  
  509.         // look for the known tokens
  510.         if ( token == _T("underlined") || token == _("underlined") )
  511.         {
  512.             SetUnderlined(TRUE);
  513.         }
  514.         else if ( token == _T("light") || token == _("light") )
  515.         {
  516.             SetWeight(wxFONTWEIGHT_LIGHT);
  517.         }
  518.         else if ( token == _T("bold") || token == _("bold") )
  519.         {
  520.             SetWeight(wxFONTWEIGHT_BOLD);
  521.         }
  522.         else if ( token == _T("italic") || token == _("italic") )
  523.         {
  524.             SetStyle(wxFONTSTYLE_ITALIC);
  525.         }
  526.         else if ( token.ToULong(&size) )
  527.         {
  528.             SetPointSize(size);
  529.         }
  530. #if wxUSE_FONTMAP
  531.         else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, FALSE))
  532.                     != wxFONTENCODING_DEFAULT )
  533.         {
  534.             SetEncoding(encoding);
  535.         }
  536. #endif // wxUSE_FONTMAP
  537.         else // assume it is the face name
  538.         {
  539.             if ( !face.empty() )
  540.             {
  541.                 face += _T(' ');
  542.             }
  543.  
  544.             face += token;
  545.  
  546.             // skip the code which resets face below
  547.             continue;
  548.         }
  549.  
  550.         // if we had had the facename, we shouldn't continue appending tokens
  551.         // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
  552.         // bar")
  553.         if ( !face.empty() )
  554.         {
  555.             SetFaceName(face);
  556.             face.clear();
  557.         }
  558.     }
  559.  
  560.     // we might not have flushed it inside the loop
  561.     if ( !face.empty() )
  562.     {
  563.         SetFaceName(face);
  564.     }
  565.  
  566.     return TRUE;
  567. }
  568.  
  569. #endif // generic or wxMSW or wxOS2
  570.  
  571.