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 908039f..40c4f17 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 32cbf96..ccc632d 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 dd52118..56ff7af 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 36d8a0d..cb90a13 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 d8d0ffd..eaecd72 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]);
+}
+
 }