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 // ----------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "font.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
30 #pragma message disable nosimpint
31 #include "wx/vms_x_fix.h"
35 #pragma message enable nosimpint
38 #include "wx/string.h"
40 #include "wx/gdicmn.h"
41 #include "wx/utils.h" // for wxGetDisplay()
42 #include "wx/fontutil.h" // for wxNativeFontInfo
43 #include "wx/tokenzr.h"
44 #include "wx/settings.h"
45 #include "wx/motif/private.h"
47 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 // For every wxFont, there must be a font for each display and scale requested.
54 // So these objects are stored in wxFontRefData::m_fonts
55 class wxXFont
: public wxObject
61 WXFontStructPtr m_fontStruct
; // XFontStruct
62 WXFontList m_fontList
; // Motif XmFontList
63 #if wxCHECK_MOTIF_VERSION( 2, 0 )
64 WXRenderTable m_renderTable
; // Motif XmRenderTable
66 WXDisplay
* m_display
; // XDisplay
67 int m_scale
; // Scale * 100
70 class wxFontRefData
: public wxGDIRefData
75 wxFontRefData(int size
= wxDEFAULT
,
76 int family
= wxDEFAULT
,
77 int style
= wxDEFAULT
,
78 int weight
= wxDEFAULT
,
79 bool underlined
= false,
80 const wxString
& faceName
= wxEmptyString
,
81 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
83 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
86 wxFontRefData(const wxFontRefData
& data
)
88 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
89 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
95 // common part of all ctors
101 const wxString
& faceName
,
102 wxFontEncoding encoding
);
111 wxFontEncoding m_encoding
;
113 wxNativeFontInfo m_nativeFontInfo
;
115 // A list of wxXFonts
119 // ============================================================================
121 // ============================================================================
123 // ----------------------------------------------------------------------------
125 // ----------------------------------------------------------------------------
129 m_fontStruct
= (WXFontStructPtr
) 0;
130 m_fontList
= (WXFontList
) 0;
131 #if wxCHECK_MOTIF_VERSION( 2, 0 )
132 m_renderTable
= (WXRenderTable
) 0;
134 m_display
= (WXDisplay
*) 0;
140 XmFontList fontList
= (XmFontList
) m_fontList
;
141 XmFontListFree (fontList
);
143 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
144 XmRenderTable renderTable
= (XmRenderTable
) m_renderTable
;
145 XmRenderTableFree (renderTable
);
148 // TODO: why does freeing the font produce a segv???
149 // Note that XFreeFont wasn't called in wxWin 1.68 either.
150 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
151 // XFreeFont((Display*) m_display, fontStruct);
154 // ----------------------------------------------------------------------------
156 // ----------------------------------------------------------------------------
158 void wxFontRefData::Init(int pointSize
,
163 const wxString
& faceName
,
164 wxFontEncoding encoding
)
166 if (family
== wxDEFAULT
)
171 m_faceName
= faceName
;
173 if (style
== wxDEFAULT
)
178 if (weight
== wxDEFAULT
)
183 if (pointSize
== wxDEFAULT
)
186 m_pointSize
= pointSize
;
188 m_underlined
= underlined
;
189 m_encoding
= encoding
;
192 wxFontRefData::~wxFontRefData()
194 wxList::compatibility_iterator node
= m_fonts
.GetFirst();
197 wxXFont
* f
= (wxXFont
*) node
->GetData();
199 node
= node
->GetNext();
204 // ----------------------------------------------------------------------------
206 // ----------------------------------------------------------------------------
208 wxFont::wxFont(const wxNativeFontInfo
& info
)
212 (void)Create(info
.GetXFontName());
219 bool wxFont::Create(int pointSize
,
224 const wxString
& faceName
,
225 wxFontEncoding encoding
)
228 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
229 underlined
, faceName
, encoding
);
236 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
240 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
244 m_refData
= new wxFontRefData();
246 M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
); // X font name
250 wxStringTokenizer
tn( fontname
, wxT("-") );
252 tn
.GetNextToken(); // skip initial empty token
253 tn
.GetNextToken(); // foundry
256 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
258 tmp
= tn
.GetNextToken().MakeUpper(); // weight
259 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
260 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
261 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
262 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
263 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
265 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
266 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
268 tmp
= tn
.GetNextToken().MakeUpper(); // slant
269 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
270 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
272 tn
.GetNextToken(); // set width
273 tn
.GetNextToken(); // add. style
274 tn
.GetNextToken(); // pixel size
276 tmp
= tn
.GetNextToken(); // pointsize
279 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
280 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
283 tn
.GetNextToken(); // x-res
284 tn
.GetNextToken(); // y-res
286 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
289 M_FONTDATA
->m_family
= wxMODERN
;
290 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
291 M_FONTDATA
->m_family
= wxROMAN
;
292 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
293 M_FONTDATA
->m_family
= wxSWISS
;
294 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
295 M_FONTDATA
->m_family
= wxTELETYPE
;
296 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
297 M_FONTDATA
->m_family
= wxDECORATIVE
;
298 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
299 M_FONTDATA
->m_family
= wxSCRIPT
;
301 tn
.GetNextToken(); // avg width
303 // deal with font encoding
304 M_FONTDATA
->m_encoding
= enc
;
305 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
307 wxString registry
= tn
.GetNextToken().MakeUpper(),
308 encoding
= tn
.GetNextToken().MakeUpper();
310 if ( registry
== _T("ISO8859") )
313 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
315 M_FONTDATA
->m_encoding
=
316 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
319 else if ( registry
== _T("MICROSOFT") )
322 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
324 M_FONTDATA
->m_encoding
=
325 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
328 else if ( registry
== _T("KOI8") )
330 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
332 //else: unknown encoding - may be give a warning here?
343 // ----------------------------------------------------------------------------
344 // change the font attributes
345 // ----------------------------------------------------------------------------
347 void wxFont::Unshare()
349 // Don't change shared data
352 m_refData
= new wxFontRefData();
356 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
362 void wxFont::SetPointSize(int pointSize
)
366 M_FONTDATA
->m_pointSize
= pointSize
;
367 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
372 void wxFont::SetFamily(int family
)
376 M_FONTDATA
->m_family
= family
;
377 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
382 void wxFont::SetStyle(int style
)
386 M_FONTDATA
->m_style
= style
;
387 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
392 void wxFont::SetWeight(int weight
)
396 M_FONTDATA
->m_weight
= weight
;
397 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
402 void wxFont::SetFaceName(const wxString
& faceName
)
406 M_FONTDATA
->m_faceName
= faceName
;
407 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
412 void wxFont::SetUnderlined(bool underlined
)
416 M_FONTDATA
->m_underlined
= underlined
;
421 void wxFont::SetEncoding(wxFontEncoding encoding
)
425 M_FONTDATA
->m_encoding
= encoding
;
426 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
431 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
435 M_FONTDATA
->m_nativeFontInfo
= info
;
438 // ----------------------------------------------------------------------------
439 // query font attributes
440 // ----------------------------------------------------------------------------
442 int wxFont::GetPointSize() const
444 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
446 return M_FONTDATA
->m_pointSize
;
449 wxString
wxFont::GetFaceName() const
451 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
453 return M_FONTDATA
->m_faceName
;
456 int wxFont::GetFamily() const
458 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
460 return M_FONTDATA
->m_family
;
463 int wxFont::GetStyle() const
465 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
467 return M_FONTDATA
->m_style
;
470 int wxFont::GetWeight() const
472 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
474 return M_FONTDATA
->m_weight
;
477 bool wxFont::GetUnderlined() const
479 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
481 return M_FONTDATA
->m_underlined
;
484 wxFontEncoding
wxFont::GetEncoding() const
486 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
488 return M_FONTDATA
->m_encoding
;
491 const wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
493 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
495 if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty())
498 return &(M_FONTDATA
->m_nativeFontInfo
);
501 // ----------------------------------------------------------------------------
502 // real implementation
503 // ----------------------------------------------------------------------------
505 // Find an existing, or create a new, XFontStruct
506 // based on this wxFont and the given scale. Append the
507 // font to list in the private data for future reference.
508 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
511 return (wxXFont
*)NULL
;
513 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
514 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
516 // search existing fonts first
517 wxList::compatibility_iterator node
= M_FONTDATA
->m_fonts
.GetFirst();
520 wxXFont
* f
= (wxXFont
*) node
->GetData();
521 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
523 node
= node
->GetNext();
526 // not found, create a new one
527 XFontStruct
*font
= (XFontStruct
*)
528 wxLoadQueryNearestFont(pointSize
,
529 M_FONTDATA
->m_family
,
531 M_FONTDATA
->m_weight
,
532 M_FONTDATA
->m_underlined
,
534 M_FONTDATA
->m_encoding
);
538 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
540 return (wxXFont
*) NULL
;
543 wxXFont
* f
= new wxXFont
;
544 f
->m_fontStruct
= (WXFontStructPtr
)font
;
545 f
->m_display
= ( display
? display
: wxGetDisplay() );
546 f
->m_scale
= intScale
;
547 f
->m_fontList
= XmFontListCreate ((XFontStruct
*) font
, XmSTRING_DEFAULT_CHARSET
);
548 M_FONTDATA
->m_fonts
.Append(f
);
550 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
551 XmRendition rendition
;
552 XmRenderTable renderTable
;
556 XtSetArg( args
[count
], XmNfont
, font
); ++count
;
557 XtSetArg( args
[count
], XmNunderlineType
,
558 GetUnderlined() ? XmSINGLE_LINE
: XmNO_LINE
); ++count
;
559 rendition
= XmRenditionCreate( XmGetXmDisplay( (Display
*)f
->m_display
),
562 renderTable
= XmRenderTableAddRenditions( NULL
, &rendition
, 1,
565 f
->m_renderTable
= (WXRenderTable
)renderTable
;
571 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
573 wxXFont
* f
= GetInternalFont(scale
, display
);
575 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);
578 WXFontList
wxFont::GetFontList(double scale
, WXDisplay
* display
) const
580 wxXFont
* f
= GetInternalFont(scale
, display
);
582 return (f
? f
->m_fontList
: (WXFontList
) 0);
585 #if wxCHECK_MOTIF_VERSION( 2, 0 )
587 WXRenderTable
wxFont::GetRenderTable(WXDisplay
* display
) const
589 wxXFont
* f
= GetInternalFont(1.0, display
);
591 return (f
? f
->m_renderTable
: (WXFontList
) 0);
596 WXFontType
wxFont::GetFontType(WXDisplay
* display
) const
598 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
599 return Ok() ? GetRenderTable(display
) : NULL
;
601 return Ok() ? GetFontList(1.0, display
) : NULL
;
605 /*static*/ WXString
wxFont::GetFontTag()
607 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
608 return (WXString
)XmNrenderTable
;
610 return (WXString
)XmNfontList
;