1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mgl/fontutil.cpp
3 // Purpose: Font helper functions for MGL
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "fontutil.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/fontutil.h"
28 #include "wx/fontmap.h"
29 #include "wx/tokenzr.h"
31 #include "wx/module.h"
32 #include "wx/listimpl.cpp"
34 #include "wx/mgl/private.h"
38 // ============================================================================
40 // ============================================================================
42 // ----------------------------------------------------------------------------
43 // wxNativeEncodingInfo
44 // ----------------------------------------------------------------------------
46 // convert to/from the string representation: format is
47 // encoding[;facename]
48 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
50 wxStringTokenizer
tokenizer(s
, _T(";"));
52 wxString encid
= tokenizer
.GetNextToken();
54 if ( !encid
.ToLong(&enc
) )
56 encoding
= (wxFontEncoding
)enc
;
59 facename
= tokenizer
.GetNextToken();
64 wxString
wxNativeEncodingInfo::ToString() const
70 s
<< _T(';') << facename
;
76 // ----------------------------------------------------------------------------
78 // ----------------------------------------------------------------------------
80 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
81 wxNativeEncodingInfo
*info
)
83 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
85 if ( encoding
== wxFONTENCODING_DEFAULT
)
87 encoding
= wxFont::GetDefaultEncoding();
92 case wxFONTENCODING_ISO8859_1
:
93 case wxFONTENCODING_ISO8859_2
:
94 case wxFONTENCODING_ISO8859_3
:
95 case wxFONTENCODING_ISO8859_4
:
96 case wxFONTENCODING_ISO8859_5
:
97 case wxFONTENCODING_ISO8859_6
:
98 case wxFONTENCODING_ISO8859_7
:
99 case wxFONTENCODING_ISO8859_8
:
100 case wxFONTENCODING_ISO8859_9
:
101 case wxFONTENCODING_ISO8859_10
:
102 case wxFONTENCODING_ISO8859_11
:
103 case wxFONTENCODING_ISO8859_13
:
104 case wxFONTENCODING_ISO8859_14
:
105 case wxFONTENCODING_ISO8859_15
:
106 info
->mglEncoding
= MGL_ENCODING_ISO8859_1
+
107 (encoding
- wxFONTENCODING_ISO8859_1
);
110 case wxFONTENCODING_KOI8
:
111 info
->mglEncoding
= MGL_ENCODING_KOI8
;
114 case wxFONTENCODING_CP1250
:
115 case wxFONTENCODING_CP1251
:
116 case wxFONTENCODING_CP1252
:
117 case wxFONTENCODING_CP1253
:
118 case wxFONTENCODING_CP1254
:
119 case wxFONTENCODING_CP1255
:
120 case wxFONTENCODING_CP1256
:
121 case wxFONTENCODING_CP1257
:
122 info
->mglEncoding
= MGL_ENCODING_CP1250
+
123 (encoding
- wxFONTENCODING_CP1250
);
126 case wxFONTENCODING_SYSTEM
:
127 info
->mglEncoding
= MGL_ENCODING_ASCII
;
131 // encoding not known to MGL
135 info
->encoding
= encoding
;
140 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
142 if ( !info
.facename
)
145 wxMGLFontFamily
*family
= wxTheFontsManager
->GetFamily(info
.facename
);
148 if ( family
->GetInfo()->fontLibType
== MGL_BITMAPFONT_LIB
)
149 return (info
.mglEncoding
== MGL_ENCODING_ASCII
||
150 info
.mglEncoding
== MGL_ENCODING_ISO8859_1
||
151 info
.mglEncoding
== MGL_ENCODING_ISO8859_15
||
152 info
.mglEncoding
== MGL_ENCODING_CP1252
);
158 // ----------------------------------------------------------------------------
159 // wxFontFamily, wxMGLFontInstance, wxMGLFontLibrary
160 // ----------------------------------------------------------------------------
162 WX_DECLARE_LIST(wxMGLFontInstance
, wxMGLFontInstanceList
);
163 WX_DEFINE_LIST(wxMGLFontInstanceList
);
164 WX_DEFINE_LIST(wxMGLFontFamilyList
);
166 wxMGLFontInstance::wxMGLFontInstance(wxMGLFontLibrary
*fontLib
,
167 float pt
, bool slant
, bool aa
)
175 float slantAngle
= m_slant
? 15.0 : 0.0;
177 wxLogTrace("mgl_font", "loading instance of '%s' slant=%i pt=%0.1f aa=%i",
178 m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
);
179 m_font
= MGL_loadFontInstance(m_fontLib
->GetMGLfont_lib_t(),
180 m_pt
, slantAngle
, 0.0, aa
);
181 wxASSERT_MSG( m_font
, wxT("Cannot create font instance.") );
184 wxMGLFontInstance::~wxMGLFontInstance()
186 wxLogTrace("mgl_font", "unloading instance of '%s' slant=%i pt=%0.1f aa=%i",
187 m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
);
189 MGL_unloadFontInstance(m_font
);
192 wxMGLFontLibrary::wxMGLFontLibrary(const wxString
& filename
, int type
)
195 m_fileName
= filename
;
199 m_instances
= new wxMGLFontInstanceList
;
200 m_instances
->DeleteContents(TRUE
);
203 wxMGLFontLibrary::~wxMGLFontLibrary()
205 wxLogTrace("mgl_font", "font library dtor '%s'", m_fileName
.mb_str());
209 void wxMGLFontLibrary::IncRef()
211 wxLogTrace("mgl_font", "incRef(%u) '%s'", m_refs
, m_fileName
.c_str());
214 wxLogTrace("mgl_font", "opening library '%s'", m_fileName
.mb_str());
215 m_fontLib
= MGL_openFontLib(m_fileName
.mb_str());
219 void wxMGLFontLibrary::DecRef()
221 wxLogTrace("mgl_font", "decRef(%u) '%s'", m_refs
, m_fileName
.c_str());
224 wxLogTrace("mgl_font", "killing instances of '%s'", m_fileName
.mb_str());
225 m_instances
->Clear();
226 wxLogTrace("mgl_font", "closing library '%s'", m_fileName
.mb_str());
227 MGL_closeFontLib(m_fontLib
);
232 wxMGLFontInstance
*wxMGLFontLibrary::GetFontInstance(wxFont
*font
,
233 float scale
, bool aa
)
235 wxASSERT_MSG(m_refs
> 0 && m_fontLib
, wxT("font library not loaded!"));
240 (m_fontLib
->fontLibType
== MGL_BITMAPFONT_LIB
) ? FALSE
: aa
;
241 float pt
= (float)font
->GetPointSize() * scale
;
243 slant
= (((m_type
& wxFONTFACE_ITALIC
) == 0) &&
244 (font
->GetStyle() == wxSLANT
|| font
->GetStyle() == wxITALIC
));
246 // FIXME_MGL -- MGL does not yet support slant, although the API is there
249 wxLogTrace("mgl_font", "requested instance of '%s' slant=%i pt=%0.1f aa=%i",
250 m_fileName
.mb_str(), slant
, pt
, antialiased
);
252 wxMGLFontInstance
*i
;
253 wxMGLFontInstanceList::Node
*node
;
255 for (node
= m_instances
->GetFirst(); node
; node
= node
->GetNext())
258 if ( i
->GetPt() == pt
&& i
->GetSlant() == slant
&&
259 i
->GetAA() == antialiased
)
261 wxLogTrace("mgl_font", " got from cache: slant=%i pt=%0.1f aa=%i",
262 i
->GetSlant(), i
->GetPt(), i
->GetAA());
267 i
= new wxMGLFontInstance(this, pt
, slant
, antialiased
);
268 m_instances
->Append(i
);
273 wxMGLFontFamily::wxMGLFontFamily(const font_info_t
*info
)
275 m_name
= info
->familyName
;
278 if ( info
->regularFace
[0] == '\0' )
279 m_fontLibs
[wxFONTFACE_REGULAR
] = NULL
;
281 m_fontLibs
[wxFONTFACE_REGULAR
] =
282 new wxMGLFontLibrary(info
->regularFace
, wxFONTFACE_REGULAR
);
284 if ( info
->italicFace
[0] == '\0' )
285 m_fontLibs
[wxFONTFACE_ITALIC
] = NULL
;
287 m_fontLibs
[wxFONTFACE_ITALIC
] =
288 new wxMGLFontLibrary(info
->italicFace
, wxFONTFACE_ITALIC
);
290 if ( info
->boldFace
[0] == '\0' )
291 m_fontLibs
[wxFONTFACE_BOLD
] = NULL
;
293 m_fontLibs
[wxFONTFACE_BOLD
] =
294 new wxMGLFontLibrary(info
->boldFace
, wxFONTFACE_BOLD
);
296 if ( info
->boldItalicFace
[0] == '\0' )
297 m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] = NULL
;
299 m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] =
300 new wxMGLFontLibrary(info
->boldItalicFace
, wxFONTFACE_BOLD_ITALIC
);
302 wxLogTrace("mgl_font", "new family '%s' (r=%s, i=%s, b=%s, bi=%s)\n",
303 info
->familyName
, info
->regularFace
, info
->italicFace
,
304 info
->boldFace
, info
->boldItalicFace
);
307 wxMGLFontFamily::~wxMGLFontFamily()
309 for (size_t i
= 0; i
< wxFONTFACE_MAX
; i
++)
310 delete m_fontLibs
[i
];
313 bool wxMGLFontFamily::HasFace(int type
) const
315 return (m_fontLibs
[type
] != NULL
);
319 // ----------------------------------------------------------------------------
321 // ----------------------------------------------------------------------------
323 wxMGLFontLibrary
*wxFontsManager::GetFontLibrary(wxFont
*font
)
325 wxMGLFontFamily
*family
;
327 wxString facename
= font
->GetFaceName();
329 if ( !facename
.IsEmpty() )
330 family
= GetFamily(facename
);
337 switch (font
->GetFamily())
340 facename
= wxT("Script");
343 facename
= wxT("Charter");
346 facename
= wxT("Times");
350 facename
= wxT("Courier");
353 facename
= wxT("Helvetica");
357 facename
= wxT("Helvetica");
361 family
= GetFamily(facename
);
364 if ( m_list
->GetFirst() )
365 family
= m_list
->GetFirst()->GetData();
367 wxFAIL_MSG(wxT("Fatal error, no fonts available!"));
371 type
= wxFONTFACE_REGULAR
;
373 if ( font
->GetWeight() == wxBOLD
)
374 type
|= wxFONTFACE_BOLD
;
376 // FIXME_MGL -- this should read "if ( font->GetStyle() == wxITALIC )",
377 // but since MGL does not yet support slant, we try to display it with
378 // italic face (better than nothing...)
379 if ( font
->GetStyle() == wxITALIC
|| font
->GetStyle() == wxSLANT
)
381 if ( family
->HasFace(type
| wxFONTFACE_ITALIC
) )
382 type
|= wxFONTFACE_ITALIC
;
384 if ( !family
->HasFace(type
) )
386 for (int i
= 0; i
< wxFONTFACE_MAX
; i
++)
387 if ( family
->HasFace(i
) )
394 return family
->GetLibrary(type
);
397 static ibool
enum_callback(const font_info_t
*info
, void *cookie
)
399 wxFontsManager
*db
= (wxFontsManager
*)cookie
;
404 wxFontsManager::wxFontsManager()
406 m_hash
= new wxHashTable(wxKEY_STRING
);
407 m_hash
->DeleteContents(FALSE
);
408 m_list
= new wxMGLFontFamilyList
;
409 m_list
->DeleteContents(TRUE
);
410 MGL_enumerateFonts(enum_callback
, (void*)this);
413 wxFontsManager::~wxFontsManager()
419 void wxFontsManager::AddFamily(const font_info_t
*info
)
421 wxMGLFontFamily
*f
= new wxMGLFontFamily(info
);
422 m_hash
->Put(f
->GetName().Lower(), f
);
426 wxMGLFontFamily
*wxFontsManager::GetFamily(const wxString
& name
) const
428 return (wxMGLFontFamily
*)m_hash
->Get(name
.Lower());
432 wxFontsManager
*wxTheFontsManager
= NULL
;
435 // A module that takes care of fonts DB initialization and destruction:
437 class wxFontutilModule
: public wxModule
439 DECLARE_DYNAMIC_CLASS(wxFontutilModule
)
441 wxFontutilModule() {}
444 wxTheFontsManager
= new wxFontsManager
;
449 delete wxTheFontsManager
;
453 IMPLEMENT_DYNAMIC_CLASS(wxFontutilModule
, wxModule
)