From 81590b180470e24492ac0ff5d798f6bca1eced9c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 14 Oct 2021 18:37:24 +0200 Subject: [PATCH] LibWeb: Make intrinsic width/height/ratio a Box concept and simplify it Apparently it's not only replaced elements that can have intrinsic sizes, so let's move this concept from ReplacedBox to Box. To avoid bloating Box, we make the accessors virtual. --- Userland/Libraries/LibWeb/Layout/Box.h | 8 +++++++ .../Libraries/LibWeb/Layout/ButtonBox.cpp | 3 --- .../Libraries/LibWeb/Layout/CanvasBox.cpp | 2 -- Userland/Libraries/LibWeb/Layout/CheckBox.cpp | 2 -- .../LibWeb/Layout/FormattingContext.cpp | 12 +++++----- Userland/Libraries/LibWeb/Layout/FrameBox.cpp | 2 -- Userland/Libraries/LibWeb/Layout/ImageBox.cpp | 7 +----- .../Libraries/LibWeb/Layout/RadioButton.cpp | 2 -- .../Libraries/LibWeb/Layout/ReplacedBox.h | 23 +++++-------------- 9 files changed, 21 insertions(+), 40 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/Box.h b/Userland/Libraries/LibWeb/Layout/Box.h index 2248d81be3..d3522b29be 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.h +++ b/Userland/Libraries/LibWeb/Layout/Box.h @@ -121,6 +121,14 @@ public: Painting::BorderRadiusData normalized_border_radius_data(); + virtual Optional intrinsic_width() const { return {}; } + virtual Optional intrinsic_height() const { return {}; } + virtual Optional intrinsic_ratio() const { return {}; } + + bool has_intrinsic_width() const { return intrinsic_width().has_value(); } + bool has_intrinsic_height() const { return intrinsic_height().has_value(); } + bool has_intrinsic_ratio() const { return intrinsic_ratio().has_value(); } + protected: Box(DOM::Document& document, DOM::Node* node, NonnullRefPtr style) : NodeWithStyleAndBoxModelMetrics(document, node, move(style)) diff --git a/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp b/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp index 0679257e55..1e16176122 100644 --- a/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp @@ -27,10 +27,7 @@ ButtonBox::~ButtonBox() void ButtonBox::prepare_for_replaced_layout() { set_intrinsic_width(font().width(dom_node().value()) + 20); - set_has_intrinsic_width(true); - set_intrinsic_height(20); - set_has_intrinsic_height(true); } void ButtonBox::paint(PaintContext& context, PaintPhase phase) diff --git a/Userland/Libraries/LibWeb/Layout/CanvasBox.cpp b/Userland/Libraries/LibWeb/Layout/CanvasBox.cpp index 7a4731cf24..adb0b9e396 100644 --- a/Userland/Libraries/LibWeb/Layout/CanvasBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/CanvasBox.cpp @@ -20,8 +20,6 @@ CanvasBox::~CanvasBox() void CanvasBox::prepare_for_replaced_layout() { - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); set_intrinsic_width(dom_node().width()); set_intrinsic_height(dom_node().height()); } diff --git a/Userland/Libraries/LibWeb/Layout/CheckBox.cpp b/Userland/Libraries/LibWeb/Layout/CheckBox.cpp index fc92179cdb..1b6fa930be 100644 --- a/Userland/Libraries/LibWeb/Layout/CheckBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/CheckBox.cpp @@ -17,8 +17,6 @@ namespace Web::Layout { CheckBox::CheckBox(DOM::Document& document, HTML::HTMLInputElement& element, NonnullRefPtr style) : LabelableNode(document, element, move(style)) { - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); set_intrinsic_width(13); set_intrinsic_height(13); } diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 294d153035..8ba52cacfd 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -254,7 +254,7 @@ float FormattingContext::tentative_width_for_replaced_element(const ReplacedBox& // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, // then that intrinsic width is the used value of 'width'. if (specified_height.is_auto() && width.is_auto() && box.has_intrinsic_width()) { - used_width = box.intrinsic_width(); + used_width = box.intrinsic_width().value(); } // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, @@ -264,11 +264,11 @@ float FormattingContext::tentative_width_for_replaced_element(const ReplacedBox& // // (used height) * (intrinsic ratio) else if ((specified_height.is_auto() && width.is_auto() && !box.has_intrinsic_width() && box.has_intrinsic_height() && box.has_intrinsic_ratio()) || (width.is_auto() && box.has_intrinsic_ratio())) { - used_width = compute_height_for_replaced_element(box) * box.intrinsic_ratio(); + used_width = compute_height_for_replaced_element(box) * box.intrinsic_ratio().value(); } else if (width.is_auto() && box.has_intrinsic_width()) { - used_width = box.intrinsic_width(); + used_width = box.intrinsic_width().value(); } else if (width.is_auto()) { @@ -347,11 +347,11 @@ float FormattingContext::tentative_height_for_replaced_element(const ReplacedBox // If 'height' and 'width' both have computed values of 'auto' and the element also has // an intrinsic height, then that intrinsic height is the used value of 'height'. if (specified_width.is_auto() && height.is_auto() && box.has_intrinsic_height()) - used_height = box.intrinsic_height(); + used_height = box.intrinsic_height().value(); else if (height.is_auto() && box.has_intrinsic_ratio()) - used_height = compute_width_for_replaced_element(box) / box.intrinsic_ratio(); + used_height = compute_width_for_replaced_element(box) / box.intrinsic_ratio().value(); else if (height.is_auto() && box.has_intrinsic_height()) - used_height = box.intrinsic_height(); + used_height = box.intrinsic_height().value(); else if (height.is_auto()) used_height = 150; diff --git a/Userland/Libraries/LibWeb/Layout/FrameBox.cpp b/Userland/Libraries/LibWeb/Layout/FrameBox.cpp index ce1003b620..2e3a1d1970 100644 --- a/Userland/Libraries/LibWeb/Layout/FrameBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/FrameBox.cpp @@ -26,8 +26,6 @@ void FrameBox::prepare_for_replaced_layout() { VERIFY(dom_node().nested_browsing_context()); - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); // FIXME: Do proper error checking, etc. set_intrinsic_width(dom_node().attribute(HTML::AttributeNames::width).to_int().value_or(300)); set_intrinsic_height(dom_node().attribute(HTML::AttributeNames::height).to_int().value_or(150)); diff --git a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp index 8bfb1f08fa..8977c549d0 100644 --- a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp @@ -37,25 +37,20 @@ int ImageBox::preferred_height() const void ImageBox::prepare_for_replaced_layout() { if (!m_image_loader.has_loaded_or_failed()) { - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); set_intrinsic_width(0); set_intrinsic_height(0); } else { if (m_image_loader.width()) { - set_has_intrinsic_width(true); set_intrinsic_width(m_image_loader.width()); } if (m_image_loader.height()) { - set_has_intrinsic_height(true); set_intrinsic_height(m_image_loader.height()); } if (m_image_loader.width() && m_image_loader.height()) { - set_has_intrinsic_ratio(true); set_intrinsic_ratio((float)m_image_loader.width() / (float)m_image_loader.height()); } else { - set_has_intrinsic_ratio(false); + set_intrinsic_ratio({}); } } diff --git a/Userland/Libraries/LibWeb/Layout/RadioButton.cpp b/Userland/Libraries/LibWeb/Layout/RadioButton.cpp index 8712c2f9b0..d34844b265 100644 --- a/Userland/Libraries/LibWeb/Layout/RadioButton.cpp +++ b/Userland/Libraries/LibWeb/Layout/RadioButton.cpp @@ -17,8 +17,6 @@ namespace Web::Layout { RadioButton::RadioButton(DOM::Document& document, HTML::HTMLInputElement& element, NonnullRefPtr style) : LabelableNode(document, element, move(style)) { - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); set_intrinsic_width(12); set_intrinsic_height(12); } diff --git a/Userland/Libraries/LibWeb/Layout/ReplacedBox.h b/Userland/Libraries/LibWeb/Layout/ReplacedBox.h index 0cd01808fb..4fd132ee96 100644 --- a/Userland/Libraries/LibWeb/Layout/ReplacedBox.h +++ b/Userland/Libraries/LibWeb/Layout/ReplacedBox.h @@ -19,17 +19,9 @@ public: const DOM::Element& dom_node() const { return verify_cast(*Node::dom_node()); } DOM::Element& dom_node() { return verify_cast(*Node::dom_node()); } - bool has_intrinsic_width() const { return m_has_intrinsic_width; } - bool has_intrinsic_height() const { return m_has_intrinsic_height; } - bool has_intrinsic_ratio() const { return m_has_intrinsic_ratio; } - - float intrinsic_width() const { return m_intrinsic_width; } - float intrinsic_height() const { return m_intrinsic_height; } - float intrinsic_ratio() const { return m_intrinsic_ratio; } - - void set_has_intrinsic_width(bool has) { m_has_intrinsic_width = has; } - void set_has_intrinsic_height(bool has) { m_has_intrinsic_height = has; } - void set_has_intrinsic_ratio(bool has) { m_has_intrinsic_ratio = has; } + virtual Optional intrinsic_width() const final { return m_intrinsic_width; } + virtual Optional intrinsic_height() const final { return m_intrinsic_height; } + virtual Optional intrinsic_ratio() const final { return m_intrinsic_ratio; } void set_intrinsic_width(float width) { m_intrinsic_width = width; } void set_intrinsic_height(float height) { m_intrinsic_height = height; } @@ -43,12 +35,9 @@ protected: virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; private: - bool m_has_intrinsic_width { false }; - bool m_has_intrinsic_height { false }; - bool m_has_intrinsic_ratio { false }; - float m_intrinsic_width { 0 }; - float m_intrinsic_height { 0 }; - float m_intrinsic_ratio { 0 }; + Optional m_intrinsic_width; + Optional m_intrinsic_height; + Optional m_intrinsic_ratio; }; }