Title: [270220] trunk/Source/WebCore
Revision
270220
Author
[email protected]
Date
2020-11-28 11:37:32 -0800 (Sat, 28 Nov 2020)

Log Message

Move caret rect computation out of render tree
https://bugs.webkit.org/show_bug.cgi?id=219304

Reviewed by Zalan Bujtas.

Reduce code randomly sprinkled on renderers by moving it into standalone functions.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::localCaretRectForCharacterOffset):
* editing/RenderedPosition.cpp:
(WebCore::RenderedPosition::absoluteRect const):
* editing/RenderedPosition.h:
* editing/VisiblePosition.cpp:
(WebCore::VisiblePosition::localCaretRect const):
* rendering/CaretRectComputation.cpp: Added.
(WebCore::computeCaretRectForEmptyElement):
(WebCore::computeCaretRectForLinePosition):
(WebCore::computeCaretRectForText):
(WebCore::computeCaretRectForLineBreak):
(WebCore::computeCaretRectForSVGInlineText):
(WebCore::computeCaretRectForBox):
(WebCore::computeCaretRectForBlock):
(WebCore::computeCaretRectForInline):
(WebCore::computeLocalCaretRect):
* rendering/CaretRectComputation.h: Added.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::localCaretRect const): Deleted.
* rendering/RenderBlock.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::computeCaretRect const): Deleted.
* rendering/RenderBlockFlow.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::localCaretRect const): Deleted.
* rendering/RenderBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::localCaretRectForEmptyElement const): Deleted.
* rendering/RenderBoxModelObject.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::localCaretRect const): Deleted.
* rendering/RenderInline.h:
* rendering/RenderLineBreak.cpp:
(WebCore::RenderLineBreak::localCaretRect const): Deleted.
* rendering/RenderLineBreak.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::localCaretRect const): Deleted.
* rendering/RenderObject.h:
* rendering/RenderObjectEnums.h:
* rendering/RenderText.cpp:
(WebCore::RenderText::localCaretRect const): Deleted.
* rendering/RenderText.h:
* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::localCaretRect const): Deleted.
* rendering/svg/RenderSVGInlineText.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270219 => 270220)


--- trunk/Source/WebCore/ChangeLog	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/ChangeLog	2020-11-28 19:37:32 UTC (rev 270220)
@@ -1,3 +1,61 @@
+2020-11-28  Antti Koivisto  <[email protected]>
+
+        Move caret rect computation out of render tree
+        https://bugs.webkit.org/show_bug.cgi?id=219304
+
+        Reviewed by Zalan Bujtas.
+
+        Reduce code randomly sprinkled on renderers by moving it into standalone functions.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::localCaretRectForCharacterOffset):
+        * editing/RenderedPosition.cpp:
+        (WebCore::RenderedPosition::absoluteRect const):
+        * editing/RenderedPosition.h:
+        * editing/VisiblePosition.cpp:
+        (WebCore::VisiblePosition::localCaretRect const):
+        * rendering/CaretRectComputation.cpp: Added.
+        (WebCore::computeCaretRectForEmptyElement):
+        (WebCore::computeCaretRectForLinePosition):
+        (WebCore::computeCaretRectForText):
+        (WebCore::computeCaretRectForLineBreak):
+        (WebCore::computeCaretRectForSVGInlineText):
+        (WebCore::computeCaretRectForBox):
+        (WebCore::computeCaretRectForBlock):
+        (WebCore::computeCaretRectForInline):
+        (WebCore::computeLocalCaretRect):
+        * rendering/CaretRectComputation.h: Added.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::localCaretRect const): Deleted.
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::computeCaretRect const): Deleted.
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::localCaretRect const): Deleted.
+        * rendering/RenderBox.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::localCaretRectForEmptyElement const): Deleted.
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::localCaretRect const): Deleted.
+        * rendering/RenderInline.h:
+        * rendering/RenderLineBreak.cpp:
+        (WebCore::RenderLineBreak::localCaretRect const): Deleted.
+        * rendering/RenderLineBreak.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::localCaretRect const): Deleted.
+        * rendering/RenderObject.h:
+        * rendering/RenderObjectEnums.h:
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::localCaretRect const): Deleted.
+        * rendering/RenderText.h:
+        * rendering/svg/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::localCaretRect const): Deleted.
+        * rendering/svg/RenderSVGInlineText.h:
+
 2020-11-28  Don Olmstead  <[email protected]>
 
         Remove enums for GCGLenum constants in GraphicsContextGL and ExtensionsGL

Modified: trunk/Source/WebCore/Sources.txt (270219 => 270220)


--- trunk/Source/WebCore/Sources.txt	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/Sources.txt	2020-11-28 19:37:32 UTC (rev 270220)
@@ -2154,6 +2154,7 @@
 rendering/BorderEdge.cpp
 rendering/BreakLines.cpp
 rendering/CSSFilter.cpp
+rendering/CaretRectComputation.cpp
 rendering/ClipRect.cpp
 rendering/ComplexLineLayout.cpp
 rendering/ContentfulPaintChecker.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (270219 => 270220)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-28 19:37:32 UTC (rev 270220)
