Bug 1814239 - Expose Point/Size rounded-to-multiple helpers, and use them from MaybeRoundToDisplayPixels. r=tnikkel,gfx-reviewers,nical
Turns out we already had code for this in NumericTools.h, so reuse it. I thought I was going to need this code somewhere else though I didn't end up needing it. While at it clean up unnecessary template params I noticed. Differential Revision: https://phabricator.services.mozilla.com/D168460
This commit is contained in:
@@ -12,8 +12,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
namespace mozilla::gfx {
|
||||
|
||||
/**
|
||||
* Do not use this class directly. Subclass it, pass that subclass as the
|
||||
@@ -97,7 +96,6 @@ struct BaseCoord {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
} // namespace mozilla::gfx
|
||||
|
||||
#endif /* MOZILLA_GFX_BASECOORD_H_ */
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
#include "mozilla/gfx/ScaleFactors2D.h"
|
||||
#include "Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
namespace mozilla::gfx {
|
||||
|
||||
/**
|
||||
* Rectangles have two interpretations: a set of (zero-size) points,
|
||||
@@ -740,7 +739,6 @@ struct BaseRect {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
} // namespace mozilla::gfx
|
||||
|
||||
#endif /* MOZILLA_GFX_BASERECT_H_ */
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
namespace mozilla::gfx {
|
||||
|
||||
/**
|
||||
* Do not use this class directly. Subclass it, pass that subclass as the
|
||||
@@ -109,7 +108,6 @@ struct BaseSize {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
} // namespace mozilla::gfx
|
||||
|
||||
#endif /* MOZILLA_GFX_BASESIZE_H_ */
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#ifndef MOZILLA_GFX_NUMERICTOOLS_H_
|
||||
#define MOZILLA_GFX_NUMERICTOOLS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// XXX - Move these into mfbt/MathAlgorithms.h?
|
||||
@@ -35,6 +37,10 @@ inline int32_t RoundUpToMultiple(int32_t x, int32_t aMultiplier) {
|
||||
return x - mod;
|
||||
}
|
||||
|
||||
inline int32_t RoundToMultiple(int32_t x, int32_t aMultiplier) {
|
||||
return RoundDownToMultiple(x + aMultiplier / 2, aMultiplier);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_NUMERICTOOLS_H_ */
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "BasePoint4D.h"
|
||||
#include "BaseSize.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/gfx/NumericTools.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
@@ -80,32 +81,32 @@ struct MOZ_EMPTY_BASES IntPointTyped
|
||||
constexpr IntPointTyped(ToInt aX, ToInt aY)
|
||||
: Super(Coord(aX.value), Coord(aY.value)) {}
|
||||
|
||||
static IntPointTyped<Units> Round(float aX, float aY) {
|
||||
static IntPointTyped Round(float aX, float aY) {
|
||||
return IntPointTyped(int32_t(floorf(aX + 0.5f)),
|
||||
int32_t(floorf(aY + 0.5f)));
|
||||
}
|
||||
|
||||
static IntPointTyped<Units> Ceil(float aX, float aY) {
|
||||
static IntPointTyped Ceil(float aX, float aY) {
|
||||
return IntPointTyped(int32_t(ceilf(aX)), int32_t(ceilf(aY)));
|
||||
}
|
||||
|
||||
static IntPointTyped<Units> Floor(float aX, float aY) {
|
||||
static IntPointTyped Floor(float aX, float aY) {
|
||||
return IntPointTyped(int32_t(floorf(aX)), int32_t(floorf(aY)));
|
||||
}
|
||||
|
||||
static IntPointTyped<Units> Truncate(float aX, float aY) {
|
||||
static IntPointTyped Truncate(float aX, float aY) {
|
||||
return IntPointTyped(int32_t(aX), int32_t(aY));
|
||||
}
|
||||
|
||||
static IntPointTyped<Units> Round(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped<Units> Ceil(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped<Units> Floor(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped<Units> Truncate(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped Round(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped Ceil(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped Floor(const PointTyped<Units, float>& aPoint);
|
||||
static IntPointTyped Truncate(const PointTyped<Units, float>& aPoint);
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to
|
||||
// and from unknown types should be removed.
|
||||
|
||||
static IntPointTyped<Units> FromUnknownPoint(
|
||||
static IntPointTyped FromUnknownPoint(
|
||||
const IntPointTyped<UnknownUnits>& aPoint) {
|
||||
return IntPointTyped<Units>(aPoint.x, aPoint.y);
|
||||
}
|
||||
@@ -113,6 +114,11 @@ struct MOZ_EMPTY_BASES IntPointTyped
|
||||
IntPointTyped<UnknownUnits> ToUnknownPoint() const {
|
||||
return IntPointTyped<UnknownUnits>(this->x, this->y);
|
||||
}
|
||||
|
||||
IntPointTyped RoundedToMultiple(int32_t aMultiplier) const {
|
||||
return {RoundToMultiple(this->x, aMultiplier),
|
||||
RoundToMultiple(this->y, aMultiplier)};
|
||||
}
|
||||
};
|
||||
typedef IntPointTyped<UnknownUnits> IntPoint;
|
||||
|
||||
@@ -278,34 +284,49 @@ struct MOZ_EMPTY_BASES IntSizeTyped
|
||||
constexpr IntSizeTyped(ToInt aWidth, ToInt aHeight)
|
||||
: Super(aWidth.value, aHeight.value) {}
|
||||
|
||||
static IntSizeTyped<Units> Round(float aWidth, float aHeight) {
|
||||
static IntSizeTyped Round(float aWidth, float aHeight) {
|
||||
return IntSizeTyped(int32_t(floorf(aWidth + 0.5)),
|
||||
int32_t(floorf(aHeight + 0.5)));
|
||||
}
|
||||
|
||||
static IntSizeTyped<Units> Truncate(float aWidth, float aHeight) {
|
||||
static IntSizeTyped Truncate(float aWidth, float aHeight) {
|
||||
return IntSizeTyped(int32_t(aWidth), int32_t(aHeight));
|
||||
}
|
||||
|
||||
static IntSizeTyped<Units> Ceil(float aWidth, float aHeight) {
|
||||
static IntSizeTyped Ceil(float aWidth, float aHeight) {
|
||||
return IntSizeTyped(int32_t(ceil(aWidth)), int32_t(ceil(aHeight)));
|
||||
}
|
||||
|
||||
static IntSizeTyped<Units> Floor(float aWidth, float aHeight) {
|
||||
static IntSizeTyped Floor(float aWidth, float aHeight) {
|
||||
return IntSizeTyped(int32_t(floorf(aWidth)), int32_t(floorf(aHeight)));
|
||||
}
|
||||
|
||||
static IntSizeTyped<Units> Round(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped<Units> Ceil(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped<Units> Floor(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped<Units> Truncate(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped Round(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped Ceil(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped Floor(const SizeTyped<Units, float>& aSize);
|
||||
static IntSizeTyped Truncate(const SizeTyped<Units, float>& aSize);
|
||||
|
||||
IntSizeTyped TruncatedToMultiple(int32_t aMultiplier) const {
|
||||
if (aMultiplier == 1) {
|
||||
return *this;
|
||||
}
|
||||
return {RoundDownToMultiple(this->width, aMultiplier),
|
||||
RoundDownToMultiple(this->height, aMultiplier)};
|
||||
}
|
||||
|
||||
IntSizeTyped CeiledToMultiple(int32_t aMultiplier) const {
|
||||
if (aMultiplier == 1) {
|
||||
return *this;
|
||||
}
|
||||
return {RoundUpToMultiple(this->width, aMultiplier),
|
||||
RoundUpToMultiple(this->height, aMultiplier)};
|
||||
}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to
|
||||
// and from unknown types should be removed.
|
||||
|
||||
static IntSizeTyped<Units> FromUnknownSize(
|
||||
const IntSizeTyped<UnknownUnits>& aSize) {
|
||||
return IntSizeTyped<Units>(aSize.width, aSize.height);
|
||||
static IntSizeTyped FromUnknownSize(const IntSizeTyped<UnknownUnits>& aSize) {
|
||||
return IntSizeTyped(aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
IntSizeTyped<UnknownUnits> ToUnknownSize() const {
|
||||
|
||||
@@ -13,6 +13,7 @@ using namespace mozilla::gfx;
|
||||
TestPoint::TestPoint() {
|
||||
REGISTER_TEST(TestPoint, Addition);
|
||||
REGISTER_TEST(TestPoint, Subtraction);
|
||||
REGISTER_TEST(TestPoint, RoundToMultiple);
|
||||
}
|
||||
|
||||
void TestPoint::Addition() {
|
||||
@@ -40,3 +41,13 @@ void TestPoint::Subtraction() {
|
||||
VERIFY(a.x == -3.f);
|
||||
VERIFY(a.y == 7.f);
|
||||
}
|
||||
|
||||
void TestPoint::RoundToMultiple() {
|
||||
const int32_t roundTo = 2;
|
||||
|
||||
IntPoint p(478, -394);
|
||||
VERIFY(p.RoundedToMultiple(roundTo) == p);
|
||||
|
||||
IntPoint p2(478, 393);
|
||||
VERIFY(p2.RoundedToMultiple(roundTo) != p2);
|
||||
}
|
||||
|
||||
@@ -14,4 +14,5 @@ class TestPoint : public TestBase {
|
||||
|
||||
void Addition();
|
||||
void Subtraction();
|
||||
void RoundToMultiple();
|
||||
};
|
||||
|
||||
@@ -219,23 +219,14 @@ static LayoutDeviceIntRect MaybeRoundToDisplayPixels(
|
||||
return aRect;
|
||||
}
|
||||
|
||||
auto Truncate = [&](int32_t i) { return (i / aRound) * aRound; };
|
||||
auto Round = [&](int32_t i) { return Truncate(i + aRound / 2); };
|
||||
auto RoundSize = [&](int32_t i) {
|
||||
if (i % aRound == 0) {
|
||||
return i;
|
||||
}
|
||||
const auto truncated = Truncate(i);
|
||||
if (NS_WARN_IF(aTransparency == TransparencyMode::Opaque)) {
|
||||
// If the widget doesn't support transparency, we prefer truncating to
|
||||
// ceiling, so that we don't have extra pixels not painted by our frame.
|
||||
return truncated;
|
||||
}
|
||||
return truncated + aRound;
|
||||
};
|
||||
|
||||
return LayoutDeviceIntRect(Round(aRect.x), Round(aRect.y),
|
||||
RoundSize(aRect.width), RoundSize(aRect.height));
|
||||
// If the widget doesn't support transparency, we prefer truncating to
|
||||
// ceiling, so that we don't have extra pixels not painted by our frame.
|
||||
auto size = aTransparency == TransparencyMode::Opaque
|
||||
? aRect.Size().TruncatedToMultiple(aRound)
|
||||
: aRect.Size().CeiledToMultiple(aRound);
|
||||
Unused << NS_WARN_IF(aTransparency == TransparencyMode::Opaque &&
|
||||
size != aRect.Size());
|
||||
return {aRect.TopLeft().RoundedToMultiple(aRound), size};
|
||||
}
|
||||
|
||||
LayoutDeviceIntRect nsView::CalcWidgetBounds(WindowType aType,
|
||||
|
||||
Reference in New Issue
Block a user