1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "font.h"
25 #include "wx/gdicmn.h"
26 #include "wx/tokenzr.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 #if wxUSE_FONTNAMEDIRECTORY
37 extern wxFontNameDirectory
*wxTheFontNameDirectory
;
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 // returns TRUE if there are any fonts matching this font spec
45 static bool wxTestFontSpec(const wxString
& fontspec
);
47 static GdkFont
*wxLoadQueryFont( int pointSize
,
52 const wxString
&facename
,
53 wxFontEncoding encoding
);
55 static GdkFont
*wxLoadQueryNearestFont( int pointSize
,
60 const wxString
&facename
,
61 wxFontEncoding encoding
);
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
67 class wxFontRefData
: public wxObjectRefData
70 wxFontRefData(int size
= wxDEFAULT
,
71 int family
= wxDEFAULT
,
72 int style
= wxDEFAULT
,
73 int weight
= wxDEFAULT
,
74 bool underlined
= FALSE
,
75 const wxString
& faceName
= wxEmptyString
,
76 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
77 : m_scaled_xfonts(wxKEY_INTEGER
)
79 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
82 wxFontRefData( const wxFontRefData
& data
);
84 virtual ~wxFontRefData();
87 // common part of all ctors
88 void Init(int pointSize
,
93 const wxString
& faceName
,
94 wxFontEncoding encoding
);
97 wxList m_scaled_xfonts
;
105 wxFontEncoding m_encoding
;
113 // ============================================================================
115 // ============================================================================
117 // ----------------------------------------------------------------------------
119 // ----------------------------------------------------------------------------
121 void wxFontRefData::Init(int pointSize
,
126 const wxString
& faceName
,
127 wxFontEncoding encoding
)
129 if (family
== wxDEFAULT
)
134 m_faceName
= faceName
;
136 if (style
== wxDEFAULT
)
141 if (weight
== wxDEFAULT
)
146 if (pointSize
== wxDEFAULT
)
149 m_pointSize
= pointSize
;
151 m_underlined
= underlined
;
152 m_encoding
= encoding
;
154 m_byXFontName
= FALSE
;
155 m_font
= (GdkFont
*) NULL
;
158 wxFontRefData::wxFontRefData( const wxFontRefData
& data
)
159 : m_scaled_xfonts(wxKEY_INTEGER
)
161 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
162 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
165 m_font
= gdk_font_ref( data
.m_font
);
168 wxFontRefData::~wxFontRefData()
170 wxNode
*node
= m_scaled_xfonts
.First();
173 GdkFont
*font
= (GdkFont
*)node
->Data();
174 wxNode
*next
= node
->Next();
175 gdk_font_unref( font
);
180 gdk_font_unref( m_font
);
183 // ----------------------------------------------------------------------------
185 // ----------------------------------------------------------------------------
187 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
192 wxTheFontList
->Append( this );
195 wxFont::wxFont( GdkFont
*font
, char *xFontName
)
200 // VZ: this ctor ddidn't append the font to wxTheFontList before, but
201 // there is no reason to not do it, is there?
204 m_refData
= new wxFontRefData();
206 // M_FONTDATA->m_byXFontName = TRUE;
207 M_FONTDATA
->m_font
= font
;
211 wxString
fontname( xFontName
);
212 wxStringTokenizer
tn( fontname
, _T("-") );
214 tn
.GetNextToken(); // foundry
216 M_FONTDATA
->m_faceName
= tn
.GetNextToken(); // courier
218 tmp
= tn
.GetNextToken().MakeUpper();
219 if (tmp
== _T("BOLD")) M_FONTDATA
->m_weight
= wxBOLD
;
221 tmp
= tn
.GetNextToken().MakeUpper();
222 if (tmp
== _T("I")) M_FONTDATA
->m_style
= wxITALIC
;
223 if (tmp
== _T("O")) M_FONTDATA
->m_style
= wxITALIC
;
225 tn
.GetNextToken(); // set width
226 tn
.GetNextToken(); // ?
227 tn
.GetNextToken(); // pixel size
229 tmp
= tn
.GetNextToken(); // pointsize
230 int num
= wxStrtol (tmp
.c_str(), (wxChar
**) NULL
, 10);
231 M_FONTDATA
->m_pointSize
= num
/ 10;
233 tn
.GetNextToken(); // x-res
234 tn
.GetNextToken(); // y-res
236 tmp
= tn
.GetNextToken().MakeUpper();
237 if (tmp
== _T("M")) M_FONTDATA
->m_family
= wxMODERN
;
238 else if (M_FONTDATA
->m_faceName
== _T("TIMES")) M_FONTDATA
->m_family
= wxROMAN
;
239 else if (M_FONTDATA
->m_faceName
== _T("HELVETICA")) M_FONTDATA
->m_family
= wxSWISS
;
240 else if (M_FONTDATA
->m_faceName
== _T("LUCIDATYPEWRITER")) M_FONTDATA
->m_family
= wxTELETYPE
;
241 else if (M_FONTDATA
->m_faceName
== _T("LUCIDA")) M_FONTDATA
->m_family
= wxDECORATIVE
;
242 else if (M_FONTDATA
->m_faceName
== _T("UTOPIA")) M_FONTDATA
->m_family
= wxSCRIPT
;
245 bool wxFont::Create( int pointSize
,
250 const wxString
& face
,
251 wxFontEncoding encoding
)
253 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
254 underlined
, face
, encoding
);
261 void wxFont::Unshare()
265 m_refData
= new wxFontRefData();
269 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
278 wxTheFontList
->DeleteObject( this );
281 // ----------------------------------------------------------------------------
283 // ----------------------------------------------------------------------------
285 int wxFont::GetPointSize() const
287 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
289 return M_FONTDATA
->m_pointSize
;
292 wxString
wxFont::GetFaceName() const
294 wxCHECK_MSG( Ok(), _T(""), _T("invalid font") );
296 return M_FONTDATA
->m_faceName
;
299 int wxFont::GetFamily() const
301 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
303 return M_FONTDATA
->m_family
;
306 int wxFont::GetStyle() const
308 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
310 return M_FONTDATA
->m_style
;
313 int wxFont::GetWeight() const
315 wxCHECK_MSG( Ok(), 0, _T("invalid font") );
317 return M_FONTDATA
->m_weight
;
320 bool wxFont::GetUnderlined() const
322 wxCHECK_MSG( Ok(), FALSE
, _T("invalid font") );
324 return M_FONTDATA
->m_underlined
;
328 wxFontEncoding
wxFont::GetEncoding() const
330 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, _T("invalid font") );
332 return M_FONTDATA
->m_encoding
;
335 // ----------------------------------------------------------------------------
336 // change font attributes
337 // ----------------------------------------------------------------------------
339 void wxFont::SetPointSize(int pointSize
)
343 M_FONTDATA
->m_pointSize
= pointSize
;
346 void wxFont::SetFamily(int family
)
350 M_FONTDATA
->m_family
= family
;
353 void wxFont::SetStyle(int style
)
357 M_FONTDATA
->m_style
= style
;
360 void wxFont::SetWeight(int weight
)
364 M_FONTDATA
->m_weight
= weight
;
367 void wxFont::SetFaceName(const wxString
& faceName
)
371 M_FONTDATA
->m_faceName
= faceName
;
374 void wxFont::SetUnderlined(bool underlined
)
378 M_FONTDATA
->m_underlined
= underlined
;
381 void wxFont::SetEncoding(wxFontEncoding encoding
)
385 M_FONTDATA
->m_encoding
= encoding
;
388 // ----------------------------------------------------------------------------
389 // get internal representation of font
390 // ----------------------------------------------------------------------------
392 GdkFont
*wxFont::GetInternalFont( float scale
) const
396 wxFAIL_MSG( _T("invalid font") );
398 return (GdkFont
*) NULL
;
401 /* short cut if the special X font constructor has been used */
402 if (M_FONTDATA
->m_byXFontName
)
403 return M_FONTDATA
->m_font
;
405 long int_scale
= long(scale
* 100.0 + 0.5); /* key for fontlist */
406 int point_scale
= (M_FONTDATA
->m_pointSize
* 10 * int_scale
) / 100;
407 GdkFont
*font
= (GdkFont
*) NULL
;
409 wxNode
*node
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
);
412 font
= (GdkFont
*)node
->Data();
417 if ((int_scale
== 100) &&
418 (M_FONTDATA
->m_family
== wxSWISS
) &&
419 (M_FONTDATA
->m_style
== wxNORMAL
) &&
420 (M_FONTDATA
->m_pointSize
== 12) &&
421 (M_FONTDATA
->m_weight
== wxNORMAL
) &&
422 (M_FONTDATA
->m_underlined
== FALSE
))
424 font
= gdk_font_load( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
429 font
= wxLoadQueryNearestFont( point_scale
,
430 M_FONTDATA
->m_family
,
432 M_FONTDATA
->m_weight
,
433 M_FONTDATA
->m_underlined
,
434 M_FONTDATA
->m_faceName
,
435 M_FONTDATA
->m_encoding
);
438 M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font
);
443 wxLogError(_T("could not load any font"));
449 //-----------------------------------------------------------------------------
450 // local utilities to find a X font
451 //-----------------------------------------------------------------------------
453 // returns TRUE if there are any fonts matching this font spec
454 static bool wxTestFontSpec(const wxString
& fontSpec
)
456 GdkFont
*test
= gdk_font_load( wxConvCurrent
->cWX2MB(fontSpec
) );
459 gdk_font_unref( test
);
469 static GdkFont
*wxLoadQueryFont( int pointSize
,
473 bool WXUNUSED(underlined
),
474 const wxString
&facename
,
475 wxFontEncoding encoding
)
480 case wxDECORATIVE
: xfamily
= _T("lucida"); break;
481 case wxROMAN
: xfamily
= _T("times"); break;
482 case wxMODERN
: xfamily
= _T("courier"); break;
483 case wxSWISS
: xfamily
= _T("helvetica"); break;
484 case wxTELETYPE
: xfamily
= _T("lucidatypewriter"); break;
485 case wxSCRIPT
: xfamily
= _T("utopia"); break;
486 default: xfamily
= _T("*");
490 if (!facename
.IsEmpty())
492 fontSpec
.Printf(_T("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
495 if ( wxTestFontSpec(fontSpec
) )
499 //else: no such family, use default one instead
505 case wxITALIC
: xstyle
= _T("i"); break;
506 case wxSLANT
: xstyle
= _T("o"); break;
507 case wxNORMAL
: xstyle
= _T("r"); break;
508 default: xstyle
= _T("*"); break;
514 case wxBOLD
: xweight
= _T("bold"); break;
516 case wxNORMAL
: xweight
= _T("medium"); break;
517 default: xweight
= _T("*"); break;
520 wxString xregistry
, xencoding
;
521 if ( encoding
== wxFONTENCODING_DEFAULT
)
523 // use the apps default
524 encoding
= wxFont::GetDefaultEncoding();
527 bool test
= TRUE
; // should we test for availability of encoding?
530 case wxFONTENCODING_ISO8859_1
:
531 case wxFONTENCODING_ISO8859_2
:
532 case wxFONTENCODING_ISO8859_3
:
533 case wxFONTENCODING_ISO8859_4
:
534 case wxFONTENCODING_ISO8859_5
:
535 case wxFONTENCODING_ISO8859_6
:
536 case wxFONTENCODING_ISO8859_7
:
537 case wxFONTENCODING_ISO8859_8
:
538 case wxFONTENCODING_ISO8859_9
:
539 case wxFONTENCODING_ISO8859_10
:
540 case wxFONTENCODING_ISO8859_11
:
541 case wxFONTENCODING_ISO8859_13
:
542 case wxFONTENCODING_ISO8859_14
:
543 case wxFONTENCODING_ISO8859_15
:
545 int cp
= encoding
- wxFONTENCODING_ISO8859_1
+ 1;
546 xregistry
= _T("iso8859");
547 xencoding
.Printf(_T("%d"), cp
);
551 case wxFONTENCODING_KOI8
:
552 xregistry
= _T("koi8");
553 if ( wxTestFontSpec(_T("-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1")) )
557 // test passed, no need to do it once more
566 case wxFONTENCODING_CP1250
:
567 case wxFONTENCODING_CP1251
:
568 case wxFONTENCODING_CP1252
:
570 int cp
= encoding
- wxFONTENCODING_CP1250
+ 1250;
571 fontSpec
.Printf(_T("-*-*-*-*-*-*-*-*-*-*-*-*-microsoft-cp%d"),
573 if ( wxTestFontSpec(fontSpec
) )
575 xregistry
= _T("microsoft");
576 xencoding
.Printf(_T("cp%d"), cp
);
578 // test passed, no need to do it once more
583 // fall back to LatinX
584 xregistry
= _T("iso8859");
585 xencoding
.Printf(_T("%d"), cp
- 1249);
590 case wxFONTENCODING_SYSTEM
:
599 fontSpec
.Printf(_T("-*-*-*-*-*-*-*-*-*-*-*-*-%s-%s"),
600 xregistry
.c_str(), xencoding
.c_str());
601 if ( !wxTestFontSpec(fontSpec
) )
603 // this encoding isn't available - what to do?
609 // construct the X font spec from our data
610 fontSpec
.Printf(_T("-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-%s-%s"),
611 xfamily
.c_str(), xweight
.c_str(), xstyle
.c_str(),
612 pointSize
, xregistry
.c_str(), xencoding
.c_str());
614 return gdk_font_load( wxConvCurrent
->cWX2MB(fontSpec
) );
617 static GdkFont
*wxLoadQueryNearestFont( int pointSize
,
622 const wxString
&facename
,
623 wxFontEncoding encoding
)
625 GdkFont
*font
= wxLoadQueryFont( pointSize
, family
, style
, weight
,
626 underlined
, facename
, encoding
);
630 /* search up and down by stepsize 10 */
631 int max_size
= pointSize
+ 20 * (1 + (pointSize
/180));
632 int min_size
= pointSize
- 20 * (1 + (pointSize
/180));
636 /* Search for smaller size (approx.) */
637 for ( i
= pointSize
- 10; !font
&& i
>= 10 && i
>= min_size
; i
-= 10 )
639 font
= wxLoadQueryFont(i
, family
, style
, weight
, underlined
,
640 facename
, encoding
);
643 /* Search for larger size (approx.) */
644 for ( i
= pointSize
+ 10; !font
&& i
<= max_size
; i
+= 10 )
646 font
= wxLoadQueryFont( i
, family
, style
, weight
, underlined
,
647 facename
, encoding
);
650 /* Try default family */
651 if ( !font
&& family
!= wxDEFAULT
)
653 font
= wxLoadQueryFont( pointSize
, wxDEFAULT
, style
, weight
,
654 underlined
, facename
, encoding
);
660 font
= wxLoadQueryFont(120, wxDEFAULT
, wxNORMAL
, wxNORMAL
,
661 underlined
, facename
, encoding
);
668 // wow, what's this stuff? Is it used/useful? (VZ)
671 //-----------------------------------------------------------------------------
672 // face names and index functions
673 //-----------------------------------------------------------------------------
675 static char *font_defaults
[] = {
676 "FamilyDefault", "Default",
677 "FamilyRoman", "Roman",
678 "FamilyDecorative", "Decorative",
679 "FamilyModern", "Modern",
680 "FamilyTeletype", "Teletype",
681 "FamilySwiss", "Swiss",
682 "FamilyScript", "Script",
688 "AfmItalic", "${AfmSlant}",
692 "AfmHelvetica", "Helv",
693 "AfmCourier", "Cour",
695 "Afm___", "${AfmTimes,$[weight],$[style]}",
697 "AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
698 "AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
699 "AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
700 "AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
701 "AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
703 "AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
704 "AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
706 "AfmTeletype__", "${AfmModern,$[weight],$[style]}",
708 "PostScriptMediumStraight", "",
709 "PostScriptMediumItalic", "-Oblique",
710 "PostScriptMediumSlant", "-Oblique",
711 "PostScriptLightStraight", "",
712 "PostScriptLightItalic", "-Oblique",
713 "PostScriptLightSlant", "-Oblique",
714 "PostScriptBoldStraight", "-Bold",
715 "PostScriptBoldItalic", "-BoldOblique",
716 "PostScriptBoldSlant", "-BoldOblique",
718 #if WX_NORMALIZED_PS_FONTS
719 "PostScript___", "${PostScriptTimes,$[weight],$[style]}",
721 "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
722 "PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
725 "PostScriptTimesMedium", "",
726 "PostScriptTimesLight", "",
727 "PostScriptTimesBold", "Bold",
729 "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
730 "PostScriptTimesMediumStraight", "Times-Roman",
731 "PostScriptTimesLightStraight", "Times-Roman",
732 "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
733 "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
735 "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
736 "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
738 "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
740 #if !WX_NORMALIZED_PS_FONTS
741 "PostScriptScript__", "Zapf-Chancery-MediumItalic",
744 "ScreenMedium", "medium",
745 "ScreenBold", "bold",
746 "ScreenLight", "light",
747 "ScreenStraight", "r",
751 "ScreenDefaultBase", "*-times",
753 "ScreenRomanBase", "*-times",
754 "ScreenDecorativeBase", "*-helvetica",
755 "ScreenModernBase", "*-courier",
756 "ScreenTeletypeBase", "*-lucidatypewriter",
757 "ScreenSwissBase", "*-lucida",
758 "ScreenScriptBase", "*-zapfchancery",
760 "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
761 "-normal-*-*-%d-*-*-*-*-*-*",
764 "-${ScreenDefaultBase}${ScreenStdSuffix}",
766 "-${ScreenRomanBase}${ScreenStdSuffix}",
767 "ScreenDecorative__",
768 "-${ScreenDecorativeBase}${ScreenStdSuffix}",
770 "-${ScreenModernBase}${ScreenStdSuffix}",
772 "-${ScreenTeletypeBase}${ScreenStdSuffix}",
774 "-${ScreenSwissBase}${ScreenStdSuffix}",
776 "-${ScreenScriptBase}${ScreenStdSuffix}",
780 enum {wxWEIGHT_NORMAL
, wxWEIGHT_BOLD
, wxWEIGHT_LIGHT
, wxNUM_WEIGHTS
};
781 enum {wxSTYLE_NORMAL
, wxSTYLE_ITALIC
, wxSTYLE_SLANT
, wxNUM_STYLES
};
783 static int WCoordinate(int w
)
787 case wxBOLD
: return wxWEIGHT_BOLD
;
788 case wxLIGHT
: return wxWEIGHT_LIGHT
;
790 default: return wxWEIGHT_NORMAL
;
794 static int SCoordinate(int s
)
798 case wxITALIC
: return wxSTYLE_ITALIC
;
799 case wxSLANT
: return wxSTYLE_SLANT
;
801 default: return wxSTYLE_NORMAL
;
805 //-----------------------------------------------------------------------------
807 //-----------------------------------------------------------------------------
814 inline char *GetName(int weight
, int style
)
816 return ( map
[WCoordinate(weight
)] [SCoordinate(style
)] );
819 char *map
[wxNUM_WEIGHTS
][wxNUM_STYLES
];
820 void Initialize(const char *, const char *);
823 static void SearchResource(const char *prefix
, const char **names
, int count
, char **v
)
826 char resource
[1024], **defaults
, *internal
;
831 internal
= (char *) NULL
;
833 for (i
= 0; i
< k
; i
++)
835 strcpy(resource
, prefix
);
836 for (j
= 0; j
< count
; j
++)
838 // upon failure to find a matching fontname
839 // in the default fonts above, we substitute more
840 // and more values by _ so that at last ScreenMyFontBoldNormal
841 // would turn into Screen___ and this will then get
842 // converted to -${ScreenDefaultBase}${ScreenStdSuffix}
845 strcat(resource
, names
[j
]);
847 strcat(resource
, "_");
850 // we previously search the Xt-resources here
854 defaults
= font_defaults
;
857 if (!strcmp(*defaults
, resource
))
859 internal
= defaults
[1];
869 if ((strcmp(internal
,"-${ScreenDefaultBase}${ScreenStdSuffix}") == 0) &&
870 (strcmp(names
[0], "Default") != 0))
872 // we did not find any font name in the standard list.
873 // this can (hopefully does) mean that someone supplied
874 // the facename in the wxFont constructor so we insert
877 strcpy( resource
,"-*-" ); // any producer
878 strcat( resource
, names
[0] ); // facename
879 strcat( resource
, "${ScreenStdSuffix}" ); // add size params later on
880 *v
= copystring(resource
);
884 *v
= copystring(internal
);
889 wxSuffixMap::~wxSuffixMap()
893 for (k
= 0; k
< wxNUM_WEIGHTS
; ++k
)
894 for (j
= 0; j
< wxNUM_STYLES
; ++j
)
898 map
[k
][j
] = (char *) NULL
;
902 void wxSuffixMap::Initialize(const char *resname
, const char *devresname
)
904 const char *weight
, *style
;
907 const char *names
[3];
909 for (k
= 0; k
< wxNUM_WEIGHTS
; k
++)
913 case wxWEIGHT_NORMAL
: weight
= "Medium"; break;
914 case wxWEIGHT_LIGHT
: weight
= "Light"; break;
916 default: weight
= "Bold";
918 for (j
= 0; j
< wxNUM_STYLES
; j
++)
922 case wxSTYLE_NORMAL
: style
= "Straight"; break;
923 case wxSTYLE_ITALIC
: style
= "Italic"; break;
925 default: style
= "Slant";
931 SearchResource(devresname
, names
, 3, &v
);
933 // Expand macros in the found string:
935 int len
, closer
= 0, startpos
= 0;
937 len
= (v
? strlen(v
) : 0);
938 for (i
= 0; i
< len
; i
++)
940 if (v
[i
] == '$' && ((v
[i
+1] == '[') || (v
[i
+1] == '{')))
943 closer
= (v
[i
+1] == '[') ? ']' : '}';
946 else if (v
[i
] == closer
)
949 const char *r
= (char *) NULL
; bool delete_r
= FALSE
;
952 name
= v
+ startpos
+ 2;
960 for (i
= 0, count
= 1; name
[i
]; i
++)
966 names
= new char*[count
];
968 for (i
= 0, count
= 1; i
< len
; i
++)
971 names
[count
++] = name
+ i
+ 1;
975 SearchResource("", (const char **)names
, count
, (char **)&r
);
981 for (i
= 0; i
< len
; i
++)
985 wxLogError( "Bad resource name in font lookup." );
987 } else if (!strcmp(name
, "weight")) {
989 } else if (!strcmp(name
, "style")) {
991 } else if (!strcmp(name
, "family")) {
995 wxLogError( "Bad font macro name." );
999 newstrlen
= strlen(r
);
1000 char *naya
= new char[startpos
+ newstrlen
+ len
- i
];
1001 memcpy(naya
, v
, startpos
);
1002 memcpy(naya
+ startpos
, r
, newstrlen
);
1003 memcpy(naya
+ startpos
+ newstrlen
, v
+ i
+ 1, len
- i
);
1012 // We have a final value:
1018 //-----------------------------------------------------------------------------
1020 //-----------------------------------------------------------------------------
1022 class wxFontNameItem
: public wxObject
1024 DECLARE_DYNAMIC_CLASS(wxFontNameItem
)
1026 wxFontNameItem(const char *name
, int id
, int family
);
1029 inline char* GetScreenName(int w
, int s
) {return screen
.GetName(w
, s
);}
1030 inline char* GetPostScriptName(int w
, int s
) {return printing
.GetName(w
, s
);}
1031 inline char* GetAFMName(int w
, int s
) {return afm
.GetName(w
, s
);}
1032 inline char* GetName() {return name
;}
1033 inline int GetFamily() {return family
;}
1034 inline int GetId() {return id
;}
1035 inline bool IsRoman() {return isroman
;}
1036 #if defined(__WXDEBUG__)
1037 void Dump(ostream
& str
);
1043 wxSuffixMap screen
, printing
, afm
;
1047 IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem
, wxObject
)
1049 wxFontNameItem::wxFontNameItem(const char *Name
, int Id
, int Family
)
1051 name
= copystring(Name
);
1055 screen
. Initialize(name
, "Screen");
1056 printing
.Initialize(name
, "PostScript");
1057 afm
. Initialize(name
, "Afm");
1060 wxFontNameItem::~wxFontNameItem()
1064 name
= (char *) NULL
;
1067 #if defined(__WXDEBUG__)
1068 void wxFontNameItem::Dump(ostream
& str
)
1070 str
<< "wxFontNameItem(" << name
<< ")";
1074 //-----------------------------------------------------------------------------
1076 //-----------------------------------------------------------------------------
1078 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory
, wxObject
)
1080 wxFontNameDirectory::wxFontNameDirectory()
1082 table
= new wxHashTable(wxKEY_INTEGER
, 20);
1086 wxFontNameDirectory::~wxFontNameDirectory()
1088 // Cleanup wxFontNameItems allocated
1090 wxNode
*node
= table
->Next();
1093 wxFontNameItem
*item
= (wxFontNameItem
*)node
->Data();
1095 node
= table
->Next();
1100 int wxFontNameDirectory::GetNewFontId()
1102 return (nextFontId
--);
1105 void wxFontNameDirectory::Initialize()
1107 Initialize(wxDEFAULT
, wxDEFAULT
, "Default");
1108 Initialize(wxDECORATIVE
, wxDECORATIVE
, "Decorative");
1109 Initialize(wxROMAN
, wxROMAN
, "Roman");
1110 Initialize(wxMODERN
, wxMODERN
, "Modern");
1111 Initialize(wxTELETYPE
, wxTELETYPE
, "Teletype");
1112 Initialize(wxSWISS
, wxSWISS
, "Swiss");
1113 Initialize(wxSCRIPT
, wxSCRIPT
, "Script");
1116 void wxFontNameDirectory::Initialize(int fontid
, int family
, const char *resname
)
1118 char *fam
, resource
[256];
1120 sprintf(resource
, "Family%s", resname
);
1121 SearchResource((const char *)resource
, (const char **) NULL
, 0, (char **)&fam
);
1125 if (!strcmp(fam
, "Default")) family
= wxDEFAULT
;
1126 else if (!strcmp(fam
, "Roman")) family
= wxROMAN
;
1127 else if (!strcmp(fam
, "Decorative")) family
= wxDECORATIVE
;
1128 else if (!strcmp(fam
, "Modern")) family
= wxMODERN
;
1129 else if (!strcmp(fam
, "Teletype")) family
= wxTELETYPE
;
1130 else if (!strcmp(fam
, "Swiss")) family
= wxSWISS
;
1131 else if (!strcmp(fam
, "Script")) family
= wxSCRIPT
;
1132 delete[] fam
; // free resource
1134 table
->Put(fontid
, new wxFontNameItem(resname
, fontid
, family
));
1137 int wxFontNameDirectory::FindOrCreateFontId(const char *name
, int family
)
1141 // font exists -> return id
1142 if ( (id
= GetFontId(name
)) ) return id
;
1145 Initialize(id
=GetNewFontId(), family
, name
);
1149 char *wxFontNameDirectory::GetScreenName(int fontid
, int weight
, int style
)
1151 wxFontNameItem
*item
= (wxFontNameItem
*)table
->Get(fontid
); // find font
1153 return item
->GetScreenName(weight
, style
);
1155 // font does not exist
1156 return (char *) NULL
;
1159 char *wxFontNameDirectory::GetPostScriptName(int fontid
, int weight
, int style
)
1161 wxFontNameItem
*item
= (wxFontNameItem
*)table
->Get(fontid
); // find font
1163 return item
->GetPostScriptName(weight
, style
);
1165 // font does not exist
1166 return (char *) NULL
;
1169 char *wxFontNameDirectory::GetAFMName(int fontid
, int weight
, int style
)
1171 wxFontNameItem
*item
= (wxFontNameItem
*)table
->Get(fontid
); // find font
1173 return item
->GetAFMName(weight
, style
);
1174 // font does not exist
1175 return (char *) NULL
;
1178 char *wxFontNameDirectory::GetFontName(int fontid
)
1180 wxFontNameItem
*item
= (wxFontNameItem
*)table
->Get(fontid
); // find font
1182 return item
->GetName();
1184 // font does not exist
1185 return (char *) NULL
;
1188 int wxFontNameDirectory::GetFontId(const char *name
)
1194 while ( (node
= table
->Next()) )
1196 wxFontNameItem
*item
= (wxFontNameItem
*)node
->Data();
1197 if (!strcmp(name
, item
->name
))
1201 // font does not exist
1205 int wxFontNameDirectory::GetFamily(int fontid
)
1207 wxFontNameItem
*item
= (wxFontNameItem
*)table
->Get(fontid
);
1210 return item
->family
;
1212 // font does not exist