OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org> | 2 * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org> |
3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> | 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> |
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) 2009 Google, Inc. All rights reserved. | 5 * Copyright (C) 2009 Google, Inc. All rights reserved. |
6 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 6 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
7 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 7 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 : candidateLayoutObject(nullptr), | 51 : candidateLayoutObject(nullptr), |
52 candidateDistance(std::numeric_limits<float>::max()) {} | 52 candidateDistance(std::numeric_limits<float>::max()) {} |
53 SearchCandidate(LayoutObject* layoutObject, float distance) | 53 SearchCandidate(LayoutObject* layoutObject, float distance) |
54 : candidateLayoutObject(layoutObject), candidateDistance(distance) {} | 54 : candidateLayoutObject(layoutObject), candidateDistance(distance) {} |
55 LayoutObject* candidateLayoutObject; | 55 LayoutObject* candidateLayoutObject; |
56 float candidateDistance; | 56 float candidateDistance; |
57 }; | 57 }; |
58 | 58 |
59 FloatRect SVGLayoutSupport::localOverflowRectForPaintInvalidation( | 59 FloatRect SVGLayoutSupport::localOverflowRectForPaintInvalidation( |
60 const LayoutObject& object) { | 60 const LayoutObject& object) { |
61 // This doesn't apply to LayoutSVGRoot. Use LayoutSVGRoot::localOverflowRectFo
rPaintInvalidation() instead. | 61 // This doesn't apply to LayoutSVGRoot. Use |
| 62 // LayoutSVGRoot::localOverflowRectForPaintInvalidation() instead. |
62 ASSERT(!object.isSVGRoot()); | 63 ASSERT(!object.isSVGRoot()); |
63 | 64 |
64 // Return early for any cases where we don't actually paint | 65 // Return early for any cases where we don't actually paint |
65 if (object.styleRef().visibility() != EVisibility::Visible && | 66 if (object.styleRef().visibility() != EVisibility::Visible && |
66 !object.enclosingLayer()->hasVisibleContent()) | 67 !object.enclosingLayer()->hasVisibleContent()) |
67 return FloatRect(); | 68 return FloatRect(); |
68 | 69 |
69 FloatRect paintInvalidationRect = | 70 FloatRect paintInvalidationRect = |
70 object.paintInvalidationRectInLocalSVGCoordinates(); | 71 object.paintInvalidationRectInLocalSVGCoordinates(); |
71 if (int outlineOutset = object.styleRef().outlineOutsetExtent()) | 72 if (int outlineOutset = object.styleRef().outlineOutsetExtent()) |
(...skipping 13 matching lines...) Expand all Loading... |
85 | 86 |
86 LayoutRect SVGLayoutSupport::transformPaintInvalidationRect( | 87 LayoutRect SVGLayoutSupport::transformPaintInvalidationRect( |
87 const LayoutObject& object, | 88 const LayoutObject& object, |
88 const AffineTransform& rootTransform, | 89 const AffineTransform& rootTransform, |
89 const FloatRect& localRect) { | 90 const FloatRect& localRect) { |
90 FloatRect adjustedRect = rootTransform.mapRect(localRect); | 91 FloatRect adjustedRect = rootTransform.mapRect(localRect); |
91 | 92 |
92 if (object.isSVGShape() && object.styleRef().svgStyle().hasStroke()) { | 93 if (object.isSVGShape() && object.styleRef().svgStyle().hasStroke()) { |
93 if (float strokeWidthForHairlinePadding = | 94 if (float strokeWidthForHairlinePadding = |
94 toLayoutSVGShape(object).strokeWidth()) { | 95 toLayoutSVGShape(object).strokeWidth()) { |
95 // For hairline strokes (stroke-width < 1 in device space), Skia rasterize
s up to 0.4(9) off | 96 // For hairline strokes (stroke-width < 1 in device space), Skia |
96 // the stroke center. That means enclosingIntRect is not enough - we must
also pad to 0.5. | 97 // rasterizes up to 0.4(9) off the stroke center. That means |
| 98 // enclosingIntRect is not enough - we must also pad to 0.5. |
97 // This is still fragile as it misses out on CC/DSF CTM components. | 99 // This is still fragile as it misses out on CC/DSF CTM components. |
98 const FloatSize strokeSize = rootTransform.mapSize(FloatSize( | 100 const FloatSize strokeSize = rootTransform.mapSize(FloatSize( |
99 strokeWidthForHairlinePadding, strokeWidthForHairlinePadding)); | 101 strokeWidthForHairlinePadding, strokeWidthForHairlinePadding)); |
100 if (strokeSize.width() < 1 || strokeSize.height() < 1) { | 102 if (strokeSize.width() < 1 || strokeSize.height() < 1) { |
101 float pad = | 103 float pad = |
102 0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2; | 104 0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2; |
103 DCHECK_GT(pad, 0); | 105 DCHECK_GT(pad, 0); |
104 // Additionally, square/round caps can potentially introduce an outset <
= 0.5 | 106 // Additionally, square/round caps can potentially introduce an outset |
| 107 // <= 0.5 |
105 if (object.styleRef().svgStyle().capStyle() != ButtCap) | 108 if (object.styleRef().svgStyle().capStyle() != ButtCap) |
106 pad += 0.5f; | 109 pad += 0.5f; |
107 adjustedRect.inflate(pad); | 110 adjustedRect.inflate(pad); |
108 } | 111 } |
109 } | 112 } |
110 } | 113 } |
111 | 114 |
112 if (adjustedRect.isEmpty()) | 115 if (adjustedRect.isEmpty()) |
113 return LayoutRect(); | 116 return LayoutRect(); |
114 | 117 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 159 } |
157 | 160 |
158 void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, | 161 void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, |
159 const LayoutBoxModelObject* ancestor, | 162 const LayoutBoxModelObject* ancestor, |
160 TransformState& transformState, | 163 TransformState& transformState, |
161 MapCoordinatesFlags flags) { | 164 MapCoordinatesFlags flags) { |
162 transformState.applyTransform(object->localToSVGParentTransform()); | 165 transformState.applyTransform(object->localToSVGParentTransform()); |
163 | 166 |
164 LayoutObject* parent = object->parent(); | 167 LayoutObject* parent = object->parent(); |
165 | 168 |
166 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the localToBorderBox
Transform | 169 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the |
167 // to map an element from SVG viewport coordinates to CSS box coordinates. | 170 // localToBorderBoxTransform to map an element from SVG viewport coordinates |
| 171 // to CSS box coordinates. |
168 // LayoutSVGRoot's mapLocalToAncestor method expects CSS box coordinates. | 172 // LayoutSVGRoot's mapLocalToAncestor method expects CSS box coordinates. |
169 if (parent->isSVGRoot()) | 173 if (parent->isSVGRoot()) |
170 transformState.applyTransform( | 174 transformState.applyTransform( |
171 toLayoutSVGRoot(parent)->localToBorderBoxTransform()); | 175 toLayoutSVGRoot(parent)->localToBorderBoxTransform()); |
172 | 176 |
173 parent->mapLocalToAncestor(ancestor, transformState, flags); | 177 parent->mapLocalToAncestor(ancestor, transformState, flags); |
174 } | 178 } |
175 | 179 |
176 void SVGLayoutSupport::mapAncestorToLocal(const LayoutObject& object, | 180 void SVGLayoutSupport::mapAncestorToLocal(const LayoutObject& object, |
177 const LayoutBoxModelObject* ancestor, | 181 const LayoutBoxModelObject* ancestor, |
(...skipping 17 matching lines...) Expand all Loading... |
195 } | 199 } |
196 | 200 |
197 const LayoutObject* SVGLayoutSupport::pushMappingToContainer( | 201 const LayoutObject* SVGLayoutSupport::pushMappingToContainer( |
198 const LayoutObject* object, | 202 const LayoutObject* object, |
199 const LayoutBoxModelObject* ancestorToStopAt, | 203 const LayoutBoxModelObject* ancestorToStopAt, |
200 LayoutGeometryMap& geometryMap) { | 204 LayoutGeometryMap& geometryMap) { |
201 DCHECK_NE(ancestorToStopAt, object); | 205 DCHECK_NE(ancestorToStopAt, object); |
202 | 206 |
203 LayoutObject* parent = object->parent(); | 207 LayoutObject* parent = object->parent(); |
204 | 208 |
205 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the localToBorderBox
Transform | 209 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the |
206 // to map an element from SVG viewport coordinates to CSS box coordinates. | 210 // localToBorderBoxTransform to map an element from SVG viewport coordinates |
| 211 // to CSS box coordinates. |
207 // LayoutSVGRoot's mapLocalToAncestor method expects CSS box coordinates. | 212 // LayoutSVGRoot's mapLocalToAncestor method expects CSS box coordinates. |
208 if (parent->isSVGRoot()) { | 213 if (parent->isSVGRoot()) { |
209 TransformationMatrix matrix(object->localToSVGParentTransform()); | 214 TransformationMatrix matrix(object->localToSVGParentTransform()); |
210 matrix.multiply(toLayoutSVGRoot(parent)->localToBorderBoxTransform()); | 215 matrix.multiply(toLayoutSVGRoot(parent)->localToBorderBoxTransform()); |
211 geometryMap.push(object, matrix); | 216 geometryMap.push(object, matrix); |
212 } else { | 217 } else { |
213 geometryMap.push(object, object->localToSVGParentTransform()); | 218 geometryMap.push(object, object->localToSVGParentTransform()); |
214 } | 219 } |
215 | 220 |
216 return parent; | 221 return parent; |
217 } | 222 } |
218 | 223 |
219 // Update a bounding box taking into account the validity of the other bounding
box. | 224 // Update a bounding box taking into account the validity of the other bounding |
| 225 // box. |
220 inline void SVGLayoutSupport::updateObjectBoundingBox( | 226 inline void SVGLayoutSupport::updateObjectBoundingBox( |
221 FloatRect& objectBoundingBox, | 227 FloatRect& objectBoundingBox, |
222 bool& objectBoundingBoxValid, | 228 bool& objectBoundingBoxValid, |
223 LayoutObject* other, | 229 LayoutObject* other, |
224 FloatRect otherBoundingBox) { | 230 FloatRect otherBoundingBox) { |
225 bool otherValid = | 231 bool otherValid = |
226 other->isSVGContainer() | 232 other->isSVGContainer() |
227 ? toLayoutSVGContainer(other)->isObjectBoundingBoxValid() | 233 ? toLayoutSVGContainer(other)->isObjectBoundingBoxValid() |
228 : true; | 234 : true; |
229 if (!otherValid) | 235 if (!otherValid) |
(...skipping 11 matching lines...) Expand all Loading... |
241 void SVGLayoutSupport::computeContainerBoundingBoxes( | 247 void SVGLayoutSupport::computeContainerBoundingBoxes( |
242 const LayoutObject* container, | 248 const LayoutObject* container, |
243 FloatRect& objectBoundingBox, | 249 FloatRect& objectBoundingBox, |
244 bool& objectBoundingBoxValid, | 250 bool& objectBoundingBoxValid, |
245 FloatRect& strokeBoundingBox, | 251 FloatRect& strokeBoundingBox, |
246 FloatRect& paintInvalidationBoundingBox) { | 252 FloatRect& paintInvalidationBoundingBox) { |
247 objectBoundingBox = FloatRect(); | 253 objectBoundingBox = FloatRect(); |
248 objectBoundingBoxValid = false; | 254 objectBoundingBoxValid = false; |
249 strokeBoundingBox = FloatRect(); | 255 strokeBoundingBox = FloatRect(); |
250 | 256 |
251 // When computing the strokeBoundingBox, we use the paintInvalidationRects of
the container's children so that the container's stroke includes | 257 // When computing the strokeBoundingBox, we use the paintInvalidationRects of |
252 // the resources applied to the children (such as clips and filters). This all
ows filters applied to containers to correctly bound | 258 // the container's children so that the container's stroke includes the |
253 // the children, and also improves inlining of SVG content, as the stroke boun
d is used in that situation also. | 259 // resources applied to the children (such as clips and filters). This allows |
| 260 // filters applied to containers to correctly bound the children, and also |
| 261 // improves inlining of SVG content, as the stroke bound is used in that |
| 262 // situation also. |
254 for (LayoutObject* current = container->slowFirstChild(); current; | 263 for (LayoutObject* current = container->slowFirstChild(); current; |
255 current = current->nextSibling()) { | 264 current = current->nextSibling()) { |
256 if (current->isSVGHiddenContainer()) | 265 if (current->isSVGHiddenContainer()) |
257 continue; | 266 continue; |
258 | 267 |
259 // Don't include elements in the union that do not layout. | 268 // Don't include elements in the union that do not layout. |
260 if (current->isSVGShape() && toLayoutSVGShape(current)->isShapeEmpty()) | 269 if (current->isSVGShape() && toLayoutSVGShape(current)->isShapeEmpty()) |
261 continue; | 270 continue; |
262 | 271 |
263 if (current->isSVGText() && | 272 if (current->isSVGText() && |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 329 |
321 if (screenScalingFactorChanged) { | 330 if (screenScalingFactorChanged) { |
322 // If the screen scaling factor changed we need to update the text | 331 // If the screen scaling factor changed we need to update the text |
323 // metrics (note: this also happens for layoutSizeChanged=true). | 332 // metrics (note: this also happens for layoutSizeChanged=true). |
324 if (child->isSVGText()) | 333 if (child->isSVGText()) |
325 toLayoutSVGText(child)->setNeedsTextMetricsUpdate(); | 334 toLayoutSVGText(child)->setNeedsTextMetricsUpdate(); |
326 forceChildLayout = true; | 335 forceChildLayout = true; |
327 } | 336 } |
328 | 337 |
329 if (layoutSizeChanged) { | 338 if (layoutSizeChanged) { |
330 // When selfNeedsLayout is false and the layout size changed, we have to c
heck whether this child uses relative lengths | 339 // When selfNeedsLayout is false and the layout size changed, we have to |
| 340 // check whether this child uses relative lengths |
331 if (SVGElement* element = | 341 if (SVGElement* element = |
332 child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) { | 342 child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) { |
333 if (element->hasRelativeLengths()) { | 343 if (element->hasRelativeLengths()) { |
334 // FIXME: this should be done on invalidation, not during layout. | 344 // FIXME: this should be done on invalidation, not during layout. |
335 // When the layout size changed and when using relative values tell th
e LayoutSVGShape to update its shape object | 345 // When the layout size changed and when using relative values tell |
| 346 // the LayoutSVGShape to update its shape object |
336 if (child->isSVGShape()) { | 347 if (child->isSVGShape()) { |
337 toLayoutSVGShape(child)->setNeedsShapeUpdate(); | 348 toLayoutSVGShape(child)->setNeedsShapeUpdate(); |
338 } else if (child->isSVGText()) { | 349 } else if (child->isSVGText()) { |
339 toLayoutSVGText(child)->setNeedsTextMetricsUpdate(); | 350 toLayoutSVGText(child)->setNeedsTextMetricsUpdate(); |
340 toLayoutSVGText(child)->setNeedsPositioningValuesUpdate(); | 351 toLayoutSVGText(child)->setNeedsPositioningValuesUpdate(); |
341 } | 352 } |
342 | 353 |
343 forceChildLayout = true; | 354 forceChildLayout = true; |
344 } | 355 } |
345 } | 356 } |
346 } | 357 } |
347 | 358 |
348 // Resource containers are nasty: they can invalidate clients outside the cu
rrent SubtreeLayoutScope. | 359 // Resource containers are nasty: they can invalidate clients outside the |
349 // Since they only care about viewport size changes (to resolve their relati
ve lengths), we trigger | 360 // current SubtreeLayoutScope. |
350 // their invalidation directly from SVGSVGElement::svgAttributeChange() or a
t a higher | 361 // Since they only care about viewport size changes (to resolve their |
351 // SubtreeLayoutScope (in LayoutView::layout()). We do not create a SubtreeL
ayoutScope for | 362 // relative lengths), we trigger their invalidation directly from |
352 // resources because their ability to reference each other leads to circular
layout. We protect | 363 // SVGSVGElement::svgAttributeChange() or at a higher SubtreeLayoutScope (in |
353 // against that within the layout code for resources, but it causes assertio
ns if we use a | 364 // LayoutView::layout()). We do not create a SubtreeLayoutScope for |
354 // SubTreeLayoutScope for them. | 365 // resources because their ability to reference each other leads to circular |
| 366 // layout. We protect against that within the layout code for resources, but |
| 367 // it causes assertions if we use a SubTreeLayoutScope for them. |
355 if (child->isSVGResourceContainer()) { | 368 if (child->isSVGResourceContainer()) { |
356 // Lay out any referenced resources before the child. | 369 // Lay out any referenced resources before the child. |
357 layoutResourcesIfNeeded(child); | 370 layoutResourcesIfNeeded(child); |
358 child->layoutIfNeeded(); | 371 child->layoutIfNeeded(); |
359 } else { | 372 } else { |
360 SubtreeLayoutScope layoutScope(*child); | 373 SubtreeLayoutScope layoutScope(*child); |
361 if (forceChildLayout) | 374 if (forceChildLayout) |
362 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::SvgChanged); | 375 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::SvgChanged); |
363 | 376 |
364 // Lay out any referenced resources before the child. | 377 // Lay out any referenced resources before the child. |
365 layoutResourcesIfNeeded(child); | 378 layoutResourcesIfNeeded(child); |
366 child->layoutIfNeeded(); | 379 child->layoutIfNeeded(); |
367 } | 380 } |
368 } | 381 } |
369 } | 382 } |
370 | 383 |
371 void SVGLayoutSupport::layoutResourcesIfNeeded(const LayoutObject* object) { | 384 void SVGLayoutSupport::layoutResourcesIfNeeded(const LayoutObject* object) { |
372 ASSERT(object); | 385 ASSERT(object); |
373 | 386 |
374 SVGResources* resources = | 387 SVGResources* resources = |
375 SVGResourcesCache::cachedResourcesForLayoutObject(object); | 388 SVGResourcesCache::cachedResourcesForLayoutObject(object); |
376 if (resources) | 389 if (resources) |
377 resources->layoutIfNeeded(); | 390 resources->layoutIfNeeded(); |
378 } | 391 } |
379 | 392 |
380 bool SVGLayoutSupport::isOverflowHidden(const LayoutObject* object) { | 393 bool SVGLayoutSupport::isOverflowHidden(const LayoutObject* object) { |
381 // LayoutSVGRoot should never query for overflow state - it should always clip
itself to the initial viewport size. | 394 // LayoutSVGRoot should never query for overflow state - it should always clip |
| 395 // itself to the initial viewport size. |
382 ASSERT(!object->isDocumentElement()); | 396 ASSERT(!object->isDocumentElement()); |
383 | 397 |
384 return object->style()->overflowX() == OverflowHidden || | 398 return object->style()->overflowX() == OverflowHidden || |
385 object->style()->overflowX() == OverflowScroll; | 399 object->style()->overflowX() == OverflowScroll; |
386 } | 400 } |
387 | 401 |
388 void SVGLayoutSupport::intersectPaintInvalidationRectWithResources( | 402 void SVGLayoutSupport::intersectPaintInvalidationRectWithResources( |
389 const LayoutObject* layoutObject, | 403 const LayoutObject* layoutObject, |
390 FloatRect& paintInvalidationRect) { | 404 FloatRect& paintInvalidationRect) { |
391 ASSERT(layoutObject); | 405 ASSERT(layoutObject); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 AffineTransform transform; | 546 AffineTransform transform; |
533 while (layoutObject) { | 547 while (layoutObject) { |
534 transform = layoutObject->localToSVGParentTransform() * transform; | 548 transform = layoutObject->localToSVGParentTransform() * transform; |
535 if (layoutObject->isSVGRoot()) | 549 if (layoutObject->isSVGRoot()) |
536 break; | 550 break; |
537 layoutObject = layoutObject->parent(); | 551 layoutObject = layoutObject->parent(); |
538 } | 552 } |
539 | 553 |
540 // Continue walking up the layer tree, accumulating CSS transforms. | 554 // Continue walking up the layer tree, accumulating CSS transforms. |
541 // FIXME: this queries layer compositing state - which is not | 555 // FIXME: this queries layer compositing state - which is not |
542 // supported during layout. Hence, the result may not include all CSS transfor
ms. | 556 // supported during layout. Hence, the result may not include all CSS |
| 557 // transforms. |
543 PaintLayer* layer = layoutObject ? layoutObject->enclosingLayer() : 0; | 558 PaintLayer* layer = layoutObject ? layoutObject->enclosingLayer() : 0; |
544 while (layer && layer->isAllowedToQueryCompositingState()) { | 559 while (layer && layer->isAllowedToQueryCompositingState()) { |
545 // We can stop at compositing layers, to match the backing resolution. | 560 // We can stop at compositing layers, to match the backing resolution. |
546 // FIXME: should we be computing the transform to the nearest composited lay
er, | 561 // FIXME: should we be computing the transform to the nearest composited |
547 // or the nearest composited layer that does not paint into its ancestor? | 562 // layer, or the nearest composited layer that does not paint into its |
548 // I think this is the nearest composited ancestor since we will inherit its | 563 // ancestor? I think this is the nearest composited ancestor since we will |
549 // transforms in the composited layer tree. | 564 // inherit its transforms in the composited layer tree. |
550 if (layer->compositingState() != NotComposited) | 565 if (layer->compositingState() != NotComposited) |
551 break; | 566 break; |
552 | 567 |
553 if (TransformationMatrix* layerTransform = layer->transform()) | 568 if (TransformationMatrix* layerTransform = layer->transform()) |
554 transform = layerTransform->toAffineTransform() * transform; | 569 transform = layerTransform->toAffineTransform() * transform; |
555 | 570 |
556 layer = layer->parent(); | 571 layer = layer->parent(); |
557 } | 572 } |
558 | 573 |
559 return transform; | 574 return transform; |
560 } | 575 } |
561 | 576 |
562 float SVGLayoutSupport::calculateScreenFontSizeScalingFactor( | 577 float SVGLayoutSupport::calculateScreenFontSizeScalingFactor( |
563 const LayoutObject* layoutObject) { | 578 const LayoutObject* layoutObject) { |
564 ASSERT(layoutObject); | 579 ASSERT(layoutObject); |
565 | 580 |
566 // FIXME: trying to compute a device space transform at record time is wrong.
All clients | 581 // FIXME: trying to compute a device space transform at record time is wrong. |
567 // should be updated to avoid relying on this information, and the method shou
ld be removed. | 582 // All clients should be updated to avoid relying on this information, and the |
| 583 // method should be removed. |
568 AffineTransform ctm = | 584 AffineTransform ctm = |
569 deprecatedCalculateTransformToLayer(layoutObject) * | 585 deprecatedCalculateTransformToLayer(layoutObject) * |
570 SubtreeContentTransformScope::currentContentTransformation(); | 586 SubtreeContentTransformScope::currentContentTransformation(); |
571 ctm.scale( | 587 ctm.scale( |
572 layoutObject->document().frameHost()->deviceScaleFactorDeprecated()); | 588 layoutObject->document().frameHost()->deviceScaleFactorDeprecated()); |
573 | 589 |
574 return clampTo<float>(sqrt((ctm.xScaleSquared() + ctm.yScaleSquared()) / 2)); | 590 return clampTo<float>(sqrt((ctm.xScaleSquared() + ctm.yScaleSquared()) / 2)); |
575 } | 591 } |
576 | 592 |
577 static inline bool compareCandidateDistance(const SearchCandidate& r1, | 593 static inline bool compareCandidateDistance(const SearchCandidate& r1, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 636 |
621 // If a LayoutSVGText was found and there are no potentially closer sub-trees, | 637 // If a LayoutSVGText was found and there are no potentially closer sub-trees, |
622 // just return |closestText|. | 638 // just return |closestText|. |
623 if (closestText.candidateLayoutObject && candidates.isEmpty()) | 639 if (closestText.candidateLayoutObject && candidates.isEmpty()) |
624 return closestText; | 640 return closestText; |
625 | 641 |
626 std::stable_sort(candidates.begin(), candidates.end(), | 642 std::stable_sort(candidates.begin(), candidates.end(), |
627 compareCandidateDistance); | 643 compareCandidateDistance); |
628 | 644 |
629 // Find the closest LayoutSVGText in the sub-trees in |candidates|. | 645 // Find the closest LayoutSVGText in the sub-trees in |candidates|. |
630 // If a LayoutSVGText is found that is strictly closer than any previous candi
date, then end the search. | 646 // If a LayoutSVGText is found that is strictly closer than any previous |
| 647 // candidate, then end the search. |
631 for (const SearchCandidate& searchCandidate : candidates) { | 648 for (const SearchCandidate& searchCandidate : candidates) { |
632 if (closestText.candidateDistance < searchCandidate.candidateDistance) | 649 if (closestText.candidateDistance < searchCandidate.candidateDistance) |
633 break; | 650 break; |
634 LayoutObject* candidateLayoutObject = searchCandidate.candidateLayoutObject; | 651 LayoutObject* candidateLayoutObject = searchCandidate.candidateLayoutObject; |
635 FloatPoint candidateLocalPoint = | 652 FloatPoint candidateLocalPoint = |
636 candidateLayoutObject->localToSVGParentTransform().inverse().mapPoint( | 653 candidateLayoutObject->localToSVGParentTransform().inverse().mapPoint( |
637 point); | 654 point); |
638 | 655 |
639 SearchCandidate candidateText = searchTreeForFindClosestLayoutSVGText( | 656 SearchCandidate candidateText = searchTreeForFindClosestLayoutSVGText( |
640 candidateLayoutObject, candidateLocalPoint); | 657 candidateLayoutObject, candidateLocalPoint); |
641 | 658 |
642 if (candidateText.candidateDistance < closestText.candidateDistance) | 659 if (candidateText.candidateDistance < closestText.candidateDistance) |
643 closestText = candidateText; | 660 closestText = candidateText; |
644 } | 661 } |
645 | 662 |
646 return closestText; | 663 return closestText; |
647 } | 664 } |
648 | 665 |
649 LayoutObject* SVGLayoutSupport::findClosestLayoutSVGText( | 666 LayoutObject* SVGLayoutSupport::findClosestLayoutSVGText( |
650 LayoutObject* layoutObject, | 667 LayoutObject* layoutObject, |
651 const FloatPoint& point) { | 668 const FloatPoint& point) { |
652 return searchTreeForFindClosestLayoutSVGText(layoutObject, point) | 669 return searchTreeForFindClosestLayoutSVGText(layoutObject, point) |
653 .candidateLayoutObject; | 670 .candidateLayoutObject; |
654 } | 671 } |
655 | 672 |
656 } // namespace blink | 673 } // namespace blink |
OLD | NEW |