Title: [280017] trunk
Revision
280017
Author
[email protected]
Date
2021-07-16 22:42:32 -0700 (Fri, 16 Jul 2021)

Log Message

getBoundingClientRect() returns the incorrect rectangle on elements whose parent element is set -webkit-column-count
https://bugs.webkit.org/show_bug.cgi?id=99959
rdar://80106111

Reviewed by Alan Bujtas.
Source/WebCore:

getBoundingClientRect() and getClientRects() for elements inside multicol had a quick
and dirty implementation that just mapped the element center point into a column. This
resulted in odd, negative top/left in some cases.

Fix by correctly generating multiple rects for elements that span columns, following
the repaint code path that already knew how to do this correctly.

The entry point is RenderFragmentContainer::absoluteQuadsForBox() which now has a
real implementation. For each fragment that the box covers, it calls fragmentRectsForFlowContentRect()
which generates one or more rects; RenderMultiColumnSet overrides this to
compute rects for multicol.

We have to take care not to eliminate empty rects, since the API does return these.

Tested by existing tests.

* dom/Element.cpp:
(WebCore::Element::absoluteEventBounds):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::absoluteQuadsIgnoringContinuation const):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::absoluteQuads const):
* rendering/RenderFragmentContainer.cpp:
(WebCore::RenderFragmentContainer::fragmentedFlowContentRectangle):
(WebCore::RenderFragmentContainer::fragmentRectsForFlowContentRect):
* rendering/RenderFragmentContainer.h:
(WebCore::RenderFragmentContainer::absoluteQuadsForBoxInFragment): Deleted.
* rendering/RenderFragmentedFlow.cpp:
(WebCore::RenderFragmentedFlow::absoluteQuadsForBox const):
* rendering/RenderFragmentedFlow.h:
* rendering/RenderMultiColumnFlow.h:
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::firstAndLastColumnsFromOffsets const):
(WebCore::RenderMultiColumnSet::repaintFragmentedFlowContent):
(WebCore::RenderMultiColumnSet::fragmentRectsForFlowContentRect):
(WebCore::RenderMultiColumnSet::collectLayerFragments):
* rendering/RenderMultiColumnSet.h:

LayoutTests:

These tests have all progressed.

* fast/multicol/client-rects-spanners-complex.html:
* fast/multicol/client-rects-spanners.html:
* fast/multicol/client-rects.html:
* fast/multicol/newmulticol/client-rects.html:
* imported/blink/fast/multicol/client-rects-rtl-expected.html:
* imported/blink/fast/multicol/client-rects-rtl.html: This test appeared to be hand-coded to the incorrect old behavior.
* platform/ios/fast/multicol/client-rects-expected.txt:
* platform/ios/fast/multicol/client-rects-spanners-complex-expected.txt:
* platform/ios/fast/multicol/client-rects-spanners-expected.txt:
* platform/ios/fast/multicol/newmulticol/client-rects-expected.txt:
* platform/mac/fast/multicol/client-rects-expected.txt:
* platform/mac/fast/multicol/client-rects-spanners-complex-expected.txt:
* platform/mac/fast/multicol/client-rects-spanners-expected.txt:
* platform/mac/fast/multicol/newmulticol/client-rects-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (280016 => 280017)


--- trunk/LayoutTests/ChangeLog	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/ChangeLog	2021-07-17 05:42:32 UTC (rev 280017)
@@ -1,3 +1,28 @@
+2021-07-16  Simon Fraser  <[email protected]>
+
+        getBoundingClientRect() returns the incorrect rectangle on elements whose parent element is set -webkit-column-count
+        https://bugs.webkit.org/show_bug.cgi?id=99959
+        rdar://80106111
+
+        Reviewed by Alan Bujtas.
+
+        These tests have all progressed.
+
+        * fast/multicol/client-rects-spanners-complex.html:
+        * fast/multicol/client-rects-spanners.html:
+        * fast/multicol/client-rects.html:
+        * fast/multicol/newmulticol/client-rects.html:
+        * imported/blink/fast/multicol/client-rects-rtl-expected.html:
+        * imported/blink/fast/multicol/client-rects-rtl.html: This test appeared to be hand-coded to the incorrect old behavior.
+        * platform/ios/fast/multicol/client-rects-expected.txt:
+        * platform/ios/fast/multicol/client-rects-spanners-complex-expected.txt:
+        * platform/ios/fast/multicol/client-rects-spanners-expected.txt:
+        * platform/ios/fast/multicol/newmulticol/client-rects-expected.txt:
+        * platform/mac/fast/multicol/client-rects-expected.txt:
+        * platform/mac/fast/multicol/client-rects-spanners-complex-expected.txt:
+        * platform/mac/fast/multicol/client-rects-spanners-expected.txt:
+        * platform/mac/fast/multicol/newmulticol/client-rects-expected.txt:
+
 2021-07-16  Eric Hutchison  <[email protected]>
 
         [MacOS Release wk1] media/modern-media-controls/volume-support/volume-support-drag-to-mute.html is a flaky fail and timeout.

Modified: trunk/LayoutTests/fast/multicol/client-rects-spanners-complex.html (280016 => 280017)


--- trunk/LayoutTests/fast/multicol/client-rects-spanners-complex.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/fast/multicol/client-rects-spanners-complex.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -175,7 +175,7 @@
 
     var block = document.getElementById("t4");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t5");
     range.selectNode(slider);
@@ -206,7 +206,7 @@
 
     var block = document.getElementById("t11");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t12");
     range.selectNode(slider);
@@ -237,7 +237,7 @@
 
     var block = document.getElementById("t18");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t19");
     range.selectNode(slider);

Modified: trunk/LayoutTests/fast/multicol/client-rects-spanners.html (280016 => 280017)


--- trunk/LayoutTests/fast/multicol/client-rects-spanners.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/fast/multicol/client-rects-spanners.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -173,7 +173,7 @@
 
     var block = document.getElementById("t4");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t5");
     range.selectNode(slider);
