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