Title: [188527] trunk
Revision
188527
Author
[email protected]
Date
2015-08-17 11:12:08 -0700 (Mon, 17 Aug 2015)

Log Message

Holes for find matches that span multiple lines are completely wrong
https://bugs.webkit.org/show_bug.cgi?id=148065
<rdar://problem/5305002>

Reviewed by Simon Fraser.

Test: fast/text/mark-matches-broken-line-rendering.html

Two big problems with find holes:
    - RenderedDocumentMarker only has one rect, but a marker can be painted
      by multiple text runs, each with their own rendered rect
    - paintTextMatchMarker does std::max((unsigned)a, (unsigned)0), which is
      obviously an overflow problem/not going to work if a is negative

The combination of these issues causes the holes for find matches to be
very broken: text that isn't part of the match is highlighted, and some
text that is part of the match isn't highlighted.

To fix, make RenderedDocumentMarker support multiple rects, and use signed
math (like paintDocumentMarker already did) when computing positions in paintTextMatchMarker.

* dom/DocumentMarkerController.cpp:
(WebCore::DocumentMarkerController::addTextMatchMarker):
(WebCore::DocumentMarkerController::renderedRectsForMarkers):
* dom/RenderedDocumentMarker.h:
(WebCore::RenderedDocumentMarker::RenderedDocumentMarker):
(WebCore::RenderedDocumentMarker::isRendered):
(WebCore::RenderedDocumentMarker::contains):
(WebCore::RenderedDocumentMarker::addRenderedRect):
(WebCore::RenderedDocumentMarker::renderedRects):
(WebCore::RenderedDocumentMarker::invalidate):
(WebCore::RenderedDocumentMarker::setRenderedRect): Deleted.
(WebCore::RenderedDocumentMarker::renderedRect): Deleted.
(WebCore::RenderedDocumentMarker::invalidMarkerRect): Deleted.
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintDocumentMarker):
(WebCore::InlineTextBox::paintTextMatchMarker):
(WebCore::InlineTextBox::computeRectForReplacementMarker):
* rendering/svg/SVGInlineFlowBox.cpp:
(WebCore::SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer):

* fast/text/mark-matches-broken-line-rendering-expected.html: Added.
* fast/text/mark-matches-broken-line-rendering.html: Added.
Add a test that ensures that we correctly mark test matches that cross
line breaks.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (188526 => 188527)


--- trunk/LayoutTests/ChangeLog	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/LayoutTests/ChangeLog	2015-08-17 18:12:08 UTC (rev 188527)
@@ -1,3 +1,16 @@
+2015-08-17  Timothy Horton  <[email protected]>
+
+        Holes for find matches that span multiple lines are completely wrong
+        https://bugs.webkit.org/show_bug.cgi?id=148065
+        <rdar://problem/5305002>
+
+        Reviewed by Simon Fraser.
+
+        * fast/text/mark-matches-broken-line-rendering-expected.html: Added.
+        * fast/text/mark-matches-broken-line-rendering.html: Added.
+        Add a test that ensures that we correctly mark test matches that cross
+        line breaks.
+
 2015-08-17  Chris Dumez  <[email protected]>
 
         Accessing HTMLCollection.length is slow

Added: trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering-expected.html (0 => 188527)


--- trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering-expected.html	2015-08-17 18:12:08 UTC (rev 188527)
@@ -0,0 +1,14 @@
+<style>
+p {
+    display: inline-block;
+    background-color: blue;
+    width: 60px;
+}
+
+span {
+    background-color: yellow;
+}
+</style>
+<p>
+<span>Quo</span> <span>usque</span> <span>tandem</span> <span>abutere,</span> <span>Catilina,</span> <span>patientia</span> <span>nostra?</span>
+</p>

Added: trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering.html (0 => 188527)


--- trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/mark-matches-broken-line-rendering.html	2015-08-17 18:12:08 UTC (rev 188527)
@@ -0,0 +1,16 @@
+<style>
+p {
+    display: inline-block;
+    background-color: blue;
+    width: 60px;
+}
+</style>
+<p>
+Quo usque tandem abutere, Catilina, patientia nostra?
+</p>
+<script>
+if (window.internals) {
+    internals.setMarkedTextMatchesAreHighlighted(true);
+    internals.countMatchesForText("Quo usque tandem abutere, Catilina, patientia nostra?", 0, "mark");
+}
+</script>