@@ -204,7 +204,7 @@
 
     var block = document.getElementById("t11");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t12");
     range.selectNode(slider);
@@ -235,7 +235,7 @@
 
     var block = document.getElementById("t18");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t19");
     range.selectNode(slider);

Modified: trunk/LayoutTests/fast/multicol/client-rects.html (280016 => 280017)


--- trunk/LayoutTests/fast/multicol/client-rects.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/fast/multicol/client-rects.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -169,7 +169,7 @@
 
     var block = document.getElementById("t4");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t5");
     range.selectNode(slider);
@@ -200,7 +200,7 @@
 
     var block = document.getElementById("t11");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t12");
     range.selectNode(slider);
@@ -231,7 +231,7 @@
 
     var block = document.getElementById("t18");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t19");
     range.selectNode(slider);

Modified: trunk/LayoutTests/fast/multicol/newmulticol/client-rects.html (280016 => 280017)


--- trunk/LayoutTests/fast/multicol/newmulticol/client-rects.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/fast/multicol/newmulticol/client-rects.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -172,7 +172,7 @@
 
     var block = document.getElementById("t4");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t5");
     range.selectNode(slider);
@@ -203,7 +203,7 @@
 
     var block = document.getElementById("t11");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t12");
     range.selectNode(slider);
@@ -234,7 +234,7 @@
 
     var block = document.getElementById("t18");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t19");
     range.selectNode(slider);

Modified: trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl-expected.html (280016 => 280017)


--- trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl-expected.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl-expected.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -34,16 +34,11 @@
     .special > .first > span {
         margin-top: 40px;
         height: 10px;
-        border: none;
     }
-    .special > .second span:first-child {
-        border-bottom: none;
+    .special > .first span:last-child {
         height: 10px;
-        margin-top: -10px;
-        background-color: white;
     }
-    .special > .second span:last-child {
-        border-top: none;
+    .special > .second span:first-child {
         height: 15px;
     }
 </style>
@@ -77,10 +72,7 @@
 <div class="columns">
     <div class="column second"><span></span></div>
 </div>
-<p>
-    Except here, where the blue border should be around the bigger slice of the blue square, on the left.
-</p>
 <div class="columns special">
     <div class="column first"><span></span></div>
-    <div class="column second"><span></span><span></span></div>
+    <div class="column second"><span></span></div>
 </div>

Modified: trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl.html (280016 => 280017)


--- trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl.html	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/imported/blink/fast/multicol/client-rects-rtl.html	2021-07-17 05:42:32 UTC (rev 280017)
@@ -69,10 +69,6 @@
     <br><div><br><img id="t6" style="width: 25px; height: 25px; background-color: lightblue;"></div>
 </div>
 
-<p>
-    Except here, where the blue border should be around the bigger slice of the blue square, on the left.
-</p>
-
 <div class="columns">
     <div id="t7" style=" margin-top: 40px; width: 25px; height: 25px; background-color: lightblue;"></div>
 </div>
@@ -117,7 +113,7 @@
 
     var block = document.getElementById("t4");
     range.selectNode(block);
-    placeMarkersForRange(range, 1);
+    placeMarkersForRange(range, 2);
 
     var slider = document.getElementById("t5");
     range.selectNode(slider);

Modified: trunk/LayoutTests/platform/ios/fast/multicol/client-rects-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/ios/fast/multicol/client-rects-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/ios/fast/multicol/client-rects-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -309,8 +309,10 @@
   RenderBlock (positioned) {DIV} at (550,92) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,92) size 25x25
   RenderBlock (positioned) {DIV} at (668,92) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,210) size 25x25
