Title: [285938] trunk/Source/WebCore
Revision
285938
Author
[email protected]
Date
2021-11-17 10:51:16 -0800 (Wed, 17 Nov 2021)

Log Message

InlineIterator::TextBox::offsetForPosition and positionForOffset should be layout path independent
https://bugs.webkit.org/show_bug.cgi?id=233259

Reviewed by Alan Bujtas.

Remove imperfectly duplicated code.

This also fixes editing/mac/input/caret-primary-bidi.html with IFC BiDi.

* layout/integration/InlineIteratorBoxLegacyPath.h:
(WebCore::InlineIterator::BoxLegacyPath::createTextRun const):
(WebCore::InlineIterator::BoxLegacyPath::offsetForPosition const): Deleted.
(WebCore::InlineIterator::BoxLegacyPath::positionForOffset const): Deleted.
* layout/integration/InlineIteratorBoxModernPath.h:
(WebCore::InlineIterator::BoxModernPath::createTextRun const):
(WebCore::InlineIterator::BoxModernPath::offsetForPosition const): Deleted.
(WebCore::InlineIterator::BoxModernPath::positionForOffset const): Deleted.
* layout/integration/InlineIteratorTextBox.cpp:
(WebCore::InlineIterator::TextBox::offsetForPosition const):
(WebCore::InlineIterator::TextBox::positionForOffset const):
* layout/integration/InlineIteratorTextBox.h:
(WebCore::InlineIterator::TextBox::createTextRun const):
(WebCore::InlineIterator::TextBox::offsetForPosition const): Deleted.
(WebCore::InlineIterator::TextBox::positionForOffset const): Deleted.
* rendering/LegacyInlineTextBox.cpp:
(WebCore::LegacyInlineTextBox::placeEllipsisBox):
(WebCore::LegacyInlineTextBox::offsetForPosition const): Deleted.
(WebCore::LegacyInlineTextBox::positionForOffset const): Deleted.
* rendering/LegacyInlineTextBox.h:
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::offsetForPosition const): Deleted.
(WebCore::SVGInlineTextBox::positionForOffset const): Deleted.
* rendering/svg/SVGInlineTextBox.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (285937 => 285938)


--- trunk/Source/WebCore/ChangeLog	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/ChangeLog	2021-11-17 18:51:16 UTC (rev 285938)
@@ -1,3 +1,39 @@
+2021-11-17  Antti Koivisto  <[email protected]>
+
+        InlineIterator::TextBox::offsetForPosition and positionForOffset should be layout path independent
+        https://bugs.webkit.org/show_bug.cgi?id=233259
+
+        Reviewed by Alan Bujtas.
+
+        Remove imperfectly duplicated code.
+
+        This also fixes editing/mac/input/caret-primary-bidi.html with IFC BiDi.
+
+        * layout/integration/InlineIteratorBoxLegacyPath.h:
+        (WebCore::InlineIterator::BoxLegacyPath::createTextRun const):
+        (WebCore::InlineIterator::BoxLegacyPath::offsetForPosition const): Deleted.
+        (WebCore::InlineIterator::BoxLegacyPath::positionForOffset const): Deleted.
+        * layout/integration/InlineIteratorBoxModernPath.h:
+        (WebCore::InlineIterator::BoxModernPath::createTextRun const):
+        (WebCore::InlineIterator::BoxModernPath::offsetForPosition const): Deleted.
+        (WebCore::InlineIterator::BoxModernPath::positionForOffset const): Deleted.
+        * layout/integration/InlineIteratorTextBox.cpp:
+        (WebCore::InlineIterator::TextBox::offsetForPosition const):
+        (WebCore::InlineIterator::TextBox::positionForOffset const):
+        * layout/integration/InlineIteratorTextBox.h:
+        (WebCore::InlineIterator::TextBox::createTextRun const):
+        (WebCore::InlineIterator::TextBox::offsetForPosition const): Deleted.
+        (WebCore::InlineIterator::TextBox::positionForOffset const): Deleted.
+        * rendering/LegacyInlineTextBox.cpp:
+        (WebCore::LegacyInlineTextBox::placeEllipsisBox):
+        (WebCore::LegacyInlineTextBox::offsetForPosition const): Deleted.
+        (WebCore::LegacyInlineTextBox::positionForOffset const): Deleted.
+        * rendering/LegacyInlineTextBox.h:
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::offsetForPosition const): Deleted.
+        (WebCore::SVGInlineTextBox::positionForOffset const): Deleted.
+        * rendering/svg/SVGInlineTextBox.h:
+
 2021-11-17  Dean Jackson  <[email protected]>
 
         Add ModelDocument for directly showing content that can be handled by <model>

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h (285937 => 285938)


