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" 
  23 #include "wx/fontutil.h" 
  24 #include "wx/encinfo.h" 
  25 #include "wx/fontmap.h" 
  26 #include "wx/tokenzr.h" 
  28 #include "wx/listimpl.cpp" 
  29 #include "wx/sysopt.h" 
  30 #include "wx/mgl/private.h" 
  34 // ============================================================================ 
  36 // ============================================================================ 
  38 // ---------------------------------------------------------------------------- 
  39 // wxNativeEncodingInfo 
  40 // ---------------------------------------------------------------------------- 
  42 // convert to/from the string representation: format is 
  43 //      encoding[;facename] 
  44 bool wxNativeEncodingInfo::FromString(const wxString
& s
) 
  46     wxStringTokenizer 
tokenizer(s
, _T(";")); 
  48     wxString encid 
= tokenizer
.GetNextToken(); 
  50     if ( !encid
.ToLong(&enc
) ) 
  52     encoding 
= (wxFontEncoding
)enc
; 
  55     facename 
= tokenizer
.GetNextToken(); 
  60 wxString 
wxNativeEncodingInfo::ToString() const 
  64     if ( !facename
.empty() ) 
  66         s 
<< _T(';') << facename
; 
  72 // ---------------------------------------------------------------------------- 
  74 // ---------------------------------------------------------------------------- 
  76 bool wxGetNativeFontEncoding(wxFontEncoding encoding
, 
  77                              wxNativeEncodingInfo 
*info
) 
  79     wxCHECK_MSG( info
, false, _T("bad pointer in wxGetNativeFontEncoding") ); 
  81     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
  83         encoding 
= wxFont::GetDefaultEncoding(); 
  88         case wxFONTENCODING_ISO8859_1
: 
  89         case wxFONTENCODING_ISO8859_2
: 
  90         case wxFONTENCODING_ISO8859_3
: 
  91         case wxFONTENCODING_ISO8859_4
: 
  92         case wxFONTENCODING_ISO8859_5
: 
  93         case wxFONTENCODING_ISO8859_6
: 
  94         case wxFONTENCODING_ISO8859_7
: 
  95         case wxFONTENCODING_ISO8859_8
: 
  96         case wxFONTENCODING_ISO8859_9
: 
  97         case wxFONTENCODING_ISO8859_10
: 
  98         case wxFONTENCODING_ISO8859_11
: 
  99         case wxFONTENCODING_ISO8859_13
: 
 100         case wxFONTENCODING_ISO8859_14
: 
 101         case wxFONTENCODING_ISO8859_15
: 
 102             info
->mglEncoding 
= MGL_ENCODING_ISO8859_1 
+ 
 103                                 (encoding 
- wxFONTENCODING_ISO8859_1
); 
 106         case wxFONTENCODING_KOI8
: 
 107             info
->mglEncoding 
= MGL_ENCODING_KOI8
; 
 110         case wxFONTENCODING_CP1250
: 
 111         case wxFONTENCODING_CP1251
: 
 112         case wxFONTENCODING_CP1252
: 
 113         case wxFONTENCODING_CP1253
: 
 114         case wxFONTENCODING_CP1254
: 
 115         case wxFONTENCODING_CP1255
: 
 116         case wxFONTENCODING_CP1256
: 
 117         case wxFONTENCODING_CP1257
: 
 118             info
->mglEncoding 
= MGL_ENCODING_CP1250 
+ 
 119                                 (encoding 
- wxFONTENCODING_CP1250
); 
 122         case wxFONTENCODING_SYSTEM
: 
 123             info
->mglEncoding 
= MGL_ENCODING_ASCII
; 
 127             // encoding not known to MGL 
 131     info
->encoding 
= encoding
; 
 136 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
) 
 138     if ( !info
.facename 
) 
 141     wxMGLFontFamily 
*family 
= wxTheFontsManager
->GetFamily(info
.facename
); 
 144     if ( family
->GetInfo()->fontLibType 
== MGL_BITMAPFONT_LIB 
) 
 145         return (info
.mglEncoding 
== MGL_ENCODING_ASCII 
|| 
 146                 info
.mglEncoding 
== MGL_ENCODING_ISO8859_1 
|| 
 147                 info
.mglEncoding 
== MGL_ENCODING_ISO8859_15 
|| 
 148                 info
.mglEncoding 
== MGL_ENCODING_CP1252
); 
 154 // ---------------------------------------------------------------------------- 
 155 // wxFontFamily, wxMGLFontInstance, wxMGLFontLibrary 
 156 // ---------------------------------------------------------------------------- 
 158 WX_DECLARE_LIST(wxMGLFontInstance
, wxMGLFontInstanceList
); 
 159 WX_DEFINE_LIST(wxMGLFontInstanceList
) 
 160 WX_DEFINE_LIST(wxMGLFontFamilyList
) 
 162 wxMGLFontInstance::wxMGLFontInstance(wxMGLFontLibrary 
*fontLib
, 
 163                                      float pt
, bool slant
, bool aa
) 
 171     float slantAngle 