@@ -5160,6 +5160,7 @@
 		E4E8B4EC216B79E500B8834D /* SystemFontDatabaseCoreText.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8B4EA216B79E500B8834D /* SystemFontDatabaseCoreText.h */; };
 		E4E8B4F5216B956500B8834D /* FontCascadeDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8B4F2216B8B6000B8834D /* FontCascadeDescription.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4E94D6122FF158A00DD191F /* ComplexLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E4A1AC7822FAFD500017B75B /* ComplexLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */; };
 		E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E50620842540919C00C43091 /* ContactsRequestData.h in Headers */ = {isa = PBXBuildFile; fileRef = E50620832540919B00C43091 /* ContactsRequestData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E516699120FF9918009D2C27 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = E516698F20FF9916009D2C27 /* [email protected] */; };
@@ -16337,6 +16338,8 @@
 		E4E8B4ED216B79F400B8834D /* SystemFontDatabaseCoreText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemFontDatabaseCoreText.cpp; sourceTree = "<group>"; };
 		E4E8B4F0216B8B5F00B8834D /* FontCascadeDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontCascadeDescription.cpp; sourceTree = "<group>"; };
 		E4E8B4F2216B8B6000B8834D /* FontCascadeDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontCascadeDescription.h; sourceTree = "<group>"; };
+		E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaretRectComputation.h; sourceTree = "<group>"; };
+		E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaretRectComputation.cpp; sourceTree = "<group>"; };
 		E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
 		E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
 		E4FB4B35239BEB10003C336A /* LayoutIntegrationInlineContent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationInlineContent.cpp; sourceTree = "<group>"; };
@@ -29445,6 +29448,8 @@
 				589556EC18D4A44000764B03 /* BorderEdge.h */,
 				BCEA4815097D93020094C9E4 /* BreakLines.cpp */,
 				BCEA4816097D93020094C9E4 /* BreakLines.h */,
+				E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */,
+				E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */,
 				FB92DF4915FED08700994433 /* ClipPathOperation.h */,
 				5803715F1A66F00A00BAF519 /* ClipRect.cpp */,
 				580371601A66F00A00BAF519 /* ClipRect.h */,
@@ -35112,6 +35117,7 @@
 				A0EE0DF8144F825500F80B0D /* WebGLDebugShaders.h in Headers */,
 				6E3FAE8F14733FDB00E42307 /* WebGLDepthTexture.h in Headers */,
 				5B30695E18B3D3450099D5E8 /* WebGLDrawBuffers.h in Headers */,
+				E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */,
 				6EBF0E5512A8929800DB1709 /* WebGLExtension.h in Headers */,
 				49C7B9CF1042D32F0009D447 /* WebGLFramebuffer.h in Headers */,
 				49FFBF3F11C93EE3006A7118 /* WebGLLayer.h in Headers */,

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (270219 => 270220)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -64,6 +64,7 @@
 #include "AccessibilityTableRow.h"
 #include "AccessibilityTree.h"
 #include "AccessibilityTreeItem.h"
+#include "CaretRectComputation.h"
 #include "Document.h"
 #include "Editing.h"
 #include "Editor.h"
@@ -2902,7 +2903,7 @@
     if (is<RenderLineBreak>(renderer) && LayoutIntegration::runFor(downcast<RenderLineBreak>(*renderer)) != runAndOffset.run)
         return IntRect();
 
-    return renderer->localCaretRect(runAndOffset);
+    return computeLocalCaretRect(*renderer, runAndOffset);
 }
 
 IntRect AXObjectCache::absoluteCaretBoundsForCharacterOffset(const CharacterOffset& characterOffset)

Modified: trunk/Source/WebCore/editing/RenderedPosition.cpp (270219 => 270220)


--- trunk/Source/WebCore/editing/RenderedPosition.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/editing/RenderedPosition.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "RenderedPosition.h"
 
+#include "CaretRectComputation.h"
 #include "InlineRunAndOffset.h"
 #include "InlineTextBox.h"
 #include "VisiblePosition.h"
@@ -226,7 +227,7 @@
     if (isNull())
         return IntRect();
 
-    IntRect localRect = snappedIntRect(m_renderer->localCaretRect({ m_run, m_offset }, caretRectMode));
+    IntRect localRect = snappedIntRect(computeLocalCaretRect(*m_renderer, { m_run, m_offset }, caretRectMode));
     return localRect == IntRect() ? IntRect() : m_renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
 }
 

Modified: trunk/Source/WebCore/editing/RenderedPosition.h (270219 => 270220)


--- trunk/Source/WebCore/editing/RenderedPosition.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/editing/RenderedPosition.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -30,6 +30,7 @@
 
 #pragma once
 
+#include "CaretRectComputation.h"
 #include "LayoutIntegrationLineIterator.h"
 #include "LayoutIntegrationRunIterator.h"
 #include "TextAffinity.h"

Modified: trunk/Source/WebCore/editing/VisiblePosition.cpp (270219 => 270220)


