Title: [269773] trunk/Source/WebCore
Revision
269773
Author
[email protected]
Date
2020-11-13 06:12:39 -0800 (Fri, 13 Nov 2020)

Log Message

[LFC][Integration] Add initial bidi support
https://bugs.webkit.org/show_bug.cgi?id=218884

Reviewed by Antti Koivisto.

In this patch, we introduce the Bidi Run and the Iterator and use the BidiResolver to compute
the bidi boundaries.
Currently only single direction content is passed in to the BidiResolver which meas that we always
end up with one and only one Bidi run.

* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::Iterator::offset const):
(WebCore::LayoutIntegration::Iterator::currentRun const):
(WebCore::LayoutIntegration::Iterator::runOffset const):
(WebCore::LayoutIntegration::Iterator::operator== const):
(WebCore::LayoutIntegration::Iterator::operator!= const):
(WebCore::LayoutIntegration::Iterator::atEnd const):
(WebCore::LayoutIntegration::Iterator::Iterator):
(WebCore::LayoutIntegration::Iterator::direction const):
(WebCore::LayoutIntegration::Iterator::increment):
(WebCore::LayoutIntegration::BidiRun::start const):
(WebCore::LayoutIntegration::BidiRun::end const):
(WebCore::LayoutIntegration::BidiRun::level const):
(WebCore::LayoutIntegration::BidiRun::next const):
(WebCore::LayoutIntegration::BidiRun::setNext):
(WebCore::LayoutIntegration::BidiRun::takeNext):
(WebCore::LayoutIntegration::BidiRun::BidiRun):
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (269772 => 269773)


--- trunk/Source/WebCore/ChangeLog	2020-11-13 13:12:16 UTC (rev 269772)
+++ trunk/Source/WebCore/ChangeLog	2020-11-13 14:12:39 UTC (rev 269773)
@@ -1,3 +1,34 @@
+2020-11-13  Zalan Bujtas  <[email protected]>
+
+        [LFC][Integration] Add initial bidi support
+        https://bugs.webkit.org/show_bug.cgi?id=218884
+
+        Reviewed by Antti Koivisto.
+
+        In this patch, we introduce the Bidi Run and the Iterator and use the BidiResolver to compute
+        the bidi boundaries.
+        Currently only single direction content is passed in to the BidiResolver which meas that we always
+        end up with one and only one Bidi run.
+
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::Iterator::offset const):
+        (WebCore::LayoutIntegration::Iterator::currentRun const):
+        (WebCore::LayoutIntegration::Iterator::runOffset const):
+        (WebCore::LayoutIntegration::Iterator::operator== const):
+        (WebCore::LayoutIntegration::Iterator::operator!= const):
+        (WebCore::LayoutIntegration::Iterator::atEnd const):
+        (WebCore::LayoutIntegration::Iterator::Iterator):
+        (WebCore::LayoutIntegration::Iterator::direction const):
+        (WebCore::LayoutIntegration::Iterator::increment):
+        (WebCore::LayoutIntegration::BidiRun::start const):
+        (WebCore::LayoutIntegration::BidiRun::end const):
+        (WebCore::LayoutIntegration::BidiRun::level const):
+        (WebCore::LayoutIntegration::BidiRun::next const):
+        (WebCore::LayoutIntegration::BidiRun::setNext):
+        (WebCore::LayoutIntegration::BidiRun::takeNext):
+        (WebCore::LayoutIntegration::BidiRun::BidiRun):
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+
 2020-11-13  Miguel Gomez  <[email protected]>
 
         [GTK][WPE] CSS backdrop overlay corners are not rounded on results.webkit.org

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (269772 => 269773)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2020-11-13 13:12:16 UTC (rev 269772)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2020-11-13 14:12:39 UTC (rev 269773)
@@ -28,6 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "BidiResolver.h"
 #include "InlineFormattingContext.h"
 #include "InlineFormattingState.h"
 #include "LayoutBoxGeometry.h"
@@ -59,6 +60,92 @@
     return std::max(lineLogicalWidth, lineBoxLogicalWidth);
 }
 
