void ViewportAnchor::setAnchor(const IntRect& viewRect, const FloatSize& anchorInViewCoords) { m_viewRect = viewRect; m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_anchorInViewCoords = anchorInViewCoords; if (viewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (viewRect.location() == IntPoint::zero()) return; FloatSize anchorOffset = viewRect.size(); anchorOffset.scale(anchorInViewCoords.width(), anchorInViewCoords.height()); const FloatPoint anchorPoint = FloatPoint(viewRect.location()) + anchorOffset; Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), viewRect, m_eventHandler); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPoint - m_anchorNodeBounds.location(); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
void RotationViewportAnchor::setAnchor() { RootFrameViewport* rootFrameViewport = m_rootFrameView->getRootFrameViewport(); DCHECK(rootFrameViewport); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll // fall back to that. m_visualViewportInDocument = FloatPoint(rootFrameViewport->visibleContentRect().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); IntRect innerViewRect = rootFrameViewport->visibleContentRect(); // Preserve origins at the absolute screen origin. if (innerViewRect.location() == IntPoint::zero() || innerViewRect.isEmpty()) return; IntRect outerViewRect = layoutViewport().visibleContentRect(IncludeScrollbars); // Normalize by the size of the outer rect DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = m_visualViewport->getScrollOffset(); m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); // Note, we specifically use the unscaled visual viewport size here as the // conversion into content-space below will apply the scale. FloatPoint anchorOffset(m_visualViewport->size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); // Note, we specifically convert to the rootFrameView contents here, rather // than the layout viewport. That's because hit testing works from the // FrameView's content coordinates even if it's not the layout viewport. const FloatPoint anchorPointInContents = m_rootFrameView->frameToContents( m_visualViewport->viewportToRootFrame(anchorOffset)); Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPointInContents), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPointInContents - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
void RotationViewportAnchor::setAnchor() { // FIXME: Scroll offsets are now fractional (DoublePoint and FloatPoint for the FrameView and VisualViewport // respectively. This path should be rewritten without pixel snapping. IntRect outerViewRect = m_rootFrameView->layoutViewportScrollableArea()->visibleContentRect(IncludeScrollbars); IntRect innerViewRect = enclosedIntRect(m_rootFrameView->getScrollableArea()->visibleContentRectDouble()); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll fall back to that. m_visualViewportInDocument = FloatPoint(m_rootFrameView->getScrollableArea()->visibleContentRectDouble().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); if (innerViewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (innerViewRect.location() == IntPoint::zero()) return; // Inner rectangle should be within the outer one. DCHECK(outerViewRect.contains(innerViewRect)); // Outer rectangle is used as a scale, we need positive width and height. DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = FloatSize(innerViewRect.location() - outerViewRect.location()); // Normalize by the size of the outer rect m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); FloatSize anchorOffset(innerViewRect.size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); const FloatPoint anchorPoint = FloatPoint(innerViewRect.location()) + anchorOffset; Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPoint - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
void ViewportAnchor::setAnchor(const IntRect& outerViewRect, const IntRect& innerViewRect, const FloatSize& anchorInInnerViewCoords) { // Preserve the inner viewport position in document in case we won't find the anchor m_pinchViewportInDocument = innerViewRect.location(); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_anchorInInnerViewCoords = anchorInInnerViewCoords; m_normalizedPinchViewportOffset = FloatSize(); if (innerViewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (innerViewRect.location() == IntPoint::zero()) return; // Inner rectangle should be within the outer one. ASSERT(outerViewRect.contains(innerViewRect)); // Outer rectangle is used as a scale, we need positive width and height. ASSERT(!outerViewRect.isEmpty()); m_normalizedPinchViewportOffset = innerViewRect.location() - outerViewRect.location(); // Normalize by the size of the outer rect m_normalizedPinchViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); FloatSize anchorOffset = innerViewRect.size(); anchorOffset.scale(anchorInInnerViewCoords.width(), anchorInInnerViewCoords.height()); const FloatPoint anchorPoint = FloatPoint(innerViewRect.location()) + anchorOffset; Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), innerViewRect, m_eventHandler); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPoint - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
void RotationViewportAnchor::setAnchor() { RootFrameViewport* rootFrameViewport = m_rootFrameView->getRootFrameViewport(); DCHECK(rootFrameViewport); IntRect outerViewRect = layoutViewport().visibleContentRect(IncludeScrollbars); IntRect innerViewRect = rootFrameViewport->visibleContentRect(); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll // fall back to that. m_visualViewportInDocument = FloatPoint(rootFrameViewport->visibleContentRect().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); if (innerViewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (innerViewRect.location() == IntPoint::zero()) return; // Inner rectangle should be within the outer one. DCHECK(outerViewRect.contains(innerViewRect)); // Outer rectangle is used as a scale, we need positive width and height. DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = FloatSize(innerViewRect.location() - outerViewRect.location()); // Normalize by the size of the outer rect m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); FloatPoint anchorOffset(innerViewRect.size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); const FloatPoint anchorPointInContents = m_rootFrameView->rootFrameToContents( m_visualViewport->viewportToRootFrame(anchorOffset)); Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPointInContents), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPointInContents - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }