Sfoglia il codice sorgente

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.
Andreas Kling 4 anni fa
parent
commit
e187a5365a

+ 1 - 1
Libraries/LibWeb/CSS/Length.cpp

@@ -35,7 +35,7 @@ float Length::relative_length_to_px(const Layout::Node& layout_node) const
 {
 {
     switch (m_type) {
     switch (m_type) {
     case Type::Ex:
     case Type::Ex:
-        return m_value * layout_node.specified_style().font().x_height();
+        return m_value * layout_node.font().x_height();
     case Type::Em:
     case Type::Em:
         return m_value * layout_node.font_size();
         return m_value * layout_node.font_size();
     case Type::Rem:
     case Type::Rem:

+ 2 - 3
Libraries/LibWeb/Layout/ButtonBox.cpp

@@ -45,8 +45,7 @@ ButtonBox::~ButtonBox()
 
 
 void ButtonBox::prepare_for_replaced_layout()
 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_has_intrinsic_width(true);
 
 
     set_intrinsic_height(20);
     set_intrinsic_height(20);
@@ -67,7 +66,7 @@ void ButtonBox::paint(PaintContext& context, PaintPhase phase)
         auto text_rect = enclosing_int_rect(absolute_rect());
         auto text_rect = enclosing_int_rect(absolute_rect());
         if (m_being_pressed)
         if (m_being_pressed)
             text_rect.move_by(1, 1);
             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());
     }
     }
 }
 }
 
 

+ 1 - 1
Libraries/LibWeb/Layout/LineBox.cpp

@@ -65,7 +65,7 @@ void LineBox::trim_trailing_whitespace()
         return;
         return;
     auto& last_fragment = m_fragments.last();
     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])) {
     while (last_fragment.length() && isspace(last_text[last_fragment.length() - 1])) {
         last_fragment.m_length -= 1;
         last_fragment.m_length -= 1;
         last_fragment.set_width(last_fragment.width() - space_width);
         last_fragment.set_width(last_fragment.width() - space_width);

+ 1 - 1
Libraries/LibWeb/Layout/LineBoxFragment.cpp

@@ -78,7 +78,7 @@ int LineBoxFragment::text_index_at(float x) const
     if (!is<TextNode>(layout_node()))
     if (!is<TextNode>(layout_node()))
         return 0;
         return 0;
     auto& layout_text = downcast<TextNode>(layout_node());
     auto& layout_text = downcast<TextNode>(layout_node());
-    auto& font = layout_text.specified_style().font();
+    auto& font = layout_text.font();
     Utf8View view(text());
     Utf8View view(text());
 
 
     float relative_x = x - absolute_x();
     float relative_x = x - absolute_x();

+ 2 - 0
Libraries/LibWeb/Layout/Node.cpp

@@ -222,6 +222,8 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
 {
 {
     auto& computed_values = static_cast<CSS::MutableComputedValues&>(m_computed_values);
     auto& computed_values = static_cast<CSS::MutableComputedValues&>(m_computed_values);
 
 
+    m_font = specified_style.font();
+
     auto position = specified_style.position();
     auto position = specified_style.position();
     if (position.has_value())
     if (position.has_value())
         computed_values.set_position(position.value());
         computed_values.set_position(position.value());

+ 11 - 0
Libraries/LibWeb/Layout/Node.h

@@ -125,6 +125,7 @@ public:
 
 
     bool can_contain_boxes_with_position_absolute() const;
     bool can_contain_boxes_with_position_absolute() const;
 
 
+    const Gfx::Font& font() const;
     const CSS::StyleProperties& specified_style() const;
     const CSS::StyleProperties& specified_style() const;
     const CSS::ImmutableComputedValues& style() const;
     const CSS::ImmutableComputedValues& style() const;
 
 
@@ -204,11 +205,14 @@ public:
 
 
     void apply_style(const CSS::StyleProperties&);
     void apply_style(const CSS::StyleProperties&);
 
 
+    const Gfx::Font& font() const { return *m_font; }
+
 protected:
 protected:
     NodeWithStyle(DOM::Document&, DOM::Node*, NonnullRefPtr<CSS::StyleProperties>);
     NodeWithStyle(DOM::Document&, DOM::Node*, NonnullRefPtr<CSS::StyleProperties>);
 
 
 private:
 private:
     CSS::ComputedValues m_computed_values;
     CSS::ComputedValues m_computed_values;
+    RefPtr<Gfx::Font> m_font;
 
 
     NonnullRefPtr<CSS::StyleProperties> m_specified_style;
     NonnullRefPtr<CSS::StyleProperties> m_specified_style;
     CSS::Position m_position;
     CSS::Position m_position;
@@ -229,6 +233,13 @@ private:
     BoxModelMetrics m_box_model;
     BoxModelMetrics m_box_model;
 };
 };
 
 
+inline const Gfx::Font& Node::font() const
+{
+    if (m_has_style)
+        return static_cast<const NodeWithStyle*>(this)->font();
+    return parent()->font();
+}
+
 inline const CSS::StyleProperties& Node::specified_style() const
 inline const CSS::StyleProperties& Node::specified_style() const
 {
 {
     if (m_has_style)
     if (m_has_style)

+ 4 - 4
Libraries/LibWeb/Layout/TextNode.cpp

@@ -81,7 +81,7 @@ void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& frag
     }
     }
 
 
     if (phase == PaintPhase::Foreground) {
     if (phase == PaintPhase::Foreground) {
-        painter.set_font(specified_style().font());
+        painter.set_font(font());
 
 
         if (document().inspected_node() == &dom_node())
         if (document().inspected_node() == &dom_node())
             context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
             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());
         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()) {
         if (!selection_rect.is_empty()) {
             painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
             painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
             Gfx::PainterStateSaver saver(painter);
             Gfx::PainterStateSaver saver(painter);
@@ -130,7 +130,7 @@ void TextNode::paint_cursor_if_needed(PaintContext& context, const LineBoxFragme
 
 
     auto fragment_rect = fragment.absolute_rect();
     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_top = fragment_rect.top();
     float cursor_height = fragment_rect.height();
     float cursor_height = fragment_rect.height();
     Gfx::IntRect cursor_rect(cursor_x, cursor_top, 1, cursor_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& containing_block = context.containing_block();
 
 
-    auto& font = specified_style().font();
+    auto& font = this->font();
 
 
     auto& line_boxes = containing_block.line_boxes();
     auto& line_boxes = containing_block.line_boxes();
     containing_block.ensure_last_line_box();
     containing_block.ensure_last_line_box();