From e187a5365a50cff89a6da10208bfec65e40e92a3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 6 Jan 2021 11:05:23 +0100 Subject: LibWeb: Store the used font in Layout::NodeWithStyle This is a step towards not having to carry the full set of specified values around with every layout node. --- Libraries/LibWeb/CSS/Length.cpp | 2 +- Libraries/LibWeb/Layout/ButtonBox.cpp | 5 ++--- Libraries/LibWeb/Layout/LineBox.cpp | 2 +- Libraries/LibWeb/Layout/LineBoxFragment.cpp | 2 +- Libraries/LibWeb/Layout/Node.cpp | 2 ++ Libraries/LibWeb/Layout/Node.h | 11 +++++++++++ Libraries/LibWeb/Layout/TextNode.cpp | 8 ++++---- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Libraries/LibWeb/CSS/Length.cpp b/Libraries/LibWeb/CSS/Length.cpp index dd85754ec2..08b2ca500f 100644 --- a/Libraries/LibWeb/CSS/Length.cpp +++ b/Libraries/LibWeb/CSS/Length.cpp @@ -35,7 +35,7 @@ float Length::relative_length_to_px(const Layout::Node& layout_node) const { switch (m_type) { case Type::Ex: - return m_value * layout_node.specified_style().font().x_height(); + return m_value * layout_node.font().x_height(); case Type::Em: return m_value * layout_node.font_size(); case Type::Rem: diff --git a/Libraries/LibWeb/Layout/ButtonBox.cpp b/Libraries/LibWeb/Layout/ButtonBox.cpp index 4ceaa87e8d..c0b3706e28 100644 --- a/Libraries/LibWeb/Layout/ButtonBox.cpp +++ b/Libraries/LibWeb/Layout/ButtonBox.cpp @@ -45,8 +45,7 @@ ButtonBox::~ButtonBox() void ButtonBox::prepare_for_replaced_layout() { - auto& font = specified_style().font(); - set_intrinsic_width(font.width(dom_node().value()) + 20); + set_intrinsic_width(font().width(dom_node().value()) + 20); set_has_intrinsic_width(true); set_intrinsic_height(20); @@ -67,7 +66,7 @@ void ButtonBox::paint(PaintContext& context, PaintPhase phase) auto text_rect = enclosing_int_rect(absolute_rect()); if (m_being_pressed) text_rect.move_by(1, 1); - context.painter().draw_text(text_rect, dom_node().value(), specified_style().font(), Gfx::TextAlignment::Center, context.palette().button_text()); + context.painter().draw_text(text_rect, dom_node().value(), font(), Gfx::TextAlignment::Center, context.palette().button_text()); } } diff --git a/Libraries/LibWeb/Layout/LineBox.cpp b/Libraries/LibWeb/Layout/LineBox.cpp index cf2a127755..3e01f9fd40 100644 --- a/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Libraries/LibWeb/Layout/LineBox.cpp @@ -65,7 +65,7 @@ void LineBox::trim_trailing_whitespace() return; auto& last_fragment = m_fragments.last(); - int space_width = last_fragment.layout_node().specified_style().font().glyph_width(' '); + int space_width = last_fragment.layout_node().font().glyph_width(' '); while (last_fragment.length() && isspace(last_text[last_fragment.length() - 1])) { last_fragment.m_length -= 1; last_fragment.set_width(last_fragment.width() - space_width); diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp index 106f9d18d2..ba49f93d18 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp +++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp @@ -78,7 +78,7 @@ int LineBoxFragment::text_index_at(float x) const if (!is(layout_node())) return 0; auto& layout_text = downcast(layout_node()); - auto& font = layout_text.specified_style().font(); + auto& font = layout_text.font(); Utf8View view(text()); float relative_x = x - absolute_x(); diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 18350cbeec..74c42ae027 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -222,6 +222,8 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) { auto& computed_values = static_cast(m_computed_values); + m_font = specified_style.font(); + auto position = specified_style.position(); if (position.has_value()) computed_values.set_position(position.value()); diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index 25c9b03a5e..d688aacbef 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -125,6 +125,7 @@ public: bool can_contain_boxes_with_position_absolute() const; + const Gfx::Font& font() const; const CSS::StyleProperties& specified_style() const; const CSS::ImmutableComputedValues& style() const; @@ -204,11 +205,14 @@ public: void apply_style(const CSS::StyleProperties&); + const Gfx::Font& font() const { return *m_font; } + protected: NodeWithStyle(DOM::Document&, DOM::Node*, NonnullRefPtr); private: CSS::ComputedValues m_computed_values; + RefPtr m_font; NonnullRefPtr m_specified_style; CSS::Position m_position; @@ -229,6 +233,13 @@ private: BoxModelMetrics m_box_model; }; +inline const Gfx::Font& Node::font() const +{ + if (m_has_style) + return static_cast(this)->font(); + return parent()->font(); +} + inline const CSS::StyleProperties& Node::specified_style() const { if (m_has_style) diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index 8406c4f0ed..c29291275b 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -81,7 +81,7 @@ void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& frag } if (phase == PaintPhase::Foreground) { - painter.set_font(specified_style().font()); + painter.set_font(font()); if (document().inspected_node() == &dom_node()) context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta); @@ -99,7 +99,7 @@ void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& frag painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, style().color()); - auto selection_rect = fragment.selection_rect(specified_style().font()); + auto selection_rect = fragment.selection_rect(font()); if (!selection_rect.is_empty()) { painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection()); Gfx::PainterStateSaver saver(painter); @@ -130,7 +130,7 @@ void TextNode::paint_cursor_if_needed(PaintContext& context, const LineBoxFragme auto fragment_rect = fragment.absolute_rect(); - float cursor_x = fragment_rect.x() + specified_style().font().width(fragment.text().substring_view(0, frame().cursor_position().offset() - fragment.start())); + float cursor_x = fragment_rect.x() + font().width(fragment.text().substring_view(0, frame().cursor_position().offset() - fragment.start())); float cursor_top = fragment_rect.top(); float cursor_height = fragment_rect.height(); Gfx::IntRect cursor_rect(cursor_x, cursor_top, 1, cursor_height); @@ -195,7 +195,7 @@ void TextNode::split_into_lines_by_rules(InlineFormattingContext& context, Layou { auto& containing_block = context.containing_block(); - auto& font = specified_style().font(); + auto& font = this->font(); auto& line_boxes = containing_block.line_boxes(); containing_block.ensure_last_line_box(); -- cgit v1.2.3