mirror of
https://github.com/thunderbrewhq/squall.git
synced 2026-02-04 08:59:07 +00:00
feat(region): add SRgnGetRectParamsf
This commit is contained in:
parent
ff85d9138d
commit
a5c55bc803
3 changed files with 153 additions and 14 deletions
104
storm/Region.cpp
104
storm/Region.cpp
|
|
@ -106,6 +106,45 @@ void DeleteRect(RECTF* rect) {
|
||||||
rect->top = std::numeric_limits<float>::max();
|
rect->top = std::numeric_limits<float>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SortFoundParamsCallback(const void* elem1, const void* elem2) {
|
||||||
|
const FOUNDPARAM* param1 = static_cast<const FOUNDPARAM*>(elem1);
|
||||||
|
const FOUNDPARAM* param2 = static_cast<const FOUNDPARAM*>(elem2);
|
||||||
|
|
||||||
|
return param1->sequence - param2->sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindSourceParams(RGN* rgnptr, const RECTF* rect) {
|
||||||
|
if (CompareRects(rect, &rgnptr->foundparamsrect)) return;
|
||||||
|
|
||||||
|
rgnptr->foundparams.SetCount(0);
|
||||||
|
uint32_t sourceRects = rgnptr->source.Count();
|
||||||
|
uint32_t params = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sourceRects; i++) {
|
||||||
|
if (!CheckForIntersection(rect, &rgnptr->source[i].rect)) continue;
|
||||||
|
|
||||||
|
int32_t sequence = rgnptr->source[i].sequence;
|
||||||
|
int32_t found = 0;
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < params; j++) {
|
||||||
|
if (rgnptr->foundparams[j].sequence == sequence) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
FOUNDPARAM* newParam = rgnptr->foundparams.New();
|
||||||
|
newParam->param = rgnptr->source[i].param;
|
||||||
|
newParam->sequence = sequence;
|
||||||
|
params++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::qsort(rgnptr->foundparams.Ptr(), rgnptr->foundparams.Count(), sizeof(FOUNDPARAM), SortFoundParamsCallback);
|
||||||
|
rgnptr->foundparamsrect = *rect;
|
||||||
|
}
|
||||||
|
|
||||||
void FragmentCombinedRectangles(TSGrowableArray<RECTF>* combinedArray, uint32_t firstIndex, uint32_t lastIndex, const RECTF* rect) {
|
void FragmentCombinedRectangles(TSGrowableArray<RECTF>* combinedArray, uint32_t firstIndex, uint32_t lastIndex, const RECTF* rect) {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
RECTF* checkRect;
|
RECTF* checkRect;
|
||||||
|
|
@ -249,8 +288,8 @@ void ProcessBooleanOperation(TSGrowableArray<SOURCE>* sourceArray, int32_t combi
|
||||||
}
|
}
|
||||||
|
|
||||||
int SortRectCallback(const void* elem1, const void* elem2) {
|
int SortRectCallback(const void* elem1, const void* elem2) {
|
||||||
RECTF* rct1 = (RECTF*)elem1;
|
const RECTF* rct1 = static_cast<const RECTF*>(elem1);
|
||||||
RECTF* rct2 = (RECTF*)elem2;
|
const RECTF* rct2 = static_cast<const RECTF*>(elem2);
|
||||||
|
|
||||||
double result = rct1->top == rct2->top ? rct1->left - rct2->left : rct1->top - rct2->top;
|
double result = rct1->top == rct2->top ? rct1->left - rct2->left : rct1->top - rct2->top;
|
||||||
|
|
||||||
|
|
@ -272,7 +311,7 @@ void ProduceCombinedRectangles(RGN* rgn) {
|
||||||
|
|
||||||
CombineRectangles(&rgn->combined);
|
CombineRectangles(&rgn->combined);
|
||||||
|
|
||||||
std::qsort(rgn->combined.Ptr(), rgn->combined.Count(), sizeof(rgn->combined.Ptr()[0]), SortRectCallback);
|
std::qsort(rgn->combined.Ptr(), rgn->combined.Count(), sizeof(RECTF), SortRectCallback);
|
||||||
|
|
||||||
for (uint32_t i = rgn->combined.Count(); i > 0; i = rgn->combined.Count()) {
|
for (uint32_t i = rgn->combined.Count(); i > 0; i = rgn->combined.Count()) {
|
||||||
if (!IsNullRect(&rgn->combined[i-1])) break;
|
if (!IsNullRect(&rgn->combined[i-1])) break;
|
||||||
|
|
@ -347,17 +386,17 @@ void SRgnDelete(HSRGN handle) {
|
||||||
s_rgntable.Delete(handle);
|
s_rgntable.Delete(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SRgnDuplicate(HSRGN orighandle, HSRGN *handle, uint32_t reserved) {
|
void SRgnDuplicate(HSRGN origHandle, HSRGN* handle, uint32_t reserved) {
|
||||||
STORM_VALIDATE_BEGIN;
|
STORM_VALIDATE_BEGIN;
|
||||||
STORM_VALIDATE(handle);
|
STORM_VALIDATE(handle);
|
||||||
*handle = nullptr;
|
*handle = nullptr;
|
||||||
|
|
||||||
STORM_VALIDATE(orighandle);
|
STORM_VALIDATE(origHandle);
|
||||||
STORM_VALIDATE(reserved == 0);
|
STORM_VALIDATE(reserved == 0);
|
||||||
STORM_VALIDATE_END_VOID;
|
STORM_VALIDATE_END_VOID;
|
||||||
|
|
||||||
HLOCKEDRGN origlockedhandle;
|
HLOCKEDRGN origlockedhandle;
|
||||||
auto rgn = s_rgntable.Lock(orighandle, &origlockedhandle, 0);
|
auto rgn = s_rgntable.Lock(origHandle, &origlockedhandle, 0);
|
||||||
|
|
||||||
if (rgn) {
|
if (rgn) {
|
||||||
HLOCKEDRGN newlockedhandle;
|
HLOCKEDRGN newlockedhandle;
|
||||||
|
|
@ -406,16 +445,57 @@ void SRgnGetBoundingRectf(HSRGN handle, RECTF* rect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SRgnGetRectsf(HSRGN handle, uint32_t* numrects, RECTF* buffer) {
|
void SRgnGetRectParamsf(HSRGN handle, RECTF* rect, uint32_t* numParams, void** buffer) {
|
||||||
STORM_VALIDATE_BEGIN;
|
STORM_VALIDATE_BEGIN;
|
||||||
STORM_VALIDATE(handle);
|
STORM_VALIDATE(handle);
|
||||||
STORM_VALIDATE(numrects);
|
STORM_VALIDATE(rect);
|
||||||
|
STORM_VALIDATE(numParams);
|
||||||
|
STORM_VALIDATE_END_VOID;
|
||||||
|
|
||||||
|
if (IsNullRect(rect)) {
|
||||||
|
*numParams = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HLOCKEDRGN lockedHandle;
|
||||||
|
auto rgn = s_rgntable.Lock(handle, &lockedHandle, 0);
|
||||||
|
if (!rgn) {
|
||||||
|
*numParams = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rgn->dirty) {
|
||||||
|
ProduceCombinedRectangles(rgn);
|
||||||
|
rgn->dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindSourceParams(rgn, rect);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
*numParams = std::min(*numParams, rgn->foundparams.Count());
|
||||||
|
FOUNDPARAM* foundArray = rgn->foundparams.Ptr();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < *numParams; i++) {
|
||||||
|
buffer[i] = foundArray[i].param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*numParams = rgn->foundparams.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
s_rgntable.Unlock(lockedHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SRgnGetRectsf(HSRGN handle, uint32_t* numRects, RECTF* buffer) {
|
||||||
|
STORM_VALIDATE_BEGIN;
|
||||||
|
STORM_VALIDATE(handle);
|
||||||
|
STORM_VALIDATE(numRects);
|
||||||
STORM_VALIDATE_END_VOID;
|
STORM_VALIDATE_END_VOID;
|
||||||
|
|
||||||
HLOCKEDRGN lockedHandle;
|
HLOCKEDRGN lockedHandle;
|
||||||
auto rgn = s_rgntable.Lock(handle, &lockedHandle, 0);
|
auto rgn = s_rgntable.Lock(handle, &lockedHandle, 0);
|
||||||
if (!rgn) {
|
if (!rgn) {
|
||||||
*numrects = 0;
|
*numRects = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,11 +505,11 @@ void SRgnGetRectsf(HSRGN handle, uint32_t* numrects, RECTF* buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
*numrects = std::min(*numrects, rgn->combined.Count());
|
*numRects = std::min(*numRects, rgn->combined.Count());
|
||||||
memcpy(buffer, rgn->combined.Ptr(), sizeof(rgn->combined.Ptr()[0]) * *numrects);
|
memcpy(buffer, rgn->combined.Ptr(), sizeof(rgn->combined.Ptr()[0]) * *numRects);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*numrects = rgn->combined.Count();
|
*numRects = rgn->combined.Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
s_rgntable.Unlock(lockedHandle);
|
s_rgntable.Unlock(lockedHandle);
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,12 @@ void SRgnCreate(HSRGN* handlePtr, uint32_t reserved = 0);
|
||||||
|
|
||||||
void SRgnDelete(HSRGN handle);
|
void SRgnDelete(HSRGN handle);
|
||||||
|
|
||||||
void SRgnDuplicate(HSRGN orighandle, HSRGN *handle, uint32_t reserved = 0);
|
void SRgnDuplicate(HSRGN origHandle, HSRGN* handle, uint32_t reserved = 0);
|
||||||
|
|
||||||
void SRgnGetBoundingRectf(HSRGN handle, RECTF* rect);
|
void SRgnGetBoundingRectf(HSRGN handle, RECTF* rect);
|
||||||
|
|
||||||
void SRgnGetRectsf(HSRGN handle, uint32_t* numrects, RECTF* buffer);
|
void SRgnGetRectParamsf(HSRGN handle, RECTF* rect, uint32_t* numParams, void** buffer);
|
||||||
|
|
||||||
|
void SRgnGetRectsf(HSRGN handle, uint32_t* numRects, RECTF* buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,54 @@ TEST_CASE("SRgnDuplicate", "[region]") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SRgnGetRectParamsf", "[region]") {
|
||||||
|
RgnDataTest region;
|
||||||
|
|
||||||
|
SECTION("retrieves empty list if nothing put in") {
|
||||||
|
uint32_t numParams = 1;
|
||||||
|
void* buffer[1];
|
||||||
|
|
||||||
|
RECTF rect = { 0, 0, 1, 1 };
|
||||||
|
SRgnGetRectParamsf(region, &rect, &numParams, buffer);
|
||||||
|
|
||||||
|
CHECK(numParams == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("retrieves 0 when using an invalid region object") {
|
||||||
|
HSRGN inval = reinterpret_cast<HSRGN>(1234);
|
||||||
|
|
||||||
|
uint32_t numParams = 1;
|
||||||
|
RECTF rect = { 0, 0, 1, 1 };
|
||||||
|
SRgnGetRectParamsf(inval, &rect, &numParams, nullptr);
|
||||||
|
|
||||||
|
CHECK(numParams == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("retrieves only overlapping params") {
|
||||||
|
RECTF rect1 = { 0, 0, 1, 1 };
|
||||||
|
RECTF rect2 = { 2, 2, 4, 4 };
|
||||||
|
RECTF rect3 = { 2.5, 2.5, 5, 5 };
|
||||||
|
RECTF queryRect = { 3, 3, 5, 5 };
|
||||||
|
int param1 = 5;
|
||||||
|
int param2 = 10;
|
||||||
|
int param3 = 11;
|
||||||
|
|
||||||
|
SRgnCombineRectf(region, &rect1, ¶m1, SRGN_PARAMONLY);
|
||||||
|
SRgnCombineRectf(region, &rect2, ¶m2, SRGN_PARAMONLY);
|
||||||
|
SRgnCombineRectf(region, &rect3, ¶m3, SRGN_PARAMONLY);
|
||||||
|
|
||||||
|
uint32_t numParams = 0;
|
||||||
|
SRgnGetRectParamsf(region, &queryRect, &numParams, nullptr);
|
||||||
|
REQUIRE(numParams == 2);
|
||||||
|
|
||||||
|
void* buffer[2];
|
||||||
|
SRgnGetRectParamsf(region, &queryRect, &numParams, buffer);
|
||||||
|
CHECK(numParams == 2);
|
||||||
|
CHECK(buffer[0] == ¶m2);
|
||||||
|
CHECK(buffer[1] == ¶m3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("SRgnGetRectsf", "[region]") {
|
TEST_CASE("SRgnGetRectsf", "[region]") {
|
||||||
RgnDataTest region;
|
RgnDataTest region;
|
||||||
|
|
||||||
|
|
@ -155,6 +203,15 @@ TEST_CASE("SRgnGetRectsf", "[region]") {
|
||||||
CHECK(numrects == 0);
|
CHECK(numrects == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("retrieves 0 when using an invalid region object") {
|
||||||
|
HSRGN inval = reinterpret_cast<HSRGN>(1234);
|
||||||
|
|
||||||
|
uint32_t numrects = 1;
|
||||||
|
SRgnGetRectsf(inval, &numrects, nullptr);
|
||||||
|
|
||||||
|
CHECK(numrects == 0);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("retrieves all rects that were put in") {
|
SECTION("retrieves all rects that were put in") {
|
||||||
RECTF rct1 = { 5, 5, 10, 10 };
|
RECTF rct1 = { 5, 5, 10, 10 };
|
||||||
RECTF rct2 = { 0, 0, 1, 1 };
|
RECTF rct2 = { 0, 0, 1, 1 };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue