ViewportUtils.h (5900B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_ViewportUtils_h 6 #define mozilla_ViewportUtils_h 7 8 #include "Units.h" 9 #include "mozilla/layers/ScrollableLayerGuid.h" 10 11 class nsIFrame; 12 class nsIContent; 13 class nsPresContext; 14 15 namespace mozilla { 16 17 class PresShell; 18 19 class ViewportUtils { 20 public: 21 /* Return a transform to be applied to the coordinates of input events 22 targeting content inside the scroll frame identified by |aScrollId|, which 23 converts from "visual coordinates" (which are the coordinates events have 24 when they arrive from APZ) to "layout coordinates" (which are the 25 coordinates used in most places by layout code). The transform has two 26 components: 27 1. The pres shell resolution, representing the pinch-zoom scale 28 (if the scroll frame |aScrollId| is inside the resolution, which 29 is most of the time). 30 2. A translation representing async scrolling. This can contain: 31 - For any scroll frame, a scroll component resulting from the main 32 thread incompletely applying an APZ-requested scroll position. 33 - For the RCD-RSF only, a persistent component representing the 34 offset of the visual viewport relative to the layout viewport. 35 The translation is accumulated for all scroll frames form |aScrollId| 36 up to the root, using values populated in 37 APZCCallbackHelper::UpdateCallbackTransform. See that method's 38 documentation for additional details. */ 39 template <typename Units = CSSPixel> 40 static gfx::Matrix4x4TypedFlagged<Units, Units> GetVisualToLayoutTransform( 41 nsIContent* aContent); 42 43 /* The functions below apply GetVisualToLayoutTransform() or its inverse 44 * to various quantities. 45 * 46 * To determine the appropriate scroll id to pass into 47 * GetVisualToLayoutTransform(), these functions prefer to use the one 48 * from InputAPZContext::GetTargetLayerGuid() if one is available. 49 * If one is not available, they use the scroll id of the root scroll 50 * frame of the pres shell passed in as |aContext| as a fallback. 51 */ 52 static nsPoint VisualToLayout(const nsPoint& aPt, PresShell* aContext); 53 static nsRect VisualToLayout(const nsRect& aRect, PresShell* aContext); 54 static nsPoint LayoutToVisual(const nsPoint& aPt, PresShell* aContext); 55 56 /* 57 * These functions convert the point/rect from layout to visual space 58 * by applying the inverse of GetLayoutToVisualTransform() of the root 59 * scrollframe of provided presShell. 60 */ 61 static LayoutDevicePoint DocumentRelativeLayoutToVisual( 62 const LayoutDevicePoint& aPoint, PresShell* aShell); 63 static LayoutDeviceRect DocumentRelativeLayoutToVisual( 64 const LayoutDeviceRect& aRect, PresShell* aShell); 65 static LayoutDeviceRect DocumentRelativeLayoutToVisual( 66 const LayoutDeviceIntRect& aRect, PresShell* aShell); 67 static CSSRect DocumentRelativeLayoutToVisual(const CSSRect& aRect, 68 PresShell* aShell); 69 70 /* 71 * These convert aPt/aRect, which is the layout space of aCtx, into a 72 * screen-relative visual-space quantity. Formally, we can think of the input 73 * as being in RelativeTo{aCtx->PresShell()->GetRootFrame(), 74 * ViewportType::Layout} space. And then the function iterates up the chain of 75 * presContexts, transforming the point along, until it gets to the 76 * RelativeTo{aCtx->GetRootPresContext()->PresShell()->GetRootFrame(), 77 * ViewportType::Visual} space. Then it further transforms it into a 78 * screen-relative space. Unlike other ViewportUtils methods, the input is 79 * relative to `aCtx` which might be a sub-shell of the presShell with the 80 * resolution. 81 */ 82 static LayoutDevicePoint ToScreenRelativeVisual(const LayoutDevicePoint& aPt, 83 nsPresContext* aCtx); 84 static LayoutDeviceRect ToScreenRelativeVisual(const LayoutDeviceRect& aRect, 85 nsPresContext* aCtx); 86 87 /** 88 * Returns non-null if |aFrame| is inside the async zoom container but its 89 * parent frame is not, thereby making |aFrame| a root of a subtree of 90 * frames representing content that is zoomed in. The value returned in such 91 * cases is the root scroll frame inside the async zoom container. 92 93 * Callers use this to identify points during frame tree traversal where the 94 * visual-to-layout transform needs to be applied. 95 */ 96 static const nsIFrame* IsZoomedContentRoot(const nsIFrame* aFrame); 97 98 /** 99 * If |aShell| is in a nested content process, try to infer the resolution 100 * at which the enclosing root content 101 * document has been painted. 102 * 103 * Otherwise (if |aShell| is in the chrome or top-level content process), 104 * this function returns 1.0. 105 * 106 * |aShell| must be the root pres shell in its process. 107 * 108 * This function may not return an accurate answer if there is also 109 * a CSS transform enclosing the iframe. 110 */ 111 static Scale2D TryInferEnclosingResolution(PresShell* aShell); 112 }; 113 114 // Forward declare explicit instantiations of GetVisualToLayoutTransform() for 115 // CSSPixel and LayoutDevicePixel, the only two types it gets used with. 116 // These declarations promise to callers in any translation unit that _some_ 117 // translation unit (in this case, ViewportUtils.cpp) will contain the 118 // definitions of these instantiations. This allows us to keep the definition 119 // out-of-line in the source. 120 extern template CSSToCSSMatrix4x4Flagged 121 ViewportUtils::GetVisualToLayoutTransform<CSSPixel>(nsIContent*); 122 extern template LayoutDeviceToLayoutDeviceMatrix4x4Flagged 123 ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(nsIContent*); 124 125 } // namespace mozilla 126 127 #endif /* mozilla_ViewportUtils_h */