Panda3D
|
00001 // Filename: textAssembler.I 00002 // Created by: drose (06Apr04) 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: TextAssembler::set_usage_hint 00018 // Access: Published 00019 // Description: Specifies the UsageHint that will be applied to 00020 // generated geometry. The default is UH_static, which 00021 // is probably the right setting, but if you know the 00022 // TextNode's geometry will have a short lifespan, it 00023 // may be better to set it to UH_stream. See 00024 // geomEnums.h. 00025 //////////////////////////////////////////////////////////////////// 00026 INLINE void TextAssembler:: 00027 set_usage_hint(Geom::UsageHint usage_hint) { 00028 _usage_hint = usage_hint; 00029 } 00030 00031 //////////////////////////////////////////////////////////////////// 00032 // Function: TextAssembler::get_usage_hint 00033 // Access: Published 00034 // Description: Returns the UsageHint that will be applied to 00035 // generated geometry. See set_usage_hint(). 00036 //////////////////////////////////////////////////////////////////// 00037 INLINE Geom::UsageHint TextAssembler:: 00038 get_usage_hint() const { 00039 return _usage_hint; 00040 } 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: TextAssembler::set_max_rows 00044 // Access: Published 00045 // Description: If max_rows is greater than zero, no more than 00046 // max_rows will be accepted. Text beyond that will be 00047 // truncated. 00048 // 00049 // Setting this will not truncate text immediately. You 00050 // must follow this up with a call to set_wtext() to 00051 // truncate the existing text. 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE void TextAssembler:: 00054 set_max_rows(int max_rows) { 00055 _max_rows = max_rows; 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: TextAssembler::get_max_rows 00060 // Access: Published 00061 // Description: If max_rows is greater than zero, no more than 00062 // max_rows will be accepted. Text beyond that will be 00063 // truncated. 00064 //////////////////////////////////////////////////////////////////// 00065 INLINE int TextAssembler:: 00066 get_max_rows() const { 00067 return _max_rows; 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: TextAssembler::set_dynamic_merge 00072 // Access: Published 00073 // Description: Sets the dynamic_merge flag. See 00074 // TextNode::set_flatten_flags(). 00075 //////////////////////////////////////////////////////////////////// 00076 INLINE void TextAssembler:: 00077 set_dynamic_merge(bool dynamic_merge) { 00078 _dynamic_merge = dynamic_merge; 00079 } 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: TextAssembler::get_dynamic_merge 00083 // Access: Published 00084 // Description: Returns the dynamic_merge flag. See 00085 // TextNode::set_flatten_flags(). 00086 //////////////////////////////////////////////////////////////////// 00087 INLINE bool TextAssembler:: 00088 get_dynamic_merge() const { 00089 return _dynamic_merge; 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function: TextAssembler::set_multiline_mode 00094 // Access: Published 00095 // Description: Sets the multiline mode flag. Set the multiline 00096 // mode to allow text to wrap. It defaults to true. 00097 //////////////////////////////////////////////////////////////////// 00098 INLINE void TextAssembler:: 00099 set_multiline_mode(bool flag) { 00100 _multiline_mode = flag; 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: TextAssembler::get_multiline_mode 00105 // Access: Published 00106 // Description: Returns the multline_mode flag. See 00107 // TextNode::set_multiline_mode(). 00108 //////////////////////////////////////////////////////////////////// 00109 INLINE bool TextAssembler:: 00110 get_multiline_mode() const { 00111 return _multiline_mode; 00112 } 00113 00114 //////////////////////////////////////////////////////////////////// 00115 // Function: TextAssembler::set_properties 00116 // Access: Published 00117 // Description: Specifies the default TextProperties that are applied 00118 // to the text in the absence of any nested property 00119 // change sequences. 00120 //////////////////////////////////////////////////////////////////// 00121 INLINE void TextAssembler:: 00122 set_properties(const TextProperties &properties) { 00123 _initial_cprops = new ComputedProperties(properties); 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: TextAssembler::get_properties 00128 // Access: Published 00129 // Description: Returns the default TextProperties that are applied 00130 // to the text in the absence of any nested property 00131 // change sequences. 00132 //////////////////////////////////////////////////////////////////// 00133 INLINE const TextProperties &TextAssembler:: 00134 get_properties() const { 00135 return _initial_cprops->_properties; 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: TextAssembler::get_ul 00140 // Access: Published 00141 // Description: Returns the upper-left corner of the assembled text, 00142 // in 2-d text coordinates. 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE const LVector2 &TextAssembler:: 00145 get_ul() const { 00146 return _ul; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: TextAssembler::get_lr 00151 // Access: Published 00152 // Description: Returns the lower-right corner of the assembled text, 00153 // in 2-d text coordinates. 00154 //////////////////////////////////////////////////////////////////// 00155 INLINE const LVector2 &TextAssembler:: 00156 get_lr() const { 00157 return _lr; 00158 } 00159 00160 //////////////////////////////////////////////////////////////////// 00161 // Function: TextAssembler::calc_r 00162 // Access: Published 00163 // Description: Computes the row index of the nth character or 00164 // graphic object in the text and returns it. 00165 // 00166 // If the nth character is not a normal printable 00167 // character with a position in the wordwrapped string, 00168 // returns -1 (for instance, a soft-hyphen character, or 00169 // a newline character, may not have a corresponding 00170 // position). 00171 //////////////////////////////////////////////////////////////////// 00172 int TextAssembler:: 00173 calc_r(int n) const { 00174 int r, c; 00175 if (calc_r_c(r, c, n)) { 00176 return r; 00177 } 00178 return -1; 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: TextAssembler::calc_c 00183 // Access: Published 00184 // Description: Computes the column index of the nth character or 00185 // graphic object in the text and returns it. 00186 // 00187 // If the nth character is not a normal printable 00188 // character with a position in the wordwrapped string, 00189 // returns -1 (for instance, a soft-hyphen character, or 00190 // a newline character, may not have a corresponding 00191 // position). 00192 //////////////////////////////////////////////////////////////////// 00193 int TextAssembler:: 00194 calc_c(int n) const { 00195 int r, c; 00196 if (calc_r_c(r, c, n)) { 00197 return c; 00198 } 00199 return -1; 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: TextAssembler::get_num_characters 00204 // Access: Published 00205 // Description: Returns the number of characters of text, before 00206 // wordwrapping. 00207 //////////////////////////////////////////////////////////////////// 00208 INLINE int TextAssembler:: 00209 get_num_characters() const { 00210 return _text_string.size(); 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: TextAssembler::get_character 00215 // Access: Published 00216 // Description: Returns the character at the indicated position in 00217 // the pre-wordwrapped string. If the object at this 00218 // position is a graphic object instead of a character, 00219 // returns 0. 00220 //////////////////////////////////////////////////////////////////// 00221 INLINE wchar_t TextAssembler:: 00222 get_character(int n) const { 00223 nassertr(n >= 0 && n < (int)_text_string.size(), 0); 00224 return _text_string[n]._character; 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: TextAssembler::get_graphic 00229 // Access: Published 00230 // Description: Returns the graphic object at the indicated position 00231 // in the pre-wordwrapped string. If the object at this 00232 // position is a character instead of a graphic object, 00233 // returns NULL. 00234 //////////////////////////////////////////////////////////////////// 00235 INLINE const TextGraphic *TextAssembler:: 00236 get_graphic(int n) const { 00237 nassertr(n >= 0 && n < (int)_text_string.size(), 0); 00238 return _text_string[n]._graphic; 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: TextAssembler::get_properties 00243 // Access: Published 00244 // Description: Returns the TextProperties in effect for the object 00245 // at the indicated position in the pre-wordwrapped 00246 // string. 00247 //////////////////////////////////////////////////////////////////// 00248 INLINE const TextProperties &TextAssembler:: 00249 get_properties(int n) const { 00250 nassertr(n >= 0 && n < (int)_text_string.size(), *(new TextProperties())); 00251 return _text_string[n]._cprops->_properties; 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: TextAssembler::get_width 00256 // Access: Published 00257 // Description: Returns the width of the character or object at the 00258 // indicated position in the pre-wordwrapped string. 00259 //////////////////////////////////////////////////////////////////// 00260 INLINE PN_stdfloat TextAssembler:: 00261 get_width(int n) const { 00262 nassertr(n >= 0 && n < (int)_text_string.size(), 0.0f); 00263 00264 return calc_width(_text_string[n]); 00265 } 00266 00267 //////////////////////////////////////////////////////////////////// 00268 // Function: TextAssembler::get_num_rows 00269 // Access: Published 00270 // Description: Returns the number of rows of text after it has all 00271 // been wordwrapped and assembled. 00272 //////////////////////////////////////////////////////////////////// 00273 INLINE int TextAssembler:: 00274 get_num_rows() const { 00275 return _text_block.size(); 00276 } 00277 00278 //////////////////////////////////////////////////////////////////// 00279 // Function: TextAssembler::get_num_cols 00280 // Access: Published 00281 // Description: Returns the number of characters and/or graphic 00282 // objects in the nth row. 00283 //////////////////////////////////////////////////////////////////// 00284 INLINE int TextAssembler:: 00285 get_num_cols(int r) const { 00286 nassertr(r >= 0 && r <= (int)_text_block.size(), 0); 00287 if (r == (int)_text_block.size()) { 00288 return 0; 00289 } 00290 return _text_block[r]._string.size(); 00291 } 00292 00293 //////////////////////////////////////////////////////////////////// 00294 // Function: TextAssembler::get_character 00295 // Access: Published 00296 // Description: Returns the character at the indicated position in 00297 // the indicated row. If the object at this position is 00298 // a graphic object instead of a character, returns 0. 00299 //////////////////////////////////////////////////////////////////// 00300 INLINE wchar_t TextAssembler:: 00301 get_character(int r, int c) const { 00302 nassertr(r >= 0 && r < (int)_text_block.size(), 0); 00303 nassertr(c >= 0 && c < (int)_text_block[r]._string.size(), 0); 00304 return _text_block[r]._string[c]._character; 00305 } 00306 00307 //////////////////////////////////////////////////////////////////// 00308 // Function: TextAssembler::get_graphic 00309 // Access: Published 00310 // Description: Returns the graphic object at the indicated position 00311 // in the indicated row. If the object at this position 00312 // is a character instead of a graphic object, returns 00313 // NULL. 00314 //////////////////////////////////////////////////////////////////// 00315 INLINE const TextGraphic *TextAssembler:: 00316 get_graphic(int r, int c) const { 00317 nassertr(r >= 0 && r < (int)_text_block.size(), 0); 00318 nassertr(c >= 0 && c < (int)_text_block[r]._string.size(), 0); 00319 return _text_block[r]._string[c]._graphic; 00320 } 00321 00322 //////////////////////////////////////////////////////////////////// 00323 // Function: TextAssembler::get_properties 00324 // Access: Published 00325 // Description: Returns the TextProperties in effect for the object 00326 // at the indicated position in the indicated row. 00327 //////////////////////////////////////////////////////////////////// 00328 INLINE const TextProperties &TextAssembler:: 00329 get_properties(int r, int c) const { 00330 nassertr(r >= 0 && r < (int)_text_block.size(), *(new TextProperties())); 00331 nassertr(c >= 0 && c < (int)_text_block[r]._string.size(), *(new TextProperties())); 00332 return _text_block[r]._string[c]._cprops->_properties; 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: TextAssembler::get_width 00337 // Access: Published 00338 // Description: Returns the width of the character or object at the 00339 // indicated position in the indicated row. 00340 //////////////////////////////////////////////////////////////////// 00341 INLINE PN_stdfloat TextAssembler:: 00342 get_width(int r, int c) const { 00343 nassertr(r >= 0 && r < (int)_text_block.size(), 0.0f); 00344 nassertr(c >= 0 && c < (int)_text_block[r]._string.size(), 0.0f); 00345 00346 return calc_width(_text_block[r]._string[c]); 00347 } 00348 00349 //////////////////////////////////////////////////////////////////// 00350 // Function: TextAssembler::get_ypos 00351 // Access: Published 00352 // Description: Returns the y position of the origin of all of the 00353 // characters or graphic objects in the indicated row. 00354 // 00355 // It is legal for r to exceed the index number of the 00356 // last row by 1. The value of c is presently ignored. 00357 //////////////////////////////////////////////////////////////////// 00358 INLINE PN_stdfloat TextAssembler:: 00359 get_ypos(int r, int) const { 00360 nassertr(r >= 0 && r <= (int)_text_block.size(), 0.0f); 00361 if (r == (int)_text_block.size()) { 00362 return _next_row_ypos; 00363 } else { 00364 return _text_block[r]._ypos; 00365 } 00366 } 00367 00368 //////////////////////////////////////////////////////////////////// 00369 // Function: TextAssembler::calc_width 00370 // Access: Private, Static 00371 // Description: Returns the width of a single character, according to 00372 // its associated font. 00373 //////////////////////////////////////////////////////////////////// 00374 INLINE PN_stdfloat TextAssembler:: 00375 calc_width(const TextCharacter &tch) { 00376 if (tch._graphic != (TextGraphic *)NULL) { 00377 return calc_width(tch._graphic, tch._cprops->_properties); 00378 } else { 00379 return calc_width(tch._character, tch._cprops->_properties); 00380 } 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: TextAssembler::TextCharacter::Constructor 00385 // Access: Public 00386 // Description: 00387 //////////////////////////////////////////////////////////////////// 00388 INLINE TextAssembler::TextCharacter:: 00389 TextCharacter(wchar_t character, 00390 TextAssembler::ComputedProperties *cprops) : 00391 _character(character), 00392 _graphic(NULL), 00393 _cprops(cprops) 00394 { 00395 } 00396 00397 //////////////////////////////////////////////////////////////////// 00398 // Function: TextAssembler::TextCharacter::Constructor 00399 // Access: Public 00400 // Description: 00401 //////////////////////////////////////////////////////////////////// 00402 INLINE TextAssembler::TextCharacter:: 00403 TextCharacter(const TextGraphic *graphic, const wstring &graphic_wname, 00404 TextAssembler::ComputedProperties *cprops) : 00405 _character(0), 00406 _graphic(graphic), 00407 _graphic_wname(graphic_wname), 00408 _cprops(cprops) 00409 { 00410 } 00411 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: TextAssembler::TextCharacter::Copy Constructor 00414 // Access: Public 00415 // Description: 00416 //////////////////////////////////////////////////////////////////// 00417 INLINE TextAssembler::TextCharacter:: 00418 TextCharacter(const TextAssembler::TextCharacter ©) : 00419 _character(copy._character), 00420 _graphic(copy._graphic), 00421 _graphic_wname(copy._graphic_wname), 00422 _cprops(copy._cprops) 00423 { 00424 } 00425 00426 //////////////////////////////////////////////////////////////////// 00427 // Function: TextAssembler::TextCharacter::Copy Assignment 00428 // Access: Public 00429 // Description: 00430 //////////////////////////////////////////////////////////////////// 00431 INLINE void TextAssembler::TextCharacter:: 00432 operator = (const TextAssembler::TextCharacter ©) { 00433 _character = copy._character; 00434 _graphic = copy._graphic; 00435 _graphic_wname = copy._graphic_wname; 00436 _cprops = copy._cprops; 00437 } 00438 00439 //////////////////////////////////////////////////////////////////// 00440 // Function: TextAssembler::TextRow::Constructor 00441 // Access: Public 00442 // Description: 00443 //////////////////////////////////////////////////////////////////// 00444 INLINE TextAssembler::TextRow:: 00445 TextRow(int row_start) : 00446 _row_start(row_start), 00447 _got_soft_hyphens(false), 00448 _xpos(0.0f), 00449 _ypos(0.0f) 00450 { 00451 } 00452 00453 //////////////////////////////////////////////////////////////////// 00454 // Function: TextAssembler::TextRow::Copy Constructor 00455 // Access: Public 00456 // Description: 00457 //////////////////////////////////////////////////////////////////// 00458 INLINE TextAssembler::TextRow:: 00459 TextRow(const TextAssembler::TextRow ©) : 00460 _string(copy._string), 00461 _row_start(copy._row_start), 00462 _got_soft_hyphens(copy._got_soft_hyphens), 00463 _xpos(copy._xpos), 00464 _ypos(copy._ypos), 00465 _eol_cprops(copy._eol_cprops) 00466 { 00467 } 00468 00469 //////////////////////////////////////////////////////////////////// 00470 // Function: TextAssembler::TextRow::Copy Assignment 00471 // Access: Public 00472 // Description: 00473 //////////////////////////////////////////////////////////////////// 00474 INLINE void TextAssembler::TextRow:: 00475 operator = (const TextAssembler::TextRow ©) { 00476 _string = copy._string; 00477 _row_start = copy._row_start; 00478 _got_soft_hyphens = copy._got_soft_hyphens; 00479 _xpos = copy._xpos; 00480 _ypos = copy._ypos; 00481 _eol_cprops = copy._eol_cprops; 00482 } 00483 00484 //////////////////////////////////////////////////////////////////// 00485 // Function: TextAssembler::ComputedProperties::Constructor 00486 // Access: Public 00487 // Description: 00488 //////////////////////////////////////////////////////////////////// 00489 INLINE TextAssembler::ComputedProperties:: 00490 ComputedProperties(const TextProperties &orig_properties) : 00491 _based_on(NULL), 00492 _depth(0), 00493 _properties(orig_properties) 00494 { 00495 } 00496 00497 //////////////////////////////////////////////////////////////////// 00498 // Function: TextAssembler::ComputedProperties::Constructor 00499 // Access: Public 00500 // Description: 00501 //////////////////////////////////////////////////////////////////// 00502 INLINE TextAssembler::ComputedProperties:: 00503 ComputedProperties(ComputedProperties *based_on, const wstring &wname, 00504 TextEncoder *encoder) : 00505 _based_on(based_on), 00506 _depth(_based_on->_depth + 1), 00507 _wname(wname), 00508 _properties(based_on->_properties) 00509 { 00510 TextPropertiesManager *manager = 00511 TextPropertiesManager::get_global_ptr(); 00512 00513 // Now we have to encode the wstring into a string, for lookup 00514 // in the TextPropertiesManager. 00515 string name = encoder->encode_wtext(wname); 00516 00517 const TextProperties *named_props = manager->get_properties_ptr(name); 00518 if (named_props != (TextProperties *)NULL) { 00519 _properties.add_properties(*named_props); 00520 } else { 00521 text_cat.warning() 00522 << "Unknown TextProperties: " << name << "\n"; 00523 } 00524 } 00525 00526 00527 //////////////////////////////////////////////////////////////////// 00528 // Function: TextAssembler::GlyphPlacement::add_piece 00529 // Access: Public 00530 // Description: Adds a piece of the glyph, consisting of a single 00531 // Geom and an associated RenderState. Typically, a 00532 // glyph will have exactly one piece; there will only be 00533 // multiple pieces in the case of cheesy accent marks or 00534 // ligatures. 00535 //////////////////////////////////////////////////////////////////// 00536 INLINE void TextAssembler::GlyphPlacement:: 00537 add_piece(Geom *geom, const RenderState *state) { 00538 Piece piece; 00539 piece._geom = geom; 00540 piece._state = state; 00541 _pieces.push_back(piece); 00542 } 00543 00544 //////////////////////////////////////////////////////////////////// 00545 // Function: TextAssembler::GeomCollectorKey::Constructor 00546 // Access: Public 00547 // Description: 00548 //////////////////////////////////////////////////////////////////// 00549 INLINE TextAssembler::GeomCollectorKey:: 00550 GeomCollectorKey(const RenderState *state, const GeomVertexFormat *format) : 00551 _state(state), 00552 _format(format) 00553 { 00554 } 00555 00556 //////////////////////////////////////////////////////////////////// 00557 // Function: TextAssembler::GeomCollectorKey::operator < 00558 // Access: Public 00559 // Description: 00560 //////////////////////////////////////////////////////////////////// 00561 INLINE bool TextAssembler::GeomCollectorKey:: 00562 operator < (const TextAssembler::GeomCollectorKey &other) const { 00563 if (_state != other._state) { 00564 return _state < other._state; 00565 } 00566 return _format < other._format; 00567 } 00568 00569 //////////////////////////////////////////////////////////////////// 00570 // Function: TextAssembler::GeomCollector::count_geom 00571 // Access: Public 00572 // Description: If the indicated Geom is a GeomTextGlyph, increments 00573 // its reference count and adds it into this geom. This 00574 // is necessary to keep references to outstanding 00575 // glyphs, so we know when it's safe to recycle 00576 // no-longer-used glyphs. 00577 // 00578 // If the indicated Geom is an ordinary Geom, does 00579 // nothing. 00580 //////////////////////////////////////////////////////////////////// 00581 INLINE void TextAssembler::GeomCollector:: 00582 count_geom(const Geom *geom) { 00583 #ifdef HAVE_FREETYPE 00584 _geom->count_geom(geom); 00585 #endif 00586 }