blob: e3d80cf46725c73535975984c73ebb8f54620536 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/geometry/resize_utils.h"
#include <string>
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
namespace gfx {
namespace {
// Aspect ratio is defined by width / height.
constexpr float kAspectRatioSquare = 1.0f;
constexpr float kAspectRatioHorizontal = 2.0f;
constexpr float kAspectRatioVertical = 0.5f;
constexpr Size kMinSizeHorizontal(20, 10);
constexpr Size kMaxSizeHorizontal(50, 25);
constexpr Size kMinSizeVertical(10, 20);
constexpr Size kMaxSizeVertical(25, 50);
std::string HitTestToString(ResizeEdge resize_edge) {
switch (resize_edge) {
case ResizeEdge::kTop:
return "top";
case ResizeEdge::kTopRight:
return "top-righ";
case ResizeEdge::kRight:
return "right";
case ResizeEdge::kBottomRight:
return "bottom-right";
case ResizeEdge::kBottom:
return "bottom";
case ResizeEdge::kBottomLeft:
return "bottom-left";
case ResizeEdge::kLeft:
return "left";
case ResizeEdge::kTopLeft:
return "top-left";
}
}
} // namespace
struct SizingParams {
ResizeEdge resize_edge{};
float aspect_ratio = 0.0f;
Size min_size;
absl::optional<Size> max_size;
Rect input_rect;
Rect expected_output_rect;
std::string ToString() const {
return base::StrCat(
{HitTestToString(resize_edge), " ratio=",
base::NumberToString(aspect_ratio), " [", min_size.ToString(), "..",
max_size.has_value() ? max_size->ToString() : "nullopt", "] ",
input_rect.ToString(), " -> ", expected_output_rect.ToString()});
}
};
using ResizeUtilsTest = testing::TestWithParam<SizingParams>;
TEST_P(ResizeUtilsTest, SizeRectToAspectRatio) {
Rect rect = GetParam().input_rect;
SizeRectToAspectRatio(GetParam().resize_edge, GetParam().aspect_ratio,
GetParam().min_size, GetParam().max_size, &rect);
EXPECT_EQ(rect, GetParam().expected_output_rect) << GetParam().ToString();
}
TEST_P(ResizeUtilsTest, SizeRectToAspectRatioWithExcludedMargin) {
Rect rect = GetParam().input_rect;
gfx::Size excluded_margin(2, 4);
SizeRectToAspectRatioWithExcludedMargin(
GetParam().resize_edge, GetParam().aspect_ratio, GetParam().min_size,
GetParam().max_size, excluded_margin, rect);
// With excluded margin, size should have the same aspect ratio once we remove
// the margin.
gfx::Size adjusted_size = rect.size() - excluded_margin;
const double actual_ratio =
static_cast<double>(adjusted_size.width()) / adjusted_size.height();
// Note that all of the aspect ratios are exactly representable, so `EQ` is
// really expected.
EXPECT_EQ(actual_ratio, GetParam().aspect_ratio) << GetParam().ToString();
// Also verify min / max.
EXPECT_GE(rect.size().width(), GetParam().min_size.width());
EXPECT_GE(rect.size().height(), GetParam().min_size.height());
if (GetParam().max_size) {
EXPECT_LE(rect.size().width(), GetParam().max_size->width());
EXPECT_LE(rect.size().height(), GetParam().max_size->height());
}
}
const SizingParams kSizeRectToSquareAspectRatioTestCases[] = {
// Dragging the top resizer up.
{ResizeEdge::kTop, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 98, 22, 24), Rect(100, 98, 24, 24)},
// Dragging the bottom resizer down.
{ResizeEdge::kBottom, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 100, 22, 24), Rect(100, 100, 24, 24)},
// Dragging the left resizer right.
{ResizeEdge::kLeft, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(102, 100, 22, 24), Rect(102, 102, 22, 22)},
// Dragging the right resizer left.
{ResizeEdge::kRight, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 100, 22, 24), Rect(100, 100, 22, 22)},
// Dragging the top-left resizer right.
{ResizeEdge::kTopLeft, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(102, 100, 22, 24), Rect(102, 102, 22, 22)},
// Dragging the top-right resizer down.
{ResizeEdge::kTopRight, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 102, 24, 22), Rect(100, 102, 22, 22)},
// Dragging the bottom-left resizer right.
{ResizeEdge::kBottomLeft, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 102, 22, 24), Rect(100, 102, 22, 22)},
// Dragging the bottom-right resizer up.
{ResizeEdge::kBottomRight, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 100, 24, 22), Rect(100, 100, 22, 22)},
// Dragging the bottom-right resizer left.
// Rect already as small as `kMinSizeHorizontal` allows.
{ResizeEdge::kBottomRight, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal,
Rect(100, 100, kMinSizeHorizontal.width(), kMinSizeHorizontal.width()),
Rect(100, 100, kMinSizeHorizontal.width(), kMinSizeHorizontal.width())},
// Dragging the top-left resizer left.
// Rect already as large as `kMaxSizeHorizontal` allows.
{ResizeEdge::kTopLeft, kAspectRatioSquare, kMinSizeHorizontal,
kMaxSizeHorizontal,
Rect(100, 100, kMaxSizeHorizontal.height(), kMaxSizeHorizontal.height()),
Rect(100, 100, kMaxSizeHorizontal.height(), kMaxSizeHorizontal.height())},
// Dragging the top-left resizer left.
// No max size specified.
{ResizeEdge::kTopLeft, kAspectRatioSquare, kMinSizeHorizontal,
absl::nullopt, Rect(102, 100, 22, 24), Rect(102, 102, 22, 22)},
};
const SizingParams kSizeRectToHorizontalAspectRatioTestCases[] = {
// Dragging the top resizer down.
{ResizeEdge::kTop, kAspectRatioHorizontal, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(100, 102, 48, 22), Rect(100, 102, 44, 22)},
// Dragging the left resizer left.
{ResizeEdge::kLeft, kAspectRatioHorizontal, kMinSizeHorizontal,
kMaxSizeHorizontal, Rect(96, 100, 48, 22), Rect(96, 98, 48, 24)},
// Rect already as small as `kMinSizeHorizontal` allows.
{ResizeEdge::kTop, kAspectRatioHorizontal, kMinSizeHorizontal,
kMaxSizeHorizontal,
Rect(100, 100, kMinSizeHorizontal.width(), kMinSizeHorizontal.height()),
Rect(100, 100, kMinSizeHorizontal.width(), kMinSizeHorizontal.height())},
// Rect already as large as `kMaxSizeHorizontal` allows.
{ResizeEdge::kTop, kAspectRatioHorizontal, kMinSizeHorizontal,
kMaxSizeHorizontal,
Rect(100, 100, kMaxSizeHorizontal.width(), kMaxSizeHorizontal.height()),
Rect(100, 100, kMaxSizeHorizontal.width(), kMaxSizeHorizontal.height())},
// Dragging the left resizer left.
// No max size specified.
{ResizeEdge::kLeft, kAspectRatioHorizontal, kMinSizeHorizontal,
absl::nullopt, Rect(96, 100, 48, 22), Rect(96, 98, 48, 24)},
};
const SizingParams kSizeRectToVerticalAspectRatioTestCases[] = {
// Dragging the bottom resizer up.
{ResizeEdge::kBottom, kAspectRatioVertical, kMinSizeVertical,
kMaxSizeVertical, Rect(100, 100, 24, 44), Rect(100, 100, 22, 44)},
// Dragging the right resizer right.
{ResizeEdge::kRight, kAspectRatioVertical, kMinSizeVertical,
kMaxSizeVertical, Rect(100, 100, 24, 44), Rect(100, 100, 24, 48)},
// Rect already as small as `kMinSizeVertical` allows.
{ResizeEdge::kTop, kAspectRatioVertical, kMinSizeVertical, kMaxSizeVertical,
Rect(100, 100, kMinSizeVertical.width(), kMinSizeVertical.height()),
Rect(100, 100, kMinSizeVertical.width(), kMinSizeVertical.height())},
// Rect already as large as `kMaxSizeVertical` allows.
{ResizeEdge::kTop, kAspectRatioVertical, kMinSizeVertical, kMaxSizeVertical,
Rect(100, 100, kMaxSizeVertical.width(), kMaxSizeVertical.height()),
Rect(100, 100, kMaxSizeVertical.width(), kMaxSizeVertical.height())},
// Dragging the right resizer right.
// No max size specified.
{ResizeEdge::kRight, kAspectRatioVertical, kMinSizeVertical, absl::nullopt,
Rect(100, 100, 24, 44), Rect(100, 100, 24, 48)},
};
INSTANTIATE_TEST_SUITE_P(
Square,
ResizeUtilsTest,
testing::ValuesIn(kSizeRectToSquareAspectRatioTestCases));
INSTANTIATE_TEST_SUITE_P(
Horizontal,
ResizeUtilsTest,
testing::ValuesIn(kSizeRectToHorizontalAspectRatioTestCases));
INSTANTIATE_TEST_SUITE_P(
Vertical,
ResizeUtilsTest,
testing::ValuesIn(kSizeRectToVerticalAspectRatioTestCases));
} // namespace gfx