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