michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef MOZ_UNITS_H_ michael@0: #define MOZ_UNITS_H_ michael@0: michael@0: #include "mozilla/gfx/Point.h" michael@0: #include "mozilla/gfx/Rect.h" michael@0: #include "mozilla/gfx/ScaleFactor.h" michael@0: #include "nsRect.h" michael@0: #include "nsMargin.h" michael@0: #include "mozilla/AppUnits.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: struct CSSPixel; michael@0: struct LayoutDevicePixel; michael@0: struct LayerPixel; michael@0: struct ScreenPixel; michael@0: michael@0: typedef gfx::PointTyped CSSPoint; michael@0: typedef gfx::IntPointTyped CSSIntPoint; michael@0: typedef gfx::SizeTyped CSSSize; michael@0: typedef gfx::IntSizeTyped CSSIntSize; michael@0: typedef gfx::RectTyped CSSRect; michael@0: typedef gfx::IntRectTyped CSSIntRect; michael@0: typedef gfx::MarginTyped CSSMargin; michael@0: typedef gfx::IntMarginTyped CSSIntMargin; michael@0: michael@0: typedef gfx::PointTyped LayoutDevicePoint; michael@0: typedef gfx::IntPointTyped LayoutDeviceIntPoint; michael@0: typedef gfx::SizeTyped LayoutDeviceSize; michael@0: typedef gfx::IntSizeTyped LayoutDeviceIntSize; michael@0: typedef gfx::RectTyped LayoutDeviceRect; michael@0: typedef gfx::IntRectTyped LayoutDeviceIntRect; michael@0: typedef gfx::MarginTyped LayoutDeviceMargin; michael@0: typedef gfx::IntMarginTyped LayoutDeviceIntMargin; michael@0: michael@0: typedef gfx::PointTyped LayerPoint; michael@0: typedef gfx::IntPointTyped LayerIntPoint; michael@0: typedef gfx::SizeTyped LayerSize; michael@0: typedef gfx::IntSizeTyped LayerIntSize; michael@0: typedef gfx::RectTyped LayerRect; michael@0: typedef gfx::IntRectTyped LayerIntRect; michael@0: typedef gfx::MarginTyped LayerMargin; michael@0: typedef gfx::IntMarginTyped LayerIntMargin; michael@0: michael@0: typedef gfx::PointTyped ScreenPoint; michael@0: typedef gfx::IntPointTyped ScreenIntPoint; michael@0: typedef gfx::SizeTyped ScreenSize; michael@0: typedef gfx::IntSizeTyped ScreenIntSize; michael@0: typedef gfx::RectTyped ScreenRect; michael@0: typedef gfx::IntRectTyped ScreenIntRect; michael@0: typedef gfx::MarginTyped ScreenMargin; michael@0: typedef gfx::IntMarginTyped ScreenIntMargin; michael@0: michael@0: typedef gfx::ScaleFactor CSSToLayoutDeviceScale; michael@0: typedef gfx::ScaleFactor LayoutDeviceToCSSScale; michael@0: typedef gfx::ScaleFactor CSSToLayerScale; michael@0: typedef gfx::ScaleFactor LayerToCSSScale; michael@0: typedef gfx::ScaleFactor CSSToScreenScale; michael@0: typedef gfx::ScaleFactor ScreenToCSSScale; michael@0: typedef gfx::ScaleFactor LayoutDeviceToLayerScale; michael@0: typedef gfx::ScaleFactor LayerToLayoutDeviceScale; michael@0: typedef gfx::ScaleFactor LayoutDeviceToScreenScale; michael@0: typedef gfx::ScaleFactor ScreenToLayoutDeviceScale; michael@0: typedef gfx::ScaleFactor LayerToScreenScale; michael@0: typedef gfx::ScaleFactor ScreenToLayerScale; michael@0: michael@0: /* michael@0: * The pixels that content authors use to specify sizes in. michael@0: */ michael@0: struct CSSPixel { michael@0: michael@0: // Conversions from app units michael@0: michael@0: static CSSPoint FromAppUnits(const nsPoint& aPoint) { michael@0: return CSSPoint(NSAppUnitsToFloatPixels(aPoint.x, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aPoint.y, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static CSSRect FromAppUnits(const nsRect& aRect) { michael@0: return CSSRect(NSAppUnitsToFloatPixels(aRect.x, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aRect.y, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aRect.width, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aRect.height, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static CSSMargin FromAppUnits(const nsMargin& aMargin) { michael@0: return CSSMargin(NSAppUnitsToFloatPixels(aMargin.top, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aMargin.right, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aMargin.bottom, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToFloatPixels(aMargin.left, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) { michael@0: return CSSIntPoint(NSAppUnitsToIntPixels(aPoint.x, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToIntPixels(aPoint.y, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) michael@0: { michael@0: return CSSIntSize(NSAppUnitsToIntPixels(aSize.width, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToIntPixels(aSize.height, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) { michael@0: return CSSIntRect(NSAppUnitsToIntPixels(aRect.x, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToIntPixels(aRect.y, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToIntPixels(aRect.width, float(AppUnitsPerCSSPixel())), michael@0: NSAppUnitsToIntPixels(aRect.height, float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: // Conversions to app units michael@0: michael@0: static nsPoint ToAppUnits(const CSSPoint& aPoint) { michael@0: return nsPoint(NSToCoordRoundWithClamp(aPoint.x * float(AppUnitsPerCSSPixel())), michael@0: NSToCoordRoundWithClamp(aPoint.y * float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static nsPoint ToAppUnits(const CSSIntPoint& aPoint) { michael@0: return nsPoint(NSToCoordRoundWithClamp(float(aPoint.x) * float(AppUnitsPerCSSPixel())), michael@0: NSToCoordRoundWithClamp(float(aPoint.y) * float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: michael@0: static nsRect ToAppUnits(const CSSRect& aRect) { michael@0: return nsRect(NSToCoordRoundWithClamp(aRect.x * float(AppUnitsPerCSSPixel())), michael@0: NSToCoordRoundWithClamp(aRect.y * float(AppUnitsPerCSSPixel())), michael@0: NSToCoordRoundWithClamp(aRect.width * float(AppUnitsPerCSSPixel())), michael@0: NSToCoordRoundWithClamp(aRect.height * float(AppUnitsPerCSSPixel()))); michael@0: } michael@0: }; michael@0: michael@0: /* michael@0: * The pixels that are referred to as "device pixels" in layout code. In michael@0: * general this is obtained by converting a value in app units value by the michael@0: * AppUnitsPerDevPixel() value. The size of these pixels michael@0: * are affected by: michael@0: * 1) the "full zoom" (see nsPresContext::SetFullZoom) michael@0: * 2) the "widget scale" (see nsIWidget::GetDefaultScale) michael@0: */ michael@0: struct LayoutDevicePixel { michael@0: static LayoutDeviceIntPoint FromUntyped(const nsIntPoint& aPoint) { michael@0: return LayoutDeviceIntPoint(aPoint.x, aPoint.y); michael@0: } michael@0: michael@0: static nsIntPoint ToUntyped(const LayoutDeviceIntPoint& aPoint) { michael@0: return nsIntPoint(aPoint.x, aPoint.y); michael@0: } michael@0: michael@0: static LayoutDeviceIntRect FromUntyped(const nsIntRect& aRect) { michael@0: return LayoutDeviceIntRect(aRect.x, aRect.y, aRect.width, aRect.height); michael@0: } michael@0: michael@0: static nsIntRect ToUntyped(const LayoutDeviceIntRect& aRect) { michael@0: return nsIntRect(aRect.x, aRect.y, aRect.width, aRect.height); michael@0: } michael@0: michael@0: static LayoutDeviceRect FromAppUnits(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { michael@0: return LayoutDeviceRect(NSAppUnitsToFloatPixels(aRect.x, float(aAppUnitsPerDevPixel)), michael@0: NSAppUnitsToFloatPixels(aRect.y, float(aAppUnitsPerDevPixel)), michael@0: NSAppUnitsToFloatPixels(aRect.width, float(aAppUnitsPerDevPixel)), michael@0: NSAppUnitsToFloatPixels(aRect.height, float(aAppUnitsPerDevPixel))); michael@0: } michael@0: michael@0: static LayoutDeviceIntPoint FromAppUnitsRounded(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { michael@0: return LayoutDeviceIntPoint(NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel), michael@0: NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel)); michael@0: } michael@0: michael@0: static LayoutDeviceIntPoint FromAppUnitsToNearest(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { michael@0: return FromUntyped(aPoint.ToNearestPixels(aAppUnitsPerDevPixel)); michael@0: } michael@0: michael@0: static LayoutDeviceIntRect FromAppUnitsToNearest(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { michael@0: return FromUntyped(aRect.ToNearestPixels(aAppUnitsPerDevPixel)); michael@0: } michael@0: }; michael@0: michael@0: /* michael@0: * The pixels that layout rasterizes and delivers to the graphics code. michael@0: * These are generally referred to as "device pixels" in layout code. Layer michael@0: * pixels are affected by: michael@0: * 1) the "display resolution" (see nsIPresShell::SetResolution) michael@0: * 2) the "full zoom" (see nsPresContext::SetFullZoom) michael@0: * 3) the "widget scale" (see nsIWidget::GetDefaultScale) michael@0: */ michael@0: struct LayerPixel { michael@0: }; michael@0: michael@0: /* michael@0: * The pixels that are displayed on the screen. michael@0: * On non-OMTC platforms this should be equivalent to LayerPixel units. michael@0: * On OMTC platforms these may diverge from LayerPixel units temporarily, michael@0: * while an asynchronous zoom is happening, but should eventually converge michael@0: * back to LayerPixel units. Some variables (such as those representing michael@0: * chrome UI element sizes) that are not subject to content zoom should michael@0: * generally be represented in ScreenPixel units. michael@0: */ michael@0: struct ScreenPixel { michael@0: }; michael@0: michael@0: // Operators to apply ScaleFactors directly to Points, Rects, Sizes and Margins michael@0: michael@0: template michael@0: gfx::PointTyped operator*(const gfx::PointTyped& aPoint, const gfx::ScaleFactor& aScale) { michael@0: return gfx::PointTyped(aPoint.x * aScale.scale, michael@0: aPoint.y * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::PointTyped operator/(const gfx::PointTyped& aPoint, const gfx::ScaleFactor& aScale) { michael@0: return gfx::PointTyped(aPoint.x / aScale.scale, michael@0: aPoint.y / aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::RectTyped operator*(const gfx::RectTyped& aRect, const gfx::ScaleFactor& aScale) { michael@0: return gfx::RectTyped(aRect.x * aScale.scale, michael@0: aRect.y * aScale.scale, michael@0: aRect.width * aScale.scale, michael@0: aRect.height * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::RectTyped operator/(const gfx::RectTyped& aRect, const gfx::ScaleFactor& aScale) { michael@0: return gfx::RectTyped(aRect.x / aScale.scale, michael@0: aRect.y / aScale.scale, michael@0: aRect.width / aScale.scale, michael@0: aRect.height / aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::RectTyped operator*(const gfx::IntRectTyped& aRect, const gfx::ScaleFactor& aScale) { michael@0: return gfx::RectTyped(float(aRect.x) * aScale.scale, michael@0: float(aRect.y) * aScale.scale, michael@0: float(aRect.width) * aScale.scale, michael@0: float(aRect.height) * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::RectTyped operator/(const gfx::IntRectTyped& aRect, const gfx::ScaleFactor& aScale) { michael@0: return gfx::RectTyped(float(aRect.x) / aScale.scale, michael@0: float(aRect.y) / aScale.scale, michael@0: float(aRect.width) / aScale.scale, michael@0: float(aRect.height) / aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::SizeTyped operator*(const gfx::SizeTyped& aSize, const gfx::ScaleFactor& aScale) { michael@0: return gfx::SizeTyped(aSize.width * aScale.scale, michael@0: aSize.height * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::SizeTyped operator/(const gfx::SizeTyped& aSize, const gfx::ScaleFactor& aScale) { michael@0: return gfx::SizeTyped(aSize.width / aScale.scale, michael@0: aSize.height / aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::SizeTyped operator*(const gfx::IntSizeTyped& aSize, const gfx::ScaleFactor& aScale) { michael@0: return gfx::SizeTyped(float(aSize.width) * aScale.scale, michael@0: float(aSize.height) * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::SizeTyped operator/(const gfx::IntSizeTyped& aSize, const gfx::ScaleFactor& aScale) { michael@0: return gfx::SizeTyped(float(aSize.width) / aScale.scale, michael@0: float(aSize.height) / aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::MarginTyped operator*(const gfx::MarginTyped& aMargin, const gfx::ScaleFactor& aScale) { michael@0: return gfx::MarginTyped(aMargin.top * aScale.scale, michael@0: aMargin.right * aScale.scale, michael@0: aMargin.bottom * aScale.scale, michael@0: aMargin.left * aScale.scale); michael@0: } michael@0: michael@0: template michael@0: gfx::MarginTyped operator/(const gfx::MarginTyped& aMargin, const gfx::ScaleFactor& aScale) { michael@0: return gfx::MarginTyped(aMargin.top / aScale.scale, michael@0: aMargin.right / aScale.scale, michael@0: aMargin.bottom / aScale.scale, michael@0: aMargin.left / aScale.scale); michael@0: } michael@0: michael@0: } michael@0: michael@0: #endif