Modified: trunk/Source/WebCore/ChangeLog (188526 => 188527)


--- trunk/Source/WebCore/ChangeLog	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/Source/WebCore/ChangeLog	2015-08-17 18:12:08 UTC (rev 188527)
@@ -1,5 +1,48 @@
 2015-08-17  Timothy Horton  <[email protected]>
 
+        Holes for find matches that span multiple lines are completely wrong
+        https://bugs.webkit.org/show_bug.cgi?id=148065
+        <rdar://problem/5305002>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/text/mark-matches-broken-line-rendering.html
+
+        Two big problems with find holes:
+            - RenderedDocumentMarker only has one rect, but a marker can be painted
+              by multiple text runs, each with their own rendered rect
+            - paintTextMatchMarker does std::max((unsigned)a, (unsigned)0), which is
+              obviously an overflow problem/not going to work if a is negative
+
+        The combination of these issues causes the holes for find matches to be
+        very broken: text that isn't part of the match is highlighted, and some
+        text that is part of the match isn't highlighted.
+
+        To fix, make RenderedDocumentMarker support multiple rects, and use signed
+        math (like paintDocumentMarker already did) when computing positions in paintTextMatchMarker.
+
+        * dom/DocumentMarkerController.cpp:
+        (WebCore::DocumentMarkerController::addTextMatchMarker):
+        (WebCore::DocumentMarkerController::renderedRectsForMarkers):
+        * dom/RenderedDocumentMarker.h:
+        (WebCore::RenderedDocumentMarker::RenderedDocumentMarker):
+        (WebCore::RenderedDocumentMarker::isRendered):
+        (WebCore::RenderedDocumentMarker::contains):
+        (WebCore::RenderedDocumentMarker::addRenderedRect):
+        (WebCore::RenderedDocumentMarker::renderedRects):
+        (WebCore::RenderedDocumentMarker::invalidate):
+        (WebCore::RenderedDocumentMarker::setRenderedRect): Deleted.
+        (WebCore::RenderedDocumentMarker::renderedRect): Deleted.
+        (WebCore::RenderedDocumentMarker::invalidMarkerRect): Deleted.
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintDocumentMarker):
+        (WebCore::InlineTextBox::paintTextMatchMarker):
+        (WebCore::InlineTextBox::computeRectForReplacementMarker):
+        * rendering/svg/SVGInlineFlowBox.cpp:
+        (WebCore::SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer):
+
+2015-08-17  Timothy Horton  <[email protected]>
+
         Adopt shrink-wrapping for TextIndicators on Mac
         https://bugs.webkit.org/show_bug.cgi?id=148064
 

Modified: trunk/Source/WebCore/dom/DocumentMarkerController.cpp (188526 => 188527)


--- trunk/Source/WebCore/dom/DocumentMarkerController.cpp	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/Source/WebCore/dom/DocumentMarkerController.cpp	2015-08-17 18:12:08 UTC (rev 188527)
@@ -102,7 +102,7 @@
             // matches off-screen are (that haven't been painted yet).
             Node* node = textPiece->startContainer();
             Vector<RenderedDocumentMarker*> markers = markersFor(node);
-            markers[markers.size() - 1]->setRenderedRect(range->absoluteBoundingBox());
+            markers[markers.size() - 1]->addRenderedRect(range->absoluteBoundingBox());
         }
     }
 }
@@ -439,10 +439,7 @@
             if (marker.type() != markerType)
                 continue;
 
-            if (!marker.isRendered())
-                continue;
-
-            result.append(marker.renderedRect());
+            result.appendVector(marker.renderedRects());
         }
     }
 

Modified: trunk/Source/WebCore/dom/RenderedDocumentMarker.h (188526 => 188527)