-  RenderBlock (positioned) {DIV} at (68,210) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,260) size 25x10
+  RenderBlock (positioned) {DIV} at (16,260) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,220) size 25x15
+  RenderBlock (positioned) {DIV} at (68,220) size 26x15 [border: (3px solid #0000FF80)]
 layer at (171,180) size 25x25
   RenderBlock (positioned) {DIV} at (171,180) size 25x25 [border: (3px solid #0000FF80)]
 layer at (146,233) size 25x25
@@ -337,8 +339,10 @@
   RenderBlock (positioned) {DIV} at (508,234) size 25x26 [border: (3px solid #0000FF80)]
 layer at (596,233) size 25x25
   RenderBlock (positioned) {DIV} at (596,232) size 25x26 [border: (3px solid #0000FF80)]
-layer at (676,233) size 25x25
-  RenderBlock (positioned) {DIV} at (676,232) size 25x26 [border: (3px solid #0000FF80)]
+layer at (726,180) size 10x25
+  RenderBlock (positioned) {DIV} at (726,180) size 10x25 [border: (3px solid #0000FF80)]
+layer at (686,233) size 15x25
+  RenderBlock (positioned) {DIV} at (686,232) size 15x26 [border: (3px solid #0000FF80)]
 layer at (26,301) size 25x25
   RenderBlock (positioned) {DIV} at (26,301) size 25x25 [border: (3px solid #0000FF80)]
 layer at (51,354) size 25x25
@@ -365,5 +369,7 @@
   RenderBlock (positioned) {DIV} at (409,355) size 25x26 [border: (3px solid #0000FF80)]
 layer at (501,354) size 25x25
   RenderBlock (positioned) {DIV} at (501,353) size 25x26 [border: (3px solid #0000FF80)]
-layer at (601,354) size 25x25
-  RenderBlock (positioned) {DIV} at (601,353) size 25x26 [border: (3px solid #0000FF80)]
+layer at (566,301) size 10x25
+  RenderBlock (positioned) {DIV} at (566,301) size 10x25 [border: (3px solid #0000FF80)]
+layer at (601,354) size 15x25
+  RenderBlock (positioned) {DIV} at (601,353) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-complex-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-complex-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-complex-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -398,8 +398,10 @@
   RenderBlock (positioned) {DIV} at (550,127) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,127) size 25x25
   RenderBlock (positioned) {DIV} at (668,127) size 26x25 [border: (3px solid #0000FF80)]
-layer at (16,293) size 25x25
-  RenderBlock (positioned) {DIV} at (16,293) size 25x25 [border: (3px solid #0000FF80)]
+layer at (16,293) size 25x15
+  RenderBlock (positioned) {DIV} at (16,293) size 25x15 [border: (3px solid #0000FF80)]
+layer at (69,253) size 25x10
+  RenderBlock (positioned) {DIV} at (68,253) size 26x10 [border: (3px solid #0000FF80)]
 layer at (206,218) size 25x25
   RenderBlock (positioned) {DIV} at (206,218) size 25x25 [border: (3px solid #0000FF80)]
 layer at (181,271) size 25x25
@@ -422,12 +424,16 @@
   RenderBlock (positioned) {DIV} at (571,270) size 25x26 [border: (3px solid #0000FF80)]
 layer at (596,271) size 25x25
   RenderBlock (positioned) {DIV} at (596,270) size 25x26 [border: (3px solid #0000FF80)]
-layer at (698,273) size 25x25
-  RenderBlock (positioned) {DIV} at (698,272) size 25x26 [border: (3px solid #0000FF80)]
+layer at (753,220) size 6x25
+  RenderBlock (positioned) {DIV} at (753,220) size 6x25 [border: (3px solid #0000FF80)]
+layer at (701,273) size 22x25
+  RenderBlock (positioned) {DIV} at (701,272) size 22x26 [border: (3px solid #0000FF80)]
 layer at (61,392) size 25x25
   RenderBlock (positioned) {DIV} at (61,391) size 25x26 [border: (3px solid #0000FF80)]
-layer at (231,339) size 25x25
-  RenderBlock (positioned) {DIV} at (231,339) size 25x25 [border: (3px solid #0000FF80)]
+layer at (231,339) size 15x25
+  RenderBlock (positioned) {DIV} at (231,339) size 15x25 [border: (3px solid #0000FF80)]
+layer at (191,392) size 10x25
+  RenderBlock (positioned) {DIV} at (191,391) size 10x26 [border: (3px solid #0000FF80)]
 layer at (291,339) size 25x25
   RenderBlock (positioned) {DIV} at (291,339) size 25x25 [border: (3px solid #0000FF80)]
 layer at (316,392) size 25x25
@@ -450,9 +456,13 @@
   RenderBlock (positioned) {DIV} at (706,391) size 25x26 [border: (3px solid #0000FF80)]
 layer at (681,392) size 25x25
   RenderBlock (positioned) {DIV} at (681,391) size 25x26 [border: (3px solid #0000FF80)]
-layer at (59,515) size 25x25
-  RenderBlock (positioned) {DIV} at (59,514) size 25x26 [border: (3px solid #0000FF80)]
+layer at (26,462) size 6x25
+  RenderBlock (positioned) {DIV} at (26,462) size 6x25 [border: (3px solid #0000FF80)]
+layer at (59,515) size 22x25
+  RenderBlock (positioned) {DIV} at (59,514) size 22x26 [border: (3px solid #0000FF80)]
 layer at (186,513) size 25x25
   RenderBlock (positioned) {DIV} at (186,512) size 25x26 [border: (3px solid #0000FF80)]
-layer at (276,460) size 25x25
-  RenderBlock (positioned) {DIV} at (276,460) size 25x25 [border: (3px solid #0000FF80)]
+layer at (286,460) size 15x25
+  RenderBlock (positioned) {DIV} at (286,460) size 15x25 [border: (3px solid #0000FF80)]
+layer at (331,513) size 10x25
+  RenderBlock (positioned) {DIV} at (331,512) size 10x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/ios/fast/multicol/client-rects-spanners-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -358,8 +358,10 @@
   RenderBlock (positioned) {DIV} at (550,102) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,102) size 25x25
   RenderBlock (positioned) {DIV} at (668,102) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,210) size 25x25
-  RenderBlock (positioned) {DIV} at (68,210) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,260) size 25x10
+  RenderBlock (positioned) {DIV} at (16,260) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,220) size 25x15
+  RenderBlock (positioned) {DIV} at (68,220) size 26x15 [border: (3px solid #0000FF80)]
 layer at (181,180) size 25x25
   RenderBlock (positioned) {DIV} at (181,180) size 25x25 [border: (3px solid #0000FF80)]
 layer at (156,233) size 25x25
@@ -386,8 +388,10 @@
   RenderBlock (positioned) {DIV} at (558,234) size 25x26 [border: (3px solid #0000FF80)]
 layer at (656,233) size 25x25
   RenderBlock (positioned) {DIV} at (656,232) size 25x26 [border: (3px solid #0000FF80)]
-layer at (26,354) size 25x25
-  RenderBlock (positioned) {DIV} at (26,353) size 25x26 [border: (3px solid #0000FF80)]
+layer at (76,301) size 10x25
+  RenderBlock (positioned) {DIV} at (76,301) size 10x25 [border: (3px solid #0000FF80)]
+layer at (36,354) size 15x25
+  RenderBlock (positioned) {DIV} at (36,353) size 15x26 [border: (3px solid #0000FF80)]
 layer at (126,301) size 25x25
   RenderBlock (positioned) {DIV} at (126,301) size 25x25 [border: (3px solid #0000FF80)]
 layer at (151,354) size 25x25
@@ -414,5 +418,7 @@
   RenderBlock (positioned) {DIV} at (549,355) size 25x26 [border: (3px solid #0000FF80)]
 layer at (651,354) size 25x25
   RenderBlock (positioned) {DIV} at (651,353) size 25x26 [border: (3px solid #0000FF80)]
-layer at (61,475) size 25x25
-  RenderBlock (positioned) {DIV} at (61,474) size 25x26 [border: (3px solid #0000FF80)]
+layer at (26,422) size 10x25
+  RenderBlock (positioned) {DIV} at (26,422) size 10x25 [border: (3px solid #0000FF80)]
+layer at (61,475) size 15x25
+  RenderBlock (positioned) {DIV} at (61,474) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/ios/fast/multicol/newmulticol/client-rects-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/ios/fast/multicol/newmulticol/client-rects-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/ios/fast/multicol/newmulticol/client-rects-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -309,8 +309,10 @@
   RenderBlock (positioned) {DIV} at (550,92) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,92) size 25x25
   RenderBlock (positioned) {DIV} at (668,92) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,210) size 25x25
-  RenderBlock (positioned) {DIV} at (68,210) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,260) size 25x10
+  RenderBlock (positioned) {DIV} at (16,260) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,220) size 25x15
+  RenderBlock (positioned) {DIV} at (68,220) size 26x15 [border: (3px solid #0000FF80)]
 layer at (171,180) size 25x25
   RenderBlock (positioned) {DIV} at (171,180) size 25x25 [border: (3px solid #0000FF80)]
 layer at (146,233) size 25x25
@@ -337,8 +339,10 @@
   RenderBlock (positioned) {DIV} at (508,234) size 25x26 [border: (3px solid #0000FF80)]
 layer at (596,233) size 25x25
   RenderBlock (positioned) {DIV} at (596,232) size 25x26 [border: (3px solid #0000FF80)]
-layer at (676,233) size 25x25
-  RenderBlock (positioned) {DIV} at (676,232) size 25x26 [border: (3px solid #0000FF80)]
+layer at (726,180) size 10x25
+  RenderBlock (positioned) {DIV} at (726,180) size 10x25 [border: (3px solid #0000FF80)]
+layer at (686,233) size 15x25
+  RenderBlock (positioned) {DIV} at (686,232) size 15x26 [border: (3px solid #0000FF80)]
 layer at (26,301) size 25x25
   RenderBlock (positioned) {DIV} at (26,301) size 25x25 [border: (3px solid #0000FF80)]
 layer at (51,354) size 25x25
@@ -365,5 +369,7 @@
   RenderBlock (positioned) {DIV} at (409,355) size 25x26 [border: (3px solid #0000FF80)]
 layer at (501,354) size 25x25
   RenderBlock (positioned) {DIV} at (501,353) size 25x26 [border: (3px solid #0000FF80)]
-layer at (601,354) size 25x25
-  RenderBlock (positioned) {DIV} at (601,353) size 25x26 [border: (3px solid #0000FF80)]
+layer at (566,301) size 10x25
+  RenderBlock (positioned) {DIV} at (566,301) size 10x25 [border: (3px solid #0000FF80)]
+layer at (601,354) size 15x25
+  RenderBlock (positioned) {DIV} at (601,353) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/mac/fast/multicol/client-rects-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/mac/fast/multicol/client-rects-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/mac/fast/multicol/client-rects-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -309,8 +309,10 @@
   RenderBlock (positioned) {DIV} at (550,91) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,91) size 25x25
   RenderBlock (positioned) {DIV} at (668,91) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,208) size 25x25
-  RenderBlock (positioned) {DIV} at (68,208) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,258) size 25x10
+  RenderBlock (positioned) {DIV} at (16,258) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,218) size 25x15
+  RenderBlock (positioned) {DIV} at (68,218) size 26x15 [border: (3px solid #0000FF80)]
 layer at (171,178) size 25x25
   RenderBlock (positioned) {DIV} at (171,178) size 25x25 [border: (3px solid #0000FF80)]
 layer at (146,231) size 25x25
@@ -337,8 +339,10 @@
   RenderBlock (positioned) {DIV} at (508,232) size 25x26 [border: (3px solid #0000FF80)]
 layer at (596,231) size 25x25
   RenderBlock (positioned) {DIV} at (596,230) size 25x26 [border: (3px solid #0000FF80)]
-layer at (676,231) size 25x25
-  RenderBlock (positioned) {DIV} at (676,230) size 25x26 [border: (3px solid #0000FF80)]
+layer at (726,178) size 10x25
+  RenderBlock (positioned) {DIV} at (726,178) size 10x25 [border: (3px solid #0000FF80)]
+layer at (686,231) size 15x25
+  RenderBlock (positioned) {DIV} at (686,230) size 15x26 [border: (3px solid #0000FF80)]
 layer at (26,298) size 25x25
   RenderBlock (positioned) {DIV} at (26,298) size 25x25 [border: (3px solid #0000FF80)]
 layer at (51,351) size 25x25
@@ -365,5 +369,7 @@
   RenderBlock (positioned) {DIV} at (409,352) size 25x26 [border: (3px solid #0000FF80)]
 layer at (501,351) size 25x25
   RenderBlock (positioned) {DIV} at (501,350) size 25x26 [border: (3px solid #0000FF80)]
-layer at (601,351) size 25x25
-  RenderBlock (positioned) {DIV} at (601,350) size 25x26 [border: (3px solid #0000FF80)]
+layer at (566,298) size 10x25
+  RenderBlock (positioned) {DIV} at (566,298) size 10x25 [border: (3px solid #0000FF80)]
+layer at (601,351) size 15x25
+  RenderBlock (positioned) {DIV} at (601,350) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-complex-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-complex-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-complex-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -398,8 +398,10 @@
   RenderBlock (positioned) {DIV} at (550,126) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,126) size 25x25
   RenderBlock (positioned) {DIV} at (668,126) size 26x25 [border: (3px solid #0000FF80)]
-layer at (16,292) size 25x25
-  RenderBlock (positioned) {DIV} at (16,292) size 25x25 [border: (3px solid #0000FF80)]
+layer at (16,292) size 25x15
+  RenderBlock (positioned) {DIV} at (16,292) size 25x15 [border: (3px solid #0000FF80)]
+layer at (69,252) size 25x10
+  RenderBlock (positioned) {DIV} at (68,252) size 26x10 [border: (3px solid #0000FF80)]
 layer at (206,217) size 25x25
   RenderBlock (positioned) {DIV} at (206,217) size 25x25 [border: (3px solid #0000FF80)]
 layer at (181,270) size 25x25
@@ -426,8 +428,10 @@
   RenderBlock (positioned) {DIV} at (703,271) size 25x26 [border: (3px solid #0000FF80)]
 layer at (61,390) size 25x25
   RenderBlock (positioned) {DIV} at (61,389) size 25x26 [border: (3px solid #0000FF80)]
-layer at (231,337) size 25x25
-  RenderBlock (positioned) {DIV} at (231,337) size 25x25 [border: (3px solid #0000FF80)]
+layer at (231,337) size 15x25
+  RenderBlock (positioned) {DIV} at (231,337) size 15x25 [border: (3px solid #0000FF80)]
+layer at (191,390) size 10x25
+  RenderBlock (positioned) {DIV} at (191,389) size 10x26 [border: (3px solid #0000FF80)]
 layer at (291,337) size 25x25
   RenderBlock (positioned) {DIV} at (291,337) size 25x25 [border: (3px solid #0000FF80)]
 layer at (316,390) size 25x25
@@ -454,5 +458,7 @@
   RenderBlock (positioned) {DIV} at (54,511) size 25x26 [border: (3px solid #0000FF80)]
 layer at (186,510) size 25x25
   RenderBlock (positioned) {DIV} at (186,509) size 25x26 [border: (3px solid #0000FF80)]
-layer at (276,457) size 25x25
-  RenderBlock (positioned) {DIV} at (276,457) size 25x25 [border: (3px solid #0000FF80)]
+layer at (286,457) size 15x25
+  RenderBlock (positioned) {DIV} at (286,457) size 15x25 [border: (3px solid #0000FF80)]
+layer at (331,510) size 10x25
+  RenderBlock (positioned) {DIV} at (331,509) size 10x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/mac/fast/multicol/client-rects-spanners-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -358,8 +358,10 @@
   RenderBlock (positioned) {DIV} at (550,101) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,101) size 25x25
   RenderBlock (positioned) {DIV} at (668,101) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,208) size 25x25
-  RenderBlock (positioned) {DIV} at (68,208) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,258) size 25x10
+  RenderBlock (positioned) {DIV} at (16,258) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,218) size 25x15
+  RenderBlock (positioned) {DIV} at (68,218) size 26x15 [border: (3px solid #0000FF80)]
 layer at (181,178) size 25x25
   RenderBlock (positioned) {DIV} at (181,178) size 25x25 [border: (3px solid #0000FF80)]
 layer at (156,231) size 25x25
@@ -386,8 +388,10 @@
   RenderBlock (positioned) {DIV} at (558,232) size 25x26 [border: (3px solid #0000FF80)]
 layer at (656,231) size 25x25
   RenderBlock (positioned) {DIV} at (656,230) size 25x26 [border: (3px solid #0000FF80)]
-layer at (26,351) size 25x25
-  RenderBlock (positioned) {DIV} at (26,350) size 25x26 [border: (3px solid #0000FF80)]
+layer at (76,298) size 10x25
+  RenderBlock (positioned) {DIV} at (76,298) size 10x25 [border: (3px solid #0000FF80)]
+layer at (36,351) size 15x25
+  RenderBlock (positioned) {DIV} at (36,350) size 15x26 [border: (3px solid #0000FF80)]
 layer at (126,298) size 25x25
   RenderBlock (positioned) {DIV} at (126,298) size 25x25 [border: (3px solid #0000FF80)]
 layer at (151,351) size 25x25
@@ -414,5 +418,7 @@
   RenderBlock (positioned) {DIV} at (549,352) size 25x26 [border: (3px solid #0000FF80)]
 layer at (651,351) size 25x25
   RenderBlock (positioned) {DIV} at (651,350) size 25x26 [border: (3px solid #0000FF80)]
-layer at (61,471) size 25x25
-  RenderBlock (positioned) {DIV} at (61,470) size 25x26 [border: (3px solid #0000FF80)]
+layer at (26,418) size 10x25
+  RenderBlock (positioned) {DIV} at (26,418) size 10x25 [border: (3px solid #0000FF80)]
+layer at (61,471) size 15x25
+  RenderBlock (positioned) {DIV} at (61,470) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/LayoutTests/platform/mac/fast/multicol/newmulticol/client-rects-expected.txt (280016 => 280017)


--- trunk/LayoutTests/platform/mac/fast/multicol/newmulticol/client-rects-expected.txt	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/LayoutTests/platform/mac/fast/multicol/newmulticol/client-rects-expected.txt	2021-07-17 05:42:32 UTC (rev 280017)
@@ -309,8 +309,10 @@
   RenderBlock (positioned) {DIV} at (550,91) size 26x25 [border: (3px solid #0000FF80)]
 layer at (669,91) size 25x25
   RenderBlock (positioned) {DIV} at (668,91) size 26x25 [border: (3px solid #0000FF80)]
-layer at (69,208) size 25x25
-  RenderBlock (positioned) {DIV} at (68,208) size 26x25 [border: (3px solid #0000FF80)]
+layer at (16,258) size 25x10
+  RenderBlock (positioned) {DIV} at (16,258) size 25x10 [border: (3px solid #0000FF80)]
+layer at (69,218) size 25x15
+  RenderBlock (positioned) {DIV} at (68,218) size 26x15 [border: (3px solid #0000FF80)]
 layer at (171,178) size 25x25
   RenderBlock (positioned) {DIV} at (171,178) size 25x25 [border: (3px solid #0000FF80)]
 layer at (146,231) size 25x25
@@ -337,8 +339,10 @@
   RenderBlock (positioned) {DIV} at (508,232) size 25x26 [border: (3px solid #0000FF80)]
 layer at (596,231) size 25x25
   RenderBlock (positioned) {DIV} at (596,230) size 25x26 [border: (3px solid #0000FF80)]
-layer at (676,231) size 25x25
-  RenderBlock (positioned) {DIV} at (676,230) size 25x26 [border: (3px solid #0000FF80)]
+layer at (726,178) size 10x25
+  RenderBlock (positioned) {DIV} at (726,178) size 10x25 [border: (3px solid #0000FF80)]
+layer at (686,231) size 15x25
+  RenderBlock (positioned) {DIV} at (686,230) size 15x26 [border: (3px solid #0000FF80)]
 layer at (26,298) size 25x25
   RenderBlock (positioned) {DIV} at (26,298) size 25x25 [border: (3px solid #0000FF80)]
 layer at (51,351) size 25x25
@@ -365,5 +369,7 @@
   RenderBlock (positioned) {DIV} at (409,352) size 25x26 [border: (3px solid #0000FF80)]
 layer at (501,351) size 25x25
   RenderBlock (positioned) {DIV} at (501,350) size 25x26 [border: (3px solid #0000FF80)]
-layer at (601,351) size 25x25
-  RenderBlock (positioned) {DIV} at (601,350) size 25x26 [border: (3px solid #0000FF80)]
+layer at (566,298) size 10x25
+  RenderBlock (positioned) {DIV} at (566,298) size 10x25 [border: (3px solid #0000FF80)]
+layer at (601,351) size 15x25
+  RenderBlock (positioned) {DIV} at (601,350) size 15x26 [border: (3px solid #0000FF80)]

Modified: trunk/Source/WebCore/ChangeLog (280016 => 280017)


--- trunk/Source/WebCore/ChangeLog	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/ChangeLog	2021-07-17 05:42:32 UTC (rev 280017)
@@ -1,3 +1,49 @@
+2021-07-16  Simon Fraser  <[email protected]>
+
+        getBoundingClientRect() returns the incorrect rectangle on elements whose parent element is set -webkit-column-count
+        https://bugs.webkit.org/show_bug.cgi?id=99959
+        rdar://80106111
+
+        Reviewed by Alan Bujtas.
+        
+        getBoundingClientRect() and getClientRects() for elements inside multicol had a quick
+        and dirty implementation that just mapped the element center point into a column. This
+        resulted in odd, negative top/left in some cases.
+
+        Fix by correctly generating multiple rects for elements that span columns, following
+        the repaint code path that already knew how to do this correctly.
+        
+        The entry point is RenderFragmentContainer::absoluteQuadsForBox() which now has a
+        real implementation. For each fragment that the box covers, it calls fragmentRectsForFlowContentRect()
+        which generates one or more rects; RenderMultiColumnSet overrides this to
+        compute rects for multicol.
+
+        We have to take care not to eliminate empty rects, since the API does return these.
+
+        Tested by existing tests.
+
+        * dom/Element.cpp:
+        (WebCore::Element::absoluteEventBounds):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::absoluteQuadsIgnoringContinuation const):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::absoluteQuads const):
+        * rendering/RenderFragmentContainer.cpp:
+        (WebCore::RenderFragmentContainer::fragmentedFlowContentRectangle):
+        (WebCore::RenderFragmentContainer::fragmentRectsForFlowContentRect):
+        * rendering/RenderFragmentContainer.h:
+        (WebCore::RenderFragmentContainer::absoluteQuadsForBoxInFragment): Deleted.
+        * rendering/RenderFragmentedFlow.cpp:
+        (WebCore::RenderFragmentedFlow::absoluteQuadsForBox const):
+        * rendering/RenderFragmentedFlow.h:
+        * rendering/RenderMultiColumnFlow.h:
+        * rendering/RenderMultiColumnSet.cpp:
+        (WebCore::RenderMultiColumnSet::firstAndLastColumnsFromOffsets const):
+        (WebCore::RenderMultiColumnSet::repaintFragmentedFlowContent):
+        (WebCore::RenderMultiColumnSet::fragmentRectsForFlowContentRect):
+        (WebCore::RenderMultiColumnSet::collectLayerFragments):
+        * rendering/RenderMultiColumnSet.h:
+
 2021-07-16  Kate Cheney  <[email protected]>
 
         WKWebView _javascript_ injection doesn't work if app includes WKAppBoundDomains

Modified: trunk/Source/WebCore/dom/Element.cpp (280016 => 280017)


--- trunk/Source/WebCore/dom/Element.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/dom/Element.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -1528,8 +1528,7 @@
             if (RenderFragmentedFlow* fragmentedFlow = box.enclosingFragmentedFlow()) {
                 bool wasFixed = false;
                 Vector<FloatQuad> quads;
-                FloatRect localRect(0, 0, box.width(), box.height());
-                if (fragmentedFlow->absoluteQuadsForBox(quads, &wasFixed, &box, localRect.y(), localRect.maxY())) {
+                if (fragmentedFlow->absoluteQuadsForBox(quads, &wasFixed, &box)) {
                     result = LayoutRect(unitedBoundingBoxes(quads));
                     computedBounds = true;
                 } else {

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -2796,7 +2796,7 @@
     // FIXME: This is wrong for block-flows that are horizontal.
     // https://bugs.webkit.org/show_bug.cgi?id=46781
     auto* fragmentedFlow = enclosingFragmentedFlow();
-    if (!fragmentedFlow || !fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this, logicalRect.y(), logicalRect.maxY()))
+    if (!fragmentedFlow || !fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this))
         quads.append(localToAbsoluteQuad(logicalRect, UseTransforms, wasFixed));
 }
 

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -632,12 +632,11 @@
 
 void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
 {
-    FloatRect localRect(0, 0, width(), height());
-
     RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow();
-    if (fragmentedFlow && fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this, localRect.y(), localRect.maxY()))
+    if (fragmentedFlow && fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this))
         return;
 
+    auto localRect = FloatRect { 0, 0, width(), height() };
     quads.append(localToAbsoluteQuad(localRect, UseTransforms, wasFixed));
 }
 

Modified: trunk/Source/WebCore/rendering/RenderFragmentContainer.cpp (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderFragmentContainer.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderFragmentContainer.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -258,6 +258,44 @@
     repaintRectangle(clippedRect);
 }
 
+LayoutRect RenderFragmentContainer::fragmentedFlowContentRectangle(const LayoutRect& rect, const LayoutRect& fragmentedFlowPortionRect, const LayoutPoint& fragmentLocation, const LayoutRect* fragmentedFlowPortionClipRect)
+{
+    auto clippedRect = rect;
+
+    if (fragmentedFlowPortionClipRect) {
+        LayoutRect flippedFragmentedFlowPortionClipRect(*fragmentedFlowPortionClipRect);
+        fragmentedFlow()->flipForWritingMode(flippedFragmentedFlowPortionClipRect);
+        clippedRect.edgeInclusiveIntersect(flippedFragmentedFlowPortionClipRect); // edgeInclusiveIntersect to avoid rects with zero height or width becoming zero-sized.
+    }
+
+    LayoutRect flippedFragmentedFlowPortionRect(fragmentedFlowPortionRect);
+    fragmentedFlow()->flipForWritingMode(flippedFragmentedFlowPortionRect);
+
+    // Put the fragment rect into the fragment's physical coordinate space.
+    clippedRect.setLocation(fragmentLocation + (clippedRect.location() - flippedFragmentedFlowPortionRect.location()));
+
+    // Now switch to the fragment's writing mode coordinate space and let it repaint itself.
+    flipForWritingMode(clippedRect);
+    
+    return clippedRect;
+}
+
+Vector<LayoutRect> RenderFragmentContainer::fragmentRectsForFlowContentRect(const LayoutRect& contentRect)
+{
+    auto portionRect = fragmentedFlowPortionRect();
+    auto fragmentLocation = contentBoxRect().location();
+    
+    auto fragmentRect = contentRect;
+    
+    auto flippedFragmentedFlowPortionRect = portionRect;
+    fragmentedFlow()->flipForWritingMode(flippedFragmentedFlowPortionRect);
+    fragmentRect.setLocation(fragmentLocation + (fragmentRect.location() - flippedFragmentedFlowPortionRect.location()));
+
+    flipForWritingMode(fragmentRect);
+
+    return { fragmentRect };
+}
+
 void RenderFragmentContainer::installFragmentedFlow()
 {
     ASSERT_NOT_REACHED();
@@ -381,6 +419,7 @@
     setPreferredLogicalWidthsDirty(false);
 }
 
+// FIXME: Unused.
 void RenderFragmentContainer::adjustFragmentBoundsFromFragmentedFlowPortionRect(LayoutRect& fragmentBounds) const
 {
     LayoutRect flippedFragmentedFlowPortionRect = fragmentedFlowPortionRect();

Modified: trunk/Source/WebCore/rendering/RenderFragmentContainer.h (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderFragmentContainer.h	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderFragmentContainer.h	2021-07-17 05:42:32 UTC (rev 280017)
@@ -119,7 +119,7 @@
     bool canHaveGeneratedChildren() const override { return true; }
     VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
 
-    virtual void absoluteQuadsForBoxInFragment(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) { }
+    virtual Vector<LayoutRect> fragmentRectsForFlowContentRect(const LayoutRect&);
 
 protected:
     RenderFragmentContainer(Element&, RenderStyle&&, RenderFragmentedFlow*);
@@ -138,6 +138,8 @@
     LayoutRect overflowRectForFragmentedFlowPortion(const LayoutRect& fragmentedFlowPortionRect, bool isFirstPortion, bool isLastPortion, OverflowType);
     void repaintFragmentedFlowContentRectangle(const LayoutRect& repaintRect, const LayoutRect& fragmentedFlowPortionRect, const LayoutPoint& fragmentLocation, const LayoutRect* fragmentedFlowPortionClipRect = 0);
 
+    LayoutRect fragmentedFlowContentRectangle(const LayoutRect&, const LayoutRect& fragmentedFlowPortionRect, const LayoutPoint& fragmentLocation, const LayoutRect* fragmentedFlowPortionClipRect = 0);
+
     void computeOverflowFromFragmentedFlow();
 
 private:

Modified: trunk/Source/WebCore/rendering/RenderFragmentedFlow.cpp (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderFragmentedFlow.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderFragmentedFlow.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -218,6 +218,34 @@
         fragment->repaintFragmentedFlowContent(repaintRect);
 }
 
+bool RenderFragmentedFlow::absoluteQuadsForBox(Vector<FloatQuad>& quads, bool* wasFixed, const RenderBox* box) const
+{
+    if (!hasValidFragmentInfo())
+        return false;
+
+    auto boxRect = FloatRect { { }, box->size() };
+    auto boxRectInFlowCoordinates = LayoutRect { box->localToContainerQuad(boxRect, this).boundingBox() };
+
+    RenderFragmentContainer* startFragment = nullptr;
+    RenderFragmentContainer* endFragment = nullptr;
+    if (!computedFragmentRangeForBox(box, startFragment, endFragment))
+        return false;
+
+    for (auto it = m_fragmentList.find(startFragment), end = m_fragmentList.end(); it != end; ++it) {
+        auto* fragment = *it;
+        auto rectsInFragment = fragment->fragmentRectsForFlowContentRect(boxRectInFlowCoordinates);
+        for (auto rect : rectsInFragment) {
+            auto absoluteQuad = fragment->localToAbsoluteQuad(FloatRect(rect), UseTransforms, wasFixed);
+            quads.append(absoluteQuad);
+        }
+
+        if (fragment == endFragment)
+            break;
+    }
+
+    return true;
+}
+
 class RenderFragmentedFlow::FragmentSearchAdapter {
 public:
     explicit FragmentSearchAdapter(LayoutUnit offset)

Modified: trunk/Source/WebCore/rendering/RenderFragmentedFlow.h (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderFragmentedFlow.h	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderFragmentedFlow.h	2021-07-17 05:42:32 UTC (rev 280017)
@@ -162,7 +162,7 @@
 
     bool fragmentInRange(const RenderFragmentContainer* targetFragment, const RenderFragmentContainer* startFragment, const RenderFragmentContainer* endFragment) const;
 
-    virtual bool absoluteQuadsForBox(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) const { return false; }
+    bool absoluteQuadsForBox(Vector<FloatQuad>&, bool*, const RenderBox*) const;
 
     void layout() override;
 

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h	2021-07-17 05:42:32 UTC (rev 280017)
@@ -74,9 +74,9 @@
 
     bool progressionIsReversed() const { return m_progressionIsReversed; }
     void setProgressionIsReversed(bool reversed) { m_progressionIsReversed = reversed; }
-    
-    RenderFragmentContainer* mapFromFlowToFragment(TransformState&) const override;
-    
+
+    RenderFragmentContainer* mapFromFlowToFragment(TransformState&) const final;
+
     // This method takes a logical offset and returns a physical translation that can be applied to map
     // a physical point (corresponding to the logical offset) into the fragment's physical coordinate space.
     LayoutSize physicalTranslationOffsetFromFlowToFragment(const RenderFragmentContainer*, const LayoutUnit) const;

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp	2021-07-17 05:42:32 UTC (rev 280017)
@@ -522,6 +522,36 @@
     return static_cast<float>(offset - fragmentedFlowLogicalTop) / computedColumnHeight();
 }
 
+std::pair<unsigned, unsigned> RenderMultiColumnSet::firstAndLastColumnsFromOffsets(LayoutUnit topOffset, LayoutUnit bottomOffset) const
+{
+    auto portionRect = fragmentedFlowPortionRect();
+
+    // Handle the offset being out of range.
+    auto fragmentedFlowLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x();
+    auto fragmentedFlowLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX();
+
+    auto computeColumnIndex = [&](LayoutUnit offset, bool isBottom) -> unsigned {
+        if (offset < fragmentedFlowLogicalTop)
+            return 0;
+
+        if (offset >= fragmentedFlowLogicalBottom)
+            return columnCount() - 1;
+
+        // Sometimes computedColumnHeight() is 0 here: see https://bugs.webkit.org/show_bug.cgi?id=132884
+        auto columnHeight = computedColumnHeight();
+        if (!columnHeight)
+            return 0;
+
+        auto columnIndex = static_cast<float>(offset - fragmentedFlowLogicalTop) / columnHeight;
+        if (isBottom && WTF::isIntegral(columnIndex) && columnIndex > 0)
+            columnIndex -= 1;
+
+        return static_cast<unsigned>(columnIndex);
+    };
+
+    return { computeColumnIndex(topOffset, false), computeColumnIndex(bottomOffset, true) };
+}
+
 LayoutRect RenderMultiColumnSet::fragmentedFlowPortionRectAt(unsigned index) const
 {
     LayoutRect portionRect = fragmentedFlowPortionRect();
@@ -677,6 +707,7 @@
     LayoutUnit repaintLogicalTop = isHorizontalWritingMode() ? fragmentedFlowRepaintRect.y() : fragmentedFlowRepaintRect.x();
     LayoutUnit repaintLogicalBottom = (isHorizontalWritingMode() ? fragmentedFlowRepaintRect.maxY() : fragmentedFlowRepaintRect.maxX()) - 1;
     
+    // FIXME: this should use firstAndLastColumnsFromOffsets.
     unsigned startColumn = columnIndexAtOffset(repaintLogicalTop);
     unsigned endColumn = columnIndexAtOffset(repaintLogicalBottom);
     
@@ -697,6 +728,35 @@
     }
 }
 
+Vector<LayoutRect> RenderMultiColumnSet::fragmentRectsForFlowContentRect(const LayoutRect& rect)
+{
+    auto fragmentedFlowRect = rect;
+    fragmentedFlow()->flipForWritingMode(fragmentedFlowRect);
+
+    auto logicalTop = isHorizontalWritingMode() ? fragmentedFlowRect.y() : fragmentedFlowRect.x();
+    auto logicalBottom = isHorizontalWritingMode() ? fragmentedFlowRect.maxY() : fragmentedFlowRect.maxX();
+
+    auto startAndEndColumns = firstAndLastColumnsFromOffsets(logicalTop, logicalBottom);
+
+    Vector<LayoutRect> perColumnRects;
+    
+    LayoutUnit colGap = columnGap();
+    unsigned colCount = columnCount();
+    for (unsigned i = startAndEndColumns.first; i <= startAndEndColumns.second; i++) {
+        auto colRect = columnRectAt(i);
+        flipForWritingMode(colRect);
+        
+        auto fragmentedFlowPortion = fragmentedFlowPortionRectAt(i);
+        auto fragmentedFlowOverflowPortion = fragmentedFlowPortionOverflowRect(fragmentedFlowPortion, i, colCount, colGap);
+
+        auto rectInColumn = fragmentedFlowContentRectangle(rect, fragmentedFlowPortion, colRect.location(), &fragmentedFlowOverflowPortion);
+        flipForWritingMode(rectInColumn);
+        perColumnRects.append(rectInColumn);
+    }
+
+    return perColumnRects;
+}
+
 LayoutUnit RenderMultiColumnSet::initialBlockOffsetForPainting() const
 {
     bool progressionReversed = multiColumnFlow()->progressionIsReversed();
@@ -756,6 +816,7 @@
     
     // Figure out the start and end columns and only check within that range so that we don't walk the
     // entire column set.
+    // FIXME: this should use firstAndLastColumnsFromOffsets.
     unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
     unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
     

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.h (280016 => 280017)


--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.h	2021-07-17 03:24:25 UTC (rev 280016)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.h	2021-07-17 05:42:32 UTC (rev 280017)
@@ -165,6 +165,8 @@
 
     void adjustFragmentBoundsFromFragmentedFlowPortionRect(LayoutRect& fragmentBounds) const override;
 
+    Vector<LayoutRect> fragmentRectsForFlowContentRect(const LayoutRect&) final;
+
     VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
 
     const char* renderName() const override;
@@ -185,6 +187,8 @@
     };
     unsigned columnIndexAtOffset(LayoutUnit, ColumnIndexCalculationMode = ClampToExistingColumns) const;
 
+    std::pair<unsigned, unsigned> firstAndLastColumnsFromOffsets(LayoutUnit topOffset, LayoutUnit bottomOffset) const;
+
     void setAndConstrainColumnHeight(LayoutUnit);
 
     // Return the index of the content run with the currently tallest columns, taking all implicit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to