mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-21 14:41:11 -04:00
refinements to DynamicText
This commit is contained in:
parent
f7bb229865
commit
c037a890dd
@ -18,7 +18,72 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::set_margin
|
// Function: DynamicTextFont::set_point_size
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the point size of the font. This controls the
|
||||||
|
// apparent size of the font onscreen. By convention, a
|
||||||
|
// 10 point font is about 1 screen unit high.
|
||||||
|
//
|
||||||
|
// This should only be called before any characters have
|
||||||
|
// been requested out of the font, or immediately after
|
||||||
|
// calling clear().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool DynamicTextFont::
|
||||||
|
set_point_size(float point_size) {
|
||||||
|
// If this assertion fails, you didn't call clear() first. RTFM.
|
||||||
|
nassertr(get_num_pages() == 0, false);
|
||||||
|
|
||||||
|
_point_size = point_size;
|
||||||
|
return reset_scale();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::get_point_size
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the point size of the font.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float DynamicTextFont::
|
||||||
|
get_point_size() const {
|
||||||
|
return _point_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::set_pixels_per_unit
|
||||||
|
// Access: Published
|
||||||
|
// Description: Set the resolution of the texture map, and hence the
|
||||||
|
// clarity of the resulting font. This sets the number
|
||||||
|
// of pixels in the texture map that are used for each
|
||||||
|
// onscreen unit.
|
||||||
|
//
|
||||||
|
// Setting this number larger results in an easier to
|
||||||
|
// read font, but at the cost of more texture memory.
|
||||||
|
//
|
||||||
|
// This should only be called before any characters have
|
||||||
|
// been requested out of the font, or immediately after
|
||||||
|
// calling clear().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool DynamicTextFont::
|
||||||
|
set_pixels_per_unit(float pixels_per_unit) {
|
||||||
|
// If this assertion fails, you didn't call clear() first. RTFM.
|
||||||
|
nassertr(get_num_pages() == 0, false);
|
||||||
|
|
||||||
|
_pixels_per_unit = pixels_per_unit;
|
||||||
|
return reset_scale();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::get_pixels_per_unit
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the resolution of the texture map. See
|
||||||
|
// set_pixels_per_unit().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float DynamicTextFont::
|
||||||
|
get_pixels_per_unit() const {
|
||||||
|
return _pixels_per_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::set_texture_margin
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets the number of pixels of padding that is added
|
// Description: Sets the number of pixels of padding that is added
|
||||||
// around the border of each glyph before adding it to
|
// around the border of each glyph before adding it to
|
||||||
@ -26,19 +91,48 @@
|
|||||||
// neighboring glyphs in the texture map.
|
// neighboring glyphs in the texture map.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void DynamicTextFont::
|
INLINE void DynamicTextFont::
|
||||||
set_margin(int margin) {
|
set_texture_margin(int texture_margin) {
|
||||||
_margin = margin;
|
_texture_margin = texture_margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::get_margin
|
// Function: DynamicTextFont::get_texture_margin
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the number of pixels of padding that is added
|
// Description: Returns the number of pixels of padding that is added
|
||||||
// around the border of each glyph. See set_margin().
|
// around the border of each glyph in the texture map.
|
||||||
|
// See set_texture_margin().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE int DynamicTextFont::
|
INLINE int DynamicTextFont::
|
||||||
get_margin() const {
|
get_texture_margin() const {
|
||||||
return _margin;
|
return _texture_margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::set_poly_margin
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the number of pixels of padding that is included
|
||||||
|
// around each glyph in the generated polygons. This
|
||||||
|
// helps prevent the edges of the glyphs from being cut
|
||||||
|
// off at small minifications. It is not related to the
|
||||||
|
// amount of extra pixels reserved in the texture map
|
||||||
|
// (but it should be no larger than this number, which
|
||||||
|
// is controlled by set_texture_margin()).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void DynamicTextFont::
|
||||||
|
set_poly_margin(float poly_margin) {
|
||||||
|
_poly_margin = poly_margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::get_poly_margin
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of pixels of padding that is
|
||||||
|
// included around each glyph in the generated polygons.
|
||||||
|
// See set_poly_margin().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float DynamicTextFont::
|
||||||
|
get_poly_margin() const {
|
||||||
|
return _poly_margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -43,23 +43,16 @@ static const float points_per_inch = 72.0f;
|
|||||||
// Description: The constructor expects the name of some font file
|
// Description: The constructor expects the name of some font file
|
||||||
// that FreeType can read, along with face_index,
|
// that FreeType can read, along with face_index,
|
||||||
// indicating which font within the file to load
|
// indicating which font within the file to load
|
||||||
// (usually 0), the point size of the font, and the
|
// (usually 0).
|
||||||
// resolution at which to generate the font.
|
|
||||||
//
|
|
||||||
// The choice of point size affects the apparent size of
|
|
||||||
// the generated characters (as well as the clarity),
|
|
||||||
// while the pixels_per_unit affects only the clarity.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
DynamicTextFont::
|
DynamicTextFont::
|
||||||
DynamicTextFont(const Filename &font_filename, int face_index,
|
DynamicTextFont(const Filename &font_filename, int face_index) {
|
||||||
float point_size, float pixels_per_unit) {
|
_texture_margin = 2;
|
||||||
_margin = 2;
|
_poly_margin = 1.0f;
|
||||||
_page_x_size = 256;
|
_page_x_size = 256;
|
||||||
_page_y_size = 256;
|
_page_y_size = 256;
|
||||||
_pixels_per_unit = pixels_per_unit;
|
_point_size = 10.0f;
|
||||||
|
_pixels_per_unit = 40.0f;
|
||||||
float units_per_inch = (points_per_inch / points_per_unit);
|
|
||||||
int dpi = (int)(_pixels_per_unit * units_per_inch);
|
|
||||||
|
|
||||||
if (!_ft_initialized) {
|
if (!_ft_initialized) {
|
||||||
initialize_ft_library();
|
initialize_ft_library();
|
||||||
@ -90,23 +83,16 @@ DynamicTextFont(const Filename &font_filename, int face_index,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
string name = _face->family_name;
|
string name = _face->family_name;
|
||||||
|
if (_face->style_name != NULL) {
|
||||||
name += " ";
|
name += " ";
|
||||||
name += _face->style_name;
|
name += _face->style_name;
|
||||||
|
}
|
||||||
_is_valid = true;
|
|
||||||
set_name(name);
|
set_name(name);
|
||||||
|
|
||||||
text_cat.info()
|
text_cat.info()
|
||||||
<< "Loaded font " << get_name() << "\n";
|
<< "Loaded font " << get_name() << "\n";
|
||||||
|
_is_valid = true;
|
||||||
error = FT_Set_Char_Size(_face,
|
reset_scale();
|
||||||
(int)(point_size * 64), (int)(point_size * 64),
|
|
||||||
dpi, dpi);
|
|
||||||
if (error) {
|
|
||||||
text_cat.warning()
|
|
||||||
<< "Unable to set point size of " << get_name()
|
|
||||||
<< " to " << point_size << " at " << dpi << " dots per inch.\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,6 +128,25 @@ get_page(int n) const {
|
|||||||
return _pages[n];
|
return _pages[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::clear
|
||||||
|
// Access: Published
|
||||||
|
// Description: Drops all the glyphs out of the cache and frees any
|
||||||
|
// association with any previously-generated pages.
|
||||||
|
//
|
||||||
|
// Calling this frequently can result in wasted texture
|
||||||
|
// memory, as any previously rendered text will still
|
||||||
|
// keep a pointer to the old, previously-generated
|
||||||
|
// pages. As long as the previously rendered text
|
||||||
|
// remains around, the old pages will also remain
|
||||||
|
// around.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DynamicTextFont::
|
||||||
|
clear() {
|
||||||
|
_pages.clear();
|
||||||
|
_cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::write
|
// Function: DynamicTextFont::write
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -150,7 +155,9 @@ get_page(int n) const {
|
|||||||
void DynamicTextFont::
|
void DynamicTextFont::
|
||||||
write(ostream &out, int indent_level) const {
|
write(ostream &out, int indent_level) const {
|
||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "DynamicTextFont " << get_name() << ".\n";
|
<< "DynamicTextFont " << get_name() << ", "
|
||||||
|
<< _cache.size() << " glyphs, "
|
||||||
|
<< get_num_pages() << " pages.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -165,11 +172,46 @@ get_glyph(int character) {
|
|||||||
if (ci != _cache.end()) {
|
if (ci != _cache.end()) {
|
||||||
return (*ci).second;
|
return (*ci).second;
|
||||||
}
|
}
|
||||||
|
if (!_is_valid) {
|
||||||
|
return (TextGlyph *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DynamicTextGlyph *glyph = make_glyph(character);
|
DynamicTextGlyph *glyph = make_glyph(character);
|
||||||
_cache.insert(Cache::value_type(character, glyph));
|
_cache.insert(Cache::value_type(character, glyph));
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::reset_scale
|
||||||
|
// Access: Private
|
||||||
|
// Description: Resets the font to use the current _point_size and
|
||||||
|
// _pixels_per_unit. Returns true if successful, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DynamicTextFont::
|
||||||
|
reset_scale() {
|
||||||
|
float units_per_inch = (points_per_inch / points_per_unit);
|
||||||
|
int dpi = (int)(_pixels_per_unit * units_per_inch);
|
||||||
|
|
||||||
|
int error = FT_Set_Char_Size(_face,
|
||||||
|
(int)(_point_size * 64), (int)(_point_size * 64),
|
||||||
|
dpi, dpi);
|
||||||
|
if (error) {
|
||||||
|
text_cat.warning()
|
||||||
|
<< "Unable to set " << get_name()
|
||||||
|
<< " to " << _point_size << "pt at " << dpi << " dpi.\n";
|
||||||
|
_line_height = 1.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The face's height is only relevant for scalable fonts,
|
||||||
|
// according to FreeType. How should we determine whether we
|
||||||
|
// have a scalable font or otherwise?
|
||||||
|
float pixel_size = _point_size * (_pixels_per_unit / points_per_unit);
|
||||||
|
_line_height = (float)_face->height * pixel_size / ((float)_face->units_per_EM * 64.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::make_glyph
|
// Function: DynamicTextFont::make_glyph
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -217,7 +259,7 @@ make_glyph(int character) {
|
|||||||
|
|
||||||
float advance = slot->advance.x / 64.0;
|
float advance = slot->advance.x / 64.0;
|
||||||
glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance,
|
glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance,
|
||||||
_pixels_per_unit);
|
_poly_margin, _pixels_per_unit);
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,14 +275,14 @@ make_glyph(int character) {
|
|||||||
DynamicTextGlyph *DynamicTextFont::
|
DynamicTextGlyph *DynamicTextFont::
|
||||||
slot_glyph(int x_size, int y_size) {
|
slot_glyph(int x_size, int y_size) {
|
||||||
// Increase the indicated size by the current margin.
|
// Increase the indicated size by the current margin.
|
||||||
x_size += _margin * 2;
|
x_size += _texture_margin * 2;
|
||||||
y_size += _margin * 2;
|
y_size += _texture_margin * 2;
|
||||||
|
|
||||||
Pages::iterator pi;
|
Pages::iterator pi;
|
||||||
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
|
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
|
||||||
DynamicTextPage *page = (*pi);
|
DynamicTextPage *page = (*pi);
|
||||||
|
|
||||||
DynamicTextGlyph *glyph = page->slot_glyph(x_size, y_size, _margin);
|
DynamicTextGlyph *glyph = page->slot_glyph(x_size, y_size, _texture_margin);
|
||||||
if (glyph != (DynamicTextGlyph *)NULL) {
|
if (glyph != (DynamicTextGlyph *)NULL) {
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
@ -257,7 +299,7 @@ slot_glyph(int x_size, int y_size) {
|
|||||||
// We need to make a new page.
|
// We need to make a new page.
|
||||||
PT(DynamicTextPage) page = new DynamicTextPage(this);
|
PT(DynamicTextPage) page = new DynamicTextPage(this);
|
||||||
_pages.push_back(page);
|
_pages.push_back(page);
|
||||||
return page->slot_glyph(x_size, y_size, _margin);
|
return page->slot_glyph(x_size, y_size, _texture_margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,11 +44,18 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA DynamicTextFont : public TextFont {
|
class EXPCL_PANDA DynamicTextFont : public TextFont {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
DynamicTextFont(const Filename &font_filename, int face_index,
|
DynamicTextFont(const Filename &font_filename, int face_index = 0);
|
||||||
float point_size, float pixels_per_unit);
|
|
||||||
|
|
||||||
INLINE void set_margin(int margin);
|
INLINE bool set_point_size(float point_size);
|
||||||
INLINE int get_margin() const;
|
INLINE float get_point_size() const;
|
||||||
|
|
||||||
|
INLINE bool set_pixels_per_unit(float pixels_per_unit);
|
||||||
|
INLINE float get_pixels_per_unit() const;
|
||||||
|
|
||||||
|
INLINE void set_texture_margin(int texture_margin);
|
||||||
|
INLINE int get_texture_margin() const;
|
||||||
|
INLINE void set_poly_margin(float poly_margin);
|
||||||
|
INLINE float get_poly_margin() const;
|
||||||
|
|
||||||
INLINE void set_page_size(int x_size, int y_size);
|
INLINE void set_page_size(int x_size, int y_size);
|
||||||
INLINE int get_page_x_size() const;
|
INLINE int get_page_x_size() const;
|
||||||
@ -57,20 +64,25 @@ PUBLISHED:
|
|||||||
int get_num_pages() const;
|
int get_num_pages() const;
|
||||||
DynamicTextPage *get_page(int n) const;
|
DynamicTextPage *get_page(int n) const;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual const TextGlyph *get_glyph(int character);
|
virtual const TextGlyph *get_glyph(int character);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool reset_scale();
|
||||||
DynamicTextGlyph *make_glyph(int character);
|
DynamicTextGlyph *make_glyph(int character);
|
||||||
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();
|
||||||
|
|
||||||
int _margin;
|
float _point_size;
|
||||||
int _page_x_size, _page_y_size;
|
|
||||||
float _pixels_per_unit;
|
float _pixels_per_unit;
|
||||||
|
int _texture_margin;
|
||||||
|
float _poly_margin;
|
||||||
|
int _page_x_size, _page_y_size;
|
||||||
|
|
||||||
typedef pvector< PT(DynamicTextPage) > Pages;
|
typedef pvector< PT(DynamicTextPage) > Pages;
|
||||||
Pages _pages;
|
Pages _pages;
|
||||||
|
@ -63,18 +63,18 @@ get_row(int y) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void DynamicTextGlyph::
|
void DynamicTextGlyph::
|
||||||
make_geom(int bitmap_top, int bitmap_left,
|
make_geom(int bitmap_top, int bitmap_left,
|
||||||
float advance, float pixels_per_unit) {
|
float advance, float poly_margin, float pixels_per_unit) {
|
||||||
// Determine the corners of the rectangle in geometric units.
|
// Determine the corners of the rectangle in geometric units.
|
||||||
float top = (bitmap_top + _margin) / pixels_per_unit;
|
float top = (bitmap_top + poly_margin) / pixels_per_unit;
|
||||||
float left = (bitmap_left - _margin) / pixels_per_unit;
|
float left = (bitmap_left - poly_margin) / pixels_per_unit;
|
||||||
float bottom = (bitmap_top - _y_size - _margin) / pixels_per_unit;
|
float bottom = (bitmap_top - _y_size - poly_margin) / pixels_per_unit;
|
||||||
float right = (bitmap_left + _x_size + _margin) / pixels_per_unit;
|
float right = (bitmap_left + _x_size + poly_margin) / pixels_per_unit;
|
||||||
|
|
||||||
// And the corresponding corners in UV units.
|
// And the corresponding corners in UV units.
|
||||||
float uv_top = 1.0f - (float)_y / _page->get_y_size();
|
float uv_top = 1.0f - (float)(_y - poly_margin) / _page->get_y_size();
|
||||||
float uv_left = (float)_x / _page->get_x_size();
|
float uv_left = (float)(_x - poly_margin) / _page->get_x_size();
|
||||||
float uv_bottom = 1.0f - (float)(_y + _y_size) / _page->get_y_size();
|
float uv_bottom = 1.0f - (float)(_y + _y_size + poly_margin) / _page->get_y_size();
|
||||||
float uv_right = (float)(_x + _x_size) / _page->get_x_size();
|
float uv_right = (float)(_x + _x_size + poly_margin) / _page->get_x_size();
|
||||||
|
|
||||||
// Create a corresponding tristrip.
|
// Create a corresponding tristrip.
|
||||||
_geom = new GeomTristrip;
|
_geom = new GeomTristrip;
|
||||||
|
@ -41,7 +41,8 @@ public:
|
|||||||
|
|
||||||
INLINE bool intersects(int x, int y, int x_size, int y_size) const;
|
INLINE bool intersects(int x, int y, int x_size, int y_size) const;
|
||||||
unsigned char *get_row(int y);
|
unsigned char *get_row(int y);
|
||||||
void make_geom(int top, int left, float advance, float pixels_per_unit);
|
void make_geom(int top, int left, float advance, float poly_margin,
|
||||||
|
float pixels_per_unit);
|
||||||
|
|
||||||
DynamicTextPage *_page;
|
DynamicTextPage *_page;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user