/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/layers/APZUtils.h" #include "mozilla/StaticPrefs_apz.h" #include "mozilla/StaticPrefs_layers.h" namespace mozilla { namespace layers { namespace apz { bool IsCloseToHorizontal(float aAngle, float aThreshold) { return (aAngle < aThreshold || aAngle > (M_PI - aThreshold)); } bool IsCloseToVertical(float aAngle, float aThreshold) { return (fabs(aAngle - (M_PI / 2)) < aThreshold); } bool IsStuckAtBottom(gfxFloat aTranslation, const LayerRectAbsolute& aInnerRange, const LayerRectAbsolute& aOuterRange) { // The item will be stuck at the bottom if the async scroll delta is in // the range [aOuterRange.Y(), aInnerRange.Y()]. Since the translation // is negated with repect to the async scroll delta (i.e. scrolling down // produces a positive scroll delta and negative translation), we invert it // and check to see if it falls in the specified range. return aOuterRange.Y() <= -aTranslation && -aTranslation <= aInnerRange.Y(); } bool IsStuckAtTop(gfxFloat aTranslation, const LayerRectAbsolute& aInnerRange, const LayerRectAbsolute& aOuterRange) { // Same as IsStuckAtBottom, except we want to check for the range // [aInnerRange.YMost(), aOuterRange.YMost()]. return aInnerRange.YMost() <= -aTranslation && -aTranslation <= aOuterRange.YMost(); } ScreenPoint ComputeFixedMarginsOffset( const ScreenMargin& aCompositorFixedLayerMargins, SideBits aFixedSides, const ScreenMargin& aGeckoFixedLayerMargins) { // Work out the necessary translation, in screen space. ScreenPoint translation; ScreenMargin effectiveMargin = aCompositorFixedLayerMargins - aGeckoFixedLayerMargins; if ((aFixedSides & SideBits::eLeftRight) == SideBits::eLeftRight) { translation.x += (effectiveMargin.left - effectiveMargin.right) / 2; } else if (aFixedSides & SideBits::eRight) { translation.x -= effectiveMargin.right; } else if (aFixedSides & SideBits::eLeft) { translation.x += effectiveMargin.left; } if ((aFixedSides & SideBits::eTopBottom) == SideBits::eTopBottom) { translation.y += (effectiveMargin.top - effectiveMargin.bottom) / 2; } else if (aFixedSides & SideBits::eBottom) { translation.y -= effectiveMargin.bottom; } else if (aFixedSides & SideBits::eTop) { translation.y += effectiveMargin.top; } return translation; } bool AboutToCheckerboard(const FrameMetrics& aPaintedMetrics, const FrameMetrics& aCompositorMetrics) { // The main-thread code to compute the painted area can introduce some // rounding error due to multiple unit conversions, so we inflate the rect by // one app unit to account for that. CSSRect painted = aPaintedMetrics.GetDisplayPort() + aPaintedMetrics.GetLayoutScrollOffset(); painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1))); // Inflate the rect by the danger zone. See the description of the danger zone // prefs in AsyncPanZoomController.cpp for an explanation of this. CSSRect visible = CSSRect(aCompositorMetrics.GetVisualScrollOffset(), aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels()); visible.Inflate(ScreenSize(StaticPrefs::apz_danger_zone_x(), StaticPrefs::apz_danger_zone_y()) / aCompositorMetrics.DisplayportPixelsPerCSSPixel()); // Clamp both rects to the scrollable rect, because having either of those // exceed the scrollable rect doesn't make sense, and could lead to false // positives. painted = painted.Intersect(aPaintedMetrics.GetScrollableRect()); visible = visible.Intersect(aPaintedMetrics.GetScrollableRect()); return !painted.Contains(visible); } SideBits GetOverscrollSideBits(const ParentLayerPoint& aOverscrollAmount) { SideBits sides = SideBits::eNone; if (aOverscrollAmount.x < 0) { sides |= SideBits::eLeft; } else if (aOverscrollAmount.x > 0) { sides |= SideBits::eRight; } if (aOverscrollAmount.y < 0) { sides |= SideBits::eTop; } else if (aOverscrollAmount.y > 0) { sides |= SideBits::eBottom; } return sides; } } // namespace apz } // namespace layers } // namespace mozilla