diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 26ce16ab0dde..fec6fee2f9a7 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7596,6 +7596,65 @@ nsLayoutUtils::GetContentViewerSize(nsPresContext* aPresContext, return true; } +static bool +UpdateCompositionBoundsForRCDRSF(ParentLayerRect& aCompBounds, + nsPresContext* aPresContext, + const nsRect& aFrameBounds, + bool aScaleContentViewerSize, + const LayoutDeviceToLayerScale2D& aCumulativeResolution) +{ + nsIFrame* rootFrame = aPresContext->PresShell()->GetRootFrame(); + if (!rootFrame) { + return false; + } + + // On Android, we need to do things a bit differently to get things + // right (see bug 983208, bug 988882). We use the bounds of the nearest + // widget, but clamp the height to the frame bounds height. This clamping + // is done to get correct results for a page where the page is sized to + // the screen and thus the dynamic toolbar never disappears. In such a + // case, we want the composition bounds to exclude the toolbar height, + // but the widget bounds includes it. We don't currently have a good way + // of knowing about the toolbar height, but clamping to the frame bounds + // height gives the correct answer in the cases we care about. +#ifdef MOZ_WIDGET_ANDROID + nsIWidget* widget = rootFrame->GetNearestWidget(); +#else + nsView* view = rootFrame->GetView(); + nsIWidget* widget = view ? view->GetWidget() : nullptr; +#endif + + if (widget) { + nsIntRect widgetBounds; + widget->GetBounds(widgetBounds); + widgetBounds.MoveTo(0, 0); + aCompBounds = ParentLayerRect(ViewAs(widgetBounds)); +#ifdef MOZ_WIDGET_ANDROID + ParentLayerRect frameBounds = + LayoutDeviceRect::FromAppUnits(aFrameBounds, aPresContext->AppUnitsPerDevPixel()) + * aCumulativeResolution + * LayerToParentLayerScale(1.0); + if (frameBounds.height < aCompBounds.height) { + aCompBounds.height = frameBounds.height; + } +#endif + return true; + } + + LayoutDeviceIntSize contentSize; + if (nsLayoutUtils::GetContentViewerSize(aPresContext, contentSize)) { + LayoutDeviceToParentLayerScale scale; + if (aScaleContentViewerSize && aPresContext->GetParentPresContext()) { + scale = LayoutDeviceToParentLayerScale( + aPresContext->GetParentPresContext()->PresShell()->GetCumulativeResolution()); + } + aCompBounds.SizeTo(contentSize * scale); + return true; + } + + return false; +} + static bool DeflateScrollbarAreaFromCompositionBoundsFor(nsIFrame* aScrollFrame) { @@ -7629,50 +7688,16 @@ nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame, bool aSubtract nsPresContext* presContext = aFrame->PresContext(); nsIPresShell* presShell = presContext->PresShell(); - // See the comments in the code that calculates the root - // composition bounds in ComputeFrameMetrics. - // TODO: Reuse that code here. bool isRootContentDocRootScrollFrame = presContext->IsRootContentDocument() && aFrame == presShell->GetRootScrollFrame(); if (isRootContentDocRootScrollFrame) { - if (nsIFrame* rootFrame = presShell->GetRootFrame()) { -#ifdef MOZ_WIDGET_ANDROID - nsIWidget* widget = rootFrame->GetNearestWidget(); -#else - nsView* view = rootFrame->GetView(); - nsIWidget* widget = view ? view->GetWidget() : nullptr; -#endif + ParentLayerRect compBounds; + // TODO: The UpdateCompositionBoundsForRCDRSF below doesn't take into + // account the mTransformScale as part of the LayerToParentLayerScale. + if (UpdateCompositionBoundsForRCDRSF(compBounds, presContext, aFrame->GetRect(), + false, LayoutDeviceToParentLayerScale2D(presShell->GetCumulativeResolution()))) { int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel(); - if (widget) { - nsIntRect widgetBounds; - widget->GetBounds(widgetBounds); - size = nsSize(widgetBounds.width * auPerDevPixel, - widgetBounds.height * auPerDevPixel); -#ifdef MOZ_WIDGET_ANDROID - nsRect frameRect = aFrame->GetRect(); - float cumulativeResolution = presShell->GetCumulativeResolution(); - LayoutDeviceToParentLayerScale layoutToParentLayerScale = - // The ScreenToParentLayerScale should be mTransformScale which is - // not calculated yet, but we don't yet handle CSS transforms, so we - // assume it's 1 here. - LayoutDeviceToLayerScale(cumulativeResolution) * - LayerToScreenScale(1.0) * ScreenToParentLayerScale(1.0); - ParentLayerRect frameRectPixels = - LayoutDeviceRect::FromAppUnits(frameRect, auPerDevPixel) - * layoutToParentLayerScale; - if (frameRectPixels.height < ParentLayerRect(ViewAs(widgetBounds)).height) { - // Our return value is in appunits of the parent, so we need to - // include the resolution. - size.height = - NSToCoordRound(frameRect.height * cumulativeResolution); - } -#endif - } else { - LayoutDeviceIntSize contentSize; - if (nsLayoutUtils::GetContentViewerSize(presContext, contentSize)) { - size = LayoutDevicePixel::ToAppUnits(contentSize, auPerDevPixel); - } - } + size = nsSize(compBounds.width * auPerDevPixel, compBounds.height * auPerDevPixel); } } @@ -8280,44 +8305,8 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame, bool isRootContentDocRootScrollFrame = isRootScrollFrame && presContext->IsRootContentDocument(); if (isRootContentDocRootScrollFrame) { - if (nsIFrame* rootFrame = presShell->GetRootFrame()) { - // On Android, we need to do things a bit differently to get things - // right (see bug 983208, bug 988882). We use the bounds of the nearest - // widget, but clamp the height to the frame bounds height. This clamping - // is done to get correct results for a page where the page is sized to - // the screen and thus the dynamic toolbar never disappears. In such a - // case, we want the composition bounds to exclude the toolbar height, - // but the widget bounds includes it. We don't currently have a good way - // of knowing about the toolbar height, but clamping to the frame bounds - // height gives the correct answer in the cases we care about. -#ifdef MOZ_WIDGET_ANDROID - nsIWidget* widget = rootFrame->GetNearestWidget(); -#else - nsView* view = rootFrame->GetView(); - nsIWidget* widget = view ? view->GetWidget() : nullptr; -#endif - if (widget) { - nsIntRect widgetBounds; - widget->GetBounds(widgetBounds); - widgetBounds.MoveTo(0,0); - metrics.mCompositionBounds = ParentLayerRect(ViewAs(widgetBounds)); -#ifdef MOZ_WIDGET_ANDROID - if (frameBounds.height < metrics.mCompositionBounds.height) { - metrics.mCompositionBounds.height = frameBounds.height; - } -#endif - } else { - LayoutDeviceIntSize contentSize; - if (nsLayoutUtils::GetContentViewerSize(presContext, contentSize)) { - LayoutDeviceToParentLayerScale scale; - if (presContext->GetParentPresContext()) { - float res = presContext->GetParentPresContext()->PresShell()->GetCumulativeResolution(); - scale = LayoutDeviceToParentLayerScale(res); - } - metrics.mCompositionBounds.SizeTo(contentSize * scale); - } - } - } + UpdateCompositionBoundsForRCDRSF(metrics.mCompositionBounds, presContext, + compositionBounds, true, metrics.GetCumulativeResolution()); } if (DeflateScrollbarAreaFromCompositionBoundsFor(aScrollFrame)) {