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"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 class wxFontRefData
: public wxObjectRefData
43 wxFontRefData(int size
= wxDEFAULT
,
44 int family
= wxDEFAULT
,
45 int style
= wxDEFAULT
,
46 int weight
= wxDEFAULT
,
47 bool underlined
= FALSE
,
48 const wxString
& faceName
= wxEmptyString
,
49 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
);
50 wxFontRefData( const wxFontRefData
& data
);
51 virtual ~wxFontRefData();
54 // common part of all ctors
55 void Init(int pointSize
,
60 const wxString
& faceName
,
61 wxFontEncoding encoding
);
64 wxList m_scaled_xfonts
;
71 wxFontEncoding m_encoding
;
76 // ============================================================================
78 // ============================================================================
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 void wxFontRefData::Init(int pointSize
,
89 const wxString
& faceName
,
90 wxFontEncoding encoding
)
92 if (family
== wxDEFAULT
)
97 m_faceName
= faceName
;
99 if (style
== wxDEFAULT
)
104 if (weight
== wxDEFAULT
)
109 if (pointSize
== wxDEFAULT
)
112 m_pointSize
= pointSize
;
114 m_underlined
= underlined
;
115 m_encoding
= encoding
;
118 wxFontRefData::wxFontRefData( const wxFontRefData
& data
)
119 : m_scaled_xfonts(wxKEY_INTEGER
)
121 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
122 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
125 wxFontRefData::wxFontRefData(int size
, int family
, int style
,
126 int weight
, bool underlined
, const wxString
& faceName
, wxFontEncoding encoding
)
127 : m_scaled_xfonts(wxKEY_INTEGER
)
129 Init(size
, family
, style
, weight
,
130 underlined
, faceName
, encoding
);
133 wxFontRefData::~wxFontRefData()
135 wxNode
*node
= m_scaled_xfonts
.First();
138 GdkFont
*font
= (GdkFont
*)node
->Data();
139 wxNode
*next
= node
->Next();
140 gdk_font_unref( font
);
145 // ----------------------------------------------------------------------------
147 // ----------------------------------------------------------------------------
149 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
154 wxTheFontList
->Append( this );
157 wxFont::wxFont( const wxString
& fontname
, const wxFontData
& fontdata
)
161 wxCHECK_RET( !!fontname
, _T("invalid font spec") );
163 m_refData
= new wxFontRefData();
167 wxStringTokenizer
tn( fontname
, wxT("-") );
169 tn
.GetNextToken(); // skip initial empty token
170 tn
.GetNextToken(); // foundry
172 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
174 tmp
= tn
.GetNextToken().MakeUpper(); // weight
175 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
176 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
177 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
178 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
179 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
181 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
182 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
184 tmp
= tn
.GetNextToken().MakeUpper(); // slant
185 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
186 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
188 tn
.GetNextToken(); // set width
189 tn
.GetNextToken(); // add. style
190 tn
.GetNextToken(); // pixel size
192 tmp
= tn
.GetNextToken(); // pointsize
193 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
194 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
196 tn
.GetNextToken(); // x-res
197 tn
.GetNextToken(); // y-res
199 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
202 M_FONTDATA
->m_family
= wxMODERN
;
203 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
204 M_FONTDATA
->m_family
= wxROMAN
;
205 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
206 M_FONTDATA
->m_family
= wxSWISS
;
207 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
208 M_FONTDATA
->m_family
= wxTELETYPE
;
209 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
210 M_FONTDATA
->m_family
= wxDECORATIVE
;
211 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
212 M_FONTDATA
->m_family
= wxSCRIPT
;
214 tn
.GetNextToken(); // avg width
216 // deal with font encoding
217 M_FONTDATA
->m_encoding
= fontdata
.GetEncoding();
218 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
220 wxString registry
= tn
.GetNextToken().MakeUpper(),
221 encoding
= tn
.GetNextToken().MakeUpper();
223 if ( registry
== _T("ISO8859") )
226 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
228 M_FONTDATA
->m_encoding
=
229 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
232 else if ( registry
== _T("MICROSOFT") )
235 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
237 M_FONTDATA
->m_encoding
=
238 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
241 else if ( registry
== _T("KOI8") )
243 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
245 //else: unknown encoding - may be give a warning here?
249 bool wxFont::Create( int pointSize
,
254 const wxString
& face
,
255 wxFontEncoding encoding
)
257 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
258 underlined
, face
, encoding
);
263 void wxFont::Unshare()
267 m_refData
= new wxFontRefData();
271 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
280 wxTheFontList
->DeleteObject( this );
283 // ----------------------------------------------------------------------------
285 // ----------------------------------------------------------------------------
287 int wxFont::GetPointSize() const
289 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
291 return M_FONTDATA
->m_pointSize
;
294 wxString
wxFont::GetFaceName() const
296 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
298 return M_FONTDATA
->m_faceName
;
301 int wxFont::GetFamily() const
303 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
305 return M_FONTDATA
->m_family
;
308 int wxFont::GetStyle() const
310 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
312 return M_FONTDATA
->m_style
;
315 int wxFont::GetWeight() const
317 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
319 return M_FONTDATA
->m_weight
;
322 bool wxFont::GetUnderlined() const
324 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
326 return M_FONTDATA
->m_underlined
;
330 wxFontEncoding
wxFont::GetEncoding() const
332 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
334 return M_FONTDATA
->m_encoding
;
337 // ----------------------------------------------------------------------------
338 // change font attributes
339 // ----------------------------------------------------------------------------
341 void wxFont::SetPointSize(int pointSize
)
345 M_FONTDATA
->m_pointSize
= pointSize
;
348 void wxFont::SetFamily(int family
)
352 M_FONTDATA
->m_family
= family
;
355 void wxFont::SetStyle(int style
)
359 M_FONTDATA
->m_style
= style
;
362 void wxFont::SetWeight(int weight
)
366 M_FONTDATA
->m_weight
= weight
;
369 void wxFont::SetFaceName(const wxString
& faceName
)
373 M_FONTDATA
->m_faceName
= faceName
;
376 void wxFont::SetUnderlined(bool underlined
)
380 M_FONTDATA
->m_underlined
= underlined
;
383 void wxFont::SetEncoding(wxFontEncoding encoding
)
387 M_FONTDATA
->m_encoding
= encoding
;
390 // ----------------------------------------------------------------------------
391 // get internal representation of font
392 // ----------------------------------------------------------------------------
394 static GdkFont
*g_systemDefaultGuiFont
= (GdkFont
*) NULL
;
396 static GdkFont
*GtkGetDefaultGuiFont()
398 if (!g_systemDefaultGuiFont
)
400 GtkWidget
*widget
= gtk_button_new();
401 GtkStyle
*def
= gtk_rc_get_style( widget
);
404 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
408 def
= gtk_widget_get_default_style();
410 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
412 gtk_widget_destroy( widget
);
414 return g_systemDefaultGuiFont
;
417 GdkFont
*wxFont::GetInternalFont( float scale
) const
421 wxFAIL_MSG( wxT("invalid font") );
423 return (GdkFont
*) NULL
;
426 long int_scale
= long(scale
* 100.0 + 0.5); /* key for fontlist */
427 int point_scale
= (int)((M_FONTDATA
->m_pointSize
* 10 * int_scale
) / 100);
428 GdkFont
*font
= (GdkFont
*) NULL
;
430 wxNode
*node
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
);
433 font
= (GdkFont
*)node
->Data();
437 if (*this == wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
))
439 font
= GtkGetDefaultGuiFont();
443 font
= wxLoadQueryNearestFont( point_scale
,
444 M_FONTDATA
->m_family
,
446 M_FONTDATA
->m_weight
,
447 M_FONTDATA
->m_underlined
,
448 M_FONTDATA
->m_faceName
,
449 M_FONTDATA
->m_encoding
);
452 M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font
);
455 // it's quite useless to make it a wxCHECK because we're going to crash
457 wxASSERT_MSG( font
, wxT("could not load any font?") );