Skip to content

Commit

Permalink
Add MarkableTraits to FloatRect / FloatPoint / FloatSize
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=262766
rdar://116562787

Reviewed by Chris Dumez.

This patch adds MarkableTraits to FloatRect / FloatPoint / FloatSize.
So that we can use Markable<FloatRect, FloatRect::MarkableTraits> easily.
We also add `fabsConstExpr` to ensure that this is becoming `constexpr`.
And use `isNaNConstExpr` too. Unfortunately they are not constexpr until C++23.

* Source/WTF/wtf/MathExtras.h:
(WTF::fabsConstExpr):
* Source/WebCore/platform/graphics/FloatPoint.h:
(WebCore::FloatPoint::MarkableTraits::isEmptyValue):
(WebCore::FloatPoint::MarkableTraits::emptyValue):
(WebCore::FloatPoint::nanPoint):
(WebCore::FloatPoint::isNaN const):
* Source/WebCore/platform/graphics/FloatRect.h:
(WebCore::FloatRect::MarkableTraits::isEmptyValue):
(WebCore::FloatRect::MarkableTraits::emptyValue):
(WebCore::FloatRect::isNaN const):
* Source/WebCore/platform/graphics/FloatSize.h:
(WebCore::FloatSize::MarkableTraits::isEmptyValue):
(WebCore::FloatSize::MarkableTraits::emptyValue):
(WebCore::FloatSize::isZero const):
(WebCore::FloatSize::nanSize):
(WebCore::FloatSize::isNaN const):
* Tools/TestWebKitAPI/Tests/WebCore/FloatPointTests.cpp:
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/Tests/WebCore/FloatRectTests.cpp:
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/Tests/WebCore/FloatSizeTests.cpp:
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/268992@main
  • Loading branch information
Constellation committed Oct 6, 2023
1 parent 49aa1f6 commit a1e8662
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 3 deletions.
16 changes: 15 additions & 1 deletion Source/WTF/wtf/MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ inline uint32_t reverseBits32(uint32_t value)
#endif
}

// FIXME: Replace with std::isnan() once std::isnan() is constexpr.
// FIXME: Replace with std::isnan() once std::isnan() is constexpr. requires C++23
template<typename T> constexpr typename std::enable_if_t<std::is_floating_point_v<T>, bool> isNaNConstExpr(T value)
{
#if COMPILER_HAS_CLANG_BUILTIN(__builtin_isnan)
Expand All @@ -786,6 +786,19 @@ template<typename T> constexpr typename std::enable_if_t<std::is_integral_v<T>,
return false;
}

// FIXME: Replace with std::fabs() once std::fabs() is constexpr. requires C++23
template<typename T> constexpr bool fabsConstExpr(T value)
{
static_assert(std::is_floating_point_v<T>);
if (value != value)
return value;
if (!value)
return 0.0; // -0.0 should be converted to +0.0
if (value < 0.0)
return -value;
return value;
}

} // namespace WTF

using WTF::shuffleVector;
Expand All @@ -794,4 +807,5 @@ using WTF::ctz;
using WTF::getLSBSet;
using WTF::getMSBSet;
using WTF::isNaNConstExpr;
using WTF::fabsConstExpr;
using WTF::reverseBits32;
28 changes: 28 additions & 0 deletions Source/WebCore/platform/graphics/FloatPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,26 @@ class FloatPoint {
WEBCORE_EXPORT FloatPoint matrixTransform(const TransformationMatrix&) const;
WEBCORE_EXPORT FloatPoint matrixTransform(const AffineTransform&) const;

static constexpr FloatPoint nanPoint();
constexpr bool isNaN() const;

WEBCORE_EXPORT String toJSONString() const;
WEBCORE_EXPORT Ref<JSON::Object> toJSONObject() const;

friend bool operator==(const FloatPoint&, const FloatPoint&) = default;

struct MarkableTraits {
constexpr static bool isEmptyValue(const FloatPoint& point)
{
return point.isNaN();
}

constexpr static FloatPoint emptyValue()
{
return FloatPoint::nanPoint();
}
};

private:
float m_x { 0 };
float m_y { 0 };
Expand Down Expand Up @@ -305,6 +320,19 @@ inline void add(Hasher& hasher, const FloatPoint& point)
add(hasher, point.x(), point.y());
}

constexpr FloatPoint FloatPoint::nanPoint()
{
return {
std::numeric_limits<float>::quiet_NaN(),
std::numeric_limits<float>::quiet_NaN()
};
}

constexpr bool FloatPoint::isNaN() const
{
return isNaNConstExpr(x());
}

WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatPoint&);

}
Expand Down
14 changes: 13 additions & 1 deletion Source/WebCore/platform/graphics/FloatRect.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ class FloatRect {

friend bool operator==(const FloatRect&, const FloatRect&) = default;

struct MarkableTraits {
constexpr static bool isEmptyValue(const FloatRect& rect)
{
return rect.isNaN();
}

constexpr static FloatRect emptyValue()
{
return FloatRect::nanRect();
}
};

private:
FloatPoint m_location;
FloatSize m_size;
Expand Down Expand Up @@ -336,7 +348,7 @@ constexpr FloatRect FloatRect::nanRect()

constexpr bool FloatRect::isNaN() const
{
return isnan(x());
return isNaNConstExpr(x());
}

inline void FloatRect::inflate(float deltaX, float deltaY, float deltaMaxX, float deltaMaxY)
Expand Down
30 changes: 29 additions & 1 deletion Source/WebCore/platform/graphics/FloatSize.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,34 @@ class FloatSize {
operator NSSize() const;
#endif

static constexpr FloatSize nanSize();
constexpr bool isNaN() const;

WEBCORE_EXPORT String toJSONString() const;
WEBCORE_EXPORT Ref<JSON::Object> toJSONObject() const;

friend bool operator==(const FloatSize&, const FloatSize&) = default;

struct MarkableTraits {
constexpr static bool isEmptyValue(const FloatSize& size)
{
return size.isNaN();
}

constexpr static FloatSize emptyValue()
{
return FloatSize::nanSize();
}
};

private:
float m_width { 0 };
float m_height { 0 };
};

constexpr bool FloatSize::isZero() const
{
return std::abs(m_width) < std::numeric_limits<float>::epsilon() && std::abs(m_height) < std::numeric_limits<float>::epsilon();
return fabsConstExpr(m_width) < std::numeric_limits<float>::epsilon() && fabsConstExpr(m_height) < std::numeric_limits<float>::epsilon();
}

inline FloatSize& operator+=(FloatSize& a, const FloatSize& b)
Expand Down Expand Up @@ -252,6 +267,19 @@ inline IntPoint flooredIntPoint(const FloatSize& p)
return IntPoint(clampToInteger(floorf(p.width())), clampToInteger(floorf(p.height())));
}

constexpr FloatSize FloatSize::nanSize()
{
return {
std::numeric_limits<float>::quiet_NaN(),
std::numeric_limits<float>::quiet_NaN()
};
}

constexpr bool FloatSize::isNaN() const
{
return isNaNConstExpr(width());
}

WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatSize&);

} // namespace WebCore
Expand Down
12 changes: 12 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebCore/FloatPointTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <WebCore/IntPoint.h>
#include <WebCore/IntSize.h>
#include <WebCore/TransformationMatrix.h>
#include <wtf/Markable.h>

#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
Expand Down Expand Up @@ -577,4 +578,15 @@ TEST(FloatPoint, Casting)
#endif
}

TEST(FloatPoint, Markable)
{
WebCore::FloatPoint point(1024.3f, 768.6f);
Markable<WebCore::FloatPoint, WebCore::FloatPoint::MarkableTraits> optional;
EXPECT_FALSE(optional) << "nullopt";
optional = point;
EXPECT_EQ((optional.value_or(WebCore::FloatPoint { })), point) << "retained";
optional = WebCore::FloatPoint::nanPoint();
EXPECT_FALSE(optional) << "nullopt";
}

}
12 changes: 12 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebCore/FloatRectTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <WebCore/FloatRect.h>
#include <WebCore/FloatSize.h>
#include <WebCore/IntRect.h>
#include <wtf/Markable.h>

#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
Expand Down Expand Up @@ -735,4 +736,15 @@ TEST(FloatRect, RoundedIntRect)
EXPECT_EQ(789, enclosed.maxY());
}

TEST(FloatRect, Markable)
{
WebCore::FloatRect rect(10.0f, 20.0f, 1024.3f, 768.6f);
Markable<WebCore::FloatRect, WebCore::FloatRect::MarkableTraits> optional;
EXPECT_FALSE(optional) << "nullopt";
optional = rect;
EXPECT_EQ((optional.value_or(WebCore::FloatRect { })), rect) << "retained";
optional = WebCore::FloatRect::nanRect();
EXPECT_FALSE(optional) << "nullopt";
}

}
12 changes: 12 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebCore/FloatSizeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <WebCore/FloatSize.h>
#include <WebCore/IntPoint.h>
#include <WebCore/IntSize.h>
#include <wtf/Markable.h>

#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
Expand Down Expand Up @@ -329,4 +330,15 @@ TEST(FloatSize, Rounded)
EXPECT_EQ(769, expandedSize.height());
}

TEST(FloatSize, Markable)
{
WebCore::FloatSize size(1024.3f, 768.6f);
Markable<WebCore::FloatSize, WebCore::FloatSize::MarkableTraits> optional;
EXPECT_FALSE(optional) << "nullopt";
optional = size;
EXPECT_EQ((optional.value_or(WebCore::FloatSize { })), size) << "retained";
optional = WebCore::FloatSize::nanSize();
EXPECT_FALSE(optional) << "nullopt";
}

}

0 comments on commit a1e8662

Please sign in to comment.