| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of
fset), containerTransform); | 840 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of
fset), containerTransform); |
| 841 transformState->applyTransform(containerTransform, HitTestingTransformSt
ate::AccumulateTransform); | 841 transformState->applyTransform(containerTransform, HitTestingTransformSt
ate::AccumulateTransform); |
| 842 } else { | 842 } else { |
| 843 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta
te::AccumulateTransform); | 843 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta
te::AccumulateTransform); |
| 844 } | 844 } |
| 845 | 845 |
| 846 return transformState; | 846 return transformState; |
| 847 } | 847 } |
| 848 | 848 |
| 849 | 849 |
| 850 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, doubl
e* zOffset, const HitTestingTransformState* transformState) | 850 static bool isHitCandidate(bool canDepthSort, double* zOffset, const HitTestingT
ransformState* transformState) |
| 851 { | 851 { |
| 852 if (!hitLayer) | |
| 853 return false; | |
| 854 | |
| 855 // The hit layer is depth-sorting with other layers, so just say that it was
hit. | 852 // The hit layer is depth-sorting with other layers, so just say that it was
hit. |
| 856 if (canDepthSort) | 853 if (canDepthSort) |
| 857 return true; | 854 return true; |
| 858 | 855 |
| 859 // We need to look at z-depth to decide if this layer was hit. | 856 // We need to look at z-depth to decide if this layer was hit. |
| 860 if (zOffset) { | 857 if (zOffset) { |
| 861 ASSERT(transformState); | 858 ASSERT(transformState); |
| 862 // This is actually computing our z, but that's OK because the hitLayer
is coplanar with us. | 859 // This is actually computing our z, but that's OK because the hitLayer
is coplanar with us. |
| 863 double childZOffset = computeZOffset(*transformState); | 860 double childZOffset = computeZOffset(*transformState); |
| 864 if (childZOffset > *zOffset) { | 861 if (childZOffset > *zOffset) { |
| 865 *zOffset = childZOffset; | 862 *zOffset = childZOffset; |
| 866 return true; | 863 return true; |
| 867 } | 864 } |
| 868 return false; | 865 return false; |
| 869 } | 866 } |
| 870 | 867 |
| 871 return true; | 868 return true; |
| 872 } | 869 } |
| 873 | 870 |
| 874 // hitTestLocation and hitTestRect are relative to rootLayer. | 871 // hitTestLocation and hitTestRect are relative to rootLayer. |
| 875 // A 'flattening' layer is one preserves3D() == false. | 872 // A 'flattening' layer is one preserves3D() == false. |
| 876 // transformState.m_accumulatedTransform holds the transform from the containing
flattening layer. | 873 // transformState.m_accumulatedTransform holds the transform from the containing
flattening layer. |
| 877 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c
ontaining flattening layer. | 874 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c
ontaining flattening layer. |
| 878 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of
the containing flattening layer. | 875 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of
the containing flattening layer. |
| 879 // | 876 // |
| 880 // If zOffset is non-null (which indicates that the caller wants z offset inform
ation), | 877 // If zOffset is non-null (which indicates that the caller wants z offset inform
ation), |
| 881 // *zOffset on return is the z offset of the hit point relative to the containi
ng flattening layer. | 878 // *zOffset on return is the z offset of the hit point relative to the containi
ng flattening layer. |
| 882 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
ainerLayer, const HitTestRequest& request, HitTestResult& result, | 879 bool RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLay
er, const HitTestRequest& request, HitTestResult& result, |
| 883 const LayoutRect& hitTestRect, const HitT
estLocation& hitTestLocation, | 880 const LayoutRect& hitTestRect, const HitT
estLocation& hitTestLocation, |
| 884 const HitTestingTransformState* transform
State, double* zOffset) | 881 const HitTestingTransformState* transform
State, double* zOffset) |
| 885 { | 882 { |
| 886 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) | 883 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) |
| 887 return 0; | 884 return 0; |
| 888 | 885 |
| 889 // The natural thing would be to keep HitTestingTransformState on the stack,
but it's big, so we heap-allocate. | 886 // The natural thing would be to keep HitTestingTransformState on the stack,
but it's big, so we heap-allocate. |
| 890 RefPtr<HitTestingTransformState> localTransformState; | 887 RefPtr<HitTestingTransformState> localTransformState; |
| 891 | 888 |
| 892 LayoutRect localHitTestRect = hitTestRect; | 889 LayoutRect localHitTestRect = hitTestRect; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 depthSortDescendants = true; | 956 depthSortDescendants = true; |
| 960 // Our layers can depth-test with our container, so share the z depth po
inter with the container, if it passed one down. | 957 // Our layers can depth-test with our container, so share the z depth po
inter with the container, if it passed one down. |
| 961 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; | 958 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; |
| 962 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; | 959 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; |
| 963 } else if (zOffset) { | 960 } else if (zOffset) { |
| 964 zOffsetForDescendantsPtr = 0; | 961 zOffsetForDescendantsPtr = 0; |
| 965 // Container needs us to give back a z offset for the hit layer. | 962 // Container needs us to give back a z offset for the hit layer. |
| 966 zOffsetForContentsPtr = zOffset; | 963 zOffsetForContentsPtr = zOffset; |
| 967 } | 964 } |
| 968 | 965 |
| 969 // This variable tracks which layer the mouse ends up being inside. | |
| 970 RenderLayer* candidateLayer = 0; | |
| 971 | |
| 972 // Begin by walking our list of positive layers from highest z-index down to
the lowest z-index. | 966 // Begin by walking our list of positive layers from highest z-index down to
the lowest z-index. |
| 973 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, r
equest, result, localHitTestRect, localHitTestLocation, | 967 bool hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request,
result, localHitTestRect, localHitTestLocation, |
| 974 localTransformState.get(), zOffsetForDes
cendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); | 968 localTransformState.get(), zOffsetForDescend
antsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); |
| 975 if (hitLayer) { | 969 if (hitLayer && !depthSortDescendants) |
| 976 if (!depthSortDescendants) | 970 return true; |
| 977 return hitLayer; | |
| 978 candidateLayer = hitLayer; | |
| 979 } | |
| 980 | 971 |
| 981 // Now check our overflow objects. | 972 // Now check our overflow objects. |
| 982 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, l
ocalHitTestRect, localHitTestLocation, | 973 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, l
ocalHitTestRect, localHitTestLocation, |
| 983 localTransformState.get(), zOffsetForDescendantsPtr,
zOffset, unflattenedTransformState.get(), depthSortDescendants); | 974 localTransformState.get(), zOffsetForDescendantsP
tr, zOffset, unflattenedTransformState.get(), depthSortDescendants); |
| 984 if (hitLayer) { | 975 if (hitLayer && !depthSortDescendants) |
| 985 if (!depthSortDescendants) | 976 return true; |
| 986 return hitLayer; | |
| 987 candidateLayer = hitLayer; | |
| 988 } | |
| 989 | 977 |
| 990 LayoutRect layerBounds; | 978 LayoutRect layerBounds; |
| 991 // FIXME(sky): Remove foregroundRect. It's unused. | 979 // FIXME(sky): Remove foregroundRect. It's unused. |
| 992 ClipRect contentRect, foregroundRect; | 980 ClipRect contentRect, foregroundRect; |
| 993 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects); | 981 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects); |
| 994 clipper().calculateRects(clipRectsContext, localHitTestRect, layerBounds, co
ntentRect, foregroundRect); | 982 clipper().calculateRects(clipRectsContext, localHitTestRect, layerBounds, co
ntentRect, foregroundRect); |
| 995 | 983 |
| 996 // Next we want to see if the mouse pos is inside the child RenderObjects of
the layer. | 984 // Next we want to see if the mouse pos is inside the child RenderObjects of
the layer. |
| 997 if (isSelfPaintingLayer() && contentRect.intersects(localHitTestLocation)) { | 985 if (isSelfPaintingLayer() && contentRect.intersects(localHitTestLocation)) { |
| 998 // Hit test with a temporary HitTestResult, because we only want to comm
it to 'result' if we know we're frontmost. | 986 // Hit test with a temporary HitTestResult, because we only want to comm
it to 'result' if we know we're frontmost. |
| 999 HitTestResult tempResult(result.hitTestLocation()); | 987 HitTestResult tempResult(result.hitTestLocation()); |
| 1000 if (hitTestContents(request, tempResult, layerBounds, localHitTestLocati
on) | 988 if (hitTestContents(request, tempResult, layerBounds, localHitTestLocati
on) |
| 1001 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { | 989 && isHitCandidate(false, zOffsetForContentsPtr, unflattenedTransform
State.get())) { |
| 1002 if (result.isRectBasedTest()) | 990 if (result.isRectBasedTest()) |
| 1003 result.append(tempResult); | 991 result.append(tempResult); |
| 1004 else | 992 else |
| 1005 result = tempResult; | 993 result = tempResult; |
| 1006 if (!depthSortDescendants) | 994 if (!depthSortDescendants) |
| 1007 return this; | 995 return true; |
| 1008 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. | 996 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. |
| 1009 candidateLayer = this; | 997 hitLayer = true; |
| 1010 } else if (result.isRectBasedTest()) { | 998 } else if (result.isRectBasedTest()) { |
| 1011 result.append(tempResult); | 999 result.append(tempResult); |
| 1012 } | 1000 } |
| 1013 } | 1001 } |
| 1014 | 1002 |
| 1015 return candidateLayer; | 1003 return hitLayer; |
| 1016 } | 1004 } |
| 1017 | 1005 |
| 1018 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c
onst | 1006 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c
onst |
| 1019 { | 1007 { |
| 1020 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); | 1008 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); |
| 1021 | 1009 |
| 1022 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay
erBounds.location() - renderBoxLocation()))) { | 1010 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay
erBounds.location() - renderBoxLocation()))) { |
| 1023 // It's wrong to set innerNode, but then claim that you didn't hit anyth
ing, unless it is | 1011 // It's wrong to set innerNode, but then claim that you didn't hit anyth
ing, unless it is |
| 1024 // a rect-based test. | 1012 // a rect-based test. |
| 1025 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa
sedTestResult().size())); | 1013 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa
sedTestResult().size())); |
| 1026 return false; | 1014 return false; |
| 1027 } | 1015 } |
| 1028 | 1016 |
| 1029 // For positioned generated content, we might still not have a | 1017 // For positioned generated content, we might still not have a |
| 1030 // node by the time we get to the layer level, since none of | 1018 // node by the time we get to the layer level, since none of |
| 1031 // the content in the layer has an element. So just walk up | 1019 // the content in the layer has an element. So just walk up |
| 1032 // the tree. | 1020 // the tree. |
| 1033 if (!result.innerNode() || !result.innerNonSharedNode()) { | 1021 if (!result.innerNode() || !result.innerNonSharedNode()) { |
| 1034 Node* e = enclosingElement(); | 1022 Node* e = enclosingElement(); |
| 1035 if (!result.innerNode()) | 1023 if (!result.innerNode()) |
| 1036 result.setInnerNode(e); | 1024 result.setInnerNode(e); |
| 1037 if (!result.innerNonSharedNode()) | 1025 if (!result.innerNonSharedNode()) |
| 1038 result.setInnerNonSharedNode(e); | 1026 result.setInnerNonSharedNode(e); |
| 1039 } | 1027 } |
| 1040 | 1028 |
| 1041 return true; | 1029 return true; |
| 1042 } | 1030 } |
| 1043 | 1031 |
| 1044 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, Ren
derLayer* rootLayer, | 1032 bool RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer
* rootLayer, |
| 1045 const HitTestRequest& request, HitTestResult& result, | 1033 const HitTestRequest& request, HitTestResult& result, |
| 1046 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, | 1034 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, |
| 1047 const HitTestingTransformState* transformState, | 1035 const HitTestingTransformState* transformState, |
| 1048 double* zOffsetForDescendants, double* zOffset, | 1036 double* zOffsetForDescendants, double* zOffset, |
| 1049 const HitTestingTransformState* unflattenedTransformState, | 1037 const HitTestingTransformState* unflattenedTransformState, |
| 1050 bool depthSortDescendants) | 1038 bool depthSortDescendants) |
| 1051 { | 1039 { |
| 1052 if (!hasSelfPaintingLayerDescendant()) | 1040 if (!hasSelfPaintingLayerDescendant()) |
| 1053 return 0; | 1041 return 0; |
| 1054 | 1042 |
| 1055 RenderLayer* resultLayer = 0; | 1043 bool hitLayer = false; |
| 1056 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV
isit); | 1044 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV
isit); |
| 1057 while (RenderLayerStackingNode* child = iterator.next()) { | 1045 while (RenderLayerStackingNode* child = iterator.next()) { |
| 1058 RenderLayer* childLayer = child->layer(); | 1046 RenderLayer* childLayer = child->layer(); |
| 1059 RenderLayer* hitLayer = 0; | |
| 1060 HitTestResult tempResult(result.hitTestLocation()); | 1047 HitTestResult tempResult(result.hitTestLocation()); |
| 1061 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult
, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); | 1048 hitLayer |= childLayer->hitTestLayer(rootLayer, this, request, tempResul
t, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); |
| 1062 | 1049 |
| 1063 // If it a rect-based test, we can safely append the temporary result si
nce it might had hit | 1050 // If it a rect-based test, we can safely append the temporary result si
nce it might had hit |
| 1064 // nodes but not necesserily had hitLayer set. | 1051 // nodes but not necesserily had hitLayer set. |
| 1065 if (result.isRectBasedTest()) | 1052 if (result.isRectBasedTest()) |
| 1066 result.append(tempResult); | 1053 result.append(tempResult); |
| 1067 | 1054 |
| 1068 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT
ransformState)) { | 1055 if (hitLayer && isHitCandidate(depthSortDescendants, zOffset, unflattene
dTransformState)) { |
| 1069 resultLayer = hitLayer; | |
| 1070 if (!result.isRectBasedTest()) | 1056 if (!result.isRectBasedTest()) |
| 1071 result = tempResult; | 1057 result = tempResult; |
| 1072 if (!depthSortDescendants) | 1058 if (!depthSortDescendants) |
| 1073 break; | 1059 break; |
| 1074 } | 1060 } |
| 1075 } | 1061 } |
| 1076 | 1062 |
| 1077 return resultLayer; | 1063 return hitLayer; |
| 1078 } | 1064 } |
| 1079 | 1065 |
| 1080 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
utRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromR
oot) const | 1066 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
utRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromR
oot) const |
| 1081 { | 1067 { |
| 1082 // Always examine the canvas and the root. | 1068 // Always examine the canvas and the root. |
| 1083 if (isRootLayer()) | 1069 if (isRootLayer()) |
| 1084 return true; | 1070 return true; |
| 1085 | 1071 |
| 1086 // If we aren't an inline flow, and our layer bounds do intersect the damage
rect, then we | 1072 // If we aren't an inline flow, and our layer bounds do intersect the damage
rect, then we |
| 1087 // can go ahead and return true. | 1073 // can go ahead and return true. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 } | 1343 } |
| 1358 } | 1344 } |
| 1359 | 1345 |
| 1360 void showLayerTree(const blink::RenderObject* renderer) | 1346 void showLayerTree(const blink::RenderObject* renderer) |
| 1361 { | 1347 { |
| 1362 if (!renderer) | 1348 if (!renderer) |
| 1363 return; | 1349 return; |
| 1364 showLayerTree(renderer->enclosingLayer()); | 1350 showLayerTree(renderer->enclosingLayer()); |
| 1365 } | 1351 } |
| 1366 #endif | 1352 #endif |
| OLD | NEW |