Bug 1646700 [wpt PR 24235] - Update picture-in-picture idlharness test, a=testonly
[gecko.git] / layout / base / Units.h
blobbc6bc866a1aa2591ce1dc0863e7d9ed15cf00f1b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZ_UNITS_H_
8 #define MOZ_UNITS_H_
10 #include <type_traits>
12 #include "mozilla/gfx/Coord.h"
13 #include "mozilla/gfx/Point.h"
14 #include "mozilla/gfx/Rect.h"
15 #include "mozilla/gfx/RectAbsolute.h"
16 #include "mozilla/gfx/ScaleFactor.h"
17 #include "mozilla/gfx/ScaleFactors2D.h"
18 #include "nsMargin.h"
19 #include "nsRect.h"
20 #include "nsRegion.h"
21 #include "mozilla/AppUnits.h"
23 namespace mozilla {
25 template <typename T>
26 struct IsPixel : std::false_type {};
28 // See struct declaration for a description of each unit type.
29 struct CSSPixel;
30 struct LayoutDevicePixel;
31 struct LayerPixel;
32 struct CSSTransformedLayerPixel;
33 struct RenderTargetPixel;
34 struct ScreenPixel;
35 struct ParentLayerPixel;
36 struct DesktopPixel;
37 struct ImagePixel;
39 template <>
40 struct IsPixel<CSSPixel> : std::true_type {};
41 template <>
42 struct IsPixel<LayoutDevicePixel> : std::true_type {};
43 template <>
44 struct IsPixel<LayerPixel> : std::true_type {};
45 template <>
46 struct IsPixel<CSSTransformedLayerPixel> : std::true_type {};
47 template <>
48 struct IsPixel<RenderTargetPixel> : std::true_type {};
49 template <>
50 struct IsPixel<ImagePixel> : std::true_type {};
51 template <>
52 struct IsPixel<ScreenPixel> : std::true_type {};
53 template <>
54 struct IsPixel<ParentLayerPixel> : std::true_type {};
55 template <>
56 struct IsPixel<DesktopPixel> : std::true_type {};
58 typedef gfx::CoordTyped<CSSPixel> CSSCoord;
59 typedef gfx::IntCoordTyped<CSSPixel> CSSIntCoord;
60 typedef gfx::PointTyped<CSSPixel> CSSPoint;
61 typedef gfx::IntPointTyped<CSSPixel> CSSIntPoint;
62 typedef gfx::SizeTyped<CSSPixel> CSSSize;
63 typedef gfx::IntSizeTyped<CSSPixel> CSSIntSize;
64 typedef gfx::RectTyped<CSSPixel> CSSRect;
65 typedef gfx::IntRectTyped<CSSPixel> CSSIntRect;
66 typedef gfx::MarginTyped<CSSPixel> CSSMargin;
67 typedef gfx::IntMarginTyped<CSSPixel> CSSIntMargin;
68 typedef gfx::IntRegionTyped<CSSPixel> CSSIntRegion;
70 typedef gfx::CoordTyped<LayoutDevicePixel> LayoutDeviceCoord;
71 typedef gfx::IntCoordTyped<LayoutDevicePixel> LayoutDeviceIntCoord;
72 typedef gfx::PointTyped<LayoutDevicePixel> LayoutDevicePoint;
73 typedef gfx::IntPointTyped<LayoutDevicePixel> LayoutDeviceIntPoint;
74 typedef gfx::SizeTyped<LayoutDevicePixel> LayoutDeviceSize;
75 typedef gfx::IntSizeTyped<LayoutDevicePixel> LayoutDeviceIntSize;
76 typedef gfx::RectTyped<LayoutDevicePixel> LayoutDeviceRect;
77 typedef gfx::IntRectTyped<LayoutDevicePixel> LayoutDeviceIntRect;
78 typedef gfx::MarginTyped<LayoutDevicePixel> LayoutDeviceMargin;
79 typedef gfx::IntMarginTyped<LayoutDevicePixel> LayoutDeviceIntMargin;
80 typedef gfx::IntRegionTyped<LayoutDevicePixel> LayoutDeviceIntRegion;
82 typedef gfx::CoordTyped<LayerPixel> LayerCoord;
83 typedef gfx::IntCoordTyped<LayerPixel> LayerIntCoord;
84 typedef gfx::PointTyped<LayerPixel> LayerPoint;
85 typedef gfx::IntPointTyped<LayerPixel> LayerIntPoint;
86 typedef gfx::SizeTyped<LayerPixel> LayerSize;
87 typedef gfx::IntSizeTyped<LayerPixel> LayerIntSize;
88 typedef gfx::RectTyped<LayerPixel> LayerRect;
89 typedef gfx::RectAbsoluteTyped<LayerPixel> LayerRectAbsolute;
90 typedef gfx::IntRectTyped<LayerPixel> LayerIntRect;
91 typedef gfx::MarginTyped<LayerPixel> LayerMargin;
92 typedef gfx::IntMarginTyped<LayerPixel> LayerIntMargin;
93 typedef gfx::IntRegionTyped<LayerPixel> LayerIntRegion;
95 typedef gfx::CoordTyped<CSSTransformedLayerPixel> CSSTransformedLayerCoord;
96 typedef gfx::IntCoordTyped<CSSTransformedLayerPixel>
97 CSSTransformedLayerIntCoord;
98 typedef gfx::PointTyped<CSSTransformedLayerPixel> CSSTransformedLayerPoint;
99 typedef gfx::IntPointTyped<CSSTransformedLayerPixel>
100 CSSTransformedLayerIntPoint;
101 typedef gfx::SizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerSize;
102 typedef gfx::IntSizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntSize;
103 typedef gfx::RectTyped<CSSTransformedLayerPixel> CSSTransformedLayerRect;
104 typedef gfx::IntRectTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntRect;
105 typedef gfx::MarginTyped<CSSTransformedLayerPixel> CSSTransformedLayerMargin;
106 typedef gfx::IntMarginTyped<CSSTransformedLayerPixel>
107 CSSTransformedLayerIntMargin;
108 typedef gfx::IntRegionTyped<CSSTransformedLayerPixel>
109 CSSTransformedLayerIntRegion;
111 typedef gfx::PointTyped<RenderTargetPixel> RenderTargetPoint;
112 typedef gfx::IntPointTyped<RenderTargetPixel> RenderTargetIntPoint;
113 typedef gfx::SizeTyped<RenderTargetPixel> RenderTargetSize;
114 typedef gfx::IntSizeTyped<RenderTargetPixel> RenderTargetIntSize;
115 typedef gfx::RectTyped<RenderTargetPixel> RenderTargetRect;
116 typedef gfx::IntRectTyped<RenderTargetPixel> RenderTargetIntRect;
117 typedef gfx::MarginTyped<RenderTargetPixel> RenderTargetMargin;
118 typedef gfx::IntMarginTyped<RenderTargetPixel> RenderTargetIntMargin;
119 typedef gfx::IntRegionTyped<RenderTargetPixel> RenderTargetIntRegion;
121 typedef gfx::IntRectTyped<ImagePixel> ImageIntRect;
123 typedef gfx::CoordTyped<ScreenPixel> ScreenCoord;
124 typedef gfx::IntCoordTyped<ScreenPixel> ScreenIntCoord;
125 typedef gfx::PointTyped<ScreenPixel> ScreenPoint;
126 typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint;
127 typedef gfx::SizeTyped<ScreenPixel> ScreenSize;
128 typedef gfx::IntSizeTyped<ScreenPixel> ScreenIntSize;
129 typedef gfx::RectTyped<ScreenPixel> ScreenRect;
130 typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect;
131 typedef gfx::MarginTyped<ScreenPixel> ScreenMargin;
132 typedef gfx::IntMarginTyped<ScreenPixel> ScreenIntMargin;
133 typedef gfx::IntRegionTyped<ScreenPixel> ScreenIntRegion;
135 typedef gfx::CoordTyped<ParentLayerPixel> ParentLayerCoord;
136 typedef gfx::IntCoordTyped<ParentLayerPixel> ParentLayerIntCoord;
137 typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
138 typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint;
139 typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
140 typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
141 typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
142 typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
143 typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin;
144 typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
145 typedef gfx::IntRegionTyped<ParentLayerPixel> ParentLayerIntRegion;
147 typedef gfx::CoordTyped<DesktopPixel> DesktopCoord;
148 typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord;
149 typedef gfx::PointTyped<DesktopPixel> DesktopPoint;
150 typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint;
151 typedef gfx::SizeTyped<DesktopPixel> DesktopSize;
152 typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize;
153 typedef gfx::RectTyped<DesktopPixel> DesktopRect;
154 typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect;
156 typedef gfx::ScaleFactor<CSSPixel, CSSPixel> CSSToCSSScale;
157 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
158 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
159 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
160 typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
161 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
162 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel>
163 LayoutDeviceToLayerScale;
164 typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel>
165 LayoutDeviceToScreenScale;
166 typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel>
167 LayoutDeviceToParentLayerScale;
168 typedef gfx::ScaleFactor<LayerPixel, CSSPixel> LayerToCSSScale;
169 typedef gfx::ScaleFactor<LayerPixel, LayoutDevicePixel>
170 LayerToLayoutDeviceScale;
171 typedef gfx::ScaleFactor<LayerPixel, RenderTargetPixel>
172 LayerToRenderTargetScale;
173 typedef gfx::ScaleFactor<LayerPixel, ScreenPixel> LayerToScreenScale;
174 typedef gfx::ScaleFactor<LayerPixel, ParentLayerPixel> LayerToParentLayerScale;
175 typedef gfx::ScaleFactor<RenderTargetPixel, ScreenPixel>
176 RenderTargetToScreenScale;
177 typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale;
178 typedef gfx::ScaleFactor<ScreenPixel, LayoutDevicePixel>
179 ScreenToLayoutDeviceScale;
180 typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale;
181 typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel>
182 ScreenToParentLayerScale;
183 typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
184 typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel>
185 ParentLayerToScreenScale;
186 typedef gfx::ScaleFactor<ParentLayerPixel, ParentLayerPixel>
187 ParentLayerToParentLayerScale;
188 typedef gfx::ScaleFactor<DesktopPixel, LayoutDevicePixel>
189 DesktopToLayoutDeviceScale;
191 typedef gfx::ScaleFactors2D<CSSPixel, LayoutDevicePixel>
192 CSSToLayoutDeviceScale2D;
193 typedef gfx::ScaleFactors2D<CSSPixel, LayerPixel> CSSToLayerScale2D;
194 typedef gfx::ScaleFactors2D<CSSPixel, ScreenPixel> CSSToScreenScale2D;
195 typedef gfx::ScaleFactors2D<CSSPixel, ParentLayerPixel> CSSToParentLayerScale2D;
196 typedef gfx::ScaleFactors2D<LayoutDevicePixel, CSSPixel>
197 LayoutDeviceToCSSScale2D;
198 typedef gfx::ScaleFactors2D<LayoutDevicePixel, LayerPixel>
199 LayoutDeviceToLayerScale2D;
200 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ScreenPixel>
201 LayoutDeviceToScreenScale2D;
202 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ParentLayerPixel>
203 LayoutDeviceToParentLayerScale2D;
204 typedef gfx::ScaleFactors2D<LayerPixel, CSSPixel> LayerToCSSScale2D;
205 typedef gfx::ScaleFactors2D<LayerPixel, LayoutDevicePixel>
206 LayerToLayoutDeviceScale2D;
207 typedef gfx::ScaleFactors2D<LayerPixel, RenderTargetPixel>
208 LayerToRenderTargetScale2D;
209 typedef gfx::ScaleFactors2D<LayerPixel, ScreenPixel> LayerToScreenScale2D;
210 typedef gfx::ScaleFactors2D<LayerPixel, ParentLayerPixel>
211 LayerToParentLayerScale2D;
212 typedef gfx::ScaleFactors2D<RenderTargetPixel, ScreenPixel>
213 RenderTargetToScreenScale2D;
214 typedef gfx::ScaleFactors2D<ScreenPixel, CSSPixel> ScreenToCSSScale2D;
215 typedef gfx::ScaleFactors2D<ScreenPixel, LayoutDevicePixel>
216 ScreenToLayoutDeviceScale2D;
217 typedef gfx::ScaleFactors2D<ScreenPixel, LayerPixel> ScreenToLayerScale2D;
218 typedef gfx::ScaleFactors2D<ScreenPixel, ParentLayerPixel>
219 ScreenToParentLayerScale2D;
220 typedef gfx::ScaleFactors2D<ParentLayerPixel, LayerPixel>
221 ParentLayerToLayerScale2D;
222 typedef gfx::ScaleFactors2D<ParentLayerPixel, ScreenPixel>
223 ParentLayerToScreenScale2D;
224 typedef gfx::ScaleFactors2D<ParentLayerPixel, ParentLayerPixel>
225 ParentLayerToParentLayerScale2D;
227 typedef gfx::Matrix4x4Typed<CSSPixel, CSSPixel> CSSToCSSMatrix4x4;
228 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, LayoutDevicePixel>
229 LayoutDeviceToLayoutDeviceMatrix4x4;
230 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, ParentLayerPixel>
231 LayoutDeviceToParentLayerMatrix4x4;
232 typedef gfx::Matrix4x4Typed<LayerPixel, ParentLayerPixel>
233 LayerToParentLayerMatrix4x4;
234 typedef gfx::Matrix4x4Typed<LayerPixel, ScreenPixel> LayerToScreenMatrix4x4;
235 typedef gfx::Matrix4x4Typed<ScreenPixel, ScreenPixel> ScreenToScreenMatrix4x4;
236 typedef gfx::Matrix4x4Typed<ScreenPixel, ParentLayerPixel>
237 ScreenToParentLayerMatrix4x4;
238 typedef gfx::Matrix4x4Typed<ParentLayerPixel, LayerPixel>
239 ParentLayerToLayerMatrix4x4;
240 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ScreenPixel>
241 ParentLayerToScreenMatrix4x4;
242 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ParentLayerPixel>
243 ParentLayerToParentLayerMatrix4x4;
244 typedef gfx::Matrix4x4Typed<ParentLayerPixel, RenderTargetPixel>
245 ParentLayerToRenderTargetMatrix4x4;
248 * The pixels that content authors use to specify sizes in.
250 struct CSSPixel {
251 // Conversions from app units
252 static CSSCoord FromAppUnits(nscoord aCoord) {
253 return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel()));
256 static CSSPoint FromAppUnits(const nsPoint& aPoint) {
257 return CSSPoint(
258 NSAppUnitsToFloatPixels(aPoint.x, float(AppUnitsPerCSSPixel())),
259 NSAppUnitsToFloatPixels(aPoint.y, float(AppUnitsPerCSSPixel())));
262 static CSSSize FromAppUnits(const nsSize& aSize) {
263 return CSSSize(
264 NSAppUnitsToFloatPixels(aSize.width, float(AppUnitsPerCSSPixel())),
265 NSAppUnitsToFloatPixels(aSize.height, float(AppUnitsPerCSSPixel())));
268 static CSSRect FromAppUnits(const nsRect& aRect) {
269 return CSSRect(
270 NSAppUnitsToFloatPixels(aRect.x, float(AppUnitsPerCSSPixel())),
271 NSAppUnitsToFloatPixels(aRect.y, float(AppUnitsPerCSSPixel())),
272 NSAppUnitsToFloatPixels(aRect.Width(), float(AppUnitsPerCSSPixel())),
273 NSAppUnitsToFloatPixels(aRect.Height(), float(AppUnitsPerCSSPixel())));
276 static CSSMargin FromAppUnits(const nsMargin& aMargin) {
277 return CSSMargin(
278 NSAppUnitsToFloatPixels(aMargin.top, float(AppUnitsPerCSSPixel())),
279 NSAppUnitsToFloatPixels(aMargin.right, float(AppUnitsPerCSSPixel())),
280 NSAppUnitsToFloatPixels(aMargin.bottom, float(AppUnitsPerCSSPixel())),
281 NSAppUnitsToFloatPixels(aMargin.left, float(AppUnitsPerCSSPixel())));
284 static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) {
285 return CSSIntPoint(
286 NSAppUnitsToIntPixels(aPoint.x, float(AppUnitsPerCSSPixel())),
287 NSAppUnitsToIntPixels(aPoint.y, float(AppUnitsPerCSSPixel())));
290 static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) {
291 return CSSIntSize(
292 NSAppUnitsToIntPixels(aSize.width, float(AppUnitsPerCSSPixel())),
293 NSAppUnitsToIntPixels(aSize.height, float(AppUnitsPerCSSPixel())));
296 static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) {
297 return CSSIntRect(
298 NSAppUnitsToIntPixels(aRect.x, float(AppUnitsPerCSSPixel())),
299 NSAppUnitsToIntPixels(aRect.y, float(AppUnitsPerCSSPixel())),
300 NSAppUnitsToIntPixels(aRect.Width(), float(AppUnitsPerCSSPixel())),
301 NSAppUnitsToIntPixels(aRect.Height(), float(AppUnitsPerCSSPixel())));
304 static CSSIntRect FromAppUnitsToNearest(const nsRect& aRect) {
305 return CSSIntRect::FromUnknownRect(
306 aRect.ToNearestPixels(AppUnitsPerCSSPixel()));
309 // Conversions to app units
311 static nscoord ToAppUnits(CSSCoord aCoord) {
312 return NSToCoordRoundWithClamp(aCoord * float(AppUnitsPerCSSPixel()));
315 static nsPoint ToAppUnits(const CSSPoint& aPoint) {
316 return nsPoint(
317 NSToCoordRoundWithClamp(aPoint.x * float(AppUnitsPerCSSPixel())),
318 NSToCoordRoundWithClamp(aPoint.y * float(AppUnitsPerCSSPixel())));
321 static nsPoint ToAppUnits(const CSSIntPoint& aPoint) {
322 return nsPoint(
323 NSToCoordRoundWithClamp(float(aPoint.x) * float(AppUnitsPerCSSPixel())),
324 NSToCoordRoundWithClamp(float(aPoint.y) *
325 float(AppUnitsPerCSSPixel())));
328 static nsSize ToAppUnits(const CSSSize& aSize) {
329 return nsSize(
330 NSToCoordRoundWithClamp(aSize.width * float(AppUnitsPerCSSPixel())),
331 NSToCoordRoundWithClamp(aSize.height * float(AppUnitsPerCSSPixel())));
334 static nsSize ToAppUnits(const CSSIntSize& aSize) {
335 return nsSize(NSToCoordRoundWithClamp(float(aSize.width) *
336 float(AppUnitsPerCSSPixel())),
337 NSToCoordRoundWithClamp(float(aSize.height) *
338 float(AppUnitsPerCSSPixel())));
341 static nsRect ToAppUnits(const CSSRect& aRect) {
342 return nsRect(
343 NSToCoordRoundWithClamp(aRect.x * float(AppUnitsPerCSSPixel())),
344 NSToCoordRoundWithClamp(aRect.y * float(AppUnitsPerCSSPixel())),
345 NSToCoordRoundWithClamp(aRect.Width() * float(AppUnitsPerCSSPixel())),
346 NSToCoordRoundWithClamp(aRect.Height() * float(AppUnitsPerCSSPixel())));
349 static nsRect ToAppUnits(const CSSIntRect& aRect) {
350 return nsRect(
351 NSToCoordRoundWithClamp(float(aRect.x) * float(AppUnitsPerCSSPixel())),
352 NSToCoordRoundWithClamp(float(aRect.y) * float(AppUnitsPerCSSPixel())),
353 NSToCoordRoundWithClamp(float(aRect.Width()) *
354 float(AppUnitsPerCSSPixel())),
355 NSToCoordRoundWithClamp(float(aRect.Height()) *
356 float(AppUnitsPerCSSPixel())));
359 // Conversion from a given CSS point value.
360 static CSSCoord FromPoints(float aCoord) {
361 // One inch / 72.
362 return aCoord * 96.0f / 72.0f;
367 * The pixels that are referred to as "device pixels" in layout code. In
368 * general values measured in LayoutDevicePixels are obtained by dividing a
369 * value in app units by AppUnitsPerDevPixel(). Conversion between CSS pixels
370 * and LayoutDevicePixels is affected by:
371 * 1) the "full zoom" (see nsPresContext::SetFullZoom)
372 * 2) the "widget scale" (see nsIWidget::GetDefaultScale)
374 struct LayoutDevicePixel {
375 static LayoutDeviceRect FromAppUnits(const nsRect& aRect,
376 nscoord aAppUnitsPerDevPixel) {
377 return LayoutDeviceRect(
378 NSAppUnitsToFloatPixels(aRect.x, float(aAppUnitsPerDevPixel)),
379 NSAppUnitsToFloatPixels(aRect.y, float(aAppUnitsPerDevPixel)),
380 NSAppUnitsToFloatPixels(aRect.Width(), float(aAppUnitsPerDevPixel)),
381 NSAppUnitsToFloatPixels(aRect.Height(), float(aAppUnitsPerDevPixel)));
384 static LayoutDeviceSize FromAppUnits(const nsSize& aSize,
385 nscoord aAppUnitsPerDevPixel) {
386 return LayoutDeviceSize(
387 NSAppUnitsToFloatPixels(aSize.width, aAppUnitsPerDevPixel),
388 NSAppUnitsToFloatPixels(aSize.height, aAppUnitsPerDevPixel));
391 static LayoutDevicePoint FromAppUnits(const nsPoint& aPoint,
392 nscoord aAppUnitsPerDevPixel) {
393 return LayoutDevicePoint(
394 NSAppUnitsToFloatPixels(aPoint.x, aAppUnitsPerDevPixel),
395 NSAppUnitsToFloatPixels(aPoint.y, aAppUnitsPerDevPixel));
398 static LayoutDeviceMargin FromAppUnits(const nsMargin& aMargin,
399 nscoord aAppUnitsPerDevPixel) {
400 return LayoutDeviceMargin(
401 NSAppUnitsToFloatPixels(aMargin.top, aAppUnitsPerDevPixel),
402 NSAppUnitsToFloatPixels(aMargin.right, aAppUnitsPerDevPixel),
403 NSAppUnitsToFloatPixels(aMargin.bottom, aAppUnitsPerDevPixel),
404 NSAppUnitsToFloatPixels(aMargin.left, aAppUnitsPerDevPixel));
407 static LayoutDeviceIntPoint FromAppUnitsRounded(
408 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
409 return LayoutDeviceIntPoint(
410 NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel),
411 NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel));
414 static LayoutDeviceIntPoint FromAppUnitsToNearest(
415 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
416 return LayoutDeviceIntPoint::FromUnknownPoint(
417 aPoint.ToNearestPixels(aAppUnitsPerDevPixel));
420 static LayoutDeviceIntRect FromAppUnitsToNearest(
421 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
422 return LayoutDeviceIntRect::FromUnknownRect(
423 aRect.ToNearestPixels(aAppUnitsPerDevPixel));
426 static LayoutDeviceIntRect FromAppUnitsToInside(
427 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
428 return LayoutDeviceIntRect::FromUnknownRect(
429 aRect.ToInsidePixels(aAppUnitsPerDevPixel));
432 static LayoutDeviceIntRect FromAppUnitsToOutside(
433 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
434 return LayoutDeviceIntRect::FromUnknownRect(
435 aRect.ToOutsidePixels(aAppUnitsPerDevPixel));
438 static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize,
439 nscoord aAppUnitsPerDevPixel) {
440 return LayoutDeviceIntSize(
441 NSAppUnitsToIntPixels(aSize.width, aAppUnitsPerDevPixel),
442 NSAppUnitsToIntPixels(aSize.height, aAppUnitsPerDevPixel));
445 static nsPoint ToAppUnits(const LayoutDeviceIntPoint& aPoint,
446 nscoord aAppUnitsPerDevPixel) {
447 return nsPoint(aPoint.x * aAppUnitsPerDevPixel,
448 aPoint.y * aAppUnitsPerDevPixel);
451 static nsSize ToAppUnits(const LayoutDeviceIntSize& aSize,
452 nscoord aAppUnitsPerDevPixel) {
453 return nsSize(aSize.width * aAppUnitsPerDevPixel,
454 aSize.height * aAppUnitsPerDevPixel);
457 static nsSize ToAppUnits(const LayoutDeviceSize& aSize,
458 nscoord aAppUnitsPerDevPixel) {
459 return nsSize(NSFloatPixelsToAppUnits(aSize.width, aAppUnitsPerDevPixel),
460 NSFloatPixelsToAppUnits(aSize.height, aAppUnitsPerDevPixel));
463 static nsRect ToAppUnits(const LayoutDeviceIntRect& aRect,
464 nscoord aAppUnitsPerDevPixel) {
465 return nsRect(aRect.x * aAppUnitsPerDevPixel,
466 aRect.y * aAppUnitsPerDevPixel,
467 aRect.Width() * aAppUnitsPerDevPixel,
468 aRect.Height() * aAppUnitsPerDevPixel);
471 static nsRect ToAppUnits(const LayoutDeviceRect& aRect,
472 nscoord aAppUnitsPerDevPixel) {
473 return nsRect(
474 NSFloatPixelsToAppUnits(aRect.x, aAppUnitsPerDevPixel),
475 NSFloatPixelsToAppUnits(aRect.y, aAppUnitsPerDevPixel),
476 NSFloatPixelsToAppUnits(aRect.Width(), aAppUnitsPerDevPixel),
477 NSFloatPixelsToAppUnits(aRect.Height(), aAppUnitsPerDevPixel));
480 static nsMargin ToAppUnits(const LayoutDeviceIntMargin& aMargin,
481 nscoord aAppUnitsPerDevPixel) {
482 return nsMargin(aMargin.top * aAppUnitsPerDevPixel,
483 aMargin.right * aAppUnitsPerDevPixel,
484 aMargin.bottom * aAppUnitsPerDevPixel,
485 aMargin.left * aAppUnitsPerDevPixel);
490 * The pixels that layout rasterizes and delivers to the graphics code.
491 * These also are generally referred to as "device pixels" in layout code.
492 * Conversion between CSS pixels and LayerPixels is affected by:
493 * 1) the "display resolution" (see PresShell::SetResolution)
494 * 2) the "full zoom" (see nsPresContext::SetFullZoom)
495 * 3) the "widget scale" (see nsIWidget::GetDefaultScale)
496 * 4) rasterizing at a different scale in the presence of some CSS transforms
498 struct LayerPixel {};
501 * This is Layer coordinates with the Layer's CSS transform applied.
502 * It can be thought of as intermediate between LayerPixel and
503 * ParentLayerPixel, as further applying async transforms to this
504 * yields ParentLayerPixels.
506 struct CSSTransformedLayerPixel {};
509 * Layers are always composited to a render target. This unit
510 * represents one pixel in the render target. Note that for the
511 * root render target RenderTargetPixel == ScreenPixel. Also
512 * any ContainerLayer providing an intermediate surface will
513 * have RenderTargetPixel == LayerPixel.
515 struct RenderTargetPixel {};
518 * This unit represents one pixel in an image. Image space
519 * is largely independent of any other space.
521 struct ImagePixel {};
524 * The pixels that are displayed on the screen.
525 * On non-OMTC platforms this should be equivalent to LayerPixel units.
526 * On OMTC platforms these may diverge from LayerPixel units temporarily,
527 * while an asynchronous zoom is happening, but should eventually converge
528 * back to LayerPixel units. Some variables (such as those representing
529 * chrome UI element sizes) that are not subject to content zoom should
530 * generally be represented in ScreenPixel units.
532 struct ScreenPixel {};
534 /* The layer coordinates of the parent frame.
535 * This can be arrived at in three ways:
536 * - Start with the CSS coordinates of the parent frame, multiply by the
537 * device scale and the cumulative resolution of the parent frame.
538 * - Start with the CSS coordinates of current frame, multiply by the device
539 * scale, the cumulative resolution of the current frame, and the scales
540 * from the CSS and async transforms of the current frame.
541 * - Start with global screen coordinates and unapply all CSS and async
542 * transforms from the root down to and including the parent.
543 * It's helpful to look at
544 * https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems to get a picture
545 * of how the various coordinate systems relate to each other.
547 struct ParentLayerPixel {};
550 * Pixels in the coordinate space used by the host OS to manage windows on the
551 * desktop. What these mean varies between OSs:
552 * - by default (unless implemented differently in platform-specific widget
553 * code) they are the same as LayoutDevicePixels
554 * - on Mac OS X, they're "cocoa points", which correspond to device pixels
555 * on a non-Retina display, and to 2x device pixels on Retina
556 * - on Windows *without* per-monitor DPI support, they are Windows "logical
557 * pixels", i.e. device pixels scaled according to the Windows display DPI
558 * scaling factor (typically one of 1.25, 1.5, 1.75, 2.0...)
559 * - on Windows *with* per-monitor DPI support, they are physical device pixels
560 * on each screen; note that this means the scaling between CSS pixels and
561 * desktop pixels may vary across multiple displays.
563 struct DesktopPixel {};
565 // Operators to apply ScaleFactors directly to Coords, Points, Rects, Sizes and
566 // Margins
568 template <class src, class dst>
569 gfx::CoordTyped<dst> operator*(const gfx::CoordTyped<src>& aCoord,
570 const gfx::ScaleFactor<src, dst>& aScale) {
571 return gfx::CoordTyped<dst>(aCoord.value * aScale.scale);
574 template <class src, class dst>
575 gfx::CoordTyped<dst> operator/(const gfx::CoordTyped<src>& aCoord,
576 const gfx::ScaleFactor<dst, src>& aScale) {
577 return gfx::CoordTyped<dst>(aCoord.value / aScale.scale);
580 template <class src, class dst>
581 gfx::PointTyped<dst> operator*(const gfx::PointTyped<src>& aPoint,
582 const gfx::ScaleFactor<src, dst>& aScale) {
583 return gfx::PointTyped<dst>(aPoint.x * aScale.scale, aPoint.y * aScale.scale);
586 template <class src, class dst>
587 gfx::PointTyped<dst> operator/(const gfx::PointTyped<src>& aPoint,
588 const gfx::ScaleFactor<dst, src>& aScale) {
589 return gfx::PointTyped<dst>(aPoint.x / aScale.scale, aPoint.y / aScale.scale);
592 template <class src, class dst>
593 gfx::PointTyped<dst> operator*(const gfx::PointTyped<src>& aPoint,
594 const gfx::ScaleFactors2D<src, dst>& aScale) {
595 return gfx::PointTyped<dst>(aPoint.x * aScale.xScale,
596 aPoint.y * aScale.yScale);
599 template <class src, class dst>
600 gfx::PointTyped<dst> operator/(const gfx::PointTyped<src>& aPoint,
601 const gfx::ScaleFactors2D<dst, src>& aScale) {
602 return gfx::PointTyped<dst>(aPoint.x / aScale.xScale,
603 aPoint.y / aScale.yScale);
606 template <class src, class dst>
607 gfx::PointTyped<dst> operator*(const gfx::IntPointTyped<src>& aPoint,
608 const gfx::ScaleFactor<src, dst>& aScale) {
609 return gfx::PointTyped<dst>(float(aPoint.x) * aScale.scale,
610 float(aPoint.y) * aScale.scale);
613 template <class src, class dst>
614 gfx::PointTyped<dst> operator/(const gfx::IntPointTyped<src>& aPoint,
615 const gfx::ScaleFactor<dst, src>& aScale) {
616 return gfx::PointTyped<dst>(float(aPoint.x) / aScale.scale,
617 float(aPoint.y) / aScale.scale);
620 template <class src, class dst>
621 gfx::PointTyped<dst> operator*(const gfx::IntPointTyped<src>& aPoint,
622 const gfx::ScaleFactors2D<src, dst>& aScale) {
623 return gfx::PointTyped<dst>(float(aPoint.x) * aScale.xScale,
624 float(aPoint.y) * aScale.yScale);
627 template <class src, class dst>
628 gfx::PointTyped<dst> operator/(const gfx::IntPointTyped<src>& aPoint,
629 const gfx::ScaleFactors2D<dst, src>& aScale) {
630 return gfx::PointTyped<dst>(float(aPoint.x) / aScale.xScale,
631 float(aPoint.y) / aScale.yScale);
634 template <class src, class dst>
635 gfx::RectTyped<dst> operator*(const gfx::RectTyped<src>& aRect,
636 const gfx::ScaleFactor<src, dst>& aScale) {
637 return gfx::RectTyped<dst>(aRect.x * aScale.scale, aRect.y * aScale.scale,
638 aRect.Width() * aScale.scale,
639 aRect.Height() * aScale.scale);
642 template <class src, class dst>
643 gfx::RectTyped<dst> operator/(const gfx::RectTyped<src>& aRect,
644 const gfx::ScaleFactor<dst, src>& aScale) {
645 return gfx::RectTyped<dst>(aRect.x / aScale.scale, aRect.y / aScale.scale,
646 aRect.Width() / aScale.scale,
647 aRect.Height() / aScale.scale);
650 template <class src, class dst>
651 gfx::RectTyped<dst> operator*(const gfx::RectTyped<src>& aRect,
652 const gfx::ScaleFactors2D<src, dst>& aScale) {
653 return gfx::RectTyped<dst>(aRect.x * aScale.xScale, aRect.y * aScale.yScale,
654 aRect.Width() * aScale.xScale,
655 aRect.Height() * aScale.yScale);
658 template <class src, class dst>
659 gfx::RectTyped<dst> operator/(const gfx::RectTyped<src>& aRect,
660 const gfx::ScaleFactors2D<dst, src>& aScale) {
661 return gfx::RectTyped<dst>(aRect.x / aScale.xScale, aRect.y / aScale.yScale,
662 aRect.Width() / aScale.xScale,
663 aRect.Height() / aScale.yScale);
666 template <class src, class dst>
667 gfx::RectTyped<dst> operator*(const gfx::IntRectTyped<src>& aRect,
668 const gfx::ScaleFactor<src, dst>& aScale) {
669 return gfx::RectTyped<dst>(float(aRect.x) * aScale.scale,
670 float(aRect.y) * aScale.scale,
671 float(aRect.Width()) * aScale.scale,
672 float(aRect.Height()) * aScale.scale);
675 template <class src, class dst>
676 gfx::RectTyped<dst> operator/(const gfx::IntRectTyped<src>& aRect,
677 const gfx::ScaleFactor<dst, src>& aScale) {
678 return gfx::RectTyped<dst>(float(aRect.x) / aScale.scale,
679 float(aRect.y) / aScale.scale,
680 float(aRect.Width()) / aScale.scale,
681 float(aRect.Height()) / aScale.scale);
684 template <class src, class dst>
685 gfx::RectTyped<dst> operator*(const gfx::IntRectTyped<src>& aRect,
686 const gfx::ScaleFactors2D<src, dst>& aScale) {
687 return gfx::RectTyped<dst>(float(aRect.x) * aScale.xScale,
688 float(aRect.y) * aScale.yScale,
689 float(aRect.Width()) * aScale.xScale,
690 float(aRect.Height()) * aScale.yScale);
693 template <class src, class dst>
694 gfx::RectTyped<dst> operator/(const gfx::IntRectTyped<src>& aRect,
695 const gfx::ScaleFactors2D<dst, src>& aScale) {
696 return gfx::RectTyped<dst>(float(aRect.x) / aScale.xScale,
697 float(aRect.y) / aScale.yScale,
698 float(aRect.Width()) / aScale.xScale,
699 float(aRect.Height()) / aScale.yScale);
702 template <class src, class dst>
703 gfx::SizeTyped<dst> operator*(const gfx::SizeTyped<src>& aSize,
704 const gfx::ScaleFactor<src, dst>& aScale) {
705 return gfx::SizeTyped<dst>(aSize.width * aScale.scale,
706 aSize.height * aScale.scale);
709 template <class src, class dst>
710 gfx::SizeTyped<dst> operator/(const gfx::SizeTyped<src>& aSize,
711 const gfx::ScaleFactor<dst, src>& aScale) {
712 return gfx::SizeTyped<dst>(aSize.width / aScale.scale,
713 aSize.height / aScale.scale);
716 template <class src, class dst>
717 gfx::SizeTyped<dst> operator*(const gfx::SizeTyped<src>& aSize,
718 const gfx::ScaleFactors2D<src, dst>& aScale) {
719 return gfx::SizeTyped<dst>(aSize.width * aScale.xScale,
720 aSize.height * aScale.yScale);
723 template <class src, class dst>
724 gfx::SizeTyped<dst> operator/(const gfx::SizeTyped<src>& aSize,
725 const gfx::ScaleFactors2D<dst, src>& aScale) {
726 return gfx::SizeTyped<dst>(aSize.width / aScale.xScale,
727 aSize.height / aScale.yScale);
730 template <class src, class dst>
731 gfx::SizeTyped<dst> operator*(const gfx::IntSizeTyped<src>& aSize,
732 const gfx::ScaleFactor<src, dst>& aScale) {
733 return gfx::SizeTyped<dst>(float(aSize.width) * aScale.scale,
734 float(aSize.height) * aScale.scale);
737 template <class src, class dst>
738 gfx::SizeTyped<dst> operator/(const gfx::IntSizeTyped<src>& aSize,
739 const gfx::ScaleFactor<dst, src>& aScale) {
740 return gfx::SizeTyped<dst>(float(aSize.width) / aScale.scale,
741 float(aSize.height) / aScale.scale);
744 template <class src, class dst>
745 gfx::SizeTyped<dst> operator*(const gfx::IntSizeTyped<src>& aSize,
746 const gfx::ScaleFactors2D<src, dst>& aScale) {
747 return gfx::SizeTyped<dst>(float(aSize.width) * aScale.xScale,
748 float(aSize.height) * aScale.yScale);
751 template <class src, class dst>
752 gfx::SizeTyped<dst> operator/(const gfx::IntSizeTyped<src>& aSize,
753 const gfx::ScaleFactors2D<dst, src>& aScale) {
754 return gfx::SizeTyped<dst>(float(aSize.width) / aScale.xScale,
755 float(aSize.height) / aScale.yScale);
758 template <class src, class dst>
759 gfx::MarginTyped<dst> operator*(const gfx::MarginTyped<src>& aMargin,
760 const gfx::ScaleFactor<src, dst>& aScale) {
761 return gfx::MarginTyped<dst>(
762 aMargin.top * aScale.scale, aMargin.right * aScale.scale,
763 aMargin.bottom * aScale.scale, aMargin.left * aScale.scale);
766 template <class src, class dst>
767 gfx::MarginTyped<dst> operator/(const gfx::MarginTyped<src>& aMargin,
768 const gfx::ScaleFactor<dst, src>& aScale) {
769 return gfx::MarginTyped<dst>(
770 aMargin.top / aScale.scale, aMargin.right / aScale.scale,
771 aMargin.bottom / aScale.scale, aMargin.left / aScale.scale);
774 template <class src, class dst>
775 gfx::MarginTyped<dst> operator*(const gfx::MarginTyped<src>& aMargin,
776 const gfx::ScaleFactors2D<src, dst>& aScale) {
777 return gfx::MarginTyped<dst>(
778 aMargin.top * aScale.yScale, aMargin.right * aScale.xScale,
779 aMargin.bottom * aScale.yScale, aMargin.left * aScale.xScale);
782 template <class src, class dst>
783 gfx::MarginTyped<dst> operator/(const gfx::MarginTyped<src>& aMargin,
784 const gfx::ScaleFactors2D<dst, src>& aScale) {
785 return gfx::MarginTyped<dst>(
786 aMargin.top / aScale.yScale, aMargin.right / aScale.xScale,
787 aMargin.bottom / aScale.yScale, aMargin.left / aScale.xScale);
790 // Calculate the max or min or the ratios of the widths and heights of two
791 // sizes, returning a scale factor in the correct units.
793 template <class src, class dst>
794 gfx::ScaleFactor<src, dst> MaxScaleRatio(const gfx::SizeTyped<dst>& aDestSize,
795 const gfx::SizeTyped<src>& aSrcSize) {
796 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0,
797 "Caller must verify aSrcSize has nonzero components, "
798 "to avoid division by 0 here");
799 return gfx::ScaleFactor<src, dst>(std::max(
800 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height));
803 template <class src, class dst>
804 gfx::ScaleFactor<src, dst> MinScaleRatio(const gfx::SizeTyped<dst>& aDestSize,
805 const gfx::SizeTyped<src>& aSrcSize) {
806 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0,
807 "Caller must verify aSrcSize has nonzero components, "
808 "to avoid division by 0 here");
809 return gfx::ScaleFactor<src, dst>(std::min(
810 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height));
813 template <typename T>
814 struct CoordOfImpl;
816 template <typename Units>
817 struct CoordOfImpl<gfx::PointTyped<Units>> {
818 typedef gfx::CoordTyped<Units> Type;
821 template <typename Units>
822 struct CoordOfImpl<gfx::IntPointTyped<Units>> {
823 typedef gfx::IntCoordTyped<Units> Type;
826 template <typename Units>
827 struct CoordOfImpl<gfx::RectTyped<Units>> {
828 typedef gfx::CoordTyped<Units> Type;
831 template <typename Units>
832 struct CoordOfImpl<gfx::IntRectTyped<Units>> {
833 typedef gfx::IntCoordTyped<Units> Type;
836 template <typename Units>
837 struct CoordOfImpl<gfx::SizeTyped<Units>> {
838 typedef gfx::CoordTyped<Units> Type;
841 template <typename T>
842 using CoordOf = typename CoordOfImpl<T>::Type;
844 } // namespace mozilla
846 #endif