Index: webkit/compositor_bindings/web_layer_impl_fixed_bounds.cc |
diff --git a/webkit/compositor_bindings/web_layer_impl_fixed_bounds.cc b/webkit/compositor_bindings/web_layer_impl_fixed_bounds.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..194f3c2c504ecf657bf252b278ce265e24b68c29 |
--- /dev/null |
+++ b/webkit/compositor_bindings/web_layer_impl_fixed_bounds.cc |
@@ -0,0 +1,156 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "webkit/compositor_bindings/web_layer_impl_fixed_bounds.h" |
+ |
+#include "cc/layer.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebTransformationMatrix.h" |
+#include "third_party/skia/include/utils/SkMatrix44.h" |
+#include "webkit/compositor_bindings/web_transformation_matrix_util.h" |
+ |
+using cc::Layer; |
+using webkit::WebTransformationMatrixUtil; |
+ |
+namespace WebKit { |
+ |
+WebLayerImplFixedBounds::WebLayerImplFixedBounds() |
+{ |
+} |
+ |
+WebLayerImplFixedBounds::WebLayerImplFixedBounds(scoped_refptr<Layer> layer) |
+ : WebLayerImpl(layer) |
+{ |
+} |
+ |
+ |
+WebLayerImplFixedBounds::~WebLayerImplFixedBounds() |
+{ |
+} |
+ |
+void WebLayerImplFixedBounds::invalidateRect(const WebFloatRect& rect) |
+{ |
+ // Partial invalidations seldom occur for such layers. |
+ // Simply invalidate the whole layer to avoid transformation of coordinates. |
+ invalidate(); |
+} |
+ |
+void WebLayerImplFixedBounds::setAnchorPoint(const WebFloatPoint& anchorPoint) |
+{ |
+ if (anchorPoint != this->anchorPoint()) { |
+ m_layer->setAnchorPoint(anchorPoint); |
+ updateBoundsScaleTransform(); |
+ updateLayerBoundsAndTransform(); |
+ } |
+} |
+ |
+void WebLayerImplFixedBounds::setBounds(const WebSize& bounds) |
+{ |
+ if (m_originalBounds != gfx::Size(bounds)) { |
+ m_originalBounds = bounds; |
+ updateBoundsScaleTransform(); |
+ updateLayerBoundsAndTransform(); |
+ } |
+} |
+ |
+WebSize WebLayerImplFixedBounds::bounds() const |
+{ |
+ return m_originalBounds; |
+} |
+ |
+void WebLayerImplFixedBounds::setSublayerTransform(const SkMatrix44& matrix) |
+{ |
+ gfx::Transform transform; |
+ transform.matrix() = matrix; |
+ setSublayerTransformInternal(transform); |
+} |
+ |
+void WebLayerImplFixedBounds::setSublayerTransform(const WebTransformationMatrix& matrix) |
+{ |
+ setSublayerTransformInternal(WebTransformationMatrixUtil::ToTransform(matrix)); |
+} |
+ |
+SkMatrix44 WebLayerImplFixedBounds::sublayerTransform() const |
+{ |
+ return m_originalSublayerTransform.matrix(); |
+} |
+ |
+void WebLayerImplFixedBounds::setTransform(const SkMatrix44& matrix) |
+{ |
+ gfx::Transform transform; |
+ transform.matrix() = matrix; |
+ setTransformInternal(transform); |
+} |
+ |
+void WebLayerImplFixedBounds::setTransform(const WebTransformationMatrix& matrix) |
+{ |
+ setTransformInternal(WebTransformationMatrixUtil::ToTransform(matrix)); |
+} |
+ |
+SkMatrix44 WebLayerImplFixedBounds::transform() const |
+{ |
+ return m_originalTransform.matrix(); |
+} |
+ |
+void WebLayerImplFixedBounds::setFixedBounds(const gfx::Size& fixedBounds) |
+{ |
+ if (m_fixedBounds != fixedBounds) { |
+ m_fixedBounds = fixedBounds; |
+ updateBoundsScaleTransform(); |
+ updateLayerBoundsAndTransform(); |
+ } |
+} |
+ |
+void WebLayerImplFixedBounds::setSublayerTransformInternal(const gfx::Transform& transform) |
+{ |
+ if (m_originalSublayerTransform != transform) { |
+ m_originalSublayerTransform = transform; |
+ updateLayerBoundsAndTransform(); |
+ } |
+} |
+ |
+void WebLayerImplFixedBounds::setTransformInternal(const gfx::Transform& transform) |
+{ |
+ if (m_originalTransform != transform) { |
+ m_originalTransform = transform; |
+ updateLayerBoundsAndTransform(); |
+ } |
+} |
+ |
+void WebLayerImplFixedBounds::updateLayerBoundsAndTransform() |
+{ |
+ m_layer->setBounds(m_fixedBounds); |
+ |
+ // Apply the bounds scale on original transform. |
+ m_layer->setTransform(m_originalTransform * m_boundsScaleTransform); |
+ |
+ // Undo the bounds scale for sublayer transform. |
+ gfx::Transform inverseTransform; |
+ if (m_boundsScaleTransform.GetInverse(&inverseTransform)) |
+ m_layer->setSublayerTransform(m_originalSublayerTransform * inverseTransform); |
+ else |
+ NOTREACHED() << "Bounds scale is not invertible" << m_boundsScaleTransform.ToString(); |
+} |
+ |
+void WebLayerImplFixedBounds::updateBoundsScaleTransform() |
+{ |
+ m_boundsScaleTransform.MakeIdentity(); |
+ |
+ if (m_fixedBounds.IsEmpty() || m_originalBounds.IsEmpty() || m_fixedBounds == m_originalBounds) |
+ return; |
+ |
+ // Scale caused by bounds change always scales from the top-left of the layer |
+ // despite the anchor point, so exclude the anchor point from boundsScale. |
+ gfx::PointF anchorPoint = m_layer->anchorPoint(); |
+ float anchorOffsetX = anchorPoint.x() * m_fixedBounds.width(); |
+ float anchorOffsetY = anchorPoint.y() * m_fixedBounds.height(); |
+ m_boundsScaleTransform.Translate(-anchorOffsetX, -anchorOffsetY); |
+ m_boundsScaleTransform.Scale( |
+ static_cast<float>(m_originalBounds.width()) / m_fixedBounds.width(), |
+ static_cast<float>(m_originalBounds.height()) / m_fixedBounds.height()); |
+ m_boundsScaleTransform.Translate(anchorOffsetX, anchorOffsetY); |
+} |
+ |
+} // namespace WebKit |