| Index: Source/core/frame/PinchViewport.cpp | 
| diff --git a/Source/core/frame/PinchViewport.cpp b/Source/core/frame/PinchViewport.cpp | 
| index 1410994a5a88d55e2829e63e82a9d96dd5565d27..82c3659d34d7f49e35efb0619649b92917278cb7 100644 | 
| --- a/Source/core/frame/PinchViewport.cpp | 
| +++ b/Source/core/frame/PinchViewport.cpp | 
| @@ -64,42 +64,49 @@ namespace WebCore { | 
|  | 
| PinchViewport::PinchViewport(FrameHost& owner) | 
| : m_frameHost(owner) | 
| +    , m_scale(1) | 
| { | 
| } | 
|  | 
| PinchViewport::~PinchViewport() { } | 
|  | 
| -void PinchViewport::setSize(const IntSize& newSize) | 
| +void PinchViewport::mainFrameDidChangeSize() | 
| { | 
| -    // TODO: This is currently called from WebViewImpl with the main frame size which | 
| -    // is (or will be) incorrect, address in future patches. | 
| +    ASSERT(mainFrame() && mainFrame()->view()); | 
|  | 
| if (!m_innerViewportContainerLayer || !m_innerViewportScrollLayer) | 
| return; | 
|  | 
| +    IntSize newSize = mainFrame()->view()->frameRect().size(); | 
| + | 
| m_innerViewportContainerLayer->setSize(newSize); | 
| // The innerviewport scroll layer always has the same size as its clip layer, but | 
| // the page scale layer lives between them, allowing for non-zero max scroll | 
| // offset when page scale > 1. | 
| m_innerViewportScrollLayer->setSize(newSize); | 
|  | 
| +    m_offset = clampOffsetToBoundaries(m_offset); | 
| + | 
| // Need to re-compute sizes for the overlay scrollbars. | 
| setupScrollbar(WebScrollbar::Horizontal); | 
| setupScrollbar(WebScrollbar::Vertical); | 
| } | 
|  | 
| -void PinchViewport::setLocation(const IntPoint& newLocation) | 
| +FloatRect PinchViewport::visibleRect() const | 
| +{ | 
| +    FloatSize viewportSize(mainFrame()->view()->frameRect().size()); | 
| +    viewportSize.scale(1 / m_scale); | 
| +    return FloatRect(m_offset, viewportSize); | 
| +} | 
| + | 
| +void PinchViewport::setLocation(const FloatPoint& newLocation) | 
| { | 
| -    // TODO: The update from the LayerTree will occur here before the scale delta is applied. | 
| -    // this means that the clamping below may be incorrect. Once scaling is done in PinchViewport | 
| -    // change it so they happen at the same time. | 
| +    FloatPoint clampedOffset(clampOffsetToBoundaries(newLocation)); | 
|  | 
| -    // Clamp the location within our extents. | 
| -    IntPoint location(newLocation); | 
| -    location.shrunkTo(maximumScrollPosition()); | 
| -    location.expandedTo(minimumScrollPosition()); | 
| +    if (clampedOffset == m_offset) | 
| +        return; | 
|  | 
| -    m_visibleRect.setLocation(newLocation); | 
| +    m_offset = clampedOffset; | 
|  | 
| ScrollingCoordinator* coordinator = m_frameHost.page().scrollingCoordinator(); | 
| ASSERT(coordinator); | 
| @@ -107,6 +114,19 @@ void PinchViewport::setLocation(const IntPoint& newLocation) | 
| coordinator->scrollableAreaScrollLayerDidChange(this); | 
| } | 
|  | 
| +void PinchViewport::setScale(float scale) | 
| +{ | 
| +    m_scale = scale; | 
| + | 
| +    // Old-style pinch sets scale here but we shouldn't call into the | 
| +    // clamping code below. | 
| +    if (!m_innerViewportScrollLayer) | 
| +        return; | 
| + | 
| +    // Ensure we clamp so we remain within the bounds. | 
| +    setLocation(visibleRect().location()); | 
| +} | 
| + | 
| // Modifies the top of the graphics layer tree to add layers needed to support | 
| // the inner/outer viewport fixed-position model for pinch zoom. When finished, | 
| // the tree will look like this (with * denoting added layers): | 
| @@ -171,6 +191,8 @@ void PinchViewport::attachToLayerTree(GraphicsLayer* currentLayerTreeRoot, Graph | 
| // Setup the inner viewport overlay scrollbars. | 
| setupScrollbar(WebScrollbar::Horizontal); | 
| setupScrollbar(WebScrollbar::Vertical); | 
| + | 
| +        mainFrameDidChangeSize(); | 
| } | 
|  | 
| m_innerViewportScrollLayer->removeAllChildren(); | 
| @@ -260,10 +282,7 @@ IntPoint PinchViewport::minimumScrollPosition() const | 
|  | 
| IntPoint PinchViewport::maximumScrollPosition() const | 
| { | 
| -    // TODO: Doesn't take scale into account yet. | 
| -    IntPoint maxScrollPosition(contentsSize() - visibleRect().size()); | 
| -    maxScrollPosition.clampNegativeToZero(); | 
| -    return maxScrollPosition; | 
| +    return flooredIntPoint(FloatSize(contentsSize()) - visibleRect().size()); | 
| } | 
|  | 
| IntRect PinchViewport::scrollableAreaBoundingBox() const | 
| @@ -272,7 +291,7 @@ IntRect PinchViewport::scrollableAreaBoundingBox() const | 
| // space; however, PinchViewport technically isn't a child of any Frames. | 
| // Nonetheless, the PinchViewport always occupies the entire main frame so just | 
| // return that. | 
| -    LocalFrame* frame = m_frameHost.page().mainFrame(); | 
| +    LocalFrame* frame = mainFrame(); | 
|  | 
| if (!frame || !frame->view()) | 
| return IntRect(); | 
| @@ -282,13 +301,13 @@ IntRect PinchViewport::scrollableAreaBoundingBox() const | 
|  | 
| IntSize PinchViewport::contentsSize() const | 
| { | 
| -    LocalFrame* frame = m_frameHost.page().mainFrame(); | 
| +    LocalFrame* frame = mainFrame(); | 
|  | 
| if (!frame || !frame->view()) | 
| return IntSize(); | 
|  | 
| -    // TODO: This will be visibleContentSize once page scale is removed from FrameView | 
| -    return frame->view()->unscaledVisibleContentSize(IncludeScrollbars); | 
| +    ASSERT(frame->view()->visibleContentScaleFactor() == 1); | 
| +    return frame->view()->visibleContentRect(IncludeScrollbars).size(); | 
| } | 
|  | 
| void PinchViewport::invalidateScrollbarRect(Scrollbar*, const IntRect&) | 
| @@ -330,6 +349,19 @@ void PinchViewport::paintContents(const GraphicsLayer*, GraphicsContext&, Graphi | 
| { | 
| } | 
|  | 
| +LocalFrame* PinchViewport::mainFrame() const | 
| +{ | 
| +    return m_frameHost.page().mainFrame(); | 
| +} | 
| + | 
| +FloatPoint PinchViewport::clampOffsetToBoundaries(const FloatPoint& offset) | 
| +{ | 
| +    FloatPoint clampedOffset(offset); | 
| +    clampedOffset = clampedOffset.shrunkTo(FloatPoint(maximumScrollPosition())); | 
| +    clampedOffset = clampedOffset.expandedTo(FloatPoint(minimumScrollPosition())); | 
| +    return clampedOffset; | 
| +} | 
| + | 
| String PinchViewport::debugName(const GraphicsLayer* graphicsLayer) | 
| { | 
| String name; | 
|  |