Panda3D
|
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