00001 // Filename: textNode.I 00002 // Created by: drose (13Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: TextNode::freeze 00022 // Access: Published 00023 // Description: This method is deprecated and no longer does 00024 // anything. It is included for historical purposes 00025 // only and will shortly be removed. 00026 //////////////////////////////////////////////////////////////////// 00027 INLINE int TextNode:: 00028 freeze() { 00029 return 0; 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: TextNode::thaw 00034 // Access: Published 00035 // Description: This method is deprecated and no longer does 00036 // anything. It is included for historical purposes 00037 // only and will shortly be removed. 00038 //////////////////////////////////////////////////////////////////// 00039 INLINE int TextNode:: 00040 thaw() { 00041 return 0; 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: TextNode::set_font 00046 // Access: Published 00047 // Description: Sets the font that will be used when making text. If 00048 // this is set to NULL, the default font will be used, 00049 // which can be set via set_default_font(). 00050 //////////////////////////////////////////////////////////////////// 00051 INLINE void TextNode:: 00052 set_font(TextFont *font) { 00053 if (_font != font) { 00054 _font = font; 00055 invalidate_with_measure(); 00056 } 00057 } 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Function: TextNode::get_font 00061 // Access: Published 00062 // Description: Returns the font currently in use, if any. If this 00063 // returns NULL, the default font will be used, which 00064 // can be retrieved via get_default_font(). 00065 //////////////////////////////////////////////////////////////////// 00066 INLINE TextFont *TextNode:: 00067 get_font() const { 00068 return _font; 00069 } 00070 00071 //////////////////////////////////////////////////////////////////// 00072 // Function: TextNode::set_default_font 00073 // Access: Published, Static 00074 // Description: Specifies the default font to be used for any 00075 // TextNode whose font is uninitialized or NULL. See 00076 // set_font(). 00077 //////////////////////////////////////////////////////////////////// 00078 INLINE void TextNode:: 00079 set_default_font(TextFont *font) { 00080 // If the user overrides the default, we don't need to try to load 00081 // whatever it would have been. 00082 _loaded_default_font = true; 00083 _default_font = font; 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: TextNode::get_default_font 00088 // Access: Published, Static 00089 // Description: Specifies the default font to be used for any 00090 // TextNode whose font is uninitialized or NULL. See 00091 // set_font(). 00092 //////////////////////////////////////////////////////////////////// 00093 INLINE TextFont *TextNode:: 00094 get_default_font() { 00095 if (!_loaded_default_font) { 00096 load_default_font(); 00097 } 00098 return _default_font; 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: TextNode::get_line_height 00103 // Access: Published 00104 // Description: Returns the number of units high each line of text 00105 // is. This is based on the font. 00106 //////////////////////////////////////////////////////////////////// 00107 INLINE float TextNode:: 00108 get_line_height() const { 00109 if (_font != (TextFont *)NULL) { 00110 return _font->get_line_height(); 00111 } else if (get_default_font() != (TextFont *)NULL) { 00112 return _default_font->get_line_height(); 00113 } 00114 return 0.0f; 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: TextNode::set_small_caps 00119 // Access: Published 00120 // Description: Sets the small_caps flag. When this is set, 00121 // lowercase letters are generated as scaled-down 00122 // versions of their uppercase equivalents. This is 00123 // particularly useful to set for fonts that do not have 00124 // lowercase letters. 00125 // 00126 // It is also a good idea to set this for a (dynamic) 00127 // font that has already implemented lowercase letters 00128 // as scaled-down versions of their uppercase 00129 // equivalents, since without this flag the texture 00130 // memory may needlessly duplicate equivalent glyphs for 00131 // upper and lowercase letters. Setting this flag 00132 // causes the texture memory to share the mixed-case 00133 // letters. 00134 // 00135 // The amount by which the lowercase letters are scaled 00136 // is specified by set_small_caps_scale(). 00137 //////////////////////////////////////////////////////////////////// 00138 INLINE void TextNode:: 00139 set_small_caps(bool small_caps) { 00140 if (small_caps) { 00141 _flags |= F_small_caps; 00142 } else { 00143 _flags &= ~F_small_caps; 00144 } 00145 invalidate_with_measure(); 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: TextNode::get_small_caps 00150 // Access: Published 00151 // Description: Returns the small_caps flag. See set_small_caps(). 00152 //////////////////////////////////////////////////////////////////// 00153 INLINE bool TextNode:: 00154 get_small_caps() const { 00155 return (_flags & F_small_caps) != 0; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: TextNode::set_small_caps_scale 00160 // Access: Published 00161 // Description: Sets the scale factor applied to lowercase letters 00162 // from their uppercase equivalents, when the small_caps 00163 // flag is in effect. See set_small_caps(). Normally, 00164 // this will be a number less than one. 00165 //////////////////////////////////////////////////////////////////// 00166 INLINE void TextNode:: 00167 set_small_caps_scale(float small_caps_scale) { 00168 _small_caps_scale = small_caps_scale; 00169 invalidate_with_measure(); 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function: TextNode::get_small_caps_scale 00174 // Access: Published 00175 // Description: Returns the scale factor applied to lowercase letters 00176 // from their uppercase equivalents, when the small_caps 00177 // flag is in effect. See set_small_caps() and 00178 // set_small_caps_scale(). 00179 //////////////////////////////////////////////////////////////////// 00180 INLINE float TextNode:: 00181 get_small_caps_scale() const { 00182 return _small_caps_scale; 00183 } 00184 00185 //////////////////////////////////////////////////////////////////// 00186 // Function: TextNode::set_slant 00187 // Access: Published 00188 // Description: 00189 //////////////////////////////////////////////////////////////////// 00190 INLINE void TextNode:: 00191 set_slant(float slant) { 00192 if (_slant != slant) { 00193 _slant = slant; 00194 invalidate_with_measure(); 00195 } 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: TextNode::get_slant 00200 // Access: Published 00201 // Description: 00202 //////////////////////////////////////////////////////////////////// 00203 INLINE float TextNode:: 00204 get_slant() const { 00205 return _slant; 00206 } 00207 00208 //////////////////////////////////////////////////////////////////// 00209 // Function: TextNode::set_align 00210 // Access: Published 00211 // Description: 00212 //////////////////////////////////////////////////////////////////// 00213 INLINE void TextNode:: 00214 set_align(TextNode::Alignment align_type) { 00215 if (_align != align_type) { 00216 _align = align_type; 00217 invalidate_with_measure(); 00218 } 00219 } 00220 00221 //////////////////////////////////////////////////////////////////// 00222 // Function: TextNode::get_align 00223 // Access: Published 00224 // Description: 00225 //////////////////////////////////////////////////////////////////// 00226 INLINE TextNode::Alignment TextNode:: 00227 get_align() const { 00228 return _align; 00229 } 00230 00231 //////////////////////////////////////////////////////////////////// 00232 // Function: TextNode::set_wordwrap 00233 // Access: Published 00234 // Description: Sets the TextNode up to automatically wordwrap text 00235 // that exceeds the indicated width. 00236 //////////////////////////////////////////////////////////////////// 00237 INLINE void TextNode:: 00238 set_wordwrap(float wordwrap) { 00239 if (!has_wordwrap() || _wordwrap_width != wordwrap) { 00240 _flags |= F_has_wordwrap; 00241 _wordwrap_width = wordwrap; 00242 invalidate_with_measure(); 00243 } 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: TextNode::clear_wordwrap 00248 // Access: Published 00249 // Description: Removes the wordwrap setting from the TextNode. Text 00250 // will be as wide as it is. 00251 //////////////////////////////////////////////////////////////////// 00252 INLINE void TextNode:: 00253 clear_wordwrap() { 00254 if (has_wordwrap()) { 00255 _flags &= ~F_has_wordwrap; 00256 invalidate_with_measure(); 00257 } 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: TextNode::has_wordwrap 00262 // Access: Published 00263 // Description: 00264 //////////////////////////////////////////////////////////////////// 00265 INLINE bool TextNode:: 00266 has_wordwrap() const { 00267 return (_flags & F_has_wordwrap) != 0; 00268 } 00269 00270 //////////////////////////////////////////////////////////////////// 00271 // Function: TextNode::get_wordwrap 00272 // Access: Published 00273 // Description: 00274 //////////////////////////////////////////////////////////////////// 00275 INLINE float TextNode:: 00276 get_wordwrap() const { 00277 return _wordwrap_width; 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: TextNode::set_text_color 00282 // Access: Published 00283 // Description: 00284 //////////////////////////////////////////////////////////////////// 00285 INLINE void TextNode:: 00286 set_text_color(float r, float g, float b, float a) { 00287 set_text_color(Colorf(r, g, b, a)); 00288 } 00289 00290 //////////////////////////////////////////////////////////////////// 00291 // Function: TextNode::set_text_color 00292 // Access: Published 00293 // Description: 00294 //////////////////////////////////////////////////////////////////// 00295 INLINE void TextNode:: 00296 set_text_color(const Colorf &text_color) { 00297 if (!has_text_color() || _text_color != text_color) { 00298 _text_color = text_color; 00299 _flags |= F_has_text_color; 00300 invalidate_no_measure(); 00301 } 00302 } 00303 00304 //////////////////////////////////////////////////////////////////// 00305 // Function: TextNode::clear_text_color 00306 // Access: Published 00307 // Description: Removes the text color specification; the text will 00308 // be colored whatever it was in the source font file. 00309 //////////////////////////////////////////////////////////////////// 00310 INLINE void TextNode:: 00311 clear_text_color() { 00312 if (has_text_color()) { 00313 _flags &= ~F_has_text_color; 00314 invalidate_no_measure(); 00315 } 00316 } 00317 00318 //////////////////////////////////////////////////////////////////// 00319 // Function: TextNode::has_text_color 00320 // Access: Published 00321 // Description: 00322 //////////////////////////////////////////////////////////////////// 00323 INLINE bool TextNode:: 00324 has_text_color() const { 00325 return (_flags & F_has_text_color) != 0; 00326 } 00327 00328 //////////////////////////////////////////////////////////////////// 00329 // Function: TextNode::get_text_color 00330 // Access: Published 00331 // Description: 00332 //////////////////////////////////////////////////////////////////// 00333 INLINE Colorf TextNode:: 00334 get_text_color() const { 00335 return _text_color; 00336 } 00337 00338 //////////////////////////////////////////////////////////////////// 00339 // Function: TextNode::set_frame_color 00340 // Access: Published 00341 // Description: 00342 //////////////////////////////////////////////////////////////////// 00343 INLINE void TextNode:: 00344 set_frame_color(float r, float g, float b, float a) { 00345 set_frame_color(Colorf(r, g, b, a)); 00346 } 00347 00348 //////////////////////////////////////////////////////////////////// 00349 // Function: TextNode::set_frame_color 00350 // Access: Published 00351 // Description: 00352 //////////////////////////////////////////////////////////////////// 00353 INLINE void TextNode:: 00354 set_frame_color(const Colorf &frame_color) { 00355 if (_frame_color != frame_color) { 00356 _frame_color = frame_color; 00357 invalidate_no_measure(); 00358 } 00359 } 00360 00361 //////////////////////////////////////////////////////////////////// 00362 // Function: TextNode::get_frame_color 00363 // Access: Published 00364 // Description: 00365 //////////////////////////////////////////////////////////////////// 00366 INLINE Colorf TextNode:: 00367 get_frame_color() const { 00368 return _frame_color; 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: TextNode::set_card_border 00373 // Access: Published 00374 // Description: 00375 //////////////////////////////////////////////////////////////////// 00376 INLINE void TextNode:: 00377 set_card_border(float size, float uv_portion) { 00378 if (!has_card_border() || _card_border_size != size || _card_border_uv_portion != uv_portion) { 00379 _flags |= F_has_card_border; 00380 _card_border_size = size; 00381 _card_border_uv_portion = uv_portion; 00382 invalidate_no_measure(); 00383 } 00384 } 00385 00386 //////////////////////////////////////////////////////////////////// 00387 // Function: TextNode::clear_card_border 00388 // Access: Published 00389 // Description: 00390 //////////////////////////////////////////////////////////////////// 00391 INLINE void TextNode:: 00392 clear_card_border() { 00393 if (has_card_border()) { 00394 _flags &= ~F_has_card_border; 00395 invalidate_no_measure(); 00396 } 00397 } 00398 00399 //////////////////////////////////////////////////////////////////// 00400 // Function: TextNode::get_card_border_size 00401 // Access: Published 00402 // Description: 00403 //////////////////////////////////////////////////////////////////// 00404 INLINE float TextNode:: 00405 get_card_border_size() const { 00406 return _card_border_size; 00407 } 00408 00409 //////////////////////////////////////////////////////////////////// 00410 // Function: TextNode::get_card_border_uv_portion 00411 // Access: Published 00412 // Description: 00413 //////////////////////////////////////////////////////////////////// 00414 INLINE float TextNode:: 00415 get_card_border_uv_portion() const { 00416 return _card_border_uv_portion; 00417 } 00418 00419 //////////////////////////////////////////////////////////////////// 00420 // Function: TextNode::has_card_border 00421 // Access: Published 00422 // Description: 00423 //////////////////////////////////////////////////////////////////// 00424 INLINE bool TextNode:: 00425 has_card_border() const { 00426 return (_flags & F_has_card_border) != 0; 00427 } 00428 00429 //////////////////////////////////////////////////////////////////// 00430 // Function: TextNode::set_card_color 00431 // Access: Published 00432 // Description: 00433 //////////////////////////////////////////////////////////////////// 00434 INLINE void TextNode:: 00435 set_card_color(float r, float g, float b, float a) { 00436 set_card_color(Colorf(r, g, b, a)); 00437 } 00438 00439 //////////////////////////////////////////////////////////////////// 00440 // Function: TextNode::set_card_color 00441 // Access: Published 00442 // Description: 00443 //////////////////////////////////////////////////////////////////// 00444 INLINE void TextNode:: 00445 set_card_color(const Colorf &card_color) { 00446 if (_card_color != card_color) { 00447 _card_color = card_color; 00448 invalidate_no_measure(); 00449 } 00450 } 00451 00452 //////////////////////////////////////////////////////////////////// 00453 // Function: TextNode::get_card_color 00454 // Access: Published 00455 // Description: 00456 //////////////////////////////////////////////////////////////////// 00457 INLINE Colorf TextNode:: 00458 get_card_color() const { 00459 return _card_color; 00460 } 00461 00462 //////////////////////////////////////////////////////////////////// 00463 // Function: TextNode::set_card_texture 00464 // Access: Published 00465 // Description: 00466 //////////////////////////////////////////////////////////////////// 00467 INLINE void TextNode:: 00468 set_card_texture(Texture *card_texture) { 00469 if (card_texture == (Texture *)NULL) { 00470 clear_card_texture(); 00471 } else { 00472 if (!has_card_texture() || _card_texture != card_texture) { 00473 _flags |= F_has_card_texture; 00474 _card_texture = card_texture; 00475 invalidate_no_measure(); 00476 } 00477 } 00478 } 00479 00480 //////////////////////////////////////////////////////////////////// 00481 // Function: TextNode::clear_card_texture 00482 // Access: Published 00483 // Description: 00484 //////////////////////////////////////////////////////////////////// 00485 INLINE void TextNode:: 00486 clear_card_texture() { 00487 if (has_card_texture()) { 00488 _flags &= ~F_has_card_texture; 00489 _card_texture = NULL; 00490 invalidate_no_measure(); 00491 } 00492 } 00493 00494 //////////////////////////////////////////////////////////////////// 00495 // Function: TextNode::has_card_texture 00496 // Access: Published 00497 // Description: 00498 //////////////////////////////////////////////////////////////////// 00499 INLINE bool TextNode:: 00500 has_card_texture() const { 00501 return (_flags & F_has_card_texture) != 0; 00502 } 00503 00504 //////////////////////////////////////////////////////////////////// 00505 // Function: TextNode::get_card_texture 00506 // Access: Published 00507 // Description: 00508 //////////////////////////////////////////////////////////////////// 00509 INLINE Texture *TextNode:: 00510 get_card_texture() const { 00511 return _card_texture; 00512 } 00513 00514 //////////////////////////////////////////////////////////////////// 00515 // Function: TextNode::set_shadow_color 00516 // Access: Published 00517 // Description: 00518 //////////////////////////////////////////////////////////////////// 00519 INLINE void TextNode:: 00520 set_shadow_color(float r, float g, float b, float a) { 00521 set_shadow_color(Colorf(r, g, b, a)); 00522 } 00523 00524 //////////////////////////////////////////////////////////////////// 00525 // Function: TextNode::set_shadow_color 00526 // Access: Published 00527 // Description: 00528 //////////////////////////////////////////////////////////////////// 00529 INLINE void TextNode:: 00530 set_shadow_color(const Colorf &shadow_color) { 00531 if (_shadow_color != shadow_color) { 00532 _shadow_color = shadow_color; 00533 invalidate_no_measure(); 00534 } 00535 } 00536 00537 //////////////////////////////////////////////////////////////////// 00538 // Function: TextNode::get_shadow_color 00539 // Access: Published 00540 // Description: 00541 //////////////////////////////////////////////////////////////////// 00542 INLINE Colorf TextNode:: 00543 get_shadow_color() const { 00544 return _shadow_color; 00545 } 00546 00547 //////////////////////////////////////////////////////////////////// 00548 // Function: TextNode::set_frame_as_margin 00549 // Access: Published 00550 // Description: Specifies that a border will be drawn around the text 00551 // when it is next created. The parameters are the 00552 // amount of additional padding to insert between the 00553 // frame and the text in each dimension, and all should 00554 // generally be positive. 00555 //////////////////////////////////////////////////////////////////// 00556 INLINE void TextNode:: 00557 set_frame_as_margin(float left, float right, float bottom, float top) { 00558 _flags |= (F_has_frame | F_frame_as_margin); 00559 _frame_ul.set(left, top); 00560 _frame_lr.set(right, bottom); 00561 invalidate_no_measure(); 00562 } 00563 00564 //////////////////////////////////////////////////////////////////// 00565 // Function: TextNode::set_frame_actual 00566 // Access: Published 00567 // Description: Similar to set_frame_as_margin, except the frame is 00568 // specified in actual coordinate units (relative to 00569 // the text's origin), irrespective of the size of the 00570 // text. The left and bottom coordinates should 00571 // generally be negative, while the right and top 00572 // coordinates should generally be positive. 00573 //////////////////////////////////////////////////////////////////// 00574 INLINE void TextNode:: 00575 set_frame_actual(float left, float right, float bottom, float top) { 00576 _flags |= F_has_frame; 00577 _flags &= ~F_frame_as_margin; 00578 _frame_ul.set(left, top); 00579 _frame_lr.set(right, bottom); 00580 invalidate_no_measure(); 00581 } 00582 00583 //////////////////////////////////////////////////////////////////// 00584 // Function: TextNode::clear_frame 00585 // Access: Published 00586 // Description: Specifies that a border will not be drawn around the 00587 // text. 00588 //////////////////////////////////////////////////////////////////// 00589 INLINE void TextNode:: 00590 clear_frame() { 00591 _flags &= ~F_has_frame; 00592 invalidate_no_measure(); 00593 } 00594 00595 //////////////////////////////////////////////////////////////////// 00596 // Function: TextNode::has_frame 00597 // Access: Published 00598 // Description: 00599 //////////////////////////////////////////////////////////////////// 00600 INLINE bool TextNode:: 00601 has_frame() const { 00602 return (_flags & F_has_frame) != 0; 00603 } 00604 00605 //////////////////////////////////////////////////////////////////// 00606 // Function: TextNode::is_frame_as_margin 00607 // Access: Published 00608 // Description: If this is true, the frame was set via a call to 00609 // set_frame_as_margin(), and the dimension of the frame 00610 // as returned by get_frame_as_set() represent a margin 00611 // all around the text. If false, then the frame was 00612 // set via a call to set_frame_actual(), and the 00613 // dimensions of the frame as returned by 00614 // get_frame_as_set() are relative to the text's origin. 00615 //////////////////////////////////////////////////////////////////// 00616 INLINE bool TextNode:: 00617 is_frame_as_margin() const { 00618 nassertr(has_frame(), false); 00619 return (_flags & F_frame_as_margin) != 0; 00620 } 00621 00622 //////////////////////////////////////////////////////////////////// 00623 // Function: TextNode::get_frame_as_set 00624 // Access: Published 00625 // Description: Returns the dimensions of the frame as set by 00626 // set_frame_as_margin() or set_frame_actual(). Use 00627 // is_frame_actual() to determine how to interpret the 00628 // values returned by this function. It is an error to 00629 // call this if has_frame() is false. 00630 //////////////////////////////////////////////////////////////////// 00631 INLINE LVecBase4f TextNode:: 00632 get_frame_as_set() const { 00633 nassertr(has_frame(), LVecBase4f(0.0, 0.0, 0.0, 0.0)); 00634 return LVecBase4f(_frame_ul[0], _frame_lr[0], _frame_lr[1], _frame_ul[1]); 00635 } 00636 00637 //////////////////////////////////////////////////////////////////// 00638 // Function: TextNode::get_frame_actual 00639 // Access: Published 00640 // Description: Returns the actual dimensions of the frame around the 00641 // text. If the frame was set via set_frame_as_margin(), 00642 // the result returned by this function reflects the 00643 // size of the current text; if the frame was set via 00644 // set_frame_actual(), this returns the values 00645 // actually set. 00646 //////////////////////////////////////////////////////////////////// 00647 INLINE LVecBase4f TextNode:: 00648 get_frame_actual() const { 00649 nassertr(has_frame(), LVecBase4f(0.0, 0.0, 0.0, 0.0)); 00650 if (is_frame_as_margin()) { 00651 check_measure(); 00652 return LVecBase4f(_ul2d[0] - _frame_ul[0], 00653 _lr2d[0] + _frame_lr[0], 00654 _lr2d[1] - _frame_lr[1], 00655 _ul2d[1] + _frame_ul[1]); 00656 } else { 00657 return get_frame_as_set(); 00658 } 00659 } 00660 00661 //////////////////////////////////////////////////////////////////// 00662 // Function: TextNode::set_frame_line_width 00663 // Access: Published 00664 // Description: Specifies the thickness of the lines that will be 00665 // used to draw the frame. 00666 //////////////////////////////////////////////////////////////////// 00667 INLINE void TextNode:: 00668 set_frame_line_width(float frame_width) { 00669 _frame_width = frame_width; 00670 } 00671 00672 //////////////////////////////////////////////////////////////////// 00673 // Function: TextNode::get_frame_line_width 00674 // Access: Published 00675 // Description: Returns the thickness of the lines that will be 00676 // used to draw the frame. 00677 //////////////////////////////////////////////////////////////////// 00678 INLINE float TextNode:: 00679 get_frame_line_width() const { 00680 return _frame_width; 00681 } 00682 00683 //////////////////////////////////////////////////////////////////// 00684 // Function: TextNode::set_frame_corners 00685 // Access: Published 00686 // Description: Enables or disables the drawing of corners for the 00687 // frame. These are extra points drawn at each of the 00688 // four corners, to soften the ugly edges generated when 00689 // the line width is greater than one. 00690 //////////////////////////////////////////////////////////////////// 00691 INLINE void TextNode:: 00692 set_frame_corners(bool corners) { 00693 if (corners) { 00694 _flags |= F_frame_corners; 00695 } else { 00696 _flags &= ~F_frame_corners; 00697 } 00698 } 00699 00700 //////////////////////////////////////////////////////////////////// 00701 // Function: TextNode::get_frame_corners 00702 // Access: Published 00703 // Description: 00704 //////////////////////////////////////////////////////////////////// 00705 INLINE bool TextNode:: 00706 get_frame_corners() const { 00707 return (_flags & F_frame_corners) != 0; 00708 } 00709 00710 //////////////////////////////////////////////////////////////////// 00711 // Function: TextNode::set_card_as_margin 00712 // Access: Published 00713 // Description: Specifies that a (possibly opaque or semitransparent) 00714 // card will be held behind the text when it is next 00715 // created. Like set_frame_as_margin, the parameters are 00716 // the amount of additional padding to insert around the 00717 // text in each dimension, and all should generally be 00718 // positive. 00719 //////////////////////////////////////////////////////////////////// 00720 INLINE void TextNode:: 00721 set_card_as_margin(float left, float right, float bottom, float top) { 00722 _flags |= (F_has_card | F_card_as_margin); 00723 _card_ul.set(left, top); 00724 _card_lr.set(right, bottom); 00725 invalidate_no_measure(); 00726 } 00727 00728 //////////////////////////////////////////////////////////////////// 00729 // Function: TextNode::set_card_actual 00730 // Access: Published 00731 // Description: Similar to set_card_as_margin, except the card is 00732 // specified in actual coordinate units (relative to 00733 // the text's origin), irrespective of the size of the 00734 // text. The left and bottom coordinates should 00735 // generally be negative, while the right and top 00736 // coordinates should generally be positive. 00737 //////////////////////////////////////////////////////////////////// 00738 INLINE void TextNode:: 00739 set_card_actual(float left, float right, float bottom, float top) { 00740 _flags |= F_has_card; 00741 _flags &= ~F_card_as_margin; 00742 _card_ul.set(left, top); 00743 _card_lr.set(right, bottom); 00744 invalidate_no_measure(); 00745 } 00746 00747 //////////////////////////////////////////////////////////////////// 00748 // Function: TextNode::clear_card 00749 // Access: Published 00750 // Description: Specifies that a card will not be drawn behind the 00751 // text. 00752 //////////////////////////////////////////////////////////////////// 00753 INLINE void TextNode:: 00754 clear_card() { 00755 _flags &= ~F_has_card; 00756 invalidate_no_measure(); 00757 } 00758 00759 //////////////////////////////////////////////////////////////////// 00760 // Function: TextNode::has_card 00761 // Access: Published 00762 // Description: 00763 //////////////////////////////////////////////////////////////////// 00764 INLINE bool TextNode:: 00765 has_card() const { 00766 return (_flags & F_has_card) != 0; 00767 } 00768 00769 //////////////////////////////////////////////////////////////////// 00770 // Function: TextNode::is_card_as_margin 00771 // Access: Published 00772 // Description: If this is true, the card was set via a call to 00773 // set_card_as_margin(), and the dimension of the card 00774 // as returned by get_card_as_set() represent a margin 00775 // all around the text. If false, then the card was 00776 // set via a call to set_card_actual(), and the 00777 // dimensions of the card as returned by 00778 // get_card_as_set() are relative to the text's origin. 00779 //////////////////////////////////////////////////////////////////// 00780 INLINE bool TextNode:: 00781 is_card_as_margin() const { 00782 nassertr(has_card(), false); 00783 return (_flags & F_card_as_margin) != 0; 00784 } 00785 00786 //////////////////////////////////////////////////////////////////// 00787 // Function: TextNode::get_card_as_set 00788 // Access: Published 00789 // Description: Returns the dimensions of the card as set by 00790 // set_card_as_margin() or set_card_actual(). Use 00791 // is_card_actual() to determine how to interpret the 00792 // values returned by this function. It is an error to 00793 // call this if has_card() is false. 00794 //////////////////////////////////////////////////////////////////// 00795 INLINE LVecBase4f TextNode:: 00796 get_card_as_set() const { 00797 nassertr(has_card(), LVecBase4f(0.0, 0.0, 0.0, 0.0)); 00798 return LVecBase4f(_card_ul[0], _card_lr[0], _card_lr[1], _card_ul[1]); 00799 } 00800 00801 //////////////////////////////////////////////////////////////////// 00802 // Function: TextNode::get_card_actual 00803 // Access: Published 00804 // Description: Returns the actual dimensions of the card around the 00805 // text. If the card was set via set_card_as_margin(), 00806 // the result returned by this function reflects the 00807 // size of the current text; if the card was set via 00808 // set_card_actual(), this returns the values 00809 // actually set. 00810 // 00811 // If the text has no card at all, this returns the 00812 // dimensions of the text itself, as if the card were 00813 // set with a margin of 0, 0, 0, 0. 00814 //////////////////////////////////////////////////////////////////// 00815 INLINE LVecBase4f TextNode:: 00816 get_card_actual() const { 00817 if (!has_card()) { 00818 check_measure(); 00819 return LVecBase4f(_ul2d[0], _lr2d[0], _lr2d[1], _ul2d[1]); 00820 00821 } else if (is_card_as_margin()) { 00822 check_measure(); 00823 return LVecBase4f(_ul2d[0] - _card_ul[0], 00824 _lr2d[0] + _card_lr[0], 00825 _lr2d[1] - _card_lr[1], 00826 _ul2d[1] + _card_ul[1]); 00827 } else { 00828 return get_card_as_set(); 00829 } 00830 } 00831 00832 //////////////////////////////////////////////////////////////////// 00833 // Function: TextNode::get_card_transformed 00834 // Access: Published 00835 // Description: Returns the actual card dimensions, transformed by 00836 // the matrix set by set_transform(). This returns the 00837 // card dimensions in actual coordinates as seen by the 00838 // rest of the world. Also see get_upper_left_3d() and 00839 // get_lower_right_3d(). 00840 //////////////////////////////////////////////////////////////////// 00841 INLINE LVecBase4f TextNode:: 00842 get_card_transformed() const { 00843 LVecBase4f card = get_card_actual(); 00844 LPoint3f ul = LPoint3f(card[0], 0.0, card[3]) * _transform; 00845 LPoint3f lr = LPoint3f(card[1], 0.0, card[2]) * _transform; 00846 00847 return LVecBase4f(ul[0], lr[0], lr[2], ul[2]); 00848 } 00849 00850 //////////////////////////////////////////////////////////////////// 00851 // Function: TextNode::set_shadow 00852 // Access: Published 00853 // Description: Specifies that the text should be drawn with a 00854 // shadow, by creating a second copy of the text and 00855 // offsetting it slightly behind the first. 00856 //////////////////////////////////////////////////////////////////// 00857 INLINE void TextNode:: 00858 set_shadow(float xoffset, float yoffset) { 00859 _flags |= F_has_shadow; 00860 _shadow_offset.set(xoffset, yoffset); 00861 invalidate_no_measure(); 00862 } 00863 00864 //////////////////////////////////////////////////////////////////// 00865 // Function: TextNode::clear_shadow 00866 // Access: Published 00867 // Description: Specifies that a shadow will not be drawn behind the 00868 // text. 00869 //////////////////////////////////////////////////////////////////// 00870 INLINE void TextNode:: 00871 clear_shadow() { 00872 _flags &= ~F_has_shadow; 00873 invalidate_no_measure(); 00874 } 00875 00876 //////////////////////////////////////////////////////////////////// 00877 // Function: TextNode::has_shadow 00878 // Access: Published 00879 // Description: 00880 //////////////////////////////////////////////////////////////////// 00881 INLINE bool TextNode:: 00882 has_shadow() const { 00883 return (_flags & F_has_shadow) != 0; 00884 } 00885 00886 //////////////////////////////////////////////////////////////////// 00887 // Function: TextNode::get_shadow 00888 // Access: Published 00889 // Description: Returns the offset of the shadow as set by 00890 // set_shadow(). It is an error to call this if 00891 // has_shadow() is false. 00892 //////////////////////////////////////////////////////////////////// 00893 INLINE LVecBase2f TextNode:: 00894 get_shadow() const { 00895 nassertr(has_shadow(), LVecBase2f(0.0, 0.0)); 00896 return _shadow_offset; 00897 } 00898 00899 //////////////////////////////////////////////////////////////////// 00900 // Function: TextNode::set_bin 00901 // Access: Published 00902 // Description: Names the GeomBin that the TextNode geometry should 00903 // be assigned to. If this is set, then a 00904 // GeomBinTransition will be created to explicitly place 00905 // each component in the named bin. 00906 // 00907 // The draw_order value will also be passed to each 00908 // GeomBinTransition as appropriate; this is 00909 // particularly useful if this names a GeomBinFixed, 00910 // e.g. "fixed". 00911 //////////////////////////////////////////////////////////////////// 00912 INLINE void TextNode:: 00913 set_bin(const string &bin) { 00914 _bin = bin; 00915 invalidate_no_measure(); 00916 } 00917 00918 //////////////////////////////////////////////////////////////////// 00919 // Function: TextNode::clear_bin 00920 // Access: Published 00921 // Description: Removes the effect of a previous call to 00922 // set_bin(). Text will be drawn in whatever bin 00923 // it would like to be drawn in, with no explicit 00924 // ordering. 00925 //////////////////////////////////////////////////////////////////// 00926 INLINE void TextNode:: 00927 clear_bin() { 00928 _bin = string(); 00929 } 00930 00931 //////////////////////////////////////////////////////////////////// 00932 // Function: TextNode::has_bin 00933 // Access: Published 00934 // Description: Returns true if an explicit drawing bin has been 00935 // set via set_bin(), false otherwise. 00936 //////////////////////////////////////////////////////////////////// 00937 INLINE bool TextNode:: 00938 has_bin() const { 00939 return !_bin.empty(); 00940 } 00941 00942 //////////////////////////////////////////////////////////////////// 00943 // Function: TextNode::get_bin 00944 // Access: Published 00945 // Description: Returns the drawing bin set with set_bin(), or empty 00946 // string if no bin has been set. 00947 //////////////////////////////////////////////////////////////////// 00948 INLINE const string &TextNode:: 00949 get_bin() const { 00950 return _bin; 00951 } 00952 00953 //////////////////////////////////////////////////////////////////// 00954 // Function: TextNode::set_draw_order 00955 // Access: Published 00956 // Description: Sets the drawing order of text created by the 00957 // TextMaker. This is actually the draw order of the 00958 // card and frame. The shadow is drawn at 00959 // _draw_order+1, and the text at _draw_order+2. 00960 // 00961 // This affects the sorting order assigned to the arcs 00962 // as they are created, and also is passed to whatever 00963 // bin may be assigned via set_bin(). 00964 // 00965 // The return value is the first unused draw_order 00966 // number, e.g. _draw_order + 3. 00967 //////////////////////////////////////////////////////////////////// 00968 INLINE int TextNode:: 00969 set_draw_order(int draw_order) { 00970 _draw_order = draw_order; 00971 invalidate_no_measure(); 00972 return _draw_order + 3; 00973 } 00974 00975 //////////////////////////////////////////////////////////////////// 00976 // Function: TextNode::get_draw_order 00977 // Access: Published 00978 // Description: Returns the drawing order set with set_draw_order(). 00979 //////////////////////////////////////////////////////////////////// 00980 INLINE int TextNode:: 00981 get_draw_order() const { 00982 return _draw_order; 00983 } 00984 00985 //////////////////////////////////////////////////////////////////// 00986 // Function: TextNode::set_transform 00987 // Access: Published 00988 // Description: Sets an additional transform that is applied to the 00989 // entire text paragraph. 00990 //////////////////////////////////////////////////////////////////// 00991 INLINE void TextNode:: 00992 set_transform(const LMatrix4f &transform) { 00993 _transform = transform; 00994 invalidate_with_measure(); 00995 } 00996 00997 //////////////////////////////////////////////////////////////////// 00998 // Function: TextNode::get_transform 00999 // Access: Published 01000 // Description: 01001 //////////////////////////////////////////////////////////////////// 01002 INLINE LMatrix4f TextNode:: 01003 get_transform() const { 01004 return _transform; 01005 } 01006 01007 //////////////////////////////////////////////////////////////////// 01008 // Function: TextNode::set_coordinate_system 01009 // Access: Published 01010 // Description: Specifies the coordinate system in which the text 01011 // will be generated. 01012 //////////////////////////////////////////////////////////////////// 01013 INLINE void TextNode:: 01014 set_coordinate_system(CoordinateSystem coordinate_system) { 01015 _coordinate_system = coordinate_system; 01016 invalidate_with_measure(); 01017 } 01018 01019 //////////////////////////////////////////////////////////////////// 01020 // Function: TextNode::get_coordinate_system 01021 // Access: Published 01022 // Description: 01023 //////////////////////////////////////////////////////////////////// 01024 INLINE CoordinateSystem TextNode:: 01025 get_coordinate_system() const { 01026 return _coordinate_system; 01027 } 01028 01029 //////////////////////////////////////////////////////////////////// 01030 // Function: TextNode::set_text 01031 // Access: Published 01032 // Description: Changes the text that is displayed under the 01033 // TextNode. 01034 //////////////////////////////////////////////////////////////////// 01035 INLINE void TextNode:: 01036 set_text(const string &text) { 01037 TextEncoder::set_text(text); 01038 invalidate_with_measure(); 01039 } 01040 01041 //////////////////////////////////////////////////////////////////// 01042 // Function: TextNode::set_text 01043 // Access: Published 01044 // Description: The two-parameter version of set_text() accepts an 01045 // explicit encoding; the text is immediately decoded 01046 // and stored as a wide-character string. Subsequent 01047 // calls to get_text() will return the same text 01048 // re-encoded using whichever encoding is specified by 01049 // set_encoding(). 01050 //////////////////////////////////////////////////////////////////// 01051 INLINE void TextNode:: 01052 set_text(const string &text, TextNode::Encoding encoding) { 01053 TextEncoder::set_text(text, encoding); 01054 invalidate_with_measure(); 01055 } 01056 01057 //////////////////////////////////////////////////////////////////// 01058 // Function: TextNode::clear_text 01059 // Access: Published 01060 // Description: Removes the text from the TextNode. 01061 //////////////////////////////////////////////////////////////////// 01062 INLINE void TextNode:: 01063 clear_text() { 01064 TextEncoder::clear_text(); 01065 invalidate_with_measure(); 01066 } 01067 01068 //////////////////////////////////////////////////////////////////// 01069 // Function: TextNode::append_text 01070 // Access: Published 01071 // Description: Appends the indicates string to the end of the stored 01072 // text. 01073 //////////////////////////////////////////////////////////////////// 01074 INLINE void TextNode:: 01075 append_text(const string &text) { 01076 TextEncoder::append_text(text); 01077 invalidate_with_measure(); 01078 } 01079 01080 //////////////////////////////////////////////////////////////////// 01081 // Function: TextNode::append_unicode_char 01082 // Access: Published 01083 // Description: Appends a single character to the end of the stored 01084 // text. This may be a wide character, up to 16 bits in 01085 // Unicode. 01086 //////////////////////////////////////////////////////////////////// 01087 INLINE void TextNode:: 01088 append_unicode_char(int character) { 01089 TextEncoder::append_unicode_char(character); 01090 invalidate_with_measure(); 01091 } 01092 01093 //////////////////////////////////////////////////////////////////// 01094 // Function: TextNode::calc_width 01095 // Access: Published 01096 // Description: Returns the width of a single character of the font, 01097 // or 0.0 if the character is not known. This may be a 01098 // wide character (greater than 255). 01099 //////////////////////////////////////////////////////////////////// 01100 INLINE float TextNode:: 01101 calc_width(int character) const { 01102 nassertr(_font != (TextFont *)NULL, 0.0); 01103 return _font->calc_width(character); 01104 } 01105 01106 //////////////////////////////////////////////////////////////////// 01107 // Function: TextNode::calc_width 01108 // Access: Published 01109 // Description: Returns the width of a line of text of arbitrary 01110 // characters. The line should not include the newline 01111 // character. 01112 //////////////////////////////////////////////////////////////////// 01113 INLINE float TextNode:: 01114 calc_width(const string &line) const { 01115 nassertr(_font != (TextFont *)NULL, 0.0); 01116 return _font->calc_width(decode_text(line)); 01117 } 01118 01119 //////////////////////////////////////////////////////////////////// 01120 // Function: TextNode::get_left 01121 // Access: Published 01122 // Description: Returns the leftmost extent of the text in local 2-d 01123 // coordinates, unmodified by the set_transform() 01124 // matrix. 01125 //////////////////////////////////////////////////////////////////// 01126 INLINE float TextNode:: 01127 get_left() const { 01128 check_measure(); 01129 return _ul2d[0]; 01130 } 01131 01132 //////////////////////////////////////////////////////////////////// 01133 // Function: TextNode::get_right 01134 // Access: Published 01135 // Description: Returns the rightmost extent of the text in local 2-d 01136 // coordinates, unmodified by the set_transform() 01137 // matrix. 01138 //////////////////////////////////////////////////////////////////// 01139 INLINE float TextNode:: 01140 get_right() const { 01141 check_measure(); 01142 return _lr2d[0]; 01143 } 01144 01145 //////////////////////////////////////////////////////////////////// 01146 // Function: TextNode::get_bottom 01147 // Access: Published 01148 // Description: Returns the bottommost extent of the text in local 01149 // 2-d coordinates, unmodified by the set_transform() 01150 // matrix. 01151 //////////////////////////////////////////////////////////////////// 01152 INLINE float TextNode:: 01153 get_bottom() const { 01154 check_measure(); 01155 return _lr2d[1]; 01156 } 01157 01158 //////////////////////////////////////////////////////////////////// 01159 // Function: TextNode::get_top 01160 // Access: Published 01161 // Description: Returns the topmost extent of the text in local 2-d 01162 // coordinates, unmodified by the set_transform() 01163 // matrix. 01164 //////////////////////////////////////////////////////////////////// 01165 INLINE float TextNode:: 01166 get_top() const { 01167 check_measure(); 01168 return _ul2d[1]; 01169 } 01170 01171 //////////////////////////////////////////////////////////////////// 01172 // Function: TextNode::get_height 01173 // Access: Published 01174 // Description: Returns the net height of the text in local 2-d 01175 // coordinates. 01176 //////////////////////////////////////////////////////////////////// 01177 INLINE float TextNode:: 01178 get_height() const { 01179 check_measure(); 01180 return _ul2d[1] - _lr2d[1]; 01181 } 01182 01183 //////////////////////////////////////////////////////////////////// 01184 // Function: TextNode::get_width 01185 // Access: Published 01186 // Description: Returns the net width of the text in local 2-d 01187 // coordinates. 01188 //////////////////////////////////////////////////////////////////// 01189 INLINE float TextNode:: 01190 get_width() const { 01191 check_measure(); 01192 return _lr2d[0] - _ul2d[0]; 01193 } 01194 01195 //////////////////////////////////////////////////////////////////// 01196 // Function: TextNode::get_upper_left_3d 01197 // Access: Published 01198 // Description: Returns the upper-left extent of the text object, 01199 // after it has been transformed into 3-d space by 01200 // applying the set_transform() matrix. 01201 //////////////////////////////////////////////////////////////////// 01202 INLINE LPoint3f TextNode:: 01203 get_upper_left_3d() const { 01204 check_measure(); 01205 return _ul3d; 01206 } 01207 01208 //////////////////////////////////////////////////////////////////// 01209 // Function: TextNode::get_lower_right_3d 01210 // Access: Published 01211 // Description: Returns the lower-right extent of the text object, 01212 // after it has been transformed into 3-d space by 01213 // applying the set_transform() matrix. 01214 //////////////////////////////////////////////////////////////////// 01215 INLINE LPoint3f TextNode:: 01216 get_lower_right_3d() const { 01217 check_measure(); 01218 return _lr3d; 01219 } 01220 01221 //////////////////////////////////////////////////////////////////// 01222 // Function: TextNode::get_num_rows 01223 // Access: Published 01224 // Description: Returns the number of rows of text that were 01225 // generated. This counts word-wrapped rows as well as 01226 // rows generated due to embedded newlines. 01227 //////////////////////////////////////////////////////////////////// 01228 INLINE int TextNode:: 01229 get_num_rows() const { 01230 check_measure(); 01231 return _num_rows; 01232 } 01233 01234 //////////////////////////////////////////////////////////////////// 01235 // Function: TextNode::update 01236 // Access: Published 01237 // Description: Can be called after the TextNode has been fully 01238 // configured, to force the node to recompute its text 01239 // immediately, rather than waiting for it to be drawn. 01240 // This call is optional. 01241 //////////////////////////////////////////////////////////////////// 01242 INLINE void TextNode:: 01243 update() { 01244 check_rebuild(); 01245 } 01246 01247 //////////////////////////////////////////////////////////////////// 01248 // Function: TextNode::force_update 01249 // Access: Published 01250 // Description: Forces the TextNode to recompute itself now, even if 01251 // it believes nothing has changed. Normally, this 01252 // should not need to be called, but it may be useful if 01253 // some properties change outside of the TextNode's 01254 // knowledge (for instance, within the font). 01255 //////////////////////////////////////////////////////////////////// 01256 INLINE void TextNode:: 01257 force_update() { 01258 invalidate_with_measure(); 01259 check_rebuild(); 01260 } 01261 01262 //////////////////////////////////////////////////////////////////// 01263 // Function: TextNode::set_wtext 01264 // Access: Public 01265 // Description: Changes the text that is displayed under the 01266 // TextNode, with a wide text. This automatically sets 01267 // the string reported by get_text() to the 8-bit 01268 // encoded version of the same string. 01269 //////////////////////////////////////////////////////////////////// 01270 INLINE void TextNode:: 01271 set_wtext(const wstring &wtext) { 01272 TextEncoder::set_wtext(wtext); 01273 invalidate_with_measure(); 01274 } 01275 01276 //////////////////////////////////////////////////////////////////// 01277 // Function: TextNode::append_wtext 01278 // Access: Public 01279 // Description: Appends the indicates string to the end of the stored 01280 // wide-character text. 01281 //////////////////////////////////////////////////////////////////// 01282 INLINE void TextNode:: 01283 append_wtext(const wstring &wtext) { 01284 TextEncoder::append_wtext(wtext); 01285 invalidate_with_measure(); 01286 } 01287 01288 //////////////////////////////////////////////////////////////////// 01289 // Function: TextNode::calc_width 01290 // Access: Public 01291 // Description: Returns the width of a line of text of arbitrary 01292 // characters. The line should not include the newline 01293 // character. 01294 //////////////////////////////////////////////////////////////////// 01295 INLINE float TextNode:: 01296 calc_width(const wstring &line) const { 01297 nassertr(_font != (TextFont *)NULL, 0.0); 01298 return _font->calc_width(line); 01299 } 01300 01301 //////////////////////////////////////////////////////////////////// 01302 // Function: TextNode::wordwrap_to 01303 // Access: Public 01304 // Description: Inserts newlines into the given text at the 01305 // appropriate places in order to make each line be the 01306 // longest possible line that is not longer than 01307 // wordwrap_width (and does not break any words, if 01308 // possible). Returns the new string. 01309 //////////////////////////////////////////////////////////////////// 01310 INLINE wstring TextNode:: 01311 wordwrap_to(const wstring &wtext, float wordwrap_width, 01312 bool preserve_trailing_whitespace) const { 01313 nassertr(_font != (TextFont *)NULL, wtext); 01314 return _font->wordwrap_to(wtext, wordwrap_width, preserve_trailing_whitespace); 01315 } 01316 01317 //////////////////////////////////////////////////////////////////// 01318 // Function: TextNode::invalidate_no_measure 01319 // Access: Private 01320 // Description: Called internally whenever some state on the TextNode 01321 // changes, requiring the internal geometry to be 01322 // recomputed, but which will not result in a change in 01323 // the size or shape of the text (for instance, the text 01324 // color changes). 01325 //////////////////////////////////////////////////////////////////// 01326 INLINE void TextNode:: 01327 invalidate_no_measure() { 01328 _flags |= F_needs_rebuild; 01329 } 01330 01331 //////////////////////////////////////////////////////////////////// 01332 // Function: TextNode::invalidate_with_measure 01333 // Access: Private 01334 // Description: Called internally whenever some state on the TextNode 01335 // changes, requiring the internal geometry to be 01336 // recomputed, and which will may result in a change in 01337 // the size or shape of the text (for instance, the text 01338 // scale changes). 01339 //////////////////////////////////////////////////////////////////// 01340 INLINE void TextNode:: 01341 invalidate_with_measure() { 01342 _flags |= (F_needs_rebuild | F_needs_measure); 01343 mark_bound_stale(); 01344 } 01345 01346 //////////////////////////////////////////////////////////////////// 01347 // Function: TextNode::check_rebuild 01348 // Access: Private 01349 // Description: Called internally to call do_rebuild() if necessary 01350 // (that is, if the internal geometry has changed 01351 // recently). 01352 //////////////////////////////////////////////////////////////////// 01353 INLINE void TextNode:: 01354 check_rebuild() const { 01355 if ((_flags & F_needs_rebuild) != 0) { 01356 ((TextNode *)this)->do_rebuild(); 01357 } 01358 } 01359 01360 //////////////////////////////////////////////////////////////////// 01361 // Function: TextNode::check_measure 01362 // Access: Private 01363 // Description: Called internally to call do_measure() if necessary; 01364 // this will remeasure the text without necessarily 01365 // rebuilding it. 01366 //////////////////////////////////////////////////////////////////// 01367 INLINE void TextNode:: 01368 check_measure() const { 01369 if ((_flags & F_needs_measure) != 0) { 01370 ((TextNode *)this)->do_measure(); 01371 } 01372 }