void Axis::OverscrollBy(ParentLayerCoord aOverscroll) { MOZ_ASSERT(CanScroll()); // We can get some spurious calls to OverscrollBy() with near-zero values // due to rounding error. Ignore those (they might trip the asserts below.) if (FuzzyEqualsAdditive(aOverscroll.value, 0.0f, COORDINATE_EPSILON)) { return; } EndOverscrollAnimation(); aOverscroll = ApplyResistance(aOverscroll); if (aOverscroll > 0) { #ifdef DEBUG if (!FuzzyEqualsCoordinate(GetCompositionEnd().value, GetPageEnd().value)) { nsPrintfCString message("composition end (%f) is not equal (within error) to page end (%f)\n", GetCompositionEnd().value, GetPageEnd().value); NS_ASSERTION(false, message.get()); MOZ_CRASH("GFX: Overscroll issue > 0"); } #endif MOZ_ASSERT(mOverscroll >= 0); } else if (aOverscroll < 0) { #ifdef DEBUG if (!FuzzyEqualsCoordinate(GetOrigin().value, GetPageStart().value)) { nsPrintfCString message("composition origin (%f) is not equal (within error) to page origin (%f)\n", GetOrigin().value, GetPageStart().value); NS_ASSERTION(false, message.get()); MOZ_CRASH("GFX: Overscroll issue < 0"); } #endif MOZ_ASSERT(mOverscroll <= 0); } mOverscroll += aOverscroll; }
void Axis::OverscrollBy(ParentLayerCoord aOverscroll) { MOZ_ASSERT(CanScroll()); StopSamplingOverscrollAnimation(); aOverscroll = ApplyResistance(aOverscroll); if (aOverscroll > 0) { #ifdef DEBUG if (!FuzzyEqualsCoordinate(GetCompositionEnd().value, GetPageEnd().value)) { nsPrintfCString message("composition end (%f) is not equal (within error) to page end (%f)\n", GetCompositionEnd().value, GetPageEnd().value); NS_ASSERTION(false, message.get()); MOZ_CRASH(); } #endif MOZ_ASSERT(mOverscroll >= 0); } else if (aOverscroll < 0) { #ifdef DEBUG if (!FuzzyEqualsCoordinate(GetOrigin().value, GetPageStart().value)) { nsPrintfCString message("composition origin (%f) is not equal (within error) to page origin (%f)\n", GetOrigin().value, GetPageStart().value); NS_ASSERTION(false, message.get()); MOZ_CRASH(); } #endif MOZ_ASSERT(mOverscroll <= 0); } mOverscroll += aOverscroll; }
void Axis::OverscrollBy(CSSCoord aOverscroll) { MOZ_ASSERT(CanScroll()); aOverscroll = ApplyResistance(aOverscroll); if (aOverscroll > 0) { #ifdef DEBUG if (!FuzzyEqualsAdditive(GetCompositionEnd().value, GetPageEnd().value, COORDINATE_EPSILON)) { nsPrintfCString message("composition end (%f) is not within COORDINATE_EPISLON of page end (%f)\n", GetCompositionEnd().value, GetPageEnd().value); NS_ASSERTION(false, message.get()); MOZ_CRASH(); } #endif MOZ_ASSERT(mOverscroll >= 0); } else if (aOverscroll < 0) { #ifdef DEBUG if (!FuzzyEqualsAdditive(GetOrigin().value, GetPageStart().value, COORDINATE_EPSILON)) { nsPrintfCString message("composition origin (%f) is not within COORDINATE_EPISLON of page origin (%f)\n", GetOrigin().value, GetPageStart().value); NS_ASSERTION(false, message.get()); MOZ_CRASH(); } #endif MOZ_ASSERT(mOverscroll <= 0); } mOverscroll += aOverscroll; }
float Axis::GetExcess() { switch (GetOverscroll()) { case OVERSCROLL_MINUS: return GetOrigin() - GetPageStart(); case OVERSCROLL_PLUS: return GetCompositionEnd() - GetPageEnd(); case OVERSCROLL_BOTH: return (GetCompositionEnd() - GetPageEnd()) + (GetPageStart() - GetOrigin()); default: return 0; } }
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::DisplacementWillOverscrollAmount(int32_t aDisplacement) { switch (DisplacementWillOverscroll(aDisplacement)) { case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart(); case OVERSCROLL_PLUS: return (GetCompositionEnd() + aDisplacement) - GetPageEnd(); // Don't handle overscrolled in both directions; a displacement can't cause // this, it must have already been zoomed out too far. default: return 0; } }
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; } }
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; }
void Axis::OverscrollBy(CSSCoord aOverscroll) { MOZ_ASSERT(CanScroll()); aOverscroll = ApplyResistance(aOverscroll); if (aOverscroll > 0) { MOZ_ASSERT(FuzzyEqualsAdditive(GetCompositionEnd().value, GetPageEnd().value, COORDINATE_EPSILON)); MOZ_ASSERT(mOverscroll >= 0); } else if (aOverscroll < 0) { MOZ_ASSERT(FuzzyEqualsAdditive(GetOrigin().value, GetPageStart().value, COORDINATE_EPSILON)); MOZ_ASSERT(mOverscroll <= 0); } mOverscroll += aOverscroll; }
ParentLayerCoord Axis::DisplacementWillOverscrollAmount(ParentLayerCoord aDisplacement) const { ParentLayerCoord newOrigin = GetOrigin() + aDisplacement; ParentLayerCoord newCompositionEnd = GetCompositionEnd() + aDisplacement; // If the current pan plus a displacement takes the window to the left of or // above the current page rect. bool minus = newOrigin < GetPageStart(); // If the current pan plus a displacement takes the window to the right of or // below the current page rect. bool plus = newCompositionEnd > GetPageEnd(); if (minus && plus) { // Don't handle overscrolled in both directions; a displacement can't cause // this, it must have already been zoomed out too far. return 0; } if (minus) { return newOrigin - GetPageStart(); } if (plus) { return newCompositionEnd - GetPageEnd(); } return 0; }
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; }
Axis::Overscroll Axis::DisplacementWillOverscroll(int32_t aDisplacement) { // If the current pan plus a displacement takes the window to the left of or // above the current page rect. bool minus = GetOrigin() + aDisplacement < GetPageStart(); // If the current pan plus a displacement takes the window to the right of or // below the current page rect. bool plus = GetCompositionEnd() + aDisplacement > GetPageEnd(); if (minus && plus) { return OVERSCROLL_BOTH; } if (minus) { return OVERSCROLL_MINUS; } if (plus) { return OVERSCROLL_PLUS; } return OVERSCROLL_NONE; }
Axis::Overscroll Axis::GetOverscroll() { // If the current pan takes the window to the left of or above the current // page rect. bool minus = GetOrigin() < GetPageStart(); // If the current pan takes the window to the right of or below the current // page rect. bool plus = GetCompositionEnd() > GetPageEnd(); if (minus && plus) { return OVERSCROLL_BOTH; } if (minus) { return OVERSCROLL_MINUS; } if (plus) { return OVERSCROLL_PLUS; } return OVERSCROLL_NONE; }
bool Axis::HasRoomToPan() const { return GetOrigin() > GetPageStart() || GetCompositionEnd() < GetPageEnd(); }
ParentLayerCoord Axis::GetScrollRangeEnd() const { return GetPageEnd() - GetCompositionLength(); }