Commit 653fcfdc authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Added ability to scale empty rects, and scale rects to zero.

Previous to this CL, the SkRRect backing for gfx::RRectF would
not allow scaling rects to zero, or scaling empty rects by any
factor. With this CL, both operations are supported and tested.

Bug: 497522

Change-Id: I2766d92502954ddbc052a3bb3d29f8f07de201d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1525055
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641689}
parent 1c4ea009
...@@ -12,6 +12,24 @@ ...@@ -12,6 +12,24 @@
namespace gfx { namespace gfx {
// Sets all x radii to x_rad, and all y radii to y_rad. If one of x_rad or
// y_rad are zero, sets ALL radii to zero.
RRectF::RRectF(float x,
float y,
float width,
float height,
float x_rad,
float y_rad)
: skrrect_(SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, width, height),
x_rad,
y_rad)) {
if (IsEmpty()) {
// Make sure that empty rects are created fully empty, not with some
// non-zero dimensions.
skrrect_ = SkRRect::MakeEmpty();
}
}
// Directly sets all four corners. // Directly sets all four corners.
RRectF::RRectF(float x, RRectF::RRectF(float x,
float y, float y,
...@@ -91,6 +109,15 @@ void RRectF::SetCornerRadii(Corner corner, float x_rad, float y_rad) { ...@@ -91,6 +109,15 @@ void RRectF::SetCornerRadii(Corner corner, float x_rad, float y_rad) {
} }
void RRectF::Scale(float x_scale, float y_scale) { void RRectF::Scale(float x_scale, float y_scale) {
if (IsEmpty()) {
// SkRRect doesn't support scaling of empty rects.
return;
}
if (!x_scale || !y_scale) {
// SkRRect doesn't support scaling TO an empty rect.
skrrect_ = SkRRect::MakeEmpty();
return;
}
SkMatrix scale = SkMatrix::MakeScale(x_scale, y_scale); SkMatrix scale = SkMatrix::MakeScale(x_scale, y_scale);
SkRRect result; SkRRect result;
bool success = skrrect_.transform(scale, &result); bool success = skrrect_.transform(scale, &result);
......
...@@ -30,10 +30,7 @@ class GEOMETRY_SKIA_EXPORT RRectF { ...@@ -30,10 +30,7 @@ class GEOMETRY_SKIA_EXPORT RRectF {
: RRectF(x, y, width, height, radius, radius) {} : RRectF(x, y, width, height, radius, radius) {}
// Sets all x radii to x_rad, and all y radii to y_rad. If one of x_rad or // Sets all x radii to x_rad, and all y radii to y_rad. If one of x_rad or
// y_rad are zero, sets ALL radii to zero. // y_rad are zero, sets ALL radii to zero.
RRectF(float x, float y, float width, float height, float x_rad, float y_rad) RRectF(float x, float y, float width, float height, float x_rad, float y_rad);
: skrrect_(SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, width, height),
x_rad,
y_rad)) {}
// Directly sets all four corners. // Directly sets all four corners.
RRectF(float x, RRectF(float x,
float y, float y,
......
...@@ -18,18 +18,20 @@ TEST(RRectFTest, IsEmpty) { ...@@ -18,18 +18,20 @@ TEST(RRectFTest, IsEmpty) {
} }
TEST(RRectFTest, Equals) { TEST(RRectFTest, Equals) {
ASSERT_TRUE(RRectF(0, 0, 0, 0, 0, 0) == RRectF(0, 0, 0, 0, 0, 0)); EXPECT_EQ(RRectF(0, 0, 0, 0, 0, 0), RRectF(0, 0, 0, 0, 0, 0));
ASSERT_TRUE(RRectF(1, 2, 3, 4, 5, 6) == RRectF(1, 2, 3, 4, 5, 6)); EXPECT_EQ(RRectF(1, 2, 3, 4, 5, 6), RRectF(1, 2, 3, 4, 5, 6));
ASSERT_TRUE(RRectF(1, 2, 3, 4, 5, 5) == RRectF(1, 2, 3, 4, 5)); EXPECT_EQ(RRectF(1, 2, 3, 4, 5, 5), RRectF(1, 2, 3, 4, 5));
ASSERT_TRUE(RRectF(0, 0, 2, 3, 0, 0) == RRectF(0, 0, 2, 3, 0, 1)); EXPECT_EQ(RRectF(0, 0, 2, 3, 0, 0), RRectF(0, 0, 2, 3, 0, 1));
ASSERT_TRUE(RRectF(0, 0, 2, 3, 0, 0) == RRectF(0, 0, 2, 3, 1, 0)); EXPECT_EQ(RRectF(0, 0, 2, 3, 0, 0), RRectF(0, 0, 2, 3, 1, 0));
EXPECT_EQ(RRectF(1, 2, 3, 0, 5, 6), RRectF(0, 0, 0, 0, 0, 0));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(1, 20, 30, 40, 7, 8)); EXPECT_EQ(RRectF(0, 0, 0, 0, 5, 6), RRectF(0, 0, 0, 0, 0, 0));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(10, 2, 30, 40, 7, 8));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(10, 20, 3, 40, 7, 8)); EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(1, 20, 30, 40, 7, 8));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(10, 20, 30, 4, 7, 8)); EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(10, 2, 30, 40, 7, 8));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(10, 20, 30, 40, 5, 8)); EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(10, 20, 3, 40, 7, 8));
ASSERT_TRUE(RRectF(10, 20, 30, 40, 7, 8) != RRectF(10, 20, 30, 40, 7, 6)); EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(10, 20, 30, 4, 7, 8));
EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(10, 20, 30, 40, 5, 8));
EXPECT_NE(RRectF(10, 20, 30, 40, 7, 8), RRectF(10, 20, 30, 40, 7, 6));
} }
TEST(RRectFTest, PlusMinusOffset) { TEST(RRectFTest, PlusMinusOffset) {
...@@ -187,38 +189,55 @@ TEST(RRectFTest, Contains) { ...@@ -187,38 +189,55 @@ TEST(RRectFTest, Contains) {
TEST(RRectFTest, Scale) { TEST(RRectFTest, Scale) {
// Note that SKRRect (the backing for RRectF) does not support scaling by NaN, // Note that SKRRect (the backing for RRectF) does not support scaling by NaN,
// scaling out of numerical bounds, or scaling to zero. So this test doesn't // or scaling out of numerical bounds. So this test doesn't exercise those.
// exercise those.
static const struct Test { static const struct Test {
float x1; // source float x1; // source
float y1; float y1;
float w1; float w1;
float h1; float h1;
float r1; float x_rad1;
float y_rad1;
float scale; float x_scale;
float y_scale;
float x2; // target float x2; // target
float y2; float y2;
float w2; float w2;
float h2; float h2;
float r2; float x_rad2;
float y_rad2;
} tests[] = { } tests[] = {
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.5f, 4.5f, 6.0f, 7.5f, 9.0f, 1.5f}, {3.0f, 4.0f, 5.0f, 6.0f, 0.0f, 0.0f, 1.5f, 1.5f, 4.5f, 6.0f, 7.5f, 9.0f,
{3.0f, 4.0f, 5.0f, 6.0f, 0.0f, 1.5f, 4.5f, 6.0f, 7.5f, 9.0f, 0.0f}, 0.0f, 0.0f},
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.0f, 1.5f, 1.5f, 4.5f, 6.0f, 7.5f, 9.0f,
1.5f, 1.5f},
{3.0f, 4.0f, 5.0f, 6.0f, 0.0f, 0.0f, 1.5f, 3.0f, 4.5f, 12.0f, 7.5f, 18.0f,
0.0f, 0.0f},
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.0f, 1.5f, 3.0f, 4.5f, 12.0f, 7.5f, 18.0f,
1.5f, 3.0f},
{3.0f, 4.0f, 0.0f, 6.0f, 1.0f, 1.0f, 1.5f, 1.5f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f},
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f},
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f},
{3.0f, 4.0f, 5.0f, 6.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f},
}; };
for (size_t i = 0; i < base::size(tests); ++i) { for (size_t i = 0; i < base::size(tests); ++i) {
RRectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1, tests[i].r1); RRectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1,
RRectF r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2, tests[i].r2); tests[i].x_rad1, tests[i].y_rad1);
RRectF r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2,
tests[i].x_rad2, tests[i].y_rad2);
r1.Scale(tests[i].scale); r1.Scale(tests[i].x_scale, tests[i].y_scale);
EXPECT_TRUE((r1.GetType() == RRectF::Type::kRect) || ASSERT_TRUE(r1.GetType() <= RRectF::Type::kSimple);
(r1.GetType() == RRectF::Type::kSingle));
EXPECT_EQ(r1.rect().x(), r2.rect().x()); EXPECT_EQ(r1.rect().x(), r2.rect().x());
EXPECT_EQ(r1.rect().y(), r2.rect().y()); EXPECT_EQ(r1.rect().y(), r2.rect().y());
EXPECT_EQ(r1.rect().width(), r2.rect().width()); EXPECT_EQ(r1.rect().width(), r2.rect().width());
EXPECT_EQ(r1.rect().height(), r2.rect().height()); EXPECT_EQ(r1.rect().height(), r2.rect().height());
EXPECT_EQ(r1.GetSimpleRadius(), r2.GetSimpleRadius()); EXPECT_EQ(r1.GetSimpleRadii(), r2.GetSimpleRadii());
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment