1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/fontutil.cpp
3 // Purpose: Font helper functions for MGL
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
19 #include "wx/fontutil.h"
20 #include "wx/encinfo.h"
21 #include "wx/fontmap.h"
22 #include "wx/tokenzr.h"
25 #include "wx/listimpl.cpp"
26 #include "wx/sysopt.h"
27 #include "wx/mgl/private.h"
31 // ============================================================================
33 // ============================================================================
35 // ----------------------------------------------------------------------------
36 // wxNativeEncodingInfo
37 // ----------------------------------------------------------------------------
39 // convert to/from the string representation: format is
40 // encoding[;facename]
41 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
43 wxStringTokenizer
tokenizer(s
, _T(";"));
45 wxString encid
= tokenizer
.GetNextToken();
47 if ( !encid
.ToLong(&enc
) )
49 encoding
= (wxFontEncoding
)enc
;
52 facename
= tokenizer
.GetNextToken();
57 wxString
wxNativeEncodingInfo::ToString() const
61 if ( !facename
.empty() )
63 s
<< _T(';') << facename
;
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
74 wxNativeEncodingInfo
*info
)
76 wxCHECK_MSG( info
, false, _T("bad pointer in wxGetNativeFontEncoding") );
78 if ( encoding
== wxFONTENCODING_DEFAULT
)
80 encoding
= wxFont::GetDefaultEncoding();
85 case wxFONTENCODING_ISO8859_1
:
86 case wxFONTENCODING_ISO8859_2
:
87 case wxFONTENCODING_ISO8859_3
:
88 case wxFONTENCODING_ISO8859_4
:
89 case wxFONTENCODING_ISO8859_5
:
90 case wxFONTENCODING_ISO8859_6
:
91 case wxFONTENCODING_ISO8859_7
:
92 case wxFONTENCODING_ISO8859_8
:
93 case wxFONTENCODING_ISO8859_9
:
94 case wxFONTENCODING_ISO8859_10
:
95 case wxFONTENCODING_ISO8859_11
:
96 case wxFONTENCODING_ISO8859_13
:
97 case wxFONTENCODING_ISO8859_14
:
98 case wxFONTENCODING_ISO8859_15
:
99 info
->mglEncoding
= MGL_ENCODING_ISO8859_1
+
100 (encoding
- wxFONTENCODING_ISO8859_1
);
103 case wxFONTENCODING_KOI8
:
104 info
->mglEncoding
= MGL_ENCODING_KOI8
;
107 case wxFONTENCODING_CP1250
:
108 case wxFONTENCODING_CP1251
:
109 case wxFONTENCODING_CP1252
:
110 case wxFONTENCODING_CP1253
:
111 case wxFONTENCODING_CP1254
:
112 case wxFONTENCODING_CP1255
:
113 case wxFONTENCODING_CP1256
:
114 case wxFONTENCODING_CP1257
:
115 info
->mglEncoding
= MGL_ENCODING_CP1250
+
116 (encoding
- wxFONTENCODING_CP1250
);
119 case wxFONTENCODING_SYSTEM
:
120 info
->mglEncoding
= MGL_ENCODING_ASCII
;
124 // encoding not known to MGL
128 info
->encoding
= encoding
;
133 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
135 if ( !info
.facename
)
138 wxMGLFontFamily
*family
= wxTheFontsManager
->GetFamily(info
.facename
);
141 if ( family
->GetInfo()->fontLibType
== MGL_BITMAPFONT_LIB
)
142 return (info
.mglEncoding
== MGL_ENCODING_ASCII
||
143 info
.mglEncoding
== MGL_ENCODING_ISO8859_1
||
144 info
.mglEncoding
== MGL_ENCODING_ISO8859_15
||
145 info
.mglEncoding
== MGL_ENCODING_CP1252
);
151 // ----------------------------------------------------------------------------
152 // wxFontFamily, wxMGLFontInstance, wxMGLFontLibrary
153 // ----------------------------------------------------------------------------
155 WX_DECLARE_LIST(wxMGLFontInstance
, wxMGLFontInstanceList
);
156 WX_DEFINE_LIST(wxMGLFontInstanceList
);
157 WX_DEFINE_LIST(wxMGLFontFamilyList
);
159 wxMGLFontInstance::wxMGLFontInstance(wxMGLFontLibrary
*fontLib
,
160 float pt
, bool slant
, bool aa
)
168 float slantAngle
= m_slant
? 15.0 : 0.0;
170 wxLogTrace("mgl_font", "loading instance of '%s' slant=%i pt=%0.1f aa=%i",
171 m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
);
172 m_font
= MGL_loadFontInstance(m_fontLib
->GetMGLfont_lib_t(),
173 m_pt
, slantAngle
, 0.0, aa
);
174 wxASSERT_MSG( m_font
, wxT("Cannot create font instance.") );
177 wxMGLFontInstance::~wxMGLFontInstance()
179 wxLogTrace("mgl_font", "unloading instance of '%s' slant=%i pt=%0.1f aa=%i",
180 m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
);
182 MGL_unloadFontInstance(m_font
);
185 wxMGLFontLibrary::wxMGLFontLibrary(const wxString
& filename
, int type
,
186 wxMGLFontFamily
*parentFamily
)
188 m_family
= parentFamily
;
190 m_fileName
= filename
;
194 m_instances
= new wxMGLFontInstanceList
;
195 m_instances
->DeleteContents(true);
198 wxMGLFontLibrary::~wxMGLFontLibrary()
200 wxLogTrace("mgl_font", "font library dtor '%s'", m_fileName
.mb_str());
204 void wxMGLFontLibrary::IncRef()
206 wxLogTrace("mgl_font", "incRef(%u) '%s'", m_refs
, m_fileName
.c_str());
209 wxLogTrace("mgl_font", "opening library '%s'", m_fileName
.mb_str());
210 m_fontLib
= MGL_openFontLib(m_fileName
.mb_str());
214 void wxMGLFontLibrary::DecRef()
216 wxLogTrace("mgl_font", "decRef(%u) '%s'", m_refs
, m_fileName
.c_str());
219 wxLogTrace("mgl_font", "killing instances of '%s'", m_fileName
.mb_str());
220 m_instances
->Clear();
221 wxLogTrace("mgl_font", "closing library '%s'", m_fileName
.mb_str());
222 MGL_closeFontLib(m_fontLib
);
227 static int gs_antialiasingThreshold
= -1;
229 wxMGLFontInstance
*wxMGLFontLibrary::GetFontInstance(wxFont
*font
,
230 float scale
, bool aa
)
232 wxASSERT_MSG(m_refs
> 0 && m_fontLib
, wxT("font library not loaded!"));
235 float pt
= (float)font
->GetPointSize() * scale
;
237 if ( gs_antialiasingThreshold
== -1 )
239 gs_antialiasingThreshold
= 10;
240 #if wxUSE_SYSTEM_OPTIONS
241 if ( wxSystemOptions::HasOption(wxT("mgl.aa-threshold")) )
242 gs_antialiasingThreshold
=
243 wxSystemOptions::GetOptionInt(wxT("mgl.aa-threshold"));
244 wxLogTrace("mgl_font", "AA threshold set to %i", gs_antialiasingThreshold
);
248 // Small characters don't look good when antialiased with the algorithm
249 // that FreeType uses (mere 2x2 supersampling), so lets disable it AA
250 // completely for small fonts.
251 bool antialiased
= false;
252 if (( pt
> gs_antialiasingThreshold
) &&
253 ( m_fontLib
->fontLibType
!= MGL_BITMAPFONT_LIB
) )
256 bool slant
= (((m_type
& wxFONTFACE_ITALIC
) == 0) &&
257 (font
->GetStyle() == wxSLANT
|| font
->GetStyle() == wxITALIC
));
259 // FIXME_MGL -- MGL does not yet support slant, although the API is there
262 wxLogTrace("mgl_font", "requested instance of '%s' slant=%i pt=%0.1f aa=%i",
263 m_fileName
.mb_str(), slant
, pt
, antialiased
);
265 wxMGLFontInstance
*i
;
266 wxMGLFontInstanceList::Node
*node
;
268 for (node
= m_instances
->GetFirst(); node
; node
= node
->GetNext())
271 if ( i
->GetPt() == pt
&& i
->GetSlant() == slant
&&
272 i
->GetAA() == antialiased
)
274 wxLogTrace("mgl_font", " got from cache: slant=%i pt=%0.1f aa=%i",
275 i
->GetSlant(), i
->GetPt(), i
->GetAA());
280 i
= new wxMGLFontInstance(this, pt
, slant
, antialiased
);
281 m_instances
->Append(i
);
286 wxMGLFontFamily::wxMGLFontFamily(const font_info_t
*info
)
288 m_name
= info
->familyName
;
291 if ( info
->regularFace
[0] == '\0' )
292 m_fontLibs
[wxFONTFACE_REGULAR
] = NULL
;
294 m_fontLibs
[wxFONTFACE_REGULAR
] =
295 new wxMGLFontLibrary(info
->regularFace
, wxFONTFACE_REGULAR
, this);
297 if ( info
->italicFace
[0] == '\0' )
298 m_fontLibs
[wxFONTFACE_ITALIC
] = NULL
;
300 m_fontLibs
[wxFONTFACE_ITALIC
] =
301 new wxMGLFontLibrary(info
->italicFace
, wxFONTFACE_ITALIC
, this);
303 if ( info
->boldFace
[0] == '\0' )
304 m_fontLibs
[wxFONTFACE_BOLD
] = NULL
;
306 m_fontLibs
[wxFONTFACE_BOLD
] =
307 new wxMGLFontLibrary(info
->boldFace
, wxFONTFACE_BOLD
, this);
309 if ( info
->boldItalicFace
[0] == '\0' )
310 m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] = NULL
;
312 m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] =
313 new wxMGLFontLibrary(info
->boldItalicFace
, wxFONTFACE_BOLD_ITALIC
, this);
315 wxLogTrace("mgl_font", "new family '%s' (r=%s, i=%s, b=%s, bi=%s)\n",
316 info
->familyName
, info
->regularFace
, info
->italicFace
,
317 info
->boldFace
, info
->boldItalicFace
);
320 wxMGLFontFamily::~wxMGLFontFamily()
322 for (size_t i
= 0; i
< wxFONTFACE_MAX
; i
++)
323 delete m_fontLibs
[i
];
326 bool wxMGLFontFamily::HasFace(int type
) const
328 return (m_fontLibs
[type
] != NULL
);
332 // ----------------------------------------------------------------------------
334 // ----------------------------------------------------------------------------
336 wxMGLFontLibrary
*wxFontsManager::GetFontLibrary(wxFont
*font
)
338 wxMGLFontFamily
*family
;
340 wxString facename
= font
->GetFaceName();
342 if ( !facename
.empty() )
343 family
= GetFamily(facename
);
350 switch (font
->GetFamily())
353 facename
= wxT("Script");
356 facename
= wxT("Charter");
359 facename
= wxT("Times");
363 facename
= wxT("Courier");
366 facename
= wxT("Helvetica");
370 facename
= wxT("Helvetica");
374 family
= GetFamily(facename
);
377 if ( m_list
->GetFirst() )
378 family
= m_list
->GetFirst()->GetData();
380 wxFAIL_MSG(wxT("Fatal error, no fonts available!"));
384 type
= wxFONTFACE_REGULAR
;
386 if ( font
->GetWeight() == wxBOLD
)
387 type
|= wxFONTFACE_BOLD
;
389 // FIXME_MGL -- this should read "if ( font->GetStyle() == wxITALIC )",
390 // but since MGL does not yet support slant, we try to display it with
391 // italic face (better than nothing...)
392 if ( font
->GetStyle() == wxITALIC
|| font
->GetStyle() == wxSLANT
)
394 if ( family
->HasFace(type
| wxFONTFACE_ITALIC
) )
395 type
|= wxFONTFACE_ITALIC
;
397 if ( !family
->HasFace(type
) )
399 for (int i
= 0; i
< wxFONTFACE_MAX
; i
++)
400 if ( family
->HasFace(i
) )
407 return family
->GetLibrary(type
);
410 static ibool MGLAPI
enum_callback(const font_info_t
*info
, void *cookie
)
412 wxFontsManager
*db
= (wxFontsManager
*)cookie
;
417 wxFontsManager::wxFontsManager()
419 m_hash
= new wxHashTable(wxKEY_STRING
);
420 m_hash
->DeleteContents(false);
421 m_list
= new wxMGLFontFamilyList
;
422 m_list
->DeleteContents(true);
423 MGL_enumerateFonts(enum_callback
, (void*)this);
426 wxFontsManager::~wxFontsManager()
432 void wxFontsManager::AddFamily(const font_info_t
*info
)
434 wxMGLFontFamily
*f
= new wxMGLFontFamily(info
);
435 m_hash
->Put(f
->GetName().Lower(), f
);
439 wxMGLFontFamily
*wxFontsManager::GetFamily(const wxString
& name
) const
441 return (wxMGLFontFamily
*)m_hash
->Get(name
.Lower());
445 wxFontsManager
*wxTheFontsManager
= NULL
;