tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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