--- trunk/Source/WebCore/dom/RenderedDocumentMarker.h	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/Source/WebCore/dom/RenderedDocumentMarker.h	2015-08-17 18:12:08 UTC (rev 188527)
@@ -28,39 +28,43 @@
 #define RenderedDocumentMarker_h
 
 #include "DocumentMarker.h"
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
 class RenderedDocumentMarker : public DocumentMarker {
 public:
-
     explicit RenderedDocumentMarker(const DocumentMarker& marker)
-        : DocumentMarker(marker), m_renderedRect(invalidMarkerRect())
+        : DocumentMarker(marker)
     {
     }
 
-    bool isRendered() const { return invalidMarkerRect() != m_renderedRect; }
-    bool contains(const LayoutPoint& point) const { return isRendered() && m_renderedRect.contains(point); }
-    void setRenderedRect(const LayoutRect& r) { m_renderedRect = r; }
-    const LayoutRect& renderedRect() const { return m_renderedRect; }
-    void invalidate(const LayoutRect&);
-    void invalidate() { m_renderedRect = invalidMarkerRect(); }
+    bool contains(const LayoutPoint& point) const
+    {
+        for (const auto& rect : m_renderedRects) {
+            if (rect.contains(point))
+                return true;
+        }
+        return false;
+    }
 
-private:
-    static const LayoutRect& invalidMarkerRect()
+    void addRenderedRect(const LayoutRect& r) { m_renderedRects.append(r); }
+    const Vector<LayoutRect, 1>& renderedRects() const { return m_renderedRects; }
+    void invalidate(const LayoutRect& r)
     {
-        static const LayoutRect rect = LayoutRect(-1, -1, -1, -1);
-        return rect;
+        for (const auto& rect : m_renderedRects) {
+            if (rect.intersects(r)) {
+                invalidate();
+                return;
+            }
+        }
     }
+    void invalidate() { m_renderedRects.clear(); }
 
-    LayoutRect m_renderedRect;
+private:
+    Vector<LayoutRect, 1> m_renderedRects;
 };
 
-inline void RenderedDocumentMarker::invalidate(const LayoutRect& r)
-{
-    if (m_renderedRect.intersects(r))
-        invalidate();
-}
 
 } // namespace
 

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (188526 => 188527)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2015-08-17 18:12:08 UTC (rev 188527)
@@ -1104,7 +1104,7 @@
         if (grammar || isDictationMarker) {
             markerRect.move(-boxOrigin.x(), -boxOrigin.y());
             markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
-            marker.setRenderedRect(markerRect);
+            marker.addRenderedRect(markerRect);
         }
     }
     
@@ -1132,8 +1132,8 @@
 {
     LayoutUnit selectionHeight = this->selectionHeight();
 
-    int sPos = std::max(marker.startOffset() - m_start, (unsigned)0);
-    int ePos = std::min(marker.endOffset() - m_start, (unsigned)m_len);
+    int sPos = std::max<int>(marker.startOffset() - m_start, 0);
+    int ePos = std::min<int>(marker.endOffset() - m_start, m_len);
     TextRun run = constructTextRun(style, font);
 
     // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
@@ -1142,7 +1142,7 @@
     font.adjustSelectionRectForText(run, renderedRect, sPos, ePos);
     IntRect markerRect = enclosingIntRect(renderedRect);
     markerRect = renderer().localToAbsoluteQuad(FloatQuad(markerRect)).enclosingBoundingBox();
-    marker.setRenderedRect(markerRect);
+    marker.addRenderedRect(markerRect);
     
     // Optionally highlight the text
     if (renderer().frame().editor().markedTextMatchesAreHighlighted()) {
@@ -1174,7 +1174,7 @@
     font.adjustSelectionRectForText(run, selectionRect, sPos, ePos);
     IntRect markerRect = enclosingIntRect(selectionRect);
     markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
-    marker.setRenderedRect(markerRect);
+    marker.addRenderedRect(markerRect);
 }
     
 void InlineTextBox::paintDocumentMarkers(GraphicsContext& context, const FloatPoint& boxOrigin, const RenderStyle& style, const FontCascade& font, bool background)

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp (188526 => 188527)


--- trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp	2015-08-17 17:50:09 UTC (rev 188526)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp	2015-08-17 18:12:08 UTC (rev 188527)
@@ -124,7 +124,7 @@
             }
         }
 
-        marker->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
+        marker->addRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to