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