Title: [237565] trunk/Source
Revision
237565
Author
timothy_hor...@apple.com
Date
2018-10-29 14:21:43 -0700 (Mon, 29 Oct 2018)

Log Message

Make FindOptionsShowOverlay work on iOS
https://bugs.webkit.org/show_bug.cgi?id=190551

Reviewed by Andy Estes.

Source/WebCore:

* platform/graphics/GraphicsContext.h:
Export some more GraphicsContext methods.

Source/WebKit:

* WebProcess/WebPage/FindController.cpp:
(WebKit::FindController::updateFindUIAfterPageScroll):
Update the find indicator after installing the page overlay for the find holes.
This ensures that if the find indicator mechanism also uses page overlays,
as it does on iOS, that they are installed in the correct order (because
order of installation directly affects z-order).

(WebKit::FindController::findIndicatorRadius const):
(WebKit::FindController::shouldHideFindIndicatorOnScroll const):
Add two getters for design differences between find-in-page on iOS vs. other platforms.

(WebKit::FindController::rectsForTextMatchesInRect):
Return FloatRects instead of IntRects for ease of use in the caller.
Don't clip rects for matches that intersect the current tile. We still
drop ones that don't intersect at all, but if they do intersect, we
provide the full rect (which may overlap a different tile), so that
e.g. border drawing will work correctly.

(WebKit::FindController::drawRect):
Adopt shrink-wrapping for find holes. This has minimal impact on macOS,
where the holes don't have rounded corners, but on iOS this makes
overlapping or adjacent holes look great. We already do this for the indicator,
so it only makes sense to do the same for the holes.

In order to support shrink-wrapping here, switch to using a Clear operator
with a path-fill instead of clearRect to clear out the holes.

Avoid hiding the find indicator on scroll if the platform says not to.

* WebProcess/WebPage/FindController.h:
* WebProcess/WebPage/ios/FindControllerIOS.mm:
(WebKit::FindController::findIndicatorRadius const):
(WebKit::FindController::shouldHideFindIndicatorOnScroll const):
Slightly adjust the find indicator's parameters to be compatible with having holes.
Reduce the horizontal margin by half a point so that it fits precisely in the hole.
Drop the "TightlyFitContent" text indicator parameter, because we want
rects that match the holes, and they do not tightly fit the content's height.
This matches macOS's behavior.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (237564 => 237565)


--- trunk/Source/WebCore/ChangeLog	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebCore/ChangeLog	2018-10-29 21:21:43 UTC (rev 237565)
@@ -1,3 +1,13 @@
+2018-10-29  Tim Horton  <timothy_hor...@apple.com>
+
+        Make FindOptionsShowOverlay work on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=190551
+
+        Reviewed by Andy Estes.
+
+        * platform/graphics/GraphicsContext.h:
+        Export some more GraphicsContext methods.
+
 2018-10-29  Youenn Fablet  <you...@apple.com>
 
         Invalid ssrc value in the stats of type 'inbound-rtp'

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (237564 => 237565)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2018-10-29 21:21:43 UTC (rev 237565)
@@ -282,7 +282,7 @@
     bool invalidatingControlTints() const { return m_paintInvalidationReasons == PaintInvalidationReasons::InvalidatingControlTints; }
     bool invalidatingImagesWithAsyncDecodes() const { return m_paintInvalidationReasons == PaintInvalidationReasons::InvalidatingImagesWithAsyncDecodes; }
 
-    void setStrokeThickness(float);
+    WEBCORE_EXPORT void setStrokeThickness(float);
     float strokeThickness() const { return m_state.strokeThickness; }
 
     void setStrokeStyle(StrokeStyle);
@@ -356,7 +356,7 @@
     void drawRaisedEllipse(const FloatRect&, const Color& ellipseColor, const Color& shadowColor);
 
     WEBCORE_EXPORT void fillPath(const Path&);
-    void strokePath(const Path&);
+    WEBCORE_EXPORT void strokePath(const Path&);
 
     void fillEllipse(const FloatRect&);
     void strokeEllipse(const FloatRect&);

Modified: trunk/Source/WebKit/ChangeLog (237564 => 237565)


