Browse Source

pgraph text

David Rose 24 years ago
parent
commit
e45ab93f89

+ 12 - 2
panda/src/pgraph/pandaNode.cxx

@@ -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);

+ 2 - 1
panda/src/pgraph/qpnodePath.I

@@ -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);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 18 - 0
panda/src/pgraph/qpnodePath.cxx

@@ -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);
+  }
+}

+ 2 - 0
panda/src/pgraph/qpnodePath.h

@@ -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;

+ 25 - 1
panda/src/pgraph/renderState.cxx

@@ -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

+ 2 - 0
panda/src/pgraph/renderState.h

@@ -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;

+ 1 - 1
panda/src/pgraph/transformState.cxx

@@ -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;
   }
 

+ 6 - 3
panda/src/text/Sources.pp

@@ -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
 

+ 2 - 0
panda/src/text/config_text.cxx

@@ -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();

+ 6 - 0
panda/src/text/dynamicTextGlyph.cxx

@@ -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;
 }
 

+ 135 - 0
panda/src/text/staticTextFont.cxx

@@ -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);
+    }
+  }
+}

+ 9 - 0
panda/src/text/staticTextFont.h

@@ -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() {

+ 28 - 0
panda/src/text/textGlyph.I

@@ -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

+ 4 - 0
panda/src/text/textGlyph.h

@@ -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;
 };
 

+ 0 - 2
panda/src/text/textNode.h

@@ -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;