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 wxFontRefData( const wxFontRefData
& data
);
52 virtual ~wxFontRefData();
55 // common part of all ctors
56 void Init(int pointSize
,
61 const wxString
& faceName
,
62 wxFontEncoding encoding
);
65 wxList m_scaled_xfonts
;
72 wxFontEncoding m_encoding
;
74 wxNativeFontInfo m_nativeFontInfo
;
79 // ============================================================================
81 // ============================================================================
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 void wxFontRefData::Init(int pointSize
,
92 const wxString
& faceName
,
93 wxFontEncoding encoding
)
95 if (family
== wxDEFAULT
)
100 m_faceName
= faceName
;
102 if (style
== wxDEFAULT
)
107 if (weight
== wxDEFAULT
)
112 if (pointSize
== wxDEFAULT
)
115 m_pointSize
= pointSize
;
117 m_underlined
= underlined
;
118 m_encoding
= encoding
;
121 wxFontRefData::wxFontRefData( const wxFontRefData
& data
)
122 : m_scaled_xfonts(wxKEY_INTEGER
)
124 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
125 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
128 wxFontRefData::wxFontRefData(int size
, int family
, int style
,
129 int weight
, bool underlined
,
130 const wxString
& faceName
,
131 wxFontEncoding encoding
)
132 : m_scaled_xfonts(wxKEY_INTEGER
)
134 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
137 wxFontRefData::~wxFontRefData()
139 wxNode
*node
= m_scaled_xfonts
.First();
142 GdkFont
*font
= (GdkFont
*)node
->Data();
143 wxNode
*next
= node
->Next();
144 gdk_font_unref( font
);
149 // ----------------------------------------------------------------------------
151 // ----------------------------------------------------------------------------
153 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
159 wxFont::wxFont(const wxNativeFontInfo
& info
)
163 Create(info
.xFontName
);
166 bool wxFont::Create(const wxNativeFontInfo
& info
)
168 return Create(info
.xFontName
);
171 bool wxFont::Create( int pointSize
,
176 const wxString
& face
,
177 wxFontEncoding encoding
)
179 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
180 underlined
, face
, encoding
);
185 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
189 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
193 m_refData
= new wxFontRefData();
195 M_FONTDATA
->m_nativeFontInfo
.xFontName
= fontname
; // X font name
199 wxStringTokenizer
tn( fontname
, wxT("-") );
201 tn
.GetNextToken(); // skip initial empty token
202 tn
.GetNextToken(); // foundry
205 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
207 tmp
= tn
.GetNextToken().MakeUpper(); // weight
208 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
209 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
210 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
211 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
212 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
214 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
215 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
217 tmp
= tn
.GetNextToken().MakeUpper(); // slant
218 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
219 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
221 tn
.GetNextToken(); // set width
222 tn
.GetNextToken(); // add. style
223 tn
.GetNextToken(); // pixel size
225 tmp
= tn
.GetNextToken(); // pointsize
228 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
229 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
232 tn
.GetNextToken(); // x-res
233 tn
.GetNextToken(); // y-res
235 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
238 M_FONTDATA
->m_family
= wxMODERN
;
239 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
240 M_FONTDATA
->m_family
= wxROMAN
;
241 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
242 M_FONTDATA
->m_family
= wxSWISS
;
243 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
244 M_FONTDATA
->m_family
= wxTELETYPE
;
245 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
246 M_FONTDATA
->m_family
= wxDECORATIVE
;
247 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
248 M_FONTDATA
->m_family
= wxSCRIPT
;
250 tn
.GetNextToken(); // avg width
252 // deal with font encoding
253 M_FONTDATA
->m_encoding
= enc
;
254 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
256 wxString registry
= tn
.GetNextToken().MakeUpper(),
257 encoding
= tn
.GetNextToken().MakeUpper();
259 if ( registry
== _T("ISO8859") )
262 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
264 M_FONTDATA
->m_encoding
=
265 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
268 else if ( registry
== _T("MICROSOFT") )
271 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
273 M_FONTDATA
->m_encoding
=
274 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
277 else if ( registry
== _T("KOI8") )
279 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
281 //else: unknown encoding - may be give a warning here?
288 void wxFont::Unshare()
292 m_refData
= new wxFontRefData();
296 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
306 // ----------------------------------------------------------------------------
308 // ----------------------------------------------------------------------------
310 bool wxFont::HasNativeFont() const
312 return !M_FONTDATA
->m_nativeFontInfo
.xFontName
.empty();
315 int wxFont::GetPointSize() const
317 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
319 return M_FONTDATA
->m_pointSize
;
322 wxString
wxFont::GetFaceName() const
324 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
326 return M_FONTDATA
->m_faceName
;
329 int wxFont::GetFamily() const
331 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
333 return M_FONTDATA
->m_family
;
336 int wxFont::GetStyle() const
338 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
340 return M_FONTDATA
->m_style
;
343 int wxFont::GetWeight() const
345 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
347 return M_FONTDATA
->m_weight
;
350 bool wxFont::GetUnderlined() const
352 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
354 return M_FONTDATA
->m_underlined
;
358 wxFontEncoding
wxFont::GetEncoding() const
360 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
362 return M_FONTDATA
->m_encoding
;
365 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
367 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
369 if(M_FONTDATA
->m_nativeFontInfo
.xFontName
.IsEmpty())
372 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);
375 bool wxFont::IsFixedWidth() const
377 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
379 if ( HasNativeFont() )
381 // the monospace fonts are supposed to have "M" in the spacing field
382 wxString spacing
= M_FONTDATA
->
383 m_nativeFontInfo
.GetXFontComponent(wxXLFD_SPACING
);
385 return spacing
.Upper() == _T('M');
388 return wxFontBase::IsFixedWidth();
391 // ----------------------------------------------------------------------------
392 // change font attributes
393 // ----------------------------------------------------------------------------
395 void wxFont::SetPointSize(int pointSize
)
399 M_FONTDATA
->m_pointSize
= pointSize
;
400 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
403 void wxFont::SetFamily(int family
)
407 M_FONTDATA
->m_family
= family
;
408 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
411 void wxFont::SetStyle(int style
)
415 M_FONTDATA
->m_style
= style
;
416 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
419 void wxFont::SetWeight(int weight
)
423 M_FONTDATA
->m_weight
= weight
;
424 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
427 void wxFont::SetFaceName(const wxString
& faceName
)
431 M_FONTDATA
->m_faceName
= faceName
;
432 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
435 void wxFont::SetUnderlined(bool underlined
)
439 M_FONTDATA
->m_underlined
= underlined
;
442 void wxFont::SetEncoding(wxFontEncoding encoding
)
446 M_FONTDATA
->m_encoding
= encoding
;
447 M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear(); // invalid now
450 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
454 M_FONTDATA
->m_nativeFontInfo
= info
;
457 // ----------------------------------------------------------------------------
458 // get internal representation of font
459 // ----------------------------------------------------------------------------
461 static GdkFont
*g_systemDefaultGuiFont
= (GdkFont
*) NULL
;
463 GdkFont
*GtkGetDefaultGuiFont()
465 if (!g_systemDefaultGuiFont
)
467 GtkWidget
*widget
= gtk_button_new();
468 GtkStyle
*def
= gtk_rc_get_style( widget
);
471 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
475 def
= gtk_widget_get_default_style();
477 g_systemDefaultGuiFont
= gdk_font_ref( def
->font
);
479 gtk_widget_destroy( widget
);
483 // already have it, but ref it once more before returning
484 gdk_font_ref(g_systemDefaultGuiFont
);
487 return g_systemDefaultGuiFont
;
490 GdkFont
*wxFont::GetInternalFont( float scale
) const
494 wxFAIL_MSG( wxT("invalid font") );
496 return (GdkFont
*) NULL
;
499 long int_scale
= long(scale
* 100.0 + 0.5); /* key for fontlist */
500 int point_scale
= (int)((M_FONTDATA
->m_pointSize
* 10 * int_scale
) / 100);
501 GdkFont
*font
= (GdkFont
*) NULL
;
503 wxNode
*node
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
);
506 font
= (GdkFont
*)node
->Data();
510 if (*this == wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
))
512 font
= GtkGetDefaultGuiFont();
516 font
= wxLoadQueryNearestFont( point_scale
,
517 M_FONTDATA
->m_family
,
519 M_FONTDATA
->m_weight
,
520 M_FONTDATA
->m_underlined
,
521 M_FONTDATA
->m_faceName
,
522 M_FONTDATA
->m_encoding
,
523 &M_FONTDATA
->m_nativeFontInfo
.xFontName
);
526 M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font
);
529 // it's quite useless to make it a wxCHECK because we're going to crash
531 wxASSERT_MSG( font
, wxT("could not load any font?") );