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