1/* 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 5 * Copyright (C) 2013 University of Washington. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 31#include "config.h" 32#include "FrameSnapshotting.h" 33 34#include "Document.h" 35#include "Frame.h" 36#include "FrameSelection.h" 37#include "FrameView.h" 38#include "GraphicsContext.h" 39#include "ImageBuffer.h" 40#include "Page.h" 41#include "RenderObject.h" 42 43namespace WebCore { 44 45struct ScopedFramePaintingState { 46 ScopedFramePaintingState(Frame& frame, Node* node) 47 : frame(frame) 48 , node(node) 49 , paintBehavior(frame.view()->paintBehavior()) 50 , backgroundColor(frame.view()->baseBackgroundColor()) 51 { 52 ASSERT(!node || node->renderer()); 53 } 54 55 ~ScopedFramePaintingState() 56 { 57 frame.view()->setPaintBehavior(paintBehavior); 58 frame.view()->setBaseBackgroundColor(backgroundColor); 59 frame.view()->setNodeToDraw(nullptr); 60 } 61 62 const Frame& frame; 63 const Node* node; 64 const PaintBehavior paintBehavior; 65 const Color backgroundColor; 66}; 67 68std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame& frame, const IntRect& imageRect, SnapshotOptions options) 69{ 70 if (!frame.page()) 71 return nullptr; 72 73 frame.document()->updateLayout(); 74 75 FrameView::SelectionInSnapshot shouldIncludeSelection = FrameView::IncludeSelection; 76 if (options & SnapshotOptionsExcludeSelectionHighlighting) 77 shouldIncludeSelection = FrameView::ExcludeSelection; 78 79 FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates; 80 if (options & SnapshotOptionsInViewCoordinates) 81 coordinateSpace = FrameView::ViewCoordinates; 82 83 ScopedFramePaintingState state(frame, nullptr); 84 85 PaintBehavior paintBehavior = state.paintBehavior; 86 if (options & SnapshotOptionsForceBlackText) 87 paintBehavior |= PaintBehaviorForceBlackText; 88 if (options & SnapshotOptionsPaintSelectionOnly) 89 paintBehavior |= PaintBehaviorSelectionOnly; 90 91 // Other paint behaviors are set by paintContentsForSnapshot. 92 frame.view()->setPaintBehavior(paintBehavior); 93 94 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(imageRect.size(), frame.page()->deviceScaleFactor(), ColorSpaceDeviceRGB); 95 if (!buffer) 96 return nullptr; 97 buffer->context()->translate(-imageRect.x(), -imageRect.y()); 98 99 frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace); 100 return buffer; 101} 102 103std::unique_ptr<ImageBuffer> snapshotSelection(Frame& frame, SnapshotOptions options) 104{ 105 if (!frame.selection().isRange()) 106 return nullptr; 107 108 options |= SnapshotOptionsPaintSelectionOnly; 109 return snapshotFrameRect(frame, enclosingIntRect(frame.selection().selectionBounds()), options); 110} 111 112std::unique_ptr<ImageBuffer> snapshotNode(Frame& frame, Node& node) 113{ 114 if (!node.renderer()) 115 return nullptr; 116 117 ScopedFramePaintingState state(frame, &node); 118 119 frame.view()->setBaseBackgroundColor(Color::transparent); 120 frame.view()->setNodeToDraw(&node); 121 122 LayoutRect topLevelRect; 123 return snapshotFrameRect(frame, pixelSnappedIntRect(node.renderer()->paintingRootRect(topLevelRect))); 124} 125 126} // namespace WebCore 127