Panda3D

textAssembler.I

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 &copy) :
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 &copy) {
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 &copy) :
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 &copy) {
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 }
 All Classes Functions Variables Enumerations