]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/font.cpp
no message
[wxWidgets.git] / src / gtk1 / font.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose:
4// Author: Robert Roebling
01111366 5// Id: $id$
c801d85f
KB
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
a3622daa 22extern wxFontNameDirectory *wxTheFontNameDirectory;
c801d85f
KB
23
24//-----------------------------------------------------------------------------
25// wxFont
26//-----------------------------------------------------------------------------
27
28class 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
48wxFontRefData::wxFontRefData(void) : m_scaled_xfonts(wxKEY_INTEGER)
49{
50 m_byXFontName = FALSE;
d84eb083
RR
51 m_pointSize = 12;
52 m_family = wxSWISS;
53 m_style = wxNORMAL;
54 m_weight = wxNORMAL;
c801d85f
KB
55 m_underlined = FALSE;
56 m_fontId = 0;
c67daf87
UR
57 m_faceName = (char *) NULL;
58 m_font = (GdkFont *) NULL;
ff7b1510 59}
c801d85f
KB
60
61wxFontRefData::~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;
ff7b1510 70 }
c801d85f
KB
71 if (m_faceName)
72 {
73 delete m_faceName;
c67daf87 74 m_faceName = (char *) NULL;
ff7b1510 75 }
c801d85f 76 if (m_font) gdk_font_unref( m_font );
ff7b1510 77}
c801d85f
KB
78
79//-----------------------------------------------------------------------------
80
81#define M_FONTDATA ((wxFontRefData *)m_refData)
82
83IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
84
85wxFont::wxFont(void)
86{
87 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 88}
c801d85f
KB
89
90wxFont::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 );
ff7b1510 98}
c801d85f
KB
99
100wxFont::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 {
a3622daa
VZ
107 M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, FontIdOrFamily );
108 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
c801d85f
KB
109 }
110 else
111 {
112 M_FONTDATA->m_fontId = FontIdOrFamily;
a3622daa 113 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
ff7b1510 114 }
d84eb083 115 if (Style == wxDEFAULT) Style = wxSWISS;
c801d85f 116 M_FONTDATA->m_style = Style;
d84eb083 117 if (Weight == wxDEFAULT) Weight = wxNORMAL;
c801d85f 118 M_FONTDATA->m_weight = Weight;
d84eb083 119 if (PointSize == wxDEFAULT) PointSize = 10;
c801d85f
KB
120 M_FONTDATA->m_pointSize = PointSize;
121 M_FONTDATA->m_underlined = Underlined;
122
123 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 124}
c801d85f
KB
125
126wxFont::wxFont(int PointSize, const char *Face, int Family, int Style,
127 int Weight, bool Underlined)
128{
129 m_refData = new wxFontRefData();
130
a3622daa 131 M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, Family );
c801d85f 132 M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL;
a3622daa 133 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( M_FONTDATA->m_fontId );
c801d85f
KB
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 );
ff7b1510 140}
c801d85f
KB
141
142wxFont::wxFont( const wxFont& font )
143{
144 Ref( font );
52cbfcf0
RR
145
146 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 147}
c801d85f
KB
148
149wxFont::wxFont( const wxFont* font )
150{
151 UnRef();
152 if (font) Ref( *font );
52cbfcf0
RR
153
154 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 155}
c801d85f
KB
156
157wxFont::~wxFont(void)
158{
159 if (wxTheFontList) wxTheFontList->DeleteObject( this );
ff7b1510 160}
c801d85f
KB
161
162wxFont& wxFont::operator = ( const wxFont& font )
163{
164 if (*this == font) return (*this);
165 Ref( font );
166 return *this;
ff7b1510 167}
c801d85f
KB
168
169bool wxFont::operator == ( const wxFont& font )
170{
171 return m_refData == font.m_refData;
ff7b1510 172}
c801d85f
KB
173
174bool wxFont::operator != ( const wxFont& font )
175{
176 return m_refData != font.m_refData;
ff7b1510 177}
c801d85f 178
d84eb083 179bool wxFont::Ok() const
c801d85f 180{
e55ad60e 181 return (m_refData != NULL);
ff7b1510 182}
c801d85f
KB
183
184int wxFont::GetPointSize(void) const
185{
e55ad60e
RR
186 if (!Ok())
187 {
188 wxFAIL_MSG( "invalid font" );
189 return 0;
190 }
d84eb083 191
c801d85f 192 return M_FONTDATA->m_pointSize;
ff7b1510 193}
c801d85f
KB
194
195wxString wxFont::GetFaceString(void) const
196{
e55ad60e
RR
197 if (!Ok())
198 {
199 wxFAIL_MSG( "invalid font" );
200 return "";
201 }
d84eb083 202
a3622daa 203 wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
c801d85f 204 return s;
ff7b1510 205}
c801d85f
KB
206
207wxString wxFont::GetFaceName(void) const
208{
e55ad60e
RR
209 if (!Ok())
210 {
211 wxFAIL_MSG( "invalid font" );
212 return "";
213 }
d84eb083 214
a3622daa 215 wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
c801d85f 216 return s;
ff7b1510 217}
c801d85f
KB
218
219int wxFont::GetFamily(void) const
220{
e55ad60e
RR
221 if (!Ok())
222 {
223 wxFAIL_MSG( "invalid font" );
224 return 0;
225 }
d84eb083 226
c801d85f 227 return M_FONTDATA->m_family;
ff7b1510 228}
c801d85f
KB
229
230wxString wxFont::GetFamilyString(void) const
231{
e55ad60e
RR
232 if (!Ok())
233 {
234 wxFAIL_MSG( "invalid font" );
235 return "wxDEFAULT";
236 }
d84eb083
RR
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";
ff7b1510 250}
c801d85f
KB
251
252int wxFont::GetFontId(void) const
253{
e55ad60e
RR
254 if (!Ok())
255 {
256 wxFAIL_MSG( "invalid font" );
257 return 0;
258 }
d84eb083 259
c801d85f 260 return M_FONTDATA->m_fontId; // stub
ff7b1510 261}
c801d85f
KB
262
263int wxFont::GetStyle(void) const
264{
e55ad60e
RR
265 if (!Ok())
266 {
267 wxFAIL_MSG( "invalid font" );
268 return 0;
269 }
d84eb083 270
c801d85f 271 return M_FONTDATA->m_style;
ff7b1510 272}
c801d85f
KB
273
274wxString wxFont::GetStyleString(void) const
275{
e55ad60e
RR
276 if (!Ok())
277 {
278 wxFAIL_MSG( "invalid font" );
279 return "wxDEFAULT";
280 }
d84eb083
RR
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");
ff7b1510 291}
c801d85f
KB
292
293int wxFont::GetWeight(void) const
294{
e55ad60e
RR
295 if (!Ok())
296 {
297 wxFAIL_MSG( "invalid font" );
298 return 0;
299 }
d84eb083 300
c801d85f 301 return M_FONTDATA->m_weight;
ff7b1510 302}
c801d85f
KB
303
304wxString wxFont::GetWeightString(void) const
305{
e55ad60e
RR
306 if (!Ok())
307 {
308 wxFAIL_MSG( "invalid font" );
309 return "wxDEFAULT";
310 }
d84eb083
RR
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");
ff7b1510 321}
c801d85f
KB
322
323bool wxFont::GetUnderlined(void) const
324{
e55ad60e
RR
325 if (!Ok())
326 {
327 wxFAIL_MSG( "invalid font" );
328 return FALSE;
329 }
d84eb083 330
c801d85f 331 return M_FONTDATA->m_underlined;
ff7b1510 332}
c801d85f
KB
333
334//-----------------------------------------------------------------------------
335// get internal representation of font
336//-----------------------------------------------------------------------------
337
338// local help function
339static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
340 int style, int weight,
341 bool underlined);
342
c33c4050 343GdkFont *wxFont::GetInternalFont(float scale) const
c801d85f 344{
e55ad60e
RR
345 if (!Ok())
346 {
347 wxFAIL_MSG( "invalid font" );
348 return (GdkFont*) NULL;
349 }
350
c801d85f
KB
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;
c67daf87 355 GdkFont *font = (GdkFont *) NULL;
c801d85f
KB
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 );
ff7b1510 367 }
c801d85f
KB
368 if (!font)
369 printf("could not load any font");
370// wxError("could not load any font", "wxFont");
371 return font;
ff7b1510 372}
c801d85f
KB
373
374//-----------------------------------------------------------------------------
375// local utilities to find a X font
376//-----------------------------------------------------------------------------
377
378static GdkFont *wxLoadQueryFont(int point_size, int fontid, int style,
379 int weight, bool WXUNUSED(underlined))
380{
381 char buffer[512];
a3622daa 382 char *name = wxTheFontNameDirectory->GetScreenName( fontid, weight, style );
c801d85f
KB
383
384 if (!name)
385 name = "-*-*-*-*-*-*-*-%d-*-*-*-*-*-*";
386 sprintf(buffer, name, point_size);
387
388 return gdk_font_load( buffer );
389}
390
391static 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
427static 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}",
c67daf87 528 (char *) NULL
c801d85f
KB
529};
530
531enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD, wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
532enum {wxSTYLE_NORMAL, wxSTYLE_ITALIC, wxSTYLE_SLANT, wxNUM_STYLES};
533
534static 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 }
ff7b1510 542};
c801d85f
KB
543
544static 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 }
ff7b1510 552};
c801d85f
KB
553
554//-----------------------------------------------------------------------------
555// wxSuffixMap
556//-----------------------------------------------------------------------------
557
558class wxSuffixMap {
559public:
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
575static 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
c67daf87
UR
582 *v = (char *) NULL;
583 internal = (char *) NULL;
c801d85f
KB
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
610wxSuffixMap::~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];
c67daf87 618 map[k][j] = (char *) NULL;
c801d85f
KB
619 }
620}
621
622void 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;
c67daf87 661 const char *r = (char *) NULL; bool delete_r = FALSE;
c801d85f
KB
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
731class wxFontNameItem : public wxObject {
732DECLARE_DYNAMIC_CLASS(wxFontNameItem)
733public:
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
755IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
756
757wxFontNameItem::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
768wxFontNameItem::~wxFontNameItem(void)
769{
770 if (name)
771 delete[] name;
c67daf87 772 name = (char *) NULL;
c801d85f
KB
773}
774
775#if WXDEBUG
776void wxFontNameItem::Dump(ostream& str)
777{
778 str << "wxFontNameItem(" << name << ")";
779}
780#endif
781
782//-----------------------------------------------------------------------------
783// wxFontDirectory
784//-----------------------------------------------------------------------------
785
786IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
787
788wxFontNameDirectory::wxFontNameDirectory(void)
789{
790 table = new wxHashTable(wxKEY_INTEGER, 20);
791 nextFontId = -1;
c801d85f
KB
792}
793
794wxFontNameDirectory::~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
807int wxFontNameDirectory::GetNewFontId(void)
808{
809 return (nextFontId--);
810}
811
812void 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
823void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
824{
825 char *fam, resource[256];
826
827 sprintf(resource, "Family%s", resname);
c67daf87 828 SearchResource((const char *)resource, (const char **) NULL, 0, (char **)&fam);
c801d85f
KB
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
842int 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
853char *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
c67daf87 859 return (char *) NULL;
c801d85f
KB
860}
861
862char *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
c67daf87 868 return (char *) NULL;
c801d85f
KB
869}
870
871char *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
c67daf87 877 return (char *) NULL;
c801d85f
KB
878}
879
880char *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
c67daf87 886 return (char *) NULL;
c801d85f
KB
887}
888
889int 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
904int 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}