--- trunk/Source/WebKit/ChangeLog	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebKit/ChangeLog	2018-10-29 21:21:43 UTC (rev 237565)
@@ -1,3 +1,49 @@
+2018-10-29  Tim Horton  <timothy_hor...@apple.com>
+
+        Make FindOptionsShowOverlay work on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=190551
+
+        Reviewed by Andy Estes.
+
+        * WebProcess/WebPage/FindController.cpp:
+        (WebKit::FindController::updateFindUIAfterPageScroll):
+        Update the find indicator after installing the page overlay for the find holes.
+        This ensures that if the find indicator mechanism also uses page overlays,
+        as it does on iOS, that they are installed in the correct order (because
+        order of installation directly affects z-order).
+
+        (WebKit::FindController::findIndicatorRadius const):
+        (WebKit::FindController::shouldHideFindIndicatorOnScroll const):
+        Add two getters for design differences between find-in-page on iOS vs. other platforms.
+
+        (WebKit::FindController::rectsForTextMatchesInRect):
+        Return FloatRects instead of IntRects for ease of use in the caller.
+        Don't clip rects for matches that intersect the current tile. We still
+        drop ones that don't intersect at all, but if they do intersect, we
+        provide the full rect (which may overlap a different tile), so that
+        e.g. border drawing will work correctly.
+
+        (WebKit::FindController::drawRect):
+        Adopt shrink-wrapping for find holes. This has minimal impact on macOS,
+        where the holes don't have rounded corners, but on iOS this makes
+        overlapping or adjacent holes look great. We already do this for the indicator,
+        so it only makes sense to do the same for the holes.
+
+        In order to support shrink-wrapping here, switch to using a Clear operator
+        with a path-fill instead of clearRect to clear out the holes.
+
+        Avoid hiding the find indicator on scroll if the platform says not to.
+
+        * WebProcess/WebPage/FindController.h:
+        * WebProcess/WebPage/ios/FindControllerIOS.mm:
+        (WebKit::FindController::findIndicatorRadius const):
+        (WebKit::FindController::shouldHideFindIndicatorOnScroll const):
+        Slightly adjust the find indicator's parameters to be compatible with having holes.
+        Reduce the horizontal margin by half a point so that it fits precisely in the hole.
+        Drop the "TightlyFitContent" text indicator parameter, because we want 
+        rects that match the holes, and they do not tightly fit the content's height.
+        This matches macOS's behavior.
+
 2018-10-29  Jer Noble  <jer.no...@apple.com>
 
         CRASH in CoreGraphics: ERROR_CGDataProvider_BufferIsNotBigEnough

Modified: trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp (237564 => 237565)


--- trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp	2018-10-29 21:21:43 UTC (rev 237565)
@@ -42,6 +42,7 @@
 #include <WebCore/GraphicsContext.h>
 #include <WebCore/Page.h>
 #include <WebCore/PageOverlayController.h>
+#include <WebCore/PathUtilities.h>
 #include <WebCore/PlatformMouseEvent.h>
 #include <WebCore/PluginDocument.h>
 
@@ -176,9 +177,6 @@
         }
 
         m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchRects, matchCount, m_foundStringMatchIndex, didWrap == DidWrap::Yes));
-
-        if (!(options & FindOptionsShowFindIndicator) || !selectedFrame || !updateFindIndicator(*selectedFrame, shouldShowOverlay))
-            hideFindIndicator();
     }
 
     if (!shouldShowOverlay) {
@@ -192,6 +190,9 @@
         }
         m_findPageOverlay->setNeedsDisplay();
     }
+    
+    if (found && (!(options & FindOptionsShowFindIndicator) || !selectedFrame || !updateFindIndicator(*selectedFrame, shouldShowOverlay)))
+        hideFindIndicator();
 }
 
 void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
@@ -360,6 +361,16 @@
 void FindController::didHideFindIndicator()
 {
 }
+    
+unsigned FindController::findIndicatorRadius() const
+{
+    return 0;
+}
+    
+bool FindController::shouldHideFindIndicatorOnScroll() const
+{
+    return true;
+}
 
 #endif
 
@@ -392,9 +403,9 @@
     updateFindIndicator(*selectedFrame, isShowingOverlay(), false);
 }
 
