https://bugs.webkit.org/show_bug.cgi?id=92275
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Aug 2012 21:49:46 +0000 (21:49 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Aug 2012 21:49:46 +0000 (21:49 +0000)
Need a way to get a snapshot image that does not show the selection
-and corresponding-
<rdar://problem/11956802>

Reviewed by Anders Carlsson.

../WebCore:

New function FrameView::paintContentsForSnapshot() has the option to
exclude selection from the snapshot.

Export new function
* WebCore.exp.in:

Clear the selection from the RenderView when selection is to be excluded. Restore
all of this information via FrameSelection::updateAppearance() after calling
paintContents().
* page/FrameView.cpp:
(WebCore::FrameView::paintContentsForSnapshot):
(WebCore):
* page/FrameView.h:

../WebKit2:

Added new API WKBundlePageCreateSnapshotWithOptions()

New enum SnapshotOptions tracks whether snapshots should exclude
selection highlighting in addition to tracking whether the image is
sharable like the original ImageOptions.
* Shared/API/c/WKImage.h:
* Shared/API/c/WKSharedAPICast.h:
(WebKit::snapshotOptionsFromImageOptions):
(WebKit):
(WebKit::toSnapshotOptions):
* Shared/ImageOptions.h:

New API.
* WebProcess/InjectedBundle/API/c/WKBundlePage.h:
* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageCreateSnapshotWithOptions):

These existing APIs all now call
WebPage::scaledSnapshotWithOptions().
(WKBundlePageCreateSnapshotInViewCoordinates):
(WKBundlePageCreateSnapshotInDocumentCoordinates):
(WKBundlePageCreateScaledSnapshotInDocumentCoordinates):

This patch removes WebPage::snapshotInViewCoordinates(),
WebPage::snapshotInDocumentCoordinates(), and
WebPage::scaledSnapshotInDocumentCoordinates(). All of the logic is
now consolidated into WebPage::scaledSnapshotWithOptions(). It turns
out that we never did anything different for document coordinates
versus view coordinates, so that complexity could just be eliminated
outright.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::snapshotOptionsToImageOptions):
(WebKit::WebPage::scaledSnapshotWithOptions):
(WebKit):
* WebProcess/WebPage/WebPage.h:
(WebPage):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKImage.h
Source/WebKit2/Shared/API/c/WKSharedAPICast.h
Source/WebKit2/Shared/ImageOptions.h
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h

index 1e9f220..b96b1d0 100644 (file)
@@ -1,3 +1,26 @@
+2012-08-08  Beth Dakin  <bdakin@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=92275
+        Need a way to get a snapshot image that does not show the selection
+        -and corresponding-
+        <rdar://problem/11956802>
+
+        Reviewed by Anders Carlsson.
+
+        New function FrameView::paintContentsForSnapshot() has the option to 
+        exclude selection from the snapshot.
+
+        Export new function
+        * WebCore.exp.in:
+
+        Clear the selection from the RenderView when selection is to be excluded. Restore 
+        all of this information via FrameSelection::updateAppearance() after calling 
+        paintContents().
+        * page/FrameView.cpp:
+        (WebCore::FrameView::paintContentsForSnapshot):
+        (WebCore):
+        * page/FrameView.h:
+
 2012-08-07  James Robinson  <jamesr@chromium.org>
 
         [chromium] Only use public Platform API in NonCompositedContentHost
index 47d0497..cbf8504 100644 (file)
@@ -955,6 +955,7 @@ __ZN7WebCore9FrameView21flushDeferredRepaintsEv
 __ZN7WebCore9FrameView22setBaseBackgroundColorERKNS_5ColorE
 __ZN7WebCore9FrameView23updateCanHaveScrollbarsEv
 __ZN7WebCore9FrameView24forceLayoutForPaginationERKNS_9FloatSizeES3_fNS_19AdjustViewSizeOrNotE
+__ZN7WebCore9FrameView24paintContentsForSnapshotEPNS_15GraphicsContextERKNS_7IntRectENS0_18SelectionInSnaphotE
 __ZN7WebCore9FrameView26adjustPageHeightDeprecatedEPffff
 __ZN7WebCore9FrameView29setShouldUpdateWhileOffscreenEb
 __ZN7WebCore9FrameView37updateLayoutAndStyleIfNeededRecursiveEv
