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/. */
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"
21 #include "mozilla/AppUnits.h"
26 struct IsPixel
: std::false_type
{};
28 // See struct declaration for a description of each unit type.
30 struct LayoutDevicePixel
;
32 struct CSSTransformedLayerPixel
;
33 struct RenderTargetPixel
;
35 struct ParentLayerPixel
;
40 struct IsPixel
<CSSPixel
> : std::true_type
{};
42 struct IsPixel
<LayoutDevicePixel
> : std::true_type
{};
44 struct IsPixel
<LayerPixel
> : std::true_type
{};
46 struct IsPixel
<CSSTransformedLayerPixel
> : std::true_type
{};
48 struct IsPixel
<RenderTargetPixel
> : std::true_type
{};
50 struct IsPixel
<ImagePixel
> : std::true_type
{};
52 struct IsPixel
<ScreenPixel
> : std::true_type
{};
54 struct IsPixel
<ParentLayerPixel
> : std::true_type
{};
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.
251 // Conversions from app units
252 static CSSCoord
FromAppUnits(nscoord aCoord
) {
253 return NSAppUnitsToFloatPixels(aCoord
, float(AppUnitsPerCSSPixel()));
256 static CSSPoint
FromAppUnits(const nsPoint
& aPoint
) {
258 NSAppUnitsToFloatPixels(aPoint
.x
, float(AppUnitsPerCSSPixel())),
259 NSAppUnitsToFloatPixels(aPoint
.y
, float(AppUnitsPerCSSPixel())));
262 static CSSSize
FromAppUnits(const nsSize
& aSize
) {
264 NSAppUnitsToFloatPixels(aSize
.width
, float(AppUnitsPerCSSPixel())),
265 NSAppUnitsToFloatPixels(aSize
.height
, float(AppUnitsPerCSSPixel())));
268 static CSSRect
FromAppUnits(const nsRect
& aRect
) {
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
) {
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
) {
286 NSAppUnitsToIntPixels(aPoint
.x
, float(AppUnitsPerCSSPixel())),
287 NSAppUnitsToIntPixels(aPoint
.y
, float(AppUnitsPerCSSPixel())));
290 static CSSIntSize
FromAppUnitsRounded(const nsSize
& aSize
) {
292 NSAppUnitsToIntPixels(aSize
.width
, float(AppUnitsPerCSSPixel())),
293 NSAppUnitsToIntPixels(aSize
.height
, float(AppUnitsPerCSSPixel())));
296 static CSSIntRect
FromAppUnitsRounded(const nsRect
& aRect
) {
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
) {
317 NSToCoordRoundWithClamp(aPoint
.x
* float(AppUnitsPerCSSPixel())),
318 NSToCoordRoundWithClamp(aPoint
.y
* float(AppUnitsPerCSSPixel())));
321 static nsPoint
ToAppUnits(const CSSIntPoint
& aPoint
) {
323 NSToCoordRoundWithClamp(float(aPoint
.x
) * float(AppUnitsPerCSSPixel())),
324 NSToCoordRoundWithClamp(float(aPoint
.y
) *
325 float(AppUnitsPerCSSPixel())));
328 static nsSize
ToAppUnits(const CSSSize
& aSize
) {
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
) {
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
) {
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
) {
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
) {
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
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
>
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