mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
faster text generation
This commit is contained in:
parent
c37acce234
commit
7421fe3e05
@ -53,7 +53,7 @@ get_geom() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::get_row
|
||||
// Access: Publiic
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the first byte in the pixel
|
||||
// buffer associated with the leftmost pixel in the
|
||||
// indicated row, where 0 is the topmost row and _y_size
|
||||
@ -79,7 +79,7 @@ get_row(int y) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::erase
|
||||
// Access: Publiic
|
||||
// Access: Public
|
||||
// Description: Erases the glyph from the texture map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DynamicTextGlyph::
|
||||
@ -99,7 +99,7 @@ erase() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::make_geom
|
||||
// Access: Publiic
|
||||
// Access: Public
|
||||
// Description: Creates the actual geometry for the glyph. The
|
||||
// parameters bitmap_top and bitmap_left are from
|
||||
// FreeType, and indicate the position of the top left
|
||||
|
@ -34,5 +34,13 @@ TextGlyph::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Geom) TextGlyph::
|
||||
get_geom() const {
|
||||
return _geom;
|
||||
if (_geom == (Geom *)NULL) {
|
||||
return _geom;
|
||||
}
|
||||
|
||||
// We always return a copy of the geom. That will allow the caller
|
||||
// to modify its vertices without fear of stomping on other copies;
|
||||
// it is also critical for the DynamicTextGlyph, which depends on
|
||||
// this behavior to properly count references to this glyph.
|
||||
return _geom->make_copy();
|
||||
}
|
||||
|
@ -194,7 +194,12 @@ get_expand_amp() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float TextNode::
|
||||
get_line_height() const {
|
||||
return (_font == (TextFont *)NULL) ? 0.0 : _font->get_line_height();
|
||||
if (_font != (TextFont *)NULL) {
|
||||
return _font->get_line_height();
|
||||
} else if (get_default_font() != (TextFont *)NULL) {
|
||||
return _default_font->get_line_height();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1305,6 +1310,21 @@ update() {
|
||||
check_rebuild();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::force_update
|
||||
// Access: Published
|
||||
// Description: Forces the TextNode to recompute itself now, even if
|
||||
// it believes nothing has changed. Normally, this
|
||||
// should not need to be called, but it may be useful if
|
||||
// some properties change outside of the TextNode's
|
||||
// knowledge (for instance, within the font).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextNode::
|
||||
force_update() {
|
||||
invalidate_with_measure();
|
||||
check_rebuild();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::set_wtext
|
||||
// Access: Public
|
||||
|
@ -294,7 +294,8 @@ generate() {
|
||||
assemble_text(wtext.begin(), wtext.end(), font,
|
||||
ul, lr, num_rows);
|
||||
|
||||
// Parent the text in.
|
||||
// Parent the text in. We create an intermediate node so we can
|
||||
// choose to reinstance the text_root as the shadow, below.
|
||||
PT(PandaNode) text = new PandaNode("text");
|
||||
root->add_child(text, _draw_order + 2);
|
||||
text->add_child(text_root);
|
||||
@ -883,7 +884,7 @@ do_measure() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float TextNode::
|
||||
assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
TextFont *font, PandaNode *dest) {
|
||||
TextFont *font, GeomNode *dest, const LMatrix4f &mat) {
|
||||
float xpos = 0.0f;
|
||||
while (si != send && (*si) != '\n') {
|
||||
wchar_t character = *si;
|
||||
@ -914,14 +915,26 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
const RenderState *state = glyph->get_state();
|
||||
|
||||
if (char_geom != (Geom *)NULL) {
|
||||
LMatrix4f mat = LMatrix4f::scale_mat(glyph_scale);
|
||||
mat.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
||||
LMatrix4f mat2 = LMatrix4f::scale_mat(glyph_scale);
|
||||
mat2.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
||||
LMatrix4f xform = mat2 * mat;
|
||||
|
||||
string ch(1, (char)character);
|
||||
PT(GeomNode) geode = new GeomNode(ch);
|
||||
geode->add_geom(char_geom, state);
|
||||
dest->add_child(geode);
|
||||
geode->set_transform(TransformState::make_mat(mat));
|
||||
// Transform the vertices of the geom appropriately. We
|
||||
// assume the geom is non-indexed.
|
||||
PTA_Vertexf coords;
|
||||
PTA_ushort index;
|
||||
char_geom->get_coords(coords, index);
|
||||
PTA_Vertexf new_coords;
|
||||
new_coords.reserve(coords.size());
|
||||
PTA_Vertexf::const_iterator vi;
|
||||
for (vi = coords.begin(); vi != coords.end(); ++vi) {
|
||||
new_coords.push_back((*vi) * xform);
|
||||
}
|
||||
nassertr(new_coords.size() == coords.size(), false);
|
||||
char_geom->set_coords(new_coords);
|
||||
|
||||
// Now add the geom to the destination node.
|
||||
dest->add_geom(char_geom, state);
|
||||
}
|
||||
|
||||
xpos += glyph->get_advance() * glyph_scale;
|
||||
@ -943,27 +956,21 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
PT(PandaNode) TextNode::
|
||||
assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
||||
float line_height = get_line_height();
|
||||
float line_height = font->get_line_height();
|
||||
|
||||
ul.set(0.0f, 0.8f * line_height);
|
||||
lr.set(0.0f, 0.0f);
|
||||
|
||||
// Make a group node to hold our formatted text geometry.
|
||||
PT(PandaNode) root_node = new PandaNode("text");
|
||||
// Make a geom node to hold our formatted text geometry.
|
||||
PT(GeomNode) root_node = new GeomNode("text");
|
||||
|
||||
float posy = 0.0f;
|
||||
int row_index = 0;
|
||||
while (si != send) {
|
||||
char numstr[20];
|
||||
sprintf(numstr, "row%d", row_index);
|
||||
nassertr(strlen(numstr) < 20, root_node);
|
||||
|
||||
PT(PandaNode) row = new PandaNode(numstr);
|
||||
float row_width = assemble_row(si, send, font, row);
|
||||
if (si != send) {
|
||||
// Skip past the newline.
|
||||
++si;
|
||||
}
|
||||
// First, just measure the row, so we know how wide it is.
|
||||
// (Centered or right-justified text will require us to know this
|
||||
// up front.)
|
||||
wstring::iterator tsi = si;
|
||||
float row_width = measure_row(tsi, send, font);
|
||||
|
||||
LMatrix4f mat = LMatrix4f::ident_mat();
|
||||
if (_align == A_left) {
|
||||
@ -991,8 +998,13 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||
mat = shear * mat;
|
||||
}
|
||||
|
||||
row->set_transform(TransformState::make_mat(mat));
|
||||
root_node->add_child(row);
|
||||
// Now that we've computed the row's transform matrix, generate
|
||||
// the actual geoms for the row.
|
||||
assemble_row(si, send, font, root_node, mat);
|
||||
if (si != send) {
|
||||
// Skip past the newline.
|
||||
++si;
|
||||
}
|
||||
|
||||
posy -= line_height;
|
||||
num_rows++;
|
||||
@ -1000,7 +1012,7 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||
|
||||
lr[1] = posy + 0.8f * line_height;
|
||||
|
||||
return root_node;
|
||||
return root_node.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1046,7 +1058,7 @@ measure_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
void TextNode::
|
||||
measure_text(wstring::iterator si, const wstring::iterator &send,
|
||||
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
||||
float line_height = get_line_height();
|
||||
float line_height = font->get_line_height();
|
||||
|
||||
ul.set(0.0f, 0.8f * line_height);
|
||||
lr.set(0.0f, 0.0f);
|
||||
|
@ -206,6 +206,7 @@ PUBLISHED:
|
||||
|
||||
PT(PandaNode) generate();
|
||||
INLINE void update();
|
||||
INLINE void force_update();
|
||||
|
||||
public:
|
||||
// Direct support for wide-character strings.
|
||||
@ -249,8 +250,8 @@ private:
|
||||
void do_measure();
|
||||
|
||||
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
|
||||
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
TextFont *font, PandaNode *dest);
|
||||
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||
TextFont *font, GeomNode *dest, const LMatrix4f &mat);
|
||||
PT(PandaNode) assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||
TextFont *font,
|
||||
LVector2f &ul, LVector2f &lr, int &num_rows);
|
||||
|
Loading…
x
Reference in New Issue
Block a user