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
|
// Function: DynamicTextGlyph::get_row
|
||||||
// Access: Publiic
|
// Access: Public
|
||||||
// Description: Returns a pointer to the first byte in the pixel
|
// Description: Returns a pointer to the first byte in the pixel
|
||||||
// buffer associated with the leftmost pixel in the
|
// buffer associated with the leftmost pixel in the
|
||||||
// indicated row, where 0 is the topmost row and _y_size
|
// indicated row, where 0 is the topmost row and _y_size
|
||||||
@ -79,7 +79,7 @@ get_row(int y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextGlyph::erase
|
// Function: DynamicTextGlyph::erase
|
||||||
// Access: Publiic
|
// Access: Public
|
||||||
// Description: Erases the glyph from the texture map.
|
// Description: Erases the glyph from the texture map.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void DynamicTextGlyph::
|
void DynamicTextGlyph::
|
||||||
@ -99,7 +99,7 @@ erase() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextGlyph::make_geom
|
// Function: DynamicTextGlyph::make_geom
|
||||||
// Access: Publiic
|
// Access: Public
|
||||||
// Description: Creates the actual geometry for the glyph. The
|
// Description: Creates the actual geometry for the glyph. The
|
||||||
// parameters bitmap_top and bitmap_left are from
|
// parameters bitmap_top and bitmap_left are from
|
||||||
// FreeType, and indicate the position of the top left
|
// FreeType, and indicate the position of the top left
|
||||||
|
@ -34,5 +34,13 @@ TextGlyph::
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PT(Geom) TextGlyph::
|
PT(Geom) TextGlyph::
|
||||||
get_geom() const {
|
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::
|
INLINE float TextNode::
|
||||||
get_line_height() const {
|
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();
|
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
|
// Function: TextNode::set_wtext
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -294,7 +294,8 @@ generate() {
|
|||||||
assemble_text(wtext.begin(), wtext.end(), font,
|
assemble_text(wtext.begin(), wtext.end(), font,
|
||||||
ul, lr, num_rows);
|
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");
|
PT(PandaNode) text = new PandaNode("text");
|
||||||
root->add_child(text, _draw_order + 2);
|
root->add_child(text, _draw_order + 2);
|
||||||
text->add_child(text_root);
|
text->add_child(text_root);
|
||||||
@ -883,7 +884,7 @@ do_measure() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float TextNode::
|
float TextNode::
|
||||||
assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
TextFont *font, PandaNode *dest) {
|
TextFont *font, GeomNode *dest, const LMatrix4f &mat) {
|
||||||
float xpos = 0.0f;
|
float xpos = 0.0f;
|
||||||
while (si != send && (*si) != '\n') {
|
while (si != send && (*si) != '\n') {
|
||||||
wchar_t character = *si;
|
wchar_t character = *si;
|
||||||
@ -914,14 +915,26 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
|||||||
const RenderState *state = glyph->get_state();
|
const RenderState *state = glyph->get_state();
|
||||||
|
|
||||||
if (char_geom != (Geom *)NULL) {
|
if (char_geom != (Geom *)NULL) {
|
||||||
LMatrix4f mat = LMatrix4f::scale_mat(glyph_scale);
|
LMatrix4f mat2 = LMatrix4f::scale_mat(glyph_scale);
|
||||||
mat.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
mat2.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
||||||
|
LMatrix4f xform = mat2 * mat;
|
||||||
|
|
||||||
string ch(1, (char)character);
|
// Transform the vertices of the geom appropriately. We
|
||||||
PT(GeomNode) geode = new GeomNode(ch);
|
// assume the geom is non-indexed.
|
||||||
geode->add_geom(char_geom, state);
|
PTA_Vertexf coords;
|
||||||
dest->add_child(geode);
|
PTA_ushort index;
|
||||||
geode->set_transform(TransformState::make_mat(mat));
|
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;
|
xpos += glyph->get_advance() * glyph_scale;
|
||||||
@ -943,27 +956,21 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
|||||||
PT(PandaNode) TextNode::
|
PT(PandaNode) TextNode::
|
||||||
assemble_text(wstring::iterator si, const wstring::iterator &send,
|
assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
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);
|
ul.set(0.0f, 0.8f * line_height);
|
||||||
lr.set(0.0f, 0.0f);
|
lr.set(0.0f, 0.0f);
|
||||||
|
|
||||||
// Make a group node to hold our formatted text geometry.
|
// Make a geom node to hold our formatted text geometry.
|
||||||
PT(PandaNode) root_node = new PandaNode("text");
|
PT(GeomNode) root_node = new GeomNode("text");
|
||||||
|
|
||||||
float posy = 0.0f;
|
float posy = 0.0f;
|
||||||
int row_index = 0;
|
|
||||||
while (si != send) {
|
while (si != send) {
|
||||||
char numstr[20];
|
// First, just measure the row, so we know how wide it is.
|
||||||
sprintf(numstr, "row%d", row_index);
|
// (Centered or right-justified text will require us to know this
|
||||||
nassertr(strlen(numstr) < 20, root_node);
|
// up front.)
|
||||||
|
wstring::iterator tsi = si;
|
||||||
PT(PandaNode) row = new PandaNode(numstr);
|
float row_width = measure_row(tsi, send, font);
|
||||||
float row_width = assemble_row(si, send, font, row);
|
|
||||||
if (si != send) {
|
|
||||||
// Skip past the newline.
|
|
||||||
++si;
|
|
||||||
}
|
|
||||||
|
|
||||||
LMatrix4f mat = LMatrix4f::ident_mat();
|
LMatrix4f mat = LMatrix4f::ident_mat();
|
||||||
if (_align == A_left) {
|
if (_align == A_left) {
|
||||||
@ -991,8 +998,13 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
|||||||
mat = shear * mat;
|
mat = shear * mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
row->set_transform(TransformState::make_mat(mat));
|
// Now that we've computed the row's transform matrix, generate
|
||||||
root_node->add_child(row);
|
// 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;
|
posy -= line_height;
|
||||||
num_rows++;
|
num_rows++;
|
||||||
@ -1000,7 +1012,7 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
|||||||
|
|
||||||
lr[1] = posy + 0.8f * line_height;
|
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::
|
void TextNode::
|
||||||
measure_text(wstring::iterator si, const wstring::iterator &send,
|
measure_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
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);
|
ul.set(0.0f, 0.8f * line_height);
|
||||||
lr.set(0.0f, 0.0f);
|
lr.set(0.0f, 0.0f);
|
||||||
|
@ -206,6 +206,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
PT(PandaNode) generate();
|
PT(PandaNode) generate();
|
||||||
INLINE void update();
|
INLINE void update();
|
||||||
|
INLINE void force_update();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Direct support for wide-character strings.
|
// Direct support for wide-character strings.
|
||||||
@ -249,8 +250,8 @@ private:
|
|||||||
void do_measure();
|
void do_measure();
|
||||||
|
|
||||||
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
|
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
|
||||||
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
TextFont *font, PandaNode *dest);
|
TextFont *font, GeomNode *dest, const LMatrix4f &mat);
|
||||||
PT(PandaNode) assemble_text(wstring::iterator si, const wstring::iterator &send,
|
PT(PandaNode) assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
TextFont *font,
|
TextFont *font,
|
||||||
LVector2f &ul, LVector2f &lr, int &num_rows);
|
LVector2f &ul, LVector2f &lr, int &num_rows);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user