Title: [99099] trunk
Revision
99099
Author
[email protected]
Date
2011-11-02 14:46:01 -0700 (Wed, 02 Nov 2011)

Log Message

<rdar://problem/10336700> Add API to get rendered text image without having to select it
https://bugs.webkit.org/show_bug.cgi?id=71407

Reviewed by Simon Fraser.

Source/WebCore: 

Test: TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm

* bindings/objc/DOM.mm:
(-[DOMRange renderedImageForcingBlackText:]): Added.
* bindings/objc/DOMPrivate.h:
* page/Frame.h:
* page/mac/FrameMac.mm:
(WebCore::Frame::rangeImage): Added. Sets the selection in the RenderView (only) based on the
given range and gets a selection-only rendering of the view, then restores the selection.
* rendering/RenderView.cpp:
(WebCore::RenderView::setSelection): Skip all invalidation if the repaint behavior is RepaintNothing.
(WebCore::RenderView::getSelection): Added this getter.
* rendering/RenderView.h:

Tools: 

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm: Added.
(-[RenderedImageFromDOMRangeFrameLoadDelegate webView:didFinishLoadForFrame:]):
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (99098 => 99099)


--- trunk/Source/WebCore/ChangeLog	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/ChangeLog	2011-11-02 21:46:01 UTC (rev 99099)
@@ -1,3 +1,24 @@
+2011-11-02  Dan Bernstein  <[email protected]>
+
+        <rdar://problem/10336700> Add API to get rendered text image without having to select it
+        https://bugs.webkit.org/show_bug.cgi?id=71407
+
+        Reviewed by Simon Fraser.
+
+        Test: TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm
+
+        * bindings/objc/DOM.mm:
+        (-[DOMRange renderedImageForcingBlackText:]): Added.
+        * bindings/objc/DOMPrivate.h:
+        * page/Frame.h:
+        * page/mac/FrameMac.mm:
+        (WebCore::Frame::rangeImage): Added. Sets the selection in the RenderView (only) based on the
+        given range and gets a selection-only rendering of the view, then restores the selection.
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::setSelection): Skip all invalidation if the repaint behavior is RepaintNothing.
+        (WebCore::RenderView::getSelection): Added this getter.
+        * rendering/RenderView.h:
+
 2011-11-02  Tom Sepez  <[email protected]>
 
         XSSAuditor is silent

Modified: trunk/Source/WebCore/bindings/objc/DOM.mm (99098 => 99099)


--- trunk/Source/WebCore/bindings/objc/DOM.mm	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/bindings/objc/DOM.mm	2011-11-02 21:46:01 UTC (rev 99099)
@@ -403,6 +403,16 @@
     return core(self)->boundingBox();
 }
 
+- (NSImage *)renderedImageForcingBlackText:(BOOL)forceBlackText
+{
+    WebCore::Range* range = core(self);
+    WebCore::Frame* frame = range->ownerDocument()->frame();
+    if (!frame)
+        return nil;
+
+    return frame->rangeImage(range, forceBlackText);
+}
+
 - (NSArray *)textRects
 {
     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.

Modified: trunk/Source/WebCore/bindings/objc/DOMPrivate.h (99098 => 99099)


--- trunk/Source/WebCore/bindings/objc/DOMPrivate.h	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/bindings/objc/DOMPrivate.h	2011-11-02 21:46:01 UTC (rev 99099)
@@ -45,6 +45,7 @@
 
 @interface DOMRange (DOMRangeExtensions)
 - (NSRect)boundingBox;
+- (NSImage *)renderedImageForcingBlackText:(BOOL)forceBlackText;
 - (NSArray *)lineBoxRects; // Deprecated. Use textRects instead.
 - (NSArray *)textRects;
 @end

Modified: trunk/Source/WebCore/page/Frame.h (99098 => 99099)


--- trunk/Source/WebCore/page/Frame.h	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/page/Frame.h	2011-11-02 21:46:01 UTC (rev 99099)
@@ -196,6 +196,7 @@
         
 #if PLATFORM(MAC)
         NSImage* selectionImage(bool forceBlackText = false) const;
+        NSImage* rangeImage(Range*, bool forceBlackText = false) const;
         NSImage* snapshotDragImage(Node*, NSRect* imageRect, NSRect* elementRect) const;
         NSImage* imageFromRect(NSRect) const;
 #endif

Modified: trunk/Source/WebCore/page/mac/FrameMac.mm (99098 => 99099)


--- trunk/Source/WebCore/page/mac/FrameMac.mm	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/page/mac/FrameMac.mm	2011-11-02 21:46:01 UTC (rev 99099)
@@ -48,6 +48,7 @@
 #import "PlatformWheelEvent.h"
 #import "RegularExpression.h"
 #import "RenderTableCell.h"
+#import "RenderView.h"
 #import "Scrollbar.h"
 #import "SimpleFontData.h"
 #import "visible_units.h"
@@ -104,6 +105,48 @@
     return result;
 }
 
