Commit f5124311 authored by Malay Keshav's avatar Malay Keshav Committed by Commit Bot

Apply complete surface transform to rounded corners

This patch applies the complete surface transform to the rounded corner
bounds instead of just the translation and scaling component. This may
however fail if the transform being applied does not result in an axis
aligned output.

Since this is done at multiple code locations, a new API is added to
gfx::Transform to perform this.

Test: Added unittests for the new API.
Change-Id: I75b7234ca7b1abc918b35251b77b0a9f8aec1e2d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1838980Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Malay Keshav <malaykeshav@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706813}
parent d9e39eeb
......@@ -713,14 +713,13 @@ std::pair<gfx::RRectF, bool> GetRoundedCornerRRect(
if (!property_trees->GetToTarget(node->transform_id, target_id, &to_target))
return kEmptyRoundedCornerInfo;
DCHECK(to_target.Preserves2dAxisAlignment());
auto result =
std::make_pair(node->rounded_corner_bounds, node->is_fast_rounded_corner);
SkRRect result;
if (!SkRRect(node->rounded_corner_bounds)
.transform(to_target.matrix(), &result)) {
if (!to_target.TransformRRectF(&result.first))
return kEmptyRoundedCornerInfo;
}
return std::make_pair(gfx::RRectF(result), node->is_fast_rounded_corner);
return result;
}
void UpdateRenderTarget(EffectTree* effect_tree) {
......
......@@ -98,17 +98,15 @@ struct SurfaceAggregator::RoundedCornerInfo {
RoundedCornerInfo() = default;
// |target_transform| is the transform that maps |bounds_arg| from its current
// space into the desired target space. It must be a scale+translation matrix.
// space into the desired target space. It must be an axis aligned transform.
RoundedCornerInfo(const gfx::RRectF& bounds_arg,
bool is_fast_rounded_corner,
const gfx::Transform target_transform)
: bounds(bounds_arg), is_fast_rounded_corner(is_fast_rounded_corner) {
if (bounds.IsEmpty())
return;
DCHECK(target_transform.Preserves2dAxisAlignment());
SkMatrix matrix = target_transform.matrix();
bounds.Scale(matrix.getScaleX(), matrix.getScaleY());
bounds.Offset(target_transform.To2dTranslation());
bool success = target_transform.TransformRRectF(&bounds);
DCHECK(success);
}
gfx::RRectF bounds;
......
......@@ -14,6 +14,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/geometry/vector3d_f.h"
#include "ui/gfx/rrect_f.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform_util.h"
......@@ -485,6 +486,14 @@ bool Transform::TransformRectReverse(RectF* rect) const {
return true;
}
bool Transform::TransformRRectF(RRectF* rrect) const {
SkRRect result;
if (!SkRRect(*rrect).transform(matrix_, &result))
return false;
*rrect = gfx::RRectF(result);
return true;
}
void Transform::TransformBox(BoxF* box) const {
BoxF bounds;
bool first_point = true;
......
......@@ -17,6 +17,7 @@ namespace gfx {
class BoxF;
class RectF;
class RRectF;
class Point;
class PointF;
class Point3F;
......@@ -242,6 +243,10 @@ class GEOMETRY_SKIA_EXPORT Transform {
// inverted.
bool TransformRectReverse(RectF* rect) const;
// Applies transformation on the given |rrect|. Returns false if the transform
// matrix cannot be applied to rrect.
bool TransformRRectF(RRectF* rrect) const;
// Applies transformation on the given box. After the function completes,
// |box| will be the smallest axis aligned bounding box containing the
// transformed box.
......
......@@ -19,6 +19,7 @@
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/vector3d_f.h"
#include "ui/gfx/rrect_f.h"
#include "ui/gfx/transform_util.h"
namespace gfx {
......@@ -2638,6 +2639,35 @@ TEST(XFormTest, TransformRectReverse) {
EXPECT_FALSE(singular.TransformRectReverse(&rect));
}
TEST(XFormTest, TransformRRectF) {
Transform translation;
translation.Translate(-3.f, -7.f);
RRectF rrect(1.f, 2.f, 20.f, 25.f, 5.f);
RRectF expected(-2.f, -5.f, 20.f, 25.f, 5.f);
EXPECT_TRUE(translation.TransformRRectF(&rrect));
EXPECT_EQ(expected.ToString(), rrect.ToString());
SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
rot.set3x3(0, 1, 0, -1, 0, 0, 0, 0, 1);
Transform rotation_90_Clock(rot);
rrect = RRectF(gfx::RectF(0, 0, 20.f, 25.f),
gfx::RoundedCornersF(1.f, 2.f, 3.f, 4.f));
expected = RRectF(gfx::RectF(-25.f, 0, 25.f, 20.f),
gfx::RoundedCornersF(4.f, 1.f, 2.f, 3.f));
EXPECT_TRUE(rotation_90_Clock.TransformRRectF(&rrect));
EXPECT_EQ(expected.ToString(), rrect.ToString());
Transform scale;
scale.Scale(2.f, 2.f);
rrect = RRectF(gfx::RectF(0, 0, 20.f, 25.f),
gfx::RoundedCornersF(1.f, 2.f, 3.f, 4.f));
expected = RRectF(gfx::RectF(0, 0, 40.f, 50.f),
gfx::RoundedCornersF(2.f, 4.f, 6.f, 8.f));
EXPECT_TRUE(scale.TransformRRectF(&rrect));
EXPECT_EQ(expected.ToString(), rrect.ToString());
}
TEST(XFormTest, TransformBox) {
Transform translation;
translation.Translate3d(3.f, 7.f, 6.f);
......
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