]> git.saurik.com Git - wxWidgets.git/blame - src/motif/font.cpp
The Unicode handling fixes my app seemed to need.
[wxWidgets.git] / src / motif / font.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "font.h"
14#endif
15
16#include "wx/defs.h"
17#include "wx/string.h"
18#include "wx/font.h"
19#include "wx/gdicmn.h"
dfc54541
JS
20#include "wx/utils.h"
21
f97c9854 22#include <Xm/Xm.h>
4bb6408c
JS
23
24#if !USE_SHARED_LIBRARIES
25IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
26#endif
27
f97c9854
JS
28wxXFont::wxXFont()
29{
30 m_fontStruct = (WXFontStructPtr) 0;
31 m_fontList = (WXFontList) 0;
32 m_display = (WXDisplay*) 0;
33 m_scale = 100;
34}
35
36wxXFont::~wxXFont()
37{
38 XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
39 XmFontList fontList = (XmFontList) m_fontList;
2d120f83 40
f97c9854 41 XmFontListFree (fontList);
2d120f83
JS
42
43 // TODO: why does freeing the font produce a segv???
f97c9854 44 // Note that XFreeFont wasn't called in wxWin 1.68 either.
2d120f83 45 // XFreeFont((Display*) m_display, fontStruct);
f97c9854
JS
46}
47
48wxFontRefData::wxFontRefData()
4bb6408c 49{
dfc54541
JS
50 m_style = 0;
51 m_pointSize = 0;
52 m_family = 0;
53 m_style = 0;
54 m_weight = 0;
55 m_underlined = 0;
56 m_faceName = "";
4bb6408c
JS
57}
58
f97c9854 59wxFontRefData::wxFontRefData(const wxFontRefData& data)
4bb6408c 60{
dfc54541
JS
61 m_style = data.m_style;
62 m_pointSize = data.m_pointSize;
63 m_family = data.m_family;
64 m_style = data.m_style;
65 m_weight = data.m_weight;
66 m_underlined = data.m_underlined;
67 m_faceName = data.m_faceName;
2d120f83 68
dfc54541
JS
69 // Don't have to copy actual fonts, because they'll be created
70 // on demand.
4bb6408c
JS
71}
72
73wxFontRefData::~wxFontRefData()
74{
f97c9854 75 wxNode* node = m_fonts.First();
dfc54541
JS
76 while (node)
77 {
f97c9854
JS
78 wxXFont* f = (wxXFont*) node->Data();
79 delete f;
dfc54541
JS
80 node = node->Next();
81 }
f97c9854 82 m_fonts.Clear();
4bb6408c
JS
83}
84
85wxFont::wxFont()
86{
87 if ( wxTheFontList )
88 wxTheFontList->Append(this);
89}
90
91wxFont::wxFont(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName)
92{
93 Create(pointSize, family, style, weight, underlined, faceName);
2d120f83 94
4bb6408c
JS
95 if ( wxTheFontList )
96 wxTheFontList->Append(this);
97}
98
99bool wxFont::Create(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName)
100{
101 UnRef();
102 m_refData = new wxFontRefData;
2d120f83 103
4bb6408c
JS
104 M_FONTDATA->m_family = family;
105 M_FONTDATA->m_style = style;
106 M_FONTDATA->m_weight = weight;
107 M_FONTDATA->m_pointSize = pointSize;
108 M_FONTDATA->m_underlined = underlined;
109 M_FONTDATA->m_faceName = faceName;
2d120f83 110
4bb6408c 111 RealizeResource();
2d120f83 112
4bb6408c
JS
113 return TRUE;
114}
115
116wxFont::~wxFont()
117{
118 if (wxTheFontList)
119 wxTheFontList->DeleteObject(this);
120}
121
122bool wxFont::RealizeResource()
123{
124 // TODO: create the font (if there is a native font object)
125 return FALSE;
126}
127
128void wxFont::Unshare()
129{
2d120f83
JS
130 // Don't change shared data
131 if (!m_refData)
4bb6408c 132 {
2d120f83
JS
133 m_refData = new wxFontRefData();
134 }
4bb6408c
JS
135 else
136 {
2d120f83
JS
137 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
138 UnRef();
139 m_refData = ref;
140 }
4bb6408c
JS
141}
142
143void wxFont::SetPointSize(int pointSize)
144{
145 Unshare();
2d120f83 146
4bb6408c 147 M_FONTDATA->m_pointSize = pointSize;
2d120f83 148
4bb6408c
JS
149 RealizeResource();
150}
151
152void wxFont::SetFamily(int family)
153{
154 Unshare();
2d120f83 155
4bb6408c 156 M_FONTDATA->m_family = family;
2d120f83 157
4bb6408c
JS
158 RealizeResource();
159}
160
161void wxFont::SetStyle(int style)
162{
163 Unshare();
2d120f83 164
4bb6408c 165 M_FONTDATA->m_style = style;
2d120f83 166
4bb6408c
JS
167 RealizeResource();
168}
169
170void wxFont::SetWeight(int weight)
171{
172 Unshare();
2d120f83 173
4bb6408c 174 M_FONTDATA->m_weight = weight;
2d120f83 175
4bb6408c
JS
176 RealizeResource();
177}
178
179void wxFont::SetFaceName(const wxString& faceName)
180{
181 Unshare();
2d120f83 182
4bb6408c 183 M_FONTDATA->m_faceName = faceName;
2d120f83 184
4bb6408c
JS
185 RealizeResource();
186}
187
188void wxFont::SetUnderlined(bool underlined)
189{
190 Unshare();
2d120f83 191
4bb6408c 192 M_FONTDATA->m_underlined = underlined;
2d120f83 193
4bb6408c
JS
194 RealizeResource();
195}
196
197wxString wxFont::GetFamilyString() const
198{
2d120f83
JS
199 wxString fam("");
200 switch (GetFamily())
201 {
4bb6408c 202 case wxDECORATIVE:
2d120f83
JS
203 fam = "wxDECORATIVE";
204 break;
4bb6408c 205 case wxROMAN:
2d120f83
JS
206 fam = "wxROMAN";
207 break;
4bb6408c 208 case wxSCRIPT:
2d120f83
JS
209 fam = "wxSCRIPT";
210 break;
4bb6408c 211 case wxSWISS:
2d120f83
JS
212 fam = "wxSWISS";
213 break;
4bb6408c 214 case wxMODERN:
2d120f83
JS
215 fam = "wxMODERN";
216 break;
4bb6408c 217 case wxTELETYPE:
2d120f83
JS
218 fam = "wxTELETYPE";
219 break;
4bb6408c 220 default:
2d120f83
JS
221 fam = "wxDEFAULT";
222 break;
223 }
224 return fam;
4bb6408c
JS
225}
226
227/* New font system */
228wxString wxFont::GetFaceName() const
229{
230 wxString str("");
231 if (M_FONTDATA)
2d120f83 232 str = M_FONTDATA->m_faceName ;
4bb6408c
JS
233 return str;
234}
235
236wxString wxFont::GetStyleString() const
237{
238 wxString styl("");
239 switch (GetStyle())
240 {
2d120f83
JS
241 case wxITALIC:
242 styl = "wxITALIC";
243 break;
244 case wxSLANT:
245 styl = "wxSLANT";
246 break;
247 default:
248 styl = "wxNORMAL";
249 break;
4bb6408c
JS
250 }
251 return styl;
252}
253
254wxString wxFont::GetWeightString() const
255{
256 wxString w("");
257 switch (GetWeight())
258 {
2d120f83
JS
259 case wxBOLD:
260 w = "wxBOLD";
261 break;
262 case wxLIGHT:
263 w = "wxLIGHT";
264 break;
265 default:
266 w = "wxNORMAL";
267 break;
4bb6408c
JS
268 }
269 return w;
270}
271
dfc54541
JS
272// Find an existing, or create a new, XFontStruct
273// based on this wxFont and the given scale. Append the
274// font to list in the private data for future reference.
f97c9854 275wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
dfc54541 276{
2d120f83
JS
277 if (!Ok())
278 return (wxXFont*) NULL;
279
280 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
281 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
282
283 wxNode* node = M_FONTDATA->m_fonts.First();
284 while (node)
285 {
286 wxXFont* f = (wxXFont*) node->Data();
287 if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
288 return f;
289 node = node->Next();
290 }
291
292 WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family,
293 M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined);
294
295 if (!font)
296 {
297 // search up and down by stepsize 10
298 int max_size = pointSize + 20 * (1 + (pointSize/180));
299 int min_size = pointSize - 20 * (1 + (pointSize/180));
300 int i;
301
302 // Search for smaller size (approx.)
303 for (i=pointSize-10; !font && i >= 10 && i >= min_size; i -= 10)
304 font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined);
305 // Search for larger size (approx.)
306 for (i=pointSize+10; !font && i <= max_size; i += 10)
307 font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined);
308 // Try default family
309 if (!font && M_FONTDATA->m_family != wxDEFAULT)
310 font = LoadQueryFont(pointSize, wxDEFAULT, M_FONTDATA->m_style,
311 M_FONTDATA->m_weight, M_FONTDATA->m_underlined);
312 // Bogus font
313 if (!font)
314 font = LoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
315 M_FONTDATA->m_underlined);
e97f20a0 316 wxASSERT_MSG( (font != (XFontStruct*) NULL), "Could not allocate even a default font -- something is wrong." );
2d120f83
JS
317 }
318 if (font)
319 {
320 wxXFont* f = new wxXFont;
321 f->m_fontStruct = font;
322 f->m_display = ( display ? display : wxGetDisplay() );
323 f->m_scale = intScale;
324 f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET);
325 M_FONTDATA->m_fonts.Append(f);
326 return f;
327 }
328 return (wxXFont*) NULL;
dfc54541
JS
329}
330
331WXFontStructPtr wxFont::LoadQueryFont(int pointSize, int family, int style,
2d120f83 332 int weight, bool underlined) const
dfc54541
JS
333{
334 char *xfamily;
335 char *xstyle;
336 char *xweight;
337 switch (family)
338 {
2d120f83
JS
339 case wxDECORATIVE: xfamily = "lucida";
340 break;
341 case wxROMAN: xfamily = "times";
342 break;
343 case wxMODERN: xfamily = "courier";
344 break;
345 case wxSWISS: xfamily = "lucida";
346 break;
347 case wxDEFAULT:
348 default: xfamily = "*";
dfc54541
JS
349 }
350 switch (style)
351 {
2d120f83
JS
352 case wxITALIC: xstyle = "i";
353 break;
354 case wxSLANT: xstyle = "o";
355 break;
356 case wxNORMAL: xstyle = "r";
357 break;
358 default: xstyle = "*";
359 break;
dfc54541
JS
360 }
361 switch (weight)
362 {
2d120f83
JS
363 case wxBOLD: xweight = "bold";
364 break;
365 case wxLIGHT:
366 case wxNORMAL: xweight = "medium";
367 break;
368 default: xweight = "*";
369 break;
dfc54541 370 }
2d120f83 371
dfc54541 372 sprintf(wxBuffer, "-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-*-*",
2d120f83
JS
373 xfamily, xweight, xstyle, pointSize);
374
dfc54541
JS
375 Display *dpy = (Display*) wxGetDisplay();
376 XFontStruct* font = XLoadQueryFont(dpy, wxBuffer);
2d120f83 377
dfc54541
JS
378 return (WXFontStructPtr) font;
379}