--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h	2021-11-17 18:51:16 UTC (rev 285938)
@@ -35,6 +35,8 @@
 namespace WebCore {
 namespace InlineIterator {
 
+enum class CreateTextRunMode { Painting, Editing };
+
 class BoxLegacyPath {
 public:
     BoxLegacyPath(const LegacyInlineBox* inlineBox)
@@ -62,12 +64,14 @@
     unsigned end() const { return inlineTextBox()->end(); }
     unsigned length() const { return inlineTextBox()->len(); }
 
-    unsigned offsetForPosition(float x) const { return inlineTextBox()->offsetForPosition(x); }
-    float positionForOffset(unsigned offset) const { return inlineTextBox()->positionForOffset(offset); }
-
     TextBoxSelectableRange selectableRange() const { return inlineTextBox()->selectableRange(); }
 
-    TextRun createTextRun() const { return inlineTextBox()->createTextRun(); }
+    TextRun createTextRun(CreateTextRunMode mode) const
+    {
+        bool ignoreCombinedText = mode == CreateTextRunMode::Editing;
+        bool ignoreHyphen = mode == CreateTextRunMode::Editing;
+        return inlineTextBox()->createTextRun(ignoreCombinedText, ignoreHyphen);
+    }
 
     const RenderObject& renderer() const
     {

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h (285937 => 285938)


--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h	2021-11-17 18:51:16 UTC (rev 285938)
@@ -70,39 +70,6 @@
     unsigned end() const { return box().text()->end(); }
     unsigned length() const { return box().text()->length(); }
 
-    // FIXME: Make a shared generic version of this.
-    inline unsigned offsetForPosition(float x) const
-    {
-        if (isLineBreak())
-            return 0;
-        auto rect = this->rect();
-        auto localX = x - rect.x();
-        if (localX > rect.width())
-            return length();
-        if (localX < 0)
-            return 0;
-
-        bool includePartialGlyphs = true;
-        return box().style().fontCascade().offsetForPosition(createTextRun(HyphenMode::Ignore), localX, includePartialGlyphs);
-    }
-
-    // FIXME: Make a shared generic version of this.
-    float positionForOffset(unsigned offset) const
-    {
-        ASSERT(offset >= start());
-        ASSERT(offset <= end());
-
-        if (isLineBreak())
-            return rect().x();
-
-        auto endOffset = selectableRange().clamp(offset);
-
-        LayoutRect selectionRect = LayoutRect(rect().x(), 0, 0, 0);
-        TextRun textRun = createTextRun(HyphenMode::Ignore);
-        box().style().fontCascade().adjustSelectionRectForText(textRun, selectionRect, 0, endOffset);
-        return snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), textRun.ltr()).maxX();
-    }
-
     TextBoxSelectableRange selectableRange() const
     {
         return {
@@ -113,9 +80,25 @@
         };
     }
 
-    TextRun createTextRun() const
+    TextRun createTextRun(CreateTextRunMode mode) const
     {
-        return createTextRun(HyphenMode::Include);
+        auto& style = box().style();
+        auto expansion = box().expansion();
+        auto rect = this->rect();
+        auto xPos = rect.x() - (line().lineBoxLeft() + line().contentLeft());
+
+        auto textForRun = [&] {
+            if (mode == CreateTextRunMode::Editing || !hasHyphen())
+                return text().toStringWithoutCopying();
+
+            return makeString(text(), style.hyphenString());
+        }();
+
+        bool directionalOverride = dirOverride() || style.rtlOrdering() == Order::Visual;
+        bool characterScanForCodePath = !renderText().canUseSimpleFontCodePath();
+        TextRun textRun { textForRun, xPos, expansion.horizontalExpansion, expansion.behavior, direction(), directionalOverride, characterScanForCodePath };
+        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
+        return textRun;
     };
 
     const RenderObject& renderer() const
@@ -274,28 +257,6 @@
     const LayoutIntegration::InlineContent::Boxes& boxes() const { return m_inlineContent->boxes; }
     const LayoutIntegration::Line& line() const { return m_inlineContent->lineForBox(box()); }
 
-    enum class HyphenMode { Include, Ignore };
-    TextRun createTextRun(HyphenMode hyphenMode) const
-    {
-        auto& style = box().style();
-        auto expansion = box().expansion();
-        auto rect = this->rect();
-        auto xPos = rect.x() - (line().lineBoxLeft() + line().contentLeft());
-
-        auto textForRun = [&] {
-            if (hyphenMode == HyphenMode::Ignore || !hasHyphen())
-                return text().toStringWithoutCopying();
-
-            return makeString(text(), style.hyphenString());
-        }();
-
-        bool directionalOverride = dirOverride() || style.rtlOrdering() == Order::Visual;
-        bool characterScanForCodePath = !renderText().canUseSimpleFontCodePath();
-        TextRun textRun { textForRun, xPos, expansion.horizontalExpansion, expansion.behavior, direction(), directionalOverride, characterScanForCodePath };
-        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
-        return textRun;
-    };
-
     const RenderText& renderText() const { return downcast<RenderText>(renderer()); }
     TextDirection direction() const { return bidiLevel() % 2 ? TextDirection::RTL : TextDirection::LTR; }
 

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp (285937 => 285938)


--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp	2021-11-17 18:51:16 UTC (rev 285938)
@@ -57,6 +57,38 @@
     return snappedSelectionRect(selectionRect, logicalRight(), selectionTop, selectionHeight, isHorizontal());
 }
 
+unsigned TextBox::offsetForPosition(float x, bool includePartialGlyphs) const
+{
+    if (isLineBreak())
+        return 0;
+    if (x - logicalLeft() > logicalWidth())
+        return isLeftToRightDirection() ? length() : 0;
+    if (x - logicalLeft() < 0)
+        return isLeftToRightDirection() ? 0 : length();
+    return fontCascade().offsetForPosition(createTextRun(CreateTextRunMode::Editing), x - logicalLeft(), includePartialGlyphs);
+}
+
+float TextBox::positionForOffset(unsigned offset) const
+{
+    ASSERT(offset >= start());
+    ASSERT(offset <= end());
+
+    if (isLineBreak())
+        return logicalLeft();
+
+    auto [startOffset, endOffset] = [&] {
+        if (direction() == TextDirection::RTL)
+            return std::pair { selectableRange().clamp(offset), length() };
+        return std::pair { 0u, selectableRange().clamp(offset) };
+    }();
+
+    auto selectionRect = LayoutRect(logicalLeft(), 0, 0, 0);
+    
+    auto textRun = createTextRun(CreateTextRunMode::Editing);
+    fontCascade().adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
+    return snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), textRun.ltr()).maxX();
+}
+
 bool TextBox::isCombinedText() const
 {
     auto& renderer = this->renderer();

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h (285937 => 285938)


--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h	2021-11-17 18:51:16 UTC (rev 285938)
@@ -43,7 +43,7 @@
     unsigned end() const;
     unsigned length() const;
 
-    unsigned offsetForPosition(float x) const;
+    unsigned offsetForPosition(float x, bool includePartialGlyphs = true) const;
     float positionForOffset(unsigned) const;
 
     TextBoxSelectableRange selectableRange() const;
@@ -52,7 +52,7 @@
     bool isCombinedText() const;
     const FontCascade& fontCascade() const;
 
-    TextRun createTextRun() const;
+    TextRun createTextRun(CreateTextRunMode = CreateTextRunMode::Painting) const;
 
     const RenderText& renderer() const { return downcast<RenderText>(Box::renderer()); }
 
@@ -147,20 +147,6 @@
     });
 }
 