--- trunk/Source/WebCore/editing/VisiblePosition.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/editing/VisiblePosition.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -28,6 +28,7 @@
 #include "VisiblePosition.h"
 
 #include "BoundaryPoint.h"
+#include "CaretRectComputation.h"
 #include "Document.h"
 #include "Editing.h"
 #include "FloatQuad.h"
@@ -643,7 +644,7 @@
     if (!renderer)
         return { };
 
-    return { renderer->localCaretRect(runAndOffset), const_cast<RenderObject*>(renderer) };
+    return { computeLocalCaretRect(*renderer, runAndOffset), const_cast<RenderObject*>(renderer) };
 }
 
 IntRect VisiblePosition::absoluteCaretBounds(bool* insideFixed) const

Added: trunk/Source/WebCore/rendering/CaretRectComputation.cpp (0 => 270220)


--- trunk/Source/WebCore/rendering/CaretRectComputation.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/CaretRectComputation.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CaretRectComputation.h"
+
+#include "Editing.h"
+#include "LayoutIntegrationLineIterator.h"
+#include "LayoutIntegrationRunIterator.h"
+#include "RenderBlockFlow.h"
+#include "RenderInline.h"
+#include "RenderLineBreak.h"
+#include "RenderSVGInlineText.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+static LayoutRect computeCaretRectForEmptyElement(const RenderBoxModelObject& renderer, LayoutUnit width, LayoutUnit textIndentOffset, CaretRectMode caretRectMode)
+{
+    ASSERT(!renderer.firstChild());
+
+    // FIXME: This does not take into account either :first-line or :first-letter
+    // However, as soon as some content is entered, the line boxes will be
+    // constructed and this kludge is not called any more. So only the caret size
+    // of an empty :first-line'd block is wrong. I think we can live with that.
+    const RenderStyle& currentStyle = renderer.firstLineStyle();
+
+    enum CaretAlignment { AlignLeft, AlignRight, AlignCenter };
+
+    CaretAlignment alignment = AlignLeft;
+
+    switch (currentStyle.textAlign()) {
+    case TextAlignMode::Left:
+    case TextAlignMode::WebKitLeft:
+        break;
+    case TextAlignMode::Center:
+    case TextAlignMode::WebKitCenter:
+        alignment = AlignCenter;
+        break;
+    case TextAlignMode::Right:
+    case TextAlignMode::WebKitRight:
+        alignment = AlignRight;
+        break;
+    case TextAlignMode::Justify:
+    case TextAlignMode::Start:
+        if (!currentStyle.isLeftToRightDirection())
+            alignment = AlignRight;
+        break;
+    case TextAlignMode::End:
+        if (currentStyle.isLeftToRightDirection())
+            alignment = AlignRight;
+        break;
+    }
+
+    LayoutUnit x = renderer.borderLeft() + renderer.paddingLeft();
+    LayoutUnit maxX = width - renderer.borderRight() - renderer.paddingRight();
+
+    switch (alignment) {
+    case AlignLeft:
+        if (currentStyle.isLeftToRightDirection())
+            x += textIndentOffset;
+        break;
+    case AlignCenter:
+        x = (x + maxX) / 2;
+        if (currentStyle.isLeftToRightDirection())
+            x += textIndentOffset / 2;
+        else
+            x -= textIndentOffset / 2;
+        break;
+    case AlignRight:
+        x = maxX - caretWidth;
+        if (!currentStyle.isLeftToRightDirection())
+            x -= textIndentOffset;
+        break;
+    }
+    x = std::min(x, std::max<LayoutUnit>(maxX - caretWidth, 0));
+
+    auto lineHeight = renderer.lineHeight(true, currentStyle.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+    auto height = std::min(lineHeight, LayoutUnit { currentStyle.fontMetrics().height() });
+    auto y = renderer.paddingTop() + renderer.borderTop() + (lineHeight > height ? (lineHeight - height) / 2 : LayoutUnit { });
+
+    auto rect = LayoutRect(x, y, caretWidth, height);
+
+    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
+        rect.shiftMaxXEdgeTo(width);
+
+    return currentStyle.isHorizontalWritingMode() ? rect : rect.transposedRect();
+}
+
+static LayoutRect computeCaretRectForLinePosition(const LayoutIntegration::LineIterator& line, float logicalLeftPosition, CaretRectMode caretRectMode)
+{
+    auto& containingBlock = line->containingBlock();
+    auto lineSelectionRect = line->selectionRect();
+
+    int height = lineSelectionRect.height();
+    int top = lineSelectionRect.y();
+
+    // Distribute the caret's width to either side of the offset.
+    float left = logicalLeftPosition;
+    int caretWidthLeftOfOffset = caretWidth / 2;
+    left -= caretWidthLeftOfOffset;
+    int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
+    left = roundf(left);
+
+    float lineLeft = lineSelectionRect.x();
+    float lineRight = lineSelectionRect.maxX();
+
+    bool rightAligned = false;
+    switch (containingBlock.style().textAlign()) {
+    case TextAlignMode::Right:
+    case TextAlignMode::WebKitRight:
+        rightAligned = true;
+        break;
+    case TextAlignMode::Left:
+    case TextAlignMode::WebKitLeft:
+    case TextAlignMode::Center:
+    case TextAlignMode::WebKitCenter:
+        break;
+    case TextAlignMode::Justify:
+    case TextAlignMode::Start:
+        rightAligned = !containingBlock.style().isLeftToRightDirection();
+        break;
+    case TextAlignMode::End:
+        rightAligned = containingBlock.style().isLeftToRightDirection();
+        break;
+    }
+
+    float leftEdge = std::min<float>(0, lineLeft);
+    float rightEdge = std::max<float>(containingBlock.logicalWidth(), lineRight);
+
+    if (rightAligned) {
+        left = std::max(left, leftEdge);
+        left = std::min(left, lineRight - caretWidth);
+    } else {
+        left = std::min(left, rightEdge - caretWidthRightOfOffset);
+        left = std::max(left, lineLeft);
+    }
+
+    auto rect = IntRect(left, top, caretWidth, height);
+
+    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
+        rect.shiftMaxXEdgeTo(lineRight);
+
+    return containingBlock.style().isHorizontalWritingMode() ? rect : rect.transposedRect();
+}
+
+static LayoutRect computeCaretRectForText(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode)
+{
+    if (!runAndOffset.run)
+        return { };
+
+    auto& textRun = downcast<LayoutIntegration::TextRunIterator>(runAndOffset.run);
+    auto line = textRun.line();
+
+    float position = textRun->positionForOffset(runAndOffset.offset);
+    return computeCaretRectForLinePosition(line, position, caretRectMode);
+}
+
+static LayoutRect computeCaretRectForLineBreak(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode)
+{
+    ASSERT(!runAndOffset.offset);
+
+    if (!runAndOffset.run)
+        return { };
+
+    auto line = runAndOffset.run.line();
+    return computeCaretRectForLinePosition(line, line->contentLogicalLeft(), caretRectMode);
+}
+
+static LayoutRect computeCaretRectForSVGInlineText(const InlineRunAndOffset& runAndOffset, CaretRectMode)
+{
+    auto* box = runAndOffset.run ? runAndOffset.run->legacyInlineBox() : nullptr;
+    auto caretOffset = runAndOffset.offset;
+
+    if (!is<InlineTextBox>(box))
+        return { };
+
+    auto& textBox = downcast<InlineTextBox>(*box);
+    if (caretOffset < textBox.start() || caretOffset > textBox.start() + textBox.len())
+        return { };
+
+    // Use the edge of the selection rect to determine the caret rect.
+    if (caretOffset < textBox.start() + textBox.len()) {
+        LayoutRect rect = textBox.localSelectionRect(caretOffset, caretOffset + 1);
+        LayoutUnit x = textBox.isLeftToRightDirection() ? rect.x() : rect.maxX();
+        return LayoutRect(x, rect.y(), caretWidth, rect.height());
+    }
+
+    LayoutRect rect = textBox.localSelectionRect(caretOffset - 1, caretOffset);
+    LayoutUnit x = textBox.isLeftToRightDirection() ? rect.maxX() : rect.x();
+    return { x, rect.y(), caretWidth, rect.height() };
+}
+
+static LayoutRect computeCaretRectForBox(const RenderBox& renderer, const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode)
+{
+    // VisiblePositions at offsets inside containers either a) refer to the positions before/after
+    // those containers (tables and select elements) or b) refer to the position inside an empty block.
+    // They never refer to children.
+    // FIXME: Paint the carets inside empty blocks differently than the carets before/after elements.
+
+    LayoutRect rect(renderer.location(), LayoutSize(caretWidth, renderer.height()));
+    bool ltr = runAndOffset.run ? runAndOffset.run->isLeftToRightDirection() : renderer.style().isLeftToRightDirection();
+
+    if ((!runAndOffset.offset) ^ ltr)
+        rect.move(LayoutSize(renderer.width() - caretWidth, 0_lu));
+
+    if (runAndOffset.run) {
+        auto line = runAndOffset.run.line();
+        LayoutUnit top = line->top();
+        rect.setY(top);
+        rect.setHeight(line->bottom() - top);
+    }
+
+    // If height of box is smaller than font height, use the latter one,
+    // otherwise the caret might become invisible.
+    //
+    // Also, if the box is not a replaced element, always use the font height.
+    // This prevents the "big caret" bug described in:
+    // <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
+    //
+    // FIXME: ignoring :first-line, missing good reason to take care of
+    LayoutUnit fontHeight = renderer.style().fontMetrics().height();
+    if (fontHeight > rect.height() || (!renderer.isReplaced() && !renderer.isTable()))
+        rect.setHeight(fontHeight);
+
+    // Move to local coords
+    rect.moveBy(-renderer.location());
+
+    // FIXME: Border/padding should be added for all elements but this workaround
+    // is needed because we use offsets inside an "atomic" element to represent
+    // positions before and after the element in deprecated editing offsets.
+    if (renderer.element() && !(editingIgnoresContent(*renderer.element()) || isRenderedTable(renderer.element()))) {
+        rect.setX(rect.x() + renderer.borderLeft() + renderer.paddingLeft());
+        rect.setY(rect.y() + renderer.paddingTop() + renderer.borderTop());
+    }
+
+    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
+        rect.shiftMaxXEdgeTo(renderer.x() + renderer.width());
+
+    return renderer.isHorizontalWritingMode() ? rect : rect.transposedRect();
+}
+
+static LayoutRect computeCaretRectForBlock(const RenderBlock& renderer, const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode)
+{
+    // Do the normal calculation in most cases.
+    if (renderer.firstChild())
+        return computeCaretRectForBox(renderer, runAndOffset, caretRectMode);
+
+    return computeCaretRectForEmptyElement(renderer, renderer.width(), renderer.textIndentOffset(), caretRectMode);
+}
+
+static LayoutRect computeCaretRectForInline(const RenderInline& renderer)
+{
+    if (renderer.firstChild()) {
+        // This condition is possible if the RenderInline is at an editing boundary,
+        // i.e. the VisiblePosition is:
+        //   <RenderInline editingBoundary=true>|<RenderText> </RenderText></RenderInline>
+        // FIXME: need to figure out how to make this return a valid rect, note that
+        // there are no line boxes created in the above case.
+        return { };
+    }
+
+    LayoutRect caretRect = computeCaretRectForEmptyElement(renderer, renderer.horizontalBorderAndPaddingExtent(), 0, CaretRectMode::Normal);
+
+    if (InlineBox* firstBox = renderer.firstLineBox())
+        caretRect.moveBy(LayoutPoint(firstBox->topLeft()));
+
+    return caretRect;
+}
+
+LayoutRect computeLocalCaretRect(const RenderObject& renderer, const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode)
+{
+    if (is<RenderSVGInlineText>(renderer))
+        return computeCaretRectForSVGInlineText(runAndOffset, caretRectMode);
+
+    if (is<RenderText>(renderer))
+        return computeCaretRectForText(runAndOffset, caretRectMode);
+
+    if (is<RenderLineBreak>(renderer))
+        return computeCaretRectForLineBreak(runAndOffset, caretRectMode);
+
+    if (is<RenderBlock>(renderer))
+        return computeCaretRectForBlock(downcast<RenderBlock>(renderer), runAndOffset, caretRectMode);
+
+    if (is<RenderBox>(renderer))
+        return computeCaretRectForBox(downcast<RenderBox>(renderer), runAndOffset, caretRectMode);
+
+    if (is<RenderInline>(renderer))
+        return computeCaretRectForInline(downcast<RenderInline>(renderer));
+
+    return { };
+}
+
+};

