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 26 matching lines...) Expand all Loading... | |
37 #include "core/layout/svg/LayoutSVGViewportContainer.h" | 37 #include "core/layout/svg/LayoutSVGViewportContainer.h" |
38 #include "core/layout/svg/SVGResources.h" | 38 #include "core/layout/svg/SVGResources.h" |
39 #include "core/layout/svg/SVGResourcesCache.h" | 39 #include "core/layout/svg/SVGResourcesCache.h" |
40 #include "core/paint/PaintLayer.h" | 40 #include "core/paint/PaintLayer.h" |
41 #include "core/svg/SVGElement.h" | 41 #include "core/svg/SVGElement.h" |
42 #include "platform/geometry/TransformState.h" | 42 #include "platform/geometry/TransformState.h" |
43 #include "platform/graphics/StrokeData.h" | 43 #include "platform/graphics/StrokeData.h" |
44 | 44 |
45 namespace blink { | 45 namespace blink { |
46 | 46 |
47 struct SearchCandidate { | |
48 public: | |
49 SearchCandidate() {} | |
50 SearchCandidate(LayoutObject* layoutObject, float dist) | |
51 : candidateLayoutObject(layoutObject) | |
52 , distance(dist) | |
53 { | |
54 } | |
55 LayoutObject* candidateLayoutObject; | |
56 float distance; | |
57 }; | |
58 | |
47 static inline LayoutRect adjustedEnclosingIntRect(const FloatRect& rect, | 59 static inline LayoutRect adjustedEnclosingIntRect(const FloatRect& rect, |
48 const AffineTransform& rootTransform, float strokeWidthForHairlinePadding) | 60 const AffineTransform& rootTransform, float strokeWidthForHairlinePadding) |
49 { | 61 { |
50 FloatRect adjustedRect = rect; | 62 FloatRect adjustedRect = rect; |
51 | 63 |
52 if (strokeWidthForHairlinePadding) { | 64 if (strokeWidthForHairlinePadding) { |
53 // For hairline strokes (stroke-width < 1 in device space), Skia rasteri zes up to 0.4(9) off | 65 // For hairline strokes (stroke-width < 1 in device space), Skia rasteri zes up to 0.4(9) off |
54 // the stroke center. That means enclosingIntRect is not enough - we mus t also pad to 0.5. | 66 // the stroke center. That means enclosingIntRect is not enough - we mus t also pad to 0.5. |
55 // This is still fragile as it misses out on CC/DSF CTM components. | 67 // This is still fragile as it misses out on CC/DSF CTM components. |
56 const FloatSize strokeSize = rootTransform.mapSize( | 68 const FloatSize strokeSize = rootTransform.mapSize( |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 ASSERT(layoutObject); | 481 ASSERT(layoutObject); |
470 | 482 |
471 // FIXME: trying to compute a device space transform at record time is wrong . All clients | 483 // FIXME: trying to compute a device space transform at record time is wrong . All clients |
472 // should be updated to avoid relying on this information, and the method sh ould be removed. | 484 // should be updated to avoid relying on this information, and the method sh ould be removed. |
473 AffineTransform ctm = deprecatedCalculateTransformToLayer(layoutObject) * Su btreeContentTransformScope::currentContentTransformation(); | 485 AffineTransform ctm = deprecatedCalculateTransformToLayer(layoutObject) * Su btreeContentTransformScope::currentContentTransformation(); |
474 ctm.scale(layoutObject->document().frameHost()->deviceScaleFactor()); | 486 ctm.scale(layoutObject->document().frameHost()->deviceScaleFactor()); |
475 | 487 |
476 return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); | 488 return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); |
477 } | 489 } |
478 | 490 |
491 static inline bool compareCandidateDistance(const SearchCandidate& r1, const Sea rchCandidate& r2) | |
492 { | |
493 return r1.distance < r2.distance; | |
479 } | 494 } |
495 | |
496 static inline bool isPossibleToCalculateDistance(LayoutObject* layoutObject) | |
fs
2016/01/21 16:05:54
Yeah, this is not quite what I had in mind when I
| |
497 { | |
498 if (!layoutObject->isSVGHiddenContainer() && layoutObject->localToParentTran sform().isInvertible()) | |
499 return true; | |
500 return false; | |
501 } | |
502 | |
503 LayoutObject* SVGLayoutSupport::findClosestLayoutSVGText(LayoutObject* layoutObj ect, const FloatPoint& point) | |
504 { | |
505 // Try to find the closest LayoutSVGText. If not find this level, try to sea rch on candidates. | |
506 LayoutObject* closestLayoutObject = nullptr; | |
507 float closestDistance = std::numeric_limits<float>::max(); | |
508 Vector<SearchCandidate> candidates; | |
509 for (LayoutObject* child = layoutObject->slowLastChild(); child; child = chi ld->previousSibling()) { | |
510 if (!isPossibleToCalculateDistance(child)) | |
511 continue; | |
512 | |
513 FloatRect boundingBox = child->objectBoundingBox(); | |
514 FloatPoint childLocalPoint = child->localToParentTransform().inverse().m apPoint(point); | |
515 float distance = boundingBox.squaredDistanceTo(childLocalPoint); | |
516 | |
517 if (child->isSVGText()) { | |
518 if (distance >= closestDistance) | |
519 continue; | |
520 candidates.clear(); | |
521 closestLayoutObject = child; | |
522 closestDistance = distance; | |
523 continue; | |
524 } | |
525 | |
526 if (child->isSVGContainer()) { | |
527 FloatRect boundingBox = child->objectBoundingBox(); | |
528 FloatPoint childLocalPoint = child->localToParentTransform().inverse ().mapPoint(point); | |
529 float distance = boundingBox.squaredDistanceTo(childLocalPoint); | |
530 if (distance > closestDistance) | |
531 continue; | |
532 candidates.append(SearchCandidate(child, distance)); | |
533 } | |
534 } | |
535 | |
536 if (closestLayoutObject && closestLayoutObject->isSVGText()) | |
537 return closestLayoutObject; | |
538 | |
539 // Sort using the distance between the mouse point and a candidate. | |
540 // Because if the distance is close, It is high priority to search LayoutSVG Text. | |
541 std::stable_sort(candidates.begin(), candidates.end(), compareCandidateDista nce); | |
542 | |
543 // If not find LayoutSVGText on this level of tree, try to search it on sub- tree of |condidate|. | |
544 for (SearchCandidate& searchCandidate : candidates) { | |
545 LayoutObject* candidateLayoutObject = searchCandidate.candidateLayoutObj ect; | |
546 FloatPoint candidateLocalPoint = candidateLayoutObject->localToParentTra nsform().inverse().mapPoint(point); | |
547 if (LayoutObject* result = findClosestLayoutSVGText(candidateLayoutObjec t, candidateLocalPoint)) | |
548 return result; | |
549 } | |
550 | |
551 return nullptr; | |
552 } | |
553 | |
554 } | |
OLD | NEW |