Browse Source

fix some font issues

David Rose 17 years ago
parent
commit
864dac0290

+ 6 - 5
panda/src/text/dynamicTextFont.I

@@ -494,10 +494,11 @@ get_bg() const {
 //               cached.
 //               cached.
 //
 //
 //               The color is the desired color of the outline, width
 //               The color is the desired color of the outline, width
-//               is the number of pixels beyond the letter that the
-//               outline extends, and feather is a number in the range
-//               0.0 .. 1.0 that controls the softness of the outline.
-//               Set the width to 0.0 to disable the outline.
+//               is the number of points beyond the letter that the
+//               outline extends (a typical font is 10 points high),
+//               and feather is a number in the range 0.0 .. 1.0 that
+//               controls the softness of the outline.  Set the width
+//               to 0.0 to disable the outline.
 //
 //
 //               This should only be called before any characters have
 //               This should only be called before any characters have
 //               been requested out of the font, or immediately after
 //               been requested out of the font, or immediately after
@@ -531,7 +532,7 @@ get_outline_color() const {
 //     Function: DynamicTextFont::get_outline_width
 //     Function: DynamicTextFont::get_outline_width
 //       Access: Published
 //       Access: Published
 //  Description: Returns the width of the outline pixels of the
 //  Description: Returns the width of the outline pixels of the
-//               font, as the number of pixels beyond each letter.
+//               font, as the number of points beyond each letter.
 //               See set_outline().
 //               See set_outline().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE float DynamicTextFont::
 INLINE float DynamicTextFont::

+ 17 - 8
panda/src/text/dynamicTextFont.cxx

@@ -546,7 +546,10 @@ make_glyph(int character, int glyph_index) {
       PNMImage reduced(int_x_size, int_y_size, PNMImage::CT_grayscale);
       PNMImage reduced(int_x_size, int_y_size, PNMImage::CT_grayscale);
       reduced.quick_filter_from(image);
       reduced.quick_filter_from(image);
 
 
-      outline = (int)ceil(_outline_width);
+      // convert the outline width from points to tex_pixels.
+      float outline_pixels = _outline_width / _points_per_unit * _tex_pixels_per_unit;
+      outline = (int)ceil(outline_pixels);
+
       int_x_size += outline * 2;
       int_x_size += outline * 2;
       int_y_size += outline * 2;
       int_y_size += outline * 2;
       tex_x_size += outline * 2;
       tex_x_size += outline * 2;
@@ -564,8 +567,8 @@ make_glyph(int character, int glyph_index) {
       }
       }
     }
     }
       
       
-    glyph->make_geom(slot->bitmap_top + outline * _scale_factor,
-                     slot->bitmap_left - outline * _scale_factor,
+    glyph->make_geom((int)floor(slot->bitmap_top + outline * _scale_factor + 0.5f),
+                     (int)floor(slot->bitmap_left - outline * _scale_factor + 0.5f),
                      advance, _poly_margin,
                      advance, _poly_margin,
                      tex_x_size, tex_y_size,
                      tex_x_size, tex_y_size,
                      _font_pixels_per_unit, _tex_pixels_per_unit);
                      _font_pixels_per_unit, _tex_pixels_per_unit);