Added: trunk/Source/WebCore/rendering/CaretRectComputation.h (0 => 270220)


--- trunk/Source/WebCore/rendering/CaretRectComputation.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/CaretRectComputation.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InlineRunAndOffset.h"
+#include "RenderObjectEnums.h"
+
+namespace WebCore {
+
+enum class CaretRectMode {
+    Normal,
+    ExpandToEndOfLine
+};
+
+LayoutRect computeLocalCaretRect(const RenderObject&, const InlineRunAndOffset&, CaretRectMode = CaretRectMode::Normal);
+
+};

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -2841,15 +2841,6 @@
     }
 }
 
-LayoutRect RenderBlock::localCaretRect(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode) const
-{
-    // Do the normal calculation in most cases.
-    if (firstChild())
-        return RenderBox::localCaretRect(runAndOffset, caretRectMode);
-
-    return localCaretRectForEmptyElement(width(), textIndentOffset(), caretRectMode);
-}
-
 void RenderBlock::addFocusRingRectsForInlineChildren(Vector<LayoutRect>&, const LayoutPoint&, const RenderLayerModelObject*)
 {
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -484,8 +484,6 @@
 
     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
 
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const final;
-    
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&, const RenderFragmentContainer*);
 

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -4440,59 +4440,5 @@
     maxLogicalWidth = preferredWidth(maxLogicalWidth, inlineMax);
 }
 
