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"
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"
42 #include "wx/motif/private.h"
44 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 // For every wxFont, there must be a font for each display and scale requested.
51 // So these objects are stored in wxFontRefData::m_fonts
52 class wxXFont
: public wxObject
58 WXFontStructPtr m_fontStruct
; // XFontStruct
59 WXFontList m_fontList
; // Motif XmFontList
60 #if wxCHECK_MOTIF_VERSION( 2, 0 )
61 WXRenderTable m_renderTable
; // Motif XmRenderTable
63 WXDisplay
* m_display
; // XDisplay
64 int m_scale
; // Scale * 100
67 class wxFontRefData
: public wxGDIRefData
72 wxFontRefData(int size
= wxDEFAULT
,
73 int family
= wxDEFAULT
,
74 int style
= wxDEFAULT
,
75 int weight
= wxDEFAULT
,
76 bool underlined
= FALSE
,
77 const wxString
& faceName
= wxEmptyString
,
78 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
80 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
83 wxFontRefData(const wxFontRefData
& data
)
85 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
86 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
92 // common part of all ctors
98 const wxString
& faceName
,
99 wxFontEncoding encoding
);
108 wxFontEncoding m_encoding
;
110 wxNativeFontInfo m_nativeFontInfo
;
112 // A list of wxXFonts
116 // ============================================================================
118 // ============================================================================
120 // ----------------------------------------------------------------------------
122 // ----------------------------------------------------------------------------
126 m_fontStruct
= (WXFontStructPtr
) 0;
127 m_fontList
= (WXFontList
) 0;
128 #if wxCHECK_MOTIF_VERSION( 2, 0 )
129 m_renderTable
= (WXRenderTable
) 0;
131 m_display
= (WXDisplay
*) 0;
137 XmFontList fontList
= (XmFontList
) m_fontList
;
138 XmFontListFree (fontList
);
140 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
141 XmRenderTable renderTable
= (XmRenderTable
) m_renderTable
;
142 XmRenderTableFree (renderTable
);
145 // TODO: why does freeing the font produce a segv???
146 // Note that XFreeFont wasn't called in wxWin 1.68 either.
147 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
148 // XFreeFont((Display*) m_display, fontStruct);
151 // ----------------------------------------------------------------------------
153 // ----------------------------------------------------------------------------
155 void wxFontRefData::Init(int pointSize
,
160 const wxString
& faceName
,
161 wxFontEncoding encoding
)
163 if (family
== wxDEFAULT
)
168 m_faceName
= faceName
;
170 if (style
== wxDEFAULT
)
175 if (weight
== wxDEFAULT
)
180 if (pointSize
== wxDEFAULT
)
183 m_pointSize
= pointSize
;
185 m_underlined
= underlined
;
186 m_encoding
= encoding
;
189 wxFontRefData::~wxFontRefData()
191 wxList::compatibility_iterator node
= m_fonts
.GetFirst();
194 wxXFont
* f
= (wxXFont
*) node
->GetData();
196 node
= node
->GetNext();
201 // ----------------------------------------------------------------------------
203 // ----------------------------------------------------------------------------
205 wxFont::wxFont(const wxNativeFontInfo
& info
)
209 (void)Create(info
.GetXFontName());
216 bool wxFont::Create(int pointSize
,
221 const wxString
& faceName
,
222 wxFontEncoding encoding
)
225 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
226 underlined
, faceName
, encoding
);
233 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
)
237 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
241 m_refData
= new wxFontRefData();
243 M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
); // X font name
247 wxStringTokenizer
tn( fontname
, wxT("-") );
249 tn
.GetNextToken(); // skip initial empty token
250 tn
.GetNextToken(); // foundry
253 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // family
255 tmp
= tn
.GetNextToken().MakeUpper(); // weight
256 if (tmp
== wxT("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
257 if (tmp
== wxT("BLACK")) M_FONTDATA
->m_weight
= wxBOLD
;
258 if (tmp
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
259 if (tmp
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
260 if (tmp
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
262 if (tmp
== wxT("LIGHT")) M_FONTDATA
->m_weight
= wxLIGHT
;
263 if (tmp
== wxT("THIN")) M_FONTDATA
->m_weight
= wxLIGHT
;
265 tmp
= tn
.GetNextToken().MakeUpper(); // slant
266 if (tmp
== wxT("I")) M_FONTDATA
->m_style
= wxITALIC
;
267 if (tmp
== wxT("O")) M_FONTDATA
->m_style
= wxITALIC
;
269 tn
.GetNextToken(); // set width
270 tn
.GetNextToken(); // add. style
271 tn
.GetNextToken(); // pixel size
273 tmp
= tn
.GetNextToken(); // pointsize
276 long num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
277 M_FONTDATA
->m_pointSize
= (int)(num
/ 10);
280 tn
.GetNextToken(); // x-res
281 tn
.GetNextToken(); // y-res
283 tmp
= tn
.GetNextToken().MakeUpper(); // spacing
286 M_FONTDATA
->m_family
= wxMODERN
;
287 else if (M_FONTDATA
->m_faceName
== wxT("TIMES"))
288 M_FONTDATA
->m_family
= wxROMAN
;
289 else if (M_FONTDATA
->m_faceName
== wxT("HELVETICA"))
290 M_FONTDATA
->m_family
= wxSWISS
;
291 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDATYPEWRITER"))
292 M_FONTDATA
->m_family
= wxTELETYPE
;
293 else if (M_FONTDATA
->m_faceName
== wxT("LUCIDA"))
294 M_FONTDATA
->m_family
= wxDECORATIVE
;
295 else if (M_FONTDATA
->m_faceName
== wxT("UTOPIA"))
296 M_FONTDATA
->m_family
= wxSCRIPT
;
298 tn
.GetNextToken(); // avg width
300 // deal with font encoding
301 M_FONTDATA
->m_encoding
= enc
;
302 if ( M_FONTDATA
->m_encoding
== wxFONTENCODING_SYSTEM
)
304 wxString registry
= tn
.GetNextToken().MakeUpper(),
305 encoding
= tn
.GetNextToken().MakeUpper();
307 if ( registry
== _T("ISO8859") )
310 if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 )
312 M_FONTDATA
->m_encoding
=
313 (wxFontEncoding
)(wxFONTENCODING_ISO8859_1
+ cp
- 1);
316 else if ( registry
== _T("MICROSOFT") )
319 if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 )
321 M_FONTDATA
->m_encoding
=
322 (wxFontEncoding
)(wxFONTENCODING_CP1250
+ cp
);
325 else if ( registry
== _T("KOI8") )
327 M_FONTDATA
->m_encoding
= wxFONTENCODING_KOI8
;
329 //else: unknown encoding - may be give a warning here?
340 // ----------------------------------------------------------------------------
341 // change the font attributes
342 // ----------------------------------------------------------------------------
344 void wxFont::Unshare()
346 // Don't change shared data
349 m_refData
= new wxFontRefData();
353 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
359 void wxFont::SetPointSize(int pointSize
)
363 M_FONTDATA
->m_pointSize
= pointSize
;
364 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
369 void wxFont::SetFamily(int family
)
373 M_FONTDATA
->m_family
= family
;
374 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
379 void wxFont::SetStyle(int style
)
383 M_FONTDATA
->m_style
= style
;
384 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
389 void wxFont::SetWeight(int weight
)
393 M_FONTDATA
->m_weight
= weight
;
394 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
399 void wxFont::SetFaceName(const wxString
& faceName
)
403 M_FONTDATA
->m_faceName
= faceName
;
404 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
409 void wxFont::SetUnderlined(bool underlined
)
413 M_FONTDATA
->m_underlined
= underlined
;
418 void wxFont::SetEncoding(wxFontEncoding encoding
)
422 M_FONTDATA
->m_encoding
= encoding
;
423 M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now
428 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
432 M_FONTDATA
->m_nativeFontInfo
= info
;
435 // ----------------------------------------------------------------------------
436 // query font attributes
437 // ----------------------------------------------------------------------------
439 int wxFont::GetPointSize() const
441 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
443 return M_FONTDATA
->m_pointSize
;
446 wxString
wxFont::GetFaceName() const
448 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
450 return M_FONTDATA
->m_faceName
;
453 int wxFont::GetFamily() const
455 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
457 return M_FONTDATA
->m_family
;
460 int wxFont::GetStyle() const
462 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
464 return M_FONTDATA
->m_style
;
467 int wxFont::GetWeight() const
469 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
471 return M_FONTDATA
->m_weight
;
474 bool wxFont::GetUnderlined() const
476 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
478 return M_FONTDATA
->m_underlined
;
481 wxFontEncoding
wxFont::GetEncoding() const
483 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
485 return M_FONTDATA
->m_encoding
;
488 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
490 wxCHECK_MSG( Ok(), (wxNativeFontInfo
*)NULL
, wxT("invalid font") );
492 if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty())
495 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);
498 // ----------------------------------------------------------------------------
499 // real implementation
500 // ----------------------------------------------------------------------------
502 // Find an existing, or create a new, XFontStruct
503 // based on this wxFont and the given scale. Append the
504 // font to list in the private data for future reference.
505 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
508 return (wxXFont
*)NULL
;
510 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
511 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
513 // search existing fonts first
514 wxList::compatibility_iterator node
= M_FONTDATA
->m_fonts
.GetFirst();
517 wxXFont
* f
= (wxXFont
*) node
->GetData();
518 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
520 node
= node
->GetNext();
523 // not found, create a new one
524 XFontStruct
*font
= (XFontStruct
*)
525 wxLoadQueryNearestFont(pointSize
,
526 M_FONTDATA
->m_family
,
528 M_FONTDATA
->m_weight
,
529 M_FONTDATA
->m_underlined
,
531 M_FONTDATA
->m_encoding
);
535 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
537 return (wxXFont
*) NULL
;
540 wxXFont
* f
= new wxXFont
;
541 f
->m_fontStruct
= (WXFontStructPtr
)font
;
542 f
->m_display
= ( display
? display
: wxGetDisplay() );
543 f
->m_scale
= intScale
;
544 f
->m_fontList
= XmFontListCreate ((XFontStruct
*) font
, XmSTRING_DEFAULT_CHARSET
);
545 M_FONTDATA
->m_fonts
.Append(f
);
547 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
548 XmRendition rendition
;
549 XmRenderTable renderTable
;
553 XtSetArg( args
[count
], XmNfont
, font
); ++count
;
554 XtSetArg( args
[count
], XmNunderlineType
,
555 GetUnderlined() ? XmSINGLE_LINE
: XmNO_LINE
); ++count
;
556 rendition
= XmRenditionCreate( XmGetXmDisplay( (Display
*)f
->m_display
),
559 renderTable
= XmRenderTableAddRenditions( NULL
, &rendition
, 1,
562 f
->m_renderTable
= (WXRenderTable
)renderTable
;
568 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
570 wxXFont
* f
= GetInternalFont(scale
, display
);
572 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);
575 WXFontList
wxFont::GetFontList(double scale
, WXDisplay
* display
) const
577 wxXFont
* f
= GetInternalFont(scale
, display
);
579 return (f
? f
->m_fontList
: (WXFontList
) 0);
582 #if wxCHECK_MOTIF_VERSION( 2, 0 )
584 WXRenderTable
wxFont::GetRenderTable(WXDisplay
* display
) const
586 wxXFont
* f
= GetInternalFont(1.0, display
);
588 return (f
? f
->m_renderTable
: (WXFontList
) 0);
593 WXFontType
wxFont::GetFontType(WXDisplay
* display
) const
595 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
596 return Ok() ? GetRenderTable(display
) : NULL
;
598 return Ok() ? GetFontList(1.0, display
) : NULL
;
602 /*static*/ WXString
wxFont::GetFontTag()
604 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
605 return (WXString
)XmNrenderTable
;
607 return (WXString
)XmNfontList
;