Panda3D
 All Classes Functions Variables Enumerations
freetypeFace.cxx
00001 // Filename: freetypeFace.cxx
00002 // Created by:  gogg (16Nov09)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "freetypeFace.h"
00016 
00017 #ifdef HAVE_FREETYPE
00018 
00019 #include "config_pnmtext.h"
00020 
00021 FT_Library FreetypeFace::_ft_library;
00022 bool FreetypeFace::_ft_initialized = false;
00023 bool FreetypeFace::_ft_ok = false;
00024 
00025 TypeHandle FreetypeFace::_type_handle;
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: FreetypeFace::Constructor
00029 //       Access: Public
00030 //  Description: 
00031 ////////////////////////////////////////////////////////////////////
00032 FreetypeFace::
00033 FreetypeFace() : _lock("FreetypeFace::_lock") {
00034   _face = NULL;
00035   _char_size = 0;
00036   _dpi = 0;
00037   _pixel_width = 0;
00038   _pixel_height = 0;
00039 
00040   if (!_ft_initialized) {
00041     initialize_ft_library();
00042   }
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: FreetypeFace::Destructor
00047 //       Access: Public
00048 //  Description: 
00049 ////////////////////////////////////////////////////////////////////
00050 FreetypeFace::
00051 ~FreetypeFace() {
00052   if (_face != NULL){
00053     FT_Done_Face(_face);
00054   }
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: FreetypeFace::acquire_face
00059 //       Access: Public
00060 //  Description: Retrieves the internal freetype face, and also
00061 //               acquires the lock.  The freetype face is set to the
00062 //               indicated size, either as a char_size and dpi, or as
00063 //               a specific pixel_width and height, before returning.
00064 //
00065 //               You must call release_face() when you are done using
00066 //               it, to release the lock.
00067 ////////////////////////////////////////////////////////////////////
00068 FT_Face FreetypeFace::
00069 acquire_face(int char_size, int dpi, int pixel_width, int pixel_height) {
00070   _lock.acquire();
00071 
00072   if (pixel_height != 0) {
00073     if (pixel_height != _pixel_height || pixel_width != _pixel_width) {
00074       _char_size = 0;
00075       _dpi = 0;
00076       _pixel_height = pixel_height;
00077       _pixel_width = pixel_width;
00078       FT_Set_Pixel_Sizes(_face, _pixel_width, _pixel_height);
00079     }
00080   } else {
00081     if (char_size != _char_size || dpi != _dpi) {
00082       _char_size = char_size;
00083       _dpi = dpi;
00084       _pixel_height = 0;
00085       _pixel_width = 0;
00086       if (_char_size != 0) {
00087         FT_Set_Char_Size(_face, _char_size, _char_size, _dpi, _dpi);
00088       }
00089     }
00090   }
00091 
00092   return _face;
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: FreetypeFace::release_face
00097 //       Access: Public
00098 //  Description: Releases the lock acquired by a previous call to
00099 //               acquire_face(), and allows another thread to use the
00100 //               face.
00101 ////////////////////////////////////////////////////////////////////
00102 void FreetypeFace::
00103 release_face(FT_Face face) {
00104   nassertv(_face == face);
00105   _lock.release();
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //     Function: FreetypeFace::set_face
00110 //       Access: Public
00111 //  Description: Replaces the internal freetype face.
00112 ////////////////////////////////////////////////////////////////////
00113 void FreetypeFace::
00114 set_face(FT_Face face) {
00115   MutexHolder holder(_lock);
00116 
00117   if (_face != NULL){
00118     FT_Done_Face(_face);
00119   }
00120   _face = face;
00121   _char_size = 0;
00122   _dpi = 0;
00123   _pixel_width = 0;
00124   _pixel_height = 0;
00125 
00126   _name = _face->family_name;
00127   if (_face->style_name != NULL) {
00128     _name += " ";
00129     _name += _face->style_name;
00130   }
00131   
00132   pnmtext_cat.info()
00133     << "Loaded font " << _name << "\n";
00134 
00135   if (pnmtext_cat.is_debug()) {
00136     pnmtext_cat.debug()
00137       << _name << " has " << _face->num_charmaps << " charmaps:\n";
00138     for (int i = 0; i < _face->num_charmaps; i++) {
00139       pnmtext_cat.debug(false) << " " << (void *)_face->charmaps[i];
00140     }
00141     pnmtext_cat.debug(false) << "\n";
00142     pnmtext_cat.debug()
00143       << "default charmap is " << (void *)_face->charmap << "\n";
00144   }
00145   if (_face->charmap == NULL) {
00146     // If for some reason FreeType didn't set us up a charmap,
00147     // then set it up ourselves.
00148     if (_face->num_charmaps == 0) {
00149       pnmtext_cat.warning()
00150         << _name << " has no charmaps available.\n";
00151     } else {
00152       pnmtext_cat.warning()
00153         << _name << " has no default Unicode charmap.\n";
00154       if (_face->num_charmaps > 1) {
00155         pnmtext_cat.warning()
00156           << "Arbitrarily choosing first of " 
00157           << _face->num_charmaps << " charmaps.\n";
00158       }
00159       FT_Set_Charmap(_face, _face->charmaps[0]);
00160     }
00161   }
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: FreetypeFace::initialize_ft_library
00166 //       Access: Private, Static
00167 //  Description: Should be called exactly once to initialize the
00168 //               FreeType library.
00169 ////////////////////////////////////////////////////////////////////
00170 void FreetypeFace::
00171 initialize_ft_library() {
00172   if (!_ft_initialized) {
00173     int error = FT_Init_FreeType(&_ft_library);
00174     _ft_initialized = true;
00175     if (error) {
00176       pnmtext_cat.error()
00177         << "Unable to initialize FreeType; dynamic fonts will not load.\n";
00178     } else {
00179       _ft_ok = true;
00180     }
00181   }
00182 }
00183 
00184 #endif  // HAVE_FREETYPE
 All Classes Functions Variables Enumerations