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