Add support for computing the frontmost longest effective marker subrange
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 21:28:33 +0000 (21:28 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 21:28:33 +0000 (21:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180985

Reviewed by Dave Hyatt.

Source/WebCore:

Add a new subdivision overlap strategy to return the minimum list of maximal length non-
overlapping subranges. We will make use of this strategy together with an algorithm to
coalesce adjacent subranges with visually indistinct styles to minimize the total number
of drawing commands needed to paint an entire line of text. We are not making use of
this functionality now. We will make use of it to simplify the patch for <https://bugs.webkit.org/show_bug.cgi?id=180984>.

* rendering/MarkerSubrange.cpp:
(WebCore::subdivide):
* rendering/MarkerSubrange.h:

Tools:

Adds a test case to ensure that we compute the minimum list of maximal length non-
overlapping subranges when using strategy OverlapStrategy::FrontmostWithLongestEffectiveRange.

* TestWebKitAPI/Tests/WebCore/MarkerSubrange.cpp:
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226137 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/MarkerSubrange.cpp
Source/WebCore/rendering/MarkerSubrange.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/MarkerSubrange.cpp

index 908039feb8931ac61930cb92967a847067b1b172..40c4f17f4bdeb6f18093c522b06410461cab1f99 100644 (file)
@@ -1,3 +1,20 @@
+2017-12-19  Daniel Bates  <dabates@apple.com>
+
+        Add support for computing the frontmost longest effective marker subrange
+        https://bugs.webkit.org/show_bug.cgi?id=180985
+
+        Reviewed by Dave Hyatt.
+
+        Add a new subdivision overlap strategy to return the minimum list of maximal length non-
+        overlapping subranges. We will make use of this strategy together with an algorithm to
+        coalesce adjacent subranges with visually indistinct styles to minimize the total number
+        of drawing commands needed to paint an entire line of text. We are not making use of
+        this functionality now. We will make use of it to simplify the patch for <https://bugs.webkit.org/show_bug.cgi?id=180984>.
+
+        * rendering/MarkerSubrange.cpp:
+        (WebCore::subdivide):
+        * rendering/MarkerSubrange.h:
+
 2017-12-19  Chris Dumez  <cdumez@apple.com>
 
         Handle Fetch should wait for the service worker's state to become activated
index 32cbf96e74772a5a789acd7ddd83b19dd483df9b..ccc632d92d4d54831adb3bb528fa96cdae16b77a 100644 (file)
@@ -67,14 +67,22 @@ Vector<MarkerSubrange> subdivide(const Vector<MarkerSubrange>& subranges, Overla
     unsigned offsetSoFar = offsets[0].value;
     for (unsigned i = 1; i < numberOfOffsets; ++i) {
         if (offsets[i].value > offsets[i - 1].value) {
-            if (overlapStrategy == OverlapStrategy::Frontmost) {
+            if (overlapStrategy == OverlapStrategy::Frontmost || overlapStrategy == OverlapStrategy::FrontmostWithLongestEffectiveRange) {
                 std::optional<unsigned> frontmost;
                 for (unsigned j = 0; j < i; ++j) {
                     if (!processedSubranges.contains(offsets[j].subrange))
                         frontmost = j;
                 }
-                if (frontmost)
-                    result.append({ offsetSoFar, offsets[i].value, offsets[frontmost.value()].subrange->type, offsets[frontmost.value()].subrange->marker });
+                if (frontmost) {
+                    if (overlapStrategy == OverlapStrategy::FrontmostWithLongestEffectiveRange && !result.isEmpty()) {
+                        auto& previous = result.last();
+                        if (previous.endOffset == offsetSoFar && previous.type == offsets[frontmost.value()].subrange->type && previous.marker == offsets[frontmost.value()].subrange->marker)
+                            previous.endOffset = offsets[i].value;
+                        else
+                            result.append({ offsetSoFar, offsets[i].value, offsets[frontmost.value()].subrange->type, offsets[frontmost.value()].subrange->marker });
+                    } else
+                        result.append({ offsetSoFar, offsets[i].value, offsets[frontmost.value()].subrange->type, offsets[frontmost.value()].subrange->marker });
+                }
             } else {
                 for (unsigned j = 0; j < i; ++j) {
                     if (!processedSubranges.contains(offsets[j].subrange))
index dd52118091af815471830f7ff72130bd15fac31b..56ff7aff4285caed0f6aa574b22fd7cecf691c97 100644 (file)
@@ -44,6 +44,7 @@ struct MarkerSubrange {
         // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS)-guard.
         DictationPhraseWithAlternatives,
 #endif
+        Selection,
     };
 #if !COMPILER_SUPPORTS(NSDMI_FOR_AGGREGATES)
     MarkerSubrange() = default;
@@ -61,7 +62,7 @@ struct MarkerSubrange {
     const RenderedDocumentMarker* marker { nullptr };
 };
 
-enum class OverlapStrategy { None, Frontmost };
+enum class OverlapStrategy { None, Frontmost, FrontmostWithLongestEffectiveRange };
 WEBCORE_EXPORT Vector<MarkerSubrange> subdivide(const Vector<MarkerSubrange>&, OverlapStrategy = OverlapStrategy::None);
 
 }
index 36d8a0db365980f4e97bfae0215c3451924f9442..cb90a13e5971e392121ec361bb50903c6c9434d8 100644 (file)
@@ -1,3 +1,16 @@
+2017-12-19  Daniel Bates  <dabates@apple.com>
+
+        Add support for computing the frontmost longest effective marker subrange
+        https://bugs.webkit.org/show_bug.cgi?id=180985
+
+        Reviewed by Dave Hyatt.
+
+        Adds a test case to ensure that we compute the minimum list of maximal length non-
+        overlapping subranges when using strategy OverlapStrategy::FrontmostWithLongestEffectiveRange.
+
+        * TestWebKitAPI/Tests/WebCore/MarkerSubrange.cpp:
+        (TestWebKitAPI::TEST):
+
 2017-12-18  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Attachment Support] The 'webkitattachmentbloburl' attribute should not persist after markup serialization
index d8d0ffddc49bba0ae5e5c702dd397ac7760e97f8..eaecd724ed1ff497b809169b3cb15cbe187a7fc2 100644 (file)
@@ -36,23 +36,25 @@ namespace WebCore {
 std::ostream& operator<<(std::ostream& os, MarkerSubrange::Type type)
 {
     switch (type) {
-    case MarkerSubrange::Unmarked:
-        return os << "Unmarked";
-    case MarkerSubrange::GrammarError:
-        return os << "GrammarError";
     case MarkerSubrange::Correction:
         return os << "Correction";
-    case MarkerSubrange::SpellingError:
-        return os << "SpellingError";
-    case MarkerSubrange::TextMatch:
-        return os << "TextMatch";
     case MarkerSubrange::DictationAlternatives:
         return os << "DictationAlternatives";
 #if PLATFORM(IOS)
-        // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS)-guard.
+    // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS)-guard.
     case MarkerSubrange::DictationPhraseWithAlternatives:
         return os << "DictationPhraseWithAlternatives";
 #endif
+    case MarkerSubrange::GrammarError:
+        return os << "GrammarError";
+    case MarkerSubrange::Selection:
+        return os << "Selection";
+    case MarkerSubrange::SpellingError:
+        return os << "SpellingError";
+    case MarkerSubrange::TextMatch:
+        return os << "TextMatch";
+    case MarkerSubrange::Unmarked:
+        return os << "Unmarked";
     }
 }
 
@@ -175,4 +177,40 @@ TEST(MarkerSubrange, SubdivideSpellingAndGrammarComplicatedFrontmost)
         EXPECT_EQ(expectedSubranges[i], results[i]);
 }
 
+TEST(MarkerSubrange, SubdivideGrammarAndSelectionOverlapFrontmost)
+{
+    Vector<MarkerSubrange> subranges {
+        MarkerSubrange { 0, 40, MarkerSubrange::GrammarError },
+        MarkerSubrange { 2, 60, MarkerSubrange::Selection },
+        MarkerSubrange { 50, 60, MarkerSubrange::GrammarError },
+    };
+    Vector<MarkerSubrange> expectedSubranges {
+        MarkerSubrange { 0, 2, MarkerSubrange::GrammarError },
+        MarkerSubrange { 2, 40, MarkerSubrange::Selection },
+        MarkerSubrange { 40, 50, MarkerSubrange::Selection },
+        MarkerSubrange { 50, 60, MarkerSubrange::Selection },
+    };
+    auto results = subdivide(subranges, OverlapStrategy::Frontmost);
+    ASSERT_EQ(expectedSubranges.size(), results.size());
+    for (size_t i = 0; i < expectedSubranges.size(); ++i)
+        EXPECT_EQ(expectedSubranges[i], results[i]);
+}
+
+TEST(MarkerSubrange, SubdivideGrammarAndSelectionOverlapFrontmostWithLongestEffectiveRange)
+{
+    Vector<MarkerSubrange> subranges {
+        MarkerSubrange { 0, 40, MarkerSubrange::GrammarError },
+        MarkerSubrange { 2, 60, MarkerSubrange::Selection },
+        MarkerSubrange { 50, 60, MarkerSubrange::GrammarError },
+    };
+    Vector<MarkerSubrange> expectedSubranges {
+        MarkerSubrange { 0, 2, MarkerSubrange::GrammarError },
+        MarkerSubrange { 2, 60, MarkerSubrange::Selection },
+    };
+    auto results = subdivide(subranges, OverlapStrategy::FrontmostWithLongestEffectiveRange);
+    ASSERT_EQ(expectedSubranges.size(), results.size());
+    for (size_t i = 0; i < expectedSubranges.size(); ++i)
+        EXPECT_EQ(expectedSubranges[i], results[i]);
+}
+
 }