+class Iterator {
+public:
+    Iterator() = default;
+    Iterator(const Layout::InlineLineRuns* runList, size_t currentRunIndex);
+
+    void increment();
+    unsigned offset() const { return m_offset; }
+    UCharDirection direction() const;
+
+    bool operator==(const Iterator& other) const { return offset() == other.offset(); }
+    bool operator!=(const Iterator& other) const { return offset() != other.offset(); };
+    bool atEnd() const { return !m_runList || m_runIndex == m_runList->size(); };
+
+private:
+    const Layout::LineRun& currentRun() const { return m_runList->at(m_runIndex); }
+
+    const Layout::InlineLineRuns* m_runList { nullptr };
+    size_t m_offset { 0 };
+    size_t m_runIndex { 0 };
+    size_t m_runOffset { 0 };
+};
+
+Iterator::Iterator(const Layout::InlineLineRuns* runList, size_t runIndex)
+    : m_runList(runList)
+    , m_runIndex(runIndex)
+{
+}
+
+UCharDirection Iterator::direction() const
+{
+    ASSERT(m_runList);
+    ASSERT(!atEnd());
+    auto& textContent = currentRun().text();
+    if (!textContent)
+        return U_OTHER_NEUTRAL;
+    return u_charDirection(textContent->content()[textContent->start() + m_runOffset]);
+}
+
+void Iterator::increment()
+{
+    ASSERT(m_runList);
+    ASSERT(!atEnd());
+    ++m_offset;
+    auto& currentRun = this->currentRun();
+    if (auto& textContent = currentRun.text()) {
+        if (++m_runOffset < textContent->length())
+            return;
+    }
+    ++m_runIndex;
+    m_runOffset = 0;
+}
+
+class BidiRun {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    BidiRun(unsigned start, unsigned end, BidiContext*, UCharDirection);
+
+    size_t start() const { return m_start; }
+    size_t end() const { return m_end; }
+    unsigned char level() const { return m_level; }
+
+    BidiRun* next() const { return m_next.get(); }
+    void setNext(std::unique_ptr<BidiRun>&& next) { m_next = WTFMove(next); }
+    std::unique_ptr<BidiRun> takeNext() { return WTFMove(m_next); }
+
+private:
+    std::unique_ptr<BidiRun> m_next;
+    size_t m_start { 0 };
+    size_t m_end { 0 };
+    unsigned char m_level { 0 };
+};
+
+BidiRun::BidiRun(unsigned start, unsigned end, BidiContext* context, UCharDirection direction)
+    : m_start(start)
+    , m_end(end)
+    , m_level(context->level())
+{
+    ASSERT(context);
+    if (direction == U_OTHER_NEUTRAL)
+        direction = context->dir();
+    if (m_level % 2)
+        m_level = (direction == U_LEFT_TO_RIGHT || direction == U_ARABIC_NUMBER || direction == U_EUROPEAN_NUMBER) ? m_level + 1 : m_level;
+    else
+        m_level = (direction == U_RIGHT_TO_LEFT) ? m_level + 1 : (direction == U_ARABIC_NUMBER || direction == U_EUROPEAN_NUMBER) ? m_level + 2 : m_level;
+}
+
 InlineContentBuilder::InlineContentBuilder(const Layout::LayoutState& layoutState, const RenderBlockFlow& blockFlow)
     : m_layoutState(layoutState)
     , m_blockFlow(blockFlow)
@@ -112,6 +199,14 @@
     if (runList.isEmpty())
         return;
     auto& lines = inlineFormattingState.lines();
+
+    BidiResolver<Iterator, BidiRun> bidiResolver;
+    // FIXME: Add support for override.
+    bidiResolver.setStatus(BidiStatus(m_layoutState.root().style().direction(), false));
+    // FIXME: Grab the nested isolates from the previous line.
+    bidiResolver.setPosition(Iterator(&runList, 0), 0);
+    bidiResolver.createBidiRunsForLine(Iterator(&runList, runList.size()));
+
     Vector<bool> hasAdjustedTrailingLineList(lines.size(), false);
 
     auto createDisplayBoxRun = [&](auto& lineRun) {
@@ -187,12 +282,17 @@
         inlineContent.runs.append(displayRun);
     };
 
-    for (auto& lineRun : inlineFormattingState.lineRuns()) {
-        if (auto& text = lineRun.text())
-            createDisplayTextRunForRange(lineRun, text->start(), text->end());
-        else
-            createDisplayBoxRun(lineRun);
-    }
+    auto& bidiRuns = bidiResolver.runs();
+    if (bidiRuns.runCount() == 1) {
+        // Fast path for cases when there's no bidi boundary.
+        for (auto& lineRun : inlineFormattingState.lineRuns()) {
+            if (auto& text = lineRun.text())
+                createDisplayTextRunForRange(lineRun, text->start(), text->end());
+            else
+                createDisplayBoxRun(lineRun);
+        }
+    } else
+        ASSERT_NOT_IMPLEMENTED_YET();
 }
 
 void InlineContentBuilder::createDisplayLines(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to