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