Units.h (43293B)
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/. */ 6 7 #ifndef MOZ_UNITS_H_ 8 #define MOZ_UNITS_H_ 9 10 #include <type_traits> 11 12 #include "mozilla/AppUnits.h" 13 #include "mozilla/gfx/Coord.h" 14 #include "mozilla/gfx/Point.h" 15 #include "mozilla/gfx/Rect.h" 16 #include "mozilla/gfx/RectAbsolute.h" 17 #include "mozilla/gfx/ScaleFactor.h" 18 #include "mozilla/gfx/ScaleFactors2D.h" 19 #include "nsMargin.h" 20 #include "nsRect.h" 21 #include "nsRegion.h" 22 23 namespace mozilla { 24 25 template <typename T> 26 struct IsPixel : std::false_type {}; 27 28 // See struct declaration for a description of each unit type. 29 struct CSSPixel; 30 struct OuterCSSPixel; 31 struct LayoutDevicePixel; 32 struct LayerPixel; 33 struct CSSTransformedLayerPixel; 34 struct RenderTargetPixel; 35 struct ScreenPixel; 36 struct ParentLayerPixel; 37 struct DesktopPixel; 38 struct ImagePixel; 39 struct ExternalPixel; 40 41 template <> 42 struct IsPixel<CSSPixel> : std::true_type {}; 43 template <> 44 struct IsPixel<OuterCSSPixel> : std::true_type {}; 45 template <> 46 struct IsPixel<LayoutDevicePixel> : std::true_type {}; 47 template <> 48 struct IsPixel<LayerPixel> : std::true_type {}; 49 template <> 50 struct IsPixel<CSSTransformedLayerPixel> : std::true_type {}; 51 template <> 52 struct IsPixel<RenderTargetPixel> : std::true_type {}; 53 template <> 54 struct IsPixel<ImagePixel> : std::true_type {}; 55 template <> 56 struct IsPixel<ScreenPixel> : std::true_type {}; 57 template <> 58 struct IsPixel<ParentLayerPixel> : std::true_type {}; 59 template <> 60 struct IsPixel<DesktopPixel> : std::true_type {}; 61 template <> 62 struct IsPixel<ExternalPixel> : std::true_type {}; 63 64 typedef gfx::CoordTyped<CSSPixel> CSSCoord; 65 typedef gfx::IntCoordTyped<CSSPixel> CSSIntCoord; 66 typedef gfx::PointTyped<CSSPixel, double> CSSDoublePoint; 67 typedef gfx::PointTyped<CSSPixel> CSSPoint; 68 typedef gfx::IntPointTyped<CSSPixel> CSSIntPoint; 69 typedef gfx::SizeTyped<CSSPixel> CSSSize; 70 typedef gfx::IntSizeTyped<CSSPixel> CSSIntSize; 71 typedef gfx::RectTyped<CSSPixel> CSSRect; 72 typedef gfx::IntRectTyped<CSSPixel> CSSIntRect; 73 typedef gfx::MarginTyped<CSSPixel> CSSMargin; 74 typedef gfx::IntMarginTyped<CSSPixel> CSSIntMargin; 75 typedef gfx::IntRegionTyped<CSSPixel> CSSIntRegion; 76 77 typedef gfx::CoordTyped<OuterCSSPixel> OuterCSSCoord; 78 typedef gfx::IntCoordTyped<OuterCSSPixel> OuterCSSIntCoord; 79 typedef gfx::PointTyped<OuterCSSPixel> OuterCSSPoint; 80 typedef gfx::IntPointTyped<OuterCSSPixel> OuterCSSIntPoint; 81 typedef gfx::SizeTyped<OuterCSSPixel> OuterCSSSize; 82 typedef gfx::IntSizeTyped<OuterCSSPixel> OuterCSSIntSize; 83 typedef gfx::RectTyped<OuterCSSPixel> OuterCSSRect; 84 typedef gfx::IntRectTyped<OuterCSSPixel> OuterCSSIntRect; 85 typedef gfx::MarginTyped<OuterCSSPixel> OuterCSSMargin; 86 typedef gfx::IntMarginTyped<OuterCSSPixel> OuterCSSIntMargin; 87 typedef gfx::IntRegionTyped<OuterCSSPixel> OuterCSSIntRegion; 88 89 typedef gfx::CoordTyped<LayoutDevicePixel, double> LayoutDeviceDoubleCoord; 90 typedef gfx::CoordTyped<LayoutDevicePixel> LayoutDeviceCoord; 91 typedef gfx::IntCoordTyped<LayoutDevicePixel> LayoutDeviceIntCoord; 92 typedef gfx::PointTyped<LayoutDevicePixel, double> LayoutDeviceDoublePoint; 93 typedef gfx::PointTyped<LayoutDevicePixel> LayoutDevicePoint; 94 typedef gfx::IntPointTyped<LayoutDevicePixel> LayoutDeviceIntPoint; 95 typedef gfx::SizeTyped<LayoutDevicePixel> LayoutDeviceSize; 96 typedef gfx::IntSizeTyped<LayoutDevicePixel> LayoutDeviceIntSize; 97 typedef gfx::RectTyped<LayoutDevicePixel> LayoutDeviceRect; 98 typedef gfx::IntRectTyped<LayoutDevicePixel> LayoutDeviceIntRect; 99 typedef gfx::MarginTyped<LayoutDevicePixel> LayoutDeviceMargin; 100 typedef gfx::IntMarginTyped<LayoutDevicePixel> LayoutDeviceIntMargin; 101 typedef gfx::IntRegionTyped<LayoutDevicePixel> LayoutDeviceIntRegion; 102 103 typedef gfx::CoordTyped<LayerPixel> LayerCoord; 104 typedef gfx::IntCoordTyped<LayerPixel> LayerIntCoord; 105 typedef gfx::PointTyped<LayerPixel> LayerPoint; 106 typedef gfx::IntPointTyped<LayerPixel> LayerIntPoint; 107 typedef gfx::SizeTyped<LayerPixel> LayerSize; 108 typedef gfx::IntSizeTyped<LayerPixel> LayerIntSize; 109 typedef gfx::RectTyped<LayerPixel> LayerRect; 110 typedef gfx::RectAbsoluteTyped<LayerPixel> LayerRectAbsolute; 111 typedef gfx::IntRectTyped<LayerPixel> LayerIntRect; 112 typedef gfx::MarginTyped<LayerPixel> LayerMargin; 113 typedef gfx::IntMarginTyped<LayerPixel> LayerIntMargin; 114 typedef gfx::IntRegionTyped<LayerPixel> LayerIntRegion; 115 116 typedef gfx::CoordTyped<CSSTransformedLayerPixel> CSSTransformedLayerCoord; 117 typedef gfx::IntCoordTyped<CSSTransformedLayerPixel> 118 CSSTransformedLayerIntCoord; 119 typedef gfx::PointTyped<CSSTransformedLayerPixel> CSSTransformedLayerPoint; 120 typedef gfx::IntPointTyped<CSSTransformedLayerPixel> 121 CSSTransformedLayerIntPoint; 122 typedef gfx::SizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerSize; 123 typedef gfx::IntSizeTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntSize; 124 typedef gfx::RectTyped<CSSTransformedLayerPixel> CSSTransformedLayerRect; 125 typedef gfx::IntRectTyped<CSSTransformedLayerPixel> CSSTransformedLayerIntRect; 126 typedef gfx::MarginTyped<CSSTransformedLayerPixel> CSSTransformedLayerMargin; 127 typedef gfx::IntMarginTyped<CSSTransformedLayerPixel> 128 CSSTransformedLayerIntMargin; 129 typedef gfx::IntRegionTyped<CSSTransformedLayerPixel> 130 CSSTransformedLayerIntRegion; 131 132 typedef gfx::PointTyped<RenderTargetPixel> RenderTargetPoint; 133 typedef gfx::IntPointTyped<RenderTargetPixel> RenderTargetIntPoint; 134 typedef gfx::SizeTyped<RenderTargetPixel> RenderTargetSize; 135 typedef gfx::IntSizeTyped<RenderTargetPixel> RenderTargetIntSize; 136 typedef gfx::RectTyped<RenderTargetPixel> RenderTargetRect; 137 typedef gfx::IntRectTyped<RenderTargetPixel> RenderTargetIntRect; 138 typedef gfx::MarginTyped<RenderTargetPixel> RenderTargetMargin; 139 typedef gfx::IntMarginTyped<RenderTargetPixel> RenderTargetIntMargin; 140 typedef gfx::IntRegionTyped<RenderTargetPixel> RenderTargetIntRegion; 141 142 typedef gfx::PointTyped<ImagePixel> ImagePoint; 143 typedef gfx::IntPointTyped<ImagePixel> ImageIntPoint; 144 typedef gfx::SizeTyped<ImagePixel> ImageSize; 145 typedef gfx::IntSizeTyped<ImagePixel> ImageIntSize; 146 typedef gfx::RectTyped<ImagePixel> ImageRect; 147 typedef gfx::IntRectTyped<ImagePixel> ImageIntRect; 148 149 typedef gfx::CoordTyped<ScreenPixel> ScreenCoord; 150 typedef gfx::IntCoordTyped<ScreenPixel> ScreenIntCoord; 151 typedef gfx::PointTyped<ScreenPixel> ScreenPoint; 152 typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint; 153 typedef gfx::SizeTyped<ScreenPixel> ScreenSize; 154 typedef gfx::IntSizeTyped<ScreenPixel> ScreenIntSize; 155 typedef gfx::RectTyped<ScreenPixel> ScreenRect; 156 typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect; 157 typedef gfx::MarginTyped<ScreenPixel> ScreenMargin; 158 typedef gfx::IntMarginTyped<ScreenPixel> ScreenIntMargin; 159 typedef gfx::IntRegionTyped<ScreenPixel> ScreenIntRegion; 160 161 typedef gfx::CoordTyped<ParentLayerPixel> ParentLayerCoord; 162 typedef gfx::IntCoordTyped<ParentLayerPixel> ParentLayerIntCoord; 163 typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint; 164 typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint; 165 typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize; 166 typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize; 167 typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect; 168 typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect; 169 typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin; 170 typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin; 171 typedef gfx::IntRegionTyped<ParentLayerPixel> ParentLayerIntRegion; 172 173 typedef gfx::CoordTyped<DesktopPixel> DesktopCoord; 174 typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord; 175 typedef gfx::PointTyped<DesktopPixel> DesktopPoint; 176 typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint; 177 typedef gfx::SizeTyped<DesktopPixel> DesktopSize; 178 typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize; 179 typedef gfx::RectTyped<DesktopPixel> DesktopRect; 180 typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect; 181 typedef gfx::IntMarginTyped<DesktopPixel> DesktopIntMargin; 182 183 typedef gfx::CoordTyped<ExternalPixel> ExternalCoord; 184 typedef gfx::IntCoordTyped<ExternalPixel> ExternalIntCoord; 185 typedef gfx::PointTyped<ExternalPixel> ExternalPoint; 186 typedef gfx::IntPointTyped<ExternalPixel> ExternalIntPoint; 187 typedef gfx::SizeTyped<ExternalPixel> ExternalSize; 188 typedef gfx::IntSizeTyped<ExternalPixel> ExternalIntSize; 189 typedef gfx::RectTyped<ExternalPixel> ExternalRect; 190 typedef gfx::IntRectTyped<ExternalPixel> ExternalIntRect; 191 typedef gfx::MarginTyped<ExternalPixel> ExternalMargin; 192 typedef gfx::IntMarginTyped<ExternalPixel> ExternalIntMargin; 193 typedef gfx::IntRegionTyped<ExternalPixel> ExternalIntRegion; 194 195 typedef gfx::ScaleFactor<CSSPixel, CSSPixel> CSSToCSSScale; 196 typedef gfx::ScaleFactor<CSSPixel, OuterCSSPixel> CSSToOuterCSSScale; 197 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale; 198 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale; 199 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale; 200 typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale; 201 typedef gfx::ScaleFactor<CSSPixel, DesktopPixel> CSSToDesktopScale; 202 typedef gfx::ScaleFactor<OuterCSSPixel, LayoutDevicePixel> 203 OuterCSSToLayoutDeviceScale; 204 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale; 205 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> 206 LayoutDeviceToLayerScale; 207 typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel> 208 LayoutDeviceToScreenScale; 209 typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> 210 LayoutDeviceToParentLayerScale; 211 typedef gfx::ScaleFactor<LayerPixel, CSSPixel> LayerToCSSScale; 212 typedef gfx::ScaleFactor<LayerPixel, LayoutDevicePixel> 213 LayerToLayoutDeviceScale; 214 typedef gfx::ScaleFactor<LayerPixel, RenderTargetPixel> 215 LayerToRenderTargetScale; 216 typedef gfx::ScaleFactor<LayerPixel, ScreenPixel> LayerToScreenScale; 217 typedef gfx::ScaleFactor<LayerPixel, ParentLayerPixel> LayerToParentLayerScale; 218 typedef gfx::ScaleFactor<RenderTargetPixel, ScreenPixel> 219 RenderTargetToScreenScale; 220 typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale; 221 typedef gfx::ScaleFactor<ScreenPixel, LayoutDevicePixel> 222 ScreenToLayoutDeviceScale; 223 typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale; 224 typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> 225 ScreenToParentLayerScale; 226 typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale; 227 typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> 228 ParentLayerToScreenScale; 229 typedef gfx::ScaleFactor<ParentLayerPixel, ParentLayerPixel> 230 ParentLayerToParentLayerScale; 231 typedef gfx::ScaleFactor<DesktopPixel, LayoutDevicePixel> 232 DesktopToLayoutDeviceScale; 233 typedef gfx::ScaleFactor<LayoutDevicePixel, DesktopPixel> 234 LayoutDeviceToDesktopScale; 235 typedef gfx::ScaleFactor<gfx::UnknownUnits, gfx::UnknownUnits> 236 UnknownScaleFactor; 237 238 typedef gfx::ScaleFactors2D<CSSPixel, LayoutDevicePixel> 239 CSSToLayoutDeviceScale2D; 240 typedef gfx::ScaleFactors2D<CSSPixel, LayerPixel> CSSToLayerScale2D; 241 typedef gfx::ScaleFactors2D<CSSPixel, ScreenPixel> CSSToScreenScale2D; 242 typedef gfx::ScaleFactors2D<CSSPixel, ParentLayerPixel> CSSToParentLayerScale2D; 243 typedef gfx::ScaleFactors2D<LayoutDevicePixel, CSSPixel> 244 LayoutDeviceToCSSScale2D; 245 typedef gfx::ScaleFactors2D<LayoutDevicePixel, LayerPixel> 246 LayoutDeviceToLayerScale2D; 247 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ScreenPixel> 248 LayoutDeviceToScreenScale2D; 249 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ParentLayerPixel> 250 LayoutDeviceToParentLayerScale2D; 251 typedef gfx::ScaleFactors2D<LayerPixel, CSSPixel> LayerToCSSScale2D; 252 typedef gfx::ScaleFactors2D<LayerPixel, LayoutDevicePixel> 253 LayerToLayoutDeviceScale2D; 254 typedef gfx::ScaleFactors2D<LayerPixel, RenderTargetPixel> 255 LayerToRenderTargetScale2D; 256 typedef gfx::ScaleFactors2D<LayerPixel, ScreenPixel> LayerToScreenScale2D; 257 typedef gfx::ScaleFactors2D<LayerPixel, ParentLayerPixel> 258 LayerToParentLayerScale2D; 259 typedef gfx::ScaleFactors2D<RenderTargetPixel, ScreenPixel> 260 RenderTargetToScreenScale2D; 261 typedef gfx::ScaleFactors2D<ScreenPixel, CSSPixel> ScreenToCSSScale2D; 262 typedef gfx::ScaleFactors2D<ScreenPixel, LayoutDevicePixel> 263 ScreenToLayoutDeviceScale2D; 264 typedef gfx::ScaleFactors2D<ScreenPixel, ScreenPixel> ScreenToScreenScale2D; 265 typedef gfx::ScaleFactors2D<ScreenPixel, LayerPixel> ScreenToLayerScale2D; 266 typedef gfx::ScaleFactors2D<ScreenPixel, ParentLayerPixel> 267 ScreenToParentLayerScale2D; 268 typedef gfx::ScaleFactors2D<ParentLayerPixel, LayerPixel> 269 ParentLayerToLayerScale2D; 270 typedef gfx::ScaleFactors2D<ParentLayerPixel, ScreenPixel> 271 ParentLayerToScreenScale2D; 272 typedef gfx::ScaleFactors2D<ParentLayerPixel, ParentLayerPixel> 273 ParentLayerToParentLayerScale2D; 274 typedef gfx::ScaleFactors2D<gfx::UnknownUnits, gfx::UnknownUnits> Scale2D; 275 276 typedef gfx::Matrix4x4Typed<CSSPixel, CSSPixel> CSSToCSSMatrix4x4; 277 typedef gfx::Matrix4x4TypedFlagged<CSSPixel, CSSPixel> CSSToCSSMatrix4x4Flagged; 278 typedef gfx::Matrix4x4TypedFlagged<LayoutDevicePixel, LayoutDevicePixel> 279 LayoutDeviceToLayoutDeviceMatrix4x4Flagged; 280 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, LayoutDevicePixel> 281 LayoutDeviceToLayoutDeviceMatrix4x4; 282 typedef gfx::Matrix4x4Typed<LayoutDevicePixel, ParentLayerPixel> 283 LayoutDeviceToParentLayerMatrix4x4; 284 typedef gfx::Matrix4x4Typed<LayerPixel, ParentLayerPixel> 285 LayerToParentLayerMatrix4x4; 286 typedef gfx::Matrix4x4Typed<LayerPixel, ScreenPixel> LayerToScreenMatrix4x4; 287 typedef gfx::Matrix4x4Typed<ScreenPixel, ScreenPixel> ScreenToScreenMatrix4x4; 288 typedef gfx::Matrix4x4Typed<ScreenPixel, ParentLayerPixel> 289 ScreenToParentLayerMatrix4x4; 290 typedef gfx::Matrix4x4Typed<ParentLayerPixel, LayerPixel> 291 ParentLayerToLayerMatrix4x4; 292 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ScreenPixel> 293 ParentLayerToScreenMatrix4x4; 294 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ParentLayerPixel> 295 ParentLayerToParentLayerMatrix4x4; 296 typedef gfx::Matrix4x4Typed<ParentLayerPixel, RenderTargetPixel> 297 ParentLayerToRenderTargetMatrix4x4; 298 typedef gfx::Matrix4x4Typed<ExternalPixel, ParentLayerPixel> 299 ExternalToParentLayerMatrix4x4; 300 301 /* 302 * The pixels that content authors use to specify sizes in. 303 */ 304 struct CSSPixel { 305 // Conversions from app units 306 static CSSCoord FromAppUnits(nscoord aCoord) { 307 return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel())); 308 } 309 310 static CSSIntCoord FromAppUnitsRounded(nscoord aCoord) { 311 return NSAppUnitsToIntPixels(aCoord, float(AppUnitsPerCSSPixel())); 312 } 313 314 static CSSPoint FromAppUnits(const nsPoint& aPoint) { 315 return CSSPoint(FromAppUnits(aPoint.x), FromAppUnits(aPoint.y)); 316 } 317 318 static CSSSize FromAppUnits(const nsSize& aSize) { 319 return CSSSize(FromAppUnits(aSize.width), FromAppUnits(aSize.height)); 320 } 321 322 static CSSRect FromAppUnits(const nsRect& aRect) { 323 return CSSRect(FromAppUnits(aRect.x), FromAppUnits(aRect.y), 324 FromAppUnits(aRect.Width()), FromAppUnits(aRect.Height())); 325 } 326 327 static CSSMargin FromAppUnits(const nsMargin& aMargin) { 328 return CSSMargin(FromAppUnits(aMargin.top), FromAppUnits(aMargin.right), 329 FromAppUnits(aMargin.bottom), FromAppUnits(aMargin.left)); 330 } 331 332 static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) { 333 return CSSIntPoint(FromAppUnitsRounded(aPoint.x), 334 FromAppUnitsRounded(aPoint.y)); 335 } 336 337 static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) { 338 return CSSIntSize(FromAppUnitsRounded(aSize.width), 339 FromAppUnitsRounded(aSize.height)); 340 } 341 342 static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) { 343 return CSSIntRect(FromAppUnitsRounded(aRect.x), 344 FromAppUnitsRounded(aRect.y), 345 FromAppUnitsRounded(aRect.Width()), 346 FromAppUnitsRounded(aRect.Height())); 347 } 348 349 static CSSIntMargin FromAppUnitsRounded(const nsMargin& aMargin) { 350 return CSSIntMargin( 351 FromAppUnitsRounded(aMargin.top), FromAppUnitsRounded(aMargin.right), 352 FromAppUnitsRounded(aMargin.bottom), FromAppUnitsRounded(aMargin.left)); 353 } 354 355 static CSSIntRect FromAppUnitsToNearest(const nsRect& aRect) { 356 return CSSIntRect::FromUnknownRect( 357 aRect.ToNearestPixels(AppUnitsPerCSSPixel())); 358 } 359 360 static CSSIntRect FromAppUnitsToInside(const nsRect& aRect) { 361 return CSSIntRect::FromUnknownRect( 362 aRect.ToInsidePixels(AppUnitsPerCSSPixel())); 363 } 364 365 // Conversions to app units 366 367 static nscoord ToAppUnits(CSSCoord aCoord) { 368 return NSFloatPixelsToAppUnits(aCoord, AppUnitsPerCSSPixel()); 369 } 370 371 // TODO: We might want an int32_t/CSSIntCoord overload which doesn't do float 372 // math but we'd need to ensure stuff is clamped to nscoord_MIN/MAX range. 373 static nscoord ToAppUnits(CSSIntCoord aCoord) { 374 return ToAppUnits(CSSCoord(aCoord)); 375 } 376 377 static nscoord ToAppUnits(int32_t aCoord) { 378 return ToAppUnits(CSSIntCoord(aCoord)); 379 } 380 381 static nscoord ToAppUnits(float aCoord) { 382 return ToAppUnits(CSSCoord(aCoord)); 383 } 384 385 static nsPoint ToAppUnits(const CSSPoint& aPoint) { 386 return nsPoint(ToAppUnits(aPoint.x), ToAppUnits(aPoint.y)); 387 } 388 389 static nsPoint ToAppUnits(const CSSIntPoint& aPoint) { 390 return nsPoint(ToAppUnits(CSSCoord(aPoint.x)), 391 ToAppUnits(CSSCoord(aPoint.y))); 392 } 393 394 static nsSize ToAppUnits(const CSSSize& aSize) { 395 return nsSize(ToAppUnits(aSize.width), ToAppUnits(aSize.height)); 396 } 397 398 static nsSize ToAppUnits(const CSSIntSize& aSize) { 399 return nsSize(ToAppUnits(aSize.width), ToAppUnits(aSize.height)); 400 } 401 402 static nsRect ToAppUnits(const CSSRect& aRect) { 403 return nsRect(ToAppUnits(aRect.x), ToAppUnits(aRect.y), 404 ToAppUnits(aRect.Width()), ToAppUnits(aRect.Height())); 405 } 406 407 static nsRect ToAppUnits(const CSSIntRect& aRect) { 408 return nsRect(ToAppUnits(aRect.x), ToAppUnits(aRect.y), 409 ToAppUnits(aRect.Width()), ToAppUnits(aRect.Height())); 410 } 411 412 static nsMargin ToAppUnits(const CSSMargin& aMargin) { 413 return nsMargin(ToAppUnits(aMargin.top), ToAppUnits(aMargin.right), 414 ToAppUnits(aMargin.bottom), ToAppUnits(aMargin.left)); 415 } 416 417 static nsMargin ToAppUnits(const CSSIntMargin& aMargin) { 418 return nsMargin(ToAppUnits(aMargin.top), ToAppUnits(aMargin.right), 419 ToAppUnits(aMargin.bottom), ToAppUnits(aMargin.left)); 420 } 421 422 // Conversion from a given CSS point value. 423 static CSSCoord FromPoints(float aCoord) { 424 // One inch / 72. 425 return aCoord * 96.0f / 72.0f; 426 } 427 }; 428 429 /* 430 * In the context of a scroll frame that is zoomable, OuterCSSPixel is 431 * used to disambiguate CSS pixels of the content outside of the scroll 432 * frame (which is not subject to the zoom) from CSS pixels of the content 433 * inside the scroll frame (which is, and for which CSSPixel is used). 434 */ 435 struct OuterCSSPixel { 436 static OuterCSSCoord FromAppUnits(nscoord aCoord) { 437 return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel())); 438 } 439 }; 440 441 /* 442 * The pixels that are referred to as "device pixels" in layout code. In 443 * general values measured in LayoutDevicePixels are obtained by dividing a 444 * value in app units by AppUnitsPerDevPixel(). Conversion between CSS pixels 445 * and LayoutDevicePixels is affected by: 446 * 1) the "full zoom" (see nsPresContext::SetFullZoom) 447 * 2) the "widget scale" (see nsIWidget::GetDefaultScale) 448 */ 449 struct LayoutDevicePixel { 450 static LayoutDeviceCoord FromAppUnits(nscoord aCoord, 451 nscoord aAppUnitsPerDevPixel) { 452 return LayoutDeviceCoord( 453 NSAppUnitsToFloatPixels(aCoord, float(aAppUnitsPerDevPixel))); 454 } 455 456 static LayoutDeviceIntCoord FromAppUnitsRounded( 457 nscoord aCoord, nscoord aAppUnitsPerDevPixel) { 458 return LayoutDeviceIntCoord( 459 NSAppUnitsToIntPixels(aCoord, float(aAppUnitsPerDevPixel))); 460 } 461 462 static LayoutDeviceRect FromAppUnits(const nsRect& aRect, 463 nscoord aAppUnitsPerDevPixel) { 464 return LayoutDeviceRect(FromAppUnits(aRect.x, aAppUnitsPerDevPixel), 465 FromAppUnits(aRect.y, aAppUnitsPerDevPixel), 466 FromAppUnits(aRect.Width(), aAppUnitsPerDevPixel), 467 FromAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); 468 } 469 470 static LayoutDeviceSize FromAppUnits(const nsSize& aSize, 471 nscoord aAppUnitsPerDevPixel) { 472 return LayoutDeviceSize(FromAppUnits(aSize.width, aAppUnitsPerDevPixel), 473 FromAppUnits(aSize.height, aAppUnitsPerDevPixel)); 474 } 475 476 static LayoutDevicePoint FromAppUnits(const nsPoint& aPoint, 477 nscoord aAppUnitsPerDevPixel) { 478 return LayoutDevicePoint(FromAppUnits(aPoint.x, aAppUnitsPerDevPixel), 479 FromAppUnits(aPoint.y, aAppUnitsPerDevPixel)); 480 } 481 482 static LayoutDeviceMargin FromAppUnits(const nsMargin& aMargin, 483 nscoord aAppUnitsPerDevPixel) { 484 return LayoutDeviceMargin( 485 FromAppUnits(aMargin.top, aAppUnitsPerDevPixel), 486 FromAppUnits(aMargin.right, aAppUnitsPerDevPixel), 487 FromAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), 488 FromAppUnits(aMargin.left, aAppUnitsPerDevPixel)); 489 } 490 491 static LayoutDeviceIntPoint FromAppUnitsRounded( 492 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { 493 return LayoutDeviceIntPoint( 494 FromAppUnitsRounded(aPoint.x, aAppUnitsPerDevPixel), 495 FromAppUnitsRounded(aPoint.y, aAppUnitsPerDevPixel)); 496 } 497 498 static LayoutDeviceIntRect FromAppUnitsRounded(const nsRect& aRect, 499 nscoord aAppUnitsPerDevPixel) { 500 return LayoutDeviceIntRect( 501 FromAppUnitsRounded(aRect.x, aAppUnitsPerDevPixel), 502 FromAppUnitsRounded(aRect.y, aAppUnitsPerDevPixel), 503 FromAppUnitsRounded(aRect.Width(), aAppUnitsPerDevPixel), 504 FromAppUnitsRounded(aRect.Height(), aAppUnitsPerDevPixel)); 505 } 506 507 static LayoutDeviceIntPoint FromAppUnitsToNearest( 508 const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { 509 return LayoutDeviceIntPoint::FromUnknownPoint( 510 aPoint.ToNearestPixels(aAppUnitsPerDevPixel)); 511 } 512 513 static LayoutDeviceIntRect FromAppUnitsToNearest( 514 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { 515 return LayoutDeviceIntRect::FromUnknownRect( 516 aRect.ToNearestPixels(aAppUnitsPerDevPixel)); 517 } 518 519 static LayoutDeviceIntRect FromAppUnitsToInside( 520 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { 521 return LayoutDeviceIntRect::FromUnknownRect( 522 aRect.ToInsidePixels(aAppUnitsPerDevPixel)); 523 } 524 525 static LayoutDeviceIntRect FromAppUnitsToOutside( 526 const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { 527 return LayoutDeviceIntRect::FromUnknownRect( 528 aRect.ToOutsidePixels(aAppUnitsPerDevPixel)); 529 } 530 531 static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize, 532 nscoord aAppUnitsPerDevPixel) { 533 return LayoutDeviceIntSize( 534 FromAppUnitsRounded(aSize.width, aAppUnitsPerDevPixel), 535 FromAppUnitsRounded(aSize.height, aAppUnitsPerDevPixel)); 536 } 537 538 static LayoutDeviceIntMargin FromAppUnitsRounded( 539 const nsMargin& aMargin, nscoord aAppUnitsPerDevPixel) { 540 return LayoutDeviceIntMargin( 541 FromAppUnitsRounded(aMargin.top, aAppUnitsPerDevPixel), 542 FromAppUnitsRounded(aMargin.right, aAppUnitsPerDevPixel), 543 FromAppUnitsRounded(aMargin.bottom, aAppUnitsPerDevPixel), 544 FromAppUnitsRounded(aMargin.left, aAppUnitsPerDevPixel)); 545 } 546 547 static nscoord ToAppUnits(LayoutDeviceIntCoord aCoord, 548 nscoord aAppUnitsPerDevPixel) { 549 return aCoord * aAppUnitsPerDevPixel; 550 } 551 552 static nscoord ToAppUnits(int32_t aCoord, nscoord aAppUnitsPerDevPixel) { 553 return ToAppUnits(LayoutDeviceIntCoord(aCoord), aAppUnitsPerDevPixel); 554 } 555 556 static nscoord ToAppUnits(LayoutDeviceCoord aCoord, 557 nscoord aAppUnitsPerDevPixel) { 558 return NSFloatPixelsToAppUnits(aCoord, aAppUnitsPerDevPixel); 559 } 560 561 static nscoord ToAppUnits(float aCoord, nscoord aAppUnitsPerDevPixel) { 562 return ToAppUnits(LayoutDeviceCoord(aCoord), aAppUnitsPerDevPixel); 563 } 564 565 static nscoord ToAppUnits(double aCoord, nscoord aAppUnitsPerDevPixel) { 566 return ToAppUnits(LayoutDeviceDoubleCoord(aCoord), aAppUnitsPerDevPixel); 567 } 568 569 static nscoord ToAppUnits(LayoutDeviceDoubleCoord aCoord, 570 nscoord aAppUnitsPerDevPixel) { 571 return NSDoublePixelsToAppUnits(aCoord, aAppUnitsPerDevPixel); 572 } 573 574 static nsPoint ToAppUnits(const LayoutDeviceIntPoint& aPoint, 575 nscoord aAppUnitsPerDevPixel) { 576 return nsPoint(ToAppUnits(aPoint.x, aAppUnitsPerDevPixel), 577 ToAppUnits(aPoint.y, aAppUnitsPerDevPixel)); 578 } 579 580 static nsPoint ToAppUnits(const LayoutDevicePoint& aPoint, 581 nscoord aAppUnitsPerDevPixel) { 582 return nsPoint(ToAppUnits(aPoint.x, aAppUnitsPerDevPixel), 583 ToAppUnits(aPoint.y, aAppUnitsPerDevPixel)); 584 } 585 586 static nsPoint ToAppUnits(const LayoutDeviceDoublePoint& aPoint, 587 nscoord aAppUnitsPerDevPixel) { 588 return nsPoint(ToAppUnits(aPoint.x, aAppUnitsPerDevPixel), 589 ToAppUnits(aPoint.y, aAppUnitsPerDevPixel)); 590 } 591 592 static nsSize ToAppUnits(const LayoutDeviceIntSize& aSize, 593 nscoord aAppUnitsPerDevPixel) { 594 return nsSize(ToAppUnits(aSize.width, aAppUnitsPerDevPixel), 595 ToAppUnits(aSize.height, aAppUnitsPerDevPixel)); 596 } 597 598 static nsSize ToAppUnits(const LayoutDeviceSize& aSize, 599 nscoord aAppUnitsPerDevPixel) { 600 return nsSize(ToAppUnits(aSize.width, aAppUnitsPerDevPixel), 601 ToAppUnits(aSize.height, aAppUnitsPerDevPixel)); 602 } 603 604 static nsRect ToAppUnits(const LayoutDeviceIntRect& aRect, 605 nscoord aAppUnitsPerDevPixel) { 606 return nsRect(ToAppUnits(aRect.x, aAppUnitsPerDevPixel), 607 ToAppUnits(aRect.y, aAppUnitsPerDevPixel), 608 ToAppUnits(aRect.Width(), aAppUnitsPerDevPixel), 609 ToAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); 610 } 611 612 static nsRect ToAppUnits(const LayoutDeviceRect& aRect, 613 nscoord aAppUnitsPerDevPixel) { 614 return nsRect(ToAppUnits(aRect.x, aAppUnitsPerDevPixel), 615 ToAppUnits(aRect.y, aAppUnitsPerDevPixel), 616 ToAppUnits(aRect.Width(), aAppUnitsPerDevPixel), 617 ToAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); 618 } 619 620 static nsMargin ToAppUnits(const LayoutDeviceIntMargin& aMargin, 621 nscoord aAppUnitsPerDevPixel) { 622 return nsMargin(ToAppUnits(aMargin.top, aAppUnitsPerDevPixel), 623 ToAppUnits(aMargin.right, aAppUnitsPerDevPixel), 624 ToAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), 625 ToAppUnits(aMargin.left, aAppUnitsPerDevPixel)); 626 } 627 628 static nsMargin ToAppUnits(const LayoutDeviceMargin& aMargin, 629 nscoord aAppUnitsPerDevPixel) { 630 return nsMargin(ToAppUnits(aMargin.top, aAppUnitsPerDevPixel), 631 ToAppUnits(aMargin.right, aAppUnitsPerDevPixel), 632 ToAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), 633 ToAppUnits(aMargin.left, aAppUnitsPerDevPixel)); 634 } 635 }; 636 637 /* 638 * The pixels that layout rasterizes and delivers to the graphics code. 639 * These also are generally referred to as "device pixels" in layout code. 640 * Conversion between CSS pixels and LayerPixels is affected by: 641 * 1) the "display resolution" (see PresShell::SetResolution) 642 * 2) the "full zoom" (see nsPresContext::SetFullZoom) 643 * 3) the "widget scale" (see nsIWidget::GetDefaultScale) 644 * 4) rasterizing at a different scale in the presence of some CSS transforms 645 */ 646 struct LayerPixel {}; 647 648 /* 649 * This is Layer coordinates with the Layer's CSS transform applied. 650 * It can be thought of as intermediate between LayerPixel and 651 * ParentLayerPixel, as further applying async transforms to this 652 * yields ParentLayerPixels. 653 */ 654 struct CSSTransformedLayerPixel {}; 655 656 /* 657 * Layers are always composited to a render target. This unit 658 * represents one pixel in the render target. Note that for the 659 * root render target RenderTargetPixel == ScreenPixel. Also 660 * any ContainerLayer providing an intermediate surface will 661 * have RenderTargetPixel == LayerPixel. 662 */ 663 struct RenderTargetPixel {}; 664 665 /* 666 * This unit represents one pixel in an image. Image space 667 * is largely independent of any other space. 668 */ 669 struct ImagePixel {}; 670 671 /* 672 * The pixels that are displayed on the screen. 673 * On non-OMTC platforms this should be equivalent to LayerPixel units. 674 * On OMTC platforms these may diverge from LayerPixel units temporarily, 675 * while an asynchronous zoom is happening, but should eventually converge 676 * back to LayerPixel units. Some variables (such as those representing 677 * chrome UI element sizes) that are not subject to content zoom should 678 * generally be represented in ScreenPixel units. 679 */ 680 struct ScreenPixel {}; 681 682 /* The layer coordinates of the parent frame. 683 * This can be arrived at in three ways: 684 * - Start with the CSS coordinates of the parent frame, multiply by the 685 * device scale and the cumulative resolution of the parent frame. 686 * - Start with the CSS coordinates of current frame, multiply by the device 687 * scale, the cumulative resolution of the current frame, and the scales 688 * from the CSS and async transforms of the current frame. 689 * - Start with global screen coordinates and unapply all CSS and async 690 * transforms from the root down to and including the parent. 691 * It's helpful to look at 692 * https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems to get a picture 693 * of how the various coordinate systems relate to each other. 694 */ 695 struct ParentLayerPixel {}; 696 697 /* 698 * Pixels in the coordinate space used by the host OS to manage windows on the 699 * desktop. What these mean varies between OSs: 700 * - by default (unless implemented differently in platform-specific widget 701 * code) they are the same as LayoutDevicePixels 702 * - on Mac OS X, they're "cocoa points", which correspond to device pixels 703 * on a non-Retina display, and to 2x device pixels on Retina 704 * - on Windows *without* per-monitor DPI support, they are Windows "logical 705 * pixels", i.e. device pixels scaled according to the Windows display DPI 706 * scaling factor (typically one of 1.25, 1.5, 1.75, 2.0...) 707 * - on Windows *with* per-monitor DPI support, they are physical device pixels 708 * on each screen; note that this means the scaling between CSS pixels and 709 * desktop pixels may vary across multiple displays. 710 * - on Linux, they're "Gdk points", which correspond to widget coordinates 711 * used by Gdk and X11 or Wayland compositor and are mapped to actual 712 * screen pixels by per-monitor screen scale. 713 */ 714 struct DesktopPixel {}; 715 716 struct ExternalPixel {}; 717 718 // Operators to apply ScaleFactors directly to Coords, Points, Rects, Sizes and 719 // Margins 720 721 template <class Src, class Dst> 722 gfx::CoordTyped<Dst> operator*(const gfx::CoordTyped<Src>& aCoord, 723 const gfx::ScaleFactor<Src, Dst>& aScale) { 724 return gfx::CoordTyped<Dst>(aCoord.value * aScale.scale); 725 } 726 727 template <class Src, class Dst> 728 gfx::CoordTyped<Dst> operator/(const gfx::CoordTyped<Src>& aCoord, 729 const gfx::ScaleFactor<Dst, Src>& aScale) { 730 return gfx::CoordTyped<Dst>(aCoord.value / aScale.scale); 731 } 732 733 template <class Src, class Dst, class F> 734 gfx::PointTyped<Dst, F> operator*(const gfx::PointTyped<Src, F>& aPoint, 735 const gfx::ScaleFactor<Src, Dst>& aScale) { 736 return gfx::PointTyped<Dst, F>(aPoint.x * aScale.scale, 737 aPoint.y * aScale.scale); 738 } 739 740 template <class Src, class Dst, class F> 741 gfx::PointTyped<Dst, F> operator/(const gfx::PointTyped<Src, F>& aPoint, 742 const gfx::ScaleFactor<Dst, Src>& aScale) { 743 return gfx::PointTyped<Dst, F>(aPoint.x / aScale.scale, 744 aPoint.y / aScale.scale); 745 } 746 747 template <class Src, class Dst, class F> 748 gfx::PointTyped<Dst, F> operator*( 749 const gfx::PointTyped<Src, F>& aPoint, 750 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 751 return gfx::PointTyped<Dst, F>(aPoint.x * aScale.xScale, 752 aPoint.y * aScale.yScale); 753 } 754 755 template <class Src, class Dst, class F> 756 gfx::PointTyped<Dst, F> operator/( 757 const gfx::PointTyped<Src, F>& aPoint, 758 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 759 return gfx::PointTyped<Dst, F>(aPoint.x / aScale.xScale, 760 aPoint.y / aScale.yScale); 761 } 762 763 template <class Src, class Dst> 764 gfx::PointTyped<Dst> operator*(const gfx::IntPointTyped<Src>& aPoint, 765 const gfx::ScaleFactor<Src, Dst>& aScale) { 766 return gfx::PointTyped<Dst>(float(aPoint.x) * aScale.scale, 767 float(aPoint.y) * aScale.scale); 768 } 769 770 template <class Src, class Dst> 771 gfx::PointTyped<Dst> operator/(const gfx::IntPointTyped<Src>& aPoint, 772 const gfx::ScaleFactor<Dst, Src>& aScale) { 773 return gfx::PointTyped<Dst>(float(aPoint.x) / aScale.scale, 774 float(aPoint.y) / aScale.scale); 775 } 776 777 template <class Src, class Dst, class F> 778 gfx::PointTyped<Dst, F> operator*( 779 const gfx::IntPointTyped<Src>& aPoint, 780 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 781 return gfx::PointTyped<Dst, F>(F(aPoint.x) * aScale.xScale, 782 F(aPoint.y) * aScale.yScale); 783 } 784 785 template <class Src, class Dst, class F> 786 gfx::PointTyped<Dst, F> operator/( 787 const gfx::IntPointTyped<Src>& aPoint, 788 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 789 return gfx::PointTyped<Dst, F>(F(aPoint.x) / aScale.xScale, 790 F(aPoint.y) / aScale.yScale); 791 } 792 793 template <class Src, class Dst> 794 gfx::RectTyped<Dst> operator*(const gfx::RectTyped<Src>& aRect, 795 const gfx::ScaleFactor<Src, Dst>& aScale) { 796 return gfx::RectTyped<Dst>(aRect.x * aScale.scale, aRect.y * aScale.scale, 797 aRect.Width() * aScale.scale, 798 aRect.Height() * aScale.scale); 799 } 800 801 template <class Src, class Dst> 802 gfx::RectTyped<Dst> operator/(const gfx::RectTyped<Src>& aRect, 803 const gfx::ScaleFactor<Dst, Src>& aScale) { 804 return gfx::RectTyped<Dst>(aRect.x / aScale.scale, aRect.y / aScale.scale, 805 aRect.Width() / aScale.scale, 806 aRect.Height() / aScale.scale); 807 } 808 809 template <class Src, class Dst, class F> 810 gfx::RectTyped<Dst, F> operator*( 811 const gfx::RectTyped<Src, F>& aRect, 812 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 813 return gfx::RectTyped<Dst, F>( 814 aRect.x * aScale.xScale, aRect.y * aScale.yScale, 815 aRect.Width() * aScale.xScale, aRect.Height() * aScale.yScale); 816 } 817 818 template <class Src, class Dst, class F> 819 gfx::RectTyped<Dst, F> operator/( 820 const gfx::RectTyped<Src, F>& aRect, 821 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 822 return gfx::RectTyped<Dst, F>( 823 aRect.x / aScale.xScale, aRect.y / aScale.yScale, 824 aRect.Width() / aScale.xScale, aRect.Height() / aScale.yScale); 825 } 826 827 template <class Src, class Dst> 828 gfx::RectTyped<Dst> operator*(const gfx::IntRectTyped<Src>& aRect, 829 const gfx::ScaleFactor<Src, Dst>& aScale) { 830 return gfx::RectTyped<Dst>(float(aRect.x) * aScale.scale, 831 float(aRect.y) * aScale.scale, 832 float(aRect.Width()) * aScale.scale, 833 float(aRect.Height()) * aScale.scale); 834 } 835 836 template <class Src, class Dst> 837 gfx::RectTyped<Dst> operator/(const gfx::IntRectTyped<Src>& aRect, 838 const gfx::ScaleFactor<Dst, Src>& aScale) { 839 return gfx::RectTyped<Dst>(float(aRect.x) / aScale.scale, 840 float(aRect.y) / aScale.scale, 841 float(aRect.Width()) / aScale.scale, 842 float(aRect.Height()) / aScale.scale); 843 } 844 845 template <class Src, class Dst, class F> 846 gfx::RectTyped<Dst, F> operator*( 847 const gfx::IntRectTyped<Src>& aRect, 848 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 849 return gfx::RectTyped<Dst, F>( 850 F(aRect.x) * aScale.xScale, F(aRect.y) * aScale.yScale, 851 F(aRect.Width()) * aScale.xScale, F(aRect.Height()) * aScale.yScale); 852 } 853 854 template <class Src, class Dst, class F> 855 gfx::RectTyped<Dst, F> operator/( 856 const gfx::IntRectTyped<Src>& aRect, 857 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 858 return gfx::RectTyped<Dst, F>( 859 F(aRect.x) / aScale.xScale, F(aRect.y) / aScale.yScale, 860 F(aRect.Width()) / aScale.xScale, F(aRect.Height()) / aScale.yScale); 861 } 862 863 template <class Src, class Dst> 864 gfx::SizeTyped<Dst> operator*(const gfx::SizeTyped<Src>& aSize, 865 const gfx::ScaleFactor<Src, Dst>& aScale) { 866 return gfx::SizeTyped<Dst>(aSize.width * aScale.scale, 867 aSize.height * aScale.scale); 868 } 869 870 template <class Src, class Dst> 871 gfx::SizeTyped<Dst> operator/(const gfx::SizeTyped<Src>& aSize, 872 const gfx::ScaleFactor<Dst, Src>& aScale) { 873 return gfx::SizeTyped<Dst>(aSize.width / aScale.scale, 874 aSize.height / aScale.scale); 875 } 876 877 template <class Src, class Dst, class F> 878 gfx::SizeTyped<Dst, F> operator*( 879 const gfx::SizeTyped<Src, F>& aSize, 880 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 881 return gfx::SizeTyped<Dst, F>(aSize.width * aScale.xScale, 882 aSize.height * aScale.yScale); 883 } 884 885 template <class Src, class Dst, class F> 886 gfx::SizeTyped<Dst, F> operator/( 887 const gfx::SizeTyped<Src, F>& aSize, 888 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 889 return gfx::SizeTyped<Dst, F>(aSize.width / aScale.xScale, 890 aSize.height / aScale.yScale); 891 } 892 893 template <class Src, class Dst> 894 gfx::SizeTyped<Dst> operator*(const gfx::IntSizeTyped<Src>& aSize, 895 const gfx::ScaleFactor<Src, Dst>& aScale) { 896 return gfx::SizeTyped<Dst>(float(aSize.width) * aScale.scale, 897 float(aSize.height) * aScale.scale); 898 } 899 900 template <class Src, class Dst> 901 gfx::SizeTyped<Dst> operator/(const gfx::IntSizeTyped<Src>& aSize, 902 const gfx::ScaleFactor<Dst, Src>& aScale) { 903 return gfx::SizeTyped<Dst>(float(aSize.width) / aScale.scale, 904 float(aSize.height) / aScale.scale); 905 } 906 907 template <class Src, class Dst, class F> 908 gfx::SizeTyped<Dst, F> operator*( 909 const gfx::IntSizeTyped<Src>& aSize, 910 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 911 return gfx::SizeTyped<Dst, F>(F(aSize.width) * aScale.xScale, 912 F(aSize.height) * aScale.yScale); 913 } 914 915 template <class Src, class Dst, class F> 916 gfx::SizeTyped<Dst, F> operator/( 917 const gfx::IntSizeTyped<Src>& aSize, 918 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 919 return gfx::SizeTyped<Dst, F>(F(aSize.width) / aScale.xScale, 920 F(aSize.height) / aScale.yScale); 921 } 922 923 template <class Src, class Dst> 924 gfx::MarginTyped<Dst> operator*(const gfx::MarginTyped<Src>& aMargin, 925 const gfx::ScaleFactor<Src, Dst>& aScale) { 926 return gfx::MarginTyped<Dst>( 927 aMargin.top.value * aScale.scale, aMargin.right.value * aScale.scale, 928 aMargin.bottom.value * aScale.scale, aMargin.left.value * aScale.scale); 929 } 930 931 template <class Src, class Dst> 932 gfx::MarginTyped<Dst> operator/(const gfx::MarginTyped<Src>& aMargin, 933 const gfx::ScaleFactor<Dst, Src>& aScale) { 934 return gfx::MarginTyped<Dst>( 935 aMargin.top.value / aScale.scale, aMargin.right.value / aScale.scale, 936 aMargin.bottom.value / aScale.scale, aMargin.left.value / aScale.scale); 937 } 938 939 template <class Src, class Dst, class F> 940 gfx::MarginTyped<Dst, F> operator*( 941 const gfx::MarginTyped<Src, F>& aMargin, 942 const gfx::BaseScaleFactors2D<Src, Dst, F>& aScale) { 943 return gfx::MarginTyped<Dst, F>( 944 aMargin.top.value * aScale.yScale, aMargin.right.value * aScale.xScale, 945 aMargin.bottom.value * aScale.yScale, aMargin.left.value * aScale.xScale); 946 } 947 948 template <class Src, class Dst, class F> 949 gfx::MarginTyped<Dst, F> operator/( 950 const gfx::MarginTyped<Src, F>& aMargin, 951 const gfx::BaseScaleFactors2D<Dst, Src, F>& aScale) { 952 return gfx::MarginTyped<Dst, F>( 953 aMargin.top.value / aScale.yScale, aMargin.right.value / aScale.xScale, 954 aMargin.bottom.value / aScale.yScale, aMargin.left.value / aScale.xScale); 955 } 956 957 template <class Src, class Dst> 958 gfx::MarginTyped<Dst> operator*(const gfx::IntMarginTyped<Src>& aMargin, 959 const gfx::ScaleFactor<Src, Dst>& aScale) { 960 return gfx::MarginTyped<Dst>(float(aMargin.top.value) * aScale.scale, 961 float(aMargin.right.value) * aScale.scale, 962 float(aMargin.bottom.value) * aScale.scale, 963 float(aMargin.left.value) * aScale.scale); 964 } 965 966 // Calculate the max or min or the ratios of the widths and heights of two 967 // sizes, returning a scale factor in the correct units. 968 969 template <class Src, class Dst> 970 gfx::ScaleFactor<Src, Dst> MaxScaleRatio(const gfx::SizeTyped<Dst>& aDestSize, 971 const gfx::SizeTyped<Src>& aSrcSize) { 972 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0, 973 "Caller must verify aSrcSize has nonzero components, " 974 "to avoid division by 0 here"); 975 return gfx::ScaleFactor<Src, Dst>(std::max( 976 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height)); 977 } 978 979 template <class Src, class Dst> 980 gfx::ScaleFactor<Src, Dst> MinScaleRatio(const gfx::SizeTyped<Dst>& aDestSize, 981 const gfx::SizeTyped<Src>& aSrcSize) { 982 MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0, 983 "Caller must verify aSrcSize has nonzero components, " 984 "to avoid division by 0 here"); 985 return gfx::ScaleFactor<Src, Dst>(std::min( 986 aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height)); 987 } 988 989 template <typename T> 990 struct CoordOfImpl; 991 992 template <typename Units> 993 struct CoordOfImpl<gfx::PointTyped<Units>> { 994 typedef gfx::CoordTyped<Units> Type; 995 }; 996 997 template <typename Units> 998 struct CoordOfImpl<gfx::IntPointTyped<Units>> { 999 typedef gfx::IntCoordTyped<Units> Type; 1000 }; 1001 1002 template <typename Units> 1003 struct CoordOfImpl<gfx::RectTyped<Units>> { 1004 typedef gfx::CoordTyped<Units> Type; 1005 }; 1006 1007 template <typename Units> 1008 struct CoordOfImpl<gfx::IntRectTyped<Units>> { 1009 typedef gfx::IntCoordTyped<Units> Type; 1010 }; 1011 1012 template <typename Units> 1013 struct CoordOfImpl<gfx::SizeTyped<Units>> { 1014 typedef gfx::CoordTyped<Units> Type; 1015 }; 1016 1017 template <typename T> 1018 using CoordOf = typename CoordOfImpl<T>::Type; 1019 1020 } // namespace mozilla 1021 1022 #endif