[go: up one dir, main page]

Merge 3809: [LayoutNG] Fix selection rect to unite text and line

When LayoutNG tries to extend the selection rect to the line
height, the height is set to the line height instead of being
united. It made the selection rect smaller when the line has
smaller height than the text.

This patch fixes to unite.

(cherry picked from commit 15155458fc6f1d089356e1729fc8a41bd25fb546)

Bug: 973302
Change-Id: I6a2ef38b0f682cc7d3f91858ecbcaf4a88ec819c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1657879
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#668983}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1660075
Reviewed-by: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#342}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/third_party/blink/renderer/core/layout/geometry/logical_rect.h b/third_party/blink/renderer/core/layout/geometry/logical_rect.h
index 457a9fe..b6196671 100644
--- a/third_party/blink/renderer/core/layout/geometry/logical_rect.h
+++ b/third_party/blink/renderer/core/layout/geometry/logical_rect.h
@@ -46,9 +46,16 @@
   LogicalOffset offset;
   LogicalSize size;
 
-  LogicalOffset EndOffset() const { return offset + size; }
   constexpr bool IsEmpty() const { return size.IsEmpty(); }
 
+  LayoutUnit InlineEndOffset() const {
+    return offset.inline_offset + size.inline_size;
+  }
+  LayoutUnit BlockEndOffset() const {
+    return offset.block_offset + size.block_size;
+  }
+  LogicalOffset EndOffset() const { return offset + size; }
+
   constexpr bool operator==(const LogicalRect& other) const {
     return other.offset == offset && other.size == size;
   }
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc
index f8b7005..671bb18 100644
--- a/third_party/blink/renderer/core/layout/layout_text_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -773,6 +773,23 @@
                                 "foo bar b^a|</div>"));
 }
 
+TEST_P(ParameterizedLayoutTextTest, LocalSelectionRectNegativeLeading) {
+  LoadAhem();
+  SetSelectionAndUpdateLayoutSelection(R"HTML(
+    <div id="container" style="font: 10px/10px Ahem">
+      ^
+      <span id="span" style="display: inline-block; line-height: 1px">
+        Text
+      </span>
+      |
+    </div>
+  )HTML");
+  LayoutObject* span = GetLayoutObjectByElementId("span");
+  LayoutObject* text = span->SlowFirstChild();
+  EXPECT_EQ(PhysicalRect(0, -5, LayoutNGEnabled() ? 40 : 50, 10),
+            text->LocalSelectionVisualRect());
+}
+
 TEST_P(ParameterizedLayoutTextTest, LocalSelectionRectLineHeightVertical) {
   LoadAhem();
   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(0, 10, 50, 10)
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 3a1c78f..674dbd8 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -94,6 +94,7 @@
 LogicalRect ExpandSelectionRectToLineHeight(
     const LogicalRect& rect,
     const NGPaintFragment& paint_fragment) {
+  // Compute the rect of the containing line box relative to |paint_fragment|.
   const NGPaintFragment* current_line = paint_fragment.ContainerLineBox();
   DCHECK(current_line);
   const PhysicalRect line_physical_rect(
@@ -102,8 +103,14 @@
       current_line->Size());
   const LogicalRect line_logical_rect =
       ComputeLogicalRectFor(line_physical_rect, paint_fragment);
-  return {{rect.offset.inline_offset, line_logical_rect.offset.block_offset},
-          {rect.size.inline_size, line_logical_rect.size.block_size}};
+
+  // Unite the rect only in the block direction.
+  LayoutUnit selection_top =
+      std::min(rect.offset.block_offset, line_logical_rect.offset.block_offset);
+  LayoutUnit selection_bottom =
+      std::max(rect.BlockEndOffset(), line_logical_rect.BlockEndOffset());
+  return {{rect.offset.inline_offset, selection_top},
+          {rect.size.inline_size, selection_bottom - selection_top}};
 }
 
 LogicalOffset ChildLogicalOffsetInParent(const NGPaintFragment& child) {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/selection-rect-line-height-too-small-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/selection-rect-line-height-too-small-expected.png
index 04f9505..302922b 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/selection-rect-line-height-too-small-expected.png
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/selection-rect-line-height-too-small-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png
index dc4db36..b9105ca49 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.txt
index 6cf00f0..5f51a1b 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.txt
@@ -19,7 +19,7 @@
       "paintInvalidations": [
         {
           "object": "NGPhysicalTextFragment '\u7B2C\u4E00\u6BB5\u843D paragraph 1'",
-          "rect": [549, 191, 21, 36],
+          "rect": [548, 191, 23, 36],
           "reason": "selection"
         }
       ]
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/text/selection-no-clip-text-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/text/selection-no-clip-text-expected.png
index 975d596..e95ce48 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/text/selection-no-clip-text-expected.png
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/text/selection-no-clip-text-expected.png
Binary files differ