Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/text/fontPool.cxx

Go to the documentation of this file.
00001 // Filename: fontPool.cxx
00002 // Created by:  drose (31Jan03)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "fontPool.h"
00020 #include "config_util.h"
00021 #include "config_express.h"
00022 #include "virtualFileSystem.h"
00023 #include "nodePath.h"
00024 #include "loader.h"
00025 
00026 FontPool *FontPool::_global_ptr = (FontPool *)NULL;
00027 
00028 static Loader model_loader;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: FontPool::ns_has_font
00032 //       Access: Private
00033 //  Description: The nonstatic implementation of has_font().
00034 ////////////////////////////////////////////////////////////////////
00035 bool FontPool::
00036 ns_has_font(const string &str) {
00037   Filename filename;
00038   int face_index;
00039   lookup_filename(str, filename, face_index);
00040 
00041   Fonts::const_iterator ti;
00042   ti = _fonts.find(filename);
00043   if (ti != _fonts.end()) {
00044     // This font was previously loaded.
00045     return true;
00046   }
00047 
00048   return false;
00049 }
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: FontPool::ns_load_font
00053 //       Access: Private
00054 //  Description: The nonstatic implementation of load_font().
00055 ////////////////////////////////////////////////////////////////////
00056 TextFont *FontPool::
00057 ns_load_font(const string &str) {
00058   Filename filename;
00059   int face_index;
00060   lookup_filename(str, filename, face_index);
00061 
00062   Fonts::const_iterator ti;
00063   ti = _fonts.find(filename);
00064   if (ti != _fonts.end()) {
00065     // This font was previously loaded.
00066     return (*ti).second;
00067   }
00068 
00069   text_cat.info()
00070     << "Loading font " << filename << "\n";
00071 
00072   // Now, figure out how to load the font.  If its filename extension
00073   // is "egg" or "bam", or if it's unspecified, assume it's a model
00074   // file, representing a static font.
00075   PT(TextFont) font;
00076 
00077   string extension = filename.get_extension();
00078   if (extension.empty() || extension == "egg" || extension == "bam") {
00079     PT(PandaNode) node = model_loader.load_sync(filename);
00080     if (node != (PandaNode *)NULL) {
00081       // It is a model.  Elevate all the priorities by 1, and make a
00082       // font out of it.
00083       NodePath np(node);
00084       np.adjust_all_priorities(1);
00085       font = new StaticTextFont(node);
00086     }
00087   }
00088 
00089 #ifdef HAVE_FREETYPE
00090   if (font == (TextFont *)NULL || !font->is_valid()) {
00091     // If we couldn't load the font as a model, try using FreeType to
00092     // load it as a font file.
00093     font = new DynamicTextFont(filename, face_index);
00094   }
00095 #endif
00096 
00097   if (font == (TextFont *)NULL || !font->is_valid()) {
00098     // This font was not found or could not be read.
00099     return NULL;
00100   }
00101 
00102   _fonts[filename] = font;
00103   return font;
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: FontPool::ns_add_font
00108 //       Access: Private
00109 //  Description: The nonstatic implementation of add_font().
00110 ////////////////////////////////////////////////////////////////////
00111 void FontPool::
00112 ns_add_font(const string &filename, TextFont *font) {
00113   // We blow away whatever font was there previously, if any.
00114   _fonts[filename] = font;
00115 }
00116 
00117 ////////////////////////////////////////////////////////////////////
00118 //     Function: FontPool::ns_release_font
00119 //       Access: Private
00120 //  Description: The nonstatic implementation of release_font().
00121 ////////////////////////////////////////////////////////////////////
00122 void FontPool::
00123 ns_release_font(const string &filename) {
00124   Fonts::iterator ti;
00125   ti = _fonts.find(filename);
00126   if (ti != _fonts.end()) {
00127     _fonts.erase(ti);
00128   }
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: FontPool::ns_release_all_fonts
00133 //       Access: Private
00134 //  Description: The nonstatic implementation of release_all_fonts().
00135 ////////////////////////////////////////////////////////////////////
00136 void FontPool::
00137 ns_release_all_fonts() {
00138   _fonts.clear();
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: FontPool::ns_garbage_collect
00143 //       Access: Private
00144 //  Description: The nonstatic implementation of garbage_collect().
00145 ////////////////////////////////////////////////////////////////////
00146 int FontPool::
00147 ns_garbage_collect() {
00148   int num_released = 0;
00149   Fonts new_set;
00150 
00151   Fonts::iterator ti;
00152   for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
00153     TextFont *font = (*ti).second;
00154     if (font->get_ref_count() == 1) {
00155       if (text_cat.is_debug()) {
00156         text_cat.debug()
00157           << "Releasing " << (*ti).first << "\n";
00158       }
00159       num_released++;
00160     } else {
00161       new_set.insert(new_set.end(), *ti);
00162     }
00163   }
00164 
00165   _fonts.swap(new_set);
00166   return num_released;
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function: FontPool::ns_list_contents
00171 //       Access: Private
00172 //  Description: The nonstatic implementation of list_contents().
00173 ////////////////////////////////////////////////////////////////////
00174 void FontPool::
00175 ns_list_contents(ostream &out) {
00176   out << _fonts.size() << " fonts:\n";
00177   Fonts::iterator ti;
00178   for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
00179     TextFont *font = (*ti).second;
00180     out << "  " << (*ti).first
00181         << " (count = " << font->get_ref_count() << ")\n";
00182   }
00183 }
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: FontPool::lookup_filename
00187 //       Access: Private, Static
00188 //  Description: Accepts a font "filename", which might consist of a
00189 //               filename followed by an optional colon and a face
00190 //               index, and splits it out into its two components.
00191 //               Then it looks up the filename on the model path.
00192 //               Sets the filename and face index accordingly.
00193 ////////////////////////////////////////////////////////////////////
00194 void FontPool::
00195 lookup_filename(const string &str,
00196                 Filename &filename, int &face_index) {
00197   int colon = (int)str.length() - 1;
00198   // Scan backwards over digits for a colon.
00199   while (colon >= 0 && isdigit(str[colon])) {
00200     colon--;
00201   }
00202   if (colon >= 0 && str[colon] == ':') {
00203     string digits = str.substr(colon + 1);
00204     filename = str.substr(0, colon);
00205     face_index = atoi(digits.c_str());
00206 
00207   } else {
00208     filename = str;
00209     face_index = 0;
00210   }
00211 
00212   // Now look up the filename on the model path.
00213   if (use_vfs) {
00214     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00215     vfs->resolve_filename(filename, get_model_path());
00216 
00217   } else {
00218     filename.resolve_filename(get_model_path());
00219   }
00220 }
00221 
00222 ////////////////////////////////////////////////////////////////////
00223 //     Function: FontPool::get_ptr
00224 //       Access: Private, Static
00225 //  Description: Initializes and/or returns the global pointer to the
00226 //               one FontPool object in the system.
00227 ////////////////////////////////////////////////////////////////////
00228 FontPool *FontPool::
00229 get_ptr() {
00230   if (_global_ptr == (FontPool *)NULL) {
00231     _global_ptr = new FontPool;
00232   }
00233   return _global_ptr;
00234 }

Generated on Fri May 2 00:44:16 2003 for Panda by doxygen1.3