Panda3D
Loading...
Searching...
No Matches
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
24using std::string;
25
26FontPool *FontPool::_global_ptr = nullptr;
27
28/**
29 * Lists the contents of the font pool to the indicated output stream.
30 */
32write(std::ostream &out) {
33 get_ptr()->ns_list_contents(out);
34}
35
36/**
37 * The nonstatic implementation of has_font().
38 */
39bool FontPool::
40ns_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 */
61TextFont *FontPool::
62ns_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 */
142void FontPool::
143ns_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 */
158void FontPool::
159ns_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 */
177void FontPool::
178ns_release_all_fonts() {
179 LightMutexHolder holder(_lock);
180
181 _fonts.clear();
182}
183
184/**
185 * The nonstatic implementation of garbage_collect().
186 */
187int FontPool::
188ns_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 */
215void FontPool::
216ns_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 */
236void FontPool::
237lookup_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 */
266FontPool *FontPool::
267get_ptr() {
268 if (_global_ptr == nullptr) {
269 _global_ptr = new FontPool;
270 }
271 return _global_ptr;
272}
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string get_extension() const
Returns the file extension.
Definition filename.I:400
This is the preferred interface for loading fonts for the TextNode system.
Definition fontPool.h:30
static void write(std::ostream &out)
Lists the contents of the font pool to the indicated output stream.
Definition fontPool.cxx:32
Similar to MutexHolder, but for a light mutex.
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
static Loader * get_global_ptr()
Returns a pointer to the global Loader.
Definition loader.I:212
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
get_ref_count
Returns the current reference count.
A StaticTextFont is loaded up from a model that was previously generated via egg-mkfont,...
An encapsulation of a font; i.e.
Definition textFont.h:32
A hierarchy of directories and files that appears to be one continuous file system,...
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.