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"
42 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // For every wxFont, there must be a font for each display and scale requested.
49 // So these objects are stored in wxFontRefData::m_fonts
50 class wxXFont
: public wxObject
56 WXFontStructPtr m_fontStruct
; // XFontStruct
57 WXDisplay
* m_display
; // XDisplay
58 int m_scale
; // Scale * 100
61 class wxFontRefData
: public wxGDIRefData
66 wxFontRefData(int size
= wxDEFAULT
,
67 int family
= wxDEFAULT
,
68 int style
= wxDEFAULT
,
69 int weight
= wxDEFAULT
,
70 bool underlined
= FALSE
,
71 const wxString
& faceName
= wxEmptyString
,
72 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
74 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
77 wxFontRefData(const wxFontRefData
& data
)
79 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
80 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
86 // common part of all ctors
92 const wxString
& faceName
,
93 wxFontEncoding encoding
);
102 wxFontEncoding m_encoding
;
104 wxNativeFontInfo m_nativeFontInfo
;
106 // A list of wxXFonts
110 // ============================================================================
112 // ============================================================================
114 // ----------------------------------------------------------------------------
116 // ----------------------------------------------------------------------------
120 m_fontStruct
= (WXFontStructPtr
) 0;
121 m_display
= (WXDisplay
*) 0;
127 // TODO: why does freeing the font produce a segv???
128 // Note that XFreeFont wasn't called in wxWin 1.68 either.
129 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
130 // XFreeFont((Display*) m_display, fontStruct);
133 // ----------------------------------------------------------------------------
135 // ----------------------------------------------------------------------------
137 void wxFontRefData::Init(int pointSize
,
142 const wxString
& faceName
,
143 wxFontEncoding encoding
)
145 if (family
== wxDEFAULT
)
150 m_faceName
= faceName
;
152 if (style
== wxDEFAULT
)
157 if (weight
== wxDEFAULT
)
162 if (pointSize
== wxDEFAULT
)
165 m_pointSize
= pointSize
;
167 m_underlined
= underlined
;
168 m_encoding
= encoding
;
171 wxFontRefData::~wxFontRefData()
173 wxNode
* node
= m_fonts
.First();
176 wxXFont
* f
= (wxXFont
*) node
->Data();
183 // ----------------------------------------------------------------------------
185 // ----------------------------------------------------------------------------
187 wxFont::wxFont(const wxNativeFontInfo
& info
)
191 (void)Create(info
.GetXFontName());
198 bool wxFont::Create(int pointSize
,
203 const wxString
& faceName
,
204 wxFontEncoding encoding
)
207 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
208 underlined
, faceName
, encoding
);
215 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
219 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
223 m_refData
= new wxFontRefData();
225 M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
); // X font name
229 wxStringTokenizer
tn( fontname
, wxT("-") );
231 tn
.GetNextToken(); // skip initial empty token
232 tn
.GetNextToken(); // foundry
235 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
237 tmp
= tn
.GetNextToken().MakeUpper(); // weight
238 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
239 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
240 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
241 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
242 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
244 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
245 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
247 tmp
= tn
.GetNextToken().MakeUpper(); // slant
248 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
249 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
251 tn
.GetNextToken(); // set width
252 tn
.GetNextToken(); // add. style
253 tn
.GetNextToken(); // pixel size
255 tmp
= tn
.GetNextToken(); // pointsize
258 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
259 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
262 tn
.GetNextToken(); // x-res
263 tn
.GetNextToken(); // y-res
265 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
268 M_FONTDATA
->m_family
= wxMODERN
;
269 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
270 M_FONTDATA
->m_family
= wxROMAN
;
271 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
272 M_FONTDATA
->m_family
= wxSWISS
;
273 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
274 M_FONTDATA
->m_family
= wxTELETYPE
;
275 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
276 M_FONTDATA
->m_family
= wxDECORATIVE
;
277 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
278 M_FONTDATA
->m_family
= wxSCRIPT
;
280 tn
.GetNextToken(); // avg width
282 // deal with font encoding
283 M_FONTDATA
->m_encoding
= enc
;
284 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
286 wxString registry
= tn
.GetNextToken().MakeUpper(),
287 encoding
= tn
.GetNextToken().MakeUpper();
289 if ( registry
== _T("ISO8859") )
292 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
294 M_FONTDATA
->m_encoding
=
295 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
298 else if ( registry
== _T("MICROSOFT") )
301 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
303 M_FONTDATA
->m_encoding
=
304 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
307 else if ( registry
== _T("KOI8") )
309 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
311 //else: unknown encoding - may be give a warning here?
322 // ----------------------------------------------------------------------------
323 // change the font attributes
324 // ----------------------------------------------------------------------------
326 void wxFont::Unshare()
328 // Don't change shared data
331 m_refData
= new wxFontRefData();
335 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
341 void wxFont::SetPointSize(int pointSize
)
345 M_FONTDATA
->m_pointSize
= pointSize
;
346 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
351 void wxFont::SetFamily(int family
)
355 M_FONTDATA
->m_family
= family
;
356 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
361 void wxFont::SetStyle(int style
)
365 M_FONTDATA
->m_style
= style
;
366 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
371 void wxFont::SetWeight(int weight
)
375 M_FONTDATA
->m_weight
= weight
;
376 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
381 void wxFont::SetFaceName(const wxString
& faceName
)
385 M_FONTDATA
->m_faceName
= faceName
;
386 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
391 void wxFont::SetUnderlined(bool underlined
)
395 M_FONTDATA
->m_underlined
= underlined
;
400 void wxFont::SetEncoding(wxFontEncoding encoding
)
404 M_FONTDATA
->m_encoding
= encoding
;
405 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
410 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
414 M_FONTDATA
->m_nativeFontInfo
= info
;
417 // ----------------------------------------------------------------------------
418 // query font attributes
419 // ----------------------------------------------------------------------------
421 int wxFont::GetPointSize() const
423 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
425 return M_FONTDATA
->m_pointSize
;
428 wxString
wxFont::GetFaceName() const
430 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
432 return M_FONTDATA
->m_faceName
;
435 int wxFont::GetFamily() const
437 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
439 return M_FONTDATA
->m_family
;
442 int wxFont::GetStyle() const
444 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
446 return M_FONTDATA
->m_style
;
449 int wxFont::GetWeight() const
451 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
453 return M_FONTDATA
->m_weight
;
456 bool wxFont::GetUnderlined() const
458 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
460 return M_FONTDATA
->m_underlined
;
463 wxFontEncoding
wxFont::GetEncoding() const
465 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
467 return M_FONTDATA
->m_encoding
;
470 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
472 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
474 if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty())
477 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);
480 // ----------------------------------------------------------------------------
481 // real implementation
482 // ----------------------------------------------------------------------------
484 // Find an existing, or create a new, XFontStruct
485 // based on this wxFont and the given scale. Append the
486 // font to list in the private data for future reference.
487 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
490 return (wxXFont
*)NULL
;
492 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
493 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
495 // search existing fonts first
496 wxNode
* node
= M_FONTDATA
->m_fonts
.First();
499 wxXFont
* f
= (wxXFont
*) node
->Data();
500 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
505 // not found, create a new one
506 XFontStruct
*font
= (XFontStruct
*)
507 wxLoadQueryNearestFont(pointSize
,
508 M_FONTDATA
->m_family
,
510 M_FONTDATA
->m_weight
,
511 M_FONTDATA
->m_underlined
,
513 M_FONTDATA
->m_encoding
);
517 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
519 return (wxXFont
*) NULL
;
522 wxXFont
* f
= new wxXFont
;
523 f
->m_fontStruct
= (WXFontStructPtr
)font
;
524 f
->m_display
= ( display
? display
: wxGetDisplay() );
525 f
->m_scale
= intScale
;
526 M_FONTDATA
->m_fonts
.Append(f
);
531 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
533 wxXFont
* f
= GetInternalFont(scale
, display
);
535 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);