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