Index: third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp |
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp |
index 32073042bd914cd8999f8fd2c593feade0f70a23..2a9786c55d498747fdc3c80db32de1a7d788475f 100644 |
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp |
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp |
@@ -476,4 +476,61 @@ float SVGLayoutSupport::calculateScreenFontSizeScalingFactor(const LayoutObject* |
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); |
} |
+LayoutObject* SVGLayoutSupport::findSelectedLayoutSVGText(LayoutObject* layoutObject, AffineTransform& localToParentTransform, const FloatPoint point) |
+{ |
+ LayoutObject* closestLayoutObject = nullptr; |
+ float closestDistance = std::numeric_limits<float>::max(); |
+ Vector<LayoutObject*> overlappedObjects; |
+ for (LayoutObject* child = layoutObject->slowLastChild(); child; child = child->previousSibling()) { |
+ if (child->style()->visibility() != VISIBLE) |
fs
2016/01/15 10:34:16
This is not correct at this level - 'visibility' c
|
+ continue; |
+ |
+ if (!child->isSVGContainer() && !child->isSVGText()) |
fs
2016/01/15 10:34:16
"Hidden containers" still return true for isSVGCon
|
+ continue; |
+ |
+ FloatRect bound = child->objectBoundingBox(); |
+ float distance = bound.squaredDistanceTo(child->localToParentTransform().inverse().mapPoint(point)); |
fs
2016/01/15 10:34:16
Since you're using the inverse transform you shoul
|
+ |
+ if (distance < closestDistance) { |
+ AffineTransform transform; |
+ |
+ if (closestLayoutObject) { |
+ transform = localToParentTransform * closestLayoutObject->localToParentTransform(); |
fs
2016/01/15 10:34:16
No need to transform by |localToParentTransform| s
|
+ bound = (localToParentTransform * child->localToParentTransform()).mapRect(bound); |
+ } |
+ |
+ if (closestLayoutObject && bound.intersects(transform.mapRect(closestLayoutObject->objectBoundingBox()))) { |
fs
2016/01/15 10:34:16
Not quite sure why you'd need to check overlap bet
|
+ overlappedObjects.append(child); |
+ continue; |
+ } |
+ overlappedObjects.clear(); |
+ |
+ closestLayoutObject = child; |
+ closestDistance = distance; |
+ } |
+ } |
+ |
+ if (closestLayoutObject && !closestLayoutObject->isSVGText()) { |
fs
2016/01/15 10:34:16
Use "early-out style" when possible - i.e here you
|
+ FloatPoint absolutePoint = closestLayoutObject->localToParentTransform().inverse().mapPoint(point); |
+ localToParentTransform = localToParentTransform * closestLayoutObject->localToParentTransform(); |
+ LayoutObject* result = findSelectedLayoutSVGText(closestLayoutObject, localToParentTransform, absolutePoint); |
+ |
+ if (!result) { |
+ localToParentTransform = localToParentTransform * closestLayoutObject->localToParentTransform().inverse(); |
fs
2016/01/15 10:34:16
Maintaining the transform like this looks really e
|
+ for (LayoutObject* overlappedObject : overlappedObjects) { |
+ absolutePoint = overlappedObject->localToParentTransform().inverse().mapPoint(point); |
+ localToParentTransform = localToParentTransform * overlappedObject->localToParentTransform(); |
+ result = findSelectedLayoutSVGText(overlappedObject, localToParentTransform, absolutePoint); |
+ if (result) |
+ break; |
+ localToParentTransform = localToParentTransform * overlappedObject->localToParentTransform().inverse(); |
+ } |
+ } |
+ |
+ closestLayoutObject = result; |
+ } |
+ |
+ return closestLayoutObject; |
+} |
+ |
} |