+NSImage *Frame::rangeImage(Range* range, bool forceBlackText) const
+{
+    m_view->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0));
+    m_doc->updateLayout();
+    RenderView* view = contentRenderer();
+    if (!view)
+        return nil;
+
+    VisibleSelection visibleSelection(range);
+
+    if (!visibleSelection.isRange())
+        return nil;
+
+    Position start = visibleSelection.start();
+    Position candidate = start.downstream();
+    if (candidate.isCandidate())
+        start = candidate;
+    Position end = visibleSelection.end();
+    candidate = end.upstream();
+    if (candidate.isCandidate())
+        end = candidate;
+
+    if (start.isNull() || end.isNull() || visibleSelection.visibleStart() == visibleSelection.visibleEnd())
+        return nil;
+
+    RenderObject* savedStartRenderer;
+    int savedStartOffset;
+    RenderObject* savedEndRenderer;
+    int savedEndOffset;
+    view->getSelection(savedStartRenderer, savedStartOffset, savedEndRenderer, savedEndOffset);
+
+    RenderObject* startRenderer = start.deprecatedNode()->renderer();
+    RenderObject* endRenderer = end.deprecatedNode()->renderer();
+
+    view->setSelection(startRenderer, start.deprecatedEditingOffset(), endRenderer, end.deprecatedEditingOffset(), RenderView::RepaintNothing);
+    NSImage* result = imageFromRect(view->selectionBounds());
+    view->setSelection(savedStartRenderer, savedStartOffset, savedEndRenderer, savedEndOffset, RenderView::RepaintNothing);
+
+    m_view->setPaintBehavior(PaintBehaviorNormal);
+    return result;
+}
+
 NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* elementRect) const
 {
     RenderObject* renderer = node->renderer();

Modified: trunk/Source/WebCore/rendering/RenderView.cpp (99098 => 99099)


--- trunk/Source/WebCore/rendering/RenderView.cpp	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/rendering/RenderView.cpp	2011-11-02 21:46:01 UTC (rev 99099)
@@ -488,7 +488,8 @@
         o = o->nextInPreOrder();
     }
 
-    m_layer->clearBlockSelectionGapsBounds();
+    if (blockRepaintMode != RepaintNothing)
+        m_layer->clearBlockSelectionGapsBounds();
 
     // Now that the selection state has been updated for the new objects, walk them again and
     // put them in the new objects list.
@@ -509,7 +510,7 @@
         o = o->nextInPreOrder();
     }
 
-    if (!m_frameView) {
+    if (!m_frameView || blockRepaintMode == RepaintNothing) {
         // We built the maps, but we aren't going to use them.
         // We need to delete the values, otherwise they'll all leak!
         deleteAllValues(oldSelectedObjects);
@@ -575,6 +576,14 @@
     m_frameView->endDeferredRepaints();
 }
 
+void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const
+{
+    startRenderer = m_selectionStart;
+    startOffset = m_selectionStartPos;
+    endRenderer = m_selectionEnd;
+    endOffset = m_selectionEndPos;
+}
+
 void RenderView::clearSelection()
 {
     m_layer->repaintBlockSelectionGaps();

Modified: trunk/Source/WebCore/rendering/RenderView.h (99098 => 99099)


--- trunk/Source/WebCore/rendering/RenderView.h	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Source/WebCore/rendering/RenderView.h	2011-11-02 21:46:01 UTC (rev 99099)
@@ -76,8 +76,9 @@
     virtual void paint(PaintInfo&, const LayoutPoint&);
     virtual void paintBoxDecorations(PaintInfo&, const IntPoint&);
 
-    enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld };
+    enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
     void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
+    void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const;
     void clearSelection();
     RenderObject* selectionStart() const { return m_selectionStart; }
     RenderObject* selectionEnd() const { return m_selectionEnd; }

Modified: trunk/Tools/ChangeLog (99098 => 99099)


--- trunk/Tools/ChangeLog	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Tools/ChangeLog	2011-11-02 21:46:01 UTC (rev 99099)
@@ -1,3 +1,15 @@
+2011-11-02  Dan Bernstein  <[email protected]>
+
+        <rdar://problem/10336700> Add API to get rendered text image without having to select it
+        https://bugs.webkit.org/show_bug.cgi?id=71407
+
+        Reviewed by Simon Fraser.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm: Added.
+        (-[RenderedImageFromDOMRangeFrameLoadDelegate webView:didFinishLoadForFrame:]):
+        (TestWebKitAPI::TEST):
+
 2011-11-02  Benjamin Poulain  <[email protected]>
 
         Make the main frame's base path more explicit in _drt_descriptionSuitableForTestResult

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (99098 => 99099)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2011-11-02 21:43:15 UTC (rev 99098)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2011-11-02 21:46:01 UTC (rev 99099)
@@ -24,6 +24,7 @@
 		33DC89141419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33DC89131419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp */; };
 		33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */; };
 		37200B9213A16230007A4FAD /* VectorReverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37200B9113A16230007A4FAD /* VectorReverse.cpp */; };
