diff options
author | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 02:38:17 +0000 |
---|---|---|
committer | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 02:38:17 +0000 |
commit | a823df873a3cbd4085ec4b6e425fd9fdbead80b1 (patch) | |
tree | bb35e1322127317c97d7b861b30f2bb33b4cf191 | |
parent | e3d92a7f03556e4f7675e7d6b266319f9ef68d3a (diff) | |
download | chromium_src-a823df873a3cbd4085ec4b6e425fd9fdbead80b1.zip chromium_src-a823df873a3cbd4085ec4b6e425fd9fdbead80b1.tar.gz chromium_src-a823df873a3cbd4085ec4b6e425fd9fdbead80b1.tar.bz2 |
Refactor pinch-zoom viewport.
Refactors the class PinchZoomViewport to (1) move it out of layer_tree_host_impl.* and (2) convert it to Chromium style.
BUG=none
Review URL: https://chromiumcodereview.appspot.com/11829006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175996 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/cc.gyp | 2 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 171 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 62 | ||||
-rw-r--r-- | cc/layer_tree_impl.cc | 6 | ||||
-rw-r--r-- | cc/pinch_zoom_viewport.cc | 110 | ||||
-rw-r--r-- | cc/pinch_zoom_viewport.h | 88 |
6 files changed, 241 insertions, 198 deletions
@@ -154,6 +154,8 @@ 'picture_pile.h', 'picture_pile_impl.cc', 'picture_pile_impl.h', + 'pinch_zoom_viewport.cc', + 'pinch_zoom_viewport.h', 'platform_color.h', 'prioritized_resource.cc', 'prioritized_resource.h', diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 44b305e..22995bb 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -57,105 +57,6 @@ void didVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) namespace cc { -PinchZoomViewport::PinchZoomViewport() - : m_pageScaleFactor(1) - , m_pageScaleDelta(1) - , m_sentPageScaleDelta(1) - , m_minPageScaleFactor(0) - , m_maxPageScaleFactor(0) - , m_deviceScaleFactor(1) -{ -} - -float PinchZoomViewport::totalPageScaleFactor() const -{ - return m_pageScaleFactor * m_pageScaleDelta; -} - -void PinchZoomViewport::setPageScaleDelta(float delta) -{ - // Clamp to the current min/max limits. - float totalPageScaleFactor = m_pageScaleFactor * delta; - if (m_minPageScaleFactor && totalPageScaleFactor < m_minPageScaleFactor) - delta = m_minPageScaleFactor / m_pageScaleFactor; - else if (m_maxPageScaleFactor && totalPageScaleFactor > m_maxPageScaleFactor) - delta = m_maxPageScaleFactor / m_pageScaleFactor; - - if (delta == m_pageScaleDelta) - return; - - m_pageScaleDelta = delta; -} - -bool PinchZoomViewport::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor) -{ - DCHECK(pageScaleFactor); - - if (m_sentPageScaleDelta == 1 && pageScaleFactor == m_pageScaleFactor && minPageScaleFactor == m_minPageScaleFactor && maxPageScaleFactor == m_maxPageScaleFactor) - return false; - - m_minPageScaleFactor = minPageScaleFactor; - m_maxPageScaleFactor = maxPageScaleFactor; - - m_pageScaleFactor = pageScaleFactor; - return true; -} - -gfx::RectF PinchZoomViewport::bounds() const -{ - gfx::RectF bounds(gfx::PointF(), m_layoutViewportSize); - bounds.Scale(1 / totalPageScaleFactor()); - bounds += m_zoomedViewportOffset; - return bounds; -} - -gfx::Vector2dF PinchZoomViewport::applyScroll(const gfx::Vector2dF& delta) -{ - gfx::Vector2dF overflow; - gfx::RectF pinchedBounds = bounds() + delta; - - if (pinchedBounds.x() < 0) { - overflow.set_x(pinchedBounds.x()); - pinchedBounds.set_x(0); - } - - if (pinchedBounds.y() < 0) { - overflow.set_y(pinchedBounds.y()); - pinchedBounds.set_y(0); - } - - if (pinchedBounds.right() > m_layoutViewportSize.width()) { - overflow.set_x(pinchedBounds.right() - m_layoutViewportSize.width()); - pinchedBounds += gfx::Vector2dF(m_layoutViewportSize.width() - pinchedBounds.right(), 0); - } - - if (pinchedBounds.bottom() > m_layoutViewportSize.height()) { - overflow.set_y(pinchedBounds.bottom() - m_layoutViewportSize.height()); - pinchedBounds += gfx::Vector2dF(0, m_layoutViewportSize.height() - pinchedBounds.bottom()); - } - m_zoomedViewportOffset = pinchedBounds.OffsetFromOrigin(); - - return overflow; -} - -gfx::Transform PinchZoomViewport::implTransform(bool pageScalePinchZoomEnabled) const -{ - gfx::Transform transform; - transform.Scale(m_pageScaleDelta, m_pageScaleDelta); - - // If the pinch state is applied in the impl, then push it to the - // impl transform, otherwise the scale is handled by WebCore. - if (pageScalePinchZoomEnabled) { - transform.Scale(m_pageScaleFactor, m_pageScaleFactor); - // The offset needs to be scaled by deviceScaleFactor as this transform - // needs to work with physical pixels. - gfx::Vector2dF zoomedDeviceViewportOffset = gfx::ScaleVector2d(m_zoomedViewportOffset, m_deviceScaleFactor); - transform.Translate(-zoomedDeviceViewportOffset.x(), -zoomedDeviceViewportOffset.y()); - } - - return transform; -} - class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { public: static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> create(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource) @@ -344,13 +245,13 @@ void LayerTreeHostImpl::startPageScaleAnimation(gfx::Vector2d targetOffset, bool gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta(); gfx::SizeF scaledContentSize = contentSize(); if (!m_settings.pageScalePinchZoomEnabled) { - scrollTotal.Scale(1 / m_pinchZoomViewport.pageScaleFactor()); - scaledContentSize.Scale(1 / m_pinchZoomViewport.pageScaleFactor()); + scrollTotal.Scale(1 / m_pinchZoomViewport.page_scale_factor()); + scaledContentSize.Scale(1 / m_pinchZoomViewport.page_scale_factor()); } gfx::SizeF viewportSize = gfx::ScaleSize(m_deviceViewportSize, 1 / m_deviceScaleFactor); double startTimeSeconds = (startTime - base::TimeTicks()).InSecondsF(); - m_pageScaleAnimation = PageScaleAnimation::create(scrollTotal, m_pinchZoomViewport.totalPageScaleFactor(), viewportSize, scaledContentSize, startTimeSeconds); + m_pageScaleAnimation = PageScaleAnimation::create(scrollTotal, m_pinchZoomViewport.total_page_scale_factor(), viewportSize, scaledContentSize, startTimeSeconds); if (anchorPoint) { gfx::Vector2dF anchor(targetOffset); @@ -865,12 +766,12 @@ CompositorFrameMetadata LayerTreeHostImpl::makeCompositorFrameMetadata() const CompositorFrameMetadata metadata; metadata.root_scroll_offset = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta(); if (!m_settings.pageScalePinchZoomEnabled) - metadata.root_scroll_offset.Scale(1 / m_pinchZoomViewport.pageScaleFactor()); - metadata.page_scale_factor = m_pinchZoomViewport.totalPageScaleFactor(); - metadata.viewport_size = m_pinchZoomViewport.bounds().size(); + metadata.root_scroll_offset.Scale(1 / m_pinchZoomViewport.page_scale_factor()); + metadata.page_scale_factor = m_pinchZoomViewport.total_page_scale_factor(); + metadata.viewport_size = m_pinchZoomViewport.Bounds().size(); metadata.root_layer_size = contentSize(); - metadata.min_page_scale_factor = m_pinchZoomViewport.minPageScaleFactor(); - metadata.max_page_scale_factor = m_pinchZoomViewport.maxPageScaleFactor(); + metadata.min_page_scale_factor = m_pinchZoomViewport.min_page_scale_factor(); + metadata.max_page_scale_factor = m_pinchZoomViewport.max_page_scale_factor(); return metadata; } @@ -1118,7 +1019,7 @@ void LayerTreeHostImpl::setViewportSize(const gfx::Size& layoutViewportSize, con m_layoutViewportSize = layoutViewportSize; m_deviceViewportSize = deviceViewportSize; - m_pinchZoomViewport.setLayoutViewportSize(layoutViewportSize); + m_pinchZoomViewport.set_layout_viewport_size(layoutViewportSize); updateMaxScrollOffset(); @@ -1149,14 +1050,14 @@ void LayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor) if (deviceScaleFactor == m_deviceScaleFactor) return; m_deviceScaleFactor = deviceScaleFactor; - m_pinchZoomViewport.setDeviceScaleFactor(m_deviceScaleFactor); + m_pinchZoomViewport.set_device_scale_factor(m_deviceScaleFactor); updateMaxScrollOffset(); } float LayerTreeHostImpl::pageScaleFactor() const { - return m_pinchZoomViewport.pageScaleFactor(); + return m_pinchZoomViewport.page_scale_factor(); } void LayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor) @@ -1164,20 +1065,20 @@ void LayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float if (!pageScaleFactor) return; - float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.pageScaleFactor(); - m_pinchZoomViewport.setPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor); + float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.page_scale_factor(); + m_pinchZoomViewport.SetPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor); if (!m_settings.pageScalePinchZoomEnabled && pageScaleChange != 1) adjustScrollsForPageScaleChange(rootScrollLayer(), pageScaleChange); // Clamp delta to limits and refresh display matrix. - setPageScaleDelta(m_pinchZoomViewport.pageScaleDelta() / m_pinchZoomViewport.sentPageScaleDelta()); - m_pinchZoomViewport.setSentPageScaleDelta(1); + setPageScaleDelta(m_pinchZoomViewport.page_scale_delta() / m_pinchZoomViewport.sent_page_scale_delta()); + m_pinchZoomViewport.set_sent_page_scale_delta(1); } void LayerTreeHostImpl::setPageScaleDelta(float delta) { - m_pinchZoomViewport.setPageScaleDelta(delta); + m_pinchZoomViewport.set_page_scale_delta(delta); updateMaxScrollOffset(); } @@ -1296,7 +1197,7 @@ static gfx::Vector2dF scrollLayerWithViewportSpaceDelta(PinchZoomViewport* viewp gfx::Vector2dF viewportAppliedPan; if (viewport) - viewportAppliedPan = unscrolled - viewport->applyScroll(unscrolled); + viewportAppliedPan = unscrolled - viewport->ApplyScroll(unscrolled); // Get the end point in the layer's content space so we can apply its screenSpaceTransform. gfx::PointF actualLocalEndPoint = localStartPoint + layerImpl.scrollDelta() + viewportAppliedPan - previousDelta; @@ -1401,10 +1302,10 @@ void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor // Keep the center-of-pinch anchor specified by (x, y) in a stable // position over the course of the magnify. - float pageScaleDelta = m_pinchZoomViewport.pageScaleDelta(); + float pageScaleDelta = m_pinchZoomViewport.page_scale_delta(); gfx::PointF previousScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta); setPageScaleDelta(pageScaleDelta * magnifyDelta); - pageScaleDelta = m_pinchZoomViewport.pageScaleDelta(); + pageScaleDelta = m_pinchZoomViewport.page_scale_delta(); gfx::PointF newScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta); gfx::Vector2dF move = previousScaleAnchor - newScaleAnchor; @@ -1412,10 +1313,10 @@ void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor if (m_settings.pageScalePinchZoomEnabled) { // Compute the application of the delta with respect to the current page zoom of the page. - move.Scale(1 / m_pinchZoomViewport.pageScaleFactor()); + move.Scale(1 / m_pinchZoomViewport.page_scale_factor()); } - gfx::Vector2dF scrollOverflow = m_settings.pageScalePinchZoomEnabled ? m_pinchZoomViewport.applyScroll(move) : move; + gfx::Vector2dF scrollOverflow = m_settings.pageScalePinchZoomEnabled ? m_pinchZoomViewport.ApplyScroll(move) : move; rootScrollLayer()->scrollBy(scrollOverflow); if (rootScrollLayer()->scrollbarAnimationController()) @@ -1440,7 +1341,7 @@ void LayerTreeHostImpl::computeDoubleTapZoomDeltas(ScrollAndScaleSet* scrollInfo { gfx::Vector2dF scaledScrollOffset = m_pageScaleAnimation->targetScrollOffset(); if (!m_settings.pageScalePinchZoomEnabled) - scaledScrollOffset.Scale(m_pinchZoomViewport.pageScaleFactor()); + scaledScrollOffset.Scale(m_pinchZoomViewport.page_scale_factor()); makeScrollAndScaleSet(scrollInfo, ToFlooredVector2d(scaledScrollOffset), m_pageScaleAnimation->targetPageScaleFactor()); } @@ -1453,27 +1354,27 @@ void LayerTreeHostImpl::computePinchZoomDeltas(ScrollAndScaleSet* scrollInfo) // significant amount. This also ensures only one fake delta set will be // sent. const float pinchZoomOutSensitivity = 0.95f; - if (m_pinchZoomViewport.pageScaleDelta() > pinchZoomOutSensitivity) + if (m_pinchZoomViewport.page_scale_delta() > pinchZoomOutSensitivity) return; // Compute where the scroll offset/page scale would be if fully pinch-zoomed // out from the anchor point. gfx::Vector2dF scrollBegin = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta(); - scrollBegin.Scale(m_pinchZoomViewport.pageScaleDelta()); - float scaleBegin = m_pinchZoomViewport.totalPageScaleFactor(); - float pageScaleDeltaToSend = m_pinchZoomViewport.minPageScaleFactor() / m_pinchZoomViewport.pageScaleFactor(); + scrollBegin.Scale(m_pinchZoomViewport.page_scale_delta()); + float scaleBegin = m_pinchZoomViewport.total_page_scale_factor(); + float pageScaleDeltaToSend = m_pinchZoomViewport.min_page_scale_factor() / m_pinchZoomViewport.page_scale_factor(); gfx::SizeF scaledContentsSize = gfx::ScaleSize(contentSize(), pageScaleDeltaToSend); gfx::Vector2d anchorOffset = m_previousPinchAnchor.OffsetFromOrigin(); gfx::Vector2dF scrollEnd = scrollBegin + anchorOffset; - scrollEnd.Scale(m_pinchZoomViewport.minPageScaleFactor() / scaleBegin); + scrollEnd.Scale(m_pinchZoomViewport.min_page_scale_factor() / scaleBegin); scrollEnd -= anchorOffset; scrollEnd.ClampToMax(gfx::RectF(scaledContentsSize).bottom_right() - gfx::Rect(m_deviceViewportSize).bottom_right()); scrollEnd.ClampToMin(gfx::Vector2d()); scrollEnd.Scale(1 / pageScaleDeltaToSend); scrollEnd.Scale(m_deviceScaleFactor); - makeScrollAndScaleSet(scrollInfo, gfx::ToRoundedVector2d(scrollEnd), m_pinchZoomViewport.minPageScaleFactor()); + makeScrollAndScaleSet(scrollInfo, gfx::ToRoundedVector2d(scrollEnd), m_pinchZoomViewport.min_page_scale_factor()); } void LayerTreeHostImpl::makeScrollAndScaleSet(ScrollAndScaleSet* scrollInfo, gfx::Vector2d scrollOffset, float pageScale) @@ -1486,8 +1387,8 @@ void LayerTreeHostImpl::makeScrollAndScaleSet(ScrollAndScaleSet* scrollInfo, gfx scroll.scrollDelta = scrollOffset - rootScrollLayer()->scrollOffset(); scrollInfo->scrolls.push_back(scroll); activeTree()->root_scroll_layer()->setSentScrollDelta(scroll.scrollDelta); - scrollInfo->pageScaleDelta = pageScale / m_pinchZoomViewport.pageScaleFactor(); - m_pinchZoomViewport.setSentPageScaleDelta(scrollInfo->pageScaleDelta); + scrollInfo->pageScaleDelta = pageScale / m_pinchZoomViewport.page_scale_factor(); + m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta); } static void collectScrollDeltas(ScrollAndScaleSet* scrollInfo, LayerImpl* layerImpl) @@ -1514,7 +1415,7 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::processScrollDeltas() if (m_pinchGestureActive || m_pageScaleAnimation) { scrollInfo->pageScaleDelta = 1; - m_pinchZoomViewport.setSentPageScaleDelta(1); + m_pinchZoomViewport.set_sent_page_scale_delta(1); // FIXME(aelias): Make pinch-zoom painting optimization compatible with // compositor-side scaling. if (!m_settings.pageScalePinchZoomEnabled && m_pinchGestureActive) @@ -1525,15 +1426,15 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::processScrollDeltas() } collectScrollDeltas(scrollInfo.get(), rootLayer()); - scrollInfo->pageScaleDelta = m_pinchZoomViewport.pageScaleDelta(); - m_pinchZoomViewport.setSentPageScaleDelta(scrollInfo->pageScaleDelta); + scrollInfo->pageScaleDelta = m_pinchZoomViewport.page_scale_delta(); + m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta); return scrollInfo.Pass(); } gfx::Transform LayerTreeHostImpl::implTransform() const { - return m_pinchZoomViewport.implTransform(m_settings.pageScalePinchZoomEnabled); + return m_pinchZoomViewport.ImplTransform(m_settings.pageScalePinchZoomEnabled); } void LayerTreeHostImpl::setFullRootLayerDamage() @@ -1553,11 +1454,11 @@ void LayerTreeHostImpl::animatePageScale(base::TimeTicks time) double monotonicTime = (time - base::TimeTicks()).InSecondsF(); gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta(); - setPageScaleDelta(m_pageScaleAnimation->pageScaleFactorAtTime(monotonicTime) / m_pinchZoomViewport.pageScaleFactor()); + setPageScaleDelta(m_pageScaleAnimation->pageScaleFactorAtTime(monotonicTime) / m_pinchZoomViewport.page_scale_factor()); gfx::Vector2dF nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime); if (!m_settings.pageScalePinchZoomEnabled) - nextScroll.Scale(m_pinchZoomViewport.pageScaleFactor()); + nextScroll.Scale(m_pinchZoomViewport.page_scale_factor()); rootScrollLayer()->scrollBy(nextScroll - scrollTotal); m_client->setNeedsRedrawOnImplThread(); setNeedsUpdateDrawProperties(); diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index d6ba579..d1019c1 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -13,6 +13,7 @@ #include "cc/cc_export.h" #include "cc/input_handler.h" #include "cc/output_surface_client.h" +#include "cc/pinch_zoom_viewport.h" #include "cc/render_pass.h" #include "cc/render_pass_sink.h" #include "cc/renderer.h" @@ -54,65 +55,6 @@ public: virtual void sendManagedMemoryStats() = 0; }; -// PinchZoomViewport models the bounds and offset of the viewport that is used during a pinch-zoom operation. -// It tracks the layout-space dimensions of the viewport before any applied scale, and then tracks the layout-space -// coordinates of the viewport respecting the pinch settings. -class CC_EXPORT PinchZoomViewport { -public: - PinchZoomViewport(); - - float totalPageScaleFactor() const; - - void setPageScaleFactor(float factor) { m_pageScaleFactor = factor; } - float pageScaleFactor() const { return m_pageScaleFactor; } - - void setPageScaleDelta(float delta); - float pageScaleDelta() const { return m_pageScaleDelta; } - - float minPageScaleFactor() const { return m_minPageScaleFactor; } - float maxPageScaleFactor() const { return m_maxPageScaleFactor; } - - void setSentPageScaleDelta(float delta) { m_sentPageScaleDelta = delta; } - float sentPageScaleDelta() const { return m_sentPageScaleDelta; } - - void setDeviceScaleFactor(float factor) { m_deviceScaleFactor = factor; } - float deviceScaleFactor() const { return m_deviceScaleFactor; } - - // Returns true if the passed parameters were different from those previously - // cached. - bool setPageScaleFactorAndLimits(float pageScaleFactor, - float minPageScaleFactor, - float maxPageScaleFactor); - - // Returns the bounds and offset of the scaled and translated viewport to use for pinch-zoom. - gfx::RectF bounds() const; - const gfx::Vector2dF& zoomedViewportOffset() const { return m_zoomedViewportOffset; } - - void setLayoutViewportSize(const gfx::SizeF& size) { m_layoutViewportSize = size; } - - // Apply the scroll offset in layout space to the offset of the pinch-zoom viewport. The viewport cannot be - // scrolled outside of the layout viewport bounds. Returns the component of the scroll that is un-applied due to - // this constraint. - gfx::Vector2dF applyScroll(const gfx::Vector2dF&); - - // The implTransform goes from the origin of the unzoomedDeviceViewport to the - // origin of the zoomedDeviceViewport. - // - // implTransform = S[pageScale] * Tr[-zoomedDeviceViewportOffset] - gfx::Transform implTransform(bool pageScalePinchZoomEnabled) const; - -private: - float m_pageScaleFactor; - float m_pageScaleDelta; - float m_sentPageScaleDelta; - float m_maxPageScaleFactor; - float m_minPageScaleFactor; - float m_deviceScaleFactor; - - gfx::Vector2dF m_zoomedViewportOffset; - gfx::SizeF m_layoutViewportSize; -}; - // LayerTreeHostImpl owns the LayerImpl tree as well as associated rendering state class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient, public RendererClient, @@ -298,7 +240,7 @@ public: template<typename RenderPassCuller> static void removeRenderPasses(RenderPassCuller, FrameData&); - float totalPageScaleFactorForTesting() const { return m_pinchZoomViewport.totalPageScaleFactor(); } + float totalPageScaleFactorForTesting() const { return m_pinchZoomViewport.total_page_scale_factor(); } const PinchZoomViewport& pinchZoomViewport() const { return m_pinchZoomViewport; } diff --git a/cc/layer_tree_impl.cc b/cc/layer_tree_impl.cc index 805db07..38fb937 100644 --- a/cc/layer_tree_impl.cc +++ b/cc/layer_tree_impl.cc @@ -93,11 +93,11 @@ void LayerTreeImpl::UpdateMaxScrollOffset() { // Pinch with pageScale scrolls entirely in layout space. ContentSize // returns the bounds including the page scale factor, so calculate the // pre page-scale layout size here. - float page_scale_factor = pinch_zoom_viewport().pageScaleFactor(); + float page_scale_factor = pinch_zoom_viewport().page_scale_factor(); content_bounds.set_width(content_bounds.width() / page_scale_factor); content_bounds.set_height(content_bounds.height() / page_scale_factor); } else { - view_bounds.Scale(1 / pinch_zoom_viewport().pageScaleDelta()); + view_bounds.Scale(1 / pinch_zoom_viewport().page_scale_delta()); } gfx::Vector2dF max_scroll = gfx::Rect(content_bounds).bottom_right() - @@ -127,7 +127,7 @@ void LayerTreeImpl::UpdateDrawProperties() { RootLayer(), device_viewport_size(), device_scale_factor(), - pinch_zoom_viewport().pageScaleFactor(), + pinch_zoom_viewport().page_scale_factor(), MaxTextureSize(), settings().canUseLCDText, render_surface_layer_list_); diff --git a/cc/pinch_zoom_viewport.cc b/cc/pinch_zoom_viewport.cc new file mode 100644 index 0000000..dab6c9c --- /dev/null +++ b/cc/pinch_zoom_viewport.cc @@ -0,0 +1,110 @@ +// 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 "cc/pinch_zoom_viewport.h" + +#include "base/logging.h" + +namespace cc { + +PinchZoomViewport::PinchZoomViewport() + : page_scale_factor_(1), + page_scale_delta_(1), + sent_page_scale_delta_(1), + min_page_scale_factor_(0), + max_page_scale_factor_(0), + device_scale_factor_(1) { +} + +void PinchZoomViewport::set_page_scale_delta(float delta) { + // Clamp to the current min/max limits. + float totalPageScaleFactor = page_scale_factor_ * delta; + if (min_page_scale_factor_ && totalPageScaleFactor < min_page_scale_factor_) + delta = min_page_scale_factor_ / page_scale_factor_; + else if (max_page_scale_factor_ && + totalPageScaleFactor > max_page_scale_factor_) + delta = max_page_scale_factor_ / page_scale_factor_; + + if (delta == page_scale_delta_) + return; + + page_scale_delta_ = delta; +} + +bool PinchZoomViewport::SetPageScaleFactorAndLimits( + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) { + DCHECK(page_scale_factor); + + if (sent_page_scale_delta_ == 1 && page_scale_factor == page_scale_factor_ && + min_page_scale_factor == min_page_scale_factor_ && + max_page_scale_factor == max_page_scale_factor_) + return false; + + min_page_scale_factor_ = min_page_scale_factor; + max_page_scale_factor_ = max_page_scale_factor; + + page_scale_factor_ = page_scale_factor; + return true; +} + +gfx::RectF PinchZoomViewport::Bounds() const { + gfx::RectF bounds(gfx::PointF(), layout_viewport_size_); + bounds.Scale(1 / total_page_scale_factor()); + bounds += zoomed_viewport_offset_; + return bounds; +} + +gfx::Vector2dF PinchZoomViewport::ApplyScroll(const gfx::Vector2dF delta) { + gfx::Vector2dF overflow; + gfx::RectF pinched_bounds = Bounds() + delta; + + if (pinched_bounds.x() < 0) { + overflow.set_x(pinched_bounds.x()); + pinched_bounds.set_x(0); + } + + if (pinched_bounds.y() < 0) { + overflow.set_y(pinched_bounds.y()); + pinched_bounds.set_y(0); + } + + if (pinched_bounds.right() > layout_viewport_size_.width()) { + overflow.set_x(pinched_bounds.right() - layout_viewport_size_.width()); + pinched_bounds += gfx::Vector2dF( + layout_viewport_size_.width() - pinched_bounds.right(), 0); + } + + if (pinched_bounds.bottom() > layout_viewport_size_.height()) { + overflow.set_y(pinched_bounds.bottom() - layout_viewport_size_.height()); + pinched_bounds += gfx::Vector2dF( + 0, layout_viewport_size_.height() - pinched_bounds.bottom()); + } + zoomed_viewport_offset_ = pinched_bounds.OffsetFromOrigin(); + + return overflow; +} + +gfx::Transform PinchZoomViewport::ImplTransform( + bool page_scale_pinch_zoom_enabled) const { + gfx::Transform transform; + transform.Scale(page_scale_delta_, page_scale_delta_); + + // If the pinch state is applied in the impl, then push it to the + // impl transform, otherwise the scale is handled by WebCore. + if (page_scale_pinch_zoom_enabled) { + transform.Scale(page_scale_factor_, page_scale_factor_); + // The offset needs to be scaled by deviceScaleFactor as this transform + // needs to work with physical pixels. + gfx::Vector2dF zoomed_device_viewport_offset + = gfx::ScaleVector2d(zoomed_viewport_offset_, device_scale_factor_); + transform.Translate(-zoomed_device_viewport_offset.x(), + -zoomed_device_viewport_offset.y()); + } + + return transform; +} + +} // namespace cc diff --git a/cc/pinch_zoom_viewport.h b/cc/pinch_zoom_viewport.h new file mode 100644 index 0000000..0b55a3f --- /dev/null +++ b/cc/pinch_zoom_viewport.h @@ -0,0 +1,88 @@ +// 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. + +#ifndef CC_PINCH_ZOOM_VIEWPORT_H_ +#define CC_PINCH_ZOOM_VIEWPORT_H_ + +#include "cc/cc_export.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/transform.h" + +namespace cc { + +// PinchZoomViewport models the bounds and offset of the viewport that is used +// during a pinch-zoom operation. It tracks the layout-space dimensions of the +// viewport before any applied scale, and then tracks the layout-space +// coordinates of the viewport respecting the pinch settings. +class CC_EXPORT PinchZoomViewport { + public: + PinchZoomViewport(); + + float total_page_scale_factor() const { + return page_scale_factor_ * page_scale_delta_; + } + + void set_page_scale_factor(float factor) { page_scale_factor_ = factor; } + float page_scale_factor() const { return page_scale_factor_; } + + void set_page_scale_delta(float delta); + float page_scale_delta() const { return page_scale_delta_; } + + float min_page_scale_factor() const { return min_page_scale_factor_; } + float max_page_scale_factor() const { return max_page_scale_factor_; } + + void set_sent_page_scale_delta(float delta) { + sent_page_scale_delta_ = delta; + } + + float sent_page_scale_delta() const { return sent_page_scale_delta_; } + + void set_device_scale_factor(float factor) { device_scale_factor_ = factor; } + float device_scale_factor() const { return device_scale_factor_; } + + // Returns true if the passed parameters were different from those previously + // cached. + bool SetPageScaleFactorAndLimits(float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor); + + // Returns the bounds and offset of the scaled and translated viewport to use + // for pinch-zoom. + gfx::RectF Bounds() const; + + const gfx::Vector2dF& zoomed_viewport_offset() const { + return zoomed_viewport_offset_; + } + + void set_layout_viewport_size(const gfx::SizeF& size) { + layout_viewport_size_ = size; + } + + // Apply the scroll offset in layout space to the offset of the pinch-zoom + // viewport. The viewport cannot be scrolled outside of the layout viewport + // bounds. Returns the component of the scroll that is un-applied due to this + // constraint. + gfx::Vector2dF ApplyScroll(const gfx::Vector2dF); + + // The implTransform goes from the origin of the unzoomedDeviceViewport to the + // origin of the zoomedDeviceViewport. + // + // implTransform = S[pageScale] * Tr[-zoomedDeviceViewportOffset] + gfx::Transform ImplTransform(bool page_scale_pinch_zoom_enabled) const; + + private: + float page_scale_factor_; + float page_scale_delta_; + float sent_page_scale_delta_; + float max_page_scale_factor_; + float min_page_scale_factor_; + float device_scale_factor_; + + gfx::Vector2dF zoomed_viewport_offset_; + gfx::SizeF layout_viewport_size_; +}; + +} // namespace cc + +#endif // CC_PINCH_ZOOM_VIEWPORT_H_ |