feat(region): add SRgnIsRectInRegionf

This commit is contained in:
Adam Heinermann 2025-04-21 19:26:24 -07:00 committed by fallenoak
parent d322f579a2
commit c143493110
3 changed files with 105 additions and 0 deletions

View file

@ -541,3 +541,30 @@ int32_t SRgnIsPointInRegionf(HSRGN handle, float x, float y) {
s_rgntable.Unlock(lockedHandle); s_rgntable.Unlock(lockedHandle);
return result; return result;
} }
int32_t SRgnIsRectInRegionf(HSRGN handle, const RECTF* rect) {
STORM_VALIDATE_BEGIN;
STORM_VALIDATE(handle);
STORM_VALIDATE(rect);
STORM_VALIDATE_END;
HLOCKEDRGN lockedHandle;
auto rgn = s_rgntable.Lock(handle, &lockedHandle, 0);
if (!rgn) return 0;
int32_t result = 0;
SOURCE* sourceArray = rgn->source.Ptr();
uint32_t sourceRects = rgn->source.Count();
for (uint32_t i = 0; i < sourceRects; i++) {
if (!(sourceArray[i].flags & SF_PARAMONLY)) {
if (CheckForIntersection(rect, &sourceArray[i].rect)) {
result = 1;
break;
}
}
}
s_rgntable.Unlock(lockedHandle);
return result;
}

View file

@ -22,5 +22,7 @@ void SRgnGetRectsf(HSRGN handle, uint32_t* numRects, RECTF* buffer);
int32_t SRgnIsPointInRegionf(HSRGN handle, float x, float y); int32_t SRgnIsPointInRegionf(HSRGN handle, float x, float y);
int32_t SRgnIsRectInRegionf(HSRGN handle, const RECTF* rect);
#endif #endif

View file

@ -297,3 +297,79 @@ TEST_CASE("SRgnIsPointInRegionf", "[region]") {
CHECK_FALSE(SRgnIsPointInRegionf(region, 0.9999f, 1.0f)); CHECK_FALSE(SRgnIsPointInRegionf(region, 0.9999f, 1.0f));
} }
} }
TEST_CASE("SRgnIsRectInRegionf", "[region]") {
RgnDataTest region;
RECTF rect = { 0.0f, 0.0f, 1.0f, 1.0f };
SECTION("false if region has no rects") {
CHECK_FALSE(SRgnIsRectInRegionf(region, &rect));
}
SECTION("false if using an invalid region object") {
HSRGN inval = reinterpret_cast<HSRGN>(1234);
CHECK_FALSE(SRgnIsRectInRegionf(inval, &rect));
}
SECTION("reports if rects overlap a region") {
RECTF checkRects[] = {
{ 0.5f, 0.5f, 0.5f, 0.5f },
{ 0.00001f, 0.00001f, 0.999999f, 0.999999f },
{ 11.0f, 11.0f, 12.0f, 19.0f },
{ 14.0f, 14.0f, 20.0f, 20.0f },
{ -100.0f, -100.0f, 0.000001f, 0.0000001f },
};
RECTF secondRect = { 10.0f, 10.0f, 15.0f, 20.0f };
SRgnCombineRectf(region, &rect, nullptr, SRGN_OR);
SRgnCombineRectf(region, &secondRect, nullptr, SRGN_OR);
CHECK(SRgnIsRectInRegionf(region, &checkRects[0]));
CHECK(SRgnIsRectInRegionf(region, &checkRects[1]));
CHECK(SRgnIsRectInRegionf(region, &checkRects[2]));
CHECK(SRgnIsRectInRegionf(region, &checkRects[3]));
CHECK(SRgnIsRectInRegionf(region, &checkRects[4]));
}
SECTION("reports if rects are outside a region") {
RECTF checkRects[] = {
{ 2.0f, 2.0f, 2.0f, 2.0f },
{ 1.0f, 1.0f, 2.0f, 2.0f },
{ -1.0f, -1.0f, 0.0f, 0.0f },
{ 9.0f, 9.0f, 10.0f, 10.0f }
};
RECTF secondRect = { 10.0f, 10.0f, 15.0f, 20.0f };
SRgnCombineRectf(region, &rect, nullptr, SRGN_OR);
SRgnCombineRectf(region, &secondRect, nullptr, SRGN_OR);
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[0]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[1]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[2]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[3]));
}
SECTION("ignores param only rects") {
SRgnCombineRectf(region, &rect, &rect, SRGN_PARAMONLY);
CHECK_FALSE(SRgnIsRectInRegionf(region, &rect));
}
SECTION("excludes matching on rect bounds") {
RECTF checkRects[] = {
{ -0.1f, -0.1f, 0.0f, 1.0f },
{ -0.1f, -0.1f, 1.0f, 0.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.5f, 0.0f, 0.5f, 0.0f },
{ 0.0f, 0.5f, 0.0f, 0.5f },
};
SRgnCombineRectf(region, &rect, nullptr, SRGN_OR);
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[0]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[1]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[2]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[3]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[4]));
CHECK_FALSE(SRgnIsRectInRegionf(region, &checkRects[5]));
}
}