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