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"
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 class wxFontRefData
: public wxObjectRefData
41 wxFontRefData(int size
= wxDEFAULT
,
42 int family
= wxDEFAULT
,
43 int style
= wxDEFAULT
,
44 int weight
= wxDEFAULT
,
45 bool underlined
= FALSE
,
46 const wxString
& faceName
= wxEmptyString
,
47 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
);
48 wxFontRefData( const wxFontRefData
& data
);
49 virtual ~wxFontRefData();
52 // common part of all ctors
53 void Init(int pointSize
,
58 const wxString
& faceName
,
59 wxFontEncoding encoding
);
62 wxList m_scaled_xfonts
;
69 wxFontEncoding m_encoding
;
74 // ============================================================================
76 // ============================================================================
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 void wxFontRefData::Init(int pointSize
,
87 const wxString
& faceName
,
88 wxFontEncoding encoding
)
90 if (family
== wxDEFAULT
)
95 m_faceName
= faceName
;
97 if (style
== wxDEFAULT
)
102 if (weight
== wxDEFAULT
)
107 if (pointSize
== wxDEFAULT
)
110 m_pointSize
= pointSize
;
112 m_underlined
= underlined
;
113 m_encoding
= encoding
;
116 wxFontRefData::wxFontRefData( const wxFontRefData
& data
)
117 : m_scaled_xfonts(wxKEY_INTEGER
)
119 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
120 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
123 wxFontRefData::wxFontRefData(int size
, int family
, int style
,
124 int weight
, bool underlined
, const wxString
& faceName
, wxFontEncoding encoding
)
125 : m_scaled_xfonts(wxKEY_INTEGER
)
127 Init(size
, family
, style
, weight
,
128 underlined
, faceName
, encoding
);
131 wxFontRefData::~wxFontRefData()
133 wxNode
*node
= m_scaled_xfonts
.First();
136 GdkFont
*font
= (GdkFont
*)node
->Data();
137 wxNode
*next
= node
->Next();
138 gdk_font_unref( font
);
143 // ----------------------------------------------------------------------------
145 // ----------------------------------------------------------------------------
147 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
152 wxTheFontList
->Append( this );
155 wxFont::wxFont( const wxString
& fontname
, const wxFontData
& fontdata
)
159 wxCHECK_RET( !!fontname
, _T("invalid font spec") );
161 m_refData
= new wxFontRefData();
165 wxStringTokenizer
tn( fontname
, wxT("-") );
167 tn
.GetNextToken(); // foundry
169 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
171 tmp
= tn
.GetNextToken().MakeUpper(); // weight
172 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
173 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
174 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
175 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
176 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
178 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
179 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
181 tmp
= tn
.GetNextToken().MakeUpper(); // slant
182 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
183 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
185 tn
.GetNextToken(); // set width
186 tn
.GetNextToken(); // add. style
187 tn
.GetNextToken(); // pixel size
189 tmp
= tn
.GetNextToken(); // pointsize
190 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
191 M_FONTDATA
->m_pointSize
= num
/ 10;
193 tn
.GetNextToken(); // x-res
194 tn
.GetNextToken(); // y-res
196 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
199 M_FONTDATA
->m_family
= wxMODERN
;
200 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
201 M_FONTDATA
->m_family
= wxROMAN
;
202 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
203 M_FONTDATA
->m_family
= wxSWISS
;
204 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
205 M_FONTDATA
->m_family
= wxTELETYPE
;
206 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
207 M_FONTDATA
->m_family
= wxDECORATIVE
;
208 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
209 M_FONTDATA
->m_family
= wxSCRIPT
;
211 tn
.GetNextToken(); // avg width
213 // deal with font encoding
214 M_FONTDATA
->m_encoding
= fontdata
.GetEncoding();
215 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
217 wxString registry
= tn
.GetNextToken().MakeUpper(),
218 encoding
= tn
.GetNextToken().MakeUpper();
220 if ( registry
== _T("ISO8859") )
223 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
225 M_FONTDATA
->m_encoding
=
226 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
229 else if ( registry
== _T("MICROSOFT") )
232 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
234 M_FONTDATA
->m_encoding
=
235 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
238 else if ( registry
== _T("KOI8") )
240 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
242 //else: unknown encoding - may be give a warning here?
246 bool wxFont::Create( int pointSize
,
251 const wxString
& face
,
252 wxFontEncoding encoding
)
254 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
255 underlined
, face
, encoding
);
260 void wxFont::Unshare()
264 m_refData
= new wxFontRefData();
268 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
277 wxTheFontList
->DeleteObject( this );
280 // ----------------------------------------------------------------------------
282 // ----------------------------------------------------------------------------
284 int wxFont::GetPointSize() const
286 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
288 return M_FONTDATA
->m_pointSize
;
291 wxString
wxFont::GetFaceName() const
293 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
295 return M_FONTDATA
->m_faceName
;
298 int wxFont::GetFamily() const
300 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
302 return M_FONTDATA
->m_family
;
305 int wxFont::GetStyle() const
307 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
309 return M_FONTDATA
->m_style
;
312 int wxFont::GetWeight() const
314 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
316 return M_FONTDATA
->m_weight
;
319 bool wxFont::GetUnderlined() const
321 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
323 return M_FONTDATA
->m_underlined
;
327 wxFontEncoding
wxFont::GetEncoding() const
329 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
331 return M_FONTDATA
->m_encoding
;
334 // ----------------------------------------------------------------------------
335 // change font attributes
336 // ----------------------------------------------------------------------------
338 void wxFont::SetPointSize(int pointSize
)
342 M_FONTDATA
->m_pointSize
= pointSize
;
345 void wxFont::SetFamily(int family
)
349 M_FONTDATA
->m_family
= family
;
352 void wxFont::SetStyle(int style
)
356 M_FONTDATA
->m_style
= style
;
359 void wxFont::SetWeight(int weight
)
363 M_FONTDATA
->m_weight
= weight
;
366 void wxFont::SetFaceName(const wxString
& faceName
)
370 M_FONTDATA
->m_faceName
= faceName
;
373 void wxFont::SetUnderlined(bool underlined
)
377 M_FONTDATA
->m_underlined
= underlined
;
380 void wxFont::SetEncoding(wxFontEncoding encoding
)
384 M_FONTDATA
->m_encoding
= encoding
;
387 // ----------------------------------------------------------------------------
388 // get internal representation of font
389 // ----------------------------------------------------------------------------
391 GdkFont
*wxFont::GetInternalFont( float scale
) const
395 wxFAIL_MSG( wxT("invalid font") );
397 return (GdkFont
*) NULL
;
400 long int_scale
= long(scale
* 100.0 + 0.5); /* key for fontlist */
401 int point_scale
= (int)((M_FONTDATA
->m_pointSize
* 10 * int_scale
) / 100);
402 GdkFont
*font
= (GdkFont
*) NULL
;
404 wxNode
*node
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
);
407 font
= (GdkFont
*)node
->Data();
412 if ((int_scale
== 100) &&
413 (M_FONTDATA
->m_family
== wxSWISS
) &&
414 (M_FONTDATA
->m_style
== wxNORMAL
) &&
415 (M_FONTDATA
->m_pointSize
== 12) &&
416 (M_FONTDATA
->m_weight
== wxNORMAL
) &&
417 (M_FONTDATA
->m_underlined
== FALSE
))
419 font
= gdk_font_load( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
424 font
= wxLoadQueryNearestFont( point_scale
,
425 M_FONTDATA
->m_family
,
427 M_FONTDATA
->m_weight
,
428 M_FONTDATA
->m_underlined
,
429 M_FONTDATA
->m_faceName
,
430 M_FONTDATA
->m_encoding
);
433 M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font
);
436 // it's quite useless to make it a wxCHECK because we're going to crash
438 wxASSERT_MSG( font
, wxT("could not load any font?") );