+		3722C8691461E03E00C45D00 /* RenderedImageFromDOMRange.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */; };
 		3799AD3A14120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */; };
 		37DC678D140D7C5000ABCCDB /* DOMRangeOfString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */; };
 		37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */; };
@@ -160,6 +161,7 @@
 		33DC89131419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadCanceledNoServerRedirectCallback_Bundle.cpp; sourceTree = "<group>"; };
 		33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "mouse-move-listener.html"; sourceTree = "<group>"; };
 		37200B9113A16230007A4FAD /* VectorReverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorReverse.cpp; path = WTF/VectorReverse.cpp; sourceTree = "<group>"; };
+		3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderedImageFromDOMRange.mm; sourceTree = "<group>"; };
 		3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringByEvaluatingJavaScriptFromString.mm; sourceTree = "<group>"; };
 		37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMRangeOfString.mm; sourceTree = "<group>"; };
 		37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMRangeOfString.html; sourceTree = "<group>"; };
@@ -475,6 +477,7 @@
 				37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */,
 				C07E6CAE13FD67650038B22B /* DynamicDeviceScaleFactor.mm */,
 				939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */,
+				3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */,
 				3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */,
 			);
 			path = mac;
@@ -656,6 +659,7 @@
 				BC3C4C7214575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm in Sources */,
 				BC3C4C7F14587AA60025FB62 /* WKBrowsingContextGroupTest.mm in Sources */,
 				C0C5D3BE14598B6F00A802A6 /* GetBackingScaleFactor.mm in Sources */,
+				3722C8691461E03E00C45D00 /* RenderedImageFromDOMRange.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Added: trunk/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm (0 => 99099)


--- trunk/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm	2011-11-02 21:46:01 UTC (rev 99099)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PlatformUtilities.h"
+#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/DOMPrivate.h>
+#import <wtf/RetainPtr.h>
+
+@interface RenderedImageFromDOMRangeFrameLoadDelegate : NSObject {
+}
+@end
+
+static bool didFinishLoad;
+
+@implementation RenderedImageFromDOMRangeFrameLoadDelegate
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+    didFinishLoad = true;
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+TEST(WebKit1, RenderedImageFromDOMRange)
+{
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+    RetainPtr<RenderedImageFromDOMRangeFrameLoadDelegate> frameLoadDelegate(AdoptNS, [RenderedImageFromDOMRangeFrameLoadDelegate new]);
+
+    webView.get().frameLoadDelegate = frameLoadDelegate.get();
+    [webView.get().mainFrame loadHTMLString:@"<div style=\"width: 100px;\">Lorem <span id=\"target\">ipsum dolor</span> sit amet</div>" baseURL:[NSURL URLWithString:@"about:blank"]];
+
+    Util::run(&didFinishLoad);
+
+    DOMDocument *document = webView.get().mainFrameDocument;
+    DOMRange *range = [document createRange];
+    [range selectNode:[document getElementById:@"target"]];
+    NSImage *actualImage = [range renderedImageForcingBlackText:YES];
+
+    [webView.get() setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream];
+    id <WebDocumentView> documentView = webView.get().mainFrame.frameView.documentView;
+    NSImage *expectedImage = [(id <WebDocumentSelection>)documentView selectionImageForcingBlackText:YES];
+    EXPECT_TRUE([actualImage.TIFFRepresentation isEqual:expectedImage.TIFFRepresentation]);
+}
+
+} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to