index 834a7e8..d295674 100644 (file)
@@ -3146,6 +3146,36 @@ void FrameView::setNodeToDraw(Node* node)
     m_nodeToDraw = node;
 }
 
+void FrameView::paintContentsForSnapshot(GraphicsContext* context, const IntRect& imageRect, SelectionInSnaphot shouldPaintSelection)
+{
+    updateLayoutAndStyleIfNeededRecursive();
+
+    // Cache paint behavior and set a new behavior appropriate for snapshots.
+    PaintBehavior oldBehavior = paintBehavior();
+    setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
+
+    // If the snapshot should exclude selection, then we'll clear the current selection
+    // in the render tree only. This will allow us to restore the selection from the DOM
+    // after we paint the snapshot.
+    if (shouldPaintSelection == ExcludeSelection) {
+        for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
+            if (RenderView* root = frame->contentRenderer())
+                root->clearSelection();
+        }
+    }
+
+    paintContents(context, imageRect);
+
+    // Restore selection.
+    if (shouldPaintSelection == ExcludeSelection) {
+        for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get()))
+            frame->selection()->updateAppearance();
+    }
+
+    // Restore cached paint behavior.
+    setPaintBehavior(oldBehavior);
+}
+
 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
 {
     if (context->paintingDisabled())
index 5d6094c..899b071 100644 (file)
@@ -246,6 +246,9 @@ public:
     void setLastPaintTime(double lastPaintTime) { m_lastPaintTime = lastPaintTime; }
     void setNodeToDraw(Node*);
 
+    enum SelectionInSnaphot { IncludeSelection, ExcludeSelection };
+    void paintContentsForSnapshot(GraphicsContext*, const IntRect& imageRect, SelectionInSnaphot shouldPaintSelection);
+
     virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
     virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
     virtual void paintScrollbar(GraphicsContext*, Scrollbar*, const IntRect&) OVERRIDE;
index 74a28eb..fd0abae 100644 (file)
@@ -1,3 +1,49 @@
+2012-08-08  Beth Dakin  <bdakin@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=92275
+        Need a way to get a snapshot image that does not show the selection
+        -and corresponding-
+        <rdar://problem/11956802>
+
+        Reviewed by Anders Carlsson.
+
+        Added new API WKBundlePageCreateSnapshotWithOptions()
+
+        New enum SnapshotOptions tracks whether snapshots should exclude 
+        selection highlighting in addition to tracking whether the image is 
+        sharable like the original ImageOptions.
+        * Shared/API/c/WKImage.h:
+        * Shared/API/c/WKSharedAPICast.h:
+        (WebKit::snapshotOptionsFromImageOptions):
+        (WebKit):
+        (WebKit::toSnapshotOptions):
+        * Shared/ImageOptions.h:
+
+        New API.
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageCreateSnapshotWithOptions):
+
+        These existing APIs all now call 
+        WebPage::scaledSnapshotWithOptions().
+        (WKBundlePageCreateSnapshotInViewCoordinates):
+        (WKBundlePageCreateSnapshotInDocumentCoordinates):
+        (WKBundlePageCreateScaledSnapshotInDocumentCoordinates):
+
+        This patch removes WebPage::snapshotInViewCoordinates(), 
+        WebPage::snapshotInDocumentCoordinates(), and 
+        WebPage::scaledSnapshotInDocumentCoordinates(). All of the logic is 
+        now consolidated into WebPage::scaledSnapshotWithOptions(). It turns 
+        out that we never did anything different for document coordinates 
+        versus view coordinates, so that complexity could just be eliminated 
+        outright.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::snapshotOptionsToImageOptions):
+        (WebKit::WebPage::scaledSnapshotWithOptions):
+        (WebKit):
+        * WebProcess/WebPage/WebPage.h:
+        (WebPage):
+
 2012-08-08  Anders Carlsson  <andersca@apple.com>
 
         Make the Silverlight CAOpenGLLayer opaque if we know the plug-in contents is opaque to reduce blending
index e3a2f9e..8dec00a 100644 (file)
@@ -38,6 +38,12 @@ enum {
 };
 typedef uint32_t WKImageOptions;
 
+enum {
+    kWKSnapshotOptionsShareable = 1 << 0,
+    kWKSnapshotOptionsExcludeSelectionHighlighting = 1 << 1
+};
+typedef uint32_t WKSnapshotOptions;
+
 WK_EXPORT WKTypeID WKImageGetTypeID();
 
 WK_EXPORT WKImageRef WKImageCreate(WKSize size, WKImageOptions options);
