refine dynamic font glyph placement

This commit is contained in:
David Rose 2002-12-03 18:30:45 +00:00
parent e6a55b9590
commit a31dd71369
3 changed files with 25 additions and 11 deletions

View File

@ -459,6 +459,9 @@ make_glyph(int glyph_index) {
} else { } else {
DynamicTextGlyph *glyph; DynamicTextGlyph *glyph;
float tex_x_size = bitmap.width;
float tex_y_size = bitmap.rows;
if (_tex_pixels_per_unit == _font_pixels_per_unit) { if (_tex_pixels_per_unit == _font_pixels_per_unit) {
// If the bitmap produced from the font doesn't require scaling // If the bitmap produced from the font doesn't require scaling
// before it goes to the texture, we can just copy it directly // before it goes to the texture, we can just copy it directly
@ -469,21 +472,27 @@ make_glyph(int glyph_index) {
} else { } else {
// Otherwise, we need to copy to a PNMImage first, so we can // Otherwise, we need to copy to a PNMImage first, so we can
// scale it; and then copy it to the texture from there. // scale it; and then copy it to the texture from there.
int tex_x_size = (int)(bitmap.width / _scale_factor + 0.5f); tex_x_size /= _scale_factor;
int tex_y_size = (int)(bitmap.rows / _scale_factor + 0.5f); tex_y_size /= _scale_factor;
glyph = slot_glyph(tex_x_size, tex_y_size); int int_x_size = (int)ceil(tex_x_size);
int int_y_size = (int)ceil(tex_y_size);
int bmp_x_size = (int)(int_x_size * _scale_factor + 0.5f);
int bmp_y_size = (int)(int_y_size * _scale_factor + 0.5f);
glyph = slot_glyph(int_x_size, int_y_size);
PNMImage image(bitmap.width, bitmap.rows, PNMImage::CT_grayscale); PNMImage image(bmp_x_size, bmp_y_size, PNMImage::CT_grayscale);
copy_bitmap_to_pnmimage(bitmap, image); copy_bitmap_to_pnmimage(bitmap, image);
PNMImage reduced(tex_x_size, tex_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);
copy_pnmimage_to_texture(reduced, glyph); copy_pnmimage_to_texture(reduced, glyph);
} }
glyph->_page->mark_dirty(Texture::DF_image); glyph->_page->mark_dirty(Texture::DF_image);
glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance, _poly_margin, glyph->make_geom(slot->bitmap_top, slot->bitmap_left,
advance, _poly_margin,
tex_x_size, tex_y_size,
_font_pixels_per_unit, _tex_pixels_per_unit); _font_pixels_per_unit, _tex_pixels_per_unit);
return glyph; return glyph;
} }

View File

@ -109,26 +109,30 @@ erase() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DynamicTextGlyph:: void DynamicTextGlyph::
make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin, make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin,
float tex_x_size, float tex_y_size,
float font_pixels_per_unit, float tex_pixels_per_unit) { 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);
tex_x_size += _margin * 2;
tex_y_size += _margin * 2;
// Determine the corners of the rectangle in geometric units. // Determine the corners of the rectangle in geometric units.
float tex_poly_margin = poly_margin / tex_pixels_per_unit; float tex_poly_margin = poly_margin / tex_pixels_per_unit;
float origin_y = bitmap_top / font_pixels_per_unit; float origin_y = bitmap_top / font_pixels_per_unit;
float origin_x = bitmap_left / font_pixels_per_unit; float origin_x = bitmap_left / font_pixels_per_unit;
float top = origin_y + tex_poly_margin; float top = origin_y + tex_poly_margin;
float left = origin_x - tex_poly_margin; float left = origin_x - tex_poly_margin;
float bottom = origin_y - _y_size / tex_pixels_per_unit - tex_poly_margin; float bottom = origin_y - tex_y_size / tex_pixels_per_unit - tex_poly_margin;
float right = origin_x + _x_size / tex_pixels_per_unit + tex_poly_margin; float right = origin_x + tex_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();
float uv_left = (float)(_x - poly_margin) / _page->get_x_size(); float uv_left = (float)(_x - poly_margin) / _page->get_x_size();
float uv_bottom = 1.0f - (float)(_y + _y_size + poly_margin) / _page->get_y_size(); float uv_bottom = 1.0f - (float)(_y + poly_margin + tex_y_size) / _page->get_y_size();
float uv_right = (float)(_x + _x_size + poly_margin) / _page->get_x_size(); float uv_right = (float)(_x + poly_margin + tex_x_size) / _page->get_x_size();
// Create a corresponding tristrip. // Create a corresponding tristrip.
_geom = new GeomTextGlyph(this); _geom = new GeomTextGlyph(this);

View File

@ -51,6 +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 tex_x_size, float tex_y_size,
float font_pixels_per_unit, float tex_pixels_per_unit); float font_pixels_per_unit, float tex_pixels_per_unit);
DynamicTextPage *_page; DynamicTextPage *_page;