Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: sky/engine/web/LinkHighlight.cpp

Issue 762993003: Remove GraphicsLayer family of classes. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "sky/engine/config.h"
27
28 #include "sky/engine/web/LinkHighlight.h"
29
30 #include "sky/engine/core/dom/Node.h"
31 #include "sky/engine/core/frame/FrameView.h"
32 #include "sky/engine/core/frame/LocalFrame.h"
33 #include "sky/engine/core/rendering/RenderLayer.h"
34 #include "sky/engine/core/rendering/RenderLayerModelObject.h"
35 #include "sky/engine/core/rendering/RenderObject.h"
36 #include "sky/engine/core/rendering/RenderView.h"
37 #include "sky/engine/core/rendering/style/ShadowData.h"
38 #include "sky/engine/platform/graphics/Color.h"
39 #include "sky/engine/public/platform/Platform.h"
40 #include "sky/engine/public/platform/WebCompositorAnimationCurve.h"
41 #include "sky/engine/public/platform/WebCompositorSupport.h"
42 #include "sky/engine/public/platform/WebFloatAnimationCurve.h"
43 #include "sky/engine/public/platform/WebFloatPoint.h"
44 #include "sky/engine/public/platform/WebRect.h"
45 #include "sky/engine/public/platform/WebSize.h"
46 #include "sky/engine/public/web/Sky.h"
47 #include "sky/engine/web/WebLocalFrameImpl.h"
48 #include "sky/engine/web/WebSettingsImpl.h"
49 #include "sky/engine/web/WebViewImpl.h"
50 #include "sky/engine/wtf/CurrentTime.h"
51 #include "third_party/skia/include/utils/SkMatrix44.h"
52
53 namespace blink {
54
55 class WebViewImpl;
56
57 PassOwnPtr<LinkHighlight> LinkHighlight::create(Node* node, WebViewImpl* owningW ebViewImpl)
58 {
59 return adoptPtr(new LinkHighlight(node, owningWebViewImpl));
60 }
61
62 LinkHighlight::LinkHighlight(Node* node, WebViewImpl* owningWebViewImpl)
63 : m_node(node)
64 , m_owningWebViewImpl(owningWebViewImpl)
65 , m_currentGraphicsLayer(0)
66 , m_geometryNeedsUpdate(false)
67 , m_isAnimating(false)
68 , m_startTime(monotonicallyIncreasingTime())
69 {
70 ASSERT(m_node);
71 ASSERT(owningWebViewImpl);
72 WebCompositorSupport* compositorSupport = Platform::current()->compositorSup port();
73 m_contentLayer = adoptPtr(compositorSupport->createContentLayer(this));
74 m_clipLayer = adoptPtr(compositorSupport->createLayer());
75 m_clipLayer->setTransformOrigin(WebFloatPoint3D());
76 m_clipLayer->addChild(m_contentLayer->layer());
77 m_contentLayer->layer()->setAnimationDelegate(this);
78 m_contentLayer->layer()->setDrawsContent(true);
79 m_contentLayer->layer()->setOpacity(1);
80 m_geometryNeedsUpdate = true;
81 updateGeometry();
82 }
83
84 LinkHighlight::~LinkHighlight()
85 {
86 clearGraphicsLayerLinkHighlightPointer();
87 releaseResources();
88 }
89
90 WebContentLayer* LinkHighlight::contentLayer()
91 {
92 return m_contentLayer.get();
93 }
94
95 WebLayer* LinkHighlight::clipLayer()
96 {
97 return m_clipLayer.get();
98 }
99
100 void LinkHighlight::releaseResources()
101 {
102 m_node.clear();
103 }
104
105 RenderLayer* LinkHighlight::computeEnclosingCompositingLayer()
106 {
107 return 0;
108 }
109
110 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad)
111 {
112 ASSERT(targetRenderer);
113 ASSERT(compositedRenderer);
114
115 for (unsigned i = 0; i < 4; ++i) {
116 IntPoint point;
117 switch (i) {
118 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break;
119 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break;
120 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break;
121 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break;
122 }
123
124 point = targetRenderer->frame()->view()->contentsToWindow(point);
125 point = compositedRenderer->frame()->view()->windowToContents(point);
126 FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTr ansforms);
127
128 switch (i) {
129 case 0: compositedSpaceQuad.setP1(floatPoint); break;
130 case 1: compositedSpaceQuad.setP2(floatPoint); break;
131 case 2: compositedSpaceQuad.setP3(floatPoint); break;
132 case 3: compositedSpaceQuad.setP4(floatPoint); break;
133 }
134 }
135 }
136
137 static void addQuadToPath(const FloatQuad& quad, Path& path)
138 {
139 // FIXME: Make this create rounded quad-paths, just like the axis-aligned ca se.
140 path.moveTo(quad.p1());
141 path.addLineTo(quad.p2());
142 path.addLineTo(quad.p3());
143 path.addLineTo(quad.p4());
144 path.closeSubpath();
145 }
146
147 void LinkHighlight::computeQuads(RenderObject& renderer, Vector<FloatQuad>& outQ uads) const
148 {
149 // For inline elements, absoluteQuads will return a line box based on the li ne-height
150 // and font metrics, which is technically incorrect as replaced elements lik e images
151 // should use their intristic height and expand the linebox as needed. To g et an
152 // appropriately sized highlight we descend into the children and have them add their
153 // boxes.
154 if (renderer.isRenderInline()) {
155 for (RenderObject* child = renderer.slowFirstChild(); child; child = chi ld->nextSibling())
156 computeQuads(*child, outQuads);
157 } else {
158 renderer.absoluteQuads(outQuads);
159 }
160 }
161
162 bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin gLayer)
163 {
164 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer)
165 return false;
166
167 ASSERT(compositingLayer);
168
169 // Get quads for node in absolute coordinates.
170 Vector<FloatQuad> quads;
171 computeQuads(*m_node->renderer(), quads);
172 ASSERT(quads.size());
173
174 // Adjust for offset between target graphics layer and the node's renderer.
175 FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRende rer());
176
177 Path newPath;
178 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) {
179 FloatQuad absoluteQuad = quads[quadIndex];
180 absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y());
181
182 // Transform node quads in target absolute coords to local coordinates i n the compositor layer.
183 FloatQuad transformedQuad;
184 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , compositingLayer->renderer(), transformedQuad);
185
186 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that
187 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage
188 // links: these should ideally be merged into a single rect before creat ing the path, but that's
189 // another CL.
190 if (quads.size() == 1 && transformedQuad.isRectilinear()
191 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) {
192 FloatSize rectRoundingRadii(3, 3);
193 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii);
194 } else
195 addQuadToPath(transformedQuad, newPath);
196 }
197
198 FloatRect boundingRect = newPath.boundingRect();
199 newPath.translate(-toFloatSize(boundingRect.location()));
200
201 bool pathHasChanged = !(newPath == m_path);
202 if (pathHasChanged) {
203 m_path = newPath;
204 m_contentLayer->layer()->setBounds(enclosingIntRect(boundingRect).size() );
205 }
206
207 m_contentLayer->layer()->setPosition(boundingRect.location());
208
209 return pathHasChanged;
210 }
211
212 void LinkHighlight::paintContents(WebCanvas* canvas, const WebRect& webClipRect, bool, WebFloatRect&,
213 WebContentLayerClient::GraphicsContextStatus contextStatus)
214 {
215 if (!m_node || !m_node->renderer())
216 return;
217
218 GraphicsContext gc(canvas,
219 contextStatus == WebContentLayerClient::GraphicsContextEnabled ? Graphic sContext::NothingDisabled : GraphicsContext::FullyDisabled);
220 IntRect clipRect(IntPoint(webClipRect.x, webClipRect.y), IntSize(webClipRect .width, webClipRect.height));
221 gc.clip(clipRect);
222 gc.setFillColor(m_node->renderer()->style()->tapHighlightColor());
223 gc.fillPath(m_path);
224 }
225
226 void LinkHighlight::startHighlightAnimationIfNeeded()
227 {
228 if (m_isAnimating)
229 return;
230
231 m_isAnimating = true;
232 const float startOpacity = 1;
233 // FIXME: Should duration be configurable?
234 const float fadeDuration = 0.1f;
235 const float minPreFadeDuration = 0.1f;
236
237 m_contentLayer->layer()->setOpacity(startOpacity);
238
239 WebCompositorSupport* compositorSupport = Platform::current()->compositorSup port();
240
241 OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(compositorSupport->createFlo atAnimationCurve());
242
243 curve->add(WebFloatKeyframe(0, startOpacity));
244 // Make sure we have displayed for at least minPreFadeDuration before starti ng to fade out.
245 float extraDurationRequired = std::max(0.f, minPreFadeDuration - static_cast <float>(monotonicallyIncreasingTime() - m_startTime));
246 if (extraDurationRequired)
247 curve->add(WebFloatKeyframe(extraDurationRequired, startOpacity));
248 // For layout tests we don't fade out.
249 curve->add(WebFloatKeyframe(fadeDuration + extraDurationRequired, layoutTest Mode() ? startOpacity : 0));
250
251 OwnPtr<WebCompositorAnimation> animation = adoptPtr(compositorSupport->creat eAnimation(*curve, WebCompositorAnimation::TargetPropertyOpacity));
252
253 m_contentLayer->layer()->setDrawsContent(true);
254 m_contentLayer->layer()->addAnimation(animation.leakPtr());
255
256 invalidate();
257 m_owningWebViewImpl->scheduleAnimation();
258 }
259
260 void LinkHighlight::clearGraphicsLayerLinkHighlightPointer()
261 {
262 if (m_currentGraphicsLayer) {
263 m_currentGraphicsLayer->removeLinkHighlight(this);
264 m_currentGraphicsLayer = 0;
265 }
266 }
267
268 void LinkHighlight::notifyAnimationStarted(double, WebCompositorAnimation::Targe tProperty)
269 {
270 }
271
272 void LinkHighlight::notifyAnimationFinished(double, WebCompositorAnimation::Targ etProperty)
273 {
274 // Since WebViewImpl may hang on to us for a while, make sure we
275 // release resources as soon as possible.
276 clearGraphicsLayerLinkHighlightPointer();
277 releaseResources();
278 }
279
280 void LinkHighlight::updateGeometry()
281 {
282 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl),
283 // only proceed if we actually requested an update.
284 if (!m_geometryNeedsUpdate)
285 return;
286
287 m_geometryNeedsUpdate = false;
288
289 RenderLayer* compositingLayer = computeEnclosingCompositingLayer();
290 if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLaye r)) {
291 // We only need to invalidate the layer if the highlight size has change d, otherwise
292 // we can just re-position the layer without needing to repaint.
293 m_contentLayer->layer()->invalidate();
294
295 if (m_currentGraphicsLayer)
296 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height));
297 } else if (!m_node || !m_node->renderer()) {
298 clearGraphicsLayerLinkHighlightPointer();
299 releaseResources();
300 }
301 }
302
303 void LinkHighlight::clearCurrentGraphicsLayer()
304 {
305 m_currentGraphicsLayer = 0;
306 m_geometryNeedsUpdate = true;
307 }
308
309 void LinkHighlight::invalidate()
310 {
311 // Make sure we update geometry on the next callback from WebViewImpl::layou t().
312 m_geometryNeedsUpdate = true;
313 }
314
315 WebLayer* LinkHighlight::layer()
316 {
317 return clipLayer();
318 }
319
320 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698