Bladeren bron

add scale_factor

David Rose 23 jaren geleden
bovenliggende
commit
0efa534315

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

@@ -36,12 +36,13 @@ ConfigureFn(config_text) {
 const bool text_flatten = config_text.GetBool("text-flatten", true);
 const bool text_flatten = config_text.GetBool("text-flatten", true);
 const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false);
 const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false);
 const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1);
 const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1);
-const int text_texture_margin = config_text.GetInt("text-texture-margin", 3);
-const float text_poly_margin = config_text.GetFloat("text-poly-margin", 1.0f);
+const int text_texture_margin = config_text.GetInt("text-texture-margin", 2);
+const float text_poly_margin = config_text.GetFloat("text-poly-margin", 0.6f);
 const int text_page_x_size = config_text.GetInt("text-page-x-size", 256);
 const int text_page_x_size = config_text.GetInt("text-page-x-size", 256);
 const int text_page_y_size = config_text.GetInt("text-page-y-size", 256);
 const int text_page_y_size = config_text.GetInt("text-page-y-size", 256);
 const float text_point_size = config_text.GetFloat("text-point-size", 10.0f);
 const float text_point_size = config_text.GetFloat("text-point-size", 10.0f);
 const float text_pixels_per_unit = config_text.GetFloat("text-pixels-per-unit", 30.0f);
 const float text_pixels_per_unit = config_text.GetFloat("text-pixels-per-unit", 30.0f);
+const float text_scale_factor = config_text.GetFloat("text-scale-factor", 2.0f);
 const bool text_small_caps = config_text.GetBool("text-small-caps", false);
 const bool text_small_caps = config_text.GetBool("text-small-caps", false);
 const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
 const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
 
 

+ 1 - 0
panda/src/text/config_text.h

@@ -36,6 +36,7 @@ extern const int text_page_x_size;
 extern const int text_page_y_size;
 extern const int text_page_y_size;
 extern const float text_point_size;
 extern const float text_point_size;
 extern const float text_pixels_per_unit;
 extern const float text_pixels_per_unit;
+extern const float text_scale_factor;
 extern const bool text_small_caps;
 extern const bool text_small_caps;
 extern const float text_small_caps_scale;
 extern const float text_small_caps_scale;
 
 

+ 38 - 2
panda/src/text/dynamicTextFont.I

@@ -67,7 +67,7 @@ set_pixels_per_unit(float pixels_per_unit) {
   // If this assertion fails, you didn't call clear() first.  RTFM.
   // If this assertion fails, you didn't call clear() first.  RTFM.
   nassertr(get_num_pages() == 0, false);
   nassertr(get_num_pages() == 0, false);
 
 
-  _pixels_per_unit = pixels_per_unit;
+  _tex_pixels_per_unit = pixels_per_unit;
   return reset_scale();
   return reset_scale();
 }
 }
 
 
