handle fixed-pixel-size fonts better

This commit is contained in:
David Rose 2003-09-13 01:05:12 +00:00
parent 832a96a639
commit 93384e8988
6 changed files with 137 additions and 24 deletions

View File

@ -71,7 +71,7 @@ get_point_size() const {
////////////////////////////////////////////////////////////////////
INLINE bool FreetypeFont::
set_pixels_per_unit(float pixels_per_unit) {
_tex_pixels_per_unit = pixels_per_unit;
_requested_pixels_per_unit = pixels_per_unit;
return reset_scale();
}
@ -128,7 +128,7 @@ get_pixel_size() const {
////////////////////////////////////////////////////////////////////
INLINE bool FreetypeFont::
set_scale_factor(float scale_factor) {
_scale_factor = scale_factor;
_requested_scale_factor = scale_factor;
return reset_scale();
}
@ -174,6 +174,24 @@ get_native_antialias() const {
return _native_antialias;
}
////////////////////////////////////////////////////////////////////
// Function: FreetypeFont::get_font_pixel_size
// Access: Public
// Description: This is used to report whether the requested pixel
// size is being only approximated by a fixed-pixel-size
// font. This returns 0 in the normal case, in which a
// scalable font is used, or the fixed-pixel-size font
// has exactly the requested pixel size.
//
// If this returns non-zero, it is the pixel size of the
// font that we are using to approximate our desired
// size.
////////////////////////////////////////////////////////////////////
INLINE int FreetypeFont::
get_font_pixel_size() const {
return _font_pixel_size;
}
////////////////////////////////////////////////////////////////////
// Function: FreetypeFont::get_line_height
// Access: Public

View File

@ -47,10 +47,13 @@ FreetypeFont() {
_font_loaded = false;
_point_size = text_point_size;
_requested_pixels_per_unit = text_pixels_per_unit;
_tex_pixels_per_unit = text_pixels_per_unit;
_requested_scale_factor = text_scale_factor;
_scale_factor = text_scale_factor;
_native_antialias = text_native_antialias;
_font_pixel_size = 0;
_line_height = 1.0f;
_space_advance = 0.25f;
@ -317,42 +320,57 @@ 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 and _tex_pixels_per_unit.
_tex_pixels_per_unit = _requested_pixels_per_unit;
_scale_factor = _requested_scale_factor;
_font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
float units_per_inch = (_points_per_inch / _points_per_unit);
int dpi = (int)(_font_pixels_per_unit * units_per_inch);
_font_pixel_size = 0;
int error = FT_Set_Char_Size(_face,
(int)(_point_size * 64), (int)(_point_size * 64),
dpi, dpi);
if (error) {
// If we were unable to set a particular char size, perhaps we
// have a non-scalable font. Try to figure out the closest
// available size.
// have a non-scalable font. Try to figure out the next larger
// available size, or the largest size available if nothing is
// larger.
int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
int best_size = -1;
int largest_size = -1;
if (_face->num_fixed_sizes > 0) {
best_size = 0;
int best_diff = abs(desired_height - _face->available_sizes[0].height);
for (int i = 1; i < _face->num_fixed_sizes; i++) {
int diff = abs(desired_height - _face->available_sizes[i].height);
if (diff < best_diff) {
largest_size = 0;
int best_diff = 0;
for (int i = 0; i < _face->num_fixed_sizes; i++) {
int diff = _face->available_sizes[i].height - desired_height;
if (diff > 0 && (best_size == -1 || diff < best_diff)) {
best_size = i;
best_diff = diff;
}
if (_face->available_sizes[i].height > _face->available_sizes[largest_size].height) {
largest_size = i;
}
}
}
if (best_size < 0) {
best_size = largest_size;
}
if (best_size >= 0) {
int pixel_height = _face->available_sizes[best_size].height;
int pixel_width = _face->available_sizes[best_size].width;
error = FT_Set_Pixel_Sizes(_face, pixel_width, pixel_height);
if (!error) {
pnmtext_cat.info()
<< "Using " << pixel_height << "-pixel font for "
<< get_name() << "\n";
_font_pixels_per_unit = pixel_height * _points_per_unit / _point_size;
_tex_pixels_per_unit = _font_pixels_per_unit;
_scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
_font_pixel_size = pixel_height;
if (_scale_factor < 1.0) {
// No point in enlarging a fixed-point font.
_scale_factor = 1.0;
_tex_pixels_per_unit = _font_pixels_per_unit;
}
}
}
}

View File

@ -67,6 +67,8 @@ public:
INLINE void set_native_antialias(bool native_antialias);
INLINE bool get_native_antialias() const;
INLINE int get_font_pixel_size() const;
INLINE float get_line_height() const;
INLINE float get_space_advance() const;
@ -84,11 +86,14 @@ private:
protected:
float _point_size;
float _requested_pixels_per_unit;
float _tex_pixels_per_unit;
float _requested_scale_factor;
float _scale_factor;
bool _native_antialias;
float _font_pixels_per_unit;
int _font_pixel_size;
float _line_height;
float _space_advance;

View File

@ -19,7 +19,7 @@
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::get_name
// Access: Public
// Access: Published
// Description: Disambiguates the get_name() method between that
// inherited from TextFont and that inherited from
// FreetypeFont.
@ -127,9 +127,61 @@ get_scale_factor() const {
return FreetypeFont::get_scale_factor();
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::set_native_antialias
// Access: Published
// Description: Sets whether the Freetype library's built-in
// antialias mode is enabled. There are two unrelated
// ways to achieve antialiasing: with Freetype's native
// antialias mode, and with the use of a scale_factor
// greater than one. By default, both modes are
// enabled.
//
// At low resolutions, some fonts may do better with one
// mode or the other. In general, Freetype's native
// antialiasing will produce less blurry results, but
// may introduce more artifacts.
////////////////////////////////////////////////////////////////////
INLINE void DynamicTextFont::
set_native_antialias(bool native_antialias) {
// If this assertion fails, you didn't call clear() first. RTFM.
nassertv(get_num_pages() == 0);
FreetypeFont::set_native_antialias(native_antialias);
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::get_native_antialias
// Access: Published
// Description: Returns whether Freetype's built-in antialias mode is
// enabled. See set_native_antialias().
////////////////////////////////////////////////////////////////////
INLINE bool DynamicTextFont::
get_native_antialias() const {
return FreetypeFont::get_native_antialias();
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::get_font_pixel_size
// Access: Published
// Description: This is used to report whether the requested pixel
// size is being only approximated by a fixed-pixel-size
// font. This returns 0 in the normal case, in which a
// scalable font is used, or the fixed-pixel-size font
// has exactly the requested pixel size.
//
// If this returns non-zero, it is the pixel size of the
// font that we are using to approximate our desired
// size.
////////////////////////////////////////////////////////////////////
INLINE int DynamicTextFont::
get_font_pixel_size() const {
return FreetypeFont::get_font_pixel_size();
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::get_line_height
// Access: Public
// Access: Published
// Description: Returns the number of units high each line of text
// is.
////////////////////////////////////////////////////////////////////
@ -140,7 +192,7 @@ get_line_height() const {
////////////////////////////////////////////////////////////////////
// Function: DynamicTextFont::get_space_advance
// Access: Public
// Access: Published
// Description: Returns the number of units wide a space is.
////////////////////////////////////////////////////////////////////
INLINE float DynamicTextFont::

View File

@ -60,6 +60,11 @@ PUBLISHED:
INLINE bool set_scale_factor(float scale_factor);
INLINE float get_scale_factor() const;
INLINE void set_native_antialias(bool native_antialias);
INLINE bool get_native_antialias() const;
INLINE int get_font_pixel_size() const;
INLINE float get_line_height() const;
INLINE float get_space_advance() const;

View File

@ -248,8 +248,27 @@ run() {
}
}
_text_maker->set_point_size(_point_size);
_text_maker->set_native_antialias(!_no_native_aa);
_text_maker->set_interior_flag(_got_interior);
_text_maker->set_pixels_per_unit(_pixels_per_unit);
_text_maker->set_scale_factor(_scale_factor);
// The text_maker may have had to adjust the pixels per unit and the
// scale factor according to what the font supports.
_pixels_per_unit = _text_maker->get_pixels_per_unit();
_scale_factor = _text_maker->get_scale_factor();
if (_text_maker->get_font_pixel_size() != 0) {
nout << "Using " << _text_maker->get_font_pixel_size() << "-pixel font.\n";
}
// Now we may want to tweak the scale factor so that fonts will
// actually be generated big. We have to do this after we have
// already send the current _scale_factor through the _text_maker
// for validation.
_palettize_scale_factor = _scale_factor;
if (_no_reduce || !_no_palettize) {
if (_scale_factor != 1.0 && (_no_reduce || !_no_palettize)) {
// If _no_reduce is true (-nr was specified), we want to keep the
// glyph textures full-sized, because the user asked for that.
@ -261,6 +280,8 @@ run() {
_poly_margin *= _scale_factor;
_pixels_per_unit *= _scale_factor;
_scale_factor = 1.0;
_text_maker->set_pixels_per_unit(_pixels_per_unit);
_text_maker->set_scale_factor(1.0);
}
if (_no_reduce) {
@ -272,12 +293,6 @@ run() {
_palettize_scale_factor = 1.0;
}
_text_maker->set_point_size(_point_size);
_text_maker->set_native_antialias(!_no_native_aa);
_text_maker->set_interior_flag(_got_interior);
_text_maker->set_pixels_per_unit(_pixels_per_unit);
_text_maker->set_scale_factor(_scale_factor);
if (_range.is_empty()) {
// If there's no specified range, the default is the entire ASCII
// set.