author | Brad Werth <bwerth@mozilla.com> |
Mon, 18 Mar 2019 14:59:12 +0000 | |
changeset 464845 | 8824d55c1b62ca892bf153a66213ada838c65df9 |
parent 464844 | 22aac830b13a8ff5f57f8d7c1db94d9caeb26a03 |
child 464846 | 916cbe96f1d308779b27af7b842d1c2dba8024c1 |
push id | 35727 |
push user | dvarga@mozilla.com |
push date | Tue, 19 Mar 2019 09:48:59 +0000 |
treeherder | mozilla-central@70baa37ae1eb [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | botond |
bugs | 1501665 |
milestone | 68.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/MobileViewportManager.cpp +++ b/layout/base/MobileViewportManager.cpp @@ -311,19 +311,83 @@ void MobileViewportManager::UpdateResolu // 1. screen size changes, CSS viewport does not (pages with no meta // viewport or a fixed size viewport) // 2. screen size changes, CSS viewport also does (pages with a // device-width viewport) // 3. screen size remains constant, but CSS viewport changes (meta // viewport tag is added or removed) // 4. neither screen size nor CSS viewport changes if (aDisplayWidthChangeRatio) { - newZoom = Some( - ScaleZoomWithDisplayWidth(zoom, aDisplayWidthChangeRatio.value(), - viewportSize, mMobileViewportSize)); + // One more complication is that our current zoom level may be the + // result of clamping to either the minimum or maximum zoom level + // allowed by the viewport. If we naively scale the zoom level with + // the change in the display width, we might be scaling one of these + // clamped values. What we really want to do is to make scaling of the + // zoom aware of these minimum and maximum clamping points, so that we + // keep display width changes completely reversible. + + // Because of the behavior of ShrinkToDisplaySizeIfNeeded, we are + // choosing zoom clamping points based on the content size of the + // scrollable rect, which might different from aViewportOrContentSize. + CSSSize contentSize = aViewportOrContentSize; + nsIScrollableFrame* rootScrollableFrame = + mPresShell->GetRootScrollFrameAsScrollable(); + if (rootScrollableFrame) { + nsRect scrollableRect = + nsLayoutUtils::CalculateScrollableRectForFrame( + rootScrollableFrame, nullptr); + contentSize = CSSSize::FromAppUnits(scrollableRect.Size()); + } + + // We scale the sizes, though we only care about the scaled widths. + ScreenSize minZoomDisplaySize = + contentSize * aViewportInfo.GetMinZoom(); + ScreenSize maxZoomDisplaySize = + contentSize * aViewportInfo.GetMaxZoom(); + + float ratio = aDisplayWidthChangeRatio.value(); + ScreenSize newDisplaySize(aDisplaySize); + ScreenSize oldDisplaySize = newDisplaySize / ratio; + + // To calculate an adjusted ratio, we use some combination of these + // four values: + float a(minZoomDisplaySize.width); + float b(maxZoomDisplaySize.width); + float c(oldDisplaySize.width); + float d(newDisplaySize.width); + + // For both oldDisplaySize and aDisplaySize, the values are in one of + // three "zones": + // 1) Less than or equal to minZoomDisplaySize. + // 2) Between minZoomDisplaySize and maxZoomDisplaySize. + // 3) Greater than or equal to maxZoomDisplaySize. + + // Depending on which zone each are in, the adjusted ratio is shown in + // the table below (using the a-b-c-d coding from above): + + // d | 1 | 2 | 3 | + // c +---+---+---+ + // | a | d | b | + // 1 | a | a | a | + // +---+---+---+ + // | a | d | b | + // 2 | c | c | c | + // +---+---+---+ + // | a | d | b | + // 3 | b | b | b | + // +---+---+---+ + + // Conveniently, the numerator is just d clamped to a..b, and the + // denominator is c clamped to a..b. + float numerator = clamped(d, a, b); + float denominator = clamped(c, a, b); + + float adjustedRatio = numerator / denominator; + newZoom = Some(ScaleZoomWithDisplayWidth( + zoom, adjustedRatio, viewportSize, mMobileViewportSize)); } } } else { // aType == UpdateType::ContentSize MOZ_ASSERT(aType == UpdateType::ContentSize); MOZ_ASSERT(aDisplayWidthChangeRatio.isNothing()); // We try to scale down the contents only IF the document has no // initial-scale AND IF it's the initial paint AND IF it's not restored