Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 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 "config.h" |
| 27 | |
| 28 | #include "LinkHighlight.h" |
| 29 | |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 30 | #include "SkMatrix44.h" |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 31 | #include "WebFrameImpl.h" |
| 32 | #include "WebKit.h" |
| 33 | #include "WebViewImpl.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 34 | #include "core/dom/Node.h" |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 35 | #include "core/frame/FrameView.h" |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 36 | #include "core/frame/LocalFrame.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 37 | #include "core/rendering/RenderLayer.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 38 | #include "core/rendering/RenderLayerModelObject.h" |
| 39 | #include "core/rendering/RenderObject.h" |
| 40 | #include "core/rendering/RenderView.h" |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 41 | #include "core/rendering/compositing/CompositedLayerMapping.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 42 | #include "core/rendering/style/ShadowData.h" |
Torne (Richard Coles) | f79f16f | 2013-10-31 11:16:44 +0000 | [diff] [blame] | 43 | #include "platform/graphics/Color.h" |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 44 | #include "public/platform/Platform.h" |
| 45 | #include "public/platform/WebAnimationCurve.h" |
| 46 | #include "public/platform/WebCompositorSupport.h" |
| 47 | #include "public/platform/WebFloatAnimationCurve.h" |
| 48 | #include "public/platform/WebFloatPoint.h" |
| 49 | #include "public/platform/WebRect.h" |
| 50 | #include "public/platform/WebSize.h" |
Ben Murdoch | 591b958 | 2013-07-10 11:41:44 +0100 | [diff] [blame] | 51 | #include "wtf/CurrentTime.h" |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 52 | #include "wtf/Vector.h" |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 53 | |
| 54 | using namespace WebCore; |
| 55 | |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 56 | namespace blink { |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 57 | |
| 58 | class WebViewImpl; |
| 59 | |
| 60 | PassOwnPtr<LinkHighlight> LinkHighlight::create(Node* node, WebViewImpl* owningWebViewImpl) |
| 61 | { |
| 62 | return adoptPtr(new LinkHighlight(node, owningWebViewImpl)); |
| 63 | } |
| 64 | |
| 65 | LinkHighlight::LinkHighlight(Node* node, WebViewImpl* owningWebViewImpl) |
| 66 | : m_node(node) |
| 67 | , m_owningWebViewImpl(owningWebViewImpl) |
| 68 | , m_currentGraphicsLayer(0) |
| 69 | , m_geometryNeedsUpdate(false) |
| 70 | , m_isAnimating(false) |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 71 | , m_startTime(monotonicallyIncreasingTime()) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 72 | { |
| 73 | ASSERT(m_node); |
| 74 | ASSERT(owningWebViewImpl); |
| 75 | WebCompositorSupport* compositorSupport = Platform::current()->compositorSupport(); |
| 76 | m_contentLayer = adoptPtr(compositorSupport->createContentLayer(this)); |
| 77 | m_clipLayer = adoptPtr(compositorSupport->createLayer()); |
| 78 | m_clipLayer->setAnchorPoint(WebFloatPoint()); |
| 79 | m_clipLayer->addChild(m_contentLayer->layer()); |
| 80 | m_contentLayer->layer()->setAnimationDelegate(this); |
| 81 | m_contentLayer->layer()->setDrawsContent(true); |
| 82 | m_contentLayer->layer()->setOpacity(1); |
| 83 | m_geometryNeedsUpdate = true; |
| 84 | updateGeometry(); |
| 85 | } |
| 86 | |
| 87 | LinkHighlight::~LinkHighlight() |
| 88 | { |
| 89 | clearGraphicsLayerLinkHighlightPointer(); |
| 90 | releaseResources(); |
| 91 | } |
| 92 | |
| 93 | WebContentLayer* LinkHighlight::contentLayer() |
| 94 | { |
| 95 | return m_contentLayer.get(); |
| 96 | } |
| 97 | |
| 98 | WebLayer* LinkHighlight::clipLayer() |
| 99 | { |
| 100 | return m_clipLayer.get(); |
| 101 | } |
| 102 | |
| 103 | void LinkHighlight::releaseResources() |
| 104 | { |
| 105 | m_node.clear(); |
| 106 | } |
| 107 | |
| 108 | RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() |
| 109 | { |
| 110 | if (!m_node || !m_node->renderer()) |
| 111 | return 0; |
| 112 | |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 113 | // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries |
| 114 | // to find a suitable layer. |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 115 | RenderObject* renderer = m_node->renderer(); |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 116 | RenderLayerModelObject* repaintContainer; |
| 117 | do { |
| 118 | repaintContainer = renderer->containerForRepaint(); |
| 119 | if (!repaintContainer) { |
| 120 | renderer = renderer->frame()->ownerRenderer(); |
| 121 | if (!renderer) |
| 122 | return 0; |
| 123 | } |
| 124 | } while (!repaintContainer); |
| 125 | RenderLayer* renderLayer = repaintContainer->layer(); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 126 | |
Torne (Richard Coles) | bfe3590 | 2013-10-22 16:41:51 +0100 | [diff] [blame] | 127 | if (!renderLayer || renderLayer->compositingState() == NotComposited) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 128 | return 0; |
| 129 | |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 130 | GraphicsLayer* newGraphicsLayer = renderLayer->compositedLayerMapping()->mainGraphicsLayer(); |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 131 | m_clipLayer->setTransform(SkMatrix44()); |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 132 | |
| 133 | if (!newGraphicsLayer->drawsContent()) { |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 134 | if (renderLayer->scrollableArea() && renderLayer->scrollableArea()->usesCompositedScrolling()) { |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 135 | ASSERT(renderLayer->hasCompositedLayerMapping() && renderLayer->compositedLayerMapping()->scrollingContentsLayer()); |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 136 | newGraphicsLayer = renderLayer->compositedLayerMapping()->scrollingContentsLayer(); |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 137 | } |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 138 | } |
| 139 | |
| 140 | if (m_currentGraphicsLayer != newGraphicsLayer) { |
| 141 | if (m_currentGraphicsLayer) |
| 142 | clearGraphicsLayerLinkHighlightPointer(); |
| 143 | |
| 144 | m_currentGraphicsLayer = newGraphicsLayer; |
Torne (Richard Coles) | 9bbd2f5 | 2013-09-19 22:37:05 +0100 | [diff] [blame] | 145 | m_currentGraphicsLayer->addLinkHighlight(this); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | return renderLayer; |
| 149 | } |
| 150 | |
| 151 | static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpaceQuad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad) |
| 152 | { |
| 153 | ASSERT(targetRenderer); |
| 154 | ASSERT(compositedRenderer); |
| 155 | |
| 156 | for (unsigned i = 0; i < 4; ++i) { |
| 157 | IntPoint point; |
| 158 | switch (i) { |
| 159 | case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; |
| 160 | case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; |
| 161 | case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; |
| 162 | case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; |
| 163 | } |
| 164 | |
| 165 | point = targetRenderer->frame()->view()->contentsToWindow(point); |
| 166 | point = compositedRenderer->frame()->view()->windowToContents(point); |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 167 | FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTransforms); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 168 | |
| 169 | switch (i) { |
| 170 | case 0: compositedSpaceQuad.setP1(floatPoint); break; |
| 171 | case 1: compositedSpaceQuad.setP2(floatPoint); break; |
| 172 | case 2: compositedSpaceQuad.setP3(floatPoint); break; |
| 173 | case 3: compositedSpaceQuad.setP4(floatPoint); break; |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | static void addQuadToPath(const FloatQuad& quad, Path& path) |
| 179 | { |
| 180 | // FIXME: Make this create rounded quad-paths, just like the axis-aligned case. |
| 181 | path.moveTo(quad.p1()); |
| 182 | path.addLineTo(quad.p2()); |
| 183 | path.addLineTo(quad.p3()); |
| 184 | path.addLineTo(quad.p4()); |
| 185 | path.closeSubpath(); |
| 186 | } |
| 187 | |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 188 | void LinkHighlight::computeQuads(Node* node, Vector<FloatQuad>& outQuads) const |
| 189 | { |
| 190 | if (!node || !node->renderer()) |
| 191 | return; |
| 192 | |
| 193 | RenderObject* renderer = node->renderer(); |
| 194 | |
| 195 | // For inline elements, absoluteQuads will return a line box based on the line-height |
| 196 | // and font metrics, which is technically incorrect as replaced elements like images |
| 197 | // should use their intristic height and expand the linebox as needed. To get an |
| 198 | // appropriately sized highlight we descend into the children and have them add their |
| 199 | // boxes. |
| 200 | if (renderer->isRenderInline()) { |
| 201 | for (Node* child = node->firstChild(); child; child = child->nextSibling()) |
| 202 | computeQuads(child, outQuads); |
| 203 | } else { |
| 204 | renderer->absoluteQuads(outQuads); |
| 205 | } |
| 206 | |
| 207 | } |
| 208 | |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 209 | bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositingLayer) |
| 210 | { |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 211 | if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 212 | return false; |
| 213 | |
| 214 | ASSERT(compositingLayer); |
| 215 | |
| 216 | // Get quads for node in absolute coordinates. |
| 217 | Vector<FloatQuad> quads; |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 218 | computeQuads(m_node.get(), quads); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 219 | ASSERT(quads.size()); |
| 220 | |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 221 | // Adjust for offset between target graphics layer and the node's renderer. |
| 222 | FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRenderer()); |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 223 | |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 224 | Path newPath; |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 225 | for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 226 | FloatQuad absoluteQuad = quads[quadIndex]; |
| 227 | absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y()); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 228 | |
| 229 | // Transform node quads in target absolute coords to local coordinates in the compositor layer. |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 230 | FloatQuad transformedQuad; |
| 231 | convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer(), compositingLayer->renderer(), transformedQuad); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 232 | |
| 233 | // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that |
| 234 | // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage |
| 235 | // links: these should ideally be merged into a single rect before creating the path, but that's |
| 236 | // another CL. |
| 237 | if (quads.size() == 1 && transformedQuad.isRectilinear()) { |
| 238 | FloatSize rectRoundingRadii(3, 3); |
| 239 | newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRadii); |
| 240 | } else |
| 241 | addQuadToPath(transformedQuad, newPath); |
| 242 | } |
| 243 | |
| 244 | FloatRect boundingRect = newPath.boundingRect(); |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 245 | newPath.translate(-toFloatSize(boundingRect.location())); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 246 | |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 247 | bool pathHasChanged = !(newPath == m_path); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 248 | if (pathHasChanged) { |
| 249 | m_path = newPath; |
| 250 | m_contentLayer->layer()->setBounds(enclosingIntRect(boundingRect).size()); |
| 251 | } |
| 252 | |
| 253 | m_contentLayer->layer()->setPosition(boundingRect.location()); |
| 254 | |
| 255 | return pathHasChanged; |
| 256 | } |
| 257 | |
| 258 | void LinkHighlight::paintContents(WebCanvas* canvas, const WebRect& webClipRect, bool, WebFloatRect&) |
| 259 | { |
| 260 | if (!m_node || !m_node->renderer()) |
| 261 | return; |
| 262 | |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 263 | GraphicsContext gc(canvas); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 264 | IntRect clipRect(IntPoint(webClipRect.x, webClipRect.y), IntSize(webClipRect.width, webClipRect.height)); |
| 265 | gc.clip(clipRect); |
Torne (Richard Coles) | 8abfc58 | 2013-09-12 12:10:38 +0100 | [diff] [blame] | 266 | gc.setFillColor(m_node->renderer()->style()->tapHighlightColor()); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 267 | gc.fillPath(m_path); |
| 268 | } |
| 269 | |
| 270 | void LinkHighlight::startHighlightAnimationIfNeeded() |
| 271 | { |
| 272 | if (m_isAnimating) |
| 273 | return; |
| 274 | |
| 275 | m_isAnimating = true; |
| 276 | const float startOpacity = 1; |
| 277 | // FIXME: Should duration be configurable? |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 278 | const float fadeDuration = 0.1f; |
| 279 | const float minPreFadeDuration = 0.1f; |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 280 | |
| 281 | m_contentLayer->layer()->setOpacity(startOpacity); |
| 282 | |
| 283 | WebCompositorSupport* compositorSupport = Platform::current()->compositorSupport(); |
| 284 | |
| 285 | OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(compositorSupport->createFloatAnimationCurve()); |
| 286 | |
| 287 | curve->add(WebFloatKeyframe(0, startOpacity)); |
Torne (Richard Coles) | 926b001 | 2013-03-28 15:32:48 +0000 | [diff] [blame] | 288 | // Make sure we have displayed for at least minPreFadeDuration before starting to fade out. |
| 289 | float extraDurationRequired = std::max(0.f, minPreFadeDuration - static_cast<float>(monotonicallyIncreasingTime() - m_startTime)); |
| 290 | if (extraDurationRequired) |
| 291 | curve->add(WebFloatKeyframe(extraDurationRequired, startOpacity)); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 292 | // For layout tests we don't fade out. |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 293 | curve->add(WebFloatKeyframe(fadeDuration + extraDurationRequired, blink::layoutTestMode() ? startOpacity : 0)); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 294 | |
Torne (Richard Coles) | bfe3590 | 2013-10-22 16:41:51 +0100 | [diff] [blame] | 295 | OwnPtr<WebAnimation> animation = adoptPtr(compositorSupport->createAnimation(*curve, WebAnimation::TargetPropertyOpacity)); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 296 | |
| 297 | m_contentLayer->layer()->setDrawsContent(true); |
Torne (Richard Coles) | bfe3590 | 2013-10-22 16:41:51 +0100 | [diff] [blame] | 298 | m_contentLayer->layer()->addAnimation(animation.leakPtr()); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 299 | |
| 300 | invalidate(); |
| 301 | m_owningWebViewImpl->scheduleAnimation(); |
| 302 | } |
| 303 | |
| 304 | void LinkHighlight::clearGraphicsLayerLinkHighlightPointer() |
| 305 | { |
| 306 | if (m_currentGraphicsLayer) { |
Torne (Richard Coles) | 9bbd2f5 | 2013-09-19 22:37:05 +0100 | [diff] [blame] | 307 | m_currentGraphicsLayer->removeLinkHighlight(this); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 308 | m_currentGraphicsLayer = 0; |
| 309 | } |
| 310 | } |
| 311 | |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 312 | void LinkHighlight::notifyAnimationStarted(double, blink::WebAnimation::TargetProperty) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 313 | { |
| 314 | } |
| 315 | |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 316 | void LinkHighlight::notifyAnimationFinished(double, blink::WebAnimation::TargetProperty) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 317 | { |
| 318 | // Since WebViewImpl may hang on to us for a while, make sure we |
| 319 | // release resources as soon as possible. |
| 320 | clearGraphicsLayerLinkHighlightPointer(); |
| 321 | releaseResources(); |
| 322 | } |
| 323 | |
| 324 | void LinkHighlight::updateGeometry() |
| 325 | { |
| 326 | // To avoid unnecessary updates (e.g. other entities have requested animations from our WebViewImpl), |
| 327 | // only proceed if we actually requested an update. |
| 328 | if (!m_geometryNeedsUpdate) |
| 329 | return; |
| 330 | |
| 331 | m_geometryNeedsUpdate = false; |
| 332 | |
| 333 | RenderLayer* compositingLayer = computeEnclosingCompositingLayer(); |
| 334 | if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLayer)) { |
| 335 | // We only need to invalidate the layer if the highlight size has changed, otherwise |
| 336 | // we can just re-position the layer without needing to repaint. |
| 337 | m_contentLayer->layer()->invalidate(); |
| 338 | |
| 339 | if (m_currentGraphicsLayer) |
| 340 | m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position().x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); |
Torne (Richard Coles) | 93ac45c | 2013-05-29 14:40:20 +0100 | [diff] [blame] | 341 | } else if (!m_node || !m_node->renderer()) { |
Torne (Richard Coles) | 81a5157 | 2013-05-13 16:52:28 +0100 | [diff] [blame] | 342 | clearGraphicsLayerLinkHighlightPointer(); |
| 343 | releaseResources(); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 344 | } |
| 345 | } |
| 346 | |
| 347 | void LinkHighlight::clearCurrentGraphicsLayer() |
| 348 | { |
| 349 | m_currentGraphicsLayer = 0; |
| 350 | m_geometryNeedsUpdate = true; |
| 351 | } |
| 352 | |
| 353 | void LinkHighlight::invalidate() |
| 354 | { |
| 355 | // Make sure we update geometry on the next callback from WebViewImpl::layout(). |
| 356 | m_geometryNeedsUpdate = true; |
| 357 | } |
| 358 | |
| 359 | WebLayer* LinkHighlight::layer() |
| 360 | { |
| 361 | return clipLayer(); |
| 362 | } |
| 363 | |
| 364 | } // namespace WeKit |