2009-03-04 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Mar 2009 02:36:05 +0000 (02:36 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Mar 2009 02:36:05 +0000 (02:36 +0000)
        Reviewed by Eric Seidel

        https://bugs.webkit.org/show_bug.cgi?id=24328

        If an element has backface-visibility: hidden, hit testing should not
        hit the back sides of elements. Test for that by inverting the accumulated
        transform and looking at the z vector.

        Tested by transforms/3d/hit-testing/backface-hit-test.html

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::hitTestLayer):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41441 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/rendering/RenderLayer.cpp

index 2e605c3adc71bbed9e7db394cd91b219fe147d30..6cc10146db23b46a16ad80a565b0a6b6167e8d6f 100644 (file)
@@ -1,3 +1,18 @@
+2009-03-04  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Eric Seidel
+
+        https://bugs.webkit.org/show_bug.cgi?id=24328
+        
+        If an element has backface-visibility: hidden, hit testing should not
+        hit the back sides of elements. Test for that by inverting the accumulated
+        transform and looking at the z vector.
+
+        Tested by transforms/3d/hit-testing/backface-hit-test.html
+        
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hitTestLayer):
+
 2009-03-04  Adam Langley  <agl@google.com>
 
         Reviewed by Darin Fisher.
index a9e0d369330a6ff3e513945e92cc57c229bd37ec..c9552f2814da6be7740602fa8290537581dd61d7 100644 (file)
@@ -2209,6 +2209,14 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
         if (!newTransformState->m_accumulatedTransform.isInvertible())
             return 0;
 
+        // Check for hit test on backface if backface-visibility is 'hidden'
+        if (renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
+            TransformationMatrix invertedMatrix = newTransformState->m_accumulatedTransform.inverse();
+            // If the z-vector of the matrix is negative, the back is facing towards the viewer.
+            if (invertedMatrix.m33() < 0)
+                return 0;
+        }
+
         // Compute the point and the hit test rect in the coords of this layer by using the values
         // from the transformState, which store the point and quad in the coords of the last flattened
         // layer, and the accumulated transform which lets up map through preserve-3d layers.
@@ -2218,8 +2226,6 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
         IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
         IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
 
-        // FIXME: check for hit test on backface if backface-visibility is 'hidden'
-        
         // Now do a hit test with the root layer shifted to be us.
         return hitTestLayer(this, containerLayer, request, result, localHitTestRect, localPoint, true, newTransformState.get(), zOffset);
     }