-Vector<IntRect> FindController::rectsForTextMatchesInRect(IntRect clipRect)
+Vector<FloatRect> FindController::rectsForTextMatchesInRect(IntRect clipRect)
 {
-    Vector<IntRect> rects;
+    Vector<FloatRect> rects;
 
     FrameView* mainFrameView = m_webPage->corePage()->mainFrame().view();
 
@@ -406,9 +417,8 @@
         for (FloatRect rect : document->markers().renderedRectsForMarkers(DocumentMarker::TextMatch)) {
             if (!frame->isMainFrame())
                 rect = mainFrameView->windowToContents(frame->view()->contentsToWindow(enclosingIntRect(rect)));
-            rect.intersect(clipRect);
 
-            if (rect.isEmpty())
+            if (rect.isEmpty() || !rect.intersects(clipRect))
                 continue;
 
             rects.append(rect);
@@ -434,7 +444,6 @@
 const float shadowOffsetX = 0;
 const float shadowOffsetY = 0;
 const float shadowBlurRadius = 1;
-const float shadowColorAlpha = 0.5;
 
 void FindController::drawRect(PageOverlay&, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
 {
@@ -441,33 +450,35 @@
     const int borderWidth = 1;
 
     Color overlayBackgroundColor(0.1f, 0.1f, 0.1f, 0.25f);
+    Color shadowColor(0.0f, 0.0f, 0.0f, 0.5f);
 
     IntRect borderInflatedDirtyRect = dirtyRect;
     borderInflatedDirtyRect.inflate(borderWidth);
-    Vector<IntRect> rects = rectsForTextMatchesInRect(borderInflatedDirtyRect);
+    Vector<FloatRect> rects = rectsForTextMatchesInRect(borderInflatedDirtyRect);
 
     // Draw the background.
     graphicsContext.fillRect(dirtyRect, overlayBackgroundColor);
 
-    {
-        GraphicsContextStateSaver stateSaver(graphicsContext);
+    Vector<Path> whiteFramePaths = PathUtilities::pathsWithShrinkWrappedRects(rects, findIndicatorRadius());
 
-        graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color(0.0f, 0.0f, 0.0f, shadowColorAlpha));
-        graphicsContext.setFillColor(Color::white);
+    GraphicsContextStateSaver stateSaver(graphicsContext);
 
-        // Draw white frames around the holes.
-        for (auto& rect : rects) {
-            IntRect whiteFrameRect = rect;
-            whiteFrameRect.inflate(borderWidth);
-            graphicsContext.fillRect(whiteFrameRect);
-        }
-    }
+    // Draw white frames around the holes.
+    // We double the thickness because half of the stroke will be erased when we clear the holes.
+    graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, shadowColor);
+    graphicsContext.setStrokeColor(Color::white);
+    graphicsContext.setStrokeThickness(borderWidth * 2);
+    for (auto& path : whiteFramePaths)
+        graphicsContext.strokePath(path);
 
+    graphicsContext.clearShadow();
+
     // Clear out the holes.
-    for (auto& rect : rects)
-        graphicsContext.clearRect(rect);
+    graphicsContext.setCompositeOperation(CompositeClear);
+    for (auto& path : whiteFramePaths)
+        graphicsContext.fillPath(path);
 
-    if (!m_isShowingFindIndicator)
+    if (!m_isShowingFindIndicator || !shouldHideFindIndicatorOnScroll())
         return;
 
     if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {

Modified: trunk/Source/WebKit/WebProcess/WebPage/FindController.h (237564 => 237565)


--- trunk/Source/WebKit/WebProcess/WebPage/FindController.h	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebKit/WebProcess/WebPage/FindController.h	2018-10-29 21:21:43 UTC (rev 237565)
@@ -79,7 +79,7 @@
     bool mouseEvent(WebCore::PageOverlay&, const WebCore::PlatformMouseEvent&) override;
     void drawRect(WebCore::PageOverlay&, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
 
-    Vector<WebCore::IntRect> rectsForTextMatchesInRect(WebCore::IntRect clipRect);
+    Vector<WebCore::FloatRect> rectsForTextMatchesInRect(WebCore::IntRect clipRect);
     bool updateFindIndicator(WebCore::Frame& selectedFrame, bool isShowingOverlay, bool shouldAnimate = true);
 
     void updateFindUIAfterPageScroll(bool found, const String&, FindOptions, unsigned maxMatchCount, WebCore::DidWrap);
@@ -88,6 +88,9 @@
     void didFindString();
     void didFailToFindString();
     void didHideFindIndicator();
+    
+    unsigned findIndicatorRadius() const;
+    bool shouldHideFindIndicatorOnScroll() const;
 
     WebPage* m_webPage;
     WebCore::PageOverlay* m_findPageOverlay { nullptr };

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/FindControllerIOS.mm (237564 => 237565)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/FindControllerIOS.mm	2018-10-29 20:57:15 UTC (rev 237564)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/FindControllerIOS.mm	2018-10-29 21:21:43 UTC (rev 237565)
@@ -48,10 +48,10 @@
 using namespace WebCore;
 
 const int cornerRadius = 3;
-const int totalHorizontalMargin = 2;
+const int totalHorizontalMargin = 1;
 const int totalVerticalMargin = 1;
 
-const TextIndicatorOptions findTextIndicatorOptions = TextIndicatorOptionTightlyFitContent | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionDoNotClipToVisibleRect;
+const TextIndicatorOptions findTextIndicatorOptions = TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionDoNotClipToVisibleRect;
 
 static Color highlightColor()
 {
@@ -174,6 +174,16 @@
 {
     setSelectionChangeUpdatesEnabledInAllFrames(*m_webPage, false);
 }
+    
+unsigned FindController::findIndicatorRadius() const
+{
+    return cornerRadius;
+}
+    
+bool FindController::shouldHideFindIndicatorOnScroll() const
+{
+    return false;
+}
 
 } // namespace WebKit
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to