CSSCoord Axis::ClampOriginToScrollableRect(CSSCoord aOrigin) const { CSSToParentLayerScale zoom = GetScaleForAxis(GetFrameMetrics().GetZoom()); ParentLayerCoord origin = aOrigin * zoom; ParentLayerCoord result; if (origin < GetPageStart()) { result = GetPageStart(); } else if (origin + GetCompositionLength() > GetPageEnd()) { result = GetPageEnd() - GetCompositionLength(); } else { return aOrigin; } return result / zoom; }
float Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) { float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus; switch (ScaleWillOverscroll(aScale, aFocus)) { case OVERSCROLL_MINUS: return originAfterScale - GetPageStart() * aScale; case OVERSCROLL_PLUS: return (originAfterScale + GetCompositionLength()) - NS_lround(GetPageEnd() * aScale); // Don't handle OVERSCROLL_BOTH. Client code is expected to deal with it. default: return 0; } }
CSSCoord Axis::ApplyResistance(CSSCoord aRequestedOverscroll) const { // 'resistanceFactor' is a value between 0 and 1, which: // - tends to 1 as the existing overscroll tends to 0 // - tends to 0 as the existing overscroll tends to the composition length // The actual overscroll is the requested overscroll multiplied by this // factor; this should prevent overscrolling by more than the composition // length. float resistanceFactor = 1 - fabsf(mOverscroll) / GetCompositionLength(); return resistanceFactor < 0 ? CSSCoord(0) : aRequestedOverscroll * resistanceFactor; }
float Axis::ScaleWillOverscrollAmount(float aScale, float aFocus) { float originAfterScale = (GetOrigin() + aFocus) - (aFocus / aScale); bool both = ScaleWillOverscrollBothSides(aScale); bool minus = originAfterScale < GetPageStart(); bool plus = (originAfterScale + (GetCompositionLength() / aScale)) > GetPageEnd(); if ((minus && plus) || both) { // If we ever reach here it's a bug in the client code. MOZ_ASSERT(false, "In an OVERSCROLL_BOTH condition in ScaleWillOverscrollAmount"); return 0; } if (minus) { return originAfterScale - GetPageStart(); } if (plus) { return originAfterScale + (GetCompositionLength() / aScale) - GetPageEnd(); } return 0; }
ParentLayerCoord Axis::ApplyResistance(ParentLayerCoord aRequestedOverscroll) const { // 'resistanceFactor' is a value between 0 and 1/16, which: // - tends to 1/16 as the existing overscroll tends to 0 // - tends to 0 as the existing overscroll tends to the composition length // The actual overscroll is the requested overscroll multiplied by this // factor. float resistanceFactor = (1 - fabsf(GetOverscroll()) / GetCompositionLength()) / 16; float result = resistanceFactor < 0 ? ParentLayerCoord(0) : aRequestedOverscroll * resistanceFactor; result = clamped(result, -8.0f, 8.0f); return result; }
CSSCoord Axis::ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus) const { // Internally, do computations in ParentLayer coordinates *before* the scale // is applied. CSSToParentLayerScale zoom = GetFrameMetrics().GetZoom().ToScaleFactor(); ParentLayerCoord focus = aFocus * zoom; ParentLayerCoord originAfterScale = (GetOrigin() + focus) - (focus / aScale); bool both = ScaleWillOverscrollBothSides(aScale); bool minus = GetPageStart() - originAfterScale > COORDINATE_EPSILON; bool plus = (originAfterScale + (GetCompositionLength() / aScale)) - GetPageEnd() > COORDINATE_EPSILON; if ((minus && plus) || both) { // If we ever reach here it's a bug in the client code. MOZ_ASSERT(false, "In an OVERSCROLL_BOTH condition in ScaleWillOverscrollAmount"); return 0; } if (minus) { return (originAfterScale - GetPageStart()) / zoom; } if (plus) { return (originAfterScale + (GetCompositionLength() / aScale) - GetPageEnd()) / zoom; } return 0; }
Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) { float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus; bool both = ScaleWillOverscrollBothSides(aScale); bool minus = originAfterScale < GetPageStart() * aScale; bool plus = (originAfterScale + GetCompositionLength()) > GetPageEnd() * aScale; if ((minus && plus) || both) { return OVERSCROLL_BOTH; } if (minus) { return OVERSCROLL_MINUS; } if (plus) { return OVERSCROLL_PLUS; } return OVERSCROLL_NONE; }
float Axis::GetCompositionEnd() { return GetOrigin() + GetCompositionLength(); }
bool Axis::Scrollable() { if (mAxisLocked) { return false; } return GetCompositionLength() < GetPageLength(); }
CSSCoord Axis::GetCompositionEnd() const { return GetOrigin() + GetCompositionLength(); }
bool Axis::CanScroll() const { return GetPageLength() - GetCompositionLength() > COORDINATE_EPSILON; }
ParentLayerCoord Axis::GetScrollRangeEnd() const { return GetPageEnd() - GetCompositionLength(); }