blob: ed83f0500a2545ad9cccd5ba0cd8b350305d4711 [file] [log] [blame] [edit]
// Copyright 2013 The Flutter 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 "flutter/testing/testing.h"
#include "impeller/aiks/canvas.h"
#include "impeller/geometry/path_builder.h"
// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
// NOLINTBEGIN(bugprone-unchecked-optional-access)
namespace impeller {
namespace testing {
using AiksCanvasTest = ::testing::Test;
TEST(AiksCanvasTest, EmptyCullRect) {
Canvas canvas;
ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
}
TEST(AiksCanvasTest, InitialCullRect) {
Rect initial_cull(0, 0, 10, 10);
Canvas canvas(initial_cull);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), initial_cull);
}
TEST(AiksCanvasTest, TranslatedCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect translated_cull(0, 0, 10, 10);
Canvas canvas(initial_cull);
canvas.Translate(Vector3(5, 5, 0));
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), translated_cull);
}
TEST(AiksCanvasTest, ScaledCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect scaled_cull(10, 10, 20, 20);
Canvas canvas(initial_cull);
canvas.Scale(Vector2(0.5, 0.5));
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), scaled_cull);
}
TEST(AiksCanvasTest, RectClipIntersectAgainstEmptyCullRect) {
Rect rect_clip(5, 5, 10, 10);
Canvas canvas;
canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
}
TEST(AiksCanvasTest, RectClipDiffAgainstEmptyCullRect) {
Rect rect_clip(5, 5, 10, 10);
Canvas canvas;
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
}
TEST(AiksCanvasTest, RectClipIntersectAgainstCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 5, 10, 10);
Rect result_cull(5, 5, 5, 5);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffAgainstNonCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 5, 10, 10);
Rect result_cull(0, 0, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffAboveCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect rect_clip(0, 0, 20, 4);
Rect result_cull(5, 5, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffBelowCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect rect_clip(0, 16, 20, 4);
Rect result_cull(5, 5, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffLeftOfCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect rect_clip(0, 0, 4, 20);
Rect result_cull(5, 5, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffRightOfCullRect) {
Rect initial_cull(5, 5, 10, 10);
Rect rect_clip(16, 0, 4, 20);
Rect result_cull(5, 5, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffAgainstVCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 0, 10, 10);
Rect result_cull(0, 0, 5, 10);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RectClipDiffAgainstHCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(0, 5, 10, 10);
Rect result_cull(0, 0, 10, 5);
Canvas canvas(initial_cull);
canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect) {
Rect rect_clip(5, 5, 10, 10);
Canvas canvas;
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect) {
Rect rect_clip(5, 5, 10, 10);
Canvas canvas;
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
}
TEST(AiksCanvasTest, RRectClipIntersectAgainstCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 5, 10, 10);
Rect result_cull(5, 5, 5, 5);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 5, 10, 10);
Rect result_cull(0, 0, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, 0, 10, 10);
Rect result_cull(0, 0, 6, 10);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(5, -2, 10, 14);
Rect result_cull(0, 0, 5, 10);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(0, 5, 10, 10);
Rect result_cull(0, 0, 10, 6);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
Rect rect_clip(-2, 5, 14, 10);
Rect result_cull(0, 0, 10, 5);
Canvas canvas(initial_cull);
canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, PathClipIntersectAgainstEmptyCullRect) {
PathBuilder builder;
builder.AddRect({5, 5, 1, 1});
builder.AddRect({5, 14, 1, 1});
builder.AddRect({14, 5, 1, 1});
builder.AddRect({14, 14, 1, 1});
Path path = builder.TakePath();
Rect rect_clip(5, 5, 10, 10);
Canvas canvas;
canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
}
TEST(AiksCanvasTest, PathClipDiffAgainstEmptyCullRect) {
PathBuilder builder;
builder.AddRect({5, 5, 1, 1});
builder.AddRect({5, 14, 1, 1});
builder.AddRect({14, 5, 1, 1});
builder.AddRect({14, 14, 1, 1});
Path path = builder.TakePath();
Canvas canvas;
canvas.ClipPath(path, Entity::ClipOperation::kDifference);
ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
}
TEST(AiksCanvasTest, PathClipIntersectAgainstCullRect) {
Rect initial_cull(0, 0, 10, 10);
PathBuilder builder;
builder.AddRect({5, 5, 1, 1});
builder.AddRect({5, 14, 1, 1});
builder.AddRect({14, 5, 1, 1});
builder.AddRect({14, 14, 1, 1});
Path path = builder.TakePath();
Rect result_cull(5, 5, 5, 5);
Canvas canvas(initial_cull);
canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, PathClipDiffAgainstNonCoveredCullRect) {
Rect initial_cull(0, 0, 10, 10);
PathBuilder builder;
builder.AddRect({5, 5, 1, 1});
builder.AddRect({5, 14, 1, 1});
builder.AddRect({14, 5, 1, 1});
builder.AddRect({14, 14, 1, 1});
Path path = builder.TakePath();
Rect result_cull(0, 0, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipPath(path, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
TEST(AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect) {
Rect initial_cull(5, 5, 10, 10);
PathBuilder builder;
builder.AddRect({0, 0, 100, 100});
Path path = builder.TakePath();
// Diff clip of Paths is ignored due to complexity
Rect result_cull(5, 5, 10, 10);
Canvas canvas(initial_cull);
canvas.ClipPath(path, Entity::ClipOperation::kDifference);
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
}
} // namespace testing
} // namespace impeller
// NOLINTEND(bugprone-unchecked-optional-access)