handle fixed-pixel-size fonts better
This commit is contained in:
parent
832a96a639
commit
93384e8988
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue