blob: f61dae86e7d9c29519e690220a2c71a65005ee2c [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h"
namespace views {
namespace test {
TEST(FloodFillInkDropRippleTest, TransformedCenterPointForIrregularClipBounds) {
const gfx::Size host_size(48, 50);
const gfx::Insets clip_insets(9, 8);
const gfx::Point requested_center_point(25, 24);
// |expected_center_point| is in the coordinate space of ripple's clip bounds
// defined by |clip_insets|.
const gfx::Point expected_center_point(
requested_center_point.x() - clip_insets.left(),
requested_center_point.y() - clip_insets.top());
FloodFillInkDropRipple ripple(host_size, clip_insets, requested_center_point,
SK_ColorWHITE, 0.175f);
FloodFillInkDropRippleTestApi test_api(&ripple);
gfx::Point3F actual_center(gfx::PointF(test_api.GetDrawnCenterPoint()));
test_api.TransformPoint(10, &actual_center);
EXPECT_EQ(expected_center_point,
gfx::ToRoundedPoint(actual_center.AsPointF()));
}
TEST(FloodFillInkDropRippleTest, MaxDistanceToCorners) {
const float kAbsError = 0.01f;
const gfx::Size host_size(70, 130);
// Rect with the following corners in clockwise order starting at the origin:
// (10, 30), (60, 30), (10, 100), (60, 100)
const gfx::Insets clip_insets(30, 10);
FloodFillInkDropRipple ripple(host_size, clip_insets, gfx::Point(),
SK_ColorWHITE, 0.175f);
FloodFillInkDropRippleTestApi test_api(&ripple);
// Interior points
EXPECT_NEAR(78.10f, test_api.MaxDistanceToCorners(gfx::Point(10, 40)),
kAbsError);
EXPECT_NEAR(71.06f, test_api.MaxDistanceToCorners(gfx::Point(55, 45)),
kAbsError);
EXPECT_NEAR(64.03f, test_api.MaxDistanceToCorners(gfx::Point(50, 80)),
kAbsError);
EXPECT_NEAR(68.01f, test_api.MaxDistanceToCorners(gfx::Point(20, 85)),
kAbsError);
// Exterior points
EXPECT_NEAR(110.79f, test_api.MaxDistanceToCorners(gfx::Point(3, 5)),
kAbsError);
EXPECT_NEAR(108.17f, test_api.MaxDistanceToCorners(gfx::Point(70, 10)),
kAbsError);
EXPECT_NEAR(103.08f, test_api.MaxDistanceToCorners(gfx::Point(75, 110)),
kAbsError);
EXPECT_NEAR(101.24f, test_api.MaxDistanceToCorners(gfx::Point(5, 115)),
kAbsError);
}
// Verifies that both going directly from HIDDEN to ACTIVATED state and going
// through PENDING to ACTIVAED state lead to the same final opacity and
// transform values.
TEST(FloodFillInkDropRippleTest, ActivatedFinalState) {
const float kAbsError = 0.01f;
const gfx::Size host_size(100, 50);
const gfx::Point center_point(host_size.width() / 2, host_size.height() / 2);
const SkColor color = SK_ColorWHITE;
const float visible_opacity = 0.7f;
FloodFillInkDropRipple ripple(host_size, center_point, color,
visible_opacity);
FloodFillInkDropRippleTestApi test_api(&ripple);
// Go to ACTIVATED state directly.
ripple.AnimateToState(InkDropState::ACTIVATED);
test_api.CompleteAnimations();
const float activated_opacity = test_api.GetCurrentOpacity();
const gfx::Transform activated_transform =
test_api.GetPaintedLayerTransform();
// Reset state.
ripple.AnimateToState(InkDropState::HIDDEN);
test_api.CompleteAnimations();
// Go to ACTIVATED state through PENDING state.
ripple.AnimateToState(InkDropState::ACTION_PENDING);
ripple.AnimateToState(InkDropState::ACTIVATED);
test_api.CompleteAnimations();
const float pending_activated_opacity = test_api.GetCurrentOpacity();
const gfx::Transform pending_activated_transform =
test_api.GetPaintedLayerTransform();
// Compare opacity and transform values.
EXPECT_NEAR(activated_opacity, pending_activated_opacity, kAbsError);
EXPECT_TRUE(
activated_transform.ApproximatelyEqual(pending_activated_transform));
}
TEST(FloodFillInkDropRippleTest, TransformIsPixelAligned) {
const float kEpsilon = 0.001f;
const gfx::Size host_size(11, 11);
// Keep the draw center different from the the host center to have a non zero
// offset in the transformation.
const gfx::Point center_point(host_size.width() / 3, host_size.height() / 3);
const SkColor color = SK_ColorYELLOW;
const float visible_opacity = 0.3f;
FloodFillInkDropRipple ripple(host_size, center_point, color,
visible_opacity);
FloodFillInkDropRippleTestApi test_api(&ripple);
for (auto dsf : {1.25, 1.33, 1.5, 1.6, 1.75, 1.8, 2.25}) {
SCOPED_TRACE(testing::Message()
<< std::endl
<< "Device Scale Factor: " << dsf << std::endl);
ripple.GetRootLayer()->OnDeviceScaleFactorChanged(dsf);
gfx::Point3F ripple_origin;
test_api.TransformPoint(host_size.width() / 2, &ripple_origin);
// Apply device scale factor to get the final offset.
gfx::Transform dsf_transform;
dsf_transform.Scale(dsf, dsf);
dsf_transform.TransformPoint(&ripple_origin);
EXPECT_NEAR(ripple_origin.x(), gfx::ToRoundedInt(ripple_origin.x()),
kEpsilon);
EXPECT_NEAR(ripple_origin.y(), gfx::ToRoundedInt(ripple_origin.y()),
kEpsilon);
}
}
} // namespace test
} // namespace views