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

Side by Side Diff: Source/web/LinkHighlight.cpp

Issue 687313002: Fix LinkHighlight to position correctly w.r.t. squashed layers. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « Source/web/LinkHighlight.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 WebLayer* LinkHighlight::clipLayer() 99 WebLayer* LinkHighlight::clipLayer()
100 { 100 {
101 return m_clipLayer.get(); 101 return m_clipLayer.get();
102 } 102 }
103 103
104 void LinkHighlight::releaseResources() 104 void LinkHighlight::releaseResources()
105 { 105 {
106 m_node.clear(); 106 m_node.clear();
107 } 107 }
108 108
109 RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() 109 void LinkHighlight::attachLinkHighlightToCompositingLayer(const RenderLayerModel Object* paintInvalidationContainer)
110 { 110 {
111 if (!m_node || !m_node->renderer()) 111 GraphicsLayer* newGraphicsLayer = paintInvalidationContainer->layer()->graph icsLayerBacking();
trchen 2014/10/29 23:57:30 I think we need to do a null check here. Multicol
chrishtr 2014/10/30 00:01:17 RenderObject::containerForPaintInvalidation should
trchen 2014/10/30 00:08:58 No I meant newGraphicsLayer may be null.
chrishtr 2014/10/30 00:21:59 Oh, yuck. Thanks for pointing that out. Fixed.
112 return 0; 112 if (!newGraphicsLayer->drawsContent())
113 113 newGraphicsLayer = paintInvalidationContainer->layer()->graphicsLayerBac kingForScrolling();
114 // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries
115 // to find a suitable layer.
116 RenderObject* renderer = m_node->renderer();
117 RenderLayer* renderLayer;
118 do {
119 renderLayer = renderer->enclosingLayer()->enclosingLayerForPaintInvalida tion();
120 if (!renderLayer) {
121 renderer = renderer->frame()->ownerRenderer();
122 if (!renderer)
123 return 0;
124 }
125 } while (!renderLayer);
126
127 ASSERT(renderLayer->compositingState() != NotComposited);
128
129 GraphicsLayer* newGraphicsLayer = renderLayer->graphicsLayerBacking();
130 if (!newGraphicsLayer->drawsContent()) {
131 newGraphicsLayer = renderLayer->graphicsLayerBackingForScrolling();
132 }
133 114
134 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); 115 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor));
135 116
136 if (m_currentGraphicsLayer != newGraphicsLayer) { 117 if (m_currentGraphicsLayer != newGraphicsLayer) {
137 if (m_currentGraphicsLayer) 118 if (m_currentGraphicsLayer)
138 clearGraphicsLayerLinkHighlightPointer(); 119 clearGraphicsLayerLinkHighlightPointer();
139 120
140 m_currentGraphicsLayer = newGraphicsLayer; 121 m_currentGraphicsLayer = newGraphicsLayer;
141 m_currentGraphicsLayer->addLinkHighlight(this); 122 m_currentGraphicsLayer->addLinkHighlight(this);
142 } 123 }
143
144 return renderLayer;
145 } 124 }
146 125
147 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad) 126 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, const RenderLayerModelObject* paintInvalidat ionContainer, FloatQuad& compositedSpaceQuad)
148 { 127 {
149 ASSERT(targetRenderer); 128 ASSERT(targetRenderer);
150 ASSERT(compositedRenderer); 129 ASSERT(paintInvalidationContainer);
151
152 for (unsigned i = 0; i < 4; ++i) { 130 for (unsigned i = 0; i < 4; ++i) {
153 IntPoint point; 131 IntPoint point;
154 switch (i) { 132 switch (i) {
155 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; 133 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break;
156 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; 134 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break;
157 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; 135 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break;
158 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; 136 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break;
159 } 137 }
160 138
139 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space.
161 point = targetRenderer->frame()->view()->contentsToWindow(point); 140 point = targetRenderer->frame()->view()->contentsToWindow(point);
162 point = compositedRenderer->frame()->view()->windowToContents(point); 141 point = paintInvalidationContainer->frame()->view()->windowToContents(po int);
163 FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTr ansforms); 142 FloatPoint floatPoint = paintInvalidationContainer->absoluteToLocal(poin t, UseTransforms);
143 RenderLayer::mapPointToPaintBackingCoordinates(paintInvalidationContaine r, floatPoint);
164 144
165 switch (i) { 145 switch (i) {
166 case 0: compositedSpaceQuad.setP1(floatPoint); break; 146 case 0: compositedSpaceQuad.setP1(floatPoint); break;
167 case 1: compositedSpaceQuad.setP2(floatPoint); break; 147 case 1: compositedSpaceQuad.setP2(floatPoint); break;
168 case 2: compositedSpaceQuad.setP3(floatPoint); break; 148 case 2: compositedSpaceQuad.setP3(floatPoint); break;
169 case 3: compositedSpaceQuad.setP4(floatPoint); break; 149 case 3: compositedSpaceQuad.setP4(floatPoint); break;
170 } 150 }
171 } 151 }
172 } 152 }
173 153
(...skipping 16 matching lines...) Expand all
190 170
191 // For inline elements, absoluteQuads will return a line box based on the li ne-height 171 // For inline elements, absoluteQuads will return a line box based on the li ne-height
192 // and font metrics, which is technically incorrect as replaced elements lik e images 172 // and font metrics, which is technically incorrect as replaced elements lik e images
193 // should use their intristic height and expand the linebox as needed. To g et an 173 // should use their intristic height and expand the linebox as needed. To g et an
194 // appropriately sized highlight we descend into the children and have them add their 174 // appropriately sized highlight we descend into the children and have them add their
195 // boxes. 175 // boxes.
196 if (renderer->isRenderInline()) { 176 if (renderer->isRenderInline()) {
197 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child)) 177 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child))
198 computeQuads(*child, outQuads); 178 computeQuads(*child, outQuads);
199 } else { 179 } else {
180 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space.
200 renderer->absoluteQuads(outQuads); 181 renderer->absoluteQuads(outQuads);
201 } 182 }
202 } 183 }
203 184
204 bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin gLayer) 185 bool LinkHighlight::computeHighlightLayerPathAndPosition(const RenderLayerModelO bject* paintInvalidationContainer)
205 { 186 {
206 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) 187 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer)
207 return false; 188 return false;
208 189 ASSERT(paintInvalidationContainer);
209 ASSERT(compositingLayer);
210 190
211 // Get quads for node in absolute coordinates. 191 // Get quads for node in absolute coordinates.
212 Vector<FloatQuad> quads; 192 Vector<FloatQuad> quads;
213 computeQuads(*m_node, quads); 193 computeQuads(*m_node, quads);
214 ASSERT(quads.size()); 194 ASSERT(quads.size());
215
216 // Adjust for offset between target graphics layer and the node's renderer.
217 FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRende rer());
218
219 Path newPath; 195 Path newPath;
220 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { 196 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) {
221 FloatQuad absoluteQuad = quads[quadIndex]; 197 FloatQuad absoluteQuad = quads[quadIndex];
222 absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y());
223 198
224 // Transform node quads in target absolute coords to local coordinates i n the compositor layer. 199 // Transform node quads in target absolute coords to local coordinates i n the compositor layer.
225 FloatQuad transformedQuad; 200 FloatQuad transformedQuad;
226 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , compositingLayer->renderer(), transformedQuad); 201 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , paintInvalidationContainer, transformedQuad);
227 202
228 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that 203 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that
229 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage 204 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage
230 // links: these should ideally be merged into a single rect before creat ing the path, but that's 205 // links: these should ideally be merged into a single rect before creat ing the path, but that's
231 // another CL. 206 // another CL.
232 if (quads.size() == 1 && transformedQuad.isRectilinear() 207 if (quads.size() == 1 && transformedQuad.isRectilinear()
233 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) { 208 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) {
234 FloatSize rectRoundingRadii(3, 3); 209 FloatSize rectRoundingRadii(3, 3);
235 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii); 210 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii);
236 } else 211 } else
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 releaseResources(); 299 releaseResources();
325 } 300 }
326 301
327 void LinkHighlight::updateGeometry() 302 void LinkHighlight::updateGeometry()
328 { 303 {
329 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl), 304 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl),
330 // only proceed if we actually requested an update. 305 // only proceed if we actually requested an update.
331 if (!m_geometryNeedsUpdate) 306 if (!m_geometryNeedsUpdate)
332 return; 307 return;
333 308
309 if (!m_node || !m_node->renderer())
310 return;
311
334 m_geometryNeedsUpdate = false; 312 m_geometryNeedsUpdate = false;
335 313 const RenderLayerModelObject* paintInvalidationContainer = m_node->renderer( )->containerForPaintInvalidation();
336 RenderLayer* compositingLayer = computeEnclosingCompositingLayer(); 314 attachLinkHighlightToCompositingLayer(paintInvalidationContainer);
337 if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLaye r)) { 315 if (paintInvalidationContainer && computeHighlightLayerPathAndPosition(paint InvalidationContainer)) {
338 // We only need to invalidate the layer if the highlight size has change d, otherwise 316 // We only need to invalidate the layer if the highlight size has change d, otherwise
339 // we can just re-position the layer without needing to repaint. 317 // we can just re-position the layer without needing to repaint.
340 m_contentLayer->layer()->invalidate(); 318 m_contentLayer->layer()->invalidate();
341 319
342 if (m_currentGraphicsLayer) 320 if (m_currentGraphicsLayer)
343 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); 321 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height));
344 } else if (!m_node || !m_node->renderer()) { 322 } else if (!m_node || !m_node->renderer()) {
345 clearGraphicsLayerLinkHighlightPointer(); 323 clearGraphicsLayerLinkHighlightPointer();
346 releaseResources(); 324 releaseResources();
347 } 325 }
(...skipping 10 matching lines...) Expand all
358 // Make sure we update geometry on the next callback from WebViewImpl::layou t(). 336 // Make sure we update geometry on the next callback from WebViewImpl::layou t().
359 m_geometryNeedsUpdate = true; 337 m_geometryNeedsUpdate = true;
360 } 338 }
361 339
362 WebLayer* LinkHighlight::layer() 340 WebLayer* LinkHighlight::layer()
363 { 341 {
364 return clipLayer(); 342 return clipLayer();
365 } 343 }
366 344
367 } // namespace blink 345 } // namespace blink
OLDNEW
« no previous file with comments | « Source/web/LinkHighlight.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698