-LayoutRect RenderBlockFlow::computeCaretRect(const LayoutRect& lineSelectionRect, float logicalLeftPosition, unsigned caretWidth, CaretRectMode caretRectMode) const
-{
-    int height = lineSelectionRect.height();
-    int top = lineSelectionRect.y();
-
-    // Distribute the caret's width to either side of the offset.
-    float left = logicalLeftPosition;
-    int caretWidthLeftOfOffset = caretWidth / 2;
-    left -= caretWidthLeftOfOffset;
-    int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
-    left = roundf(left);
-
-    float lineLeft = lineSelectionRect.x();
-    float lineRight = lineSelectionRect.maxX();
-
-    bool rightAligned = false;
-    switch (style().textAlign()) {
-    case TextAlignMode::Right:
-    case TextAlignMode::WebKitRight:
-        rightAligned = true;
-        break;
-    case TextAlignMode::Left:
-    case TextAlignMode::WebKitLeft:
-    case TextAlignMode::Center:
-    case TextAlignMode::WebKitCenter:
-        break;
-    case TextAlignMode::Justify:
-    case TextAlignMode::Start:
-        rightAligned = !style().isLeftToRightDirection();
-        break;
-    case TextAlignMode::End:
-        rightAligned = style().isLeftToRightDirection();
-        break;
-    }
-
-    float leftEdge = std::min<float>(0, lineLeft);
-    float rightEdge = std::max<float>(logicalWidth(), lineRight);
-
-    if (rightAligned) {
-        left = std::max(left, leftEdge);
-        left = std::min(left, lineRight - caretWidth);
-    } else {
-        left = std::min(left, rightEdge - caretWidthRightOfOffset);
-        left = std::max(left, lineLeft);
-    }
-
-    auto rect = IntRect(left, top, caretWidth, height);
-
-    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
-        rect.shiftMaxXEdgeTo(lineRight);
-
-    return style().isHorizontalWritingMode() ? rect : rect.transposedRect();
 }
