Skip to content

Commit

Permalink
font: Reimplement font::get_max_height() using Pango
Browse files Browse the repository at this point in the history
A few caveats:

 * This implementation allows configuring the font family class and
   style to select the correct font for any given context. The default
   values are equivalent to what was being done in the SDL_ttf-based
   version, but not future-proof. Users like the GUI2 textbox should
   make use of the new optional parameters to select a more relevant
   font going forward (not part of this commit).

 * Pango has a line height metric, equivalent to SDL_ttf's
   TTF_FontLineSkip(). However, this is not what we want here -- the
   ascender + descender formula is intended to give us a neat box where
   the tallest glyph can fit, not the minimum distance between
   baselines. This is important for the GUI2 textbox in particular.

 * The internal implementation uses the default text renderer and sets
   relevant parameters. This should not introduce new issues, but if it
   does then that means someone is not resetting the renderer properly
   before using it.

This notably rids GUI2 of its one known dependency on SDL_ttf.
  • Loading branch information
irydacea committed Mar 13, 2021
1 parent 0024cfa commit 66659e0
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 12 deletions.
9 changes: 0 additions & 9 deletions src/font/sdl_ttf.cpp
Expand Up @@ -352,15 +352,6 @@ SDL_Rect draw_text_line(surface& gui_surface, const SDL_Rect& area, int size,
return dest;
}

int get_max_height(int size)
{
// Only returns the maximal size of the first font
const auto font = sdl_ttf::get_font(font_id(0, size));
if(font == nullptr)
return 0;
return TTF_FontHeight(font.get());
}

int line_width(const std::string& line, int font_size, int style)
{
return line_size(line,font_size,style).w;
Expand Down
3 changes: 0 additions & 3 deletions src/font/sdl_ttf.hpp
Expand Up @@ -35,9 +35,6 @@ SDL_Rect draw_text_line(surface& gui_surface, const SDL_Rect& area, int size,
const color_t& color, const std::string& text,
int x, int y, bool use_tooltips, int style);

// Returns the maximum height of a font, in pixels
int get_max_height(int size);

/**
* Determine the width of a line of text given a certain font size.
* The font type used is the default wesnoth font type.
Expand Down
30 changes: 30 additions & 0 deletions src/font/text.cpp
Expand Up @@ -477,6 +477,26 @@ pango_text& pango_text::set_add_outline(bool do_add)
return *this;
}

int pango_text::get_max_glyph_height() const
{
p_font font{ get_font_families(font_class_), font_size_, font_style_ };

PangoFont* f = pango_font_map_load_font(
pango_cairo_font_map_get_default(),
context_.get(),
font.get());

PangoFontMetrics* m = pango_font_get_metrics(f, nullptr);

auto ascent = pango_font_metrics_get_ascent(m);
auto descent = pango_font_metrics_get_descent(m);

pango_font_metrics_unref(m);
g_object_unref(f);

return ceil(pango_units_to_double(ascent + descent));
}

void pango_text::recalculate(const bool force) const
{
if(calculation_dirty_ || force) {
Expand Down Expand Up @@ -900,4 +920,14 @@ pango_text& get_text_renderer()
return text_renderer;
}

int get_max_height(unsigned size, font::family_class fclass, pango_text::FONT_STYLE style)
{
// Reset metrics to defaults
return get_text_renderer()
.set_family_class(fclass)
.set_font_style(style)
.set_font_size(size)
.get_max_glyph_height();
}

} // namespace font
22 changes: 22 additions & 0 deletions src/font/text.hpp
Expand Up @@ -143,6 +143,15 @@ class pango_text

/***** ***** ***** ***** Query details ***** ***** ***** *****/

/**
* Returns the maximum glyph height of a font, in pixels.
*
* @returns The height of the tallest possible glyph for the selected
* font. More specifically, the result is the sum of the maximum
* ascent and descent lengths.
*/
int get_max_glyph_height() const;

/**
* Gets the location for the cursor.
*
Expand Down Expand Up @@ -431,4 +440,17 @@ class pango_text
*/
pango_text& get_text_renderer();

/**
* Returns the maximum glyph height of a font, in pixels.
*
* @param size Desired font size in pixels.
* @param fclass Font family to use for measurement.
* @param style Font style to select the correct variant for measurement.
*
* @returns The height of the tallest possible glyph for the selected
* font. More specifically, the result is the sum of the maximum
* ascent and descent lengths.
*/
int get_max_height(unsigned size, font::family_class fclass = font::FONT_SANS_SERIF, pango_text::FONT_STYLE style = pango_text::STYLE_NORMAL);

} // namespace font

0 comments on commit 66659e0

Please sign in to comment.