Bug 1467873 - Fix FrameMetrics::CalculateCompositedRectInCssPixels(). r=kats
- Fix the implementation to return a numerically correct result
- Change call sites that should have instead been using
CalculateCompositedSizeInCssPixels(), to do so
- Rename and document to emphasize that the returned rect is in the
CSS pixels of the content surrounding the scroll frame
MozReview-Commit-ID: GCPbA1k88rz
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -192,22 +192,35 @@ public:
CSSSize CalculateCompositedSizeInCssPixels() const
{
if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
return CSSSize(); // avoid division by zero
}
return mCompositionBounds.Size() / GetZoom();
}
- CSSRect CalculateCompositedRectInCssPixels() const
+ /*
+ * Calculate the composition bounds of this frame in the CSS pixels of
+ * the content surrounding the scroll frame. (This can be thought of as
+ * "parent CSS" pixels).
+ * Note that it does not make to ask for the composition bounds in the
+ * CSS pixels of the scrolled content (that is, regular CSS pixels),
+ * because the origin of the composition bounds is not meaningful in that
+ * coordinate space. (The size is, use CalculateCompositedSizeInCssPixels()
+ * for that.)
+ */
+ CSSRect CalculateCompositionBoundsInCssPixelsOfSurroundingContent() const
{
if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
return CSSRect(); // avoid division by zero
}
- return mCompositionBounds / GetZoom();
+ // The CSS pixels of the scrolled content and the CSS pixels of the
+ // surrounding content only differ if the scrolled content is rendered
+ // at a higher resolution, and the difference is the resolution.
+ return mCompositionBounds / GetZoom() * CSSToCSSScale{mPresShellResolution};
}
CSSSize CalculateBoundedCompositedSizeInCssPixels() const
{
CSSSize size = CalculateCompositedSizeInCssPixels();
size.width = std::min(size.width, mRootCompositionSize.width);
size.height = std::min(size.height, mRootCompositionSize.height);
return size;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1051,17 +1051,17 @@ nsEventStatus AsyncPanZoomController::Ha
maxThumbPos -= scrollbarData.mThumbLength;
float scrollPercent = thumbPosition / maxThumbPos;
CSSCoord minScrollPosition =
GetAxisStart(direction, mFrameMetrics.GetScrollableRect().TopLeft());
CSSCoord maxScrollPosition =
GetAxisStart(direction, mFrameMetrics.GetScrollableRect().BottomRight()) -
- GetAxisLength(direction, mFrameMetrics.CalculateCompositedRectInCssPixels());
+ GetAxisLength(direction, mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent());
CSSCoord scrollPosition = minScrollPosition + (scrollPercent * (maxScrollPosition - minScrollPosition));
scrollPosition = std::max(scrollPosition, minScrollPosition);
scrollPosition = std::min(scrollPosition, maxScrollPosition);
CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
if (direction == ScrollDirection::eHorizontal) {
scrollOffset.x = scrollPosition;
@@ -1745,17 +1745,17 @@ AsyncPanZoomController::ConvertScrollbar
// First, get it into the right coordinate space.
CSSPoint scrollbarPoint = aScrollbarPoint / mFrameMetrics.GetZoom();
// The scrollbar can be transformed with the frame but the pres shell
// resolution is only applied to the scroll frame.
scrollbarPoint = scrollbarPoint * mFrameMetrics.GetPresShellResolution();
// Now, get it to be relative to the beginning of the scroll track.
- CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositedRectInCssPixels();
+ CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent();
return GetAxisStart(*aThumbData.mDirection, scrollbarPoint)
- GetAxisStart(*aThumbData.mDirection, cssCompositionBound)
- aThumbData.mScrollTrackStart;
}
static bool
AllowsScrollingMoreThanOnePage(double aMultiplier)
{
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -205,20 +205,20 @@ SetDisplayPortMargins(nsIPresShell* aPre
bool hadDisplayPort = nsLayoutUtils::HasDisplayPort(aContent);
ScreenMargin margins = aMetrics.GetDisplayPortMargins();
nsLayoutUtils::SetDisplayPortMargins(aContent, aPresShell, margins, 0);
if (!hadDisplayPort) {
nsLayoutUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
aContent->GetPrimaryFrame(), nsLayoutUtils::RepaintMode::Repaint);
}
- CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
+ CSSSize baseSize = aMetrics.CalculateCompositedSizeInCssPixels();
nsRect base(0, 0,
- baseCSS.Width() * nsPresContext::AppUnitsPerCSSPixel(),
- baseCSS.Height() * nsPresContext::AppUnitsPerCSSPixel());
+ baseSize.width * nsPresContext::AppUnitsPerCSSPixel(),
+ baseSize.height * nsPresContext::AppUnitsPerCSSPixel());
nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
}
static already_AddRefed<nsIPresShell>
GetPresShell(const nsIContent* aContent)
{
nsCOMPtr<nsIPresShell> result;
if (nsIDocument* doc = aContent->GetComposedDoc()) {
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -134,16 +134,17 @@ typedef gfx::CoordTyped<DesktopPixel> De
typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord;
typedef gfx::PointTyped<DesktopPixel> DesktopPoint;
typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint;
typedef gfx::SizeTyped<DesktopPixel> DesktopSize;
typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize;
typedef gfx::RectTyped<DesktopPixel> DesktopRect;
typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect;
+typedef gfx::ScaleFactor<CSSPixel, CSSPixel> CSSToCSSScale;
typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel> LayoutDeviceToScreenScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;