Bug 1841478 - Use strongly-typed coordinates in the BaseSize constructor. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D182654
This commit is contained in:
Razvan Cojocaru
2023-07-10 02:59:01 +00:00
parent e5d35fdc57
commit 272df8f2b0
9 changed files with 41 additions and 21 deletions

View File

@@ -19,7 +19,7 @@ namespace mozilla::gfx {
* Sub parameter, and only use that subclass. This allows methods to safely
* cast 'this' to 'Sub*'.
*/
template <class T, class Sub>
template <class T, class Sub, class Coord = T>
struct BaseSize {
union {
struct {
@@ -30,7 +30,8 @@ struct BaseSize {
// Constructors
constexpr BaseSize() : width(0), height(0) {}
constexpr BaseSize(T aWidth, T aHeight) : width(aWidth), height(aHeight) {}
constexpr BaseSize(Coord aWidth, Coord aHeight)
: width(aWidth), height(aHeight) {}
void SizeTo(T aWidth, T aHeight) {
width = aWidth;
@@ -103,7 +104,7 @@ struct BaseSize {
}
friend std::ostream& operator<<(std::ostream& aStream,
const BaseSize<T, Sub>& aSize) {
const BaseSize<T, Sub, Coord>& aSize) {
return aStream << '(' << aSize.width << " x " << aSize.height << ')';
}
};

View File

@@ -103,8 +103,9 @@ struct MOZ_EMPTY_BASES IntCoordTyped
static_assert(sizeof(IntCoordTyped) == sizeof(Rep),
"Would be unfortunate otherwise!");
}
template <class T, typename = typename std::enable_if<
std::is_integral<T>::value>::type>
template <class T,
typename = typename std::enable_if<std::is_integral<T>::value ||
std::is_enum<T>::value>::type>
constexpr MOZ_IMPLICIT IntCoordTyped(T aValue) : Super(aValue) {
static_assert(sizeof(IntCoordTyped) == sizeof(Rep),
"Would be unfortunate otherwise!");

View File

@@ -379,8 +379,8 @@ class Log final {
}
return *this;
}
template <typename T, typename Sub>
Log& operator<<(const BaseSize<T, Sub>& aSize) {
template <typename T, typename Sub, typename Coord>
Log& operator<<(const BaseSize<T, Sub, Coord>& aSize) {
if (MOZ_UNLIKELY(LogIt())) {
mMessage << "Size(" << aSize.width << "," << aSize.height << ")";
}

View File

@@ -269,19 +269,19 @@ typedef Point4DTyped<UnknownUnits, double> PointDouble4D;
template <class Units>
struct MOZ_EMPTY_BASES IntSizeTyped
: public BaseSize<int32_t, IntSizeTyped<Units> >,
: public BaseSize<int32_t, IntSizeTyped<Units>, IntCoordTyped<Units> >,
public Units {
static_assert(IsPixel<Units>::value,
"'Units' must be a coordinate system tag");
typedef IntParam<int32_t> ToInt;
typedef BaseSize<int32_t, IntSizeTyped<Units> > Super;
typedef IntCoordTyped<Units> Coord;
typedef BaseSize<int32_t, IntSizeTyped<Units>, Coord> Super;
constexpr IntSizeTyped() : Super() {
static_assert(sizeof(IntSizeTyped) == sizeof(int32_t) * 2,
"Would be unfortunate otherwise!");
}
constexpr IntSizeTyped(ToInt aWidth, ToInt aHeight)
constexpr IntSizeTyped(Coord aWidth, Coord aHeight)
: Super(aWidth.value, aHeight.value) {}
static IntSizeTyped Round(float aWidth, float aHeight) {
@@ -337,18 +337,20 @@ typedef IntSizeTyped<UnknownUnits> IntSize;
typedef Maybe<IntSize> MaybeIntSize;
template <class Units, class F = Float>
struct MOZ_EMPTY_BASES SizeTyped : public BaseSize<F, SizeTyped<Units, F> >,
public Units {
struct MOZ_EMPTY_BASES SizeTyped
: public BaseSize<F, SizeTyped<Units, F>, CoordTyped<Units, F> >,
public Units {
static_assert(IsPixel<Units>::value,
"'Units' must be a coordinate system tag");
typedef BaseSize<F, SizeTyped<Units, F> > Super;
typedef CoordTyped<Units, F> Coord;
typedef BaseSize<F, SizeTyped<Units, F>, Coord> Super;
constexpr SizeTyped() : Super() {
static_assert(sizeof(SizeTyped) == sizeof(F) * 2,
"Would be unfortunate otherwise!");
}
constexpr SizeTyped(F aWidth, F aHeight) : Super(aWidth, aHeight) {}
constexpr SizeTyped(Coord aWidth, Coord aHeight) : Super(aWidth, aHeight) {}
explicit SizeTyped(const IntSizeTyped<Units>& size)
: Super(F(size.width), F(size.height)) {}

View File

@@ -18,9 +18,18 @@
# include <windows.h>
#endif
using mozilla::CSSIntCoord;
using mozilla::CSSIntSize;
using mozilla::ScreenIntCoord;
using mozilla::gfx::IntRect;
using mozilla::gfx::IntRectAbsolute;
static_assert(std::is_constructible_v<CSSIntSize, CSSIntCoord, CSSIntCoord>);
static_assert(
!std::is_constructible_v<CSSIntSize, ScreenIntCoord, ScreenIntCoord>);
static_assert(std::is_constructible_v<CSSIntSize, int, int>);
static_assert(!std::is_constructible_v<CSSIntSize, float, float>);
template <class RectType>
static bool TestConstructors() {
// Create a rectangle

View File

@@ -210,6 +210,10 @@ Maybe<gfx::Matrix4x4> ToUnknownMatrix(
// Using these functions does not require a justification, but once we convert
// all code to use strongly typed units they should not be needed any longer.
template <class TargetUnits>
gfx::CoordTyped<TargetUnits> ViewAs(const gfx::Coord& aCoord) {
return gfx::CoordTyped<TargetUnits>(aCoord.value);
}
template <class TargetUnits>
gfx::PointTyped<TargetUnits> ViewAs(const gfxPoint& aPoint) {
return gfx::PointTyped<TargetUnits>(aPoint.x, aPoint.y);
}

View File

@@ -10016,8 +10016,9 @@ bool nsLayoutUtils::FrameIsMostlyScrolledOutOfViewInCrossProcess(
auto scale =
browserChild->GetChildToParentConversionMatrix().As2D().ScaleFactors();
ScreenSize margin(scale.xScale * CSSPixel::FromAppUnits(aMargin),
scale.yScale * CSSPixel::FromAppUnits(aMargin));
const CSSCoord cssMargin = CSSPixel::FromAppUnits(aMargin);
ScreenSize margin =
CSSSize(cssMargin, cssMargin) * ViewAs<CSSToScreenScale2D>(scale);
return visibleRect->width < margin.width ||
visibleRect->height < margin.height;

View File

@@ -52,8 +52,8 @@ struct AspectRatio {
return AspectRatio(aWidth / aHeight, aUseBoxSizing);
}
template <typename T, typename Sub>
static AspectRatio FromSize(const gfx::BaseSize<T, Sub>& aSize) {
template <typename T, typename Sub, typename Coord>
static AspectRatio FromSize(const gfx::BaseSize<T, Sub, Coord>& aSize) {
return FromSize(aSize.Width(), aSize.Height());
}

View File

@@ -268,10 +268,12 @@ class TextDrawTarget : public DrawTarget {
if (aVertical) {
pos.x -= aThickness / 2; // adjust from center to corner
size = LayoutDeviceSize(aThickness, aEnd.y - aStart.y);
size = LayoutDeviceSize(aThickness,
ViewAs<LayoutDevicePixel>(aEnd.y - aStart.y));
} else {
pos.y -= aThickness / 2; // adjust from center to corner
size = LayoutDeviceSize(aEnd.x - aStart.x, aThickness);
size = LayoutDeviceSize(ViewAs<LayoutDevicePixel>(aEnd.x - aStart.x),
aThickness);
}
wr::Line decoration;