-inline unsigned TextBox::offsetForPosition(float x) const
-{
-    return WTF::switchOn(m_pathVariant, [&](auto& path) {
-        return path.offsetForPosition(x);
-    });
-}
-
-inline float TextBox::positionForOffset(unsigned offset) const
-{
-    return WTF::switchOn(m_pathVariant, [&](auto& path) {
-        return path.positionForOffset(offset);
-    });
-}
-
 inline TextBoxSelectableRange TextBox::selectableRange() const
 {
     return WTF::switchOn(m_pathVariant, [&](auto& path) {
@@ -168,10 +154,10 @@
     });
 }
 
-inline TextRun TextBox::createTextRun() const
+inline TextRun TextBox::createTextRun(CreateTextRunMode mode) const
 {
     return WTF::switchOn(m_pathVariant, [&](auto& path) {
-        return path.createTextRun();
+        return path.createTextRun(mode);
     });
 }
 

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (285937 => 285938)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-11-17 18:51:16 UTC (rev 285938)
@@ -34,10 +34,10 @@
 #include "FloatRoundedRect.h"
 #include "Frame.h"
 #include "GraphicsContext.h"
-
 #include "HighlightData.h"
 #include "HitTestResult.h"
 #include "ImageBuffer.h"
+#include "InlineIteratorTextBox.h"
 #include "InlineTextBoxStyle.h"
 #include "LegacyEllipsisBox.h"
 #include "Page.h"