index fd1a896..cc605d1 100644 (file)
@@ -758,6 +758,28 @@ inline ImageOptions toImageOptions(WKImageOptions wkImageOptions)
     return static_cast<ImageOptions>(imageOptions);
 }
 
+inline SnapshotOptions snapshotOptionsFromImageOptions(WKImageOptions wkImageOptions)
+{
+    unsigned snapshotOptions = 0;
+
+    if (wkImageOptions & kWKImageOptionsShareable)
+        snapshotOptions |= SnapshotOptionsShareable;
+
+    return snapshotOptions;
+}
+
+inline SnapshotOptions toSnapshotOptions(WKSnapshotOptions wkSnapshotOptions)
+{
+    unsigned snapshotOptions = 0;
+
+    if (wkSnapshotOptions & kWKSnapshotOptionsShareable)
+        snapshotOptions |= SnapshotOptionsShareable;
+    if (wkSnapshotOptions & kWKSnapshotOptionsExcludeSelectionHighlighting)
+        snapshotOptions |= SnapshotOptionsExcludeSelectionHighlighting;
+
+    return snapshotOptions;
+}
+
 } // namespace WebKit
 
 #endif // WKSharedAPICast_h
index caf79bf..534cd23 100644 (file)
@@ -32,6 +32,12 @@ enum ImageOptions {
     ImageOptionsShareable = 1 << 0,
 };
 
+enum {
+    SnapshotOptionsShareable = 1 << 0,
+    SnapshotOptionsExcludeSelectionHighlighting = 1 << 1
+};
+typedef uint32_t SnapshotOptions;
+
 } // namespace WebKit
 
 #endif // ImageOptions_h
index 2ae2237..1f43a12 100644 (file)
@@ -287,21 +287,27 @@ bool WKBundlePageFindString(WKBundlePageRef pageRef, WKStringRef target, WKFindO
     return toImpl(pageRef)->findStringFromInjectedBundle(toImpl(target)->string(), toFindOptions(findOptions));
 }
 
+WKImageRef WKBundlePageCreateSnapshotWithOptions(WKBundlePageRef pageRef, WKRect rect, WKSnapshotOptions options)
+{
+    RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, toSnapshotOptions(options));
+    return toAPI(webImage.release().leakRef());
+}
+
 WKImageRef WKBundlePageCreateSnapshotInViewCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options)
 {
-    RefPtr<WebImage> webImage = toImpl(pageRef)->snapshotInViewCoordinates(toIntRect(rect), toImageOptions(options));
+    RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, snapshotOptionsFromImageOptions(options));
     return toAPI(webImage.release().leakRef());
 }
 
 WKImageRef WKBundlePageCreateSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options)
 {
-    RefPtr<WebImage> webImage = toImpl(pageRef)->snapshotInDocumentCoordinates(toIntRect(rect), toImageOptions(options));
+    RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, snapshotOptionsFromImageOptions(options));
     return toAPI(webImage.release().leakRef());
 }
 
 WKImageRef WKBundlePageCreateScaledSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, double scaleFactor, WKImageOptions options)
 {
-    RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotInDocumentCoordinates(toIntRect(rect), scaleFactor, toImageOptions(options));
+    RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), scaleFactor, snapshotOptionsFromImageOptions(options));
     return toAPI(webImage.release().leakRef());
 }
 
index aa86092..28eee5c 100644 (file)
@@ -398,8 +398,14 @@ WK_EXPORT bool WKBundlePageCanHandleRequest(WKURLRequestRef request);
 
 WK_EXPORT bool WKBundlePageFindString(WKBundlePageRef page, WKStringRef target, WKFindOptions findOptions);
 
+WK_EXPORT WKImageRef WKBundlePageCreateSnapshotWithOptions(WKBundlePageRef page, WKRect rect, WKSnapshotOptions options);
+
+// We should deprecate these functions in favor of just using WKBundlePageCreateSnapshotWithOptions.
 WK_EXPORT WKImageRef WKBundlePageCreateSnapshotInViewCoordinates(WKBundlePageRef page, WKRect rect, WKImageOptions options);
 WK_EXPORT WKImageRef WKBundlePageCreateSnapshotInDocumentCoordinates(WKBundlePageRef page, WKRect rect, WKImageOptions options);