-
-}
 // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -398,7 +398,6 @@
     void addFloatsToNewParent(RenderBlockFlow& toBlockFlow) const;
     
     LayoutUnit endPaddingWidthForCaret() const;
-    LayoutRect computeCaretRect(const LayoutRect& lineSelectionRect, float logicalLeftPosition, unsigned caretWidth, CaretRectMode = CaretRectMode::Normal) const;
 
 protected:
     bool shouldResetLogicalHeightBeforeLayout() const override { return true; }

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -4432,55 +4432,6 @@
     computedValues.m_position = logicalTopPos;
 }
 
-LayoutRect RenderBox::localCaretRect(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode) const
-{
-    // VisiblePositions at offsets inside containers either a) refer to the positions before/after
-    // those containers (tables and select elements) or b) refer to the position inside an empty block.
-    // They never refer to children.
-    // FIXME: Paint the carets inside empty blocks differently than the carets before/after elements.
-
-    LayoutRect rect(location(), LayoutSize(caretWidth, height()));
-    bool ltr = runAndOffset.run ? runAndOffset.run->isLeftToRightDirection() : style().isLeftToRightDirection();
-
-    if ((!runAndOffset.offset) ^ ltr)
-        rect.move(LayoutSize(width() - caretWidth, 0_lu));
-
-    if (runAndOffset.run) {
-        auto line = runAndOffset.run.line();
-        LayoutUnit top = line->top();
-        rect.setY(top);
-        rect.setHeight(line->bottom() - top);
-    }
-
-    // If height of box is smaller than font height, use the latter one,
-    // otherwise the caret might become invisible.
-    //
-    // Also, if the box is not a replaced element, always use the font height.
-    // This prevents the "big caret" bug described in:
-    // <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
-    //
-    // FIXME: ignoring :first-line, missing good reason to take care of
-    LayoutUnit fontHeight = style().fontMetrics().height();
-    if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
-        rect.setHeight(fontHeight);
-
-    // Move to local coords
-    rect.moveBy(-location());
-
-    // FIXME: Border/padding should be added for all elements but this workaround
-    // is needed because we use offsets inside an "atomic" element to represent
-    // positions before and after the element in deprecated editing offsets.
-    if (element() && !(editingIgnoresContent(*element()) || isRenderedTable(element()))) {
-        rect.setX(rect.x() + borderLeft() + paddingLeft());
-        rect.setY(rect.y() + paddingTop() + borderTop());
-    }
-
-    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
-        rect.shiftMaxXEdgeTo(x() + width());
-
-    return isHorizontalWritingMode() ? rect : rect.transposedRect();
-}
-
 VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point, const RenderFragmentContainer* fragment)
 {
     // no children...return this render object's element, if there is one, and offset 0

Modified: trunk/Source/WebCore/rendering/RenderBox.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBox.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -497,8 +497,6 @@
     bool isUnsplittableForPagination() const;
 
     bool shouldTreatChildAsReplacedInTableCells() const;
-    
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const override;
 
     virtual LayoutRect overflowClipRect(const LayoutPoint& location, RenderFragmentContainer* = nullptr, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, PaintPhase = PaintPhase::BlockBackground) const;
     virtual LayoutRect overflowClipRectForChildLayers(const LayoutPoint& location, RenderFragmentContainer* fragment, OverlayScrollbarSizeRelevancy relevancy) const { return overflowClipRect(location, fragment, relevancy); }

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -2626,78 +2626,6 @@
     firstLetterRemainingTextMap().remove(this);
 }
 
-LayoutRect RenderBoxModelObject::localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset, CaretRectMode caretRectMode) const
-{
-    ASSERT(!firstChild());
-
-    // FIXME: This does not take into account either :first-line or :first-letter
-    // However, as soon as some content is entered, the line boxes will be
-    // constructed and this kludge is not called any more. So only the caret size
-    // of an empty :first-line'd block is wrong. I think we can live with that.
-    const RenderStyle& currentStyle = firstLineStyle();
-
-    enum CaretAlignment { alignLeft, alignRight, alignCenter };
-
-    CaretAlignment alignment = alignLeft;
-
-    switch (currentStyle.textAlign()) {
-    case TextAlignMode::Left:
-    case TextAlignMode::WebKitLeft:
-        break;
-    case TextAlignMode::Center:
-    case TextAlignMode::WebKitCenter:
-        alignment = alignCenter;
-        break;
-    case TextAlignMode::Right:
-    case TextAlignMode::WebKitRight:
-        alignment = alignRight;
-        break;
-    case TextAlignMode::Justify:
-    case TextAlignMode::Start:
-        if (!currentStyle.isLeftToRightDirection())
-            alignment = alignRight;
-        break;
-    case TextAlignMode::End:
-        if (currentStyle.isLeftToRightDirection())
-            alignment = alignRight;
-        break;
-    }
-
-    LayoutUnit x = borderLeft() + paddingLeft();
-    LayoutUnit maxX = width - borderRight() - paddingRight();
-
-    switch (alignment) {
-    case alignLeft:
-        if (currentStyle.isLeftToRightDirection())
-            x += textIndentOffset;
-        break;
-    case alignCenter:
-        x = (x + maxX) / 2;
-        if (currentStyle.isLeftToRightDirection())
-            x += textIndentOffset / 2;
-        else
-            x -= textIndentOffset / 2;
-        break;
-    case alignRight:
-        x = maxX - caretWidth;
-        if (!currentStyle.isLeftToRightDirection())
-            x -= textIndentOffset;
-        break;
-    }
-    x = std::min(x, std::max<LayoutUnit>(maxX - caretWidth, 0));
-
-    auto lineHeight = this->lineHeight(true, currentStyle.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
-    auto height = std::min(lineHeight, LayoutUnit { currentStyle.fontMetrics().height() });
-    auto y = paddingTop() + borderTop() + (lineHeight > height ? (lineHeight - height) / 2 : LayoutUnit { });
-
-    auto rect = LayoutRect(x, y, caretWidth, height);
-
-    if (caretRectMode == CaretRectMode::ExpandToEndOfLine)
-        rect.shiftMaxXEdgeTo(width);
-
-    return currentStyle.isHorizontalWritingMode() ? rect : rect.transposedRect();
-}
-
 bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext& context)
 {
     // FIXME: We may want to not antialias when scaled by an integral value,

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -260,8 +260,6 @@
 
     InterpolationQuality chooseInterpolationQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
 
-    LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset, CaretRectMode = CaretRectMode::Normal) const;
-
     static bool shouldAntialiasLines(GraphicsContext&);
 
     static void clipRoundedInnerRect(GraphicsContext&, const FloatRect&, const FloatRoundedRect& clipRect);

Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderInline.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -236,25 +236,6 @@
     }
 }
 
-LayoutRect RenderInline::localCaretRect(const InlineRunAndOffset&, CaretRectMode) const
-{
-    if (firstChild()) {
-        // This condition is possible if the RenderInline is at an editing boundary,
-        // i.e. the VisiblePosition is:
-        //   <RenderInline editingBoundary=true>|<RenderText> </RenderText></RenderInline>
-        // FIXME: need to figure out how to make this return a valid rect, note that
-        // there are no line boxes created in the above case.
-        return LayoutRect();
-    }
-
-    LayoutRect caretRect = localCaretRectForEmptyElement(horizontalBorderAndPaddingExtent(), 0);
-
-    if (InlineBox* firstBox = firstLineBox())
-        caretRect.moveBy(LayoutPoint(firstBox->topLeft()));
-
-    return caretRect;
-}
-
 void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     m_lineBoxes.paint(this, paintInfo, paintOffset);

Modified: trunk/Source/WebCore/rendering/RenderInline.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderInline.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderInline.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -86,8 +86,6 @@
     void setAlwaysCreateLineBoxes() { setRenderInlineAlwaysCreatesLineBoxes(true); }
     void updateAlwaysCreateLineBoxes(bool fullLayout);
 
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const final;
-
     bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
 
 protected:

Modified: trunk/Source/WebCore/rendering/RenderLineBreak.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderLineBreak.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderLineBreak.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -159,18 +159,6 @@
     m_inlineBoxWrapper->root().setHasSelectedChildren(state != HighlightState::None);
 }
 
-LayoutRect RenderLineBreak::localCaretRect(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode) const
-{
-    ASSERT(!runAndOffset.offset);
-    ASSERT(runAndOffset.run == LayoutIntegration::runFor(*this));
-
-    if (!runAndOffset.run)
-        return LayoutRect();
-
-    auto line = runAndOffset.run.line();
-    return line->containingBlock().computeCaretRect(line->selectionRect(), line->contentLogicalLeft(), caretWidth, caretRectMode);
-}
-
 IntRect RenderLineBreak::linesBoundingBox() const
 {
     auto run = LayoutIntegration::runFor(*this);
@@ -214,7 +202,10 @@
         return;
     auto line = run.line();
 
-    LayoutRect rect = line->containingBlock().computeCaretRect(line->selectionRect(), line->contentLogicalLeft(), 0);
+    auto lineSelectionRect = line->selectionRect();
+    LayoutRect rect = IntRect(run->logicalLeft(), lineSelectionRect.y(), 0, lineSelectionRect.height());
+    if (!line->isHorizontal())
+        rect = rect.transposedRect();
 
     if (line->legacyRootInlineBox() && line->legacyRootInlineBox()->isFirstAfterPageBreak()) {
         if (run->isHorizontal())

Modified: trunk/Source/WebCore/rendering/RenderLineBreak.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderLineBreak.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderLineBreak.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -66,7 +66,6 @@
     int caretMinOffset() const final;
     int caretMaxOffset() const final;
     bool canBeSelectionLeaf() const final;
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const final;
     void setSelectionState(HighlightState) final;
 
     LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode) const final;

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -1400,11 +1400,6 @@
     return offset;
 }
 