@@ -79,7 +79,43 @@ set_pixels_per_unit(float pixels_per_unit) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE float DynamicTextFont::
 INLINE float DynamicTextFont::
 get_pixels_per_unit() const {
 get_pixels_per_unit() const {
-  return _pixels_per_unit;
+  return _tex_pixels_per_unit;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DynamicTextFont::set_scale_factor
+//       Access: Published
+//  Description: Sets the factor by which the font is rendered larger
+//               by the FreeType library before being filtered down to
+//               its actual size in the texture as specified by
+//               set_pixels_per_unit().  This may be set to a number
+//               larger than 1.0 to improve the font's antialiasing
+//               (since FreeType doesn't really do a swell job of
+//               antialiasing by itself).  There is some performance
+//               implication for setting this different than 1.0.
+//
+//               This should only be called before any characters have
+//               been requested out of the font, or immediately after
+//               calling clear().
+////////////////////////////////////////////////////////////////////
+INLINE bool DynamicTextFont::
+set_scale_factor(float scale_factor) {
+  // If this assertion fails, you didn't call clear() first.  RTFM.
+  nassertr(get_num_pages() == 0, false);
+
+  _scale_factor = scale_factor;
+  return reset_scale();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DynamicTextFont::get_scale_factor
+//       Access: Published
+//  Description: Returns the antialiasing scale factor.  See
+//               set_scale_factor().
+////////////////////////////////////////////////////////////////////
+INLINE float DynamicTextFont::
+get_scale_factor() const {
+  return _scale_factor;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 184 - 64
panda/src/text/dynamicTextFont.cxx

@@ -55,7 +55,8 @@ DynamicTextFont(const Filename &font_filename, int face_index) {
   _page_x_size = text_page_x_size;
   _page_x_size = text_page_x_size;
   _page_y_size = text_page_y_size;
   _page_y_size = text_page_y_size;
   _point_size = text_point_size;
   _point_size = text_point_size;
-  _pixels_per_unit = text_pixels_per_unit;
+  _tex_pixels_per_unit = text_pixels_per_unit;
+  _scale_factor = text_scale_factor;
   _small_caps = text_small_caps;
   _small_caps = text_small_caps;
   _small_caps_scale = text_small_caps_scale;
   _small_caps_scale = text_small_caps_scale;
 
 
@@ -337,14 +338,19 @@ update_filters() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DynamicTextFont::reset_scale
 //     Function: DynamicTextFont::reset_scale
 //       Access: Private
 //       Access: Private
-//  Description: Resets the font to use the current _point_size and
-//               _pixels_per_unit.  Returns true if successful, false
-//               otherwise.
+//  Description: Resets the font based on the current values for
+//               _point_size, _tex_pixels_per_unit, and _scale_factor.
+//               Returns true if successful, false otherwise.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DynamicTextFont::
 bool DynamicTextFont::
 reset_scale() {
 reset_scale() {
+  // The font may be rendered larger (by a factor of _scale_factor),
+  // and then reduced into the texture.  Hence the difference between
+  // _font_pixels_per_unit aned _tex_pixels_per_unit.
+  _font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
+
   float units_per_inch = (points_per_inch / points_per_unit);
   float units_per_inch = (points_per_inch / points_per_unit);
-  int dpi = (int)(_pixels_per_unit * units_per_inch);
+  int dpi = (int)(_font_pixels_per_unit * units_per_inch);
   
   
   int error = FT_Set_Char_Size(_face,
   int error = FT_Set_Char_Size(_face,
                                (int)(_point_size * 64), (int)(_point_size * 64),
                                (int)(_point_size * 64), (int)(_point_size * 64),
@@ -353,7 +359,7 @@ reset_scale() {
     // If we were unable to set a particular char size, perhaps we
     // If we were unable to set a particular char size, perhaps we
     // have a non-scalable font.  Try to figure out the closest
     // have a non-scalable font.  Try to figure out the closest
     // available size.
     // available size.
-    int desired_height = (int)(_pixels_per_unit * _point_size / points_per_unit + 0.5f);
+    int desired_height = (int)(_font_pixels_per_unit * _point_size / points_per_unit + 0.5f);
     int best_size = -1;
     int best_size = -1;
     if (_face->num_fixed_sizes > 0) {
     if (_face->num_fixed_sizes > 0) {
       best_size = 0;
       best_size = 0;
@@ -375,7 +381,8 @@ reset_scale() {
           << "Using " << pixel_height << "-pixel font for "
           << "Using " << pixel_height << "-pixel font for "
           << get_name() << "\n";
           << get_name() << "\n";
 
 
-        _pixels_per_unit = pixel_height * points_per_unit / _point_size;
+        _font_pixels_per_unit = pixel_height * points_per_unit / _point_size;
+        _tex_pixels_per_unit = _font_pixels_per_unit;
       }
       }
     }
     }
   }
   }
@@ -388,7 +395,7 @@ reset_scale() {
     return false;
     return false;
   }
   }
 
 
-  _line_height = _face->size->metrics.height / (_pixels_per_unit * 64.0f);
+  _line_height = _face->size->metrics.height / (_font_pixels_per_unit * 64.0f);
 
 
   // Determine the correct width for a space.
   // Determine the correct width for a space.
   error = FT_Load_Char(_face, ' ', FT_LOAD_DEFAULT);
   error = FT_Load_Char(_face, ' ', FT_LOAD_DEFAULT);
@@ -397,7 +404,7 @@ reset_scale() {
     _space_advance = 0.25f * _line_height;
     _space_advance = 0.25f * _line_height;
 
 
   } else {
   } else {
-    _space_advance = _face->glyph->advance.x / (_pixels_per_unit * 64.0f);
+    _space_advance = _face->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
   }
   }
 
 
   return true;
   return true;
@@ -427,74 +434,187 @@ make_glyph(int glyph_index) {
 
 
   if (bitmap.width == 0 || bitmap.rows == 0) {
   if (bitmap.width == 0 || bitmap.rows == 0) {
     // If we got an empty bitmap, it's a special case.
     // If we got an empty bitmap, it's a special case.
-    PT(DynamicTextGlyph) glyph = new DynamicTextGlyph(advance / _pixels_per_unit);
+    PT(DynamicTextGlyph) glyph = 
+      new DynamicTextGlyph(advance / _font_pixels_per_unit);
     _empty_glyphs.push_back(glyph);
     _empty_glyphs.push_back(glyph);
     return glyph;
     return glyph;
 
 
   } else {
   } else {
-    DynamicTextGlyph *glyph = slot_glyph(bitmap.width, bitmap.rows);
-
-    if (bitmap.pixel_mode == ft_pixel_mode_grays && bitmap.num_grays == 256) {
-      // This is the easy case: we can memcpy the rendered glyph
-      // directly into our texture image, one row at a time.
-      unsigned char *buffer_row = bitmap.buffer;
-      for (int yi = 0; yi < bitmap.rows; yi++) {
-        unsigned char *texture_row = glyph->get_row(yi);
-        nassertr(texture_row != (unsigned char *)NULL, (DynamicTextGlyph *)NULL);
-        memcpy(texture_row, buffer_row, bitmap.width);
-        buffer_row += bitmap.pitch;
-      }
+    DynamicTextGlyph *glyph;
 
 
-    } else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
-      // This is a little bit more work: we have to expand the
-      // one-bit-per-pixel bitmap into a one-byte-per-pixel texture.
-      unsigned char *buffer_row = bitmap.buffer;
-      for (int yi = 0; yi < bitmap.rows; yi++) {
-        unsigned char *texture_row = glyph->get_row(yi);
-        nassertr(texture_row != (unsigned char *)NULL, (DynamicTextGlyph *)NULL);
-
-        int bit = 0x80;
-        unsigned char *b = buffer_row;
-        for (int xi = 0; xi < bitmap.width; xi++) {
-          if (*b & bit) {
-            texture_row[xi] = 0xff;
-          } else {
-            texture_row[xi] = 0x00;
-          }
-          bit >>= 1;
-          if (bit == 0) {
-            ++b;
-            bit = 0x80;
-          }
-        }
+    if (_tex_pixels_per_unit == _font_pixels_per_unit) {
+      // If the bitmap produced from the font doesn't require scaling
+      // before it goes to the texture, we can just copy it directly
+      // into the texture.
+      glyph = slot_glyph(bitmap.width, bitmap.rows);
+      copy_bitmap_to_texture(bitmap, glyph);
 
 
-        buffer_row += bitmap.pitch;
-      }
+    } else {
+      // Otherwise, we need to copy to a PNMImage first, so we can
+      // scale it; and then copy it to the texture from there.
+      int tex_x_size = (int)(bitmap.width / _scale_factor + 0.5f);
+      int tex_y_size = (int)(bitmap.rows / _scale_factor + 0.5f);
+      glyph = slot_glyph(tex_x_size, tex_y_size);
+
+      PNMImage image(bitmap.width, bitmap.rows, PNMImage::CT_grayscale);
+      copy_bitmap_to_pnmimage(bitmap, image);
+
+      PNMImage reduced(tex_x_size, tex_y_size, PNMImage::CT_grayscale);
+      reduced.quick_filter_from(image);
+      copy_pnmimage_to_texture(reduced, glyph);
+    }
       
       
+    glyph->_page->mark_dirty(Texture::DF_image);
+    
+    glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance, _poly_margin,
+                     _font_pixels_per_unit, _tex_pixels_per_unit);
+    return glyph;
+  }
+}
 
 
-    } else if (bitmap.pixel_mode == ft_pixel_mode_grays) {
-      // Here we must expand a grayscale pixmap with n levels of gray
-      // into our 256-level texture.
-      unsigned char *buffer_row = bitmap.buffer;
-      for (int yi = 0; yi < bitmap.rows; yi++) {
-        unsigned char *texture_row = glyph->get_row(yi);
-        nassertr(texture_row != (unsigned char *)NULL, (DynamicTextGlyph *)NULL);
-        for (int xi = 0; xi < bitmap.width; xi++) {
-          texture_row[xi] = (int)(buffer_row[xi] * 255) / (bitmap.num_grays - 1);
+////////////////////////////////////////////////////////////////////
+//     Function: DynamicTextFont::copy_bitmap_to_texture
+//       Access: Private
+//  Description: Copies a bitmap as rendered by FreeType directly into
+//               the texture memory image for the indicated glyph,
+//               without any scaling of pixels.
+////////////////////////////////////////////////////////////////////
+void DynamicTextFont::
+copy_bitmap_to_texture(const FT_Bitmap &bitmap, DynamicTextGlyph *glyph) {
+  if (bitmap.pixel_mode == ft_pixel_mode_grays && bitmap.num_grays == 256) {
+    // This is the easy case: we can memcpy the rendered glyph
+    // directly into our texture image, one row at a time.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      
+      unsigned char *texture_row = glyph->get_row(yi);
+      nassertv(texture_row != (unsigned char *)NULL);
+      memcpy(texture_row, buffer_row, bitmap.width);
+      buffer_row += bitmap.pitch;
+    }
+    
+  } else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
+    // This is a little bit more work: we have to expand the
+    // one-bit-per-pixel bitmap into a one-byte-per-pixel texture.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      unsigned char *texture_row = glyph->get_row(yi);
+      nassertv(texture_row != (unsigned char *)NULL);
+      
+      int bit = 0x80;
+      unsigned char *b = buffer_row;
+      for (int xi = 0; xi < bitmap.width; xi++) {
+        if (*b & bit) {
+          texture_row[xi] = 0xff;
+        } else {
+          texture_row[xi] = 0x00;
+        }
+        bit >>= 1;
+        if (bit == 0) {
+          ++b;
+          bit = 0x80;
         }
         }
-        buffer_row += bitmap.pitch;
       }
       }
-
-    } else {
-      text_cat.error()
-        << "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
+      
+      buffer_row += bitmap.pitch;
     }
     }
+    
+    
+  } else if (bitmap.pixel_mode == ft_pixel_mode_grays) {
+    // Here we must expand a grayscale pixmap with n levels of gray
+    // into our 256-level texture.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      unsigned char *texture_row = glyph->get_row(yi);
+      nassertv(texture_row != (unsigned char *)NULL);
+      for (int xi = 0; xi < bitmap.width; xi++) {
+        texture_row[xi] = (int)(buffer_row[xi] * 255) / (bitmap.num_grays - 1);
+      }
+      buffer_row += bitmap.pitch;
+    }
+    
+  } else {
+    text_cat.error()
+      << "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
+  }
+}
 
 
-    glyph->_page->mark_dirty(Texture::DF_image);
+////////////////////////////////////////////////////////////////////
+//     Function: DynamicTextFont::copy_bitmap_to_pnmimage
+//       Access: Private
+//  Description: Copies a bitmap as rendered by FreeType into a
+//               PNMImage, so it can be rescaled.
+////////////////////////////////////////////////////////////////////
+void DynamicTextFont::
+copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image) {
+  if (bitmap.pixel_mode == ft_pixel_mode_grays && 
+      bitmap.num_grays == (int)image.get_maxval() + 1) {
+    // This is the easy case: we can copy the rendered glyph
+    // directly into our image, one pixel at a time.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      for (int xi = 0; xi < bitmap.width; xi++) {
+        image.set_gray_val(xi, yi, buffer_row[xi]);
+      }
+      buffer_row += bitmap.pitch;
+    }
     
     
-    glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance,
-                     _poly_margin, _pixels_per_unit);
-    return glyph;
+  } else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
+    // This is a little bit more work: we have to expand the
+    // one-bit-per-pixel bitmap into a one-byte-per-pixel image.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      xelval maxval = image.get_maxval();
+      int bit = 0x80;
+      unsigned char *b = buffer_row;
+      for (int xi = 0; xi < bitmap.width; xi++) {
+        if (*b & bit) {
+          image.set_gray_val(xi, yi, maxval);
+        } else {
+          image.set_gray_val(xi, yi, 0);
+        }
+        bit >>= 1;
+        if (bit == 0) {
+          ++b;
+          bit = 0x80;
+        }
+      }
+      
+      buffer_row += bitmap.pitch;
+    }
+    
+    
+  } else if (bitmap.pixel_mode == ft_pixel_mode_grays) {
+    // Here we must expand a grayscale pixmap with n levels of gray
+    // into our 256-level texture.
+    unsigned char *buffer_row = bitmap.buffer;
+    for (int yi = 0; yi < bitmap.rows; yi++) {
+      for (int xi = 0; xi < bitmap.width; xi++) {
+        image.set_gray(xi, yi, (float)buffer_row[xi] / (bitmap.num_grays - 1));
+      }
+      buffer_row += bitmap.pitch;
+    }
+    
+  } else {
+    text_cat.error()
+      << "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DynamicTextFont::copy_pnmimage_to_texture
+//       Access: Private
+//  Description: Copies a bitmap stored in a PNMImage into
+//               the texture memory image for the indicated glyph.
+////////////////////////////////////////////////////////////////////
+void DynamicTextFont::
+copy_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph) {
+  for (int yi = 0; yi < image.get_y_size(); yi++) {
+    unsigned char *texture_row = glyph->get_row(yi);
+    nassertv(texture_row != (unsigned char *)NULL);
+    for (int xi = 0; xi < image.get_x_size(); xi++) {
+      texture_row[xi] = image.get_gray_val(xi, yi);
+    }
   }
   }
 }
 }
 
 

