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