Panda3D
Loading...
Searching...
No Matches
textNode.I
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 textNode.I
10 * @author drose
11 * @date 2002-03-13
12 */
13
14/**
15 * Returns the number of units high each line of text is. This is based on
16 * the font. Note that it is possible for the text to include nested font
17 * change commands, in which case the value of this method is questionable.
18 */
19INLINE PN_stdfloat TextNode::
20get_line_height() const {
21 TextFont *font = get_font();
22 if (font == nullptr) {
23 return 0.0f;
24 }
25
26 return font->get_line_height();
27}
28
29/**
30 * Sets the maximum number of rows that may be formatted by the TextNode. If
31 * more text than this is attempted, it will be truncated and has_overflow()
32 * will return true.
33 */
34INLINE void TextNode::
35set_max_rows(int max_rows) {
36 MutexHolder holder(_lock);
37 _max_rows = max_rows;
38 invalidate_with_measure();
39}
40
41/**
42 * Resets the TextNode's default behavior of not limiting the number of rows
43 * of text.
44 */
45INLINE void TextNode::
47 MutexHolder holder(_lock);
48 _max_rows = 0;
49 invalidate_with_measure();
50}
51
52/**
53 * Returns true if a limit on the height of the TextNode has been set via
54 * set_max_rows(), false otherwise.
55 */
56INLINE bool TextNode::
57has_max_rows() const {
58 MutexHolder holder(_lock);
59 return _max_rows > 0;
60}
61
62/**
63 * Returns the limit on the height of the TextNode specified by
64 * set_max_rows().
65 */
66INLINE int TextNode::
67get_max_rows() const {
68 MutexHolder holder(_lock);
69 return _max_rows;
70}
71
72/**
73 * Returns true if the last text set on the text node exceeded the max_rows
74 * constraint, or false if it all fit.
75 */
76INLINE bool TextNode::
77has_overflow() const {
78 MutexHolder holder(_lock);
79 check_measure();
80 return (_flags & F_has_overflow) != 0;
81}
82
83/**
84 *
85 */
86INLINE void TextNode::
87set_frame_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) {
88 set_frame_color(LColor(r, g, b, a));
89}
90
91/**
92 *
93 */
94INLINE void TextNode::
95set_frame_color(const LColor &frame_color) {
96 MutexHolder holder(_lock);
97 if (_frame_color != frame_color) {
98 _frame_color = frame_color;
99 invalidate_no_measure();
100 }
101}
102
103/**
104 *
105 */
106INLINE LColor TextNode::
107get_frame_color() const {
108 MutexHolder holder(_lock);
109 return _frame_color;
110}
111
112/**
113 *
114 */
115INLINE void TextNode::
116set_card_border(PN_stdfloat size, PN_stdfloat uv_portion) {
117 MutexHolder holder(_lock);
118 if ((_flags & F_has_card_border) == 0 || _card_border_size != size || _card_border_uv_portion != uv_portion) {
119 _flags |= F_has_card_border;
120 _card_border_size = size;
121 _card_border_uv_portion = uv_portion;
122 invalidate_no_measure();
123 }
124}
125
126/**
127 *
128 */
129INLINE void TextNode::
130clear_card_border() {
131 MutexHolder holder(_lock);
132 if (_flags & F_has_card_border) {
133 _flags &= ~F_has_card_border;
134 invalidate_no_measure();
135 }
136}
137
138/**
139 *
140 */
141INLINE PN_stdfloat TextNode::
142get_card_border_size() const {
143 MutexHolder holder(_lock);
144 return _card_border_size;
145}
146
147/**
148 *
149 */
150INLINE PN_stdfloat TextNode::
151get_card_border_uv_portion() const {
152 MutexHolder holder(_lock);
153 return _card_border_uv_portion;
154}
155
156/**
157 *
158 */
159INLINE bool TextNode::
160has_card_border() const {
161 MutexHolder holder(_lock);
162 return (_flags & F_has_card_border) != 0;
163}
164
165/**
166 *
167 */
168INLINE void TextNode::
169set_card_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) {
170 set_card_color(LColor(r, g, b, a));
171}
172
173/**
174 *
175 */
176INLINE void TextNode::
177set_card_color(const LColor &card_color) {
178 MutexHolder holder(_lock);
179 if (_card_color != card_color) {
180 _card_color = card_color;
181 invalidate_no_measure();
182 }
183}
184
185/**
186 *
187 */
188INLINE LColor TextNode::
189get_card_color() const {
190 MutexHolder holder(_lock);
191 return _card_color;
192}
193
194/**
195 *
196 */
197INLINE void TextNode::
198set_card_texture(Texture *card_texture) {
199 if (card_texture == nullptr) {
200 clear_card_texture();
201 } else {
202 MutexHolder holder(_lock);
203 if ((_flags & F_has_card_texture) == 0 || _card_texture != card_texture) {
204 _flags |= F_has_card_texture;
205 _card_texture = card_texture;
206 invalidate_no_measure();
207 }
208 }
209}
210
211/**
212 *
213 */
214INLINE void TextNode::
215clear_card_texture() {
216 MutexHolder holder(_lock);
217 if (_flags & F_has_card_texture) {
218 _flags &= ~F_has_card_texture;
219 _card_texture = nullptr;
220 invalidate_no_measure();
221 }
222}
223
224/**
225 *
226 */
227INLINE bool TextNode::
228has_card_texture() const {
229 MutexHolder holder(_lock);
230 return (_flags & F_has_card_texture) != 0;
231}
232
233/**
234 *
235 */
236INLINE Texture *TextNode::
237get_card_texture() const {
238 MutexHolder holder(_lock);
239 return _card_texture;
240}
241
242/**
243 * Specifies that a border will be drawn around the text when it is next
244 * created. The parameters are the amount of additional padding to insert
245 * between the frame and the text in each dimension, and all should generally
246 * be positive.
247 */
248INLINE void TextNode::
249set_frame_as_margin(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) {
250 MutexHolder holder(_lock);
251 _flags |= (F_has_frame | F_frame_as_margin);
252 _frame_ul.set(left, top);
253 _frame_lr.set(right, bottom);
254 invalidate_no_measure();
255}
256
257/**
258 * Similar to set_frame_as_margin, except the frame is specified in actual
259 * coordinate units (relative to the text's origin), irrespective of the size
260 * of the text. The left and bottom coordinates should generally be negative,
261 * while the right and top coordinates should generally be positive.
262 */
263INLINE void TextNode::
264set_frame_actual(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) {
265 MutexHolder holder(_lock);
266 _flags |= F_has_frame;
267 _flags &= ~F_frame_as_margin;
268 _frame_ul.set(left, top);
269 _frame_lr.set(right, bottom);
270 invalidate_no_measure();
271}
272
273/**
274 * Specifies that a border will not be drawn around the text.
275 */
276INLINE void TextNode::
277clear_frame() {
278 MutexHolder holder(_lock);
279 _flags &= ~F_has_frame;
280 invalidate_no_measure();
281}
282
283/**
284 *
285 */
286INLINE bool TextNode::
287has_frame() const {
288 MutexHolder holder(_lock);
289 return (_flags & F_has_frame) != 0;
290}
291
292/**
293 * If this is true, the frame was set via a call to set_frame_as_margin(), and
294 * the dimension of the frame as returned by get_frame_as_set() represent a
295 * margin all around the text. If false, then the frame was set via a call to
296 * set_frame_actual(), and the dimensions of the frame as returned by
297 * get_frame_as_set() are relative to the text's origin.
298 */
299INLINE bool TextNode::
300is_frame_as_margin() const {
301 MutexHolder holder(_lock);
302 nassertr((_flags & F_has_frame) != 0, false);
303 return (_flags & F_frame_as_margin) != 0;
304}
305
306/**
307 * Returns the dimensions of the frame as set by set_frame_as_margin() or
308 * set_frame_actual(). Use is_frame_actual() to determine how to interpret
309 * the values returned by this function. It is an error to call this if
310 * has_frame() is false.
311 */
312INLINE LVecBase4 TextNode::
313get_frame_as_set() const {
314 MutexHolder holder(_lock);
315 nassertr((_flags & F_has_frame) != 0, LVecBase4(0.0, 0.0, 0.0, 0.0));
316 return LVecBase4(_frame_ul[0], _frame_lr[0], _frame_lr[1], _frame_ul[1]);
317}
318
319/**
320 * Returns the actual dimensions of the frame around the text. If the frame
321 * was set via set_frame_as_margin(), the result returned by this function
322 * reflects the size of the current text; if the frame was set via
323 * set_frame_actual(), this returns the values actually set.
324 *
325 * If the text has no frame at all, this returns the dimensions of the text
326 * itself, as if the frame were set with a margin of 0, 0, 0, 0.
327 */
328INLINE LVecBase4 TextNode::
329get_frame_actual() const {
330 MutexHolder holder(_lock);
331 if (_flags & F_has_frame) {
332 if (_flags & F_frame_as_margin) {
333 check_measure();
334 return LVecBase4(_text_ul[0] - _frame_ul[0],
335 _text_lr[0] + _frame_lr[0],
336 _text_lr[1] - _frame_lr[1],
337 _text_ul[1] + _frame_ul[1]);
338 } else {
339 return LVecBase4(_frame_ul[0], _frame_lr[0], _frame_lr[1], _frame_ul[1]);
340 }
341 } else {
342 check_measure();
343 return LVecBase4(_text_ul[0], _text_lr[0], _text_lr[1], _text_ul[1]);
344 }
345}
346
347/**
348 * Specifies the thickness of the lines that will be used to draw the frame.
349 */
350INLINE void TextNode::
351set_frame_line_width(PN_stdfloat frame_width) {
352 MutexHolder holder(_lock);
353 _frame_width = frame_width;
354 invalidate_no_measure();
355}
356
357/**
358 * Returns the thickness of the lines that will be used to draw the frame.
359 */
360INLINE PN_stdfloat TextNode::
361get_frame_line_width() const {
362 MutexHolder holder(_lock);
363 return _frame_width;
364}
365
366/**
367 * Enables or disables the drawing of corners for the frame. These are extra
368 * points drawn at each of the four corners, to soften the ugly edges
369 * generated when the line width is greater than one.
370 */
371INLINE void TextNode::
372set_frame_corners(bool corners) {
373 MutexHolder holder(_lock);
374 if (corners) {
375 _flags |= F_frame_corners;
376 } else {
377 _flags &= ~F_frame_corners;
378 }
379 invalidate_no_measure();
380}
381
382/**
383 *
384 */
385INLINE bool TextNode::
386get_frame_corners() const {
387 MutexHolder holder(_lock);
388 return (_flags & F_frame_corners) != 0;
389}
390
391/**
392 * Specifies that a (possibly opaque or semitransparent) card will be held
393 * behind the text when it is next created. Like set_frame_as_margin, the
394 * parameters are the amount of additional padding to insert around the text
395 * in each dimension, and all should generally be positive.
396 */
397INLINE void TextNode::
398set_card_as_margin(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) {
399 MutexHolder holder(_lock);
400 _flags |= (F_has_card | F_card_as_margin);
401 _card_ul.set(left, top);
402 _card_lr.set(right, bottom);
403 invalidate_no_measure();
404}
405
406/**
407 * Similar to set_card_as_margin, except the card is specified in actual
408 * coordinate units (relative to the text's origin), irrespective of the size
409 * of the text. The left and bottom coordinates should generally be negative,
410 * while the right and top coordinates should generally be positive.
411 */
412INLINE void TextNode::
413set_card_actual(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) {
414 MutexHolder holder(_lock);
415 _flags |= F_has_card;
416 _flags &= ~F_card_as_margin;
417 _card_ul.set(left, top);
418 _card_lr.set(right, bottom);
419 invalidate_no_measure();
420}
421
422/**
423 * Sets the card_decal flag. When this is true, the text is decalled onto the
424 * card, which is necessary if the TextNode is to be rendered in the 3-d world
425 * without putting it in a bin.
426 */
427INLINE void TextNode::
428set_card_decal(bool card_decal) {
429 MutexHolder holder(_lock);
430 if (card_decal) {
431 _flags |= F_card_decal;
432 } else {
433 _flags &= ~F_card_decal;
434 }
435 invalidate_no_measure();
436}
437
438/**
439 * Specifies that a card will not be drawn behind the text.
440 */
441INLINE void TextNode::
442clear_card() {
443 MutexHolder holder(_lock);
444 _flags &= ~F_has_card;
445 invalidate_no_measure();
446}
447
448/**
449 *
450 */
451INLINE bool TextNode::
452has_card() const {
453 MutexHolder holder(_lock);
454 return (_flags & F_has_card) != 0;
455}
456
457/**
458 * Returns the card_decal flag. See set_card_decal().
459 */
460INLINE bool TextNode::
461get_card_decal() const {
462 MutexHolder holder(_lock);
463 return (_flags & F_card_decal) != 0;
464}
465
466/**
467 * If this is true, the card was set via a call to set_card_as_margin(), and
468 * the dimension of the card as returned by get_card_as_set() represent a
469 * margin all around the text. If false, then the card was set via a call to
470 * set_card_actual(), and the dimensions of the card as returned by
471 * get_card_as_set() are relative to the text's origin.
472 */
473INLINE bool TextNode::
474is_card_as_margin() const {
475 MutexHolder holder(_lock);
476 nassertr((_flags & F_has_card) != 0, false);
477 return (_flags & F_card_as_margin) != 0;
478}
479
480/**
481 * Returns the dimensions of the card as set by set_card_as_margin() or
482 * set_card_actual(). Use is_card_actual() to determine how to interpret the
483 * values returned by this function. It is an error to call this if
484 * has_card() is false.
485 */
486INLINE LVecBase4 TextNode::
487get_card_as_set() const {
488 MutexHolder holder(_lock);
489 nassertr((_flags & F_has_card) != 0, LVecBase4(0.0, 0.0, 0.0, 0.0));
490 return LVecBase4(_card_ul[0], _card_lr[0], _card_lr[1], _card_ul[1]);
491}
492
493/**
494 * Returns the actual dimensions of the card around the text. If the card was
495 * set via set_card_as_margin(), the result returned by this function reflects
496 * the size of the current text; if the card was set via set_card_actual(),
497 * this returns the values actually set.
498 *
499 * If the text has no card at all, this returns the dimensions of the text
500 * itself, as if the card were set with a margin of 0, 0, 0, 0.
501 */
502INLINE LVecBase4 TextNode::
503get_card_actual() const {
504 MutexHolder holder(_lock);
505 if (_flags & F_has_card) {
506 if (_flags & F_card_as_margin) {
507 check_measure();
508 return LVecBase4(_text_ul[0] - _card_ul[0],
509 _text_lr[0] + _card_lr[0],
510 _text_lr[1] - _card_lr[1],
511 _text_ul[1] + _card_ul[1]);
512 } else {
513 return LVecBase4(_card_ul[0], _card_lr[0], _card_lr[1], _card_ul[1]);
514 }
515 } else {
516 check_measure();
517 return LVecBase4(_text_ul[0], _text_lr[0], _text_lr[1], _text_ul[1]);
518 }
519}
520
521/**
522 * Returns the actual card dimensions, transformed by the matrix set by
523 * set_transform(). This returns the card dimensions in actual coordinates as
524 * seen by the rest of the world. Also see get_upper_left_3d() and
525 * get_lower_right_3d().
526 */
527INLINE LVecBase4 TextNode::
528get_card_transformed() const {
529 LVecBase4 card = get_card_actual();
530
531 MutexHolder holder(_lock);
532 LPoint3 ul = LPoint3(card[0], 0.0, card[3]) * _transform;
533 LPoint3 lr = LPoint3(card[1], 0.0, card[2]) * _transform;
534
535 return LVecBase4(ul[0], lr[0], lr[2], ul[2]);
536}
537
538/**
539 * Sets an additional transform that is applied to the entire text paragraph.
540 */
541INLINE void TextNode::
542set_transform(const LMatrix4 &transform) {
543 MutexHolder holder(_lock);
544 _transform = transform;
545 invalidate_with_measure();
546}
547
548/**
549 *
550 */
551INLINE LMatrix4 TextNode::
552get_transform() const {
553 MutexHolder holder(_lock);
554 return _transform;
555}
556
557/**
558 * Specifies the coordinate system in which the text will be generated.
559 */
560INLINE void TextNode::
561set_coordinate_system(CoordinateSystem coordinate_system) {
562 MutexHolder holder(_lock);
563 _coordinate_system = coordinate_system;
564 invalidate_with_measure();
565}
566
567/**
568 *
569 */
570INLINE CoordinateSystem TextNode::
571get_coordinate_system() const {
572 MutexHolder holder(_lock);
573 return _coordinate_system;
574}
575
576/**
577 * Specifies the UsageHint that will be applied to generated geometry. The
578 * default is UH_static, which is probably the right setting, but if you know
579 * the TextNode's geometry will have a short lifespan, it may be better to set
580 * it to UH_stream. See geomEnums.h.
581 */
582INLINE void TextNode::
583set_usage_hint(Geom::UsageHint usage_hint) {
584 MutexHolder holder(_lock);
585 _usage_hint = usage_hint;
586 invalidate_no_measure();
587}
588
589/**
590 * Returns the UsageHint that will be applied to generated geometry. See
591 * set_usage_hint().
592 */
593INLINE Geom::UsageHint TextNode::
594get_usage_hint() const {
595 MutexHolder holder(_lock);
596 return _usage_hint;
597}
598
599/**
600 * Sets the flatten flags. This should be a union of the
601 * TextNode::FlattenFlags options. This controls the degree of flattening
602 * performed on the TextNode's internal geometry (i.e. the scene graph
603 * returned by generate()) each time the text is changed. In general, more
604 * flattening means a more optimal result, but it will take more time to
605 * generate.
606 *
607 * The choice may be any of these three:
608 *
609 * FF_none - No flatten operation is called. The letters are left as
610 * independent Geoms.
611 *
612 * FF_light - A flatten_light() operation is called. The attributes are
613 * applied to the vertices, but no nodes are removed.
614 *
615 * FF_medium - A flatten_medium() operation is called. The attributes are
616 * applied to the vertices, and a few trivial nodes are removed.
617 *
618 * FF_strong - A flatten_strong() operation is called. The attributes are
619 * applied to the vertices, and the resulting nodes are aggressively combined
620 * into as few nodes as possible.
621 *
622 * In addition to the above choices, you may optionally include the following
623 * flag:
624 *
625 * FF_dynamic_merge - Copy the geoms into a single GeomVertexData as we go,
626 * instead of relying on the flatten operation at the end. This pre-flattens
627 * the text considerably, and may obviate the need for flatten altogether; it
628 * also tends to improve performance considerably even if you do call flatten.
629 * However, it is not as fast as not calling flatten at all.
630 *
631 * The default is taken from the text-flatten and text-dynamic-merge config
632 * variables.
633 */
634INLINE void TextNode::
635set_flatten_flags(int flatten_flags) {
636 MutexHolder holder(_lock);
637 _flatten_flags = flatten_flags;
638}
639
640/**
641 * Returns the flatten flags. See set_flatten_flags().
642 */
643INLINE int TextNode::
644get_flatten_flags() const {
645 MutexHolder holder(_lock);
646 return _flatten_flags;
647}
648
649/**
650 * Sets the font that will be used when making text. If this is set to NULL,
651 * the default font will be used, which can be set via set_default_font().
652 */
653INLINE void TextNode::
654set_font(TextFont *font) {
655 MutexHolder holder(_lock);
657 invalidate_with_measure();
658}
659
660/**
661 * Resets the font to the default font.
662 */
663INLINE void TextNode::
664clear_font() {
665 MutexHolder holder(_lock);
667 invalidate_with_measure();
668}
669
670/**
671 * Sets the small_caps flag. When this is set, lowercase letters are
672 * generated as scaled-down versions of their uppercase equivalents. This is
673 * particularly useful to set for fonts that do not have lowercase letters.
674 *
675 * It is also a good idea to set this for a (dynamic) font that has already
676 * implemented lowercase letters as scaled-down versions of their uppercase
677 * equivalents, since without this flag the texture memory may needlessly
678 * duplicate equivalent glyphs for upper and lowercase letters. Setting this
679 * flag causes the texture memory to share the mixed-case letters.
680 *
681 * The amount by which the lowercase letters are scaled is specified by
682 * set_small_caps_scale().
683 */
684INLINE void TextNode::
685set_small_caps(bool small_caps) {
686 MutexHolder holder(_lock);
688 invalidate_with_measure();
689}
690
691/**
692 *
693 */
694INLINE void TextNode::
695clear_small_caps() {
696 MutexHolder holder(_lock);
697 TextProperties::clear_small_caps();
698 invalidate_with_measure();
699}
700
701/**
702 * Sets the scale factor applied to lowercase letters from their uppercase
703 * equivalents, when the small_caps flag is in effect. See set_small_caps().
704 * Normally, this will be a number less than one.
705 */
706INLINE void TextNode::
707set_small_caps_scale(PN_stdfloat small_caps_scale) {
708 MutexHolder holder(_lock);
709 TextProperties::set_small_caps_scale(small_caps_scale);
710 invalidate_with_measure();
711}
712
713/**
714 *
715 */
716INLINE void TextNode::
717clear_small_caps_scale() {
718 MutexHolder holder(_lock);
719 TextProperties::clear_small_caps_scale();
720 invalidate_with_measure();
721}
722
723/**
724 *
725 */
726INLINE void TextNode::
727set_slant(PN_stdfloat slant) {
728 MutexHolder holder(_lock);
730 invalidate_with_measure();
731}
732
733/**
734 *
735 */
736INLINE void TextNode::
737clear_slant() {
738 MutexHolder holder(_lock);
739 TextProperties::clear_slant();
740 invalidate_with_measure();
741}
742
743/**
744 *
745 */
746INLINE void TextNode::
747set_align(TextNode::Alignment align_type) {
748 MutexHolder holder(_lock);
749 TextProperties::set_align(align_type);
750 invalidate_with_measure();
751}
752
753/**
754 *
755 */
756INLINE void TextNode::
757clear_align() {
758 MutexHolder holder(_lock);
760 invalidate_with_measure();
761}
762
763/**
764 * Specifies the amount of extra space that is inserted before the first
765 * character of each line. This can be thought of as a left margin.
766 */
767INLINE void TextNode::
768set_indent(PN_stdfloat indent) {
769 MutexHolder holder(_lock);
771 invalidate_with_measure();
772}
773
774/**
775 *
776 */
777INLINE void TextNode::
778clear_indent() {
779 MutexHolder holder(_lock);
781 invalidate_with_measure();
782}
783
784/**
785 * Sets the text up to automatically wordwrap when it exceeds the indicated
786 * width. This can be thought of as a right margin or margin width.
787 */
788INLINE void TextNode::
789set_wordwrap(PN_stdfloat wordwrap) {
790 MutexHolder holder(_lock);
792 invalidate_with_measure();
793}
794
795/**
796 * Removes the wordwrap setting from the TextNode. Text will be as wide as it
797 * is.
798 */
799INLINE void TextNode::
801 MutexHolder holder(_lock);
803 invalidate_with_measure();
804}
805
806/**
807 *
808 */
809INLINE void TextNode::
810set_text_color(const LColor &text_color) {
811 MutexHolder holder(_lock);
812 TextProperties::set_text_color(text_color);
813 invalidate_no_measure();
814}
815
816/**
817 *
818 */
819INLINE void TextNode::
820set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) {
821 set_text_color(LColor(r, g, b, a));
822}
823
824/**
825 * Removes the text color specification; the text will be colored whatever it
826 * was in the source font file.
827 */
828INLINE void TextNode::
830 MutexHolder holder(_lock);
832 invalidate_no_measure();
833}
834
835/**
836 *
837 */
838INLINE void TextNode::
839set_shadow_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) {
840 set_shadow_color(LColor(r, g, b, a));
841}
842
843/**
844 *
845 */
846INLINE void TextNode::
847set_shadow_color(const LColor &shadow_color) {
848 MutexHolder holder(_lock);
849 TextProperties::set_shadow_color(shadow_color);
850 invalidate_no_measure();
851}
852
853/**
854 *
855 */
856INLINE void TextNode::
857clear_shadow_color() {
858 MutexHolder holder(_lock);
860 invalidate_with_measure();
861}
862
863/**
864 * Specifies that the text should be drawn with a shadow, by creating a second
865 * copy of the text and offsetting it slightly behind the first.
866 */
867INLINE void TextNode::
868set_shadow(PN_stdfloat xoffset, PN_stdfloat yoffset) {
869 set_shadow(LVecBase2(xoffset, yoffset));
870}
871
872/**
873 * Specifies that the text should be drawn with a shadow, by creating a second
874 * copy of the text and offsetting it slightly behind the first.
875 */
876INLINE void TextNode::
877set_shadow(const LVecBase2 &shadow_offset) {
878 MutexHolder holder(_lock);
879 TextProperties::set_shadow(shadow_offset);
880 invalidate_no_measure();
881}
882
883/**
884 * Specifies that a shadow will not be drawn behind the text.
885 */
886INLINE void TextNode::
887clear_shadow() {
888 MutexHolder holder(_lock);
890 invalidate_no_measure();
891}
892
893/**
894 * Names the GeomBin that the TextNode geometry should be assigned to. If
895 * this is set, then a GeomBinTransition will be created to explicitly place
896 * each component in the named bin.
897 *
898 * The draw_order value will also be passed to each GeomBinTransition as
899 * appropriate; this is particularly useful if this names a GeomBinFixed, e.g.
900 * "fixed".
901 */
902INLINE void TextNode::
903set_bin(const std::string &bin) {
904 MutexHolder holder(_lock);
906 invalidate_no_measure();
907}
908
909/**
910 * Removes the effect of a previous call to set_bin(). Text will be drawn in
911 * whatever bin it would like to be drawn in, with no explicit ordering.
912 */
913INLINE void TextNode::
914clear_bin() {
915 MutexHolder holder(_lock);
917 invalidate_no_measure();
918}
919
920/**
921 * Sets the drawing order of text created by the TextMaker. This is actually
922 * the draw order of the card and frame. The shadow is drawn at
923 * _draw_order+1, and the text at _draw_order+2.
924 *
925 * This affects the sorting order assigned to the arcs as they are created,
926 * and also is passed to whatever bin may be assigned via set_bin().
927 *
928 * The return value is the first unused draw_order number, e.g. _draw_order +
929 * 3.
930 */
931INLINE int TextNode::
932set_draw_order(int draw_order) {
933 MutexHolder holder(_lock);
934 invalidate_no_measure();
935 return TextProperties::set_draw_order(draw_order);
936}
937
938/**
939 *
940 */
941INLINE void TextNode::
942clear_draw_order() {
943 MutexHolder holder(_lock);
944 TextProperties::clear_draw_order();
945 invalidate_with_measure();
946}
947
948/**
949 * Sets the width of each tab stop, in screen units. A tab character embedded
950 * in the text will advance the horizontal position to the next tab stop.
951 */
952INLINE void TextNode::
953set_tab_width(PN_stdfloat tab_width) {
954 MutexHolder holder(_lock);
956 invalidate_with_measure();
957}
958
959/**
960 *
961 */
962INLINE void TextNode::
963clear_tab_width() {
964 MutexHolder holder(_lock);
965 TextProperties::clear_tab_width();
966 invalidate_with_measure();
967}
968
969/**
970 * Specifies the factor by which to scale each letter of the text as it is
971 * placed. This can be used (possibly in conjunction with set_glyph_shift())
972 * to implement superscripting or subscripting.
973 */
974INLINE void TextNode::
975set_glyph_scale(PN_stdfloat glyph_scale) {
976 MutexHolder holder(_lock);
978 invalidate_with_measure();
979}
980
981/**
982 *
983 */
984INLINE void TextNode::
985clear_glyph_scale() {
986 MutexHolder holder(_lock);
987 TextProperties::clear_glyph_scale();
988 invalidate_with_measure();
989}
990
991/**
992 * Specifies a vertical amount to shift each letter of the text as it is
993 * placed. This can be used (possibly in conjunction with set_glyph_scale())
994 * to implement superscripting or subscripting.
995 */
996INLINE void TextNode::
997set_glyph_shift(PN_stdfloat glyph_shift) {
998 MutexHolder holder(_lock);
1000 invalidate_with_measure();
1001}
1002
1003/**
1004 *
1005 */
1006INLINE void TextNode::
1007clear_glyph_shift() {
1008 MutexHolder holder(_lock);
1009 TextProperties::clear_glyph_shift();
1010 invalidate_with_measure();
1011}
1012
1013/**
1014 * Returns a string that represents the contents of the text, as it has been
1015 * formatted by wordwrap rules.
1016 *
1017 * In earlier versions, this did not contain any embedded special characters
1018 * like \1 or \3; now it does.
1019 */
1020INLINE std::string TextNode::
1021get_wordwrapped_text() const {
1023}
1024
1025/**
1026 * Returns the width of a line of text of arbitrary characters. The line
1027 * should not include the newline character.
1028 */
1029INLINE PN_stdfloat TextNode::
1030calc_width(const std::string &line) const {
1031 return calc_width(decode_text(line));
1032}
1033
1034/**
1035 * Returns a wstring that represents the contents of the text, as it has been
1036 * formatted by wordwrap rules.
1037 *
1038 * In earlier versions, this did not contain any embedded special characters
1039 * like \1 or \3; now it does.
1040 */
1041INLINE std::wstring TextNode::
1042get_wordwrapped_wtext() const {
1043 MutexHolder holder(_lock);
1044 check_measure();
1045 return _wordwrapped_wtext;
1046}
1047
1048/**
1049 * Returns the leftmost extent of the text in local 2-d coordinates,
1050 * unmodified by the set_transform() matrix.
1051 */
1052INLINE PN_stdfloat TextNode::
1053get_left() const {
1054 MutexHolder holder(_lock);
1055 check_measure();
1056 return _text_ul[0];
1057}
1058
1059/**
1060 * Returns the rightmost extent of the text in local 2-d coordinates,
1061 * unmodified by the set_transform() matrix.
1062 */
1063INLINE PN_stdfloat TextNode::
1064get_right() const {
1065 MutexHolder holder(_lock);
1066 check_measure();
1067 return _text_lr[0];
1068}
1069
1070/**
1071 * Returns the bottommost extent of the text in local 2-d coordinates,
1072 * unmodified by the set_transform() matrix.
1073 */
1074INLINE PN_stdfloat TextNode::
1075get_bottom() const {
1076 MutexHolder holder(_lock);
1077 check_measure();
1078 return _text_lr[1];
1079}
1080
1081/**
1082 * Returns the topmost extent of the text in local 2-d coordinates, unmodified
1083 * by the set_transform() matrix.
1084 */
1085INLINE PN_stdfloat TextNode::
1086get_top() const {
1087 MutexHolder holder(_lock);
1088 check_measure();
1089 return _text_ul[1];
1090}
1091
1092/**
1093 * Returns the net height of the text in local 2-d coordinates.
1094 */
1095INLINE PN_stdfloat TextNode::
1096get_height() const {
1097 MutexHolder holder(_lock);
1098 check_measure();
1099 return _text_ul[1] - _text_lr[1];
1100}
1101
1102/**
1103 * Returns the net width of the text in local 2-d coordinates.
1104 */
1105INLINE PN_stdfloat TextNode::
1106get_width() const {
1107 MutexHolder holder(_lock);
1108 check_measure();
1109 return _text_lr[0] - _text_ul[0];
1110}
1111
1112/**
1113 * Returns the upper-left extent of the text object, after it has been
1114 * transformed into 3-d space by applying the set_transform() matrix.
1115 */
1116INLINE LPoint3 TextNode::
1117get_upper_left_3d() const {
1118 MutexHolder holder(_lock);
1119 check_measure();
1120 return _ul3d;
1121}
1122
1123/**
1124 * Returns the lower-right extent of the text object, after it has been
1125 * transformed into 3-d space by applying the set_transform() matrix.
1126 */
1127INLINE LPoint3 TextNode::
1128get_lower_right_3d() const {
1129 MutexHolder holder(_lock);
1130 check_measure();
1131 return _lr3d;
1132}
1133
1134/**
1135 * Returns the number of rows of text that were generated. This counts word-
1136 * wrapped rows as well as rows generated due to embedded newlines.
1137 */
1138INLINE int TextNode::
1139get_num_rows() const {
1140 MutexHolder holder(_lock);
1141 check_measure();
1142 return _num_rows;
1143}
1144
1145/**
1146 * Generates the text, according to the parameters indicated within the
1147 * TextNode, and returns a Node that may be parented within the tree to
1148 * represent it.
1149 */
1150PT(PandaNode) TextNode::
1151generate() {
1152 MutexHolder holder(_lock);
1153 return do_generate();
1154}
1155
1156/**
1157 * Can be called after the TextNode has been fully configured, to force the
1158 * node to recompute its text immediately, rather than waiting for it to be
1159 * drawn. This call is optional.
1160 */
1161INLINE void TextNode::
1162update() {
1163 MutexHolder holder(_lock);
1164 check_rebuild();
1165}
1166
1167/**
1168 * Forces the TextNode to recompute itself now, even if it believes nothing
1169 * has changed. Normally, this should not need to be called, but it may be
1170 * useful if some properties change outside of the TextNode's knowledge (for
1171 * instance, within the font).
1172 */
1173INLINE void TextNode::
1174force_update() {
1175 MutexHolder holder(_lock);
1176 mark_internal_bounds_stale();
1177 do_rebuild();
1178}
1179
1180/**
1181 * Called internally whenever some state on the TextNode changes, requiring
1182 * the internal geometry to be recomputed, but which will not result in a
1183 * change in the size or shape of the text (for instance, the text color
1184 * changes).
1185 */
1186INLINE void TextNode::
1187invalidate_no_measure() {
1188 _flags |= F_needs_rebuild;
1189}
1190
1191/**
1192 * Called internally whenever some state on the TextNode changes, requiring
1193 * the internal geometry to be recomputed, and which will may result in a
1194 * change in the size or shape of the text (for instance, the text scale
1195 * changes).
1196 */
1197INLINE void TextNode::
1198invalidate_with_measure() {
1199 _flags |= (F_needs_rebuild | F_needs_measure);
1200 mark_internal_bounds_stale();
1201}
1202
1203/**
1204 * Called internally to call do_rebuild() if necessary (that is, if the
1205 * internal geometry has changed recently).
1206 */
1207INLINE void TextNode::
1208check_rebuild() const {
1209 if ((_flags & F_needs_rebuild) != 0) {
1210 ((TextNode *)this)->do_rebuild();
1211 }
1212}
1213
1214/**
1215 * Called internally to call do_measure() if necessary; this will remeasure
1216 * the text without necessarily rebuilding it.
1217 */
1218INLINE void TextNode::
1219check_measure() const {
1220 if ((_flags & F_needs_measure) != 0) {
1221 ((TextNode *)this)->do_measure();
1222 }
1223}
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition mutexHolder.h:25
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
std::wstring decode_text(const std::string &text) const
Returns the given wstring decoded to a single-byte string, via the current encoding system.
std::string encode_wtext(const std::wstring &wtext) const
Encodes a wide-text string into a single-char string, according to the current encoding.
An encapsulation of a font; i.e.
Definition textFont.h:32
get_line_height
Returns the number of units high each line of text is.
Definition textFont.h:69
The primary interface to this module.
Definition textNode.h:48
set_glyph_scale
Specifies the factor by which to scale each letter of the text as it is placed.
Definition textNode.h:263
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.
Definition textNode.cxx:177
void clear_card()
Specifies that a card will not be drawn behind the text.
Definition textNode.I:442
clear_wordwrap
Removes the wordwrap setting from the TextNode.
Definition textNode.h:248
LVecBase4 get_frame_actual() const
Returns the actual dimensions of the frame around the text.
Definition textNode.I:329
LVecBase4 get_frame_as_set() const
Returns the dimensions of the frame as set by set_frame_as_margin() or set_frame_actual().
Definition textNode.I:313
PN_stdfloat get_bottom() const
Returns the bottommost extent of the text in local 2-d coordinates, unmodified by the set_transform()...
Definition textNode.I:1075
PN_stdfloat get_left() const
Returns the leftmost extent of the text in local 2-d coordinates, unmodified by the set_transform() m...
Definition textNode.I:1053
void set_card_actual(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Similar to set_card_as_margin, except the card is specified in actual coordinate units (relative to t...
Definition textNode.I:413
get_usage_hint
Returns the UsageHint that will be applied to generated geometry.
Definition textNode.h:233
LVecBase4 get_card_as_set() const
Returns the dimensions of the card as set by set_card_as_margin() or set_card_actual().
Definition textNode.I:487
PN_stdfloat get_line_height() const
Returns the number of units high each line of text is.
Definition textNode.I:20
set_max_rows
Sets the maximum number of rows that may be formatted by the TextNode.
Definition textNode.h:225
std::string get_wordwrapped_text() const
Returns a string that represents the contents of the text, as it has been formatted by wordwrap rules...
Definition textNode.I:1021
set_indent
Specifies the amount of extra space that is inserted before the first character of each line.
Definition textNode.h:247
void set_frame_as_margin(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Specifies that a border will be drawn around the text when it is next created.
Definition textNode.I:249
clear_text_color
Removes the text color specification; the text will be colored whatever it was in the source font fil...
Definition textNode.h:253
int get_num_rows() const
Returns the number of rows of text that were generated.
Definition textNode.I:1139
set_frame_corners
Enables or disables the drawing of corners for the frame.
Definition textNode.h:230
set_shadow
Specifies that the text should be drawn with a shadow, by creating a second copy of the text and offs...
Definition textNode.h:256
set_wordwrap
Sets the text up to automatically wordwrap when it exceeds the indicated width.
Definition textNode.h:248
void clear_max_rows()
Resets the TextNode's default behavior of not limiting the number of rows of text.
Definition textNode.I:46
clear_font
Resets the font to the default font.
Definition textNode.h:236
void set_frame_actual(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Similar to set_frame_as_margin, except the frame is specified in actual coordinate units (relative to...
Definition textNode.I:264
set_tab_width
Sets the width of each tab stop, in screen units.
Definition textNode.h:261
get_frame_line_width
Returns the thickness of the lines that will be used to draw the frame.
Definition textNode.h:229
void update()
Can be called after the TextNode has been fully configured, to force the node to recompute its text i...
Definition textNode.I:1162
PN_stdfloat get_top() const
Returns the topmost extent of the text in local 2-d coordinates, unmodified by the set_transform() ma...
Definition textNode.I:1086
get_max_rows
Returns the limit on the height of the TextNode specified by set_max_rows().
Definition textNode.h:225
set_usage_hint
Specifies the UsageHint that will be applied to generated geometry.
Definition textNode.h:233
clear_shadow
Specifies that a shadow will not be drawn behind the text.
Definition textNode.h:256
void set_card_decal(bool card_decal)
Sets the card_decal flag.
Definition textNode.I:428
bool is_frame_as_margin() const
If this is true, the frame was set via a call to set_frame_as_margin(), and the dimension of the fram...
Definition textNode.I:300
LVecBase4 get_card_transformed() const
Returns the actual card dimensions, transformed by the matrix set by set_transform().
Definition textNode.I:528
bool has_max_rows() const
Returns true if a limit on the height of the TextNode has been set via set_max_rows(),...
Definition textNode.I:57
void set_card_as_margin(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Specifies that a (possibly opaque or semitransparent) card will be held behind the text when it is ne...
Definition textNode.I:398
set_draw_order
Sets the drawing order of text created by the TextMaker.
Definition textNode.h:259
set_small_caps_scale
Sets the scale factor applied to lowercase letters from their uppercase equivalents,...
Definition textNode.h:240
get_flatten_flags
Returns the flatten flags.
Definition textNode.h:234
bool is_card_as_margin() const
If this is true, the card was set via a call to set_card_as_margin(), and the dimension of the card a...
Definition textNode.I:474
LVecBase4 get_card_actual() const
Returns the actual dimensions of the card around the text.
Definition textNode.I:503
PN_stdfloat get_height() const
Returns the net height of the text in local 2-d coordinates.
Definition textNode.I:1096
bool has_overflow() const
Returns true if the last text set on the text node exceeded the max_rows constraint,...
Definition textNode.I:77
set_frame_line_width
Specifies the thickness of the lines that will be used to draw the frame.
Definition textNode.h:229
PN_stdfloat get_width() const
Returns the net width of the text in local 2-d coordinates.
Definition textNode.I:1106
set_flatten_flags
Sets the flatten flags.
Definition textNode.h:234
set_coordinate_system
Specifies the coordinate system in which the text will be generated.
Definition textNode.h:232
void force_update()
Forces the TextNode to recompute itself now, even if it believes nothing has changed.
Definition textNode.I:1174
set_small_caps
Sets the small_caps flag.
Definition textNode.h:238
PN_stdfloat get_right() const
Returns the rightmost extent of the text in local 2-d coordinates, unmodified by the set_transform() ...
Definition textNode.I:1064
void clear_frame()
Specifies that a border will not be drawn around the text.
Definition textNode.I:277
set_bin
Names the GeomBin that the TextNode geometry should be assigned to.
Definition textNode.h:257
LPoint3 get_upper_left_3d() const
Returns the upper-left extent of the text object, after it has been transformed into 3-d space by app...
Definition textNode.I:1117
set_transform
Sets an additional transform that is applied to the entire text paragraph.
Definition textNode.h:231
LPoint3 get_lower_right_3d() const
Returns the lower-right extent of the text object, after it has been transformed into 3-d space by ap...
Definition textNode.I:1128
clear_bin
Removes the effect of a previous call to set_bin().
Definition textNode.h:257
set_glyph_shift
Specifies a vertical amount to shift each letter of the text as it is placed.
Definition textNode.h:265
std::wstring get_wordwrapped_wtext() const
Returns a wstring that represents the contents of the text, as it has been formatted by wordwrap rule...
Definition textNode.I:1042
bool get_card_decal() const
Returns the card_decal flag.
Definition textNode.I:461
set_font
Sets the font that will be used when making text.
Definition textNode.h:236
set_glyph_shift
Specifies a vertical amount to shift each letter of the text as it is placed.
set_shadow
Specifies that the text should be drawn with a shadow, by creating a second copy of the text and offs...
set_align
Specifies the alignment of the text within its margins.
clear_bin
Removes the effect of a previous call to set_bin().
clear_font
Restores the default font to the text.
clear_shadow
Specifies that a shadow will not be drawn behind the text.
set_draw_order
Sets the drawing order of text created by the TextNode.
set_wordwrap
Sets the text up to automatically wordwrap when it exceeds the indicated width.
clear_indent
Removes the indent setting from the text.
clear_shadow_color
Removes the shadow color specification.
set_font
Sets the font that will be used when making text.
set_small_caps_scale
Sets the scale factor applied to lowercase letters from their uppercase equivalents,...
set_tab_width
Sets the width of each tab stop, in screen units.
clear_text_color
Removes the text color specification; the text will be colored whatever it was in the source font fil...
set_glyph_scale
Specifies the factor by which to scale each letter of the text as it is placed, in addition to any sc...
clear_wordwrap
Removes the wordwrap setting from the text.
set_indent
Specifies the amount of extra space that is inserted before the first character of each line.
clear_align
Restores the default alignment of the text.
set_small_caps
Sets the small_caps flag.
set_slant
Specifies the factor by which the text slants to the right.
set_bin
Names the CullBin that the text geometry should be assigned to.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition texture.h:72
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition indent.cxx:20