1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:57:34 +00:00

LibVT: Compute the font metrics once and cache them

The height of a line or column doesn't change unless the font changes,
and we were already caching the line height. This patch extends it so
we also cache the column width.
This commit is contained in:
Andreas Kling 2023-01-05 13:12:50 +01:00
parent b4946eac6e
commit 2e1b8b90f4
2 changed files with 29 additions and 10 deletions

View file

@ -121,7 +121,7 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy)
else else
set_font(Gfx::FontDatabase::the().get_by_name(font_entry)); set_font(Gfx::FontDatabase::the().get_by_name(font_entry));
m_line_height = font().glyph_height() + m_line_spacing; update_cached_font_metrics();
m_terminal.set_size(Config::read_i32("Terminal"sv, "Window"sv, "Width"sv, 80), Config::read_i32("Terminal"sv, "Window"sv, "Height"sv, 25)); m_terminal.set_size(Config::read_i32("Terminal"sv, "Window"sv, "Width"sv, 80), Config::read_i32("Terminal"sv, "Window"sv, "Height"sv, 25));
@ -153,14 +153,14 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy)
Gfx::IntRect TerminalWidget::glyph_rect(u16 row, u16 column) Gfx::IntRect TerminalWidget::glyph_rect(u16 row, u16 column)
{ {
int y = row * m_line_height; int y = row * m_line_height;
int x = column * font().glyph_width('x'); int x = column * m_column_width;
return { x + frame_thickness() + m_inset, y + frame_thickness() + m_inset, static_cast<int>(ceilf(font().glyph_width('x'))), font().glyph_height() }; return { x + frame_thickness() + m_inset, y + frame_thickness() + m_inset, m_column_width, font().glyph_height() };
} }
Gfx::IntRect TerminalWidget::row_rect(u16 row) Gfx::IntRect TerminalWidget::row_rect(u16 row)
{ {
int y = row * m_line_height; int y = row * m_line_height;
Gfx::IntRect rect = { frame_thickness() + m_inset, y + frame_thickness() + m_inset, static_cast<int>(ceilf(font().glyph_width('x'))) * m_terminal.columns(), font().glyph_height() }; Gfx::IntRect rect = { frame_thickness() + m_inset, y + frame_thickness() + m_inset, m_column_width * m_terminal.columns(), font().glyph_height() };
rect.inflate(0, m_line_spacing); rect.inflate(0, m_line_spacing);
return rect; return rect;
} }
@ -511,7 +511,7 @@ void TerminalWidget::relayout(Gfx::IntSize size)
TemporaryChange change(m_in_relayout, true); TemporaryChange change(m_in_relayout, true);
auto base_size = compute_base_size(); auto base_size = compute_base_size();
int new_columns = (size.width() - base_size.width()) / font().glyph_width('x'); int new_columns = (size.width() - base_size.width()) / m_column_width;
int new_rows = (size.height() - base_size.height()) / m_line_height; int new_rows = (size.height() - base_size.height()) / m_line_height;
m_terminal.set_size(new_columns, new_rows); m_terminal.set_size(new_columns, new_rows);
@ -534,7 +534,7 @@ Gfx::IntSize TerminalWidget::compute_base_size() const
void TerminalWidget::apply_size_increments_to_window(GUI::Window& window) void TerminalWidget::apply_size_increments_to_window(GUI::Window& window)
{ {
window.set_size_increment({ static_cast<int>(ceilf(font().glyph_width('x'))), m_line_height }); window.set_size_increment({ m_column_width, m_line_height });
window.set_base_size(compute_base_size()); window.set_base_size(compute_base_size());
} }
@ -595,7 +595,7 @@ VT::Position TerminalWidget::buffer_position_at(Gfx::IntPoint position) const
{ {
auto adjusted_position = position.translated(-(frame_thickness() + m_inset), -(frame_thickness() + m_inset)); auto adjusted_position = position.translated(-(frame_thickness() + m_inset), -(frame_thickness() + m_inset));
int row = adjusted_position.y() / m_line_height; int row = adjusted_position.y() / m_line_height;
int column = adjusted_position.x() / font().glyph_width('x'); int column = adjusted_position.x() / m_column_width;
if (row < 0) if (row < 0)
row = 0; row = 0;
if (column < 0) if (column < 0)
@ -1167,11 +1167,23 @@ void TerminalWidget::drop_event(GUI::DropEvent& event)
void TerminalWidget::did_change_font() void TerminalWidget::did_change_font()
{ {
GUI::Frame::did_change_font(); GUI::Frame::did_change_font();
m_line_height = font().glyph_height() + m_line_spacing; update_cached_font_metrics();
if (!size().is_empty()) if (!size().is_empty())
relayout(size()); relayout(size());
} }
static void collect_font_metrics(Gfx::Font const& font, int& column_width, int& line_height, int& line_spacing)
{
line_spacing = 4;
column_width = static_cast<int>(ceilf(font.glyph_width('x')));
line_height = static_cast<int>(ceilf(font.glyph_height())) + line_spacing;
}
void TerminalWidget::update_cached_font_metrics()
{
collect_font_metrics(font(), m_column_width, m_line_height, m_line_spacing);
}
void TerminalWidget::clear_including_history() void TerminalWidget::clear_including_history()
{ {
m_terminal.clear_including_history(); m_terminal.clear_including_history();
@ -1229,9 +1241,13 @@ void TerminalWidget::update_color_scheme()
Gfx::IntSize TerminalWidget::widget_size_for_font(Gfx::Font const& font) const Gfx::IntSize TerminalWidget::widget_size_for_font(Gfx::Font const& font) const
{ {
int column_width = 0;
int line_height = 0;
int line_spacing = 0;
collect_font_metrics(font, column_width, line_height, line_spacing);
return { return {
(frame_thickness() * 2) + (m_inset * 2) + (m_terminal.columns() * static_cast<int>(ceilf(font.glyph_width('x')))) + m_scrollbar->width(), (frame_thickness() * 2) + (m_inset * 2) + (m_terminal.columns() * column_width) + m_scrollbar->width(),
(frame_thickness() * 2) + (m_inset * 2) + (m_terminal.rows() * (font.glyph_height() + m_line_spacing)) (frame_thickness() * 2) + (m_inset * 2) + (m_terminal.rows() * line_height)
}; };
} }

View file

@ -161,6 +161,8 @@ private:
VT::Position next_position_after(const VT::Position&, bool should_wrap) const; VT::Position next_position_after(const VT::Position&, bool should_wrap) const;
VT::Position previous_position_before(const VT::Position&, bool should_wrap) const; VT::Position previous_position_before(const VT::Position&, bool should_wrap) const;
void update_cached_font_metrics();
VT::Terminal m_terminal; VT::Terminal m_terminal;
VT::Range m_selection; VT::Range m_selection;
@ -191,6 +193,7 @@ private:
int m_inset { 2 }; int m_inset { 2 };
int m_line_spacing { 4 }; int m_line_spacing { 4 };
int m_line_height { 0 }; int m_line_height { 0 };
int m_column_width { 0 };
int m_ptm_fd { -1 }; int m_ptm_fd { -1 };