diff -r 000000000000 -r 6474c204b198 layout/base/Units.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/base/Units.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,294 @@ +/* -*- 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 "mozilla/gfx/Point.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/gfx/ScaleFactor.h" +#include "nsRect.h" +#include "nsMargin.h" +#include "mozilla/AppUnits.h" + +namespace mozilla { + +struct CSSPixel; +struct LayoutDevicePixel; +struct LayerPixel; +struct ScreenPixel; + +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::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::PointTyped LayerPoint; +typedef gfx::IntPointTyped LayerIntPoint; +typedef gfx::SizeTyped LayerSize; +typedef gfx::IntSizeTyped LayerIntSize; +typedef gfx::RectTyped LayerRect; +typedef gfx::IntRectTyped LayerIntRect; +typedef gfx::MarginTyped LayerMargin; +typedef gfx::IntMarginTyped LayerIntMargin; + +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::ScaleFactor CSSToLayoutDeviceScale; +typedef gfx::ScaleFactor LayoutDeviceToCSSScale; +typedef gfx::ScaleFactor CSSToLayerScale; +typedef gfx::ScaleFactor LayerToCSSScale; +typedef gfx::ScaleFactor CSSToScreenScale; +typedef gfx::ScaleFactor ScreenToCSSScale; +typedef gfx::ScaleFactor LayoutDeviceToLayerScale; +typedef gfx::ScaleFactor LayerToLayoutDeviceScale; +typedef gfx::ScaleFactor LayoutDeviceToScreenScale; +typedef gfx::ScaleFactor ScreenToLayoutDeviceScale; +typedef gfx::ScaleFactor LayerToScreenScale; +typedef gfx::ScaleFactor ScreenToLayerScale; + +/* + * The pixels that content authors use to specify sizes in. + */ +struct CSSPixel { + + // Conversions from app units + + static CSSPoint FromAppUnits(const nsPoint& aPoint) { + return CSSPoint(NSAppUnitsToFloatPixels(aPoint.x, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aPoint.y, float(AppUnitsPerCSSPixel()))); + } + + static CSSRect FromAppUnits(const nsRect& aRect) { + return CSSRect(NSAppUnitsToFloatPixels(aRect.x, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aRect.y, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aRect.width, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aRect.height, float(AppUnitsPerCSSPixel()))); + } + + static CSSMargin FromAppUnits(const nsMargin& aMargin) { + return CSSMargin(NSAppUnitsToFloatPixels(aMargin.top, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aMargin.right, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aMargin.bottom, float(AppUnitsPerCSSPixel())), + NSAppUnitsToFloatPixels(aMargin.left, float(AppUnitsPerCSSPixel()))); + } + + static CSSIntPoint FromAppUnitsRounded(const nsPoint& aPoint) { + return CSSIntPoint(NSAppUnitsToIntPixels(aPoint.x, float(AppUnitsPerCSSPixel())), + NSAppUnitsToIntPixels(aPoint.y, float(AppUnitsPerCSSPixel()))); + } + + static CSSIntSize FromAppUnitsRounded(const nsSize& aSize) + { + return CSSIntSize(NSAppUnitsToIntPixels(aSize.width, float(AppUnitsPerCSSPixel())), + NSAppUnitsToIntPixels(aSize.height, float(AppUnitsPerCSSPixel()))); + } + + static CSSIntRect FromAppUnitsRounded(const nsRect& aRect) { + return CSSIntRect(NSAppUnitsToIntPixels(aRect.x, float(AppUnitsPerCSSPixel())), + NSAppUnitsToIntPixels(aRect.y, float(AppUnitsPerCSSPixel())), + NSAppUnitsToIntPixels(aRect.width, float(AppUnitsPerCSSPixel())), + NSAppUnitsToIntPixels(aRect.height, float(AppUnitsPerCSSPixel()))); + } + + // Conversions to app units + + static nsPoint ToAppUnits(const CSSPoint& aPoint) { + return nsPoint(NSToCoordRoundWithClamp(aPoint.x * float(AppUnitsPerCSSPixel())), + NSToCoordRoundWithClamp(aPoint.y * float(AppUnitsPerCSSPixel()))); + } + + static nsPoint ToAppUnits(const CSSIntPoint& aPoint) { + return nsPoint(NSToCoordRoundWithClamp(float(aPoint.x) * float(AppUnitsPerCSSPixel())), + NSToCoordRoundWithClamp(float(aPoint.y) * float(AppUnitsPerCSSPixel()))); + } + + static nsRect ToAppUnits(const CSSRect& aRect) { + return nsRect(NSToCoordRoundWithClamp(aRect.x * float(AppUnitsPerCSSPixel())), + NSToCoordRoundWithClamp(aRect.y * float(AppUnitsPerCSSPixel())), + NSToCoordRoundWithClamp(aRect.width * float(AppUnitsPerCSSPixel())), + NSToCoordRoundWithClamp(aRect.height * float(AppUnitsPerCSSPixel()))); + } +}; + +/* + * The pixels that are referred to as "device pixels" in layout code. In + * general this is obtained by converting a value in app units value by the + * AppUnitsPerDevPixel() value. The size of these pixels + * are affected by: + * 1) the "full zoom" (see nsPresContext::SetFullZoom) + * 2) the "widget scale" (see nsIWidget::GetDefaultScale) + */ +struct LayoutDevicePixel { + static LayoutDeviceIntPoint FromUntyped(const nsIntPoint& aPoint) { + return LayoutDeviceIntPoint(aPoint.x, aPoint.y); + } + + static nsIntPoint ToUntyped(const LayoutDeviceIntPoint& aPoint) { + return nsIntPoint(aPoint.x, aPoint.y); + } + + static LayoutDeviceIntRect FromUntyped(const nsIntRect& aRect) { + return LayoutDeviceIntRect(aRect.x, aRect.y, aRect.width, aRect.height); + } + + static nsIntRect ToUntyped(const LayoutDeviceIntRect& aRect) { + return nsIntRect(aRect.x, aRect.y, aRect.width, aRect.height); + } + + static LayoutDeviceRect FromAppUnits(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { + return LayoutDeviceRect(NSAppUnitsToFloatPixels(aRect.x, float(aAppUnitsPerDevPixel)), + NSAppUnitsToFloatPixels(aRect.y, float(aAppUnitsPerDevPixel)), + NSAppUnitsToFloatPixels(aRect.width, float(aAppUnitsPerDevPixel)), + NSAppUnitsToFloatPixels(aRect.height, float(aAppUnitsPerDevPixel))); + } + + static LayoutDeviceIntPoint FromAppUnitsRounded(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { + return LayoutDeviceIntPoint(NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel), + NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel)); + } + + static LayoutDeviceIntPoint FromAppUnitsToNearest(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) { + return FromUntyped(aPoint.ToNearestPixels(aAppUnitsPerDevPixel)); + } + + static LayoutDeviceIntRect FromAppUnitsToNearest(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) { + return FromUntyped(aRect.ToNearestPixels(aAppUnitsPerDevPixel)); + } +}; + +/* + * The pixels that layout rasterizes and delivers to the graphics code. + * These are generally referred to as "device pixels" in layout code. Layer + * pixels are affected by: + * 1) the "display resolution" (see nsIPresShell::SetResolution) + * 2) the "full zoom" (see nsPresContext::SetFullZoom) + * 3) the "widget scale" (see nsIWidget::GetDefaultScale) + */ +struct LayerPixel { +}; + +/* + * 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 { +}; + +// Operators to apply ScaleFactors directly to Points, Rects, Sizes and Margins + +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::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::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::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::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::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::ScaleFactor& aScale) { + return gfx::MarginTyped(aMargin.top / aScale.scale, + aMargin.right / aScale.scale, + aMargin.bottom / aScale.scale, + aMargin.left / aScale.scale); +} + +} + +#endif