= m_slant 
? 15.0 : 0.0; 
 173     wxLogTrace("mgl_font", "loading instance of '%s' slant=%i pt=%0.1f aa=%i", 
 174                m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
); 
 175     m_font 
= MGL_loadFontInstance(m_fontLib
->GetMGLfont_lib_t(), 
 176                                   m_pt
, slantAngle
, 0.0, aa
); 
 177     wxASSERT_MSG( m_font
, wxT("Cannot create font instance.") ); 
 180 wxMGLFontInstance::~wxMGLFontInstance() 
 182     wxLogTrace("mgl_font", "unloading instance of '%s' slant=%i pt=%0.1f aa=%i", 
 183                m_fontLib
->GetMGLfont_lib_t()->name
, m_slant
, m_pt
, m_aa
); 
 185         MGL_unloadFontInstance(m_font
); 
 188 wxMGLFontLibrary::wxMGLFontLibrary(const wxString
& filename
, int type
, 
 189                                    wxMGLFontFamily 
*parentFamily
) 
 191     m_family 
= parentFamily
; 
 193     m_fileName 
= filename
; 
 197     m_instances 
= new wxMGLFontInstanceList
; 
 198     m_instances
->DeleteContents(true); 
 201 wxMGLFontLibrary::~wxMGLFontLibrary() 
 203     wxLogTrace("mgl_font", "font library dtor '%s'", m_fileName
.mb_str()); 
 207 void wxMGLFontLibrary::IncRef() 
 209     wxLogTrace("mgl_font", "incRef(%u) '%s'", m_refs
, m_fileName
.c_str()); 
 212         wxLogTrace("mgl_font", "opening library '%s'", m_fileName
.mb_str()); 
 213         m_fontLib 
= MGL_openFontLib(m_fileName
.mb_str()); 
 217 void wxMGLFontLibrary::DecRef() 
 219     wxLogTrace("mgl_font", "decRef(%u) '%s'", m_refs
, m_fileName
.c_str()); 
 222         wxLogTrace("mgl_font", "killing instances of '%s'", m_fileName
.mb_str()); 
 223         m_instances
->Clear(); 
 224         wxLogTrace("mgl_font", "closing library '%s'", m_fileName
.mb_str()); 
 225         MGL_closeFontLib(m_fontLib
); 
 230 static int gs_antialiasingThreshold 
= -1; 
 232 wxMGLFontInstance 
*wxMGLFontLibrary::GetFontInstance(wxFont 
*font
, 
 233                                                      float scale
, bool aa
) 
 235     wxASSERT_MSG(m_refs 
> 0 && m_fontLib
, wxT("font library not loaded!")); 
 238     float pt 
= (float)font
->GetPointSize() * scale
; 
 240     if ( gs_antialiasingThreshold 
== -1 ) 
 242         gs_antialiasingThreshold 
= 10; 
 243 #if wxUSE_SYSTEM_OPTIONS 
 244         if ( wxSystemOptions::HasOption(wxT("mgl.aa-threshold")) ) 
 245             gs_antialiasingThreshold 
= 
 246                 wxSystemOptions::GetOptionInt(wxT("mgl.aa-threshold")); 
 247         wxLogTrace("mgl_font", "AA threshold set to %i", gs_antialiasingThreshold
); 
 251     // Small characters don't look good when antialiased with the algorithm 
 252     // that FreeType uses (mere 2x2 supersampling), so lets disable it AA 
 253     // completely for small fonts. 
 254     bool antialiased 
= false; 
 255     if (( pt 
> gs_antialiasingThreshold 
) && 
 256         ( m_fontLib
->fontLibType 
!= MGL_BITMAPFONT_LIB 
) ) 
 259     bool slant 
= (((m_type 
& wxFONTFACE_ITALIC
) == 0) && 
 260              (font
->GetStyle() == wxSLANT 
|| font
->GetStyle() == wxITALIC
)); 
 262     // FIXME_MGL -- MGL does not yet support slant, although the API is there 
 265     wxLogTrace("mgl_font", "requested instance of '%s' slant=%i pt=%0.1f aa=%i", 
 266                m_fileName
.mb_str(), slant
, pt
, antialiased
); 
 268     wxMGLFontInstance 
*i
; 
 269     wxMGLFontInstanceList::Node 
*node
; 
 271     for (node 
= m_instances
->GetFirst(); node
; node 
= node
->GetNext()) 
 274         if ( i
->GetPt() == pt 
&& i
->GetSlant() == slant 
&& 
 275              i
->GetAA() == antialiased 
) 
 277             wxLogTrace("mgl_font", "    got from cache: slant=%i pt=%0.1f aa=%i", 
 278                        i
->GetSlant(), i
->GetPt(), i
->GetAA()); 
 283     i 
= new wxMGLFontInstance(this, pt
, slant
, antialiased
); 
 284     m_instances
->Append(i
); 
 289 wxMGLFontFamily::wxMGLFontFamily(const font_info_t 
*info
) 
 291     m_name 
= info
->familyName
; 
 294     if ( info
->regularFace
[0] == '\0' ) 
 295         m_fontLibs
