]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/font.cpp
Put the call to CheckForKeyDown() back in to ProcessXEvent because key down events...
[wxWidgets.git] / src / gtk / font.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose:
4// Author: Robert Roebling
a81258be 5// Id: $Id$
c801d85f 6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8bbe427f 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "font.h"
12#endif
13
14#include "wx/font.h"
15#include "wx/utils.h"
5705323e 16#include "wx/log.h"
4cb122de 17#include "wx/gdicmn.h"
c801d85f
KB
18#include <strings.h>
19
83624f79
RR
20#include "gdk/gdk.h"
21
c801d85f
KB
22//-----------------------------------------------------------------------------
23// local data
24//-----------------------------------------------------------------------------
25
36b3b54a 26/*
a3622daa 27extern wxFontNameDirectory *wxTheFontNameDirectory;
36b3b54a 28*/
c801d85f
KB
29
30//-----------------------------------------------------------------------------
31// wxFont
32//-----------------------------------------------------------------------------
33
34class wxFontRefData: public wxObjectRefData
35{
8bbe427f
VZ
36public:
37
38 wxFontRefData();
358fc25c 39 wxFontRefData( const wxFontRefData& data );
8bbe427f
VZ
40 ~wxFontRefData();
41
358fc25c
RR
42 wxList m_scaled_xfonts;
43 int m_pointSize;
44 int m_family, m_style, m_weight;
45 bool m_underlined;
358fc25c 46 wxString m_faceName;
8bbe427f 47
358fc25c
RR
48 bool m_byXFontName;
49 GdkFont *m_font;
8bbe427f 50
c801d85f
KB
51 friend wxFont;
52};
53
8bbe427f
VZ
54wxFontRefData::wxFontRefData() : m_scaled_xfonts(wxKEY_INTEGER)
55{
56 m_byXFontName = FALSE;
57 m_pointSize = 12;
58 m_family = wxSWISS;
59 m_style = wxNORMAL;
60 m_weight = wxNORMAL;
61 m_underlined = FALSE;
8bbe427f
VZ
62 m_font = (GdkFont *) NULL;
63}
64
358fc25c
RR
65wxFontRefData::wxFontRefData( const wxFontRefData& data ) : m_scaled_xfonts(wxKEY_INTEGER)
66{
67 m_byXFontName = FALSE;
68 m_pointSize = data.m_pointSize;
69 m_family = data.m_family;
70 m_style = data.m_style;
71 m_weight = data.m_weight;
72 m_underlined = data.m_underlined;
358fc25c
RR
73 m_faceName = data.m_faceName;
74 m_font = (GdkFont *) NULL;
75 if (data.m_font) m_font = gdk_font_ref( data.m_font );
76}
77
8bbe427f
VZ
78wxFontRefData::~wxFontRefData()
79{
80 wxNode *node = m_scaled_xfonts.First();
81 while (node)
82 {
83 GdkFont *font = (GdkFont*)node->Data();
84 wxNode *next = node->Next();
85 gdk_font_unref( font );
86 node = next;
87 }
8bbe427f 88 if (m_font) gdk_font_unref( m_font );
ff7b1510 89}
c801d85f
KB
90
91//-----------------------------------------------------------------------------
92
93#define M_FONTDATA ((wxFontRefData *)m_refData)
94
95IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
96
8bbe427f 97wxFont::wxFont()
c801d85f 98{
8bbe427f 99 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 100}
c801d85f
KB
101
102wxFont::wxFont( char *xFontName )
103{
8bbe427f
VZ
104 if (!xFontName) return;
105
106 m_refData = new wxFontRefData();
107
108 M_FONTDATA->m_byXFontName = TRUE;
109 M_FONTDATA->m_font = gdk_font_load( xFontName );
ff7b1510 110}
c801d85f 111
8fc613f1 112wxFont::wxFont( int pointSize, int family, int style, int weight, bool underlined, const wxString& face )
8bbe427f
VZ
113{
114 m_refData = new wxFontRefData();
115
36b3b54a
RR
116 if (family == wxDEFAULT)
117 M_FONTDATA->m_family = wxSWISS;
8bbe427f 118 else
36b3b54a
RR
119 M_FONTDATA->m_family = family;
120
121 if (!face.IsEmpty()) M_FONTDATA->m_faceName = face;
8bbe427f 122
36b3b54a
RR
123 if (style == wxDEFAULT)
124 M_FONTDATA->m_style = wxNORMAL;
125 else
126 M_FONTDATA->m_style = style;
127
128 if (weight == wxDEFAULT)
129 M_FONTDATA->m_weight = wxNORMAL;
130 else
131 M_FONTDATA->m_weight = weight;
132
133 if (pointSize == wxDEFAULT)
134 M_FONTDATA->m_pointSize = 12;
135 else
136 M_FONTDATA->m_pointSize = pointSize;
137
358fc25c 138 M_FONTDATA->m_underlined = underlined;
8bbe427f
VZ
139
140 if (wxTheFontList) wxTheFontList->Append( this );
358fc25c 141
ff7b1510 142}
c801d85f 143
8bbe427f
VZ
144wxFont::wxFont( const wxFont& font )
145{
146 Ref( font );
147
148 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 149}
c801d85f 150
8bbe427f 151wxFont::~wxFont()
c801d85f 152{
8bbe427f 153 if (wxTheFontList) wxTheFontList->DeleteObject( this );
ff7b1510 154}
c801d85f 155
8bbe427f
VZ
156wxFont& wxFont::operator = ( const wxFont& font )
157{
158 if (*this == font) return (*this);
159 Ref( font );
160 return *this;
ff7b1510 161}
c801d85f 162
f03fc89f 163bool wxFont::operator == ( const wxFont& font ) const
8bbe427f
VZ
164{
165 return m_refData == font.m_refData;
ff7b1510 166}
c801d85f 167
f03fc89f 168bool wxFont::operator != ( const wxFont& font ) const
8bbe427f
VZ
169{
170 return m_refData != font.m_refData;
ff7b1510 171}
c801d85f 172
d84eb083 173bool wxFont::Ok() const
c801d85f 174{
8bbe427f 175 return (m_refData != NULL);
ff7b1510 176}
c801d85f 177
8bbe427f 178int wxFont::GetPointSize() const
c801d85f 179{
ed9b9841 180 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
8bbe427f
VZ
181
182 return M_FONTDATA->m_pointSize;
ff7b1510 183}
c801d85f 184
8bbe427f 185wxString wxFont::GetFaceName() const
c801d85f 186{
ed9b9841 187 wxCHECK_MSG( Ok(), _T(""), _T("invalid font") );
8bbe427f 188
36b3b54a 189 return M_FONTDATA->m_faceName;
ff7b1510 190}
c801d85f 191
8bbe427f 192int wxFont::GetFamily() const
c801d85f 193{
ed9b9841 194 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
8bbe427f
VZ
195
196 return M_FONTDATA->m_family;
ff7b1510 197}
c801d85f 198
8bbe427f 199wxString wxFont::GetFamilyString() const
c801d85f 200{
ed9b9841 201 wxCHECK_MSG( Ok(), _T("wxDEFAULT"), _T("invalid font") );
8bbe427f
VZ
202
203 switch (M_FONTDATA->m_family)
204 {
ed9b9841
OK
205 case wxDECORATIVE: return wxString(_T("wxDECORATIVE"));
206 case wxROMAN: return wxString(_T("wxROMAN"));
207 case wxSCRIPT: return wxString(_T("wxSCRIPT"));
208 case wxSWISS: return wxString(_T("wxSWISS"));
209 case wxMODERN: return wxString(_T("wxMODERN"));
210 case wxTELETYPE: return wxString(_T("wxTELETYPE"));
211 default: return _T("wxDEFAULT");
8bbe427f
VZ
212 }
213
e55ad60e 214 return "wxDEFAULT";
ff7b1510 215}
c801d85f 216
8bbe427f 217int wxFont::GetStyle() const
c801d85f 218{
ed9b9841 219 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
d84eb083 220
8bbe427f 221 return M_FONTDATA->m_style;
ff7b1510 222}
c801d85f 223
8bbe427f 224wxString wxFont::GetStyleString() const
c801d85f 225{
ed9b9841 226 wxCHECK_MSG( Ok(), _T("wxDEFAULT"), _T("invalid font") );
8bbe427f
VZ
227
228 switch (M_FONTDATA->m_style)
229 {
ed9b9841
OK
230 case wxNORMAL: return wxString(_T("wxNORMAL"));
231 case wxSLANT: return wxString(_T("wxSLANT"));
232 case wxITALIC: return wxString(_T("wxITALIC"));
233 default: return wxString(_T("wxDEFAULT"));
8bbe427f 234 }
d84eb083 235
ed9b9841 236 return wxString(_T("wxDEFAULT"));
ff7b1510 237}
c801d85f 238
8bbe427f 239int wxFont::GetWeight() const
c801d85f 240{
ed9b9841 241 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
8bbe427f
VZ
242
243 return M_FONTDATA->m_weight;
244}
245
246wxString wxFont::GetWeightString() const
247{
ed9b9841 248 wxCHECK_MSG( Ok(), _T("wxDEFAULT"), _T("invalid font") );
8bbe427f
VZ
249
250 switch (M_FONTDATA->m_weight)
251 {
ed9b9841
OK
252 case wxNORMAL: return wxString(_T("wxNORMAL"));
253 case wxBOLD: return wxString(_T("wxBOLD"));
254 case wxLIGHT: return wxString(_T("wxLIGHT"));
255 default: return wxString(_T("wxDEFAULT"));
8bbe427f
VZ
256 }
257
ed9b9841 258 return wxString(_T("wxDEFAULT"));
8bbe427f
VZ
259}
260
261bool wxFont::GetUnderlined() const
262{
ed9b9841 263 wxCHECK_MSG( Ok(), FALSE, _T("invalid font") );
8bbe427f
VZ
264
265 return M_FONTDATA->m_underlined;
ff7b1510 266}
c801d85f 267
358fc25c
RR
268void wxFont::Unshare()
269{
270 if (!m_refData)
271 {
272 m_refData = new wxFontRefData();
273 }
274 else
275 {
276 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
277 UnRef();
278 m_refData = ref;
279 }
280}
281
282void wxFont::SetPointSize(int pointSize)
283{
284 Unshare();
285
286 M_FONTDATA->m_pointSize = pointSize;
287}
288
289void wxFont::SetFamily(int family)
290{
291 Unshare();
292
293 M_FONTDATA->m_family = family;
294}
295
296void wxFont::SetStyle(int style)
297{
298 Unshare();
299
300 M_FONTDATA->m_style = style;
301}
302
303void wxFont::SetWeight(int weight)
304{
305 Unshare();
306
307 M_FONTDATA->m_weight = weight;
308}
309
310void wxFont::SetFaceName(const wxString& faceName)
311{
312 Unshare();
313
314 M_FONTDATA->m_faceName = faceName;
315}
316
317void wxFont::SetUnderlined(bool underlined)
318{
319 Unshare();
320
321 M_FONTDATA->m_underlined = underlined;
322}
323
c801d85f
KB
324//-----------------------------------------------------------------------------
325// get internal representation of font
326//-----------------------------------------------------------------------------
327
36b3b54a
RR
328static GdkFont *wxLoadQueryNearestFont( int point_size, int family, int style, int weight,
329 bool underlined, const wxString &facename );
c801d85f 330
36b3b54a 331GdkFont *wxFont::GetInternalFont( float scale ) const
c801d85f 332{
8bbe427f
VZ
333 if (!Ok())
334 {
ed9b9841 335 wxFAIL_MSG( _T("invalid font") );
8bbe427f
VZ
336 return (GdkFont*) NULL;
337 }
338
36b3b54a 339 /* short cut if the special X font constructor has been used */
8bbe427f
VZ
340 if (M_FONTDATA->m_byXFontName) return M_FONTDATA->m_font;
341
36b3b54a 342 long int_scale = long(scale * 100.0 + 0.5); /* key for fontlist */
8bbe427f
VZ
343 int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
344 GdkFont *font = (GdkFont *) NULL;
345
346 wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
347 if (node)
348 {
349 font = (GdkFont*)node->Data();
350 }
351 else
352 {
36b3b54a 353/*
8bbe427f
VZ
354 if ((int_scale == 100) &&
355 (M_FONTDATA->m_family == wxSWISS) &&
356 (M_FONTDATA->m_style == wxNORMAL) &&
357 (M_FONTDATA->m_pointSize == 12) &&
358 (M_FONTDATA->m_weight == wxNORMAL) &&
359 (M_FONTDATA->m_underlined == FALSE))
360 {
361 font = gdk_font_load( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
362 }
363 else
36b3b54a 364*/
8bbe427f 365 {
36b3b54a
RR
366 font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_family, M_FONTDATA->m_style,
367 M_FONTDATA->m_weight, M_FONTDATA->m_underlined, M_FONTDATA->m_faceName );
8bbe427f
VZ
368 }
369 M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
370 }
36b3b54a 371
8bbe427f 372 if (!font)
36b3b54a 373 {
ed9b9841 374 wxLogError(_T("could not load any font"));
36b3b54a 375 }
5705323e 376
8bbe427f 377 return font;
ff7b1510 378}
c801d85f
KB
379
380//-----------------------------------------------------------------------------
381// local utilities to find a X font
382//-----------------------------------------------------------------------------
383
36b3b54a
RR
384static GdkFont*wxLoadQueryFont( int pointSize, int family, int style, int weight,
385 bool underlined, const wxString &facename )
c801d85f 386{
ed9b9841
OK
387 wxChar *xfamily = (wxChar*) NULL;
388 wxChar *xstyle = (wxChar*) NULL;
389 wxChar *xweight = (wxChar*) NULL;
36b3b54a
RR
390
391 switch (family)
392 {
ed9b9841
OK
393 case wxDECORATIVE: xfamily = _T("lucida"); break;
394 case wxROMAN: xfamily = _T("times"); break;
395 case wxMODERN: xfamily = _T("courier"); break;
396 case wxSWISS: xfamily = _T("helvetica"); break;
397 case wxTELETYPE: xfamily = _T("lucidatypewriter"); break;
398 case wxSCRIPT: xfamily = _T("utopia"); break;
399 default: xfamily = _T("*");
36b3b54a
RR
400 }
401
402 if (!facename.IsEmpty())
403 {
ed9b9841 404 wxSprintf( wxBuffer, _T("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"), facename.c_str() );
dcf924a3 405 GdkFont *test = gdk_font_load( wxConvCurrent->cWX2MB(wxBuffer) );
36b3b54a
RR
406 if (test)
407 {
408 gdk_font_unref( test );
409 xfamily = WXSTRINGCAST facename;
410 }
411 }
412
413 switch (style)
414 {
ed9b9841
OK
415 case wxITALIC: xstyle = _T("i"); break;
416 case wxSLANT: xstyle = _T("o"); break;
417 case wxNORMAL: xstyle = _T("r"); break;
418 default: xstyle = _T("*"); break;
36b3b54a
RR
419 }
420 switch (weight)
421 {
ed9b9841 422 case wxBOLD: xweight = _T("bold"); break;
36b3b54a 423 case wxLIGHT:
ed9b9841
OK
424 case wxNORMAL: xweight = _T("medium"); break;
425 default: xweight = _T("*"); break;
36b3b54a
RR
426 }
427
ed9b9841 428 wxSprintf( wxBuffer, _T("-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-*-*"),
36b3b54a
RR
429 xfamily, xweight, xstyle, pointSize);
430
dcf924a3 431 return gdk_font_load( wxConvCurrent->cWX2MB(wxBuffer) );
c801d85f
KB
432}
433
36b3b54a
RR
434static GdkFont *wxLoadQueryNearestFont( int point_size, int family, int style, int weight,
435 bool underlined, const wxString &facename )
c801d85f 436{
36b3b54a 437 GdkFont *font = wxLoadQueryFont( point_size, family, style, weight, underlined, facename );
c801d85f 438
36b3b54a
RR
439 if (!font)
440 {
441 /* search up and down by stepsize 10 */
8bbe427f
VZ
442 int max_size = point_size + 20 * (1 + (point_size/180));
443 int min_size = point_size - 20 * (1 + (point_size/180));
36b3b54a 444
8fc613f1
RR
445 int i;
446
36b3b54a 447 /* Search for smaller size (approx.) */
8fc613f1 448 for (i=point_size-10; !font && i >= 10 && i >= min_size; i -= 10)
36b3b54a
RR
449 font = wxLoadQueryFont(i, family, style, weight, underlined, facename );
450
451 /* Search for larger size (approx.) */
8fc613f1 452 for (i=point_size+10; !font && i <= max_size; i += 10)
36b3b54a
RR
453 font = wxLoadQueryFont( i, family, style, weight, underlined, facename );
454
455 /* Try default family */
456 if (!font && family != wxDEFAULT)
457 font = wxLoadQueryFont( point_size, wxDEFAULT, style, weight, underlined, facename );
458
459 /* Bogus font */
8bbe427f 460 if (!font)
36b3b54a 461 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, underlined, facename );
c801d85f 462 }
36b3b54a 463
c801d85f
KB
464 return font;
465}
466
36b3b54a
RR
467/*
468
c801d85f
KB
469//-----------------------------------------------------------------------------
470// face names and index functions
471//-----------------------------------------------------------------------------
472
473static char *font_defaults[] = {
474 "FamilyDefault", "Default",
475 "FamilyRoman", "Roman",
476 "FamilyDecorative", "Decorative",
477 "FamilyModern", "Modern",
478 "FamilyTeletype", "Teletype",
479 "FamilySwiss", "Swiss",
480 "FamilyScript", "Script",
481
482 "AfmMedium", "",
483 "AfmBold", "Bo",
484 "AfmLight", "",
485 "AfmStraight", "",
486 "AfmItalic", "${AfmSlant}",
487 "AfmSlant", "O",
488 "AfmRoman", "Ro",
489 "AfmTimes", "Times",
490 "AfmHelvetica", "Helv",
491 "AfmCourier", "Cour",
8bbe427f 492
c801d85f
KB
493 "Afm___", "${AfmTimes,$[weight],$[style]}",
494
495 "AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
496 "AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
497 "AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
498 "AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
499 "AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
500
501 "AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
502 "AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
503
504 "AfmTeletype__", "${AfmModern,$[weight],$[style]}",
505
506 "PostScriptMediumStraight", "",
507 "PostScriptMediumItalic", "-Oblique",
508 "PostScriptMediumSlant", "-Oblique",
509 "PostScriptLightStraight", "",
510 "PostScriptLightItalic", "-Oblique",
511 "PostScriptLightSlant", "-Oblique",
512 "PostScriptBoldStraight", "-Bold",
513 "PostScriptBoldItalic", "-BoldOblique",
514 "PostScriptBoldSlant", "-BoldOblique",
8bbe427f 515
c801d85f
KB
516#if WX_NORMALIZED_PS_FONTS
517 "PostScript___", "${PostScriptTimes,$[weight],$[style]}",
518#else
519 "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
520 "PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
521#endif
522
523 "PostScriptTimesMedium", "",
524 "PostScriptTimesLight", "",
525 "PostScriptTimesBold", "Bold",
526
527 "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
528 "PostScriptTimesMediumStraight", "Times-Roman",
529 "PostScriptTimesLightStraight", "Times-Roman",
530 "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
531 "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
532
533 "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
534 "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
535
536 "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
537
538#if !WX_NORMALIZED_PS_FONTS
539 "PostScriptScript__", "Zapf-Chancery-MediumItalic",
540#endif
541
542 "ScreenMedium", "medium",
543 "ScreenBold", "bold",
544 "ScreenLight", "light",
545 "ScreenStraight", "r",
546 "ScreenItalic", "i",
547 "ScreenSlant", "o",
548
b1c71cd0
RR
549 "ScreenDefaultBase", "*-times",
550
c801d85f
KB
551 "ScreenRomanBase", "*-times",
552 "ScreenDecorativeBase", "*-helvetica",
553 "ScreenModernBase", "*-courier",
554 "ScreenTeletypeBase", "*-lucidatypewriter",
555 "ScreenSwissBase", "*-lucida",
556 "ScreenScriptBase", "*-zapfchancery",
557
558 "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
8bbe427f 559 "-normal-*-*-%d-*-*-*-*-*-*",
c801d85f
KB
560
561 "Screen___",
562 "-${ScreenDefaultBase}${ScreenStdSuffix}",
563 "ScreenRoman__",
564 "-${ScreenRomanBase}${ScreenStdSuffix}",
565 "ScreenDecorative__",
566 "-${ScreenDecorativeBase}${ScreenStdSuffix}",
567 "ScreenModern__",
568 "-${ScreenModernBase}${ScreenStdSuffix}",
569 "ScreenTeletype__",
570 "-${ScreenTeletypeBase}${ScreenStdSuffix}",
571 "ScreenSwiss__",
572 "-${ScreenSwissBase}${ScreenStdSuffix}",
573 "ScreenScript__",
574 "-${ScreenScriptBase}${ScreenStdSuffix}",
c67daf87 575 (char *) NULL
c801d85f
KB
576};
577
578enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD, wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
579enum {wxSTYLE_NORMAL, wxSTYLE_ITALIC, wxSTYLE_SLANT, wxNUM_STYLES};
580
581static int WCoordinate(int w)
582{
5705323e
RR
583 switch (w)
584 {
8bbe427f
VZ
585 case wxBOLD: return wxWEIGHT_BOLD;
586 case wxLIGHT: return wxWEIGHT_LIGHT;
587 case wxNORMAL:
588 default: return wxWEIGHT_NORMAL;
c801d85f 589 }
ff7b1510 590};
c801d85f
KB
591
592static int SCoordinate(int s)
593{
5705323e
RR
594 switch (s)
595 {
8bbe427f
VZ
596 case wxITALIC: return wxSTYLE_ITALIC;
597 case wxSLANT: return wxSTYLE_SLANT;
598 case wxNORMAL:
599 default: return wxSTYLE_NORMAL;
c801d85f 600 }
ff7b1510 601};
c801d85f
KB
602
603//-----------------------------------------------------------------------------
604// wxSuffixMap
605//-----------------------------------------------------------------------------
606
5705323e
RR
607class wxSuffixMap
608{
c801d85f 609public:
8bbe427f 610 ~wxSuffixMap();
c801d85f
KB
611
612 inline char *GetName(int weight, int style)
613 {
8bbe427f 614 return ( map [WCoordinate(weight)] [SCoordinate(style)] );
c801d85f
KB
615 }
616
617 char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
618 void Initialize(const char *, const char *);
619};
620
c801d85f
KB
621static void SearchResource(const char *prefix, const char **names, int count, char **v)
622{
623 int k, i, j;
624 char resource[1024], **defaults, *internal;
625
626 k = 1 << count;
8bbe427f 627
c67daf87
UR
628 *v = (char *) NULL;
629 internal = (char *) NULL;
c801d85f 630
5705323e
RR
631 for (i = 0; i < k; i++)
632 {
8bbe427f 633 strcpy(resource, prefix);
5705323e
RR
634 for (j = 0; j < count; j++)
635 {
36b3b54a
RR
636 // upon failure to find a matching fontname
637 // in the default fonts above, we substitute more
638 // and more values by _ so that at last ScreenMyFontBoldNormal
639 // would turn into Screen___ and this will then get
640 // converted to -${ScreenDefaultBase}${ScreenStdSuffix}
5705323e 641
8bbe427f
VZ
642 if (!(i & (1 << j)))
643 strcat(resource, names[j]);
644 else
645 strcat(resource, "_");
646 }
5705323e 647
36b3b54a 648 // we previously search the Xt-resources here
5705323e
RR
649
650 if (!internal)
651 {
8bbe427f 652 defaults = font_defaults;
5705323e
RR
653 while (*defaults)
654 {
655 if (!strcmp(*defaults, resource))
656 {
8bbe427f
VZ
657 internal = defaults[1];
658 break;
659 }
660 defaults += 2;
661 }
662 }
c801d85f 663 }
5705323e 664
c801d85f 665 if (internal)
5705323e 666 {
b1c71cd0
RR
667 if ((strcmp(internal,"-${ScreenDefaultBase}${ScreenStdSuffix}") == 0) &&
668 (strcmp(names[0], "Default") != 0))
5705323e 669 {
36b3b54a
RR
670 // we did not find any font name in the standard list.
671 // this can (hopefully does) mean that someone supplied
672 // the facename in the wxFont constructor so we insert
673 // it here
5705323e 674
36b3b54a
RR
675 strcpy( resource,"-*-" ); // any producer
676 strcat( resource, names[0] ); // facename
677 strcat( resource, "${ScreenStdSuffix}" ); // add size params later on
5705323e
RR
678 *v = copystring(resource);
679 }
680 else
681 {
682 *v = copystring(internal);
683 }
684 }
c801d85f
KB
685}
686
8bbe427f 687wxSuffixMap::~wxSuffixMap()
c801d85f
KB
688{
689 int k, j;
690
691 for (k = 0; k < wxNUM_WEIGHTS; ++k)
8bbe427f 692 for (j = 0; j < wxNUM_STYLES; ++j)
5705323e
RR
693 if (map[k][j])
694 {
8bbe427f
VZ
695 delete[] map[k][j];
696 map[k][j] = (char *) NULL;
697 }
c801d85f
KB
698}
699
700void wxSuffixMap::Initialize(const char *resname, const char *devresname)
701{
702 const char *weight, *style;
703 char *v;
704 int i, j, k;
705 const char *names[3];
706
5705323e
RR
707 for (k = 0; k < wxNUM_WEIGHTS; k++)
708 {
709 switch (k)
710 {
8bbe427f
VZ
711 case wxWEIGHT_NORMAL: weight = "Medium"; break;
712 case wxWEIGHT_LIGHT: weight = "Light"; break;
713 case wxWEIGHT_BOLD:
5705323e 714 default: weight = "Bold";
8bbe427f 715 }
5705323e
RR
716 for (j = 0; j < wxNUM_STYLES; j++)
717 {
718 switch (j)
719 {
8bbe427f
VZ
720 case wxSTYLE_NORMAL: style = "Straight"; break;
721 case wxSTYLE_ITALIC: style = "Italic"; break;
722 case wxSTYLE_SLANT:
723 default: style = "Slant";
724 }
725 names[0] = resname;
726 names[1] = weight;
727 names[2] = style;
728
729 SearchResource(devresname, names, 3, &v);
5705323e 730
36b3b54a 731 // Expand macros in the found string:
8bbe427f
VZ
732found:
733 int len, closer = 0, startpos = 0;
734
735 len = (v ? strlen(v) : 0);
5705323e
RR
736 for (i = 0; i < len; i++)
737 {
738 if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{')))
739 {
8bbe427f
VZ
740 startpos = i;
741 closer = (v[i+1] == '[') ? ']' : '}';
742 ++i;
5705323e
RR
743 }
744 else if (v[i] == closer)
745 {
8bbe427f
VZ
746 int newstrlen;
747 const char *r = (char *) NULL; bool delete_r = FALSE;
748 char *name;
749
750 name = v + startpos + 2;
751 v[i] = 0;
752
5705323e
RR
753 if (closer == '}')
754 {
8bbe427f
VZ
755 int i, count, len;
756 char **names;
757
758 for (i = 0, count = 1; name[i]; i++)
759 if (name[i] == ',')
760 count++;
761
762 len = i;
763
764 names = new char*[count];
765 names[0] = name;
766 for (i = 0, count = 1; i < len; i++)
5705323e
RR
767 if (name[i] == ',')
768 {
8bbe427f
VZ
769 names[count++] = name + i + 1;
770 name[i] = 0;
771 }
772
773 SearchResource("", (const char **)names, count, (char **)&r);
774 delete_r = (r != 0);
775 delete[] names;
776
5705323e
RR
777 if (!r)
778 {
8bbe427f
VZ
779 for (i = 0; i < len; i++)
780 if (!name[i])
781 name[i] = ',';
782 r = "";
5705323e 783 wxLogError( "Bad resource name in font lookup." );
8bbe427f
VZ
784 }
785 } else if (!strcmp(name, "weight")) {
786 r = weight;
787 } else if (!strcmp(name, "style")) {
788 r = style;
789 } else if (!strcmp(name, "family")) {
790 r = resname;
791 } else {
792 r = "";
5705323e 793 wxLogError( "Bad font macro name." );
8bbe427f
VZ
794 }
795
796 // add r to v
797 newstrlen = strlen(r);
798 char *naya = new char[startpos + newstrlen + len - i];
799 memcpy(naya, v, startpos);
800 memcpy(naya + startpos, r, newstrlen);
801 memcpy(naya + startpos + newstrlen, v + i + 1, len - i);
802 if (delete_r)
803 delete[] (char*)r;
804 delete[] v;
805 v = naya;
806
807 goto found;
808 }
809 }
36b3b54a 810 // We have a final value:
8bbe427f
VZ
811 map[k][j] = v;
812 }
c801d85f
KB
813 }
814}
815
816//-----------------------------------------------------------------------------
817// wxFontNameItem
818//-----------------------------------------------------------------------------
819
358fc25c
RR
820class wxFontNameItem : public wxObject
821{
8bbe427f 822 DECLARE_DYNAMIC_CLASS(wxFontNameItem)
c801d85f 823public:
8bbe427f
VZ
824 wxFontNameItem(const char *name, int id, int family);
825 ~wxFontNameItem();
826
827 inline char* GetScreenName(int w, int s) {return screen.GetName(w, s);}
828 inline char* GetPostScriptName(int w, int s) {return printing.GetName(w, s);}
829 inline char* GetAFMName(int w, int s) {return afm.GetName(w, s);}
830 inline char* GetName() {return name;}
831 inline int GetFamily() {return family;}
832 inline int GetId() {return id;}
833 inline bool IsRoman() {return isroman;}
ea57084d 834#if defined(__WXDEBUG__)
8bbe427f 835 void Dump(ostream& str);
c801d85f
KB
836#endif
837
8bbe427f
VZ
838 int id;
839 int family;
840 char *name;
841 wxSuffixMap screen, printing, afm;
842 bool isroman;
c801d85f
KB
843};
844
845IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
846
847wxFontNameItem::wxFontNameItem(const char *Name, int Id, int Family)
848{
849 name = copystring(Name);
850 id = Id;
851 family = Family;
852
853 screen. Initialize(name, "Screen");
854 printing.Initialize(name, "PostScript");
855 afm. Initialize(name, "Afm");
856}
857
8bbe427f 858wxFontNameItem::~wxFontNameItem()
c801d85f
KB
859{
860 if (name)
8bbe427f 861 delete[] name;
c67daf87 862 name = (char *) NULL;
c801d85f
KB
863}
864
ea57084d 865#if defined(__WXDEBUG__)
c801d85f
KB
866void wxFontNameItem::Dump(ostream& str)
867{
868 str << "wxFontNameItem(" << name << ")";
869}
870#endif
871
872//-----------------------------------------------------------------------------
873// wxFontDirectory
874//-----------------------------------------------------------------------------
875
876IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
877
8bbe427f 878wxFontNameDirectory::wxFontNameDirectory()
c801d85f
KB
879{
880 table = new wxHashTable(wxKEY_INTEGER, 20);
881 nextFontId = -1;
c801d85f
KB
882}
883
884wxFontNameDirectory::~wxFontNameDirectory()
885{
886 // Cleanup wxFontNameItems allocated
887 table->BeginFind();
888 wxNode *node = table->Next();
358fc25c
RR
889 while (node)
890 {
8bbe427f
VZ
891 wxFontNameItem *item = (wxFontNameItem*)node->Data();
892 delete item;
893 node = table->Next();
c801d85f
KB
894 }
895 delete table;
896}
897
8bbe427f 898int wxFontNameDirectory::GetNewFontId()
c801d85f
KB
899{
900 return (nextFontId--);
901}
902
903void wxFontNameDirectory::Initialize()
904{
905 Initialize(wxDEFAULT, wxDEFAULT, "Default");
906 Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
907 Initialize(wxROMAN, wxROMAN, "Roman");
908 Initialize(wxMODERN, wxMODERN, "Modern");
909 Initialize(wxTELETYPE, wxTELETYPE, "Teletype");
910 Initialize(wxSWISS, wxSWISS, "Swiss");
911 Initialize(wxSCRIPT, wxSCRIPT, "Script");
912}
913
914void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
915{
916 char *fam, resource[256];
8bbe427f 917
c801d85f 918 sprintf(resource, "Family%s", resname);
c67daf87 919 SearchResource((const char *)resource, (const char **) NULL, 0, (char **)&fam);
5705323e 920
358fc25c
RR
921 if (fam)
922 {
8bbe427f
VZ
923 if (!strcmp(fam, "Default")) family = wxDEFAULT;
924 else if (!strcmp(fam, "Roman")) family = wxROMAN;
925 else if (!strcmp(fam, "Decorative")) family = wxDECORATIVE;
926 else if (!strcmp(fam, "Modern")) family = wxMODERN;
927 else if (!strcmp(fam, "Teletype")) family = wxTELETYPE;
928 else if (!strcmp(fam, "Swiss")) family = wxSWISS;
929 else if (!strcmp(fam, "Script")) family = wxSCRIPT;
930 delete[] fam; // free resource
c801d85f
KB
931 }
932 table->Put(fontid, new wxFontNameItem(resname, fontid, family));
933}
934
935int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
936{
937 int id;
5705323e 938
c801d85f
KB
939 // font exists -> return id
940 if ( (id = GetFontId(name)) ) return id;
358fc25c 941
c801d85f
KB
942 // create new font
943 Initialize(id=GetNewFontId(), family, name);
944 return id;
945}
946
947char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
948{
949 wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
950 if (item)
8bbe427f 951 return item->GetScreenName(weight, style);
358fc25c 952
c801d85f 953 // font does not exist
c67daf87 954 return (char *) NULL;
c801d85f
KB
955}
956
957char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
958{
959 wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
960 if (item)
8bbe427f 961 return item->GetPostScriptName(weight, style);
358fc25c 962
c801d85f 963 // font does not exist
c67daf87 964 return (char *) NULL;
c801d85f
KB
965}
966
967char *wxFontNameDirectory::GetAFMName(int fontid, int weight, int style)
968{
969 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
970 if (item)
8bbe427f 971 return item->GetAFMName(weight, style);
c801d85f 972 // font does not exist
c67daf87 973 return (char *) NULL;
c801d85f
KB
974}
975
976char *wxFontNameDirectory::GetFontName(int fontid)
977{
978 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
979 if (item)
8bbe427f 980 return item->GetName();
358fc25c 981
c801d85f 982 // font does not exist
c67daf87 983 return (char *) NULL;
c801d85f
KB
984}
985
986int wxFontNameDirectory::GetFontId(const char *name)
987{
988 wxNode *node;
989
990 table->BeginFind();
991
358fc25c
RR
992 while ( (node = table->Next()) )
993 {
8bbe427f
VZ
994 wxFontNameItem *item = (wxFontNameItem*)node->Data();
995 if (!strcmp(name, item->name))
996 return item->id;
c801d85f 997 }
358fc25c 998
c801d85f
KB
999 // font does not exist
1000 return 0;
1001}
1002
1003int wxFontNameDirectory::GetFamily(int fontid)
1004{
1005 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid);
8bbe427f 1006
c801d85f 1007 if (item)
8bbe427f 1008 return item->family;
358fc25c 1009
c801d85f
KB
1010 // font does not exist
1011 return wxDEFAULT;
1012}
36b3b54a
RR
1013
1014*/