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