Panda3D
freetypeFace.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 freetypeFace.cxx
10  * @author gogg
11  * @date 2009-11-16
12  */
13 
14 #include "freetypeFace.h"
15 
16 #ifdef HAVE_FREETYPE
17 
18 #include "config_pnmtext.h"
19 
20 FT_Library FreetypeFace::_ft_library;
21 bool FreetypeFace::_ft_initialized = false;
22 bool FreetypeFace::_ft_ok = false;
23 
24 TypeHandle FreetypeFace::_type_handle;
25 
26 /**
27  *
28  */
29 FreetypeFace::
30 FreetypeFace() : _lock("FreetypeFace::_lock") {
31  _face = nullptr;
32  _char_size = 0;
33  _dpi = 0;
34  _pixel_width = 0;
35  _pixel_height = 0;
36 
37  if (!_ft_initialized) {
38  initialize_ft_library();
39  }
40 }
41 
42 /**
43  *
44  */
45 FreetypeFace::
46 ~FreetypeFace() {
47  if (_face != nullptr){
48  FT_Done_Face(_face);
49  }
50 }
51 
52 /**
53  * Retrieves the internal freetype face, and also acquires the lock. The
54  * freetype face is set to the indicated size, either as a char_size and dpi,
55  * or as a specific pixel_width and height, before returning.
56  *
57  * You must call release_face() when you are done using it, to release the
58  * lock.
59  */
60 FT_Face FreetypeFace::
61 acquire_face(int char_size, int dpi, int pixel_width, int pixel_height) {
62  _lock.acquire();
63 
64  if (pixel_height != 0) {
65  if (pixel_height != _pixel_height || pixel_width != _pixel_width) {
66  _char_size = 0;
67  _dpi = 0;
68  _pixel_height = pixel_height;
69  _pixel_width = pixel_width;
70  FT_Set_Pixel_Sizes(_face, _pixel_width, _pixel_height);
71  }
72  } else {
73  if (char_size != _char_size || dpi != _dpi) {
74  _char_size = char_size;
75  _dpi = dpi;
76  _pixel_height = 0;
77  _pixel_width = 0;
78  if (_char_size != 0) {
79  FT_Set_Char_Size(_face, _char_size, _char_size, _dpi, _dpi);
80  }
81  }
82  }
83 
84  return _face;
85 }
86 
87 /**
88  * Releases the lock acquired by a previous call to acquire_face(), and allows
89  * another thread to use the face.
90  */
91 void FreetypeFace::
92 release_face(FT_Face face) {
93  nassertv(_face == face);
94  _lock.release();
95 }
96 
97 /**
98  * Replaces the internal freetype face.
99  */
100 void FreetypeFace::
101 set_face(FT_Face face) {
102  MutexHolder holder(_lock);
103 
104  if (_face != nullptr){
105  FT_Done_Face(_face);
106  }
107  _face = face;
108  _char_size = 0;
109  _dpi = 0;
110  _pixel_width = 0;
111  _pixel_height = 0;
112 
113  _name = _face->family_name;
114  if (_face->style_name != nullptr) {
115  _name += " ";
116  _name += _face->style_name;
117  }
118 
119  pnmtext_cat.info()
120  << "Loaded font " << _name << "\n";
121 
122  if (pnmtext_cat.is_debug()) {
123  pnmtext_cat.debug()
124  << _name << " has " << _face->num_charmaps << " charmaps:\n";
125  for (int i = 0; i < _face->num_charmaps; i++) {
126  pnmtext_cat.debug(false) << " " << (void *)_face->charmaps[i];
127  }
128  pnmtext_cat.debug(false) << "\n";
129  pnmtext_cat.debug()
130  << "default charmap is " << (void *)_face->charmap << "\n";
131  }
132  if (_face->charmap == nullptr) {
133  // If for some reason FreeType didn't set us up a charmap, then set it up
134  // ourselves.
135  if (_face->num_charmaps == 0) {
136  pnmtext_cat.warning()
137  << _name << " has no charmaps available.\n";
138  } else {
139  pnmtext_cat.warning()
140  << _name << " has no default Unicode charmap.\n";
141  if (_face->num_charmaps > 1) {
142  pnmtext_cat.warning()
143  << "Arbitrarily choosing first of "
144  << _face->num_charmaps << " charmaps.\n";
145  }
146  FT_Set_Charmap(_face, _face->charmaps[0]);
147  }
148  }
149 }
150 
151 /**
152  * Should be called exactly once to initialize the FreeType library.
153  */
154 void FreetypeFace::
155 initialize_ft_library() {
156  if (!_ft_initialized) {
157  int error = FT_Init_FreeType(&_ft_library);
158  _ft_initialized = true;
159  if (error) {
160  pnmtext_cat.error()
161  << "Unable to initialize FreeType; dynamic fonts will not load.\n";
162  } else {
163  _ft_ok = true;
164  }
165  }
166 }
167 
168 #endif // HAVE_FREETYPE
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81