Skip to content

Commit

Permalink
Update slicing methods API
Browse files Browse the repository at this point in the history
Now all the slice methods are const and return *this. Also
sliceV and sliceH now use two references to return the results
  • Loading branch information
martincapello committed Jul 31, 2024
1 parent 96df4bd commit cbcb6cd
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 71 deletions.
84 changes: 44 additions & 40 deletions gfx/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,41 +410,41 @@ class RectT {
}

// Slices vertically this Rect along the provided px coordinate.
// This rect is the right slice and the returned rect is the left slice.
RectT sliceV(T px) {
if (px < x)
return RectT<T>();

if (px > x2()) {
auto leftSlice = *this;
x = y = w = h = 0;
return leftSlice;
// Sets the left and right rects in the references of the same name.
const RectT& sliceV(T px, RectT& left, RectT& right) const {
if (px < x) {
left = RectT();
right = *this;
}
else if (px > x2()) {
left = *this;
right = RectT();
}
else {
left = RectT(x, y, px - x, h);
right = RectT(px, y, x2() - px, h);
}

gfx::RectT<T> leftSlice = RectT<T>(x, y, px - x, h);

w = x2() - px;
x = px;
return leftSlice;
return *this;
}

// Slices horizontally this Rect along the provided py coordinate.
// This rect is the bottom slice and the returned rect is the top slice.
RectT sliceH(T py) {
if (py < y)
return RectT<T>();

if (py > y2()) {
auto topSlice = *this;
x = y = w = h = 0;
return topSlice;
// Sets the top and bottom rects in the references of the same name.
const RectT& sliceH(T py, RectT& top, RectT& bottom) const {
if (py < y) {
top = RectT();
bottom = *this;
}
else if (py > y2()) {
top = *this;
bottom = RectT();
}
else {
top = RectT(x, y, w, py - y);
bottom = RectT(x, py, w, y2() - py);
}

auto topSlice = RectT<T>(x, y, w, py - y);

h = y2() - py;
y = py;
return topSlice;
return *this;
}

// Slices this rect in nine pieces and returns all the rects in the slices
Expand All @@ -460,24 +460,28 @@ class RectT {
// | | | [6] | [7] | [8] |
// +---------------------+ +--------+-----+------+
//
// Note that this method doesn't modify this rect.
void nineSlice(RectT<T> center, RectT<T> slices[9]) const {
RectT<T> remaining = *this;
gfx::RectT<T> left = remaining.sliceV(x + center.x);
RectT<T> middle = remaining.sliceV(x + center.x2());
RectT<T> right = remaining;
const RectT& nineSlice(const RectT& center, RectT slices[9]) const {
gfx::RectT<T> left, middle, right;

slices[0] = left.sliceH(y + center.y);
slices[1] = middle.sliceH(y + center.y);
slices[2] = right.sliceH(y + center.y);
{
gfx::RectT<T> remaining;
this->sliceV(x + center.x, left, remaining);
remaining.sliceV(x + center.x2(), middle, right);
}

slices[3] = left.sliceH(y + center.y2());
slices[4] = middle.sliceH(y + center.y2());
slices[5] = right.sliceH(y + center.y2());
left .sliceH(y + center.y , slices[0], left);
middle.sliceH(y + center.y , slices[1], middle);
right .sliceH(y + center.y , slices[2], right);

left .sliceH(y + center.y2(), slices[3], left);
middle.sliceH(y + center.y2(), slices[4], middle);
right .sliceH(y + center.y2(), slices[5], right);

slices[6] = left;
slices[7] = middle;
slices[8] = right;

return *this;
}

};
Expand Down
54 changes: 23 additions & 31 deletions gfx/rect_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,80 +68,72 @@ TEST(Rect, Floor)
TEST(Rect, SliceV)
{
const int x = 3, y = 4;
auto r = gfx::Rect(x, y, 5, 7);
auto l = r.sliceV(x);
gfx::Rect l, r;
auto rect = gfx::Rect(x, y, 5, 7);
rect.sliceV(x, l, r);
EXPECT_EQ(gfx::Rect(x,y,0,7), l);
EXPECT_EQ(gfx::Rect(x,y,5,7), r);

r = gfx::Rect(x, y, 5, 7);
l = r.sliceV(x-1);
rect.sliceV(x-1, l, r);
EXPECT_EQ(gfx::Rect(0,0,0,0), l);
EXPECT_EQ(gfx::Rect(x,y,5,7), r);

r = gfx::Rect(x, y, 5, 7);
l = r.sliceV(x+1);
rect.sliceV(x+1, l, r);
EXPECT_EQ(gfx::Rect(x,y,1,7), l);
EXPECT_EQ(gfx::Rect(x+1,y,4,7), r);

r = gfx::Rect(x, y, 5, 7);
l = r.sliceV(x+4);
rect.sliceV(x+4, l, r);
EXPECT_EQ(gfx::Rect(x,y,4,7), l);
EXPECT_EQ(gfx::Rect(x+4,y,1,7), r);

r = gfx::Rect(x, y, 5, 7);
l = r.sliceV(x+5);
rect.sliceV(x+5, l, r);
EXPECT_EQ(gfx::Rect(x,y,5,7), l);
EXPECT_EQ(gfx::Rect(x+5,y,0,7), r);

r = gfx::Rect(x, y, 5, 7);
l = r.sliceV(x+6);
rect.sliceV(x+6, l, r);
EXPECT_EQ(gfx::Rect(x,y,5,7), l);
EXPECT_EQ(gfx::Rect(0,0,0,0), r);
}

TEST(Rect, SliceH)
{
const int x = 3, y = 4;
auto b = gfx::Rect(x, y, 5, 7);
auto t = b.sliceH(y);
gfx::Rect t, b;
auto rect = gfx::Rect(x, y, 5, 7);
rect.sliceH(y, t, b);
EXPECT_EQ(gfx::Rect(x,y,5,0), t);
EXPECT_EQ(gfx::Rect(x,y,5,7), b);

b = gfx::Rect(x, y, 5, 7);
t = b.sliceH(y-1);
rect.sliceH(y-1, t, b);
EXPECT_EQ(gfx::Rect(0,0,0,0), t);
EXPECT_EQ(gfx::Rect(x,y,5,7), b);

b = gfx::Rect(x, y, 5, 7);
t = b.sliceH(y+1);
rect.sliceH(y+1, t, b);
EXPECT_EQ(gfx::Rect(x,y,5,1), t);
EXPECT_EQ(gfx::Rect(x,y+1,5,6), b);

b = gfx::Rect(x, y, 5, 7);
t = b.sliceH(y+6);
rect.sliceH(y+6, t, b);
EXPECT_EQ(gfx::Rect(x,y,5,6), t);
EXPECT_EQ(gfx::Rect(x,y+6,5,1), b);

b = gfx::Rect(x, y, 5, 7);
t = b.sliceH(y+7);
rect.sliceH(y+7, t, b);
EXPECT_EQ(gfx::Rect(x,y,5,7), t);
EXPECT_EQ(gfx::Rect(x,y+7,5,0), b);

b = gfx::Rect(x, y, 5, 7);
t = b.sliceH(y+8);
rect.sliceH(y+8, t, b);
EXPECT_EQ(gfx::Rect(x,y,5,7), t);
EXPECT_EQ(gfx::Rect(0,0,0,0), b);
}

TEST(Rect, NineSlice)
{
const int x = 3, y = 4;
auto r = gfx::Rect(x, y, 6, 6);
auto rect = gfx::Rect(x, y, 6, 6);
gfx::Rect slices[9];

// Slice using an inner rect.
r.nineSlice(gfx::Rect(3, 3, 2, 2), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), r);
rect.nineSlice(gfx::Rect(3, 3, 2, 2), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), rect);
EXPECT_EQ(gfx::Rect(x ,y ,3,3), slices[0]);
EXPECT_EQ(gfx::Rect(x+3,y ,2,3), slices[1]);
EXPECT_EQ(gfx::Rect(x+5,y ,1,3), slices[2]);
Expand All @@ -153,8 +145,8 @@ TEST(Rect, NineSlice)
EXPECT_EQ(gfx::Rect(x+5,y+5,1,1), slices[8]);

// Slice using a center rect with the same size as the rect being sliced.
r.nineSlice(gfx::Rect(0, 0, 6, 6), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), r);
rect.nineSlice(gfx::Rect(0, 0, 6, 6), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), rect);
EXPECT_EQ(gfx::Rect(x ,y ,0,0), slices[0]);
EXPECT_EQ(gfx::Rect(x ,y ,6,0), slices[1]);
EXPECT_EQ(gfx::Rect(x+6,y ,0,0), slices[2]);
Expand All @@ -166,8 +158,8 @@ TEST(Rect, NineSlice)
EXPECT_EQ(gfx::Rect(x+6,y+6,0,0), slices[8]);

// Slice using an outer rect.
r.nineSlice(gfx::Rect(-1, -1, 8, 8), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), r);
rect.nineSlice(gfx::Rect(-1, -1, 8, 8), slices);
EXPECT_EQ(gfx::Rect(x,y,6,6), rect);
EXPECT_EQ(gfx::Rect(0,0,0,0), slices[0]);
EXPECT_EQ(gfx::Rect(0,0,0,0), slices[1]);
EXPECT_EQ(gfx::Rect(0,0,0,0), slices[2]);
Expand Down

0 comments on commit cbcb6cd

Please sign in to comment.