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