@@ -664,20 +667,26 @@ copy_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph) {
     if (_has_outline) {
     if (_has_outline) {
       // Gaussian blur the glyph to generate an outline.
       // Gaussian blur the glyph to generate an outline.
       PNMImage outline(image.get_x_size(), image.get_y_size(), PNMImage::CT_grayscale);
       PNMImage outline(image.get_x_size(), image.get_y_size(), PNMImage::CT_grayscale);
-      outline.gaussian_filter_from(_outline_width, image);
+      float outline_pixels = _outline_width / _points_per_unit * _tex_pixels_per_unit;
+      outline.gaussian_filter_from(outline_pixels * 0.707, image);
+
+      // Filter the resulting outline to make a harder edge.  Square
+      // _outline_feather first to make the range more visually linear
+      // (this approximately compensates for the Gaussian falloff of
+      // the feathered edge).
+      float f = _outline_feather * _outline_feather;
 
 
-      // Filter the resulting outline to make a harder edge.
       for (int yi = 0; yi < outline.get_y_size(); yi++) {
       for (int yi = 0; yi < outline.get_y_size(); yi++) {
         for (int xi = 0; xi < outline.get_x_size(); xi++) {
         for (int xi = 0; xi < outline.get_x_size(); xi++) {
           float v = outline.get_gray(xi, yi);
           float v = outline.get_gray(xi, yi);
           if (v == 0.0f) {
           if (v == 0.0f) {
             // Do nothing.
             // Do nothing.
-          } else if (v >= _outline_feather) {
+          } else if (v >= f) {
             // Clamp to 1.
             // Clamp to 1.
             outline.set_gray(xi, yi, 1.0);
             outline.set_gray(xi, yi, 1.0);
           } else {
           } else {
-            // Linearly scale the range 0 .. _outline_feather onto 0 .. 1.
-            outline.set_gray(xi, yi, v / _outline_feather);
+            // Linearly scale the range 0 .. f onto 0 .. 1.
+            outline.set_gray(xi, yi, v / f);
           }
           }
         }
         }
       }
       }

+ 3 - 4
panda/src/text/dynamicTextGlyph.cxx

@@ -74,10 +74,9 @@ erase(DynamicTextFont *font) {
   nassertv(_page != (DynamicTextPage *)NULL);
   nassertv(_page != (DynamicTextPage *)NULL);
   nassertv(_page->has_ram_image());
   nassertv(_page->has_ram_image());
 
 
-  int ysizetop = _page->get_y_size() - 1;
-  int width = _page->get_x_size();
-
-  _page->fill_region(_x, _y, _x_size, _y_size, font->get_bg());
+  _page->fill_region(_x + _margin, 
+                     _page->get_y_size() - (_y + _y_size + _margin),
+                     _x_size, _y_size, font->get_bg());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/text/dynamicTextPage.cxx

@@ -96,7 +96,7 @@ slot_glyph(int character, int x_size, int y_size, int margin) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DynamicTextPage::
 void DynamicTextPage::
 fill_region(int x, int y, int x_size, int y_size, const Colorf &color) {
 fill_region(int x, int y, int x_size, int y_size, const Colorf &color) {
-  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
+  nassertv(x >= 0 && x + x_size <= _x_size && y >= 0 && y + y_size <= _y_size);
   int num_components = get_num_components();
   int num_components = get_num_components();
   if (num_components == 1) {
   if (num_components == 1) {
     // Luminance or alpha.
     // Luminance or alpha.

+ 38 - 0
panda/src/text/geomTextGlyph.cxx

@@ -42,6 +42,18 @@ GeomTextGlyph(DynamicTextGlyph *glyph, const GeomVertexData *data) :
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTextGlyph::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+GeomTextGlyph::
+GeomTextGlyph(const GeomVertexData *data) :
+  Geom(data)
+{
+  // With this constructor, there are no glyphs initially.
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomTextGlyph::Copy Constructor
 //     Function: GeomTextGlyph::Copy Constructor
 //       Access: Public
 //       Access: Public
@@ -146,6 +158,32 @@ copy_primitives_from(const Geom *other) {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTextGlyph::count_geom
+//       Access: Public
+//  Description: Records the reference count of the other Geom within
+//               this Geom, as if the primitives were copied in via
+//               copy_primitives_from() (but does not actually copy
+//               any primitives).  This is particularly necessary for
+//               GeomTextGlyph's reference counting mechanism.
+//
+//               Does nothing if the other Geom is not a
+//               GeomTextGlyph.
+////////////////////////////////////////////////////////////////////
+void GeomTextGlyph::
+count_geom(const Geom *other) {
+  if (other->is_of_type(GeomTextGlyph::get_class_type())) {
+    const GeomTextGlyph *tother;
+    DCAST_INTO_V(tother, other);
+    
+    Glyphs::const_iterator gi;
+    for (gi = tother->_glyphs.begin(); gi != tother->_glyphs.end(); ++gi) {
+      _glyphs.push_back(*gi);
+      (*gi)->_geom_count++;
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomTextGlyph::output
 //     Function: GeomTextGlyph::output
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 7 - 5
panda/src/text/geomTextGlyph.h

@@ -25,16 +25,17 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : GeomTextGlyph
 //       Class : GeomTextGlyph
 // Description : This is a specialization on Geom for containing a
 // Description : This is a specialization on Geom for containing a
-//               triangle strip intended to represent a
-//               DynamicTextGlyph.  Its sole purpose is to maintain
-//               the geom count on the glyph, so we can determine the
-//               actual usage count on a dynamic glyph (and thus know
-//               when it is safe to recycle the glyph).
+//               primitive intended to represent a DynamicTextGlyph.
+//               Its sole purpose is to maintain the geom count on the
+//               glyph, so we can determine the actual usage count on
+//               a dynamic glyph (and thus know when it is safe to
+//               recycle the glyph).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA_TEXT GeomTextGlyph : public Geom {
 class EXPCL_PANDA_TEXT GeomTextGlyph : public Geom {
 public:
 public:
   GeomTextGlyph(DynamicTextGlyph *glyph,
   GeomTextGlyph(DynamicTextGlyph *glyph,
                 const GeomVertexData *data);
                 const GeomVertexData *data);
+  GeomTextGlyph(const GeomVertexData *data);
   GeomTextGlyph(const GeomTextGlyph &copy);
   GeomTextGlyph(const GeomTextGlyph &copy);
   void operator = (const GeomTextGlyph &copy);
   void operator = (const GeomTextGlyph &copy);
   virtual ~GeomTextGlyph();
   virtual ~GeomTextGlyph();
@@ -42,6 +43,7 @@ public:
 
 
   virtual Geom *make_copy() const;
   virtual Geom *make_copy() const;
   virtual bool copy_primitives_from(const Geom *other);
   virtual bool copy_primitives_from(const Geom *other);
+  void count_geom(const Geom *other);
 
 
   virtual void output(ostream &out) const;
   virtual void output(ostream &out) const;
   virtual void write(ostream &out, int indent_level = 0) const;
   virtual void write(ostream &out, int indent_level = 0) const;

+ 17 - 0
panda/src/text/textAssembler.I

@@ -543,3 +543,20 @@ operator < (const TextAssembler::GeomCollectorKey &other) const {
   }
   }
   return _format < other._format;
   return _format < other._format;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextAssembler::GeomCollector::count_geom
+//       Access: Public
+//  Description: If the indicated Geom is a GeomTextGlyph, increments
+//               its reference count and adds it into this geom.  This
+//               is necessary to keep references to outstanding
+//               glyphs, so we know when it's safe to recycle
+//               no-longer-used glyphs.
+//
+//               If the indicated Geom is an ordinary Geom, does
+//               nothing.
+////////////////////////////////////////////////////////////////////
+INLINE void TextAssembler::GeomCollector::
+count_geom(const Geom *geom) {
+  _geom->count_geom(geom);
+}

+ 2 - 1
panda/src/text/textAssembler.cxx

@@ -2221,6 +2221,7 @@ assign_append_to(GeomCollectorMap &geom_collector_map,
       mi = geom_collector_map.insert(GeomCollectorMap::value_type(key, GeomCollector(vdata->get_format()))).first;
       mi = geom_collector_map.insert(GeomCollectorMap::value_type(key, GeomCollector(vdata->get_format()))).first;
     }
     }
     GeomCollector &geom_collector = (*mi).second;
     GeomCollector &geom_collector = (*mi).second;
+    geom_collector.count_geom(geom);
 
 
     // We use this map to keep track of vertex indices we have already
     // We use this map to keep track of vertex indices we have already
     // added, so that we don't needlessly duplicate vertices into our
     // added, so that we don't needlessly duplicate vertices into our
@@ -2299,7 +2300,7 @@ copy_graphic_to(PandaNode *node, const RenderState *state,
 TextAssembler::GeomCollector::
 TextAssembler::GeomCollector::
 GeomCollector(const GeomVertexFormat *format) :
 GeomCollector(const GeomVertexFormat *format) :
   _vdata(new GeomVertexData("merged_geom", format, Geom::UH_static)),
   _vdata(new GeomVertexData("merged_geom", format, Geom::UH_static)),
-  _geom(new Geom(_vdata))
+  _geom(new GeomTextGlyph(_vdata))
 {
 {
 }
 }
 
 

+ 3 - 2
panda/src/text/textAssembler.h

@@ -22,7 +22,7 @@
 #include "unicodeLatinMap.h"
 #include "unicodeLatinMap.h"
 #include "geomNode.h"
 #include "geomNode.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "geom.h"
+#include "geomTextGlyph.h"
 #include "textPropertiesManager.h"
 #include "textPropertiesManager.h"
 #include "textEncoder.h"
 #include "textEncoder.h"
 #include "geomVertexRewriter.h"
 #include "geomVertexRewriter.h"
@@ -200,6 +200,7 @@ private:
     GeomCollector(const GeomVertexFormat *format);
     GeomCollector(const GeomVertexFormat *format);
     GeomCollector(const GeomCollector &copy);
     GeomCollector(const GeomCollector &copy);
 
 
+    INLINE void count_geom(const Geom *geom);
     GeomPrimitive *get_primitive(TypeHandle prim_type);
     GeomPrimitive *get_primitive(TypeHandle prim_type);
     int append_vertex(const GeomVertexData *orig_vdata, int orig_row,
     int append_vertex(const GeomVertexData *orig_vdata, int orig_row,
                       const LMatrix4f &xform);
                       const LMatrix4f &xform);
@@ -207,7 +208,7 @@ private:
 
 
   private:
   private:
     PT(GeomVertexData) _vdata;
     PT(GeomVertexData) _vdata;
-    PT(Geom) _geom;
+    PT(GeomTextGlyph) _geom;
     PT(GeomTriangles) _triangles;
     PT(GeomTriangles) _triangles;
     PT(GeomLines) _lines;
     PT(GeomLines) _lines;
     PT(GeomPoints) _points;
     PT(GeomPoints) _points;