Panda3D
 All Classes Functions Variables Enumerations
textProperties.cxx
1 // Filename: textProperties.cxx
2 // Created by: drose (06Apr04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "textProperties.h"
16 #include "config_text.h"
17 #include "default_font.h"
18 #include "dynamicTextFont.h"
19 #include "staticTextFont.h"
20 #include "bamFile.h"
21 #include "fontPool.h"
22 
23 PT(TextFont) TextProperties::_default_font;
24 bool TextProperties::_loaded_default_font = false;
25 
26 TypeHandle TextProperties::_type_handle;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: TextProperties::Constructor
30 // Access: Published
31 // Description:
32 ////////////////////////////////////////////////////////////////////
35  _specified = 0;
36 
37  _small_caps = text_small_caps;
38  _small_caps_scale = text_small_caps_scale;
39  _slant = 0.0f;
40  _underscore = false;
41  _underscore_height = 0.0f;
42  _align = A_left;
43  _indent_width = 0.0f;
44  _wordwrap_width = 0.0f;
45  _preserve_trailing_whitespace = false;
46  _text_color.set(1.0f, 1.0f, 1.0f, 1.0f);
47  _shadow_color.set(0.0f, 0.0f, 0.0f, 1.0f);
48  _shadow_offset.set(0.0f, 0.0f);
49  _draw_order = 1;
50  _tab_width = text_tab_width;
51  _glyph_scale = 1.0f;
52  _glyph_shift = 0.0f;
53  _text_scale = 1.0f;
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: TextProperties::Copy Constructor
58 // Access: Published
59 // Description:
60 ////////////////////////////////////////////////////////////////////
61 TextProperties::
62 TextProperties(const TextProperties &copy) {
63  (*this) = copy;
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: TextProperties::Copy Assignment Operator
68 // Access: Published
69 // Description:
70 ////////////////////////////////////////////////////////////////////
71 void TextProperties::
72 operator = (const TextProperties &copy) {
73  _specified = copy._specified;
74 
75  _font = copy._font;
76  _small_caps = copy._small_caps;
77  _small_caps_scale = copy._small_caps_scale;
78  _slant = copy._slant;
79  _underscore = copy._underscore;
80  _underscore_height = copy._underscore_height;
81  _align = copy._align;
82  _indent_width = copy._indent_width;
83  _wordwrap_width = copy._wordwrap_width;
84  _preserve_trailing_whitespace = copy._preserve_trailing_whitespace;
85  _text_color = copy._text_color;
86  _shadow_color = copy._shadow_color;
87  _shadow_offset = copy._shadow_offset;
88  _bin = copy._bin;
89  _draw_order = copy._draw_order;
90  _tab_width = copy._tab_width;
91  _glyph_scale = copy._glyph_scale;
92  _glyph_shift = copy._glyph_shift;
93  _text_scale = copy._text_scale;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: TextProperties::operator ==
98 // Access: Published
99 // Description:
100 ////////////////////////////////////////////////////////////////////
101 bool TextProperties::
102 operator == (const TextProperties &other) const {
103  if (_specified != other._specified) {
104  return false;
105  }
106 
107  if ((_specified & F_has_font) && _font != other._font) {
108  return false;
109  }
110  if ((_specified & F_has_small_caps) && _small_caps != other._small_caps) {
111  return false;
112  }
113  if ((_specified & F_has_small_caps_scale) && _small_caps_scale != other._small_caps_scale) {
114  return false;
115  }
116  if ((_specified & F_has_slant) && _slant != other._slant) {
117  return false;
118  }
119  if ((_specified & F_has_underscore) && _underscore != other._underscore) {
120  return false;
121  }
122  if ((_specified & F_has_underscore_height) && _underscore_height != other._underscore_height) {
123  return false;
124  }
125  if ((_specified & F_has_align) && _align != other._align) {
126  return false;
127  }
128  if ((_specified & F_has_indent) && _indent_width != other._indent_width) {
129  return false;
130  }
131  if ((_specified & F_has_wordwrap) && _wordwrap_width != other._wordwrap_width) {
132  return false;
133  }
134  if ((_specified & F_has_preserve_trailing_whitespace) && _preserve_trailing_whitespace != other._preserve_trailing_whitespace) {
135  return false;
136  }
137  if ((_specified & F_has_text_color) && _text_color != other._text_color) {
138  return false;
139  }
140  if ((_specified & F_has_text_color) && _text_color != other._text_color) {
141  return false;
142  }
143  if ((_specified & F_has_shadow_color) && _shadow_color != other._shadow_color) {
144  return false;
145  }
146  if ((_specified & F_has_shadow) && _shadow_offset != other._shadow_offset) {
147  return false;
148  }
149  if ((_specified & F_has_bin) && _bin != other._bin) {
150  return false;
151  }
152  if ((_specified & F_has_draw_order) && _draw_order != other._draw_order) {
153  return false;
154  }
155  if ((_specified & F_has_tab_width) && _tab_width != other._tab_width) {
156  return false;
157  }
158  if ((_specified & F_has_glyph_scale) && _glyph_scale != other._glyph_scale) {
159  return false;
160  }
161  if ((_specified & F_has_glyph_shift) && _glyph_shift != other._glyph_shift) {
162  return false;
163  }
164  if ((_specified & F_has_text_scale) && _text_scale != other._text_scale) {
165  return false;
166  }
167  return true;
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: TextProperties::clear
172 // Access: Published
173 // Description: Unsets all properties that have been specified so
174 // far, and resets the TextProperties structure to its
175 // initial empty state.
176 ////////////////////////////////////////////////////////////////////
177 void TextProperties::
178 clear() {
179  (*this) = TextProperties();
180 }
181 
182 ////////////////////////////////////////////////////////////////////
183 // Function: TextProperties::add_properties
184 // Access: Published
185 // Description: Sets any properties that are explicitly specified in
186 // other on this object. Leaves other properties
187 // unchanged.
188 ////////////////////////////////////////////////////////////////////
189 void TextProperties::
190 add_properties(const TextProperties &other) {
191  if (other.has_font()) {
192  set_font(other.get_font());
193  }
194  if (other.has_small_caps()) {
197  }
198  if (other.has_slant()) {
199  set_slant(other.get_slant());
200  }
201  if (other.has_underscore()) {
203  }
204  if (other.has_underscore_height()) {
206  }
207  if (other.has_align()) {
208  set_align(other.get_align());
209  }
210  if (other.has_indent()) {
211  set_indent(other.get_indent());
212  }
213  if (other.has_wordwrap()) {
214  set_wordwrap(other.get_wordwrap());
215  }
216  if (other.has_text_color()) {
217  set_text_color(other.get_text_color());
218  }
219  if (other.has_shadow_color()) {
220  set_shadow_color(other.get_shadow_color());
221  }
222  if (other.has_shadow()) {
223  set_shadow(other.get_shadow());
224  }
225  if (other.has_bin()) {
226  set_bin(other.get_bin());
227  }
228  if (other.has_draw_order()) {
230  }
231  if (other.has_tab_width()) {
232  set_tab_width(other.get_tab_width());
233  }
234 
235  // The glyph scale and shift are a special case: rather than
236  // replacing the previous value, they modify it, so that they apply
237  // cumulatively to nested TextProperties.
238  if (other.has_glyph_shift()) {
240  }
241  if (other.has_glyph_scale()) {
243  }
244 
245  if (other.has_text_scale()) {
247  }
248 }
249 
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: TextProperties::write
253 // Access: Published
254 // Description:
255 ////////////////////////////////////////////////////////////////////
256 void TextProperties::
257 write(ostream &out, int indent_level) const {
258  if (!is_any_specified()) {
259  indent(out, indent_level)
260  << "default properties\n";
261  }
262  if (has_font()) {
263  if (get_font() != (TextFont *)NULL) {
264  indent(out, indent_level)
265  << "with font " << _font->get_name() << "\n";
266  } else {
267  indent(out, indent_level)
268  << "with NULL font\n";
269  }
270  }
271  if (has_small_caps()) {
272  indent(out, indent_level)
273  << "small caps = " << get_small_caps() << "\n";
274  }
275  if (has_small_caps_scale()) {
276  indent(out, indent_level)
277  << "small caps scale = " << get_small_caps_scale() << "\n";
278  }
279  if (has_slant()) {
280  indent(out, indent_level)
281  << "slant = " << get_slant() << "\n";
282  }
283  if (has_underscore()) {
284  indent(out, indent_level)
285  << "underscore = " << get_underscore() << "\n";
286  }
287  if (has_underscore_height()) {
288  indent(out, indent_level)
289  << "underscore_height = " << get_underscore_height() << "\n";
290  }
291 
292  if (has_align()) {
293  indent(out, indent_level)
294  << "alignment is ";
295  switch (get_align()) {
296  case A_left:
297  out << "A_left\n";
298  break;
299 
300  case A_right:
301  out << "A_right\n";
302  break;
303 
304  case A_center:
305  out << "A_center\n";
306  break;
307 
308  case A_boxed_left:
309  out << "A_boxed_left\n";
310  break;
311 
312  case A_boxed_right:
313  out << "A_boxed_right\n";
314  break;
315 
316  case A_boxed_center:
317  out << "A_boxed_center\n";
318  break;
319  }
320  }
321 
322  if (has_indent()) {
323  indent(out, indent_level)
324  << "indent at " << get_indent() << " units.\n";
325  }
326 
327  if (has_wordwrap()) {
328  indent(out, indent_level)
329  << "word-wrapping at " << get_wordwrap() << " units.\n";
330  }
331 
332  if (has_text_color()) {
333  indent(out, indent_level)
334  << "text color is " << get_text_color() << "\n";
335  }
336 
337  if (has_shadow()) {
338  indent(out, indent_level)
339  << "shadow at " << get_shadow() << "\n";
340  }
341  if (has_shadow_color()) {
342  indent(out, indent_level)
343  << "shadow color is " << get_shadow_color() << "\n";
344  }
345 
346  if (has_bin()) {
347  indent(out, indent_level)
348  << "bin is " << get_bin() << "\n";
349  }
350  if (has_draw_order()) {
351  indent(out, indent_level)
352  << "draw order is " << get_draw_order() << "\n";
353  }
354 
355  if (has_tab_width()) {
356  indent(out, indent_level)
357  << "tab width is " << get_tab_width() << "\n";
358  }
359 
360  if (has_glyph_scale()) {
361  indent(out, indent_level)
362  << "glyph scale is " << get_glyph_scale() << "\n";
363  }
364  if (has_glyph_shift()) {
365  indent(out, indent_level)
366  << "glyph shift is " << get_glyph_shift() << "\n";
367  }
368 
369  if (has_text_scale()) {
370  indent(out, indent_level)
371  << "text scale is " << get_text_scale() << "\n";
372  }
373 }
374 
375 ////////////////////////////////////////////////////////////////////
376 // Function: TextProperties::load_default_font
377 // Access: Private, Static
378 // Description: This function is called once (or never), the first
379 // time someone attempts to render a TextNode using the
380 // default font. It should attempt to load the default
381 // font, using the compiled-in version if it is
382 // available, or whatever system file may be named in
383 // Configrc.
384 ////////////////////////////////////////////////////////////////////
385 void TextProperties::
386 load_default_font() {
387  _loaded_default_font = true;
388 
389  if (!text_default_font.empty()) {
390  // First, attempt to load the user-specified filename.
391  _default_font = FontPool::load_font(text_default_font.get_value());
392  if (_default_font != (TextFont *)NULL && _default_font->is_valid()) {
393  return;
394  }
395  }
396 
397  // Then, attempt to load the compiled-in font, if we have one.
398 #ifdef COMPILE_IN_DEFAULT_FONT
399 #ifdef HAVE_FREETYPE
400  // Loading the compiled-in FreeType font is relatively easy.
401  _default_font = new DynamicTextFont((const char *)default_font_data,
402  default_font_size, 0);
403  // The compiled-in font seems to confuse FreeType about its winding order.
404  ((DynamicTextFont *)_default_font.p())->set_winding_order(DynamicTextFont::WO_left);
405 
406 #else
407  // The compiled-in Bam font requires creating a BamFile object to
408  // decode it.
409  string data((const char *)default_font_data, default_font_size);
410 
411 #ifdef HAVE_ZLIB
412  // The font data is stored compressed; decompress it on-the-fly.
413  istringstream inz(data);
414  IDecompressStream in(&inz, false);
415 
416 #else
417  // The font data is stored uncompressed, so just load it.
418  istringstream in(data);
419 #endif // HAVE_ZLIB
420 
421  BamFile bam_file;
422  if (bam_file.open_read(in, "default font stream")) {
423  PT(PandaNode) node = bam_file.read_node();
424  if (node != (PandaNode *)NULL) {
425  _default_font = new StaticTextFont(node);
426  }
427  }
428 
429 #endif // HAVE_FREETYPE
430 #endif // COMPILE_IN_DEFAULT_FONT
431 }
The principle public interface to reading and writing Bam disk files.
Definition: bamFile.h:45
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
void set_shadow(PN_stdfloat xoffset, PN_stdfloat yoffset)
Specifies that the text should be drawn with a shadow, by creating a second copy of the text and offs...
bool open_read(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated filename for reading.
Definition: bamFile.cxx:56
void set_font(TextFont *font)
Sets the font that will be used when making text.
PN_stdfloat get_glyph_scale() const
Returns the scale factor of each letter as specified by set_glyph_scale().
void add_properties(const TextProperties &other)
Sets any properties that are explicitly specified in other on this object.
PN_stdfloat get_glyph_shift() const
Returns the vertical shift of each letter as specified by set_glyph_shift().
void set_align(Alignment align_type)
Specifies the alignment of the text within its margins.
void set_underscore_height(PN_stdfloat underscore_height)
Specifies the vertical height of the underscore, relative to the text baseline.
void set_glyph_scale(PN_stdfloat glyph_scale)
Specifies the factor by which to scale each letter of the text as it is placed, in addition to any sc...
void set_bin(const string &bin)
Names the CullBin that the text geometry should be assigned to.
PN_stdfloat get_slant() const
Returns the factor by which the text is specified to slant to the right.
bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
void set_text_scale(PN_stdfloat text_scale)
Specifies the factor by which to scale the text, in addition to any scalings imposed by the node...
Filename get_value() const
Returns the variable&#39;s value.
PN_stdfloat get_text_scale() const
Returns the scale factor of the text as specified by set_text_scale().
void set_small_caps(bool small_caps)
Sets the small_caps flag.
An encapsulation of a font; i.e.
Definition: textFont.h:36
A StaticTextFont is loaded up from a model that was previously generated via egg-mkfont, and contains all of its glyphs already generated and available for use.
bool has_bin() const
Returns true if an explicit drawing bin has been set via set_bin(), false otherwise.
void set_wordwrap(PN_stdfloat wordwrap)
Sets the text up to automatically wordwrap when it exceeds the indicated width.
void set_small_caps_scale(PN_stdfloat small_caps_scale)
Sets the scale factor applied to lowercase letters from their uppercase equivalents, when the small_caps flag is in effect.
void set_slant(PN_stdfloat slant)
Specifies the factor by which the text slants to the right.
PN_stdfloat get_small_caps_scale() const
Returns the scale factor applied to lowercase letters from their uppercase equivalents, when the small_caps flag is in effect.
bool get_underscore() const
Returns the underscore flag.
int set_draw_order(int draw_order)
Sets the drawing order of text created by the TextNode.
void set_indent(PN_stdfloat indent)
Specifies the amount of extra space that is inserted before the first character of each line...
void set_underscore(bool underscore)
Sets the underscore flag.
const string & get_bin() const
Returns the drawing bin set with set_bin(), or empty string if no bin has been set.
static TextFont * load_font(const string &filename)
Loads the given filename up into a font, if it has not already been loaded, and returns the new font...
Definition: fontPool.I:52
TextFont * get_font() const
Returns the font currently in use, if any.
void clear()
Unsets all properties that have been specified so far, and resets the TextProperties structure to its...
PN_stdfloat get_tab_width() const
Returns the width set via set_tab_width().
This defines the set of visual properties that may be assigned to the individual characters of the te...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
void set_glyph_shift(PN_stdfloat glyph_shift)
Specifies a vertical amount to shift each letter of the text as it is placed.
void set_tab_width(PN_stdfloat tab_width)
Sets the width of each tab stop, in screen units.
LVector2 get_shadow() const
Returns the offset of the shadow as set by set_shadow().
int get_draw_order() const
Returns the drawing order set with set_draw_order().
PN_stdfloat get_underscore_height() const
Returns the vertical height of the underscore; see set_underscore_height().
bool get_small_caps() const
Returns the small_caps flag.