Panda3D
fontPool.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file fontPool.cxx
10  * @author drose
11  * @date 2003-01-31
12  */
13 
14 #include "fontPool.h"
15 #include "staticTextFont.h"
16 #include "dynamicTextFont.h"
17 #include "config_putil.h"
18 #include "config_express.h"
19 #include "virtualFileSystem.h"
20 #include "nodePath.h"
21 #include "loader.h"
22 #include "lightMutexHolder.h"
23 
24 using std::string;
25 
26 FontPool *FontPool::_global_ptr = nullptr;
27 
28 /**
29  * Lists the contents of the font pool to the indicated output stream.
30  */
31 void FontPool::
32 write(std::ostream &out) {
33  get_ptr()->ns_list_contents(out);
34 }
35 
36 /**
37  * The nonstatic implementation of has_font().
38  */
39 bool FontPool::
40 ns_has_font(const string &str) {
41  LightMutexHolder holder(_lock);
42 
43  string index_str;
44  Filename filename;
45  int face_index;
46  lookup_filename(str, index_str, filename, face_index);
47 
48  Fonts::const_iterator ti;
49  ti = _fonts.find(index_str);
50  if (ti != _fonts.end()) {
51  // This font was previously loaded.
52  return true;
53  }
54 
55  return false;
56 }
57 
58 /**
59  * The nonstatic implementation of load_font().
60  */
61 TextFont *FontPool::
62 ns_load_font(const string &str) {
63  string index_str;
64  Filename filename;
65  int face_index;
66  lookup_filename(str, index_str, filename, face_index);
67 
68  {
69  LightMutexHolder holder(_lock);
70 
71  Fonts::const_iterator ti;
72  ti = _fonts.find(index_str);
73  if (ti != _fonts.end()) {
74  // This font was previously loaded.
75  return (*ti).second;
76  }
77  }
78 
79  text_cat.info()
80  << "Loading font " << filename << "\n";
81 
82  // Now, figure out how to load the font. If its filename extension is "egg"
83  // or "bam", or if it's unspecified, assume it's a model file, representing
84  // a static font.
85  PT(TextFont) font;
86 
87  string extension = filename.get_extension();
88  if (extension.empty() || extension == "egg" || extension == "bam") {
89  Loader *model_loader = Loader::get_global_ptr();
90  PT(PandaNode) node = model_loader->load_sync(filename);
91  if (node != nullptr) {
92  // It is a model. Elevate all the priorities by 1, and make a font out
93  // of it.
94 
95  // On second thought, why should we elevate the priorities? The
96  // DynamicTextFont doesn't do this, and doing so for the StaticTextFont
97  // only causes problems (it changes the default ColorAttrib from pri -1
98  // to pri 0).
99  /*
100  NodePath np(node);
101  np.adjust_all_priorities(1);
102  */
103 
104  font = new StaticTextFont(node);
105  }
106  }
107 
108 #ifdef HAVE_FREETYPE
109  if (font == nullptr || !font->is_valid()) {
110  // If we couldn't load the font as a model, try using FreeType to load it
111  // as a font file.
112  font = new DynamicTextFont(filename, face_index);
113  }
114 #endif
115 
116  if (font == nullptr || !font->is_valid()) {
117  // This font was not found or could not be read.
118  return nullptr;
119  }
120 
121 
122  {
123  LightMutexHolder holder(_lock);
124 
125  // Look again. It may have been loaded by another thread.
126  Fonts::const_iterator ti;
127  ti = _fonts.find(index_str);
128  if (ti != _fonts.end()) {
129  // This font was previously loaded.
130  return (*ti).second;
131  }
132 
133  _fonts[index_str] = font;
134  }
135 
136  return font;
137 }
138 
139 /**
140  * The nonstatic implementation of add_font().
141  */
142 void FontPool::
143 ns_add_font(const string &str, TextFont *font) {
144  LightMutexHolder holder(_lock);
145 
146  string index_str;
147  Filename filename;
148  int face_index;
149  lookup_filename(str, index_str, filename, face_index);
150 
151  // We blow away whatever font was there previously, if any.
152  _fonts[index_str] = font;
153 }
154 
155 /**
156  * The nonstatic implementation of release_font().
157  */
158 void FontPool::
159 ns_release_font(const string &str) {
160  LightMutexHolder holder(_lock);
161 
162  string index_str;
163  Filename filename;
164  int face_index;
165  lookup_filename(str, index_str, filename, face_index);
166 
167  Fonts::iterator ti;
168  ti = _fonts.find(index_str);
169  if (ti != _fonts.end()) {
170  _fonts.erase(ti);
171  }
172 }
173 
174 /**
175  * The nonstatic implementation of release_all_fonts().
176  */
177 void FontPool::
178 ns_release_all_fonts() {
179  LightMutexHolder holder(_lock);
180 
181  _fonts.clear();
182 }
183 
184 /**
185  * The nonstatic implementation of garbage_collect().
186  */
187 int FontPool::
188 ns_garbage_collect() {
189  LightMutexHolder holder(_lock);
190 
191  int num_released = 0;
192  Fonts new_set;
193 
194  Fonts::iterator ti;
195  for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
196  TextFont *font = (*ti).second;
197  if (font->get_ref_count() == 1) {
198  if (text_cat.is_debug()) {
199  text_cat.debug()
200  << "Releasing " << (*ti).first << "\n";
201  }
202  num_released++;
203  } else {
204  new_set.insert(new_set.end(), *ti);
205  }
206  }
207 
208  _fonts.swap(new_set);
209  return num_released;
210 }
211 
212 /**
213  * The nonstatic implementation of list_contents().
214  */
215 void FontPool::
216 ns_list_contents(std::ostream &out) const {
217  LightMutexHolder holder(_lock);
218 
219  out << _fonts.size() << " fonts:\n";
220  Fonts::const_iterator ti;
221  for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
222  TextFont *font = (*ti).second;
223  out << " " << (*ti).first
224  << " (count = " << font->get_ref_count() << ")\n";
225  }
226 }
227 
228 /**
229  * Accepts a font "filename", which might consist of a filename followed by an
230  * optional colon and a face index, and splits it out into its two components.
231  * Then it looks up the filename on the model path. Sets the filename and
232  * face index accordingly. Also sets index_str to be the concatenation of the
233  * found filename with the face index, thus restoring the original input (but
234  * normalized to contain the full path.)
235  */
236 void FontPool::
237 lookup_filename(const string &str, string &index_str,
238  Filename &filename, int &face_index) {
239  int colon = (int)str.length() - 1;
240  // Scan backwards over digits for a colon.
241  while (colon >= 0 && isdigit(str[colon])) {
242  --colon;
243  }
244  if (colon >= 0 && str[colon] == ':') {
245  string digits = str.substr(colon + 1);
246  filename = str.substr(0, colon);
247  face_index = atoi(digits.c_str());
248  } else {
249  filename = str;
250  face_index = 0;
251  }
252 
253  // Now look up the filename on the model path.
255  vfs->resolve_filename(filename, get_model_path());
256 
257  std::ostringstream strm;
258  strm << filename << ":" << face_index;
259  index_str = strm.str();
260 }
261 
262 /**
263  * Initializes and/or returns the global pointer to the one FontPool object in
264  * the system.
265  */
266 FontPool *FontPool::
267 get_ptr() {
268  if (_global_ptr == nullptr) {
269  _global_ptr = new FontPool;
270  }
271  return _global_ptr;
272 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
get_ref_count
Returns the current reference count.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the preferred interface for loading fonts for the TextNode system.
Definition: fontPool.h:30
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A hierarchy of directories and files that appears to be one continuous file system,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A convenient class for loading models from disk, in bam or egg format (or any of a number of other fo...
Definition: loader.h:42
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An encapsulation of a font; i.e.
Definition: textFont.h:32
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A StaticTextFont is loaded up from a model that was previously generated via egg-mkfont,...
static Loader * get_global_ptr()
Returns a pointer to the global Loader.
Definition: loader.I:212
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Similar to MutexHolder, but for a light mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
std::string get_extension() const
Returns the file extension.
Definition: filename.I:400
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void write(std::ostream &out)
Lists the contents of the font pool to the indicated output stream.
Definition: fontPool.cxx:32