1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:17:45 +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
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));
@ -153,14 +153,14 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy)
Gfx::IntRect TerminalWidget::glyph_rect(u16 row, u16 column)
{
int y = row * m_line_height;
int x = column * font().glyph_width('x');
return { x + frame_thickness() + m_inset, y + frame_thickness() + m_inset, static_cast<int>(ceilf(font().glyph_width('x'))), font().glyph_height() };
int x = column * m_column_width;
return { x + frame_thickness() + m_inset, y + frame_thickness() + m_inset, m_column_width, font().glyph_height() };
}
Gfx::IntRect TerminalWidget::row_rect(u16 row)
{
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);
return rect;
}
@ -511,7 +511,7 @@ void TerminalWidget::relayout(Gfx::IntSize size)
TemporaryChange change(m_in_relayout, true);
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;
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)
{
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());
}
@ -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));
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)
row = 0;
if (column < 0)
@ -1167,11 +1167,23 @@ void TerminalWidget::drop_event(GUI::DropEvent& event)
void TerminalWidget::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())
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()
{
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
{
int column_width = 0;
int line_height = 0;
int line_spacing = 0;
collect_font_metrics(font, column_width, line_height, line_spacing);
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.rows() * (font.glyph_height() + m_line_spacing))
(frame_thickness() * 2) + (m_inset * 2) + (m_terminal.columns() * column_width) + m_scrollbar->width(),
(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 previous_position_before(const VT::Position&, bool should_wrap) const;
void update_cached_font_metrics();
VT::Terminal m_terminal;
VT::Range m_selection;
@ -191,6 +193,7 @@ private:
int m_inset { 2 };
int m_line_spacing { 4 };
int m_line_height { 0 };
int m_column_width { 0 };
int m_ptm_fd { -1 };