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"
27 #pragma message disable nosimpint
28 #include "wx/vms_x_fix.h"
32 #pragma message enable nosimpint
35 #include "wx/string.h"
37 #include "wx/gdicmn.h"
38 #include "wx/utils.h" // for wxGetDisplay()
39 #include "wx/fontutil.h" // for wxNativeFontInfo
40 #include "wx/tokenzr.h"
41 #include "wx/settings.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 WXFontList m_fontList
; // Motif XmFontList
59 WXDisplay
* m_display
; // XDisplay
60 int m_scale
; // Scale * 100
63 class wxFontRefData
: public wxGDIRefData
68 wxFontRefData(int size
= wxDEFAULT
,
69 int family
= wxDEFAULT
,
70 int style
= wxDEFAULT
,
71 int weight
= wxDEFAULT
,
72 bool underlined
= FALSE
,
73 const wxString
& faceName
= wxEmptyString
,
74 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
76 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
79 wxFontRefData(const wxFontRefData
& data
)
81 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
82 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
88 // common part of all ctors
94 const wxString
& faceName
,
95 wxFontEncoding encoding
);
104 wxFontEncoding m_encoding
;
106 wxNativeFontInfo m_nativeFontInfo
;
108 // A list of wxXFonts
112 // ============================================================================
114 // ============================================================================
116 // ----------------------------------------------------------------------------
118 // ----------------------------------------------------------------------------
122 m_fontStruct
= (WXFontStructPtr
) 0;
123 m_fontList
= (WXFontList
) 0;
124 m_display
= (WXDisplay
*) 0;
130 XmFontList fontList
= (XmFontList
) m_fontList
;
132 XmFontListFree (fontList
);
134 // TODO: why does freeing the font produce a segv???
135 // Note that XFreeFont wasn't called in wxWin 1.68 either.
136 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
137 // XFreeFont((Display*) m_display, fontStruct);
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
144 void wxFontRefData::Init(int pointSize
,
149 const wxString
& faceName
,
150 wxFontEncoding encoding
)
152 if (family
== wxDEFAULT
)
157 m_faceName
= faceName
;
159 if (style
== wxDEFAULT
)
164 if (weight
== wxDEFAULT
)
169 if (pointSize
== wxDEFAULT
)
172 m_pointSize
= pointSize
;
174 m_underlined
= underlined
;
175 m_encoding
= encoding
;
178 wxFontRefData::~wxFontRefData()
180 wxNode
* node
= m_fonts
.First();
183 wxXFont
* f
= (wxXFont
*) node
->Data();
190 // ----------------------------------------------------------------------------
192 // ----------------------------------------------------------------------------
194 wxFont::wxFont(const wxNativeFontInfo
& info
)
198 (void)Create(info
.GetXFontName());
205 bool wxFont::Create(int pointSize
,
210 const wxString
& faceName
,
211 wxFontEncoding encoding
)
214 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
215 underlined
, faceName
, encoding
);
222 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
226 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
230 m_refData
= new wxFontRefData();
232 M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
); // X font name
236 wxStringTokenizer
tn( fontname
, wxT("-") );
238 tn
.GetNextToken(); // skip initial empty token
239 tn
.GetNextToken(); // foundry
242 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
244 tmp
= tn
.GetNextToken().MakeUpper(); // weight
245 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
246 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
247 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
248 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
249 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
251 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
252 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
254 tmp
= tn
.GetNextToken().MakeUpper(); // slant
255 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
256 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
258 tn
.GetNextToken(); // set width
259 tn
.GetNextToken(); // add. style
260 tn
.GetNextToken(); // pixel size
262 tmp
= tn
.GetNextToken(); // pointsize
265 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
266 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
269 tn
.GetNextToken(); // x-res
270 tn
.GetNextToken(); // y-res
272 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
275 M_FONTDATA
->m_family
= wxMODERN
;
276 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
277 M_FONTDATA
->m_family
= wxROMAN
;
278 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
279 M_FONTDATA
->m_family
= wxSWISS
;
280 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
281 M_FONTDATA
->m_family
= wxTELETYPE
;
282 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
283 M_FONTDATA
->m_family
= wxDECORATIVE
;
284 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
285 M_FONTDATA
->m_family
= wxSCRIPT
;
287 tn
.GetNextToken(); // avg width
289 // deal with font encoding
290 M_FONTDATA
->m_encoding
= enc
;
291 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
293 wxString registry
= tn
.GetNextToken().MakeUpper(),
294 encoding
= tn
.GetNextToken().MakeUpper();
296 if ( registry
== _T("ISO8859") )
299 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
301 M_FONTDATA
->m_encoding
=
302 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
305 else if ( registry
== _T("MICROSOFT") )
308 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
310 M_FONTDATA
->m_encoding
=
311 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
314 else if ( registry
== _T("KOI8") )
316 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
318 //else: unknown encoding - may be give a warning here?
329 // ----------------------------------------------------------------------------
330 // change the font attributes
331 // ----------------------------------------------------------------------------
333 void wxFont::Unshare()
335 // Don't change shared data
338 m_refData
= new wxFontRefData();
342 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
348 void wxFont::SetPointSize(int pointSize
)
352 M_FONTDATA
->m_pointSize
= pointSize
;
353 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
358 void wxFont::SetFamily(int family
)
362 M_FONTDATA
->m_family
= family
;
363 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
368 void wxFont::SetStyle(int style
)
372 M_FONTDATA
->m_style
= style
;
373 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
378 void wxFont::SetWeight(int weight
)
382 M_FONTDATA
->m_weight
= weight
;
383 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
388 void wxFont::SetFaceName(const wxString
& faceName
)
392 M_FONTDATA
->m_faceName
= faceName
;
393 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
398 void wxFont::SetUnderlined(bool underlined
)
402 M_FONTDATA
->m_underlined
= underlined
;
407 void wxFont::SetEncoding(wxFontEncoding encoding
)
411 M_FONTDATA
->m_encoding
= encoding
;
412 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
417 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
421 M_FONTDATA
->m_nativeFontInfo
= info
;
424 // ----------------------------------------------------------------------------
425 // query font attributes
426 // ----------------------------------------------------------------------------
428 int wxFont::GetPointSize() const
430 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
432 return M_FONTDATA
->m_pointSize
;
435 wxString
wxFont::GetFaceName() const
437 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
439 return M_FONTDATA
->m_faceName
;
442 int wxFont::GetFamily() const
444 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
446 return M_FONTDATA
->m_family
;
449 int wxFont::GetStyle() const
451 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
453 return M_FONTDATA
->m_style
;
456 int wxFont::GetWeight() const
458 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
460 return M_FONTDATA
->m_weight
;
463 bool wxFont::GetUnderlined() const
465 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
467 return M_FONTDATA
->m_underlined
;
470 wxFontEncoding
wxFont::GetEncoding() const
472 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
474 return M_FONTDATA
->m_encoding
;
477 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
479 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
481 if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty())
484 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);
487 // ----------------------------------------------------------------------------
488 // real implementation
489 // ----------------------------------------------------------------------------
491 // Find an existing, or create a new, XFontStruct
492 // based on this wxFont and the given scale. Append the
493 // font to list in the private data for future reference.
494 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
497 return (wxXFont
*)NULL
;
499 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
500 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
502 // search existing fonts first
503 wxNode
* node
= M_FONTDATA
->m_fonts
.First();
506 wxXFont
* f
= (wxXFont
*) node
->Data();
507 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
512 // not found, create a new one
513 XFontStruct
*font
= (XFontStruct
*)
514 wxLoadQueryNearestFont(pointSize
,
515 M_FONTDATA
->m_family
,
517 M_FONTDATA
->m_weight
,
518 M_FONTDATA
->m_underlined
,
520 M_FONTDATA
->m_encoding
);
524 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
526 return (wxXFont
*) NULL
;
529 wxXFont
* f
= new wxXFont
;
530 f
->m_fontStruct
= (WXFontStructPtr
)font
;
531 f
->m_display
= ( display
? display
: wxGetDisplay() );
532 f
->m_scale
= intScale
;
533 f
->m_fontList
= XmFontListCreate ((XFontStruct
*) font
, XmSTRING_DEFAULT_CHARSET
);
534 M_FONTDATA
->m_fonts
.Append(f
);
539 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
541 wxXFont
* f
= GetInternalFont(scale
, display
);
543 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);
546 WXFontList
wxFont::GetFontList(double scale
, WXDisplay
* display
) const
548 wxXFont
* f
= GetInternalFont(scale
, display
);
550 return (f
? f
->m_fontList
: (WXFontList
) 0);