瀏覽代碼

LibWeb: Apply min/max constraints to sizes that are initially definite

Also add a comment explaining how we determine initial definite sizes.
Andreas Kling 2 年之前
父節點
當前提交
20711c76b7
共有 1 個文件被更改,包括 33 次插入0 次删除
  1. 33 0
      Userland/Libraries/LibWeb/Layout/LayoutState.cpp

+ 33 - 0
Userland/Libraries/LibWeb/Layout/LayoutState.cpp

@@ -183,6 +183,15 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us
 {
     m_node = &node;
 
+    // NOTE: In the code below, we decide if `node` has definite width and/or height.
+    //       This attempts to cover all the *general* cases where CSS considers sizes to be definite.
+    //       If `node` has definite values for min/max-width or min/max-height and a definite
+    //       preferred size in the same axis, we clamp the preferred size here as well.
+    //
+    //       There are additional cases where CSS considers values to be definite. We model all of
+    //       those by having our engine consider sizes to be definite *once they are assigned to
+    //       the UsedValues by calling set_content_width() or set_content_height().
+
     auto const& computed_values = node.computed_values();
 
     auto is_definite_size = [&](CSS::Size const& size, float& resolved_definite_size, bool width) {
@@ -252,8 +261,32 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us
         return false;
     };
 
+    float min_width = 0;
+    bool has_definite_min_width = is_definite_size(computed_values.min_width(), min_width, true);
+    float max_width = 0;
+    bool has_definite_max_width = is_definite_size(computed_values.max_width(), max_width, true);
+
+    float min_height = 0;
+    bool has_definite_min_height = is_definite_size(computed_values.min_height(), min_height, false);
+    float max_height = 0;
+    bool has_definite_max_height = is_definite_size(computed_values.max_height(), max_height, false);
+
     m_has_definite_width = is_definite_size(computed_values.width(), m_content_width, true);
     m_has_definite_height = is_definite_size(computed_values.height(), m_content_height, false);
+
+    if (m_has_definite_width) {
+        if (has_definite_min_width)
+            m_content_width = max(min_width, m_content_width);
+        if (has_definite_max_width)
+            m_content_width = min(max_width, m_content_width);
+    }
+
+    if (m_has_definite_height) {
+        if (has_definite_min_height)
+            m_content_height = max(min_height, m_content_height);
+        if (has_definite_max_height)
+            m_content_height = min(max_height, m_content_height);
+    }
 }
 
 void LayoutState::UsedValues::set_content_width(float width)