pgraph text

This commit is contained in:
David Rose 2002-03-13 23:14:28 +00:00
parent 7346c65f35
commit e45ab93f89
15 changed files with 252 additions and 10 deletions

View File

@ -926,6 +926,8 @@ remove_all_children() {
child_node->fix_path_lengths(cdata_child);
child_node->parents_changed();
}
cdata->_down.clear();
for (di = cdata->_stashed.begin(); di != cdata->_stashed.end(); ++di) {
PT(PandaNode) child_node = (*di).get_child();
CDWriter cdata_child(child_node->_cycler);
@ -955,6 +957,7 @@ remove_all_children() {
child_node->fix_path_lengths(cdata_child);
child_node->parents_changed();
}
cdata->_stashed.clear();
// Mark the bounding volumes stale.
force_bound_stale();
@ -1517,9 +1520,16 @@ fix_path_lengths(const CData *cdata) {
////////////////////////////////////////////////////////////////////
void PandaNode::
r_list_descendants(ostream &out, int indent_level) const {
indent(out, indent_level) << *this << "\n";
CDReader cdata(_cycler);
indent(out, indent_level) << *this;
if (!cdata->_transform->is_identity()) {
out << " " << *cdata->_transform;
}
if (!cdata->_state->is_empty()) {
out << " " << *cdata->_state;
}
out << "\n";
Down::const_iterator di;
for (di = cdata->_down.begin(); di != cdata->_down.end(); ++di) {
(*di).get_child()->r_list_descendants(out, indent_level + 2);

View File

@ -938,7 +938,8 @@ get_distance(const qpNodePath &other) const {
////////////////////////////////////////////////////////////////////
INLINE void qpNodePath::
adjust_all_priorities(int adjustment) {
nassertv(false);
nassertv(!is_empty());
r_adjust_all_priorities(node(), adjustment);
}
////////////////////////////////////////////////////////////////////

View File

@ -2472,3 +2472,21 @@ r_find_matches(qpNodePathCollection &result,
r_find_matches(result, next_level, max_matches, num_levels_remaining);
}
}
////////////////////////////////////////////////////////////////////
// Function: qpNodePath::r_adjust_all_priorities
// Access: Private
// Description: The recursive implementation of
// adjust_all_priorities(). This walks through the
// subgraph defined by the indicated node and below.
////////////////////////////////////////////////////////////////////
void qpNodePath::
r_adjust_all_priorities(PandaNode *node, int adjustment) {
node->set_state(node->get_state()->adjust_all_priorities(adjustment));
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
r_adjust_all_priorities(cr.get_child(i), adjustment);
}
}

View File

@ -488,6 +488,8 @@ private:
const qpFindApproxLevel &level,
int max_matches, int num_levels_remaining) const;
void r_adjust_all_priorities(PandaNode *node, int adjustment);
PT(qpNodePathComponent) _head;
ErrorType _error_type;
static int _max_search_depth;

View File

@ -451,7 +451,7 @@ add_attrib(const RenderAttrib *attrib, int override) const {
// Access: Published
// Description: Returns a new RenderState object that represents the
// same as the source state, with the indicated
// RenderAttrib removed
// RenderAttrib removed.
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
remove_attrib(TypeHandle type) const {
@ -472,6 +472,30 @@ remove_attrib(TypeHandle type) const {
return return_new(new_state);
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::remove_attrib
// Access: Published
// Description: Returns a new RenderState object that represents the
// same as the source state, with all attributes'
// override values incremented (or decremented, if
// negative) by the indicated amount. If the override
// would drop below zero, it is set to zero.
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
adjust_all_priorities(int adjustment) const {
RenderState *new_state = new RenderState;
new_state->_attributes.reserve(_attributes.size());
Attributes::const_iterator ai;
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
Attribute attrib = *ai;
attrib._override = max(attrib._override + adjustment, 0);
new_state->_attributes.push_back(attrib);
}
return return_new(new_state);
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::get_attrib
// Access: Published, Virtual

View File

@ -81,6 +81,8 @@ PUBLISHED:
CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
CPT(RenderState) remove_attrib(TypeHandle type) const;
CPT(RenderState) adjust_all_priorities(int adjustment) const;
const RenderAttrib *get_attrib(TypeHandle type) const;
void output(ostream &out) const;

View File

@ -186,7 +186,7 @@ operator < (const TransformState &other) const {
if (c != 0) {
return c < 0;
}
c = _scale.compare_to(other._hpr);
c = _scale.compare_to(other._scale);
return c < 0;
}

View File

@ -6,7 +6,8 @@
#define TARGET text
#define LOCAL_LIBS \
cull putil gobj sgattrib graph sgraph linmath sgraphutil pnmimage gsgbase \
cull putil gobj sgattrib pgraph graph sgraph linmath \
sgraphutil pnmimage gsgbase \
mathutil
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
@ -21,7 +22,8 @@
stringDecoder.I stringDecoder.h \
textFont.I textFont.h \
textGlyph.I textGlyph.h \
textNode.I textNode.h textNode.cxx
textNode.I textNode.h textNode.cxx \
qptextNode.I qptextNode.h qptextNode.cxx
#define INCLUDED_SOURCES \
config_text.cxx \
@ -43,7 +45,8 @@
stringDecoder.I stringDecoder.h \
textFont.I textFont.h \
textGlyph.I textGlyph.h \
textNode.I textNode.h
textNode.I textNode.h \
qptextNode.I qptextNode.h
#define IGATESCAN all

View File

@ -20,6 +20,7 @@
#include "staticTextFont.h"
#include "textFont.h"
#include "textNode.h"
#include "qptextNode.h"
#include "dynamicTextFont.h"
#include "dynamicTextPage.h"
#include "geomTextGlyph.h"
@ -68,6 +69,7 @@ init_libtext() {
StaticTextFont::init_type();
TextFont::init_type();
TextNode::init_type();
qpTextNode::init_type();
#ifdef HAVE_FREETYPE
DynamicTextFont::init_type();

View File

@ -22,6 +22,9 @@
#include "dynamicTextPage.h"
#include "geomTextGlyph.h"
#include "textureAttrib.h"
#include "transparencyAttrib.h"
#include "renderState.h"
#include "textureTransition.h"
#include "transparencyTransition.h"
@ -164,6 +167,9 @@ make_geom(int bitmap_top, int bitmap_left,
_trans.set_transition(tex);
_trans.set_transition(trans);
_state = RenderState::make(TextureAttrib::make(_page),
TransparencyAttrib::make(TransparencyAttrib::M_alpha));
_advance = advance / pixels_per_unit;
}

View File

@ -21,6 +21,9 @@
#include "geom.h"
#include "geomPoint.h"
#include "qpgeomNode.h"
#include "renderState.h"
#include "geomNode.h"
#include "namedNode.h"
#include "renderRelation.h"
@ -49,6 +52,25 @@ StaticTextFont(Node *font_def) {
}
}
////////////////////////////////////////////////////////////////////
// Function: StaticTextFont::Constructor
// Access: Published
// Description: The constructor expects the root node to a model
// generated via egg-mkfont, which consists of a set of
// models, one per each character in the font.
////////////////////////////////////////////////////////////////////
StaticTextFont::
StaticTextFont(PandaNode *font_def) {
nassertv(font_def != (PandaNode *)NULL);
_qpfont = font_def;
_glyphs.clear();
find_characters(font_def, RenderState::make_empty());
_is_valid = !_glyphs.empty();
set_name(font_def->get_name());
}
////////////////////////////////////////////////////////////////////
// Function: StaticTextFont::write
// Access: Published, Virtual
@ -298,3 +320,116 @@ find_characters(Node *root) {
}
}
}
////////////////////////////////////////////////////////////////////
// Function: StaticTextFont::find_character_gsets
// Access: Private
// Description: Given that 'root' is a PandaNode containing at least
// a polygon and a point which define the character's
// appearance and kern position, respectively,
// recursively walk the hierarchy and root and locate
// those two Geoms.
////////////////////////////////////////////////////////////////////
void StaticTextFont::
find_character_gsets(PandaNode *root, Geom *&ch, GeomPoint *&dot,
const RenderState *&state, const RenderState *net_state) {
CPT(RenderState) next_net_state = net_state->compose(root->get_state());
if (root->is_geom_node()) {
qpGeomNode *geode = DCAST(qpGeomNode, root);
for (int i = 0; i < geode->get_num_geoms(); i++) {
dDrawable *geom = geode->get_geom(i);
if (geom->is_of_type(GeomPoint::get_class_type())) {
dot = DCAST(GeomPoint, geom);
} else if (geom->is_of_type(Geom::get_class_type())) {
ch = DCAST(Geom, geom);
state = next_net_state->compose(geode->get_geom_state(i));
}
}
} else {
PandaNode::Children cr = root->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
find_character_gsets(cr.get_child(i), ch, dot, state, next_net_state);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: StaticTextFont::find_characters
// Access: Private
// Description: Walk the hierarchy beginning at the indicated root
// and locate any nodes whose names are just integers.
// These are taken to be characters, and their
// definitions and kern informations are retrieved.
////////////////////////////////////////////////////////////////////
void StaticTextFont::
find_characters(PandaNode *root, const RenderState *net_state) {
CPT(RenderState) next_net_state = net_state->compose(root->get_state());
string name = root->get_name();
bool all_digits = !name.empty();
const char *p = name.c_str();
while (all_digits && *p != '\0') {
// VC++ complains if we treat an int as a bool, so we have to do
// this != 0 comparison on the int isdigit() function to shut it
// up.
all_digits = (isdigit(*p) != 0);
p++;
}
if (all_digits) {
int character = atoi(name.c_str());
Geom *ch = NULL;
GeomPoint *dot = NULL;
const RenderState *state = NULL;
find_character_gsets(root, ch, dot, state, next_net_state);
if (dot != NULL) {
// Get the first vertex from the "dot" geoset. This will be the
// origin of the next character.
PTA_Vertexf alist;
PTA_ushort ilist;
float width;
dot->get_coords(alist, ilist);
if (ilist.empty()) {
width = alist[0][0];
} else {
width = alist[ilist[0]][0];
}
_glyphs[character] = new TextGlyph(ch, state, width);
}
} else if (name == "ds") {
// The group "ds" is a special node that indicate's the font's
// design size, or line height.
Geom *ch = NULL;
GeomPoint *dot = NULL;
const RenderState *state = NULL;
find_character_gsets(root, ch, dot, state, next_net_state);
if (dot != NULL) {
// Get the first vertex from the "dot" geoset. This will be the
// design size indicator.
PTA_Vertexf alist;
PTA_ushort ilist;
dot->get_coords(alist, ilist);
if (ilist.empty()) {
_line_height = alist[0][2];
} else {
_line_height = alist[ilist[0]][2];
}
_space_advance = 0.25f * _line_height;
}
} else {
PandaNode::Children cr = root->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
find_characters(cr.get_child(i), next_net_state);
}
}
}

View File

@ -25,6 +25,8 @@
#include "textFont.h"
#include "textGlyph.h"
#include "pt_Node.h"
#include "pandaNode.h"
#include "pointerTo.h"
#include "pmap.h"
class Node;
@ -42,6 +44,7 @@ class GeomPoint;
class EXPCL_PANDA StaticTextFont : public TextFont {
PUBLISHED:
StaticTextFont(Node *font_def);
StaticTextFont(PandaNode *font_def);
virtual void write(ostream &out, int indent_level) const;
@ -53,11 +56,17 @@ private:
bool find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
AllTransitionsWrapper &trans);
void find_characters(Node *root);
void find_character_gsets(PandaNode *root, Geom *&ch, GeomPoint *&dot,
const RenderState *&state,
const RenderState *net_state);
void find_characters(PandaNode *root,
const RenderState *net_state);
typedef pmap<int, PT(TextGlyph)> Glyphs;
Glyphs _glyphs;
float _font_height;
PT_Node _font;
PT(PandaNode) _qpfont;
public:
static TypeHandle get_class_type() {

View File

@ -37,6 +37,21 @@ INLINE TextGlyph::
TextGlyph(Geom *geom, const AllTransitionsWrapper &trans, float advance) :
_geom(geom), _trans(trans), _advance(advance)
{
_state = RenderState::make_empty();
}
////////////////////////////////////////////////////////////////////
// Function: TextGlyph::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TextGlyph::
TextGlyph(Geom *geom, const RenderState *state, float advance) :
_geom(geom), _state(state), _advance(advance)
{
if (_state == (RenderState *)NULL) {
_state = RenderState::make_empty();
}
}
////////////////////////////////////////////////////////////////////
@ -48,6 +63,7 @@ INLINE TextGlyph::
TextGlyph(const TextGlyph &copy) :
_geom(copy._geom),
_trans(copy._trans),
_state(copy._state),
_advance(copy._advance)
{
}
@ -61,6 +77,7 @@ INLINE void TextGlyph::
operator = (const TextGlyph &copy) {
_geom = copy._geom;
_trans = copy._trans;
_state = copy._state;
_advance = copy._advance;
}
@ -75,6 +92,17 @@ get_trans() const {
return _trans;
}
////////////////////////////////////////////////////////////////////
// Function: TextGlyph::get_state
// Access: Public
// Description: Returns the state in which the glyph should be
// rendered.
////////////////////////////////////////////////////////////////////
INLINE const RenderState *TextGlyph::
get_state() const {
return _state;
}
////////////////////////////////////////////////////////////////////
// Function: TextGlyph::get_advance
// Access: Public

View File

@ -21,6 +21,7 @@
#include "pandabase.h"
#include "allTransitionsWrapper.h"
#include "renderState.h"
#include "referenceCount.h"
#include "geom.h"
#include "pointerTo.h"
@ -37,17 +38,20 @@ class EXPCL_PANDA TextGlyph : public ReferenceCount {
public:
INLINE TextGlyph();
INLINE TextGlyph(Geom *geom, const AllTransitionsWrapper &trans, float advance);
INLINE TextGlyph(Geom *geom, const RenderState *state, float advance);
INLINE TextGlyph(const TextGlyph &copy);
INLINE void operator = (const TextGlyph &copy);
virtual ~TextGlyph();
virtual PT(Geom) get_geom() const;
INLINE const AllTransitionsWrapper &get_trans() const;
INLINE const RenderState *get_state() const;
INLINE float get_advance() const;
protected:
PT(Geom) _geom;
AllTransitionsWrapper _trans;
CPT(RenderState) _state;
float _advance;
};

View File

@ -35,11 +35,9 @@
#include "allTransitionsWrapper.h"
// These are deprecated. Use TextNode::Alignment instead.
BEGIN_PUBLISH
#define TM_ALIGN_LEFT 1
#define TM_ALIGN_RIGHT 2
#define TM_ALIGN_CENTER 3
END_PUBLISH
class StringDecoder;