Skip to content

Commit 87a5843

Browse files
committedFeb 6, 2023
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
1 parent 6ebc85d commit 87a5843

File tree

8 files changed

+73
-49
lines changed

8 files changed

+73
-49
lines changed
 

‎gfx/2d/BaseCoord.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
#include "mozilla/Attributes.h"
1313
#include "mozilla/MathAlgorithms.h"
1414

15-
namespace mozilla {
16-
namespace gfx {
15+
namespace mozilla::gfx {
1716

1817
/**
1918
* Do not use this class directly. Subclass it, pass that subclass as the
@@ -97,7 +96,6 @@ struct BaseCoord {
9796
}
9897
};
9998

100-
} // namespace gfx
101-
} // namespace mozilla
99+
} // namespace mozilla::gfx
102100

103101
#endif /* MOZILLA_GFX_BASECOORD_H_ */

‎gfx/2d/BaseRect.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
#include "mozilla/gfx/ScaleFactors2D.h"
1818
#include "Types.h"
1919

20-
namespace mozilla {
21-
namespace gfx {
20+
namespace mozilla::gfx {
2221

2322
/**
2423
* Rectangles have two interpretations: a set of (zero-size) points,
@@ -740,7 +739,6 @@ struct BaseRect {
740739
}
741740
};
742741

743-
} // namespace gfx
744-
} // namespace mozilla
742+
} // namespace mozilla::gfx
745743

746744
#endif /* MOZILLA_GFX_BASERECT_H_ */

‎gfx/2d/BaseSize.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
#include "mozilla/Attributes.h"
1414

15-
namespace mozilla {
16-
namespace gfx {
15+
namespace mozilla::gfx {
1716

1817
/**
1918
* Do not use this class directly. Subclass it, pass that subclass as the
@@ -109,7 +108,6 @@ struct BaseSize {
109108
}
110109
};
111110

112-
} // namespace gfx
113-
} // namespace mozilla
111+
} // namespace mozilla::gfx
114112

115113
#endif /* MOZILLA_GFX_BASESIZE_H_ */

‎gfx/2d/NumericTools.h

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef MOZILLA_GFX_NUMERICTOOLS_H_
88
#define MOZILLA_GFX_NUMERICTOOLS_H_
99

10+
#include <cstdint>
11+
1012
namespace mozilla {
1113

1214
// XXX - Move these into mfbt/MathAlgorithms.h?
@@ -35,6 +37,10 @@ inline int32_t RoundUpToMultiple(int32_t x, int32_t aMultiplier) {
3537
return x - mod;
3638
}
3739

40+
inline int32_t RoundToMultiple(int32_t x, int32_t aMultiplier) {
41+
return RoundDownToMultiple(x + aMultiplier / 2, aMultiplier);
42+
}
43+
3844
} // namespace mozilla
3945

4046
#endif /* MOZILLA_GFX_NUMERICTOOLS_H_ */

‎gfx/2d/Point.h

+41-20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "BasePoint4D.h"
1717
#include "BaseSize.h"
1818
#include "mozilla/Maybe.h"
19+
#include "mozilla/gfx/NumericTools.h"
1920

2021
#include <cmath>
2122
#include <type_traits>
@@ -80,39 +81,44 @@ struct MOZ_EMPTY_BASES IntPointTyped
8081
constexpr IntPointTyped(ToInt aX, ToInt aY)
8182
: Super(Coord(aX.value), Coord(aY.value)) {}
8283

83-
static IntPointTyped<Units> Round(float aX, float aY) {
84+
static IntPointTyped Round(float aX, float aY) {
8485
return IntPointTyped(int32_t(floorf(aX + 0.5f)),
8586
int32_t(floorf(aY + 0.5f)));
8687
}
8788

88-
static IntPointTyped<Units> Ceil(float aX, float aY) {
89+
static IntPointTyped Ceil(float aX, float aY) {
8990
return IntPointTyped(int32_t(ceilf(aX)), int32_t(ceilf(aY)));
9091
}
9192

92-
static IntPointTyped<Units> Floor(float aX, float aY) {
93+
static IntPointTyped Floor(float aX, float aY) {
9394
return IntPointTyped(int32_t(floorf(aX)), int32_t(floorf(aY)));
9495
}
9596

96-
static IntPointTyped<Units> Truncate(float aX, float aY) {
97+
static IntPointTyped Truncate(float aX, float aY) {
9798
return IntPointTyped(int32_t(aX), int32_t(aY));
9899
}
99100

100-
static IntPointTyped<Units> Round(const PointTyped<Units, float>& aPoint);
101-
static IntPointTyped<Units> Ceil(const PointTyped<Units, float>& aPoint);
102-
static IntPointTyped<Units> Floor(const PointTyped<Units, float>& aPoint);
103-
static IntPointTyped<Units> Truncate(const PointTyped<Units, float>& aPoint);
101+
static IntPointTyped Round(const PointTyped<Units, float>& aPoint);
102+
static IntPointTyped Ceil(const PointTyped<Units, float>& aPoint);
103+
static IntPointTyped Floor(const PointTyped<Units, float>& aPoint);
104+
static IntPointTyped Truncate(const PointTyped<Units, float>& aPoint);
104105

105106
// XXX When all of the code is ported, the following functions to convert to
106107
// and from unknown types should be removed.
107108

108-
static IntPointTyped<Units> FromUnknownPoint(
109+
static IntPointTyped FromUnknownPoint(
109110
const IntPointTyped<UnknownUnits>& aPoint) {
110111
return IntPointTyped<Units>(aPoint.x, aPoint.y);
111112
}
112113

113114
IntPointTyped<UnknownUnits> ToUnknownPoint() const {
114115
return IntPointTyped<UnknownUnits>(this->x, this->y);
115116
}
117+
118+
IntPointTyped RoundedToMultiple(int32_t aMultiplier) const {
119+
return {RoundToMultiple(this->x, aMultiplier),
120+
RoundToMultiple(this->y, aMultiplier)};
121+
}
116122
};
117123
typedef IntPointTyped<UnknownUnits> IntPoint;
118124

@@ -278,34 +284,49 @@ struct MOZ_EMPTY_BASES IntSizeTyped
278284
constexpr IntSizeTyped(ToInt aWidth, ToInt aHeight)
279285
: Super(aWidth.value, aHeight.value) {}
280286

281-
static IntSizeTyped<Units> Round(float aWidth, float aHeight) {
287+
static IntSizeTyped Round(float aWidth, float aHeight) {
282288
return IntSizeTyped(int32_t(floorf(aWidth + 0.5)),
283289
int32_t(floorf(aHeight + 0.5)));
284290
}
285291

286-
static IntSizeTyped<Units> Truncate(float aWidth, float aHeight) {
292+
static IntSizeTyped Truncate(float aWidth, float aHeight) {
287293
return IntSizeTyped(int32_t(aWidth), int32_t(aHeight));
288294
}
289295

290-
static IntSizeTyped<Units> Ceil(float aWidth, float aHeight) {
296+
static IntSizeTyped Ceil(float aWidth, float aHeight) {
291297
return IntSizeTyped(int32_t(ceil(aWidth)), int32_t(ceil(aHeight)));
292298
}
293299

294-
static IntSizeTyped<Units> Floor(float aWidth, float aHeight) {
300+
static IntSizeTyped Floor(float aWidth, float aHeight) {
295301
return IntSizeTyped(int32_t(floorf(aWidth)), int32_t(floorf(aHeight)));
296302
}
297303

298-
static IntSizeTyped<Units> Round(const SizeTyped<Units, float>& aSize);
299-
static IntSizeTyped<Units> Ceil(const SizeTyped<Units, float>& aSize);
300-
static IntSizeTyped<Units> Floor(const SizeTyped<Units, float>& aSize);
301-
static IntSizeTyped<Units> Truncate(const SizeTyped<Units, float>& aSize);
304+
static IntSizeTyped Round(const SizeTyped<Units, float>& aSize);
305+
static IntSizeTyped Ceil(const SizeTyped<Units, float>& aSize);
306+
static IntSizeTyped Floor(const SizeTyped<Units, float>& aSize);
307+
static IntSizeTyped Truncate(const SizeTyped<Units, float>& aSize);
308+
309+
IntSizeTyped TruncatedToMultiple(int32_t aMultiplier) const {
310+
if (aMultiplier == 1) {
311+
return *this;
312+
}
313+
return {RoundDownToMultiple(this->width, aMultiplier),
314+
RoundDownToMultiple(this->height, aMultiplier)};
315+
}
316+
317+
IntSizeTyped CeiledToMultiple(int32_t aMultiplier) const {
318+
if (aMultiplier == 1) {
319+
return *this;
320+
}
321+
return {RoundUpToMultiple(this->width, aMultiplier),
322+
RoundUpToMultiple(this->height, aMultiplier)};
323+
}
302324

303325
// XXX When all of the code is ported, the following functions to convert to
304326
// and from unknown types should be removed.
305327

306-
static IntSizeTyped<Units> FromUnknownSize(
307-
const IntSizeTyped<UnknownUnits>& aSize) {
308-
return IntSizeTyped<Units>(aSize.width, aSize.height);
328+
static IntSizeTyped FromUnknownSize(const IntSizeTyped<UnknownUnits>& aSize) {
329+
return IntSizeTyped(aSize.width, aSize.height);
309330
}
310331

311332
IntSizeTyped<UnknownUnits> ToUnknownSize() const {

‎gfx/2d/unittest/TestPoint.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ using namespace mozilla::gfx;
1313
TestPoint::TestPoint() {
1414
REGISTER_TEST(TestPoint, Addition);
1515
REGISTER_TEST(TestPoint, Subtraction);
16+
REGISTER_TEST(TestPoint, RoundToMultiple);
1617
}
1718

1819
void TestPoint::Addition() {
@@ -40,3 +41,13 @@ void TestPoint::Subtraction() {
4041
VERIFY(a.x == -3.f);
4142
VERIFY(a.y == 7.f);
4243
}
44+
45+
void TestPoint::RoundToMultiple() {
46+
const int32_t roundTo = 2;
47+
48+
IntPoint p(478, -394);
49+
VERIFY(p.RoundedToMultiple(roundTo) == p);
50+
51+
IntPoint p2(478, 393);
52+
VERIFY(p2.RoundedToMultiple(roundTo) != p2);
53+
}

‎gfx/2d/unittest/TestPoint.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ class TestPoint : public TestBase {
1414

1515
void Addition();
1616
void Subtraction();
17+
void RoundToMultiple();
1718
};

‎view/nsView.cpp

+8-17
Original file line numberDiff line numberDiff line change
@@ -219,23 +219,14 @@ static LayoutDeviceIntRect MaybeRoundToDisplayPixels(
219219
return aRect;
220220
}
221221

222-
auto Truncate = [&](int32_t i) { return (i / aRound) * aRound; };
223-
auto Round = [&](int32_t i) { return Truncate(i + aRound / 2); };
224-
auto RoundSize = [&](int32_t i) {
225-
if (i % aRound == 0) {
226-
return i;
227-
}
228-
const auto truncated = Truncate(i);
229-
if (NS_WARN_IF(aTransparency == TransparencyMode::Opaque)) {
230-
// If the widget doesn't support transparency, we prefer truncating to
231-
// ceiling, so that we don't have extra pixels not painted by our frame.
232-
return truncated;
233-
}
234-
return truncated + aRound;
235-
};
236-
237-
return LayoutDeviceIntRect(Round(aRect.x), Round(aRect.y),
238-
RoundSize(aRect.width), RoundSize(aRect.height));
222+
// If the widget doesn't support transparency, we prefer truncating to
223+
// ceiling, so that we don't have extra pixels not painted by our frame.
224+
auto size = aTransparency == TransparencyMode::Opaque
225+
? aRect.Size().TruncatedToMultiple(aRound)
226+
: aRect.Size().CeiledToMultiple(aRound);
227+
Unused << NS_WARN_IF(aTransparency == TransparencyMode::Opaque &&
228+
size != aRect.Size());
229+
return {aRect.TopLeft().RoundedToMultiple(aRound), size};
239230
}
240231

241232
LayoutDeviceIntRect nsView::CalcWidgetBounds(WindowType aType,

0 commit comments

Comments
 (0)
Failed to load comments.