+ 9 - 1
panda/src/text/dynamicTextFont.h

@@ -53,6 +53,9 @@ PUBLISHED:
   INLINE bool set_pixels_per_unit(float pixels_per_unit);
   INLINE bool set_pixels_per_unit(float pixels_per_unit);
   INLINE float get_pixels_per_unit() const;
   INLINE float get_pixels_per_unit() const;
 
 
+  INLINE bool set_scale_factor(float scale_factor);
+  INLINE float get_scale_factor() const;
+
   INLINE void set_small_caps(bool small_caps);
   INLINE void set_small_caps(bool small_caps);
   INLINE bool get_small_caps() const;
   INLINE bool get_small_caps() const;
   INLINE void set_small_caps_scale(float small_caps_scale);
   INLINE void set_small_caps_scale(float small_caps_scale);
@@ -94,12 +97,17 @@ private:
   void update_filters();
   void update_filters();
   bool reset_scale();
   bool reset_scale();
   DynamicTextGlyph *make_glyph(int glyph_index);
   DynamicTextGlyph *make_glyph(int glyph_index);
+  void copy_bitmap_to_texture(const FT_Bitmap &bitmap, DynamicTextGlyph *glyph);
+  void copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image);
+  void copy_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph);
   DynamicTextGlyph *slot_glyph(int x_size, int y_size);
   DynamicTextGlyph *slot_glyph(int x_size, int y_size);
 
 
   static void initialize_ft_library();
   static void initialize_ft_library();
 
 
   float _point_size;
   float _point_size;