+
+// We should keep this function since it allows passing a scale factor, but we should re-name it to
+// WKBundlePageCreateScaledSnapshotWithOptions.
 WK_EXPORT WKImageRef WKBundlePageCreateScaledSnapshotInDocumentCoordinates(WKBundlePageRef page, WKRect rect, double scaleFactor, WKImageOptions options);
 
 WK_EXPORT double WKBundlePageGetBackingScaleFactor(WKBundlePageRef page);
index ce110f3..75d4211 100644 (file)
@@ -1191,43 +1191,27 @@ void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut)
 #endif
 }
 
-PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
+static ImageOptions snapshotOptionsToImageOptions(SnapshotOptions snapshotOptions)
 {
-    FrameView* frameView = m_mainFrame->coreFrame()->view();
-    if (!frameView)
-        return 0;
-
-    IntSize bitmapSize = rect.size();
-    float deviceScaleFactor = corePage()->deviceScaleFactor();
-    bitmapSize.scale(deviceScaleFactor);
-
-    RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, options);
-    if (!snapshot->bitmap())
-        return 0;
-    
-    OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
-    graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
-    graphicsContext->translate(-rect.x(), -rect.y());
-
-    frameView->updateLayoutAndStyleIfNeededRecursive();
+    unsigned imageOptions = 0;
 
-    PaintBehavior oldBehavior = frameView->paintBehavior();
-    frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
-    frameView->paint(graphicsContext.get(), rect);
-    frameView->setPaintBehavior(oldBehavior);
+    if (snapshotOptions & SnapshotOptionsShareable)
+        imageOptions |= ImageOptionsShareable;
 
-    return snapshot.release();
+    return static_cast<ImageOptions>(imageOptions);
 }
 
-PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
+PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double scaleFactor, SnapshotOptions options)
 {
     FrameView* frameView = m_mainFrame->coreFrame()->view();
     if (!frameView)
         return 0;
 
+    IntSize bitmapSize = rect.size();
     float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor();
-    IntSize size(ceil(rect.width() * combinedScaleFactor), ceil(rect.height() * combinedScaleFactor));
-    RefPtr<WebImage> snapshot = WebImage::create(size, options);
+    bitmapSize.scale(combinedScaleFactor);
+
+    RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
     if (!snapshot->bitmap())
         return 0;
 
@@ -1235,21 +1219,15 @@ PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect&
     graphicsContext->applyDeviceScaleFactor(combinedScaleFactor);
     graphicsContext->translate(-rect.x(), -rect.y());
 
-    frameView->updateLayoutAndStyleIfNeededRecursive();
+    FrameView::SelectionInSnaphot shouldPaintSelection = FrameView::IncludeSelection;
+    if (options & SnapshotOptionsExcludeSelectionHighlighting)
+        shouldPaintSelection = FrameView::ExcludeSelection;
 
-    PaintBehavior oldBehavior = frameView->paintBehavior();
-    frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
-    frameView->paintContents(graphicsContext.get(), rect);
-    frameView->setPaintBehavior(oldBehavior);
+    frameView->paintContentsForSnapshot(graphicsContext.get(), rect, shouldPaintSelection);
 
     return snapshot.release();
 }
 
-PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
-{
-    return scaledSnapshotInDocumentCoordinates(rect, 1, options);
-}
-
 void WebPage::pageDidScroll()
 {
     m_uiClient.pageDidScroll(this);
index f09f2fe..7d8688b 100644 (file)
@@ -346,9 +346,7 @@ public:
     WebCore::IntPoint screenToWindow(const WebCore::IntPoint&);
     WebCore::IntRect windowToScreen(const WebCore::IntRect&);
 
-    PassRefPtr<WebImage> snapshotInViewCoordinates(const WebCore::IntRect&, ImageOptions);
-    PassRefPtr<WebImage> snapshotInDocumentCoordinates(const WebCore::IntRect&, ImageOptions);
-    PassRefPtr<WebImage> scaledSnapshotInDocumentCoordinates(const WebCore::IntRect&, double scaleFactor, ImageOptions);
+    PassRefPtr<WebImage> scaledSnapshotWithOptions(const WebCore::IntRect&, double scaleFactor, SnapshotOptions);
 
     static const WebEvent* currentEvent();