1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "font.h"
23 #include "wx/fontutil.h"
24 #include "wx/cmndata.h"
27 #include "wx/gdicmn.h"
28 #include "wx/tokenzr.h"
29 #include "wx/settings.h"
34 #include <gdk/gdkprivate.h>
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 class wxFontRefData
: public wxObjectRefData
44 wxFontRefData(int size
= wxDEFAULT
,
45 int family
= wxDEFAULT
,
46 int style
= wxDEFAULT
,
47 int weight
= wxDEFAULT
,
48 bool underlined
= FALSE
,
49 const wxString
& faceName
= wxEmptyString
,
50 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
,
51 const wxNativeFontInfo
& info
= wxNullNativeFontInfo
);
52 wxFontRefData( const wxFontRefData
& data
);
53 virtual ~wxFontRefData();
56 // common part of all ctors
57 void Init(int pointSize
,
62 const wxString
& faceName
,
63 wxFontEncoding encoding
,
64 const wxNativeFontInfo
& info
);
67 wxList m_scaled_xfonts
;
74 wxFontEncoding m_encoding
;
75 wxNativeFontInfo m_nativeFontInfo
;
80 // ============================================================================
82 // ============================================================================
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 void wxFontRefData::Init(int pointSize
,
93 const wxString
& faceName
,
94 wxFontEncoding encoding
,
95 const wxNativeFontInfo
& info
= wxNullNativeFontInfo
)
97 if (family
== wxDEFAULT
)
102 m_faceName
= faceName
;
104 if (style
== wxDEFAULT
)
109 if (weight
== wxDEFAULT
)
114 if (pointSize
== wxDEFAULT
)
117 m_pointSize
= pointSize
;
119 m_underlined
= underlined
;
120 m_encoding
= encoding
;
121 m_nativeFontInfo
= info
;
124 wxFontRefData::wxFontRefData( const wxFontRefData
& data
)
125 : m_scaled_xfonts(wxKEY_INTEGER
)
127 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
128 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
,
129 data
.m_nativeFontInfo
);
132 wxFontRefData::wxFontRefData(int size
, int family
, int style
,
133 int weight
, bool underlined
, const wxString
& faceName
, wxFontEncoding encoding
,
134 const wxNativeFontInfo
& info
= wxNullNativeFontInfo
)
135 : m_scaled_xfonts(wxKEY_INTEGER
)
137 Init(size
, family
, style
, weight
,
138 underlined
, faceName
, encoding
, info
);
141 wxFontRefData::~wxFontRefData()
143 wxNode
*node
= m_scaled_xfonts
.First();
146 GdkFont
*font
= (GdkFont
*)node
->Data();
147 wxNode
*next
= node
->Next();
148 gdk_font_unref( font
);
153 // ----------------------------------------------------------------------------
155 // ----------------------------------------------------------------------------
157 bool wxNativeFontInfo::FromString(const wxString
& s
)
163 wxString
wxNativeFontInfo::ToString() const
168 // ----------------------------------------------------------------------------
170 // ----------------------------------------------------------------------------
172 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
177 wxTheFontList
->Append( this );
180 wxFont::wxFont(const wxNativeFontInfo
& info
)
182 Create(info
.xFontName
, wxFontData());
185 bool wxFont::Create( int pointSize
,
190 const wxString
& face
,
191 wxFontEncoding encoding
,
192 const wxNativeFontInfo
& info
)
194 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
195 underlined
, face
, encoding
, info
);
200 bool wxFont::Create(const wxString
& fontname
, const wxFontData
& fontdata
)
206 *this = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
);
210 m_refData
= new wxFontRefData();
212 M_FONTDATA
->m_nativeFontInfo
.xFontName
= fontname
; // X font name
216 wxStringTokenizer
tn( fontname
, wxT("-") );
218 tn
.GetNextToken(); // skip initial empty token
219 tn
.GetNextToken(); // foundry
222 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
224 tmp
= tn
.GetNextToken().MakeUpper(); // weight
225 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
226 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
227 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
228 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
229 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
231 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
232 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
234 tmp
= tn
.GetNextToken().MakeUpper(); // slant
235 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
236 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
238 tn
.GetNextToken(); // set width
239 tn
.GetNextToken(); // add. style
240 tn
.GetNextToken(); // pixel size
242 tmp
= tn
.GetNextToken(); // pointsize
245 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
246 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
249 tn
.GetNextToken(); // x-res
250 tn
.GetNextToken(); // y-res
252 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
255 M_FONTDATA
->m_family
= wxMODERN
;
256 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
257 M_FONTDATA
->m_family
= wxROMAN
;
258 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
259 M_FONTDATA
->m_family
= wxSWISS
;
260 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
261 M_FONTDATA
->m_family
= wxTELETYPE
;
262 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
263 M_FONTDATA
->m_family
= wxDECORATIVE
;
264 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
265 M_FONTDATA
->m_family
= wxSCRIPT
;
267 tn
.GetNextToken(); // avg width
269 // deal with font encoding
270 M_FONTDATA
->m_encoding
= fontdata
.GetEncoding();
271 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
273 wxString registry
= tn
.GetNextToken().MakeUpper(),
274 encoding
= tn
.GetNextToken().MakeUpper();
276 if ( registry
== _T("ISO8859") )
279 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
281 M_FONTDATA
->m_encoding
=
282 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
285 else if ( registry
== _T("MICROSOFT") )
288 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
290 M_FONTDATA
->m_encoding
=
291 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
294 else if ( registry
== _T("KOI8") )
296 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
298 //else: unknown encoding - may be give a warning here?
305 void wxFont::Unshare()
309 m_refData
= new wxFontRefData();
313 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
322 wxTheFontList
->DeleteObject( this );
325 // ----------------------------------------------------------------------------
327 // ----------------------------------------------------------------------------
329 int wxFont::GetPointSize() const
331 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
333 return M_FONTDATA
->m_pointSize
;
336 wxString
wxFont::GetFaceName() const
338 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
340 return M_FONTDATA
->m_faceName
;
343 int wxFont::GetFamily() const
345 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
347 return M_FONTDATA
->m_family
;
350 int wxFont::GetStyle() const
352 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
354 return M_FONTDATA
->m_style
;
357 int wxFont::GetWeight() const
359 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
361 return M_FONTDATA
->m_weight
;
364 bool wxFont::GetUnderlined() const
366 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
368 return M_FONTDATA
->m_underlined
;
372 wxFontEncoding
wxFont::GetEncoding() const
374 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
376 return M_FONTDATA
->m_encoding
;
379 wxNativeFontInfo
wxFont::GetNativeFontInfo() const
381 wxCHECK_MSG( Ok(), wxNullNativeFontInfo
, wxT("invalid font") );
383 if(M_FONTDATA
->m_nativeFontInfo
.xFontName
.IsEmpty())
385 return M_FONTDATA
->m_nativeFontInfo
;
389 // ----------------------------------------------------------------------------
390 // change font attributes
391 // ----------------------------------------------------------------------------
393 void wxFont::SetPointSize(int pointSize
)
397 M_FONTDATA
->m_pointSize
= pointSize
;
398 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
401 void wxFont::SetFamily(int family
)
405 M_FONTDATA
->m_family
= family
;
406 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
409 void wxFont::SetStyle(int style
)
413 M_FONTDATA
->m_style
= style
;
414 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
417 void wxFont::SetWeight(int weight
)
421 M_FONTDATA
->m_weight
= weight
;
422 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
425 void wxFont::SetFaceName(const wxString
& faceName
)
429 M_FONTDATA
->m_faceName
= faceName
;
430 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
433 void wxFont::SetUnderlined(bool underlined
)
437 M_FONTDATA
->m_underlined
= underlined
;
440 void wxFont::SetEncoding(wxFontEncoding encoding
)
444 M_FONTDATA
->m_encoding
= encoding
;
445 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
448 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
452 M_FONTDATA
->m_nativeFontInfo
= info
;
455 // ----------------------------------------------------------------------------
456 // get internal representation of font
457 // ----------------------------------------------------------------------------
459 static GdkFont
*g_systemDefaultGuiFont
= (GdkFont
*) NULL
;
461 GdkFont
*GtkGetDefaultGuiFont()
463 if (!g_systemDefaultGuiFont
)
465 GtkWidget
*widget
= gtk_button_new();
466 GtkStyle
*def
= gtk_rc_get_style( widget
);
469 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
473 def
= gtk_widget_get_default_style();
475 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
477 gtk_widget_destroy( widget
);
479 return g_systemDefaultGuiFont
;
482 GdkFont
*wxFont::GetInternalFont( float scale
) const
486 wxFAIL_MSG( wxT("invalid font") );
488 return (GdkFont
*) NULL
;
491 long int_scale
= long(scale
* 100.0 + 0.5); /* key for fontlist */
492 int point_scale
= (int)((M_FONTDATA
->m_pointSize
* 10 * int_scale
) / 100);
493 GdkFont
*font
= (GdkFont
*) NULL
;
495 wxNode
*node
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
);
498 font
= (GdkFont
*)node
->Data();
502 if (*this == wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
))
504 font
= GtkGetDefaultGuiFont();
508 font
= wxLoadQueryNearestFont( point_scale
,
509 M_FONTDATA
->m_family
,
511 M_FONTDATA
->m_weight
,
512 M_FONTDATA
->m_underlined
,
513 M_FONTDATA
->m_faceName
,
514 M_FONTDATA
->m_encoding
,
515 &M_FONTDATA
->m_nativeFontInfo
.xFontName
);
518 M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font
);
521 // it's quite useless to make it a wxCHECK because we're going to crash
523 wxASSERT_MSG( font
, wxT("could not load any font?") );