Skip to content

Commit 93384e8

Browse files
committed
handle fixed-pixel-size fonts better
1 parent 832a96a commit 93384e8

File tree

6 files changed

+137
-24
lines changed

6 files changed

+137
-24
lines changed

panda/src/pnmtext/freetypeFont.I

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ get_point_size() const {
7171
////////////////////////////////////////////////////////////////////
7272
INLINE bool FreetypeFont::
7373
set_pixels_per_unit(float pixels_per_unit) {
74-
_tex_pixels_per_unit = pixels_per_unit;
74+
_requested_pixels_per_unit = pixels_per_unit;
7575
return reset_scale();
7676
}
7777

@@ -128,7 +128,7 @@ get_pixel_size() const {
128128
////////////////////////////////////////////////////////////////////
129129
INLINE bool FreetypeFont::
130130
set_scale_factor(float scale_factor) {
131-
_scale_factor = scale_factor;
131+
_requested_scale_factor = scale_factor;
132132
return reset_scale();
133133
}
134134

@@ -174,6 +174,24 @@ get_native_antialias() const {
174174
return _native_antialias;
175175
}
176176

177+
////////////////////////////////////////////////////////////////////
178+
// Function: FreetypeFont::get_font_pixel_size
179+
// Access: Public
180+
// Description: This is used to report whether the requested pixel
181+
// size is being only approximated by a fixed-pixel-size
182+
// font. This returns 0 in the normal case, in which a
183+
// scalable font is used, or the fixed-pixel-size font
184+
// has exactly the requested pixel size.
185+
//
186+
// If this returns non-zero, it is the pixel size of the
187+
// font that we are using to approximate our desired
188+
// size.
189+
////////////////////////////////////////////////////////////////////
190+
INLINE int FreetypeFont::
191+
get_font_pixel_size() const {
192+
return _font_pixel_size;
193+
}
194+
177195
////////////////////////////////////////////////////////////////////
178196
// Function: FreetypeFont::get_line_height
179197
// Access: Public

panda/src/pnmtext/freetypeFont.cxx

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,13 @@ FreetypeFont() {
4747
_font_loaded = false;
4848

4949
_point_size = text_point_size;
50+
_requested_pixels_per_unit = text_pixels_per_unit;
5051
_tex_pixels_per_unit = text_pixels_per_unit;
52+
_requested_scale_factor = text_scale_factor;
5153
_scale_factor = text_scale_factor;
5254
_native_antialias = text_native_antialias;
5355

56+
_font_pixel_size = 0;
5457
_line_height = 1.0f;
5558
_space_advance = 0.25f;
5659

@@ -317,42 +320,57 @@ reset_scale() {
317320
// The font may be rendered larger (by a factor of _scale_factor),
318321
// and then reduced into the texture. Hence the difference between
319322
// _font_pixels_per_unit and _tex_pixels_per_unit.
323+
_tex_pixels_per_unit = _requested_pixels_per_unit;
324+
_scale_factor = _requested_scale_factor;
320325
_font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
321326

322327
float units_per_inch = (_points_per_inch / _points_per_unit);
323328
int dpi = (int)(_font_pixels_per_unit * units_per_inch);
324329

330+
_font_pixel_size = 0;
325331
int error = FT_Set_Char_Size(_face,
326332
(int)(_point_size * 64), (int)(_point_size * 64),
327333
dpi, dpi);
328334
if (error) {
329335
// If we were unable to set a particular char size, perhaps we
330-
// have a non-scalable font. Try to figure out the closest
331-
// available size.
336+
// have a non-scalable font. Try to figure out the next larger
337+
// available size, or the largest size available if nothing is
338+
// larger.
332339
int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
333340
int best_size = -1;
341+
int largest_size = -1;
334342
if (_face->num_fixed_sizes > 0) {
335-
best_size = 0;
336-
int best_diff = abs(desired_height - _face->available_sizes[0].height);
337-
for (int i = 1; i < _face->num_fixed_sizes; i++) {
338-
int diff = abs(desired_height - _face->available_sizes[i].height);
339-
if (diff < best_diff) {
343+
largest_size = 0;
344+
int best_diff = 0;
345+
for (int i = 0; i < _face->num_fixed_sizes; i++) {
346+
int diff = _face->available_sizes[i].height - desired_height;
347+
if (diff > 0 && (best_size == -1 || diff < best_diff)) {
340348
best_size = i;
341349
best_diff = diff;
342350
}
351+
if (_face->available_sizes[i].height > _face->available_sizes[largest_size].height) {
352+
largest_size = i;
353+
}
343354
}
344355
}
356+
if (best_size < 0) {
357+
best_size = largest_size;
358+
}
359+
345360
if (best_size >= 0) {
346361
int pixel_height = _face->available_sizes[best_size].height;
347362
int pixel_width = _face->available_sizes[best_size].width;
348363
error = FT_Set_Pixel_Sizes(_face, pixel_width, pixel_height);
349364
if (!error) {
350-
pnmtext_cat.info()
351-
<< "Using " << pixel_height << "-pixel font for "
352-
<< get_name() << "\n";
353-
354365
_font_pixels_per_unit = pixel_height * _points_per_unit / _point_size;
355-
_tex_pixels_per_unit = _font_pixels_per_unit;
366+
_scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
367+
_font_pixel_size = pixel_height;
368+
369+
if (_scale_factor < 1.0) {
370+
// No point in enlarging a fixed-point font.
371+
_scale_factor = 1.0;
372+
_tex_pixels_per_unit = _font_pixels_per_unit;
373+
}
356374
}
357375
}
358376
}

panda/src/pnmtext/freetypeFont.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class EXPCL_PANDA FreetypeFont : public Namable {
6767
INLINE void set_native_antialias(bool native_antialias);
6868
INLINE bool get_native_antialias() const;
6969

70+
INLINE int get_font_pixel_size() const;
71+
7072
INLINE float get_line_height() const;
7173
INLINE float get_space_advance() const;
7274

@@ -84,11 +86,14 @@ class EXPCL_PANDA FreetypeFont : public Namable {
8486

8587
protected:
8688
float _point_size;
89+
float _requested_pixels_per_unit;
8790
float _tex_pixels_per_unit;
91+
float _requested_scale_factor;
8892
float _scale_factor;
8993
bool _native_antialias;
9094
float _font_pixels_per_unit;
9195

96+
int _font_pixel_size;
9297
float _line_height;
9398
float _space_advance;
9499

panda/src/text/dynamicTextFont.I

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
////////////////////////////////////////////////////////////////////
2121
// Function: DynamicTextFont::get_name
22-
// Access: Public
22+
// Access: Published
2323
// Description: Disambiguates the get_name() method between that
2424
// inherited from TextFont and that inherited from
2525
// FreetypeFont.
@@ -127,9 +127,61 @@ get_scale_factor() const {
127127
return FreetypeFont::get_scale_factor();
128128
}
129129

130+
////////////////////////////////////////////////////////////////////
131+
// Function: DynamicTextFont::set_native_antialias
132+
// Access: Published
133+
// Description: Sets whether the Freetype library's built-in
134+
// antialias mode is enabled. There are two unrelated
135+
// ways to achieve antialiasing: with Freetype's native
136+
// antialias mode, and with the use of a scale_factor
137+
// greater than one. By default, both modes are
138+
// enabled.
139+
//
140+
// At low resolutions, some fonts may do better with one
141+
// mode or the other. In general, Freetype's native
142+
// antialiasing will produce less blurry results, but
143+
// may introduce more artifacts.
144+
////////////////////////////////////////////////////////////////////
145+
INLINE void DynamicTextFont::
146+
set_native_antialias(bool native_antialias) {
147+
// If this assertion fails, you didn't call clear() first. RTFM.
148+
nassertv(get_num_pages() == 0);
149+
150+
FreetypeFont::set_native_antialias(native_antialias);
151+
}
152+
153+
////////////////////////////////////////////////////////////////////
154+
// Function: DynamicTextFont::get_native_antialias
155+
// Access: Published
156+
// Description: Returns whether Freetype's built-in antialias mode is
157+
// enabled. See set_native_antialias().
158+
////////////////////////////////////////////////////////////////////
159+
INLINE bool DynamicTextFont::
160+
get_native_antialias() const {
161+
return FreetypeFont::get_native_antialias();
162+
}
163+
164+
////////////////////////////////////////////////////////////////////
165+
// Function: DynamicTextFont::get_font_pixel_size
166+
// Access: Published
167+
// Description: This is used to report whether the requested pixel
168+
// size is being only approximated by a fixed-pixel-size
169+
// font. This returns 0 in the normal case, in which a
170+
// scalable font is used, or the fixed-pixel-size font
171+
// has exactly the requested pixel size.
172+
//
173+
// If this returns non-zero, it is the pixel size of the
174+
// font that we are using to approximate our desired
175+
// size.
176+
////////////////////////////////////////////////////////////////////
177+
INLINE int DynamicTextFont::
178+
get_font_pixel_size() const {
179+
return FreetypeFont::get_font_pixel_size();
180+
}
181+
130182
////////////////////////////////////////////////////////////////////
131183
// Function: DynamicTextFont::get_line_height
132-
// Access: Public
184+
// Access: Published
133185
// Description: Returns the number of units high each line of text
134186
// is.
135187
////////////////////////////////////////////////////////////////////
@@ -140,7 +192,7 @@ get_line_height() const {
140192

141193
////////////////////////////////////////////////////////////////////
142194
// Function: DynamicTextFont::get_space_advance
143-
// Access: Public
195+
// Access: Published
144196
// Description: Returns the number of units wide a space is.
145197
////////////////////////////////////////////////////////////////////
146198
INLINE float DynamicTextFont::

panda/src/text/dynamicTextFont.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class EXPCL_PANDA DynamicTextFont : public TextFont, public FreetypeFont {
6060
INLINE bool set_scale_factor(float scale_factor);
6161
INLINE float get_scale_factor() const;
6262

63+
INLINE void set_native_antialias(bool native_antialias);
64+
INLINE bool get_native_antialias() const;
65+
66+
INLINE int get_font_pixel_size() const;
67+
6368
INLINE float get_line_height() const;
6469
INLINE float get_space_advance() const;
6570

pandatool/src/egg-mkfont/eggMakeFont.cxx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,27 @@ run() {
248248
}
249249
}
250250

251+
_text_maker->set_point_size(_point_size);
252+
_text_maker->set_native_antialias(!_no_native_aa);
253+
_text_maker->set_interior_flag(_got_interior);
254+
_text_maker->set_pixels_per_unit(_pixels_per_unit);
255+
_text_maker->set_scale_factor(_scale_factor);
256+
257+
// The text_maker may have had to adjust the pixels per unit and the
258+
// scale factor according to what the font supports.
259+
_pixels_per_unit = _text_maker->get_pixels_per_unit();
260+
_scale_factor = _text_maker->get_scale_factor();
261+
262+
if (_text_maker->get_font_pixel_size() != 0) {
263+
nout << "Using " << _text_maker->get_font_pixel_size() << "-pixel font.\n";
264+
}
265+
266+
// Now we may want to tweak the scale factor so that fonts will
267+
// actually be generated big. We have to do this after we have
268+
// already send the current _scale_factor through the _text_maker
269+
// for validation.
251270
_palettize_scale_factor = _scale_factor;
252-
if (_no_reduce || !_no_palettize) {
271+
if (_scale_factor != 1.0 && (_no_reduce || !_no_palettize)) {
253272
// If _no_reduce is true (-nr was specified), we want to keep the
254273
// glyph textures full-sized, because the user asked for that.
255274

@@ -261,6 +280,8 @@ run() {
261280
_poly_margin *= _scale_factor;
262281
_pixels_per_unit *= _scale_factor;
263282
_scale_factor = 1.0;
283+
_text_maker->set_pixels_per_unit(_pixels_per_unit);
284+
_text_maker->set_scale_factor(1.0);
264285
}
265286

266287
if (_no_reduce) {
@@ -272,12 +293,6 @@ run() {
272293
_palettize_scale_factor = 1.0;
273294
}
274295

275-
_text_maker->set_point_size(_point_size);
276-
_text_maker->set_native_antialias(!_no_native_aa);
277-
_text_maker->set_interior_flag(_got_interior);
278-
_text_maker->set_pixels_per_unit(_pixels_per_unit);
279-
_text_maker->set_scale_factor(_scale_factor);
280-
281296
if (_range.is_empty()) {
282297
// If there's no specified range, the default is the entire ASCII
283298
// set.

0 commit comments

Comments
 (0)