mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
236 lines
8.1 KiB
C++
236 lines
8.1 KiB
C++
// 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 "rtree.h"
|
|
|
|
#include "flutter/testing/testing.h"
|
|
#include "third_party/skia/include/core/SkCanvas.h"
|
|
#include "third_party/skia/include/core/SkPictureRecorder.h"
|
|
|
|
namespace flutter {
|
|
namespace testing {
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsNoIntersection) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// If no rect is intersected with the query rect, then the result list is
|
|
// empty.
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(20, 20, 40, 40), rect_paint);
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(40, 40, 80, 80));
|
|
ASSERT_TRUE(hits.empty());
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsSingleRectIntersection) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Given a single rect A that intersects with the query rect,
|
|
// the result list contains this rect.
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(120, 120, 160, 160), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(140, 140, 150, 150));
|
|
ASSERT_EQ(1UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(120, 120, 160, 160));
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsIgnoresNonDrawingRecords) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Creates two non drawing records.
|
|
recording_canvas->translate(100, 100);
|
|
// The result list should only contain the clipping rect.
|
|
recording_canvas->clipRect(SkRect::MakeLTRB(40, 40, 50, 50),
|
|
SkClipOp::kIntersect);
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(20, 20, 80, 80), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
// The rtree has a translate, a clip and a rect record.
|
|
ASSERT_EQ(3, rtree_factory.getInstance()->getCount());
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(0, 0, 1000, 1000));
|
|
ASSERT_EQ(1UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(120, 120, 180, 180));
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsMultipleRectIntersection) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Given the A, B that intersect with the query rect,
|
|
// there should be A and B in the result list since
|
|
// they don't intersect with each other.
|
|
//
|
|
// +-----+ +-----+
|
|
// | A | | B |
|
|
// +-----+ +-----+
|
|
// A
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
|
|
// B
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(0, 0, 1000, 1050));
|
|
ASSERT_EQ(2UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(100, 100, 200, 200));
|
|
ASSERT_EQ(*std::next(hits.begin(), 1), SkRect::MakeLTRB(300, 100, 400, 200));
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase1) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Given the A, and B rects, which intersect with the query rect,
|
|
// the result list contains the rect resulting from the union of A and B.
|
|
//
|
|
// +-----+
|
|
// | A |
|
|
// | +-----+
|
|
// | | C |
|
|
// | +-----+
|
|
// | |
|
|
// +-----+
|
|
|
|
// A
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 150, 150), rect_paint);
|
|
// B
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(125, 125, 175, 175), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeXYWH(120, 120, 126, 126));
|
|
ASSERT_EQ(1UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(100, 100, 175, 175));
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase2) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Given the A, B, and C rects that intersect with the query rect,
|
|
// there should be only C in the result list,
|
|
// since A and B are contained in C.
|
|
//
|
|
// +---------------------+
|
|
// | C |
|
|
// | +-----+ +-----+ |
|
|
// | | A | | B | |
|
|
// | +-----+ +-----+ |
|
|
// +---------------------+
|
|
// +-----+
|
|
// | D |
|
|
// +-----+
|
|
|
|
// A
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
|
|
// B
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
|
|
// C
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(50, 50, 500, 250), rect_paint);
|
|
// D
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(280, 100, 280, 320), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(30, 30, 550, 270));
|
|
ASSERT_EQ(1UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(50, 50, 500, 250));
|
|
}
|
|
|
|
TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase3) {
|
|
auto rtree_factory = RTreeFactory();
|
|
auto recorder = std::make_unique<SkPictureRecorder>();
|
|
auto recording_canvas =
|
|
recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
|
|
|
|
auto rect_paint = SkPaint();
|
|
rect_paint.setColor(SkColors::kCyan);
|
|
rect_paint.setStyle(SkPaint::Style::kFill_Style);
|
|
|
|
// Given the A, B, C and D rects that intersect with the query rect,
|
|
// the result list contains a single rect, which is the union of
|
|
// these four rects.
|
|
//
|
|
// +------------------------------+
|
|
// | D |
|
|
// | +-----+ +-----+ +-----+ |
|
|
// | | A | | B | | C | |
|
|
// | +-----+ +-----+ | | |
|
|
// +----------------------| |-+
|
|
// +-----+
|
|
// +-----+
|
|
// | E |
|
|
// +-----+
|
|
|
|
// A
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
|
|
// B
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
|
|
// C
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(500, 100, 600, 300), rect_paint);
|
|
// D
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(50, 50, 620, 250), rect_paint);
|
|
// E
|
|
recording_canvas->drawRect(SkRect::MakeLTRB(280, 100, 280, 320), rect_paint);
|
|
|
|
recorder->finishRecordingAsPicture();
|
|
|
|
auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
|
|
SkRect::MakeLTRB(30, 30, 550, 270));
|
|
ASSERT_EQ(1UL, hits.size());
|
|
ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(50, 50, 620, 300));
|
|
}
|
|
|
|
} // namespace testing
|
|
} // namespace flutter
|