56 PStatCollector TextNode::_text_generate_pcollector(
"*:Generate Text");
62 TextNode(
const string &name) :
PandaNode(name) {
67 _usage_hint = GeomEnums::UH_static;
70 _flatten_flags |= FF_strong;
72 if (text_dynamic_merge) {
73 _flatten_flags |= FF_dynamic_merge;
76 if (text_small_caps) {
80 _frame_color.set(1.0f, 1.0f, 1.0f, 1.0f);
81 _card_color.set(1.0f, 1.0f, 1.0f, 1.0f);
85 _frame_ul.set(0.0f, 0.0f);
86 _frame_lr.set(0.0f, 0.0f);
87 _card_ul.set(0.0f, 0.0f);
88 _card_lr.set(0.0f, 0.0f);
90 _transform = LMatrix4::ident_mat();
91 _coordinate_system = CS_default;
93 _ul3d.set(0.0f, 0.0f, 0.0f);
94 _lr3d.set(0.0f, 0.0f, 0.0f);
107 _usage_hint = GeomEnums::UH_static;
109 _frame_color.set(1.0f, 1.0f, 1.0f, 1.0f);
110 _card_color.set(1.0f, 1.0f, 1.0f, 1.0f);
114 _frame_ul.set(0.0f, 0.0f);
115 _frame_lr.set(0.0f, 0.0f);
116 _card_ul.set(0.0f, 0.0f);
117 _card_lr.set(0.0f, 0.0f);
119 _transform = LMatrix4::ident_mat();
120 _coordinate_system = CS_default;
122 _ul3d.set(0.0f, 0.0f, 0.0f);
123 _lr3d.set(0.0f, 0.0f, 0.0f);
134 _card_texture(copy._card_texture),
135 _frame_color(copy._frame_color),
136 _card_color(copy._card_color),
138 _max_rows(copy._max_rows),
140 _frame_width(copy._frame_width),
141 _card_border_size(copy._card_border_size),
142 _card_border_uv_portion(copy._card_border_uv_portion),
143 _frame_ul(copy._frame_ul),
144 _frame_lr(copy._frame_lr),
145 _card_ul(copy._card_ul),
146 _card_lr(copy._card_lr),
147 _transform(copy._transform),
148 _coordinate_system(copy._coordinate_system),
152 invalidate_with_measure();
179 if (font ==
nullptr) {
201 if (font ==
nullptr) {
220 if (font ==
nullptr) {
244 if (font ==
nullptr) {
259 if (font ==
nullptr) {
263 PN_stdfloat width = 0.0f;
265 std::wstring::const_iterator si;
266 for (si = line.begin(); si != line.end(); ++si) {
277 output(std::ostream &out)
const {
278 PandaNode::output(out);
280 PT(
PandaNode) internal_geom = do_get_internal_geom();
282 if (internal_geom !=
nullptr) {
283 geom_count = count_geoms(internal_geom);
286 out <<
" (" << geom_count <<
" geoms)";
293 write(std::ostream &out,
int indent_level)
const {
294 PandaNode::write(out, indent_level);
296 TextProperties::write(out, indent_level + 2);
297 indent(out, indent_level + 2)
298 <<
"transform is: " << *TransformState::make_mat(_transform) <<
"\n";
299 indent(out, indent_level + 2)
300 <<
"in coordinate system " << _coordinate_system <<
"\n";
301 indent(out, indent_level + 2)
302 <<
"text is " <<
get_text() <<
"\n";
314 get_internal_geom()
const {
318 <<
"TextNode::get_internal_geom() called.\n";
319 return do_get_internal_geom();
328 invalidate_with_measure();
343 SceneGraphReducer::TT_tex_matrix |
344 SceneGraphReducer::TT_other;
360 if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
361 const LMatrix4 &mat = attribs._transform->get_mat();
364 if ((_flags & F_needs_measure) == 0) {
372 if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
373 if (attribs._color !=
nullptr) {
377 TextProperties::set_text_color(c);
378 TextProperties::set_shadow_color(c);
381 invalidate_no_measure();
385 if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
386 if (attribs._color_scale !=
nullptr) {
389 if (s != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)) {
390 LVecBase4 tc = get_text_color();
391 tc.componentwise_mult(s);
392 TextProperties::set_text_color(tc);
394 LVecBase4 sc = get_shadow_color();
395 sc.componentwise_mult(s);
396 TextProperties::set_shadow_color(sc);
398 _frame_color.componentwise_mult(s);
399 _card_color.componentwise_mult(s);
401 invalidate_no_measure();
408 if ((_flags & F_needs_rebuild) == 0 &&
409 _internal_geom !=
nullptr) {
411 gr.
apply_attribs(_internal_geom, attribs, attrib_types, transformer);
427 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
bool &found_any,
430 PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform,
433 PT(
PandaNode) geom = do_get_internal_geom();
434 if (geom !=
nullptr) {
435 geom->calc_tight_bounds(min_point, max_point,
436 found_any, next_transform, current_thread);
439 return next_transform;
463 PT(
PandaNode) internal_geom = do_get_internal_geom();
464 if (internal_geom !=
nullptr) {
492 int &internal_vertices,
494 Thread *current_thread)
const {
507 vertices[0].set(_ul3d[0], _ul3d[1], _ul3d[2]);
508 vertices[1].set(_ul3d[0], _ul3d[1], _lr3d[2]);
509 vertices[2].set(_ul3d[0], _lr3d[1], _ul3d[2]);
510 vertices[3].set(_ul3d[0], _lr3d[1], _lr3d[2]);
511 vertices[4].set(_lr3d[0], _ul3d[1], _ul3d[2]);
512 vertices[5].set(_lr3d[0], _ul3d[1], _lr3d[2]);
513 vertices[6].set(_lr3d[0], _lr3d[1], _ul3d[2]);
514 vertices[7].set(_lr3d[0], _lr3d[1], _lr3d[2]);
517 gbv->
around(vertices, vertices + 8);
519 internal_bounds = bound;
520 internal_vertices = 0;
531 PT(
PandaNode) child = do_get_internal_geom();
532 if (child !=
nullptr) {
533 CPT(
RenderState) child_state = node_state->compose(child->get_state());
534 child->r_prepare_scene(gsg, child_state, transformer, current_thread);
547 _flags &= ~(F_needs_rebuild | F_needs_measure);
548 _internal_geom = do_generate();
572 if (text_cat.is_debug()) {
574 <<
"Rebuilding " << get_type() <<
" " << get_name()
575 <<
" with '" <<
get_text() <<
"'\n";
587 _ul3d.set(0.0f, 0.0f, 0.0f);
588 _lr3d.set(0.0f, 0.0f, 0.0f);
592 size_t newline = name.find(
'\n');
593 if (newline != string::npos) {
594 name = name.substr(0, newline);
603 if (font ==
nullptr) {
610 LMatrix4::convert_mat(CS_zup_right, _coordinate_system) *
614 root->set_transform(transform);
620 assembler.set_properties(*
this);
621 assembler.set_max_rows(_max_rows);
622 assembler.set_usage_hint(_usage_hint);
623 assembler.set_dynamic_merge((_flatten_flags & FF_dynamic_merge) != 0);
624 bool all_set = assembler.set_wtext(wtext);
627 _flags &= ~F_has_overflow;
630 _flags |= F_has_overflow;
633 PT(
PandaNode) text_root = assembler.assemble_text();
634 _text_ul = assembler.get_ul();
635 _text_lr = assembler.get_lr();
636 _num_rows = assembler.get_num_rows();
637 _wordwrapped_wtext = assembler.get_wordwrapped_wtext();
641 root->add_child(text, get_draw_order() + 2);
642 text->add_child(text_root);
646 const LVector2 &ul = assembler.get_ul();
647 const LVector2 &lr = assembler.get_lr();
648 _ul3d.set(ul[0], 0.0f, ul[1]);
649 _lr3d.set(lr[0], 0.0f, lr[1]);
651 _ul3d = _ul3d * _transform;
652 _lr3d = _lr3d * _transform;
655 _flags &= ~F_needs_measure;
661 if (_flatten_flags & FF_strong) {
662 root_np.flatten_strong();
663 }
else if (_flatten_flags & FF_medium) {
664 root_np.flatten_medium();
665 }
else if (_flatten_flags & FF_light) {
666 root_np.flatten_light();
671 if (_flags & F_has_card) {
673 if (_flags & F_has_card_border) {
674 card_root = make_card_with_border();
676 card_root = make_card();
678 card_root->set_transform(transform);
679 card_root->set_attrib(ColorAttrib::make_flat(_card_color));
680 if (_card_color[3] != 1.0f) {
681 card_root->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
683 if (_flags & F_has_card_texture) {
684 card_root->set_attrib(TextureAttrib::make(_card_texture));
688 card_root->set_attrib(CullBinAttrib::make(get_bin(), get_draw_order()));
697 card_root->add_child(root);
700 if (_flags & F_card_decal) {
701 card_root->set_effect(DecalEffect::make());
705 if (_flags & F_has_frame) {
707 frame_root->set_transform(transform);
708 root->add_child(frame_root, get_draw_order() + 1);
709 frame_root->set_attrib(ColorAttrib::make_flat(_frame_color));
710 if (_frame_color[3] != 1.0f) {
711 frame_root->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
715 frame_root->set_attrib(CullBinAttrib::make(get_bin(), get_draw_order() + 1));
730 do_get_internal_geom()
const {
733 return _internal_geom;
742 nassertr((_flags & F_needs_measure) == 0,
nullptr);
746 PN_stdfloat left = _frame_ul[0];
747 PN_stdfloat right = _frame_lr[0];
748 PN_stdfloat bottom = _frame_lr[1];
749 PN_stdfloat top = _frame_ul[1];
751 if (_flags & F_frame_as_margin) {
752 left = _text_ul[0] - left;
753 right = _text_lr[0] + right;
754 bottom = _text_lr[1] - bottom;
755 top = _text_ul[1] + top;
758 CPT(
RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _frame_width);
763 vdata->unclean_set_num_rows(4);
766 vertex.set_data3(left, 0.0f, top);
767 vertex.set_data3(left, 0.0f, bottom);
768 vertex.set_data3(right, 0.0f, bottom);
769 vertex.set_data3(right, 0.0f, top);
772 frame->add_consecutive_vertices(0, 4);
773 frame->add_vertex(0);
774 frame->close_primitive();
777 geom->add_primitive(frame);
778 frame_node->add_geom(geom, state);
780 if (_flags & F_frame_corners) {
782 corners->add_consecutive_vertices(0, 4);
784 geom2->add_primitive(corners);
785 frame_node->add_geom(geom2, state);
797 nassertr((_flags & F_needs_measure) == 0,
nullptr);
801 PN_stdfloat left = _card_ul[0];
802 PN_stdfloat right = _card_lr[0];
803 PN_stdfloat bottom = _card_lr[1];
804 PN_stdfloat top = _card_ul[1];
806 if (_flags & F_card_as_margin) {
807 left = _text_ul[0] - left;
808 right = _text_lr[0] + right;
809 bottom = _text_lr[1] - bottom;
810 top = _text_ul[1] + top;
815 vdata->unclean_set_num_rows(4);
819 vertex.set_data3(left, 0.0f, top);
820 vertex.set_data3(left, 0.0f, bottom);
821 vertex.set_data3(right, 0.0f, top);
822 vertex.set_data3(right, 0.0f, bottom);
824 texcoord.set_data2(0.0f, 1.0f);
825 texcoord.set_data2(0.0f, 0.0f);
826 texcoord.set_data2(1.0f, 1.0f);
827 texcoord.set_data2(1.0f, 0.0f);
830 card->add_consecutive_vertices(0, 4);
831 card->close_primitive();
834 geom->add_primitive(card);
836 card_node->add_geom(geom);
847 make_card_with_border() {
849 nassertr((_flags & F_needs_measure) == 0,
nullptr);
853 PN_stdfloat left = _card_ul[0];
854 PN_stdfloat right = _card_lr[0];
855 PN_stdfloat bottom = _card_lr[1];
856 PN_stdfloat top = _card_ul[1];
858 if (_flags & F_card_as_margin) {
859 left = _text_ul[0] - left;
860 right = _text_lr[0] + right;
861 bottom = _text_lr[1] - bottom;
862 top = _text_ul[1] + top;
873 vdata->unclean_set_num_rows(16);
878 vertex.set_data3(left, 0.02, top);
879 vertex.set_data3(left, 0.02, top - _card_border_size);
880 vertex.set_data3(left + _card_border_size, 0.02, top);
881 vertex.set_data3(left + _card_border_size, 0.02,
882 top - _card_border_size);
884 vertex.set_data3(right - _card_border_size, 0.02, top);
885 vertex.set_data3(right - _card_border_size, 0.02,
886 top - _card_border_size);
887 vertex.set_data3(right, 0.02, top);
888 vertex.set_data3(right, 0.02, top - _card_border_size);
890 vertex.set_data3(left, 0.02, bottom + _card_border_size);
891 vertex.set_data3(left, 0.02, bottom);
892 vertex.set_data3(left + _card_border_size, 0.02,
893 bottom + _card_border_size);
894 vertex.set_data3(left + _card_border_size, 0.02, bottom);
896 vertex.set_data3(right - _card_border_size, 0.02,
897 bottom + _card_border_size);
898 vertex.set_data3(right - _card_border_size, 0.02, bottom);
899 vertex.set_data3(right, 0.02, bottom + _card_border_size);
900 vertex.set_data3(right, 0.02, bottom);
902 texcoord.set_data2(0.0f, 1.0f);
903 texcoord.set_data2(0.0f, 1.0f - _card_border_uv_portion);
904 texcoord.set_data2(0.0f + _card_border_uv_portion, 1.0f);
905 texcoord.set_data2(0.0f + _card_border_uv_portion,
906 1.0f - _card_border_uv_portion);
907 texcoord.set_data2(1.0f -_card_border_uv_portion, 1.0f);
908 texcoord.set_data2(1.0f -_card_border_uv_portion,
909 1.0f - _card_border_uv_portion);
910 texcoord.set_data2(1.0f, 1.0f);
911 texcoord.set_data2(1.0f, 1.0f - _card_border_uv_portion);
913 texcoord.set_data2(0.0f, _card_border_uv_portion);
914 texcoord.set_data2(0.0f, 0.0f);
915 texcoord.set_data2(_card_border_uv_portion, _card_border_uv_portion);
916 texcoord.set_data2(_card_border_uv_portion, 0.0f);
918 texcoord.set_data2(1.0f - _card_border_uv_portion, _card_border_uv_portion);
919 texcoord.set_data2(1.0f - _card_border_uv_portion, 0.0f);
920 texcoord.set_data2(1.0f, _card_border_uv_portion);
921 texcoord.set_data2(1.0f, 0.0f);
924 card->reserve_num_vertices(24);
927 card->add_consecutive_vertices(0, 8);
928 card->close_primitive();
934 card->add_vertex(10);
936 card->add_vertex(12);
938 card->add_vertex(14);
939 card->close_primitive();
942 card->add_consecutive_vertices(8, 8);
943 card->close_primitive();
946 geom->add_primitive(card);
948 card_node->add_geom(geom);
967 for (
size_t i = 0; i < children.get_num_children(); ++i) {
968 num_geoms += count_geoms(children.get_child(i));
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void text_changed() final
Given that we have just read an ampersand from the StringDecoder, and that we have expand_amp in effe...
bool has_character(wchar_t character) const
Returns true if the named character exists in the font or can be synthesized by Panda,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
static bool has_character(wchar_t character, const TextProperties &properties)
Returns true if the named character exists in the font or can be synthesized by Panda,...
Defines a series of disconnected points.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class can be used to convert text between multiple representations, e.g.
PT(PandaNode) TextNode
Returns the actual node that is used internally to render the text, if the TextNode is parented withi...
This defines a bounding sphere, consisting of a center and a radius.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
An interface for simplifying ("flattening") scene graphs by eliminating unneeded nodes and collapsing...
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a series of triangle strips.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static bool is_whitespace(wchar_t character, const TextProperties &properties)
Returns true if the indicated character represents whitespace in the font, or false if anything visib...
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state, GeomTransformer &transformer, Thread *current_thread)
The recursive implementation of prepare_scene().
void traverse(const NodePath &root)
Begins the traversal from the indicated node.
An encapsulation of a font; i.e.
virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer)
Applies whatever attributes are specified in the AccumulatedAttribs object (and by the attrib_types b...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
get_scale
Returns the scale to be applied to colors.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that represents a single element that may be timed and/or counted via stats.
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
static bool has_exact_character(wchar_t character, const TextProperties &properties)
Returns true if the named character exists in the font exactly as named, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool debug_is_locked() const
Returns true if the current thread has locked the Mutex, false otherwise.
static PN_stdfloat calc_width(wchar_t character, const TextProperties &properties)
Returns the width of a single character, according to its associated font.
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_small_caps
Sets the small_caps flag.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
This class is not normally used directly by user code, but is used by the TextNode to lay out a block...
virtual int get_unsafe_to_apply_attribs() const
Returns the union of all attributes from SceneGraphReducer::AttribTypes that may not safely be applie...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_children
Returns an object that can be used to walk through the list of children of the node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_text
Returns the current text, as encoded via the current encoding system.
Applies a scale to colors in the scene graph and on vertices.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void apply_attribs(PandaNode *node, int attrib_types=~(TT_clip_plane|TT_cull_face|TT_apply_texture_color))
Walks the scene graph, accumulating attribs of the indicated types, applying them to the vertices,...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
get_num_geoms
Returns the number of geoms in the node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a series of line strips.
The primary interface to this module.
This defines the set of visual properties that may be assigned to the individual characters of the te...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Indicates what color should be applied to renderable geometry.
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
const std::wstring & get_wtext() const
Returns the text associated with the TextEncoder, as a wide-character string.
bool has_exact_character(wchar_t character) const
Returns true if the named character exists in the font exactly as named, false otherwise.
virtual void r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state, GeomTransformer &transformer, Thread *current_thread)
The recursive implementation of prepare_scene().
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool is_geom_node() const
A simple downcast check.
get_color_type
Returns the type of color specified by this ColorAttrib.
bool around(const GeometricBoundingVolume **first, const GeometricBoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
PN_stdfloat calc_width(wchar_t character) const
Returns the width of a single character of the font, or 0.0 if the character is not known.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
CPT(TransformState) TextNode
This is used to support NodePath::calc_tight_bounds().
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
bool is_whitespace(wchar_t character) const
Returns true if the indicated character represents whitespace in the font, or false if anything visib...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds, int &internal_vertices, int pipeline_stage, Thread *current_thread) const
Called when needed to recompute the node's _internal_bound object.