[wxFONTFACE_REGULAR
] = NULL
; 
 297         m_fontLibs
[wxFONTFACE_REGULAR
] = 
 298             new wxMGLFontLibrary(info
->regularFace
, wxFONTFACE_REGULAR
, this); 
 300     if ( info
->italicFace
[0] == '\0' ) 
 301         m_fontLibs
[wxFONTFACE_ITALIC
] = NULL
; 
 303         m_fontLibs
[wxFONTFACE_ITALIC
] = 
 304             new wxMGLFontLibrary(info
->italicFace
, wxFONTFACE_ITALIC
, this); 
 306     if ( info
->boldFace
[0] == '\0' ) 
 307         m_fontLibs
[wxFONTFACE_BOLD
] = NULL
; 
 309         m_fontLibs
[wxFONTFACE_BOLD
] = 
 310             new wxMGLFontLibrary(info
->boldFace
, wxFONTFACE_BOLD
, this); 
 312     if ( info
->boldItalicFace
[0] == '\0' ) 
 313         m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] = NULL
; 
 315         m_fontLibs
[wxFONTFACE_BOLD_ITALIC
] = 
 316             new wxMGLFontLibrary(info
->boldItalicFace
, wxFONTFACE_BOLD_ITALIC
, this); 
 318     wxLogTrace("mgl_font", "new family '%s' (r=%s, i=%s, b=%s, bi=%s)\n", 
 319                info
->familyName
, info
->regularFace
, info
->italicFace
, 
 320                info
->boldFace
, info
->boldItalicFace
); 
 323 wxMGLFontFamily::~wxMGLFontFamily() 
 325     for (size_t i 
= 0; i 
< wxFONTFACE_MAX
; i
++) 
 326         delete m_fontLibs
[i
]; 
 329 bool wxMGLFontFamily::HasFace(int type
) const 
 331     return (m_fontLibs
[type
] != NULL
); 
 335 // ---------------------------------------------------------------------------- 
 337 // ---------------------------------------------------------------------------- 
 339 wxMGLFontLibrary 
*wxFontsManager::GetFontLibrary(wxFont 
*font
) 
 341     wxMGLFontFamily 
*family
; 
 343     wxString facename 
= font
->GetFaceName(); 
 345     if ( !facename
.empty() ) 
 346         family 
= GetFamily(facename
); 
 353         switch (font
->GetFamily()) 
 356                 facename 
= wxT("Script"); 
 359                 facename 
= wxT("Charter"); 
 362                 facename 
= wxT("Times"); 
 366                 facename 
= wxT("Courier"); 
 369                 facename 
= wxT("Helvetica"); 
 373                 facename 
= wxT("Helvetica"); 
 377         family 
= GetFamily(facename
); 
 380            if ( m_list
->GetFirst() ) 
 381                family 
= m_list
->GetFirst()->GetData(); 
 383                wxFAIL_MSG(wxT("Fatal error, no fonts available!")); 
 387     type 
= wxFONTFACE_REGULAR
; 
 389     if ( font
->GetWeight() == wxBOLD 
) 
 390         type 
|= wxFONTFACE_BOLD
; 
 392     // FIXME_MGL -- this should read "if ( font->GetStyle() == wxITALIC )", 
 393     // but since MGL does not yet support slant, we try to display it with 
 394     // italic face (better than nothing...) 
 395     if ( font
->GetStyle() == wxITALIC 
|| font
->GetStyle() == wxSLANT 
) 
 397         if ( family
->HasFace(type 
| wxFONTFACE_ITALIC
) ) 
 398             type 
|= wxFONTFACE_ITALIC
; 
 400     if ( !family
->HasFace(type
) ) 
 402         for (int i 
= 0; i 
< wxFONTFACE_MAX
; i
++) 
 403             if ( family
->HasFace(i
) ) 
 410     return family
->GetLibrary(type
); 
 413 static ibool MGLAPI 
enum_callback(const font_info_t 
*info
, void *cookie
) 
 415     wxFontsManager 
*db 
= (wxFontsManager
*)cookie
; 
 420 wxFontsManager::wxFontsManager() 
 422     m_hash 
= new wxHashTable(wxKEY_STRING
); 
 423     m_hash
->DeleteContents(false); 
 424     m_list 
= new wxMGLFontFamilyList
; 
 425     m_list
->DeleteContents(true); 
 426     MGL_enumerateFonts(enum_callback
, (void*)this); 
 429 wxFontsManager::~wxFontsManager() 
 435 void wxFontsManager::AddFamily(const font_info_t 
*info
) 
 437     wxMGLFontFamily 
*f 
= new wxMGLFontFamily(info
); 
 438     m_hash
->Put(f
->GetName().Lower(), f
); 
 442 wxMGLFontFamily 
*wxFontsManager::GetFamily(const wxString
& name
) const 
 444     return (wxMGLFontFamily
*)m_hash
->Get(name
.Lower()); 
 448 wxFontsManager 
*wxTheFontsManager 
= NULL
;