CSSToScreenScale MobileViewportManager::ClampZoom(const CSSToScreenScale& aZoom, const nsViewportInfo& aViewportInfo) { CSSToScreenScale zoom = aZoom; if (zoom < aViewportInfo.GetMinZoom()) { zoom = aViewportInfo.GetMinZoom(); MVM_LOG("%p: Clamped to %f\n", this, zoom.scale); } if (zoom > aViewportInfo.GetMaxZoom()) { zoom = aViewportInfo.GetMaxZoom(); MVM_LOG("%p: Clamped to %f\n", this, zoom.scale); } return zoom; }
mozilla::layers::ZoomConstraints ComputeZoomConstraintsFromViewportInfo(const nsViewportInfo& aViewportInfo) { mozilla::layers::ZoomConstraints constraints; constraints.mAllowZoom = aViewportInfo.IsZoomAllowed(); constraints.mAllowDoubleTapZoom = aViewportInfo.IsDoubleTapZoomAllowed(); constraints.mMinZoom.scale = aViewportInfo.GetMinZoom().scale; constraints.mMaxZoom.scale = aViewportInfo.GetMaxZoom().scale; return constraints; }
mozilla::layers::ZoomConstraints ComputeZoomConstraintsFromViewportInfo(const nsViewportInfo& aViewportInfo) { mozilla::layers::ZoomConstraints constraints; constraints.mAllowZoom = aViewportInfo.IsZoomAllowed() && gfxPrefs::APZAllowZooming(); constraints.mAllowDoubleTapZoom = constraints.mAllowZoom; if (constraints.mAllowZoom) { constraints.mMinZoom.scale = aViewportInfo.GetMinZoom().scale; constraints.mMaxZoom.scale = aViewportInfo.GetMaxZoom().scale; } else { constraints.mMinZoom.scale = aViewportInfo.GetDefaultZoom().scale; constraints.mMaxZoom.scale = aViewportInfo.GetDefaultZoom().scale; } return constraints; }
CSSToScreenScale MobileViewportManager::UpdateResolution(const nsViewportInfo& aViewportInfo, const ScreenIntSize& aDisplaySize, const CSSSize& aViewport, const Maybe<float>& aDisplayWidthChangeRatio) { CSSToLayoutDeviceScale cssToDev = mPresShell->GetPresContext()->CSSToDevPixelScale(); LayoutDeviceToLayerScale res(mPresShell->GetResolution()); if (mIsFirstPaint) { CSSToScreenScale defaultZoom; if (mRestoreResolution) { defaultZoom = CSSToScreenScale(mRestoreResolution.value() * cssToDev.scale); MVM_LOG("%p: restored zoom is %f\n", this, defaultZoom.scale); defaultZoom = ClampZoom(defaultZoom, aViewportInfo); } else { defaultZoom = aViewportInfo.GetDefaultZoom(); MVM_LOG("%p: default zoom from viewport is %f\n", this, defaultZoom.scale); if (!aViewportInfo.IsDefaultZoomValid()) { defaultZoom = MaxScaleRatio(ScreenSize(aDisplaySize), aViewport); MVM_LOG("%p: Intrinsic computed zoom is %f\n", this, defaultZoom.scale); defaultZoom = ClampZoom(defaultZoom, aViewportInfo); } } MOZ_ASSERT(aViewportInfo.GetMinZoom() <= defaultZoom && defaultZoom <= aViewportInfo.GetMaxZoom()); CSSToParentLayerScale zoom = ViewTargetAs<ParentLayerPixel>(defaultZoom, PixelCastJustification::ScreenIsParentLayerForRoot); LayoutDeviceToLayerScale resolution = zoom / cssToDev * ParentLayerToLayerScale(1); MVM_LOG("%p: setting resolution %f\n", this, resolution.scale); mPresShell->SetResolutionAndScaleTo(resolution.scale); return defaultZoom; } // If this is not a first paint, then in some cases we want to update the pre- // existing resolution so as to maintain how much actual content is visible // within the display width. Note that "actual content" may be different with // respect to CSS pixels because of the CSS viewport size changing. // // aDisplayWidthChangeRatio is non-empty if: // (a) The meta-viewport tag information changes, and so the CSS viewport // might change as a result. If this happens after the content has been // painted, we want to adjust the zoom to compensate. OR // (b) The display size changed from a nonzero value to another nonzero value. // This covers the case where e.g. the device was rotated, and again we // want to adjust the zoom to compensate. // Note in particular that aDisplayWidthChangeRatio will be None if all that // happened was a change in the full-zoom. In this case, we still want to // compute a new CSS viewport, but we don't want to update the resolution. // // Given the above, the algorithm below accounts for all types of changes I // can conceive of: // 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) { float cssViewportChangeRatio = (mMobileViewportSize.width == 0) ? 1.0f : aViewport.width / mMobileViewportSize.width; LayoutDeviceToLayerScale newRes(res.scale * aDisplayWidthChangeRatio.value() / cssViewportChangeRatio); MVM_LOG("%p: Old resolution was %f, changed by %f/%f to %f\n", this, res.scale, aDisplayWidthChangeRatio.value(), cssViewportChangeRatio, newRes.scale); mPresShell->SetResolutionAndScaleTo(newRes.scale); res = newRes; } return ViewTargetAs<ScreenPixel>(cssToDev * res / ParentLayerToLayerScale(1), PixelCastJustification::ScreenIsParentLayerForRoot); }