]> git.saurik.com Git - wxWidgets.git/blob - src/dfb/fontmgr.cpp
fix assert when the control doesn't have a valid date initially (bug 1648192)
[wxWidgets.git] / src / dfb / fontmgr.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/fontmgr.cpp
3 // Purpose: font management for wxDFB
4 // Author: Vaclav Slavik
5 // Created: 2006-11-18
6 // RCS-ID: $Id$
7 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
8 // (c) 2006 REA Elektronik GmbH
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/utils.h"
21 #include "wx/log.h"
22 #endif
23
24 #include "wx/fileconf.h"
25 #include "wx/filename.h"
26 #include "wx/tokenzr.h"
27 #include "wx/dir.h"
28
29 #include "wx/private/fontmgr.h"
30 #include "wx/dfb/wrapdfb.h"
31
32 // ============================================================================
33 // implementation
34 // ============================================================================
35
36 // ----------------------------------------------------------------------------
37 // wxFontInstance
38 // ----------------------------------------------------------------------------
39
40 wxFontInstance::wxFontInstance(float ptSize, bool aa,
41 const wxString& filename)
42 : wxFontInstanceBase(ptSize, aa)
43 {
44 int scrSizePx, scrSizeMM;
45 wxDisplaySize(NULL, &scrSizePx);
46 wxDisplaySizeMM(NULL, &scrSizeMM);
47 double dpi = (scrSizePx / (scrSizeMM * mm2inches));
48 // NB: DFB's fract_height value is 32bit integer with the last 6 bit
49 // representing fractional value, hence the multiplication by 64;
50 // 1pt=1/72inch, hence "/ 72"
51 int pixSize = int(ptSize * dpi * 64 / 72);
52
53 DFBFontDescription desc;
54 desc.flags = (DFBFontDescriptionFlags)(
55 DFDESC_ATTRIBUTES | DFDESC_FRACT_HEIGHT);
56 desc.attributes = aa ? DFFA_NONE : DFFA_MONOCHROME;
57 desc.fract_height = pixSize;
58 m_font = wxIDirectFB::Get()->CreateFont(filename.fn_str(), &desc);
59
60 wxASSERT_MSG( m_font, _T("cannot create font instance") );
61 }
62
63 // ----------------------------------------------------------------------------
64 // wxFontFace
65 // ----------------------------------------------------------------------------
66
67 wxFontInstance *wxFontFace::CreateFontInstance(float ptSize, bool aa)
68 {
69 return new wxFontInstance(ptSize, aa, m_fileName);
70 }
71
72 // ----------------------------------------------------------------------------
73 // wxFontBundle
74 // ----------------------------------------------------------------------------
75
76 wxFontBundle::wxFontBundle(const wxString& name,
77 const wxString& fileRegular,
78 const wxString& fileBold,
79 const wxString& fileItalic,
80 const wxString& fileBoldItalic,
81 bool isFixed)
82 {
83 m_name = name;
84 m_isFixed = isFixed;
85
86 if ( !fileRegular.empty() )
87 m_faces[FaceType_Regular] = new wxFontFace(fileRegular);
88 if ( !fileItalic.empty() )
89 m_faces[FaceType_Italic] = new wxFontFace(fileItalic);
90 if ( !fileBold.empty() )
91 m_faces[FaceType_Bold] = new wxFontFace(fileBold);
92 if ( !fileBoldItalic.empty() )
93 m_faces[FaceType_BoldItalic] = new wxFontFace(fileBoldItalic);
94 }
95
96 // ----------------------------------------------------------------------------
97 // wxFontsManager
98 // ----------------------------------------------------------------------------
99
100 /*
101 The code below looks up and parses font configuration files FontsIndex.
102 The files are looked up in directories specified in the WXDFB_FONTPATH
103 environment variable (separated with :, similarly to the PATH variable).
104 If the variable is not set, $prefix/share/wx/fonts directory is used.
105 All subdirectories of directories on the path are scanned for FontsIndex
106 files.
107
108 The FontsIndex file is standard wxFileConfig file text file. Each toplevel
109 group specifies one font bundle, font's name is the name of group. Group's
110 entries look like this:
111
112 [Font Name]
113 # font files (at least one of them must be present):
114 Regular=RegularFaceFile.ttf
115 Italic=ItalicFaceFile.ttf
116 Bold=BoldFaceFile.ttf
117 BoldItalic=BoldItalicFaceFile.ttf
118 # optional tag indicating this font is fixed-with (default is false):
119 IsFixed=1
120
121 Additionally, there may be DefaultXXX entries at the toplevel for every
122 family XXX and a Default entry that is shortcut for setting all families'
123 default, their value is name of the default font:
124
125 # optional tags indicating the default font for given family:
126 DefaultDecorative=Font Name
127 DefaultRoman=Font Name
128 DefaultScript=Font Name
129 DefaultSwiss=Font Name
130 DefaultModern=Font Name
131 DefaultTeletype=Font Name
132 # indicate the font that is default for all families (optional):
133 Default=Font Name
134 */
135
136 void wxFontsManager::AddAllFonts()
137 {
138 wxString path;
139 if ( !wxGetEnv(_T("WXDFB_FONTPATH"), &path) )
140 path = _T(wxINSTALL_PREFIX "/share/wx/fonts");
141
142 wxStringTokenizer tkn(path, wxPATH_SEP);
143 while ( tkn.HasMoreTokens() )
144 {
145 wxString dir = tkn.GetNextToken();
146
147 wxArrayString indexFiles;
148 if ( !wxDir::GetAllFiles(dir, &indexFiles, _T("FontsIndex")) )
149 continue;
150
151 for ( wxArrayString::const_iterator i = indexFiles.begin();
152 i != indexFiles.end(); ++i )
153 {
154 AddFontsFromDir(*i);
155 }
156 }
157
158 if ( GetBundles().empty() )
159 {
160 // wxDFB is unusable without fonts, so terminate the app
161 wxLogFatalError(_("No fonts found in %s."), path.c_str());
162 }
163 }
164
165 void wxFontsManager::AddFontsFromDir(const wxString& indexFile)
166 {
167 wxFileName fn(indexFile);
168 wxString dir = fn.GetPath();
169
170 if ( !fn.FileExists() )
171 {
172 wxLogWarning(_("Fonts index file %s disappeared while loading fonts."),
173 indexFile.c_str());
174 return;
175 }
176
177 wxLogTrace(_T("font"), _T("adding fonts from %s"), dir.c_str());
178
179 wxFileConfig cfg(wxEmptyString, wxEmptyString,
180 indexFile, wxEmptyString,
181 wxCONFIG_USE_LOCAL_FILE);
182
183 long i;
184 wxString name;
185 for ( bool cont = cfg.GetFirstGroup(name, i);
186 cont;
187 cont = cfg.GetNextGroup(name, i) )
188 {
189 AddFont(dir, name, cfg);
190 }
191
192 // set default fonts for families:
193 SetDefaultFonts(cfg);
194 }
195
196 static wxString
197 ReadFilePath(const wxString& name, const wxString& dir, wxFileConfig& cfg)
198 {
199 wxString p = cfg.Read(name, wxEmptyString);
200
201 if ( p.empty() || wxFileName(p).IsAbsolute() )
202 return p;
203
204 return dir + _T("/") + p;
205 }
206
207 void wxFontsManager::AddFont(const wxString& dir,
208 const wxString& name,
209 wxFileConfig& cfg)
210 {
211 wxLogTrace(_T("font"), _T("adding font '%s'"), name.c_str());
212
213 wxConfigPathChanger ch(&cfg, wxString::Format(_T("/%s/"), name.c_str()));
214
215 AddBundle
216 (
217 new wxFontBundle
218 (
219 name,
220 ReadFilePath(_T("Regular"), dir, cfg),
221 ReadFilePath(_T("Italic"), dir, cfg),
222 ReadFilePath(_T("Bold"), dir, cfg),
223 ReadFilePath(_T("BoldItalic"), dir, cfg),
224 cfg.Read(_T("IsFixed"), (long)false)
225 )
226 );
227 }
228
229 void wxFontsManager::SetDefaultFonts(wxFileConfig& cfg)
230 {
231 wxString name;
232
233 if ( cfg.Read(_T("Default"), &name) )
234 {
235 m_defaultFacenames[wxFONTFAMILY_DECORATIVE] =
236 m_defaultFacenames[wxFONTFAMILY_ROMAN] =
237 m_defaultFacenames[wxFONTFAMILY_SCRIPT] =
238 m_defaultFacenames[wxFONTFAMILY_SWISS] =
239 m_defaultFacenames[wxFONTFAMILY_MODERN] =
240 m_defaultFacenames[wxFONTFAMILY_TELETYPE] = name;
241 }
242
243 if ( cfg.Read(_T("DefaultDecorative"), &name) )
244 m_defaultFacenames[wxFONTFAMILY_DECORATIVE] = name;
245 if ( cfg.Read(_T("DefaultRoman"), &name) )
246 m_defaultFacenames[wxFONTFAMILY_ROMAN] = name;
247 if ( cfg.Read(_T("DefaultScript"), &name) )
248 m_defaultFacenames[wxFONTFAMILY_SCRIPT] = name;
249 if ( cfg.Read(_T("DefaultSwiss"), &name) )
250 m_defaultFacenames[wxFONTFAMILY_SWISS] = name;
251 if ( cfg.Read(_T("DefaultModern"), &name) )
252 m_defaultFacenames[wxFONTFAMILY_MODERN] = name;
253 if ( cfg.Read(_T("DefaultTeletype"), &name) )
254 m_defaultFacenames[wxFONTFAMILY_TELETYPE] = name;
255 }