Bug 1700051: part 33) Move `AdjustSoftBeginAndBuildSoftText` to `SoftText`. r=smaug
[gecko.git] / layout / base / Units.h
blob554f5e5789bf579ac8770be811642c0d4259c45e
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;
38 struct ExternalPixel;
40 template <>
41 struct IsPixel<CSSPixel> : std::true_type {};
42 template <>
43 struct IsPixel<LayoutDevicePixel> : std::true_type {};
44 template <>
45 struct IsPixel<LayerPixel> : std::true_type {};
46 template <>
47 struct IsPixel<CSSTransformedLayerPixel> : std::true_type {};
48 template <>
49 struct IsPixel<RenderTargetPixel> : std::true_type {};
50 template <>
51 struct IsPixel<ImagePixel> : std::true_type {};
52 template <>
53 struct IsPixel<ScreenPixel> : std::true_type {};
54 template <>
55 struct IsPixel<ParentLayerPixel> : std::true_type {};
56 template <>
57 struct IsPixel<DesktopPixel> : std::true_type {};
58 template <>
59 struct IsPixel<ExternalPixel> : std::true_type {};
61 typedef gfx::CoordTyped<CSSPixel> CSSCoord;
62 typedef gfx::IntCoordTyped<CSSPixel> CSSIntCoord;
63 typedef gfx::PointTyped<CSSPixel> CSSPoint;
64 typedef gfx::IntPointTyped<CSSPixel> CSSIntPoint;
65 typedef gfx::SizeTyped<CSSPixel> CSSSize;
66 typedef gfx::IntSizeTyped<CSSPixel> CSSIntSize;
67 typedef gfx::RectTyped<CSSPixel> CSSRect;
68 typedef gfx::IntRectTyped<CSSPixel> CSSIntRect;
69 typedef gfx::MarginTyped<CSSPixel> CSSMargin;
70 typedef gfx::IntMarginTyped<CSSPixel> CSSIntMargin;
71 typedef gfx::IntRegionTyped<CSSPixel> CSSIntRegion;
73 typedef gfx::CoordTyped<LayoutDevicePixel> LayoutDeviceCoord;
74 typedef gfx::IntCoordTyped<LayoutDevicePixel> LayoutDeviceIntCoord;
75 typedef gfx::PointTyped<LayoutDevicePixel> LayoutDevicePoint;
76 typedef gfx::IntPointTyped<LayoutDevicePixel> LayoutDeviceIntPoint;
77 typedef gfx::SizeTyped<LayoutDevicePixel> LayoutDeviceSize;
78 typedef gfx::IntSizeTyped<LayoutDevicePixel> LayoutDeviceIntSize;
79 typedef gfx::RectTyped<LayoutDevicePixel> LayoutDeviceRect;
80 typedef gfx::IntRectTyped<LayoutDevicePixel> LayoutDeviceIntRect;
81 typedef gfx::MarginTyped<LayoutDevicePixel> LayoutDeviceMargin;
82 typedef gfx::IntMarginTyped<LayoutDevicePixel> LayoutDeviceIntMargin;
83 typedef gfx::IntRegionTyped<LayoutDevicePixel> LayoutDeviceIntRegion;
85 typedef gfx::CoordTyped<LayerPixel> LayerCoord;
86 typedef gfx::IntCoordTyped<LayerPixel> LayerIntCoord;
87 typedef gfx::PointTyped<LayerPixel> LayerPoint;
88 typedef gfx::IntPointTyped<LayerPixel> LayerIntPoint;
89 typedef gfx::SizeTyped<LayerPixel> LayerSize;
90 typedef gfx::IntSizeTyped<LayerPixel> LayerIntSize;
91 typedef gfx::RectTyped<LayerPixel> LayerRect;
92 typedef gfx::RectAbsoluteTyped<LayerPixel> LayerRectAbsolute;
93 typedef gfx::IntRectTyped<LayerPixel> LayerIntRect;
94 typedef gfx::MarginTyped<LayerPixel> LayerMargin;
95 typedef gfx::IntMarginTyped<LayerPixel> LayerIntMargin;
96 typedef gfx::IntRegionTyped<LayerPixel> LayerIntRegion;
98 typedef gfx::CoordTyped<CSSTransformedLayerPixel> CSSTransformedLayerCoord;
99 typedef gfx::IntCoordTyped<CSSTransformedLayerPixel>
100 CSSTransformedLayerIntCoord;
101 typedef gfx::PointTyped<CSSTransformedLayerPixel> CSSTransformedLayerPoint;
102 typedef gfx::IntPointTyped<CSSTransformedLayerPixel>
103 CSSTransformedLayerIntPoint;
104 typedef gfx::SizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerSize;
105 typedef gfx::IntSizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntSize;
106 typedef gfx::RectTyped<CSSTransformedLayerPixel> CSSTransformedLayerRect;
107 typedef gfx::IntRectTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntRect;
108 typedef gfx::MarginTyped<CSSTransformedLayerPixel> CSSTransformedLayerMargin;
109 typedef gfx::IntMarginTyped<CSSTransformedLayerPixel>
110 CSSTransformedLayerIntMargin;
111 typedef gfx::IntRegionTyped<CSSTransformedLayerPixel>
112 CSSTransformedLayerIntRegion;
114 typedef gfx::PointTyped<RenderTargetPixel> RenderTargetPoint;
115 typedef gfx::IntPointTyped<RenderTargetPixel> RenderTargetIntPoint;
116 typedef gfx::SizeTyped<RenderTargetPixel> RenderTargetSize;
117 typedef gfx::IntSizeTyped<RenderTargetPixel> RenderTargetIntSize;
118 typedef gfx::RectTyped<RenderTargetPixel> RenderTargetRect;
119 typedef gfx::IntRectTyped<RenderTargetPixel> RenderTargetIntRect;
120 typedef gfx::MarginTyped<RenderTargetPixel> RenderTargetMargin;
121 typedef gfx::IntMarginTyped<RenderTargetPixel> RenderTargetIntMargin;
122 typedef gfx::IntRegionTyped<RenderTargetPixel> RenderTargetIntRegion;
124 typedef gfx::IntRectTyped<ImagePixel> ImageIntRect;
126 typedef gfx::CoordTyped<ScreenPixel> ScreenCoord;
127 typedef gfx::IntCoordTyped<ScreenPixel> ScreenIntCoord;
128 typedef gfx::PointTyped<ScreenPixel> ScreenPoint;
129 typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint;
130 typedef gfx::SizeTyped<ScreenPixel> ScreenSize;
131 typedef gfx::IntSizeTyped<ScreenPixel> ScreenIntSize;
132 typedef gfx::RectTyped<ScreenPixel> ScreenRect;
133 typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect;
134 typedef gfx::MarginTyped<ScreenPixel> ScreenMargin;
135 typedef gfx::IntMarginTyped<ScreenPixel> ScreenIntMargin;
136 typedef gfx::IntRegionTyped<ScreenPixel> ScreenIntRegion;
138 typedef gfx::CoordTyped<ParentLayerPixel> ParentLayerCoord;
139 typedef gfx::IntCoordTyped<ParentLayerPixel> ParentLayerIntCoord;
140 typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
141 typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint;
142 typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
143 typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
144 typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
145 typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
146 typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin;
147 typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
148 typedef gfx::IntRegionTyped<ParentLayerPixel> ParentLayerIntRegion;
150 typedef gfx::CoordTyped<DesktopPixel> DesktopCoord;
151 typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord;
152 typedef gfx::PointTyped<DesktopPixel> DesktopPoint;
153 typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint;
154 typedef gfx::SizeTyped<DesktopPixel> DesktopSize;
155 typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize;
156 typedef gfx::RectTyped<DesktopPixel> DesktopRect;
157 typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect;
159 typedef gfx::CoordTyped<ExternalPixel> ExternalCoord;
160 typedef gfx::IntCoordTyped<ExternalPixel> ExternalIntCoord;
161 typedef gfx::PointTyped<ExternalPixel> ExternalPoint;
162 typedef gfx::IntPointTyped<ExternalPixel> ExternalIntPoint;
163 typedef gfx::SizeTyped<ExternalPixel> ExternalSize;
164 typedef gfx::IntSizeTyped<ExternalPixel> ExternalIntSize;
165 typedef gfx::RectTyped<ExternalPixel> ExternalRect;
166 typedef gfx::IntRectTyped<ExternalPixel> ExternalIntRect;
167 typedef gfx::MarginTyped<ExternalPixel> ExternalMargin;
168 typedef gfx::IntMarginTyped<ExternalPixel> ExternalIntMargin;
169 typedef gfx::IntRegionTyped<ExternalPixel> ExternalIntRegion;
171 typedef gfx::ScaleFactor<CSSPixel, CSSPixel> CSSToCSSScale;
172 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
173 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
174 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
175 typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
176 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
177 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel>
178 LayoutDeviceToLayerScale;
179 typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel>
180 LayoutDeviceToScreenScale;
181 typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel>
182 LayoutDeviceToParentLayerScale;
183 typedef gfx::ScaleFactor<LayerPixel, CSSPixel> LayerToCSSScale;
184 typedef gfx::ScaleFactor<LayerPixel, LayoutDevicePixel>
185 LayerToLayoutDeviceScale;
186 typedef gfx::ScaleFactor<LayerPixel, RenderTargetPixel>
187 LayerToRenderTargetScale;
188 typedef gfx::ScaleFactor<LayerPixel, ScreenPixel> LayerToScreenScale;
189 typedef gfx::ScaleFactor<LayerPixel, ParentLayerPixel> LayerToParentLayerScale;
190 typedef gfx::ScaleFactor<RenderTargetPixel, ScreenPixel>
191 RenderTargetToScreenScale;
192 typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale;
193 typedef gfx::ScaleFactor<ScreenPixel, LayoutDevicePixel>
194 ScreenToLayoutDeviceScale;
195 typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale;
196 typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel>
197 ScreenToParentLayerScale;
198 typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
199 typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel>
200 ParentLayerToScreenScale;
201 typedef gfx::ScaleFactor<ParentLayerPixel, ParentLayerPixel>
202 ParentLayerToParentLayerScale;
203 typedef gfx::ScaleFactor<DesktopPixel, LayoutDevicePixel>
204 DesktopToLayoutDeviceScale;
206 typedef gfx::ScaleFactors2D<CSSPixel, LayoutDevicePixel>
207 CSSToLayoutDeviceScale2D;
208 typedef gfx::ScaleFactors2D<CSSPixel, LayerPixel> CSSToLayerScale2D;
209 typedef gfx::ScaleFactors2D<CSSPixel, ScreenPixel> CSSToScreenScale2D;
210 typedef gfx::ScaleFactors2D<CSSPixel, ParentLayerPixel> CSSToParentLayerScale2D;
211 typedef gfx::ScaleFactors2D<LayoutDevicePixel, CSSPixel>
212 LayoutDeviceToCSSScale2D;
213 typedef gfx::ScaleFactors2D<LayoutDevicePixel, LayerPixel>
214 LayoutDeviceToLayerScale2D;
215 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ScreenPixel>
216 LayoutDeviceToScreenScale2D;
217 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ParentLayerPixel>
218 LayoutDeviceToParentLayerScale2D;
219 typedef gfx::ScaleFactors2D<LayerPixel, CSSPixel> LayerToCSSScale2D;
220 typedef gfx::ScaleFactors2D<LayerPixel, LayoutDevicePixel>
221 LayerToLayoutDeviceScale2D;
222 typedef gfx::ScaleFactors2D<LayerPixel, RenderTargetPixel>
223 LayerToRenderTargetScale2D;
224 typedef gfx::ScaleFactors2D<LayerPixel, ScreenPixel> LayerToScreenScale2D;
225 typedef gfx::ScaleFactors2D<LayerPixel, ParentLayerPixel>
226 LayerToParentLayerScale2D;
227 typedef gfx::ScaleFactors2D<RenderTargetPixel, ScreenPixel>
228 RenderTargetToScreenScale2D;
229 typedef gfx::ScaleFactors2D<ScreenPixel, CSSPixel> ScreenToCSSScale2D;
230 typedef gfx::ScaleFactors2D<ScreenPixel, LayoutDevicePixel>
231 ScreenToLayoutDeviceScale2D;
232 typedef gfx::ScaleFactors2D<ScreenPixel, LayerPixel> ScreenToLayerScale2D;
233 typedef gfx::ScaleFactors2D<ScreenPixel, ParentLayerPixel>
234 ScreenToParentLayerScale2D;
235 typedef gfx::ScaleFactors2D<ParentLayerPixel, LayerPixel>
236 ParentLayerToLayerScale2D;
237 typedef gfx::ScaleFactors2D<ParentLayerPixel, ScreenPixel>
238 ParentLayerToScreenScale2D;
239 typedef gfx::ScaleFactors2D<ParentLayerPixel, ParentLayerPixel>
240 ParentLayerToParentLayerScale2D;
242 typedef gfx::Matrix4x4Typed<CSSPixel, CSSPixel> CSSToCSSMatrix4x4;
243 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, LayoutDevicePixel>
244 LayoutDeviceToLayoutDeviceMatrix4x4;
245 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, ParentLayerPixel>
246 LayoutDeviceToParentLayerMatrix4x4;
247 typedef gfx::Matrix4x4Typed<LayerPixel, ParentLayerPixel>
248 LayerToParentLayerMatrix4x4;
249 typedef gfx::Matrix4x4Typed<LayerPixel, ScreenPixel> LayerToScreenMatrix4x4;
250 typedef gfx::Matrix4x4Typed<ScreenPixel, ScreenPixel> ScreenToScreenMatrix4x4;
251 typedef gfx::Matrix4x4Typed<ScreenPixel, ParentLayerPixel>
252 ScreenToParentLayerMatrix4x4;
253 typedef gfx::Matrix4x4Typed<ParentLayerPixel, LayerPixel>
254 ParentLayerToLayerMatrix4x4;
255 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ScreenPixel>
256 ParentLayerToScreenMatrix4x4;
257 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ParentLayerPixel>
258 ParentLayerToParentLayerMatrix4x4;
259 typedef gfx::Matrix4x4Typed<ParentLayerPixel, RenderTargetPixel>
260 ParentLayerToRenderTargetMatrix4x4;
261 typedef gfx::Matrix4x4Typed<ExternalPixel, ParentLayerPixel>
262 ExternalToParentLayerMatrix4x4;
265 * The pixels that content authors use to specify sizes in.
267 struct CSSPixel {
268 // Conversions from app units
269 static CSSCoord FromAppUnits(nscoord aCoord) {
270 return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel()));
273 static CSSPoint FromAppUnits(const nsPoint& aPoint) {
274 return CSSPoint(
275 NSAppUnitsToFloatPixels(aPoint.x, float(AppUnitsPerCSSPixel())),
276 NSAppUnitsToFloatPixels(aPoint.y, float(AppUnitsPerCSSPixel())));
279 static CSSSize FromAppUnits(const nsSize& aSize) {
280 return CSSSize(
281 NSAppUnitsToFloatPixels(aSize.width, float(AppUnitsPerCSSPixel())),
282 NSAppUnitsToFloatPixels(aSize.height, float(AppUnitsPerCSSPixel())));
285 static CSSRect FromAppUnits(const nsRect& aRect) {
286 return CSSRect(
287 NSAppUnitsToFloatPixels(aRect.x, float(AppUnitsPerCSSPixel())),
288 NSAppUnitsToFloatPixels(aRect.y, float(AppUnitsPerCSSPixel())),
289 NSAppUnitsToFloatPixels(aRect.Width(), float(AppUnitsPerCSSPixel())),
290 NSAppUnitsToFloatPixels(aRect.Height(), float(AppUnitsPerCSSPixel())));
293 static CSSMargin FromAppUnits(const nsMargin& aMargin) {
294 return CSSMargin(
295 NSAppUnitsToFloatPixels(aMargin.top, float(AppUnitsPerCSSPixel())),
296 NSAppUnitsToFloatPixels(aMargin.right, float(AppUnitsPerCSSPixel())),
297 NSAppUnitsToFloatPixels(aMargin.bottom, float(AppUnitsPerCSSPixel())),
298 NSAppUnitsToFloatPixels(aMargin.left, float(AppUnitsPerCSSPixel())));
301 static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) {
302 return CSSIntPoint(
303 NSAppUnitsToIntPixels(aPoint.x, float(AppUnitsPerCSSPixel())),
304 NSAppUnitsToIntPixels(aPoint.y, float(AppUnitsPerCSSPixel())));
307 static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) {
308 return CSSIntSize(
309 NSAppUnitsToIntPixels(aSize.width, float(AppUnitsPerCSSPixel())),
310 NSAppUnitsToIntPixels(aSize.height, float(AppUnitsPerCSSPixel())));
313 static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) {
314 return CSSIntRect(
315 NSAppUnitsToIntPixels(aRect.x, float(AppUnitsPerCSSPixel())),
316 NSAppUnitsToIntPixels(aRect.y, float(AppUnitsPerCSSPixel())),
317 NSAppUnitsToIntPixels(aRect.Width(), float(AppUnitsPerCSSPixel())),
318 NSAppUnitsToIntPixels(aRect.Height(), float(AppUnitsPerCSSPixel())));
321 static CSSIntRect FromAppUnitsToNearest(const nsRect& aRect) {
322 return CSSIntRect::FromUnknownRect(
323 aRect.ToNearestPixels(AppUnitsPerCSSPixel()));
326 // Conversions to app units
328 static nscoord ToAppUnits(CSSCoord aCoord) {
329 return NSToCoordRoundWithClamp(aCoord * float(AppUnitsPerCSSPixel()));
332 static nsPoint ToAppUnits(const CSSPoint& aPoint) {
333 return nsPoint(
334 NSToCoordRoundWithClamp(aPoint.x * float(AppUnitsPerCSSPixel())),
335 NSToCoordRoundWithClamp(aPoint.y * float(AppUnitsPerCSSPixel())));
338 static nsPoint ToAppUnits(const CSSIntPoint& aPoint) {
339 return nsPoint(
340 NSToCoordRoundWithClamp(float(aPoint.x) * float(AppUnitsPerCSSPixel())),
341 NSToCoordRoundWithClamp(float(aPoint.y) *
342 float(AppUnitsPerCSSPixel())));
345 static nsSize ToAppUnits(const CSSSize& aSize) {
346 return nsSize(
347 NSToCoordRoundWithClamp(aSize.width * float(AppUnitsPerCSSPixel())),
348 NSToCoordRoundWithClamp(aSize.height * float(AppUnitsPerCSSPixel())));
351 static nsSize ToAppUnits(const CSSIntSize& aSize) {
352 return nsSize(NSToCoordRoundWithClamp(float(aSize.width) *
353 float(AppUnitsPerCSSPixel())),
354 NSToCoordRoundWithClamp(float(aSize.height) *
355 float(AppUnitsPerCSSPixel())));
358 static nsRect ToAppUnits(const CSSRect& aRect) {
359 return nsRect(
360 NSToCoordRoundWithClamp(aRect.x * float(AppUnitsPerCSSPixel())),
361 NSToCoordRoundWithClamp(aRect.y * float(AppUnitsPerCSSPixel())),
362 NSToCoordRoundWithClamp(aRect.Width() * float(AppUnitsPerCSSPixel())),
363 NSToCoordRoundWithClamp(aRect.Height() * float(AppUnitsPerCSSPixel())));
366 static nsRect ToAppUnits(const CSSIntRect& aRect) {
367 return nsRect(
368 NSToCoordRoundWithClamp(float(aRect.x) * float(AppUnitsPerCSSPixel())),
369 NSToCoordRoundWithClamp(float(aRect.y) * float(AppUnitsPerCSSPixel())),
370 NSToCoordRoundWithClamp(float(aRect.Width()) *
371 float(AppUnitsPerCSSPixel())),
372 NSToCoordRoundWithClamp(float(aRect.Height()) *
373 float(AppUnitsPerCSSPixel())));
376 // Conversion from a given CSS point value.
377 static CSSCoord FromPoints(float aCoord) {
378 // One inch / 72.
379 return aCoord * 96.0f / 72.0f;
384 * The pixels that are referred to as "device pixels" in layout code. In
385 * general values measured in LayoutDevicePixels are obtained by dividing a
386 * value in app units by AppUnitsPerDevPixel(). Conversion between CSS pixels
387 * and LayoutDevicePixels is affected by:
388 * 1) the "full zoom" (see nsPresContext::SetFullZoom)
389 * 2) the "widget scale" (see nsIWidget::GetDefaultScale)
391 struct LayoutDevicePixel {
392 static LayoutDeviceRect FromAppUnits(const nsRect& aRect,
393 nscoord aAppUnitsPerDevPixel) {
394 return LayoutDeviceRect(
395 NSAppUnitsToFloatPixels(aRect.x, float(aAppUnitsPerDevPixel)),
396 NSAppUnitsToFloatPixels(aRect.y, float(aAppUnitsPerDevPixel)),
397 NSAppUnitsToFloatPixels(aRect.Width(), float(aAppUnitsPerDevPixel)),
398 NSAppUnitsToFloatPixels(aRect.Height(), float(aAppUnitsPerDevPixel)));
401 static LayoutDeviceSize FromAppUnits(const nsSize& aSize,
402 nscoord aAppUnitsPerDevPixel) {
403 return LayoutDeviceSize(
404 NSAppUnitsToFloatPixels(aSize.width, aAppUnitsPerDevPixel),
405 NSAppUnitsToFloatPixels(aSize.height, aAppUnitsPerDevPixel));
408 static LayoutDevicePoint FromAppUnits(const nsPoint& aPoint,
409 nscoord aAppUnitsPerDevPixel) {
410 return LayoutDevicePoint(
411 NSAppUnitsToFloatPixels(aPoint.x, aAppUnitsPerDevPixel),
412 NSAppUnitsToFloatPixels(aPoint.y, aAppUnitsPerDevPixel));
415 static LayoutDeviceMargin FromAppUnits(const nsMargin& aMargin,
416 nscoord aAppUnitsPerDevPixel) {
417 return LayoutDeviceMargin(
418 NSAppUnitsToFloatPixels(aMargin.top, aAppUnitsPerDevPixel),
419 NSAppUnitsToFloatPixels(aMargin.right, aAppUnitsPerDevPixel),
420 NSAppUnitsToFloatPixels(aMargin.bottom, aAppUnitsPerDevPixel),
421 NSAppUnitsToFloatPixels(aMargin.left, aAppUnitsPerDevPixel));
424 static LayoutDeviceIntPoint FromAppUnitsRounded(
425 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
426 return LayoutDeviceIntPoint(
427 NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel),
428 NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel));
431 static LayoutDeviceIntPoint FromAppUnitsToNearest(
432 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
433 return LayoutDeviceIntPoint::FromUnknownPoint(
434 aPoint.ToNearestPixels(aAppUnitsPerDevPixel));
437 static LayoutDeviceIntRect FromAppUnitsToNearest(
438 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
439 return LayoutDeviceIntRect::FromUnknownRect(
440 aRect.ToNearestPixels(aAppUnitsPerDevPixel));
443 static LayoutDeviceIntRect FromAppUnitsToInside(
444 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
445 return LayoutDeviceIntRect::FromUnknownRect(
446 aRect.ToInsidePixels(aAppUnitsPerDevPixel));
449 static LayoutDeviceIntRect FromAppUnitsToOutside(
450 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
451 return LayoutDeviceIntRect::FromUnknownRect(
452 aRect.ToOutsidePixels(aAppUnitsPerDevPixel));
455 static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize,
456 nscoord aAppUnitsPerDevPixel) {
457 return LayoutDeviceIntSize(
458 NSAppUnitsToIntPixels(aSize.width, aAppUnitsPerDevPixel),
459 NSAppUnitsToIntPixels(aSize.height, aAppUnitsPerDevPixel));
462 static nsPoint ToAppUnits(const LayoutDeviceIntPoint& aPoint,
463 nscoord aAppUnitsPerDevPixel) {
464 return nsPoint(aPoint.x * aAppUnitsPerDevPixel,
465 aPoint.y * aAppUnitsPerDevPixel);
468 static nsSize ToAppUnits(const LayoutDeviceIntSize& aSize,
469 nscoord aAppUnitsPerDevPixel) {
470 return nsSize(aSize.width * aAppUnitsPerDevPixel,
471 aSize.height * aAppUnitsPerDevPixel);
474 static nsSize ToAppUnits(const LayoutDeviceSize& aSize,
475 nscoord aAppUnitsPerDevPixel) {
476 return nsSize(NSFloatPixelsToAppUnits(aSize.width, aAppUnitsPerDevPixel),
477 NSFloatPixelsToAppUnits(aSize.height, aAppUnitsPerDevPixel));
480 static nsRect ToAppUnits(const LayoutDeviceIntRect& aRect,
481 nscoord aAppUnitsPerDevPixel) {
482 return nsRect(aRect.x * aAppUnitsPerDevPixel,
483 aRect.y * aAppUnitsPerDevPixel,
484 aRect.Width() * aAppUnitsPerDevPixel,
485 aRect.Height() * aAppUnitsPerDevPixel);
488 static nsRect ToAppUnits(const LayoutDeviceRect& aRect,
489 nscoord aAppUnitsPerDevPixel) {
490 return nsRect(
491 NSFloatPixelsToAppUnits(aRect.x, aAppUnitsPerDevPixel),
492 NSFloatPixelsToAppUnits(aRect.y, aAppUnitsPerDevPixel),
493 NSFloatPixelsToAppUnits(aRect.Width(), aAppUnitsPerDevPixel),
494 NSFloatPixelsToAppUnits(aRect.Height(), aAppUnitsPerDevPixel));
497 static nsMargin ToAppUnits(const LayoutDeviceIntMargin& aMargin,
498 nscoord aAppUnitsPerDevPixel) {
499 return nsMargin(aMargin.top * aAppUnitsPerDevPixel,
500 aMargin.right * aAppUnitsPerDevPixel,
501 aMargin.bottom * aAppUnitsPerDevPixel,
502 aMargin.left * aAppUnitsPerDevPixel);
507 * The pixels that layout rasterizes and delivers to the graphics code.
508 * These also are generally referred to as "device pixels" in layout code.
509 * Conversion between CSS pixels and LayerPixels is affected by:
510 * 1) the "display resolution" (see PresShell::SetResolution)
511 * 2) the "full zoom" (see nsPresContext::SetFullZoom)
512 * 3) the "widget scale" (see nsIWidget::GetDefaultScale)
513 * 4) rasterizing at a different scale in the presence of some CSS transforms
515 struct LayerPixel {};
518 * This is Layer coordinates with the Layer's CSS transform applied.
519 * It can be thought of as intermediate between LayerPixel and
520 * ParentLayerPixel, as further applying async transforms to this
521 * yields ParentLayerPixels.
523 struct CSSTransformedLayerPixel {};
526 * Layers are always composited to a render target. This unit
527 * represents one pixel in the render target. Note that for the
528 * root render target RenderTargetPixel == ScreenPixel. Also
529 * any ContainerLayer providing an intermediate surface will
530 * have RenderTargetPixel == LayerPixel.
532 struct RenderTargetPixel {};
535 * This unit represents one pixel in an image. Image space
536 * is largely independent of any other space.
538 struct ImagePixel {};
541 * The pixels that are displayed on the screen.
542 * On non-OMTC platforms this should be equivalent to LayerPixel units.
543 * On OMTC platforms these may diverge from LayerPixel units temporarily,
544 * while an asynchronous zoom is happening, but should eventually converge
545 * back to LayerPixel units. Some variables (such as those representing
546 * chrome UI element sizes) that are not subject to content zoom should
547 * generally be represented in ScreenPixel units.
549 struct ScreenPixel {};
551 /* The layer coordinates of the parent frame.
552 * This can be arrived at in three ways:
553 * - Start with the CSS coordinates of the parent frame, multiply by the
554 * device scale and the cumulative resolution of the parent frame.
555 * - Start with the CSS coordinates of current frame, multiply by the device
556 * scale, the cumulative resolution of the current frame, and the scales
557 * from the CSS and async transforms of the current frame.
558 * - Start with global screen coordinates and unapply all CSS and async
559 * transforms from the root down to and including the parent.
560 * It's helpful to look at
561 * https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems to get a picture
562 * of how the various coordinate systems relate to each other.
564 struct ParentLayerPixel {};
567 * Pixels in the coordinate space used by the host OS to manage windows on the
568 * desktop. What these mean varies between OSs:
569 * - by default (unless implemented differently in platform-specific widget
570 * code) they are the same as LayoutDevicePixels
571 * - on Mac OS X, they're "cocoa points", which correspond to device pixels
572 * on a non-Retina display, and to 2x device pixels on Retina
573 * - on Windows *without* per-monitor DPI support, they are Windows "logical
574 * pixels", i.e. device pixels scaled according to the Windows display DPI
575 * scaling factor (typically one of 1.25, 1.5, 1.75, 2.0...)
576 * - on Windows *with* per-monitor DPI support, they are physical device pixels
577 * on each screen; note that this means the scaling between CSS pixels and
578 * desktop pixels may vary across multiple displays.
580 struct DesktopPixel {};
582 struct ExternalPixel {};
584 // Operators to apply ScaleFactors directly to Coords, Points, Rects, Sizes and
585 // Margins
587 template <class src, class dst>
588 gfx::CoordTyped<dst> operator*(const gfx::CoordTyped<src>& aCoord,
589 const gfx::ScaleFactor<src, dst>& aScale) {
590 return gfx::CoordTyped<dst>(aCoord.value * aScale.scale);
593 template <class src, class dst>
594 gfx::CoordTyped<dst> operator/(const gfx::CoordTyped<src>& aCoord,
595 const gfx::ScaleFactor<dst, src>& aScale) {
596 return gfx::CoordTyped<dst>(aCoord.value / aScale.scale);
599 template <class src, class dst>
600 gfx::PointTyped<dst> operator*(const gfx::PointTyped<src>& aPoint,
601 const gfx::ScaleFactor<src, dst>& aScale) {
602 return gfx::PointTyped<dst>(aPoint.x * aScale.scale, aPoint.y * aScale.scale);
605 template <class src, class dst>
606 gfx::PointTyped<dst> operator/(const gfx::PointTyped<src>& aPoint,
607 const gfx::ScaleFactor<dst, src>& aScale) {
608 return gfx::PointTyped<dst>(aPoint.x / aScale.scale, aPoint.y / aScale.scale);
611 template <class src, class dst>
612 gfx::PointTyped<dst> operator*(const gfx::PointTyped<src>& aPoint,
613 const gfx::ScaleFactors2D<src, dst>& aScale) {
614 return gfx::PointTyped<dst>(aPoint.x * aScale.xScale,
615 aPoint.y * aScale.yScale);
618 template <class src, class dst>
619 gfx::PointTyped<dst> operator/(const gfx::PointTyped<src>& aPoint,
620 const gfx::ScaleFactors2D<dst, src>& aScale) {
621 return gfx::PointTyped<dst>(aPoint.x / aScale.xScale,
622 aPoint.y / aScale.yScale);
625 template <class src, class dst>
626 gfx::PointTyped<dst> operator*(const gfx::IntPointTyped<src>& aPoint,
627 const gfx::ScaleFactor<src, dst>& aScale) {
628 return gfx::PointTyped<dst>(float(aPoint.x) * aScale.scale,
629 float(aPoint.y) * aScale.scale);
632 template <class src, class dst>
633 gfx::PointTyped<dst> operator/(const gfx::IntPointTyped<src>& aPoint,
634 const gfx::ScaleFactor<dst, src>& aScale) {
635 return gfx::PointTyped<dst>(float(aPoint.x) / aScale.scale,
636 float(aPoint.y) / aScale.scale);
639 template <class src, class dst>
640 gfx::PointTyped<dst> operator*(const gfx::IntPointTyped<src>& aPoint,
641 const gfx::ScaleFactors2D<src, dst>& aScale) {
642 return gfx::PointTyped<dst>(float(aPoint.x) * aScale.xScale,
643 float(aPoint.y) * aScale.yScale);
646 template <class src, class dst>
647 gfx::PointTyped<dst> operator/(const gfx::IntPointTyped<src>& aPoint,
648 const gfx::ScaleFactors2D<dst, src>& aScale) {
649 return gfx::PointTyped<dst>(float(aPoint.x) / aScale.xScale,
650 float(aPoint.y) / aScale.yScale);
653 template <class src, class dst>
654 gfx::RectTyped<dst> operator*(const gfx::RectTyped<src>& aRect,
655 const gfx::ScaleFactor<src, dst>& aScale) {
656 return gfx::RectTyped<dst>(aRect.x * aScale.scale, aRect.y * aScale.scale,
657 aRect.Width() * aScale.scale,
658 aRect.Height() * aScale.scale);
661 template <class src, class dst>
662 gfx::RectTyped<dst> operator/(const gfx::RectTyped<src>& aRect,
663 const gfx::ScaleFactor<dst, src>& aScale) {
664 return gfx::RectTyped<dst>(aRect.x / aScale.scale, aRect.y / aScale.scale,
665 aRect.Width() / aScale.scale,
666 aRect.Height() / aScale.scale);
669 template <class src, class dst>
670 gfx::RectTyped<dst> operator*(const gfx::RectTyped<src>& aRect,
671 const gfx::ScaleFactors2D<src, dst>& aScale) {
672 return gfx::RectTyped<dst>(aRect.x * aScale.xScale, aRect.y * aScale.yScale,
673 aRect.Width() * aScale.xScale,
674 aRect.Height() * aScale.yScale);
677 template <class src, class dst>
678 gfx::RectTyped<dst> operator/(const gfx::RectTyped<src>& aRect,
679 const gfx::ScaleFactors2D<dst, src>& aScale) {
680 return gfx::RectTyped<dst>(aRect.x / aScale.xScale, aRect.y / aScale.yScale,
681 aRect.Width() / aScale.xScale,
682 aRect.Height() / aScale.yScale);
685 template <class src, class dst>
686 gfx::RectTyped<dst> operator*(const gfx::IntRectTyped<src>& aRect,
687 const gfx::ScaleFactor<src, dst>& aScale) {
688 return gfx::RectTyped<dst>(float(aRect.x) * aScale.scale,
689 float(aRect.y) * aScale.scale,
690 float(aRect.Width()) * aScale.scale,
691 float(aRect.Height()) * aScale.scale);
694 template <class src, class dst>
695 gfx::RectTyped<dst> operator/(const gfx::IntRectTyped<src>& aRect,
696 const gfx::ScaleFactor<dst, src>& aScale) {
697 return gfx::RectTyped<dst>(float(aRect.x) / aScale.scale,
698 float(aRect.y) / aScale.scale,
699 float(aRect.Width()) / aScale.scale,
700 float(aRect.Height()) / aScale.scale);
703 template <class src, class dst>
704 gfx::RectTyped<dst> operator*(const gfx::IntRectTyped<src>& aRect,
705 const gfx::ScaleFactors2D<src, dst>& aScale) {
706 return gfx::RectTyped<dst>(float(aRect.x) * aScale.xScale,
707 float(aRect.y) * aScale.yScale,
708 float(aRect.Width()) * aScale.xScale,
709 float(aRect.Height()) * aScale.yScale);
712 template <class src, class dst>
713 gfx::RectTyped<dst> operator/(const gfx::IntRectTyped<src>& aRect,
714 const gfx::ScaleFactors2D<dst, src>& aScale) {
715 return gfx::RectTyped<dst>(float(aRect.x) / aScale.xScale,
716 float(aRect.y) / aScale.yScale,
717 float(aRect.Width()) / aScale.xScale,
718 float(aRect.Height()) / aScale.yScale);
721 template <class src, class dst>
722 gfx::SizeTyped<dst> operator*(const gfx::SizeTyped<src>& aSize,
723 const gfx::ScaleFactor<src, dst>& aScale) {
724 return gfx::SizeTyped<dst>(aSize.width * aScale.scale,
725 aSize.height * aScale.scale);
728 template <class src, class dst>
729 gfx::SizeTyped<dst> operator/(const gfx::SizeTyped<src>& aSize,
730 const gfx::ScaleFactor<dst, src>& aScale) {
731 return gfx::SizeTyped<dst>(aSize.width / aScale.scale,
732 aSize.height / aScale.scale);
735 template <class src, class dst>
736 gfx::SizeTyped<dst> operator*(const gfx::SizeTyped<src>& aSize,
737 const gfx::ScaleFactors2D<src, dst>& aScale) {
738 return gfx::SizeTyped<dst>(aSize.width * aScale.xScale,
739 aSize.height * aScale.yScale);
742 template <class src, class dst>
743 gfx::SizeTyped<dst> operator/(const gfx::SizeTyped<src>& aSize,
744 const gfx::ScaleFactors2D<dst, src>& aScale) {
745 return gfx::SizeTyped<dst>(aSize.width / aScale.xScale,
746 aSize.height / aScale.yScale);
749 template <class src, class dst>
750 gfx::SizeTyped<dst> operator*(const gfx::IntSizeTyped<src>& aSize,
751 const gfx::ScaleFactor<src, dst>& aScale) {
752 return gfx::SizeTyped<dst>(float(aSize.width) * aScale.scale,
753 float(aSize.height) * aScale.scale);
756 template <class src, class dst>
757 gfx::SizeTyped<dst> operator/(const gfx::IntSizeTyped<src>& aSize,
758 const gfx::ScaleFactor<dst, src>& aScale) {
759 return gfx::SizeTyped<dst>(float(aSize.width) / aScale.scale,
760 float(aSize.height) / aScale.scale);
763 template <class src, class dst>
764 gfx::SizeTyped<dst> operator*(const gfx::IntSizeTyped<src>& aSize,
765 const gfx::ScaleFactors2D<src, dst>& aScale) {
766 return gfx::SizeTyped<dst>(float(aSize.width) * aScale.xScale,
767 float(aSize.height) * aScale.yScale);
770 template <class src, class dst>
771 gfx::SizeTyped<dst> operator/(const gfx::IntSizeTyped<src>& aSize,
772 const gfx::ScaleFactors2D<dst, src>& aScale) {
773 return gfx::SizeTyped<dst>(float(aSize.width) / aScale.xScale,
774 float(aSize.height) / aScale.yScale);
777 template <class src, class dst>
778 gfx::MarginTyped<dst> operator*(const gfx::MarginTyped<src>& aMargin,
779 const gfx::ScaleFactor<src, dst>& aScale) {
780 return gfx::MarginTyped<dst>(
781 aMargin.top * aScale.scale, aMargin.right * aScale.scale,
782 aMargin.bottom * aScale.scale, aMargin.left * aScale.scale);
785 template <class src, class dst>
786 gfx::MarginTyped<dst> operator/(const gfx::MarginTyped<src>& aMargin,
787 const gfx::ScaleFactor<dst, src>& aScale) {
788 return gfx::MarginTyped<dst>(
789 aMargin.top / aScale.scale, aMargin.right / aScale.scale,
790 aMargin.bottom / aScale.scale, aMargin.left / aScale.scale);
793 template <class src, class dst>
794 gfx::MarginTyped<dst> operator*(const gfx::MarginTyped<src>& aMargin,
795 const gfx::ScaleFactors2D<src, dst>& aScale) {
796 return gfx::MarginTyped<dst>(
797 aMargin.top * aScale.yScale, aMargin.right * aScale.xScale,
798 aMargin.bottom * aScale.yScale, aMargin.left * aScale.xScale);
801 template <class src, class dst>
802 gfx::MarginTyped<dst> operator/(const gfx::MarginTyped<src>& aMargin,
803 const gfx::ScaleFactors2D<dst, src>& aScale) {
804 return gfx::MarginTyped<dst>(
805 aMargin.top / aScale.yScale, aMargin.right / aScale.xScale,
806 aMargin.bottom / aScale.yScale, aMargin.left / aScale.xScale);
809 // Calculate the max or min or the ratios of the widths and heights of two
810 // sizes, returning a scale factor in the correct units.
812 template <class src, class dst>
813 gfx::ScaleFactor<src, dst> MaxScaleRatio(const gfx::SizeTyped<dst>& aDestSize,
814 const gfx::SizeTyped<src>& aSrcSize) {
815 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0,
816 "Caller must verify aSrcSize has nonzero components, "
817 "to avoid division by 0 here");
818 return gfx::ScaleFactor<src, dst>(std::max(
819 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height));
822 template <class src, class dst>
823 gfx::ScaleFactor<src, dst> MinScaleRatio(const gfx::SizeTyped<dst>& aDestSize,
824 const gfx::SizeTyped<src>& aSrcSize) {
825 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0,
826 "Caller must verify aSrcSize has nonzero components, "
827 "to avoid division by 0 here");
828 return gfx::ScaleFactor<src, dst>(std::min(
829 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height));
832 template <typename T>
833 struct CoordOfImpl;
835 template <typename Units>
836 struct CoordOfImpl<gfx::PointTyped<Units>> {
837 typedef gfx::CoordTyped<Units> Type;
840 template <typename Units>
841 struct CoordOfImpl<gfx::IntPointTyped<Units>> {
842 typedef gfx::IntCoordTyped<Units> Type;
845 template <typename Units>
846 struct CoordOfImpl<gfx::RectTyped<Units>> {
847 typedef gfx::CoordTyped<Units> Type;
850 template <typename Units>
851 struct CoordOfImpl<gfx::IntRectTyped<Units>> {
852 typedef gfx::IntCoordTyped<Units> Type;
855 template <typename Units>
856 struct CoordOfImpl<gfx::SizeTyped<Units>> {
857 typedef gfx::CoordTyped<Units> Type;
860 template <typename T>
861 using CoordOf = typename CoordOfImpl<T>::Type;
863 } // namespace mozilla
865 #endif