1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/font.cpp
3 // Purpose: wxFont class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "font.h"
25 #pragma message disable nosimpint
26 #include "wx/vms_x_fix.h"
30 #pragma message enable nosimpint
34 #include "wx/string.h"
36 #include "wx/gdicmn.h"
37 #include "wx/utils.h" // for wxGetDisplay()
38 #include "wx/fontutil.h" // for wxNativeFontInfo
39 #include "wx/tokenzr.h"
40 #include "wx/settings.h"
41 #include "wx/x11/private.h"
43 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 // For every wxFont, there must be a font for each display and scale requested.
50 // So these objects are stored in wxFontRefData::m_fonts
51 class wxXFont
: public wxObject
57 WXFontStructPtr m_fontStruct
; // XFontStruct
58 WXDisplay
* m_display
; // XDisplay
59 int m_scale
; // Scale * 100
62 class wxFontRefData
: public wxGDIRefData
67 wxFontRefData(int size
= wxDEFAULT
,
68 int family
= wxDEFAULT
,
69 int style
= wxDEFAULT
,
70 int weight
= wxDEFAULT
,
71 bool underlined
= FALSE
,
72 const wxString
& faceName
= wxEmptyString
,
73 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
75 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
78 wxFontRefData(const wxFontRefData
& data
)
80 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
81 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
87 // common part of all ctors
93 const wxString
& faceName
,
94 wxFontEncoding encoding
);
103 wxFontEncoding m_encoding
;
105 wxNativeFontInfo m_nativeFontInfo
;
107 // A list of wxXFonts
111 // ============================================================================
113 // ============================================================================
115 // ----------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------
121 m_fontStruct
= (WXFontStructPtr
) 0;
122 m_display
= (WXDisplay
*) 0;
128 // TODO: why does freeing the font produce a segv???
129 // Note that XFreeFont wasn't called in wxWin 1.68 either.
130 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
131 // XFreeFont((Display*) m_display, fontStruct);
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 void wxFontRefData::Init(int pointSize
,
143 const wxString
& faceName
,
144 wxFontEncoding encoding
)
146 if (family
== wxDEFAULT
)
151 m_faceName
= faceName
;
153 if (style
== wxDEFAULT
)
158 if (weight
== wxDEFAULT
)
163 if (pointSize
== wxDEFAULT
)
166 m_pointSize
= pointSize
;
168 m_underlined
= underlined
;
169 m_encoding
= encoding
;
172 wxFontRefData::~wxFontRefData()
174 wxNode
* node
= m_fonts
.First();
177 wxXFont
* f
= (wxXFont
*) node
->Data();
184 // ----------------------------------------------------------------------------
186 // ----------------------------------------------------------------------------
188 wxFont::wxFont(const wxNativeFontInfo
& info
)
192 (void)Create(info
.GetXFontName());
199 bool wxFont::Create(int pointSize
,
204 const wxString
& faceName
,
205 wxFontEncoding encoding
)
208 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
209 underlined
, faceName
, encoding
);
216 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
220 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
224 m_refData
= new wxFontRefData();
226 M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
); // X font name
230 wxStringTokenizer
tn( fontname
, wxT("-") );
232 tn
.GetNextToken(); // skip initial empty token
233 tn
.GetNextToken(); // foundry
236 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
238 tmp
= tn
.GetNextToken().MakeUpper(); // weight
239 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
240 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
241 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
242 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
243 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
245 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
246 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
248 tmp
= tn
.GetNextToken().MakeUpper(); // slant
249 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
250 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
252 tn
.GetNextToken(); // set width
253 tn
.GetNextToken(); // add. style
254 tn
.GetNextToken(); // pixel size
256 tmp
= tn
.GetNextToken(); // pointsize
259 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
260 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
263 tn
.GetNextToken(); // x-res
264 tn
.GetNextToken(); // y-res
266 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
269 M_FONTDATA
->m_family
= wxMODERN
;
270 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
271 M_FONTDATA
->m_family
= wxROMAN
;
272 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
273 M_FONTDATA
->m_family
= wxSWISS
;
274 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
275 M_FONTDATA
->m_family
= wxTELETYPE
;
276 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
277 M_FONTDATA
->m_family
= wxDECORATIVE
;
278 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
279 M_FONTDATA
->m_family
= wxSCRIPT
;
281 tn
.GetNextToken(); // avg width
283 // deal with font encoding
284 M_FONTDATA
->m_encoding
= enc
;
285 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
287 wxString registry
= tn
.GetNextToken().MakeUpper(),
288 encoding
= tn
.GetNextToken().MakeUpper();
290 if ( registry
== _T("ISO8859") )
293 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
295 M_FONTDATA
->m_encoding
=
296 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
299 else if ( registry
== _T("MICROSOFT") )
302 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
304 M_FONTDATA
->m_encoding
=
305 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
308 else if ( registry
== _T("KOI8") )
310 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
312 //else: unknown encoding - may be give a warning here?
323 // ----------------------------------------------------------------------------
324 // change the font attributes
325 // ----------------------------------------------------------------------------
327 void wxFont::Unshare()
329 // Don't change shared data
332 m_refData
= new wxFontRefData();
336 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
342 void wxFont::SetPointSize(int pointSize
)
346 M_FONTDATA
->m_pointSize
= pointSize
;
347 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
352 void wxFont::SetFamily(int family
)
356 M_FONTDATA
->m_family
= family
;
357 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
362 void wxFont::SetStyle(int style
)
366 M_FONTDATA
->m_style
= style
;
367 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
372 void wxFont::SetWeight(int weight
)
376 M_FONTDATA
->m_weight
= weight
;
377 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
382 void wxFont::SetFaceName(const wxString
& faceName
)
386 M_FONTDATA
->m_faceName
= faceName
;
387 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
392 void wxFont::SetUnderlined(bool underlined
)
396 M_FONTDATA
->m_underlined
= underlined
;
401 void wxFont::SetEncoding(wxFontEncoding encoding
)
405 M_FONTDATA
->m_encoding
= encoding
;
406 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
411 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
415 M_FONTDATA
->m_nativeFontInfo
= info
;
418 // ----------------------------------------------------------------------------
419 // query font attributes
420 // ----------------------------------------------------------------------------
422 int wxFont::GetPointSize() const
424 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
426 return M_FONTDATA
->m_pointSize
;
429 wxString
wxFont::GetFaceName() const
431 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
433 return M_FONTDATA
->m_faceName
;
436 int wxFont::GetFamily() const
438 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
440 return M_FONTDATA
->m_family
;
443 int wxFont::GetStyle() const
445 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
447 return M_FONTDATA
->m_style
;
450 int wxFont::GetWeight() const
452 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
454 return M_FONTDATA
->m_weight
;
457 bool wxFont::GetUnderlined() const
459 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
461 return M_FONTDATA
->m_underlined
;
464 wxFontEncoding
wxFont::GetEncoding() const
466 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
468 return M_FONTDATA
->m_encoding
;
471 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
473 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
475 if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty())
478 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);
481 // ----------------------------------------------------------------------------
482 // real implementation
483 // ----------------------------------------------------------------------------
485 // Find an existing, or create a new, XFontStruct
486 // based on this wxFont and the given scale. Append the
487 // font to list in the private data for future reference.
488 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
491 return (wxXFont
*)NULL
;
493 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
494 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
496 // search existing fonts first
497 wxNode
* node
= M_FONTDATA
->m_fonts
.First();
500 wxXFont
* f
= (wxXFont
*) node
->Data();
501 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
506 // not found, create a new one
507 XFontStruct
*font
= (XFontStruct
*)
508 wxLoadQueryNearestFont(pointSize
,
509 M_FONTDATA
->m_family
,
511 M_FONTDATA
->m_weight
,
512 M_FONTDATA
->m_underlined
,
514 M_FONTDATA
->m_encoding
);
518 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
520 return (wxXFont
*) NULL
;
523 wxXFont
* f
= new wxXFont
;
524 f
->m_fontStruct
= (WXFontStructPtr
)font
;
525 f
->m_display
= ( display
? display
: wxGetDisplay() );
526 f
->m_scale
= intScale
;
527 M_FONTDATA
->m_fonts
.Append(f
);
532 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
534 wxXFont
* f
= GetInternalFont(scale
, display
);
536 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);