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