/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZ_UNITS_H_ #define MOZ_UNITS_H_ #include #include "mozilla/gfx/Coord.h" #include "mozilla/gfx/Point.h" #include "mozilla/gfx/Rect.h" #include "mozilla/gfx/RectAbsolute.h" #include "mozilla/gfx/ScaleFactor.h" #include "mozilla/gfx/ScaleFactors2D.h" #include "nsMargin.h" #include "nsRect.h" #include "nsRegion.h" #include "mozilla/AppUnits.h" namespace mozilla { template struct IsPixel : std::false_type {}; // See struct declaration for a description of each unit type. struct CSSPixel; struct OuterCSSPixel; struct LayoutDevicePixel; struct LayerPixel; struct CSSTransformedLayerPixel; struct RenderTargetPixel; struct ScreenPixel; struct ParentLayerPixel; struct DesktopPixel; struct ImagePixel; struct ExternalPixel; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; template <> struct IsPixel : std::true_type {}; typedef gfx::CoordTyped CSSCoord; typedef gfx::IntCoordTyped CSSIntCoord; typedef gfx::PointTyped CSSPoint; typedef gfx::IntPointTyped CSSIntPoint; typedef gfx::SizeTyped CSSSize; typedef gfx::IntSizeTyped CSSIntSize; typedef gfx::RectTyped CSSRect; typedef gfx::IntRectTyped CSSIntRect; typedef gfx::MarginTyped CSSMargin; typedef gfx::IntMarginTyped CSSIntMargin; typedef gfx::IntRegionTyped CSSIntRegion; typedef gfx::CoordTyped OuterCSSCoord; typedef gfx::IntCoordTyped OuterCSSIntCoord; typedef gfx::PointTyped OuterCSSPoint; typedef gfx::IntPointTyped OuterCSSIntPoint; typedef gfx::SizeTyped OuterCSSSize; typedef gfx::IntSizeTyped OuterCSSIntSize; typedef gfx::RectTyped OuterCSSRect; typedef gfx::IntRectTyped OuterCSSIntRect; typedef gfx::MarginTyped OuterCSSMargin; typedef gfx::IntMarginTyped OuterCSSIntMargin; typedef gfx::IntRegionTyped OuterCSSIntRegion; typedef gfx::CoordTyped LayoutDeviceCoord; typedef gfx::IntCoordTyped LayoutDeviceIntCoord; typedef gfx::PointTyped LayoutDevicePoint; typedef gfx::IntPointTyped LayoutDeviceIntPoint; typedef gfx::SizeTyped LayoutDeviceSize; typedef gfx::IntSizeTyped LayoutDeviceIntSize; typedef gfx::RectTyped LayoutDeviceRect; typedef gfx::IntRectTyped LayoutDeviceIntRect; typedef gfx::MarginTyped LayoutDeviceMargin; typedef gfx::IntMarginTyped LayoutDeviceIntMargin; typedef gfx::IntRegionTyped LayoutDeviceIntRegion; typedef gfx::CoordTyped LayerCoord; typedef gfx::IntCoordTyped LayerIntCoord; typedef gfx::PointTyped LayerPoint; typedef gfx::IntPointTyped LayerIntPoint; typedef gfx::SizeTyped LayerSize; typedef gfx::IntSizeTyped LayerIntSize; typedef gfx::RectTyped LayerRect; typedef gfx::RectAbsoluteTyped LayerRectAbsolute; typedef gfx::IntRectTyped LayerIntRect; typedef gfx::MarginTyped LayerMargin; typedef gfx::IntMarginTyped LayerIntMargin; typedef gfx::IntRegionTyped LayerIntRegion; typedef gfx::CoordTyped CSSTransformedLayerCoord; typedef gfx::IntCoordTyped CSSTransformedLayerIntCoord; typedef gfx::PointTyped CSSTransformedLayerPoint; typedef gfx::IntPointTyped CSSTransformedLayerIntPoint; typedef gfx::SizeTyped CSSTransformedLayerSize; typedef gfx::IntSizeTyped CSSTransformedLayerIntSize; typedef gfx::RectTyped CSSTransformedLayerRect; typedef gfx::IntRectTyped CSSTransformedLayerIntRect; typedef gfx::MarginTyped CSSTransformedLayerMargin; typedef gfx::IntMarginTyped CSSTransformedLayerIntMargin; typedef gfx::IntRegionTyped CSSTransformedLayerIntRegion; typedef gfx::PointTyped RenderTargetPoint; typedef gfx::IntPointTyped RenderTargetIntPoint; typedef gfx::SizeTyped RenderTargetSize; typedef gfx::IntSizeTyped RenderTargetIntSize; typedef gfx::RectTyped RenderTargetRect; typedef gfx::IntRectTyped RenderTargetIntRect; typedef gfx::MarginTyped RenderTargetMargin; typedef gfx::IntMarginTyped RenderTargetIntMargin; typedef gfx::IntRegionTyped RenderTargetIntRegion; typedef gfx::PointTyped ImagePoint; typedef gfx::IntPointTyped ImageIntPoint; typedef gfx::SizeTyped ImageSize; typedef gfx::IntSizeTyped ImageIntSize; typedef gfx::RectTyped ImageRect; typedef gfx::IntRectTyped ImageIntRect; typedef gfx::CoordTyped ScreenCoord; typedef gfx::IntCoordTyped ScreenIntCoord; typedef gfx::PointTyped ScreenPoint; typedef gfx::IntPointTyped ScreenIntPoint; typedef gfx::SizeTyped ScreenSize; typedef gfx::IntSizeTyped ScreenIntSize; typedef gfx::RectTyped ScreenRect; typedef gfx::IntRectTyped ScreenIntRect; typedef gfx::MarginTyped ScreenMargin; typedef gfx::IntMarginTyped ScreenIntMargin; typedef gfx::IntRegionTyped ScreenIntRegion; typedef gfx::CoordTyped ParentLayerCoord; typedef gfx::IntCoordTyped ParentLayerIntCoord; typedef gfx::PointTyped ParentLayerPoint; typedef gfx::IntPointTyped ParentLayerIntPoint; typedef gfx::SizeTyped ParentLayerSize; typedef gfx::IntSizeTyped ParentLayerIntSize; typedef gfx::RectTyped ParentLayerRect; typedef gfx::IntRectTyped ParentLayerIntRect; typedef gfx::MarginTyped ParentLayerMargin; typedef gfx::IntMarginTyped ParentLayerIntMargin; typedef gfx::IntRegionTyped ParentLayerIntRegion; typedef gfx::CoordTyped DesktopCoord; typedef gfx::IntCoordTyped DesktopIntCoord; typedef gfx::PointTyped DesktopPoint; typedef gfx::IntPointTyped DesktopIntPoint; typedef gfx::SizeTyped DesktopSize; typedef gfx::IntSizeTyped DesktopIntSize; typedef gfx::RectTyped DesktopRect; typedef gfx::IntRectTyped DesktopIntRect; typedef gfx::CoordTyped ExternalCoord; typedef gfx::IntCoordTyped ExternalIntCoord; typedef gfx::PointTyped ExternalPoint; typedef gfx::IntPointTyped ExternalIntPoint; typedef gfx::SizeTyped ExternalSize; typedef gfx::IntSizeTyped ExternalIntSize; typedef gfx::RectTyped ExternalRect; typedef gfx::IntRectTyped ExternalIntRect; typedef gfx::MarginTyped ExternalMargin; typedef gfx::IntMarginTyped ExternalIntMargin; typedef gfx::IntRegionTyped ExternalIntRegion; typedef gfx::ScaleFactor CSSToCSSScale; typedef gfx::ScaleFactor CSSToOuterCSSScale; typedef gfx::ScaleFactor CSSToLayoutDeviceScale; typedef gfx::ScaleFactor CSSToLayerScale; typedef gfx::ScaleFactor CSSToScreenScale; typedef gfx::ScaleFactor CSSToParentLayerScale; typedef gfx::ScaleFactor CSSToDesktopScale; typedef gfx::ScaleFactor OuterCSSToLayoutDeviceScale; typedef gfx::ScaleFactor LayoutDeviceToCSSScale; typedef gfx::ScaleFactor LayoutDeviceToLayerScale; typedef gfx::ScaleFactor LayoutDeviceToScreenScale; typedef gfx::ScaleFactor LayoutDeviceToParentLayerScale; typedef gfx::ScaleFactor LayerToCSSScale; typedef gfx::ScaleFactor LayerToLayoutDeviceScale; typedef gfx::ScaleFactor LayerToRenderTargetScale; typedef gfx::ScaleFactor LayerToScreenScale; typedef gfx::ScaleFactor LayerToParentLayerScale; typedef gfx::ScaleFactor RenderTargetToScreenScale; typedef gfx::ScaleFactor ScreenToCSSScale; typedef gfx::ScaleFactor ScreenToLayoutDeviceScale; typedef gfx::ScaleFactor ScreenToLayerScale; typedef gfx::ScaleFactor ScreenToParentLayerScale; typedef gfx::ScaleFactor ParentLayerToLayerScale; typedef gfx::ScaleFactor ParentLayerToScreenScale; typedef gfx::ScaleFactor ParentLayerToParentLayerScale; typedef gfx::ScaleFactor DesktopToLayoutDeviceScale; typedef gfx::ScaleFactor LayoutDeviceToDesktopScale; typedef gfx::ScaleFactors2D CSSToLayoutDeviceScale2D; typedef gfx::ScaleFactors2D CSSToLayerScale2D; typedef gfx::ScaleFactors2D CSSToScreenScale2D; typedef gfx::ScaleFactors2D CSSToParentLayerScale2D; typedef gfx::ScaleFactors2D LayoutDeviceToCSSScale2D; typedef gfx::ScaleFactors2D LayoutDeviceToLayerScale2D; typedef gfx::ScaleFactors2D LayoutDeviceToScreenScale2D; typedef gfx::ScaleFactors2D LayoutDeviceToParentLayerScale2D; typedef gfx::ScaleFactors2D LayerToCSSScale2D; typedef gfx::ScaleFactors2D LayerToLayoutDeviceScale2D; typedef gfx::ScaleFactors2D LayerToRenderTargetScale2D; typedef gfx::ScaleFactors2D LayerToScreenScale2D; typedef gfx::ScaleFactors2D LayerToParentLayerScale2D; typedef gfx::ScaleFactors2D RenderTargetToScreenScale2D; typedef gfx::ScaleFactors2D ScreenToCSSScale2D; typedef gfx::ScaleFactors2D ScreenToLayoutDeviceScale2D; typedef gfx::ScaleFactors2D ScreenToScreenScale2D; typedef gfx::ScaleFactors2D ScreenToLayerScale2D; typedef gfx::ScaleFactors2D ScreenToParentLayerScale2D; typedef gfx::ScaleFactors2D ParentLayerToLayerScale2D; typedef gfx::ScaleFactors2D ParentLayerToScreenScale2D; typedef gfx::ScaleFactors2D ParentLayerToParentLayerScale2D; typedef gfx::ScaleFactors2D Scale2D; typedef gfx::Matrix4x4Typed CSSToCSSMatrix4x4; typedef gfx::Matrix4x4Typed LayoutDeviceToLayoutDeviceMatrix4x4; typedef gfx::Matrix4x4Typed LayoutDeviceToParentLayerMatrix4x4; typedef gfx::Matrix4x4Typed LayerToParentLayerMatrix4x4; typedef gfx::Matrix4x4Typed LayerToScreenMatrix4x4; typedef gfx::Matrix4x4Typed ScreenToScreenMatrix4x4; typedef gfx::Matrix4x4Typed ScreenToParentLayerMatrix4x4; typedef gfx::Matrix4x4Typed ParentLayerToLayerMatrix4x4; typedef gfx::Matrix4x4Typed ParentLayerToScreenMatrix4x4; typedef gfx::Matrix4x4Typed ParentLayerToParentLayerMatrix4x4; typedef gfx::Matrix4x4Typed ParentLayerToRenderTargetMatrix4x4; typedef gfx::Matrix4x4Typed ExternalToParentLayerMatrix4x4; /* * The pixels that content authors use to specify sizes in. */ struct CSSPixel { // Conversions from app units static CSSCoord FromAppUnits(nscoord aCoord) { return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel())); } static CSSIntCoord FromAppUnitsRounded(nscoord aCoord) { return NSAppUnitsToIntPixels(aCoord, float(AppUnitsPerCSSPixel())); } static CSSPoint FromAppUnits(const nsPoint& aPoint) { return CSSPoint(FromAppUnits(aPoint.x), FromAppUnits(aPoint.y)); } static CSSSize FromAppUnits(const nsSize& aSize) { return CSSSize(FromAppUnits(aSize.width), FromAppUnits(aSize.height)); } static CSSRect FromAppUnits(const nsRect& aRect) { return CSSRect(FromAppUnits(aRect.x), FromAppUnits(aRect.y), FromAppUnits(aRect.Width()), FromAppUnits(aRect.Height())); } static CSSMargin FromAppUnits(const nsMargin& aMargin) { return CSSMargin(FromAppUnits(aMargin.top), FromAppUnits(aMargin.right), FromAppUnits(aMargin.bottom), FromAppUnits(aMargin.left)); } static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) { return CSSIntPoint(FromAppUnitsRounded(aPoint.x), FromAppUnitsRounded(aPoint.y)); } static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) { return CSSIntSize(FromAppUnitsRounded(aSize.width), FromAppUnitsRounded(aSize.height)); } static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) { return CSSIntRect(FromAppUnitsRounded(aRect.x), FromAppUnitsRounded(aRect.y), FromAppUnitsRounded(aRect.Width()), FromAppUnitsRounded(aRect.Height())); } static CSSIntMargin FromAppUnitsRounded(const nsMargin& aMargin) { return CSSIntMargin( FromAppUnitsRounded(aMargin.top), FromAppUnitsRounded(aMargin.right), FromAppUnitsRounded(aMargin.bottom), FromAppUnitsRounded(aMargin.left)); } static CSSIntRect FromAppUnitsToNearest(const nsRect& aRect) { return CSSIntRect::FromUnknownRect( aRect.ToNearestPixels(AppUnitsPerCSSPixel())); } static CSSIntRect FromAppUnitsToInside(const nsRect& aRect) { return CSSIntRect::FromUnknownRect( aRect.ToInsidePixels(AppUnitsPerCSSPixel())); } // Conversions to app units // TODO: We might want an int32_t/CSSIntCoord overload which doesn't do float // math but we'd need to ensure stuff is clamped to nscoord_MIN/MAX range. static nscoord ToAppUnits(CSSCoord aCoord) { return NSFloatPixelsToAppUnits(aCoord, AppUnitsPerCSSPixel()); } static nsPoint ToAppUnits(const CSSPoint& aPoint) { return nsPoint(ToAppUnits(aPoint.x), ToAppUnits(aPoint.y)); } static nsPoint ToAppUnits(const CSSIntPoint& aPoint) { return nsPoint(ToAppUnits(CSSCoord(aPoint.x)), ToAppUnits(CSSCoord(aPoint.y))); } static nsSize ToAppUnits(const CSSSize& aSize) { return nsSize(ToAppUnits(aSize.width), ToAppUnits(aSize.height)); } static nsSize ToAppUnits(const CSSIntSize& aSize) { return nsSize(ToAppUnits(aSize.width), ToAppUnits(aSize.height)); } static nsRect ToAppUnits(const CSSRect& aRect) { return nsRect(ToAppUnits(aRect.x), ToAppUnits(aRect.y), ToAppUnits(aRect.Width()), ToAppUnits(aRect.Height())); } static nsRect ToAppUnits(const CSSIntRect& aRect) { return nsRect(ToAppUnits(aRect.x), ToAppUnits(aRect.y), ToAppUnits(aRect.Width()), ToAppUnits(aRect.Height())); } static nsMargin ToAppUnits(const CSSMargin& aMargin) { return nsMargin(ToAppUnits(aMargin.top), ToAppUnits(aMargin.right), ToAppUnits(aMargin.bottom), ToAppUnits(aMargin.left)); } static nsMargin ToAppUnits(const CSSIntMargin& aMargin) { return nsMargin(ToAppUnits(CSSCoord(aMargin.top)), ToAppUnits(CSSCoord(aMargin.right)), ToAppUnits(CSSCoord(aMargin.bottom)), ToAppUnits(CSSCoord(aMargin.left))); } // Conversion from a given CSS point value. static CSSCoord FromPoints(float aCoord) { // One inch / 72. return aCoord * 96.0f / 72.0f; } }; /* * In the context of a scroll frame that is zoomable, OuterCSSPixel is * used to disambiguate CSS pixels of the content outside of the scroll * frame (which is not subject to the zoom) from CSS pixels of the content * inside the scroll frame (which is, and for which CSSPixel is used). */ struct OuterCSSPixel { static OuterCSSCoord FromAppUnits(nscoord aCoord) { return NSAppUnitsToFloatPixels(aCoord, float(AppUnitsPerCSSPixel())); } }; /* * The pixels that are referred to as "device pixels" in layout code. In * general values measured in LayoutDevicePixels are obtained by dividing a * value in app units by AppUnitsPerDevPixel(). Conversion between CSS pixels * and LayoutDevicePixels is affected by: * 1) the "full zoom" (see nsPresContext::SetFullZoom) * 2) the "widget scale" (see nsIWidget::GetDefaultScale) */ struct LayoutDevicePixel { static LayoutDeviceCoord FromAppUnits(nscoord aCoord, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceCoord( NSAppUnitsToFloatPixels(aCoord, float(aAppUnitsPerDevPixel))); } static LayoutDeviceIntCoord FromAppUnitsRounded( nscoord aCoord, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntCoord( NSAppUnitsToIntPixels(aCoord, float(aAppUnitsPerDevPixel))); } static LayoutDeviceRect FromAppUnits(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceRect(FromAppUnits(aRect.x, aAppUnitsPerDevPixel), FromAppUnits(aRect.y, aAppUnitsPerDevPixel), FromAppUnits(aRect.Width(), aAppUnitsPerDevPixel), FromAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); } static LayoutDeviceSize FromAppUnits(const nsSize& aSize, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceSize(FromAppUnits(aSize.width, aAppUnitsPerDevPixel), FromAppUnits(aSize.height, aAppUnitsPerDevPixel)); } static LayoutDevicePoint FromAppUnits(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { return LayoutDevicePoint(FromAppUnits(aPoint.x, aAppUnitsPerDevPixel), FromAppUnits(aPoint.y, aAppUnitsPerDevPixel)); } static LayoutDeviceMargin FromAppUnits(const nsMargin& aMargin, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceMargin( FromAppUnits(aMargin.top, aAppUnitsPerDevPixel), FromAppUnits(aMargin.right, aAppUnitsPerDevPixel), FromAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), FromAppUnits(aMargin.left, aAppUnitsPerDevPixel)); } static LayoutDeviceIntPoint FromAppUnitsRounded( const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntPoint( FromAppUnitsRounded(aPoint.x, aAppUnitsPerDevPixel), FromAppUnitsRounded(aPoint.y, aAppUnitsPerDevPixel)); } static LayoutDeviceIntRect FromAppUnitsRounded(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntRect( FromAppUnitsRounded(aRect.x, aAppUnitsPerDevPixel), FromAppUnitsRounded(aRect.y, aAppUnitsPerDevPixel), FromAppUnitsRounded(aRect.Width(), aAppUnitsPerDevPixel), FromAppUnitsRounded(aRect.Height(), aAppUnitsPerDevPixel)); } static LayoutDeviceIntPoint FromAppUnitsToNearest( const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntPoint::FromUnknownPoint( aPoint.ToNearestPixels(aAppUnitsPerDevPixel)); } static LayoutDeviceIntRect FromAppUnitsToNearest( const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntRect::FromUnknownRect( aRect.ToNearestPixels(aAppUnitsPerDevPixel)); } static LayoutDeviceIntRect FromAppUnitsToInside( const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntRect::FromUnknownRect( aRect.ToInsidePixels(aAppUnitsPerDevPixel)); } static LayoutDeviceIntRect FromAppUnitsToOutside( const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntRect::FromUnknownRect( aRect.ToOutsidePixels(aAppUnitsPerDevPixel)); } static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntSize( FromAppUnitsRounded(aSize.width, aAppUnitsPerDevPixel), FromAppUnitsRounded(aSize.height, aAppUnitsPerDevPixel)); } static LayoutDeviceIntMargin FromAppUnitsRounded( const nsMargin& aMargin, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntMargin( FromAppUnitsRounded(aMargin.top, aAppUnitsPerDevPixel), FromAppUnitsRounded(aMargin.right, aAppUnitsPerDevPixel), FromAppUnitsRounded(aMargin.bottom, aAppUnitsPerDevPixel), FromAppUnitsRounded(aMargin.left, aAppUnitsPerDevPixel)); } static nscoord ToAppUnits(LayoutDeviceIntCoord aCoord, nscoord aAppUnitsPerDevPixel) { return aCoord * aAppUnitsPerDevPixel; } static nscoord ToAppUnits(int32_t aCoord, nscoord aAppUnitsPerDevPixel) { return ToAppUnits(LayoutDeviceIntCoord(aCoord), aAppUnitsPerDevPixel); } static nscoord ToAppUnits(LayoutDeviceCoord aCoord, nscoord aAppUnitsPerDevPixel) { return NSFloatPixelsToAppUnits(aCoord, aAppUnitsPerDevPixel); } static nscoord ToAppUnits(float aCoord, nscoord aAppUnitsPerDevPixel) { return ToAppUnits(LayoutDeviceCoord(aCoord), aAppUnitsPerDevPixel); } static nsPoint ToAppUnits(const LayoutDeviceIntPoint& aPoint, nscoord aAppUnitsPerDevPixel) { return nsPoint(ToAppUnits(aPoint.x, aAppUnitsPerDevPixel), ToAppUnits(aPoint.y, aAppUnitsPerDevPixel)); } static nsSize ToAppUnits(const LayoutDeviceIntSize& aSize, nscoord aAppUnitsPerDevPixel) { return nsSize(ToAppUnits(aSize.width, aAppUnitsPerDevPixel), ToAppUnits(aSize.height, aAppUnitsPerDevPixel)); } static nsSize ToAppUnits(const LayoutDeviceSize& aSize, nscoord aAppUnitsPerDevPixel) { return nsSize(ToAppUnits(aSize.width, aAppUnitsPerDevPixel), ToAppUnits(aSize.height, aAppUnitsPerDevPixel)); } static nsRect ToAppUnits(const LayoutDeviceIntRect& aRect, nscoord aAppUnitsPerDevPixel) { return nsRect(ToAppUnits(aRect.x, aAppUnitsPerDevPixel), ToAppUnits(aRect.y, aAppUnitsPerDevPixel), ToAppUnits(aRect.Width(), aAppUnitsPerDevPixel), ToAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); } static nsRect ToAppUnits(const LayoutDeviceRect& aRect, nscoord aAppUnitsPerDevPixel) { return nsRect(ToAppUnits(aRect.x, aAppUnitsPerDevPixel), ToAppUnits(aRect.y, aAppUnitsPerDevPixel), ToAppUnits(aRect.Width(), aAppUnitsPerDevPixel), ToAppUnits(aRect.Height(), aAppUnitsPerDevPixel)); } static nsMargin ToAppUnits(const LayoutDeviceIntMargin& aMargin, nscoord aAppUnitsPerDevPixel) { return nsMargin(ToAppUnits(aMargin.top, aAppUnitsPerDevPixel), ToAppUnits(aMargin.right, aAppUnitsPerDevPixel), ToAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), ToAppUnits(aMargin.left, aAppUnitsPerDevPixel)); } static nsMargin ToAppUnits(const LayoutDeviceMargin& aMargin, nscoord aAppUnitsPerDevPixel) { return nsMargin(ToAppUnits(aMargin.top, aAppUnitsPerDevPixel), ToAppUnits(aMargin.right, aAppUnitsPerDevPixel), ToAppUnits(aMargin.bottom, aAppUnitsPerDevPixel), ToAppUnits(aMargin.left, aAppUnitsPerDevPixel)); } }; /* * The pixels that layout rasterizes and delivers to the graphics code. * These also are generally referred to as "device pixels" in layout code. * Conversion between CSS pixels and LayerPixels is affected by: * 1) the "display resolution" (see PresShell::SetResolution) * 2) the "full zoom" (see nsPresContext::SetFullZoom) * 3) the "widget scale" (see nsIWidget::GetDefaultScale) * 4) rasterizing at a different scale in the presence of some CSS transforms */ struct LayerPixel {}; /* * This is Layer coordinates with the Layer's CSS transform applied. * It can be thought of as intermediate between LayerPixel and * ParentLayerPixel, as further applying async transforms to this * yields ParentLayerPixels. */ struct CSSTransformedLayerPixel {}; /* * Layers are always composited to a render target. This unit * represents one pixel in the render target. Note that for the * root render target RenderTargetPixel == ScreenPixel. Also * any ContainerLayer providing an intermediate surface will * have RenderTargetPixel == LayerPixel. */ struct RenderTargetPixel {}; /* * This unit represents one pixel in an image. Image space * is largely independent of any other space. */ struct ImagePixel {}; /* * The pixels that are displayed on the screen. * On non-OMTC platforms this should be equivalent to LayerPixel units. * On OMTC platforms these may diverge from LayerPixel units temporarily, * while an asynchronous zoom is happening, but should eventually converge * back to LayerPixel units. Some variables (such as those representing * chrome UI element sizes) that are not subject to content zoom should * generally be represented in ScreenPixel units. */ struct ScreenPixel {}; /* The layer coordinates of the parent frame. * This can be arrived at in three ways: * - Start with the CSS coordinates of the parent frame, multiply by the * device scale and the cumulative resolution of the parent frame. * - Start with the CSS coordinates of current frame, multiply by the device * scale, the cumulative resolution of the current frame, and the scales * from the CSS and async transforms of the current frame. * - Start with global screen coordinates and unapply all CSS and async * transforms from the root down to and including the parent. * It's helpful to look at * https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems to get a picture * of how the various coordinate systems relate to each other. */ struct ParentLayerPixel {}; /* * Pixels in the coordinate space used by the host OS to manage windows on the * desktop. What these mean varies between OSs: * - by default (unless implemented differently in platform-specific widget * code) they are the same as LayoutDevicePixels * - on Mac OS X, they're "cocoa points", which correspond to device pixels * on a non-Retina display, and to 2x device pixels on Retina * - on Windows *without* per-monitor DPI support, they are Windows "logical * pixels", i.e. device pixels scaled according to the Windows display DPI * scaling factor (typically one of 1.25, 1.5, 1.75, 2.0...) * - on Windows *with* per-monitor DPI support, they are physical device pixels * on each screen; note that this means the scaling between CSS pixels and * desktop pixels may vary across multiple displays. */ struct DesktopPixel {}; struct ExternalPixel {}; // Operators to apply ScaleFactors directly to Coords, Points, Rects, Sizes and // Margins template gfx::CoordTyped operator*(const gfx::CoordTyped& aCoord, const gfx::ScaleFactor& aScale) { return gfx::CoordTyped(aCoord.value * aScale.scale); } template gfx::CoordTyped operator/(const gfx::CoordTyped& aCoord, const gfx::ScaleFactor& aScale) { return gfx::CoordTyped(aCoord.value / aScale.scale); } template gfx::PointTyped operator*(const gfx::PointTyped& aPoint, const gfx::ScaleFactor& aScale) { return gfx::PointTyped(aPoint.x * aScale.scale, aPoint.y * aScale.scale); } template gfx::PointTyped operator/(const gfx::PointTyped& aPoint, const gfx::ScaleFactor& aScale) { return gfx::PointTyped(aPoint.x / aScale.scale, aPoint.y / aScale.scale); } template gfx::PointTyped operator*( const gfx::PointTyped& aPoint, const gfx::BaseScaleFactors2D& aScale) { return gfx::PointTyped(aPoint.x * aScale.xScale, aPoint.y * aScale.yScale); } template gfx::PointTyped operator/( const gfx::PointTyped& aPoint, const gfx::BaseScaleFactors2D& aScale) { return gfx::PointTyped(aPoint.x / aScale.xScale, aPoint.y / aScale.yScale); } template gfx::PointTyped operator*(const gfx::IntPointTyped& aPoint, const gfx::ScaleFactor& aScale) { return gfx::PointTyped(float(aPoint.x) * aScale.scale, float(aPoint.y) * aScale.scale); } template gfx::PointTyped operator/(const gfx::IntPointTyped& aPoint, const gfx::ScaleFactor& aScale) { return gfx::PointTyped(float(aPoint.x) / aScale.scale, float(aPoint.y) / aScale.scale); } template gfx::PointTyped operator*( const gfx::IntPointTyped& aPoint, const gfx::BaseScaleFactors2D& aScale) { return gfx::PointTyped(F(aPoint.x) * aScale.xScale, F(aPoint.y) * aScale.yScale); } template gfx::PointTyped operator/( const gfx::IntPointTyped& aPoint, const gfx::BaseScaleFactors2D& aScale) { return gfx::PointTyped(F(aPoint.x) / aScale.xScale, F(aPoint.y) / aScale.yScale); } template gfx::RectTyped operator*(const gfx::RectTyped& aRect, const gfx::ScaleFactor& aScale) { return gfx::RectTyped(aRect.x * aScale.scale, aRect.y * aScale.scale, aRect.Width() * aScale.scale, aRect.Height() * aScale.scale); } template gfx::RectTyped operator/(const gfx::RectTyped& aRect, const gfx::ScaleFactor& aScale) { return gfx::RectTyped(aRect.x / aScale.scale, aRect.y / aScale.scale, aRect.Width() / aScale.scale, aRect.Height() / aScale.scale); } template gfx::RectTyped operator*( const gfx::RectTyped& aRect, const gfx::BaseScaleFactors2D& aScale) { return gfx::RectTyped( aRect.x * aScale.xScale, aRect.y * aScale.yScale, aRect.Width() * aScale.xScale, aRect.Height() * aScale.yScale); } template gfx::RectTyped operator/( const gfx::RectTyped& aRect, const gfx::BaseScaleFactors2D& aScale) { return gfx::RectTyped( aRect.x / aScale.xScale, aRect.y / aScale.yScale, aRect.Width() / aScale.xScale, aRect.Height() / aScale.yScale); } template gfx::RectTyped operator*(const gfx::IntRectTyped& aRect, const gfx::ScaleFactor& aScale) { return gfx::RectTyped(float(aRect.x) * aScale.scale, float(aRect.y) * aScale.scale, float(aRect.Width()) * aScale.scale, float(aRect.Height()) * aScale.scale); } template gfx::RectTyped operator/(const gfx::IntRectTyped& aRect, const gfx::ScaleFactor& aScale) { return gfx::RectTyped(float(aRect.x) / aScale.scale, float(aRect.y) / aScale.scale, float(aRect.Width()) / aScale.scale, float(aRect.Height()) / aScale.scale); } template gfx::RectTyped operator*( const gfx::IntRectTyped& aRect, const gfx::BaseScaleFactors2D& aScale) { return gfx::RectTyped( F(aRect.x) * aScale.xScale, F(aRect.y) * aScale.yScale, F(aRect.Width()) * aScale.xScale, F(aRect.Height()) * aScale.yScale); } template gfx::RectTyped operator/( const gfx::IntRectTyped& aRect, const gfx::BaseScaleFactors2D& aScale) { return gfx::RectTyped( F(aRect.x) / aScale.xScale, F(aRect.y) / aScale.yScale, F(aRect.Width()) / aScale.xScale, F(aRect.Height()) / aScale.yScale); } template gfx::SizeTyped operator*(const gfx::SizeTyped& aSize, const gfx::ScaleFactor& aScale) { return gfx::SizeTyped(aSize.width * aScale.scale, aSize.height * aScale.scale); } template gfx::SizeTyped operator/(const gfx::SizeTyped& aSize, const gfx::ScaleFactor& aScale) { return gfx::SizeTyped(aSize.width / aScale.scale, aSize.height / aScale.scale); } template gfx::SizeTyped operator*( const gfx::SizeTyped& aSize, const gfx::BaseScaleFactors2D& aScale) { return gfx::SizeTyped(aSize.width * aScale.xScale, aSize.height * aScale.yScale); } template gfx::SizeTyped operator/( const gfx::SizeTyped& aSize, const gfx::BaseScaleFactors2D& aScale) { return gfx::SizeTyped(aSize.width / aScale.xScale, aSize.height / aScale.yScale); } template gfx::SizeTyped operator*(const gfx::IntSizeTyped& aSize, const gfx::ScaleFactor& aScale) { return gfx::SizeTyped(float(aSize.width) * aScale.scale, float(aSize.height) * aScale.scale); } template gfx::SizeTyped operator/(const gfx::IntSizeTyped& aSize, const gfx::ScaleFactor& aScale) { return gfx::SizeTyped(float(aSize.width) / aScale.scale, float(aSize.height) / aScale.scale); } template gfx::SizeTyped operator*( const gfx::IntSizeTyped& aSize, const gfx::BaseScaleFactors2D& aScale) { return gfx::SizeTyped(F(aSize.width) * aScale.xScale, F(aSize.height) * aScale.yScale); } template gfx::SizeTyped operator/( const gfx::IntSizeTyped& aSize, const gfx::BaseScaleFactors2D& aScale) { return gfx::SizeTyped(F(aSize.width) / aScale.xScale, F(aSize.height) / aScale.yScale); } template gfx::MarginTyped operator*(const gfx::MarginTyped& aMargin, const gfx::ScaleFactor& aScale) { return gfx::MarginTyped( aMargin.top.value * aScale.scale, aMargin.right.value * aScale.scale, aMargin.bottom.value * aScale.scale, aMargin.left.value * aScale.scale); } template gfx::MarginTyped operator/(const gfx::MarginTyped& aMargin, const gfx::ScaleFactor& aScale) { return gfx::MarginTyped( aMargin.top / aScale.scale, aMargin.right / aScale.scale, aMargin.bottom / aScale.scale, aMargin.left / aScale.scale); } template gfx::MarginTyped operator*( const gfx::MarginTyped& aMargin, const gfx::BaseScaleFactors2D& aScale) { return gfx::MarginTyped( aMargin.top.value * aScale.yScale, aMargin.right.value * aScale.xScale, aMargin.bottom.value * aScale.yScale, aMargin.left.value * aScale.xScale); } template gfx::MarginTyped operator/( const gfx::MarginTyped& aMargin, const gfx::BaseScaleFactors2D& aScale) { return gfx::MarginTyped( aMargin.top.value / aScale.yScale, aMargin.right.value / aScale.xScale, aMargin.bottom.value / aScale.yScale, aMargin.left.value / aScale.xScale); } // Calculate the max or min or the ratios of the widths and heights of two // sizes, returning a scale factor in the correct units. template gfx::ScaleFactor MaxScaleRatio(const gfx::SizeTyped& aDestSize, const gfx::SizeTyped& aSrcSize) { MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0, "Caller must verify aSrcSize has nonzero components, " "to avoid division by 0 here"); return gfx::ScaleFactor(std::max( aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height)); } template gfx::ScaleFactor MinScaleRatio(const gfx::SizeTyped& aDestSize, const gfx::SizeTyped& aSrcSize) { MOZ_ASSERT(aSrcSize.width != 0 && aSrcSize.height != 0, "Caller must verify aSrcSize has nonzero components, " "to avoid division by 0 here"); return gfx::ScaleFactor(std::min( aDestSize.width / aSrcSize.width, aDestSize.height / aSrcSize.height)); } template struct CoordOfImpl; template struct CoordOfImpl> { typedef gfx::CoordTyped Type; }; template struct CoordOfImpl> { typedef gfx::IntCoordTyped Type; }; template struct CoordOfImpl> { typedef gfx::CoordTyped Type; }; template struct CoordOfImpl> { typedef gfx::IntCoordTyped Type; }; template struct CoordOfImpl> { typedef gfx::CoordTyped Type; }; template using CoordOf = typename CoordOfImpl::Type; } // namespace mozilla #endif