-  float _pixels_per_unit;
+  float _tex_pixels_per_unit;
+  float _scale_factor;
+  float _font_pixels_per_unit;
   bool _small_caps;
   bool _small_caps;
   float _small_caps_scale;
   float _small_caps_scale;
   int _texture_margin;
   int _texture_margin;

+ 10 - 7
panda/src/text/dynamicTextGlyph.cxx

@@ -108,18 +108,21 @@ erase() {
 //               the pen should be advanced after drawing this glyph.
 //               the pen should be advanced after drawing this glyph.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DynamicTextGlyph::
 void DynamicTextGlyph::
-make_geom(int bitmap_top, int bitmap_left, 
-          float advance, float poly_margin, float pixels_per_unit) {
+make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin, 
+          float font_pixels_per_unit, float tex_pixels_per_unit) {
   nassertv(_page != (DynamicTextPage *)NULL);
   nassertv(_page != (DynamicTextPage *)NULL);
 
 
   // This function should not be called twice.
   // This function should not be called twice.
   nassertv(_geom_count == 0);
   nassertv(_geom_count == 0);
 
 
   // Determine the corners of the rectangle in geometric units.
   // Determine the corners of the rectangle in geometric units.
-  float top = (bitmap_top + poly_margin) / pixels_per_unit;
-  float left = (bitmap_left - poly_margin) / pixels_per_unit;
-  float bottom = (bitmap_top - _y_size - poly_margin) / pixels_per_unit;
-  float right = (bitmap_left + _x_size + poly_margin) / pixels_per_unit;
+  float tex_poly_margin = poly_margin / tex_pixels_per_unit;
+  float origin_y = bitmap_top / font_pixels_per_unit;
+  float origin_x = bitmap_left / font_pixels_per_unit;
+  float top = origin_y + tex_poly_margin;
+  float left = origin_x - tex_poly_margin;
+  float bottom = origin_y - _y_size / tex_pixels_per_unit - tex_poly_margin;
+  float right = origin_x + _x_size / tex_pixels_per_unit + tex_poly_margin;
 
 
   // And the corresponding corners in UV units.
   // And the corresponding corners in UV units.
   float uv_top = 1.0f - (float)(_y - poly_margin) / _page->get_y_size();
   float uv_top = 1.0f - (float)(_y - poly_margin) / _page->get_y_size();
@@ -162,7 +165,7 @@ make_geom(int bitmap_top, int bitmap_left,
   _state = RenderState::make(TextureAttrib::make(_page),
   _state = RenderState::make(TextureAttrib::make(_page),
                              TransparencyAttrib::make(TransparencyAttrib::M_alpha));
                              TransparencyAttrib::make(TransparencyAttrib::M_alpha));
 
 
-  _advance = advance / pixels_per_unit;
+  _advance = advance / font_pixels_per_unit;
 }
 }
 
 
 
 

+ 1 - 1
panda/src/text/dynamicTextGlyph.h

@@ -51,7 +51,7 @@ public:
   unsigned char *get_row(int y);
   unsigned char *get_row(int y);
   void erase();
   void erase();
   void make_geom(int top, int left, float advance, float poly_margin,
   void make_geom(int top, int left, float advance, float poly_margin,
-                 float pixels_per_unit);
+                 float font_pixels_per_unit, float tex_pixels_per_unit);
 
 
   DynamicTextPage *_page;
   DynamicTextPage *_page;
   int _geom_count;
   int _geom_count;