Panda3D

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