[MSE][GStreamer] Remove dead code in MediaPlayerPrivateGStreamer::doSeek()
[WebKit-https.git] / Source / WebCore / platform / DragImage.cpp
1 /*
2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "DragImage.h"
28
29 #include "Frame.h"
30 #include "FrameSnapshotting.h"
31 #include "FrameView.h"
32 #include "ImageBuffer.h"
33 #include "NotImplemented.h"
34 #include "Range.h"
35 #include "RenderElement.h"
36 #include "RenderObject.h"
37 #include "RenderView.h"
38 #include "TextIndicator.h"
39
40 namespace WebCore {
41
42 #if PLATFORM(COCOA)
43 const float ColorSwatchCornerRadius = 4;
44 const float ColorSwatchStrokeSize = 4;
45 const float ColorSwatchWidth = 24;
46 #endif
47
48 DragImageRef fitDragImageToMaxSize(DragImageRef image, const IntSize& layoutSize, const IntSize& maxSize)
49 {
50     float heightResizeRatio = 0.0f;
51     float widthResizeRatio = 0.0f;
52     float resizeRatio = -1.0f;
53     IntSize originalSize = dragImageSize(image);
54
55     if (layoutSize.width() > maxSize.width()) {
56         widthResizeRatio = maxSize.width() / (float)layoutSize.width();
57         resizeRatio = widthResizeRatio;
58     }
59
60     if (layoutSize.height() > maxSize.height()) {
61         heightResizeRatio = maxSize.height() / (float)layoutSize.height();
62         if ((resizeRatio < 0.0f) || (resizeRatio > heightResizeRatio))
63             resizeRatio = heightResizeRatio;
64     }
65
66     if (layoutSize == originalSize)
67         return resizeRatio > 0.0f ? scaleDragImage(image, FloatSize(resizeRatio, resizeRatio)) : image;
68
69     // The image was scaled in the webpage so at minimum we must account for that scaling.
70     float scaleX = layoutSize.width() / (float)originalSize.width();
71     float scaleY = layoutSize.height() / (float)originalSize.height();
72     if (resizeRatio > 0.0f) {
73         scaleX *= resizeRatio;
74         scaleY *= resizeRatio;
75     }
76
77     return scaleDragImage(image, FloatSize(scaleX, scaleY));
78 }
79
80 struct ScopedNodeDragEnabler {
81     ScopedNodeDragEnabler(Frame& frame, Node& node)
82         : frame(frame)
83         , node(node)
84     {
85         if (node.renderer())
86             node.renderer()->updateDragState(true);
87         frame.document()->updateLayout();
88     }
89
90     ~ScopedNodeDragEnabler()
91     {
92         if (node.renderer())
93             node.renderer()->updateDragState(false);
94     }
95
96     const Frame& frame;
97     const Node& node;
98 };
99
100 static DragImageRef createDragImageFromSnapshot(std::unique_ptr<ImageBuffer> snapshot, Node* node)
101 {
102     if (!snapshot)
103         return nullptr;
104
105     ImageOrientationDescription orientation;
106 #if ENABLE(CSS_IMAGE_ORIENTATION)
107     if (node) {
108         RenderObject* renderer = node->renderer();
109         if (!renderer || !is<RenderElement>(renderer))
110             return nullptr;
111
112         auto& renderElement = downcast<RenderElement>(*renderer);
113         orientation.setRespectImageOrientation(renderElement.shouldRespectImageOrientation());
114         orientation.setImageOrientationEnum(renderElement.style().imageOrientation());
115     }
116 #else
117     UNUSED_PARAM(node);
118 #endif
119     RefPtr<Image> image = ImageBuffer::sinkIntoImage(WTFMove(snapshot), PreserveResolution::Yes);
120     if (!image)
121         return nullptr;
122     return createDragImageFromImage(image.get(), orientation);
123 }
124
125 DragImageRef createDragImageForNode(Frame& frame, Node& node)
126 {
127     ScopedNodeDragEnabler enableDrag(frame, node);
128     return createDragImageFromSnapshot(snapshotNode(frame, node), &node);
129 }
130
131 #if !ENABLE(DATA_INTERACTION)
132
133 DragImageRef createDragImageForSelection(Frame& frame, TextIndicatorData&, bool forceBlackText)
134 {
135     SnapshotOptions options = forceBlackText ? SnapshotOptionsForceBlackText : SnapshotOptionsNone;
136     return createDragImageFromSnapshot(snapshotSelection(frame, options), nullptr);
137 }
138
139 #endif
140
141 struct ScopedFrameSelectionState {
142     ScopedFrameSelectionState(Frame& frame)
143         : frame(frame)
144     {
145         if (auto* renderView = frame.contentRenderer())
146             selection = renderView->selection().get();
147     }
148
149     ~ScopedFrameSelectionState()
150     {
151         if (auto* renderView = frame.contentRenderer()) {
152             ASSERT(selection);
153             renderView->selection().set(selection.value(), SelectionRangeData::RepaintMode::Nothing);
154         }
155     }
156
157     const Frame& frame;
158     Optional<SelectionRangeData::Context> selection;
159 };
160
161 #if !PLATFORM(IOS_FAMILY)
162
163 DragImageRef createDragImageForRange(Frame& frame, Range& range, bool forceBlackText)
164 {
165     frame.document()->updateLayout();
166     RenderView* view = frame.contentRenderer();
167     if (!view)
168         return nullptr;
169
170     // To snapshot the range, temporarily select it and take selection snapshot.
171     Position start = range.startPosition();
172     Position candidate = start.downstream();
173     if (candidate.deprecatedNode() && candidate.deprecatedNode()->renderer())
174         start = candidate;
175
176     Position end = range.endPosition();
177     candidate = end.upstream();
178     if (candidate.deprecatedNode() && candidate.deprecatedNode()->renderer())
179         end = candidate;
180
181     if (start.isNull() || end.isNull() || start == end)
182         return nullptr;
183
184     const ScopedFrameSelectionState selectionState(frame);
185
186     RenderObject* startRenderer = start.deprecatedNode()->renderer();
187     RenderObject* endRenderer = end.deprecatedNode()->renderer();
188     if (!startRenderer || !endRenderer)
189         return nullptr;
190
191     SnapshotOptions options = SnapshotOptionsPaintSelectionOnly | (forceBlackText ? SnapshotOptionsForceBlackText : SnapshotOptionsNone);
192     int startOffset = start.deprecatedEditingOffset();
193     int endOffset = end.deprecatedEditingOffset();
194     ASSERT(startOffset >= 0 && endOffset >= 0);
195     view->selection().set({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }, SelectionRangeData::RepaintMode::Nothing);
196     // We capture using snapshotFrameRect() because we fake up the selection using
197     // FrameView but snapshotSelection() uses the selection from the Frame itself.
198     return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selection().boundsClippedToVisibleContent(), options), nullptr);
199 }
200
201 #endif
202
203 DragImageRef createDragImageForImage(Frame& frame, Node& node, IntRect& imageRect, IntRect& elementRect)
204 {
205     ScopedNodeDragEnabler enableDrag(frame, node);
206
207     RenderObject* renderer = node.renderer();
208     if (!renderer)
209         return nullptr;
210
211     // Calculate image and element metrics for the client, then create drag image.
212     LayoutRect topLevelRect;
213     IntRect paintingRect = snappedIntRect(renderer->paintingRootRect(topLevelRect));
214
215     if (paintingRect.isEmpty())
216         return nullptr;
217
218     elementRect = snappedIntRect(topLevelRect);
219     imageRect = paintingRect;
220
221     return createDragImageFromSnapshot(snapshotNode(frame, node), &node);
222 }
223
224 #if !ENABLE(DATA_INTERACTION)
225 DragImageRef platformAdjustDragImageForDeviceScaleFactor(DragImageRef image, float deviceScaleFactor)
226 {
227     // Later code expects the drag image to be scaled by device's scale factor.
228     return scaleDragImage(image, { deviceScaleFactor, deviceScaleFactor });
229 }
230 #endif
231
232 #if !PLATFORM(MAC)
233 const int linkDragBorderInset = 2;
234
235 IntPoint dragOffsetForLinkDragImage(DragImageRef dragImage)
236 {
237     IntSize size = dragImageSize(dragImage);
238     return { -size.width() / 2, -linkDragBorderInset };
239 }
240
241 FloatPoint anchorPointForLinkDragImage(DragImageRef dragImage)
242 {
243     IntSize size = dragImageSize(dragImage);
244     return { 0.5, static_cast<float>((size.height() - linkDragBorderInset) / size.height()) };
245 }
246 #endif
247
248 DragImage::DragImage()
249     : m_dragImageRef { nullptr }
250 {
251 }
252
253 DragImage::DragImage(DragImageRef dragImageRef)
254     : m_dragImageRef { dragImageRef }
255 {
256 }
257
258 DragImage::DragImage(DragImage&& other)
259     : m_dragImageRef { std::exchange(other.m_dragImageRef, nullptr) }
260 {
261     m_indicatorData = other.m_indicatorData;
262     m_visiblePath = other.m_visiblePath;
263 }
264
265 DragImage& DragImage::operator=(DragImage&& other)
266 {
267     if (m_dragImageRef)
268         deleteDragImage(m_dragImageRef);
269
270     m_dragImageRef = std::exchange(other.m_dragImageRef, nullptr);
271     m_indicatorData = other.m_indicatorData;
272     m_visiblePath = other.m_visiblePath;
273
274     return *this;
275 }
276
277 DragImage::~DragImage()
278 {
279     if (m_dragImageRef)
280         deleteDragImage(m_dragImageRef);
281 }
282
283 #if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN)
284
285 IntSize dragImageSize(DragImageRef)
286 {
287     notImplemented();
288     return { 0, 0 };
289 }
290
291 void deleteDragImage(DragImageRef)
292 {
293     notImplemented();
294 }
295
296 DragImageRef scaleDragImage(DragImageRef, FloatSize)
297 {
298     notImplemented();
299     return nullptr;
300 }
301
302 DragImageRef dissolveDragImageToFraction(DragImageRef, float)
303 {
304     notImplemented();
305     return nullptr;
306 }
307
308 DragImageRef createDragImageFromImage(Image*, ImageOrientationDescription)
309 {
310     notImplemented();
311     return nullptr;
312 }
313
314 DragImageRef createDragImageIconForCachedImageFilename(const String&)
315 {
316     notImplemented();
317     return nullptr;
318 }
319
320 DragImageRef createDragImageForLink(Element&, URL&, const String&, TextIndicatorData&, FontRenderingMode, float)
321 {
322     notImplemented();
323     return nullptr;
324 }
325
326 #endif
327
328 } // namespace WebCore
329