-LayoutRect RenderObject::localCaretRect(const InlineRunAndOffset&, CaretRectMode) const
-{
-    return LayoutRect();
-}
-
 bool RenderObject::isRooted() const
 {
     return isDescendantOf(&view());

Modified: trunk/Source/WebCore/rendering/RenderObject.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderObject.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderObject.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -672,9 +672,6 @@
     // Whether or not a given block needs to paint selection gaps.
     virtual bool shouldPaintSelectionGaps() const { return false; }
 
-    // Returns the local coordinates of the caret within this render object.
-    virtual LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode = CaretRectMode::Normal) const;
-
     // When performing a global document tear-down, or when going into the back/forward cache, the renderer of the document is cleared.
     bool renderTreeBeingDestroyed() const;
 

Modified: trunk/Source/WebCore/rendering/RenderObjectEnums.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderObjectEnums.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderObjectEnums.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -61,10 +61,4 @@
 };
 typedef unsigned MapCoordinatesFlags;
 
-enum class CaretRectMode {
-    Normal,
-    ExpandToEndOfLine
-};
-
-
 }

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -699,18 +699,6 @@
     return createVisiblePosition(0, Affinity::Downstream);
 }
 
-LayoutRect RenderText::localCaretRect(const InlineRunAndOffset& runAndOffset, CaretRectMode caretRectMode) const
-{
-    if (!runAndOffset.run)
-        return LayoutRect();
-
-    auto& textRun = downcast<LayoutIntegration::TextRunIterator>(runAndOffset.run);
-    auto line = textRun.line();
-
-    float position = textRun->positionForOffset(runAndOffset.offset);
-    return line->containingBlock().computeCaretRect(line->selectionRect(), position, caretWidth, caretRectMode);
-}
-
 ALWAYS_INLINE float RenderText::widthFromCache(const FontCascade& f, unsigned start, unsigned len, float xPos, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow, const RenderStyle& style) const
 {
     if (style.hasTextCombine() && is<RenderCombineText>(*this)) {

Modified: trunk/Source/WebCore/rendering/RenderText.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/RenderText.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/RenderText.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -203,7 +203,6 @@
 
     void setSelectionState(HighlightState) final;
     LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) final;
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const override;
     LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const final;
 
     void computePreferredLogicalWidths(float leadWidth, HashSet<const Font*>& fallbackFonts, GlyphOverflow&);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp (270219 => 270220)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2020-11-28 19:37:32 UTC (rev 270220)
@@ -119,30 +119,6 @@
     return box; 
 }
 
-LayoutRect RenderSVGInlineText::localCaretRect(const InlineRunAndOffset& runAndOffset, CaretRectMode) const
-{
-    auto* box = runAndOffset.run ? runAndOffset.run->legacyInlineBox() : nullptr;
-    auto caretOffset = runAndOffset.offset;
-
-    if (!is<InlineTextBox>(box))
-        return LayoutRect();
-
-    auto& textBox = downcast<InlineTextBox>(*box);
-    if (caretOffset < textBox.start() || caretOffset > textBox.start() + textBox.len())
-        return LayoutRect();
-
-    // Use the edge of the selection rect to determine the caret rect.
-    if (caretOffset < textBox.start() + textBox.len()) {
-        LayoutRect rect = textBox.localSelectionRect(caretOffset, caretOffset + 1);
-        LayoutUnit x = textBox.isLeftToRightDirection() ? rect.x() : rect.maxX();
-        return LayoutRect(x, rect.y(), caretWidth, rect.height());
-    }
-
-    LayoutRect rect = textBox.localSelectionRect(caretOffset - 1, caretOffset);
-    LayoutUnit x = textBox.isLeftToRightDirection() ? rect.maxX() : rect.x();
-    return LayoutRect(x, rect.y(), caretWidth, rect.height());
-}
-
 FloatRect RenderSVGInlineText::floatLinesBoundingBox() const
 {
     FloatRect boundingBox;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h (270219 => 270220)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h	2020-11-28 17:05:21 UTC (rev 270219)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h	2020-11-28 19:37:32 UTC (rev 270220)
@@ -62,7 +62,6 @@
     bool isSVGInlineText() const override { return true; }
 
     VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
-    LayoutRect localCaretRect(const InlineRunAndOffset&, CaretRectMode) const override;
     IntRect linesBoundingBox() const override;
     std::unique_ptr<InlineTextBox> createTextBox() override;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to