1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        mgl/fontutil.cpp 
   3 // Purpose:     Font helper functions for MGL 
   4 // Author:      Vaclav Slavik 
   7 // Copyright:   (c) 2001, Vaclav Slavik 
   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
; 
 330         family 
= GetFamily(font
->GetFaceName()); 
 334         facename 
= font
->GetFaceName(); 
 340         switch (font
->GetFamily()) 
 343                 facename 
= wxT("Script"); 
 346                 facename 
= wxT("Charter"); 
 349                 facename 
= wxT("Times"); 
 353                 facename 
= wxT("Courier"); 
 356                 facename 
= wxT("Helvetica"); 
 360                 facename 
= wxT("Helvetica"); 
 364         family 
= GetFamily(facename
); 
 367            if ( m_list
->GetFirst() ) 
 368                family 
= m_list
->GetFirst()->GetData(); 
 370                wxFAIL_MSG(wxT("Fatal error, no fonts available!")); 
 374     type 
= wxFONTFACE_REGULAR
; 
 376     if ( font
->GetWeight() == wxBOLD 
) 
 377         type 
|= wxFONTFACE_BOLD
; 
 379     // FIXME_MGL -- this should read "if ( font->GetStyle() == wxITALIC )", 
 380     // but since MGL does not yet support slant, we try to display it with 
 381     // italic face (better than nothing...) 
 382     if ( font
->GetStyle() == wxITALIC 
|| font
->GetStyle() == wxSLANT 
) 
 384         if ( family
->HasFace(type 
| wxFONTFACE_ITALIC
) ) 
 385             type 
|= wxFONTFACE_ITALIC
; 
 387     if ( !family
->HasFace(type
) ) 
 389         for (int i 
= 0; i 
< wxFONTFACE_MAX
; i
++) 
 390             if ( family
->HasFace(i
) ) 
 397     return family
->GetLibrary(type
); 
 400 static ibool 
enum_callback(const font_info_t 
*info
, void *cookie
) 
 402     wxFontsManager 
*db 
= (wxFontsManager
*)cookie
; 
 407 wxFontsManager::wxFontsManager() 
 409     m_hash 
= new wxHashTable(wxKEY_STRING
); 
 410     m_hash
->DeleteContents(FALSE
); 
 411     m_list 
= new wxMGLFontFamilyList
; 
 412     m_list
->DeleteContents(TRUE
); 
 413     MGL_enumerateFonts(enum_callback
, (void*)this); 
 416 wxFontsManager::~wxFontsManager() 
 422 void wxFontsManager::AddFamily(const font_info_t 
*info
) 
 424     wxMGLFontFamily 
*f 
= new wxMGLFontFamily(info
); 
 425     m_hash
->Put(f
->GetName().Lower(), f
); 
 429 wxMGLFontFamily 
*wxFontsManager::GetFamily(const wxString
& name
) const 
 431     return (wxMGLFontFamily
*)m_hash
->Get(name
.Lower()); 
 435 wxFontsManager 
*wxTheFontsManager 
= NULL
; 
 438 // A module that takes care of fonts DB initialization and destruction: 
 440 class wxFontutilModule
: public wxModule
 
 442 DECLARE_DYNAMIC_CLASS(wxFontutilModule
) 
 444     wxFontutilModule() {} 
 447         wxTheFontsManager 
= new wxFontsManager
; 
 452         delete wxTheFontsManager
; 
 456 IMPLEMENT_DYNAMIC_CLASS(wxFontutilModule
, wxModule
)