@@ -268,7 +268,7 @@
             ellipsisX = ltr ? left() + visibleBoxWidth : right() - visibleBoxWidth;
         }
 
-        int offset = offsetForPosition(ellipsisX, false);
+        int offset = InlineIterator::textBoxFor(this)->offsetForPosition(ellipsisX, false);
         if (!offset) {
             // No characters should be rendered. Set ourselves to full truncation and place the ellipsis at the min of our start
             // and the ellipsis edge.
@@ -452,46 +452,6 @@
     return logicalLeft() - root().logicalLeft();
 }
 
-int LegacyInlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs) const
-{
-    if (isLineBreak())
-        return 0;
-    if (lineOffset - logicalLeft() > logicalWidth())
-        return isLeftToRightDirection() ? len() : 0;
-    if (lineOffset - logicalLeft() < 0)
-        return isLeftToRightDirection() ? 0 : len();
-    bool ignoreCombinedText = true;
-    bool ignoreHyphen = true;
-    return lineFont().offsetForPosition(createTextRun(ignoreCombinedText, ignoreHyphen), lineOffset - logicalLeft(), includePartialGlyphs);
-}
-
-float LegacyInlineTextBox::positionForOffset(unsigned offset) const
-{
-    ASSERT(offset >= m_start);
-    ASSERT(offset <= m_start + len());
-
-    if (isLineBreak())
-        return logicalLeft();
-
-    unsigned startOffset;
-    unsigned endOffset;
-    if (isLeftToRightDirection()) {
-        startOffset = 0;
-        endOffset = selectableRange().clamp(offset);
-    } else {
-        startOffset = selectableRange().clamp(offset);
-        endOffset = m_len;
-    }
-
-    // FIXME: Do we need to add rightBearing here?
-    LayoutRect selectionRect = LayoutRect(logicalLeft(), 0, 0, 0);
-    bool ignoreCombinedText = true;
-    bool ignoreHyphen = true;
-    TextRun textRun = createTextRun(ignoreCombinedText, ignoreHyphen);
-    lineFont().adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
-    return snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), textRun.ltr()).maxX();
-}
-
 TextRun LegacyInlineTextBox::createTextRun(bool ignoreCombinedText, bool ignoreHyphen) const
 {
     const auto& style = lineStyle();

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (285937 => 285938)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-11-17 18:51:16 UTC (rev 285938)
@@ -146,9 +146,6 @@
     float textPos() const; // returns the x position relative to the left start of the text line.
 
 public:
-    virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
-    virtual float positionForOffset(unsigned offset) const;
-
     bool hasMarkers() const;
 
 private:

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp (285937 => 285938)


--- trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp	2021-11-17 18:51:16 UTC (rev 285938)
@@ -78,14 +78,6 @@
         nextBox->dirtyOwnLineBoxes();
 }
 
-int SVGInlineTextBox::offsetForPosition(float, bool) const
-{
-    // SVG doesn't use the standard offset <-> position selection system, as it's not suitable for SVGs complex needs.
-    // vertical text selection, inline boxes spanning multiple lines (contrary to HTML, etc.)
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const
 {
     float scalingFactor = renderer().scalingFactor();
@@ -103,13 +95,6 @@
     return fragment.characterOffset - start() + renderer().scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
 }
 
-float SVGInlineTextBox::positionForOffset(unsigned) const
-{
-    // SVG doesn't use the offset <-> position selection system. 
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, unsigned startPosition, unsigned endPosition, const RenderStyle& style) const
 {
     ASSERT_WITH_SECURITY_IMPLICATION(startPosition < endPosition);

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h (285937 => 285938)


--- trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h	2021-11-17 18:50:01 UTC (rev 285937)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h	2021-11-17 18:51:16 UTC (rev 285938)
@@ -43,8 +43,6 @@
 
     int selectionTop() { return top(); }
     int selectionHeight() { return static_cast<int>(ceilf(m_logicalHeight)); }
-    int offsetForPosition(float x, bool includePartialGlyphs = true) const override;
-    float positionForOffset(unsigned offset) const override;
 
     void paintSelectionBackground(PaintInfo&);
     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to