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