[ios][platform_view] fix platform view clipping path intersection (flutter/engine#54820)
It turns out that when there are multiple paths to clip, they are unioned together, rather than intersected. But clipping paths need to be intersected. There isn't any good way to intersect arbitrary paths. However, it is easy to intersect rect paths, which is the most common use case. Then we simply fallback to software rendering if we have to intersect non-rect paths. That is: **Case 1** Only 1 clipping path (either rect path or arbitrary path): Hardware rendering. This should be the most common use case **Case 2** Multiple rect clipping path: Hardware rendering. This is also common, and it's the linked issue that we are fixing. **Case 3** Other complex case (multiple non-rect clipping path) Fallback to software rendering. This should be rare. After https://github.com/flutter/engine/pull/53826, we don't have a working benchmark that measures the main thread anymore. However, this PR shouldn't impact our ad benchmark, since it only has 1 clipping path. I will verify manually by checking Instruments and make sure no software rendering is happening. But we really should make the benchmark working again, not just for performance improvement, but also for monitoring regression. *List which issues are fixed by this PR. You must list at least one issue.* Fixes https://github.com/flutter/flutter/issues/153904 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
@ -1856,6 +1856,102 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClipRect_multipleClips {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
|
||||
/*platform=*/GetDefaultTaskRunner(),
|
||||
/*raster=*/GetDefaultTaskRunner(),
|
||||
/*ui=*/GetDefaultTaskRunner(),
|
||||
/*io=*/GetDefaultTaskRunner());
|
||||
auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
|
||||
flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner());
|
||||
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
|
||||
/*delegate=*/mock_delegate,
|
||||
/*rendering_api=*/mock_delegate.settings_.enable_impeller
|
||||
? flutter::IOSRenderingAPI::kMetal
|
||||
: flutter::IOSRenderingAPI::kSoftware,
|
||||
/*platform_views_controller=*/flutterPlatformViewsController,
|
||||
/*task_runners=*/runners,
|
||||
/*worker_task_runner=*/nil,
|
||||
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
|
||||
|
||||
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
|
||||
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
|
||||
flutterPlatformViewsController->RegisterViewFactory(
|
||||
factory, @"MockFlutterPlatformView",
|
||||
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
|
||||
FlutterResult result = ^(id result) {
|
||||
};
|
||||
flutterPlatformViewsController->OnMethodCall(
|
||||
[FlutterMethodCall
|
||||
methodCallWithMethodName:@"create"
|
||||
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
|
||||
result);
|
||||
|
||||
XCTAssertNotNil(gMockPlatformView);
|
||||
|
||||
UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
|
||||
flutterPlatformViewsController->SetFlutterView(flutterView);
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
SkMatrix screenScaleMatrix =
|
||||
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect1 = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack.PushClipRect(rect1);
|
||||
// Push another clip rect
|
||||
SkRect rect2 = SkRect::MakeXYWH(3, 3, 3, 3);
|
||||
stack.PushClipRect(rect2);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
|
||||
flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
|
||||
flutterPlatformViewsController->CompositeWithParams(
|
||||
2, flutterPlatformViewsController->GetCompositionParams(2));
|
||||
|
||||
gMockPlatformView.backgroundColor = UIColor.redColor;
|
||||
XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
|
||||
ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
|
||||
[flutterView addSubview:childClippingView];
|
||||
|
||||
[flutterView setNeedsLayout];
|
||||
[flutterView layoutIfNeeded];
|
||||
|
||||
/*
|
||||
clip 1 clip 2
|
||||
2 3 4 5 6 2 3 4 5 6
|
||||
2 + - - + 2
|
||||
3 | | 3 + - - +
|
||||
4 | | 4 | |
|
||||
5 + - - + 5 | |
|
||||
6 6 + - - +
|
||||
|
||||
Result should be the intersection of 2 clips
|
||||
2 3 4 5 6
|
||||
2
|
||||
3 + - +
|
||||
4 | |
|
||||
5 + - +
|
||||
6
|
||||
*/
|
||||
CGRect insideClipping = CGRectMake(3, 3, 2, 2);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
CGPoint point = CGPointMake(i, j);
|
||||
int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
|
||||
if (CGRectContainsPoint(insideClipping, point)) {
|
||||
XCTAssertEqual(alpha, 255);
|
||||
} else {
|
||||
XCTAssertEqual(alpha, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClipRRect {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
@ -1959,6 +2055,126 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClipRRect_multipleClips {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
|
||||
/*platform=*/GetDefaultTaskRunner(),
|
||||
/*raster=*/GetDefaultTaskRunner(),
|
||||
/*ui=*/GetDefaultTaskRunner(),
|
||||
/*io=*/GetDefaultTaskRunner());
|
||||
auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
|
||||
flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner());
|
||||
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
|
||||
/*delegate=*/mock_delegate,
|
||||
/*rendering_api=*/mock_delegate.settings_.enable_impeller
|
||||
? flutter::IOSRenderingAPI::kMetal
|
||||
: flutter::IOSRenderingAPI::kSoftware,
|
||||
/*platform_views_controller=*/flutterPlatformViewsController,
|
||||
/*task_runners=*/runners,
|
||||
/*worker_task_runner=*/nil,
|
||||
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
|
||||
|
||||
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
|
||||
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
|
||||
flutterPlatformViewsController->RegisterViewFactory(
|
||||
factory, @"MockFlutterPlatformView",
|
||||
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
|
||||
FlutterResult result = ^(id result) {
|
||||
};
|
||||
flutterPlatformViewsController->OnMethodCall(
|
||||
[FlutterMethodCall
|
||||
methodCallWithMethodName:@"create"
|
||||
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
|
||||
result);
|
||||
|
||||
XCTAssertNotNil(gMockPlatformView);
|
||||
|
||||
UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
|
||||
flutterPlatformViewsController->SetFlutterView(flutterView);
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
SkMatrix screenScaleMatrix =
|
||||
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rrect
|
||||
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipRRect(rrect);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6);
|
||||
stack.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
|
||||
flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
|
||||
flutterPlatformViewsController->CompositeWithParams(
|
||||
2, flutterPlatformViewsController->GetCompositionParams(2));
|
||||
|
||||
gMockPlatformView.backgroundColor = UIColor.redColor;
|
||||
XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
|
||||
ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
|
||||
[flutterView addSubview:childClippingView];
|
||||
|
||||
[flutterView setNeedsLayout];
|
||||
[flutterView layoutIfNeeded];
|
||||
|
||||
/*
|
||||
clip 1 clip 2
|
||||
2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9
|
||||
2 / - - - - \ 2 + - - - - +
|
||||
3 | | 3 | |
|
||||
4 | | 4 | |
|
||||
5 | | 5 | |
|
||||
6 | | 6 | |
|
||||
7 \ - - - - / 7 + - - - - +
|
||||
|
||||
Result should be the intersection of 2 clips
|
||||
2 3 4 5 6 7 8 9
|
||||
2 + - - \
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | |
|
||||
7 + - - /
|
||||
*/
|
||||
CGRect clipping = CGRectMake(4, 2, 4, 6);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
CGPoint point = CGPointMake(i, j);
|
||||
int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
|
||||
if (i == 7 && (j == 2 || j == 7)) {
|
||||
// Upper and lower right corners should be partially transparent.
|
||||
XCTAssert(0 < alpha && alpha < 255);
|
||||
} else if (
|
||||
// left
|
||||
(i == 4 && j >= 2 && j <= 7) ||
|
||||
// right
|
||||
(i == 7 && j >= 2 && j <= 7) ||
|
||||
// top
|
||||
(j == 2 && i >= 4 && i <= 7) ||
|
||||
// bottom
|
||||
(j == 7 && i >= 4 && i <= 7)) {
|
||||
// Since we are falling back to software rendering for this case
|
||||
// The edge pixels can be anti-aliased, so it may not be fully opaque.
|
||||
XCTAssert(alpha > 127);
|
||||
} else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
|
||||
(j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
|
||||
// Since we are falling back to software rendering for this case
|
||||
// The edge pixels can be anti-aliased, so it may not be fully transparent.
|
||||
XCTAssert(alpha < 127);
|
||||
} else if (CGRectContainsPoint(clipping, point)) {
|
||||
// Other pixels inside clipping should be fully opaque.
|
||||
XCTAssertEqual(alpha, 255);
|
||||
} else {
|
||||
// Pixels outside clipping should be fully transparent.
|
||||
XCTAssertEqual(alpha, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClipPath {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
@ -2063,6 +2279,127 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClipPath_multipleClips {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
|
||||
/*platform=*/GetDefaultTaskRunner(),
|
||||
/*raster=*/GetDefaultTaskRunner(),
|
||||
/*ui=*/GetDefaultTaskRunner(),
|
||||
/*io=*/GetDefaultTaskRunner());
|
||||
auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
|
||||
flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner());
|
||||
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
|
||||
/*delegate=*/mock_delegate,
|
||||
/*rendering_api=*/mock_delegate.settings_.enable_impeller
|
||||
? flutter::IOSRenderingAPI::kMetal
|
||||
: flutter::IOSRenderingAPI::kSoftware,
|
||||
/*platform_views_controller=*/flutterPlatformViewsController,
|
||||
/*task_runners=*/runners,
|
||||
/*worker_task_runner=*/nil,
|
||||
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
|
||||
|
||||
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
|
||||
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
|
||||
flutterPlatformViewsController->RegisterViewFactory(
|
||||
factory, @"MockFlutterPlatformView",
|
||||
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
|
||||
FlutterResult result = ^(id result) {
|
||||
};
|
||||
flutterPlatformViewsController->OnMethodCall(
|
||||
[FlutterMethodCall
|
||||
methodCallWithMethodName:@"create"
|
||||
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
|
||||
result);
|
||||
|
||||
XCTAssertNotNil(gMockPlatformView);
|
||||
|
||||
UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
|
||||
flutterPlatformViewsController->SetFlutterView(flutterView);
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
SkMatrix screenScaleMatrix =
|
||||
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip path
|
||||
SkPath path;
|
||||
path.addRoundRect(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipPath(path);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6);
|
||||
stack.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
|
||||
flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
|
||||
flutterPlatformViewsController->CompositeWithParams(
|
||||
2, flutterPlatformViewsController->GetCompositionParams(2));
|
||||
|
||||
gMockPlatformView.backgroundColor = UIColor.redColor;
|
||||
XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
|
||||
ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
|
||||
[flutterView addSubview:childClippingView];
|
||||
|
||||
[flutterView setNeedsLayout];
|
||||
[flutterView layoutIfNeeded];
|
||||
|
||||
/*
|
||||
clip 1 clip 2
|
||||
2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9
|
||||
2 / - - - - \ 2 + - - - - +
|
||||
3 | | 3 | |
|
||||
4 | | 4 | |
|
||||
5 | | 5 | |
|
||||
6 | | 6 | |
|
||||
7 \ - - - - / 7 + - - - - +
|
||||
|
||||
Result should be the intersection of 2 clips
|
||||
2 3 4 5 6 7 8 9
|
||||
2 + - - \
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | |
|
||||
7 + - - /
|
||||
*/
|
||||
CGRect clipping = CGRectMake(4, 2, 4, 6);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
CGPoint point = CGPointMake(i, j);
|
||||
int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
|
||||
if (i == 7 && (j == 2 || j == 7)) {
|
||||
// Upper and lower right corners should be partially transparent.
|
||||
XCTAssert(0 < alpha && alpha < 255);
|
||||
} else if (
|
||||
// left
|
||||
(i == 4 && j >= 2 && j <= 7) ||
|
||||
// right
|
||||
(i == 7 && j >= 2 && j <= 7) ||
|
||||
// top
|
||||
(j == 2 && i >= 4 && i <= 7) ||
|
||||
// bottom
|
||||
(j == 7 && i >= 4 && i <= 7)) {
|
||||
// Since we are falling back to software rendering for this case
|
||||
// The edge pixels can be anti-aliased, so it may not be fully opaque.
|
||||
XCTAssert(alpha > 127);
|
||||
} else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
|
||||
(j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
|
||||
// Since we are falling back to software rendering for this case
|
||||
// The edge pixels can be anti-aliased, so it may not be fully transparent.
|
||||
XCTAssert(alpha < 127);
|
||||
} else if (CGRectContainsPoint(clipping, point)) {
|
||||
// Other pixels inside clipping should be fully opaque.
|
||||
XCTAssertEqual(alpha, 255);
|
||||
} else {
|
||||
// Pixels outside clipping should be fully transparent.
|
||||
XCTAssertEqual(alpha, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
|
||||
@ -197,12 +197,14 @@ static BOOL _preparedOnce = NO;
|
||||
// information about screen scale.
|
||||
@property(nonatomic) CATransform3D reverseScreenScale;
|
||||
|
||||
- (void)addTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix;
|
||||
- (fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FlutterClippingMaskView {
|
||||
CGMutablePathRef pathSoFar_;
|
||||
std::vector<fml::CFRef<CGPathRef>> paths_;
|
||||
BOOL containsNonRectPath_;
|
||||
CGRect rectSoFar_;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
@ -213,7 +215,8 @@ static BOOL _preparedOnce = NO;
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
self.backgroundColor = UIColor.clearColor;
|
||||
_reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1);
|
||||
pathSoFar_ = CGPathCreateMutable();
|
||||
rectSoFar_ = self.bounds;
|
||||
containsNonRectPath_ = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -227,16 +230,13 @@ static BOOL _preparedOnce = NO;
|
||||
}
|
||||
|
||||
- (void)reset {
|
||||
CGPathRelease(pathSoFar_);
|
||||
pathSoFar_ = CGPathCreateMutable();
|
||||
paths_.clear();
|
||||
rectSoFar_ = self.bounds;
|
||||
containsNonRectPath_ = NO;
|
||||
[self shapeLayer].path = nil;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
CGPathRelease(pathSoFar_);
|
||||
}
|
||||
|
||||
// In some scenarios, when we add this view as a maskView of the ChildClippingView, iOS added
|
||||
// this view as a subview of the ChildClippingView.
|
||||
// This results this view blocking touch events on the ChildClippingView.
|
||||
@ -246,16 +246,58 @@ static BOOL _preparedOnce = NO;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// It's hard to compute intersection of arbitrary non-rect paths.
|
||||
// So we fallback to software rendering.
|
||||
if (containsNonRectPath_ && paths_.size() > 1) {
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
|
||||
// For mask view, only the alpha channel is used.
|
||||
CGContextSetAlpha(context, 1);
|
||||
|
||||
for (size_t i = 0; i < paths_.size(); i++) {
|
||||
CGContextAddPath(context, paths_.at(i));
|
||||
CGContextClip(context);
|
||||
}
|
||||
CGContextFillRect(context, rect);
|
||||
CGContextRestoreGState(context);
|
||||
} else {
|
||||
// Either a single path, or multiple rect paths.
|
||||
// Use hardware rendering with CAShapeLayer.
|
||||
[super drawRect:rect];
|
||||
if (![self shapeLayer].path) {
|
||||
if (paths_.size() == 1) {
|
||||
// A single path, either rect or non-rect.
|
||||
[self shapeLayer].path = paths_.at(0);
|
||||
} else {
|
||||
// Multiple paths, all paths must be rects.
|
||||
CGPathRef pathSoFar = CGPathCreateWithRect(rectSoFar_, nil);
|
||||
[self shapeLayer].path = pathSoFar;
|
||||
CGPathRelease(pathSoFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix {
|
||||
CGRect clipRect = GetCGRectFromSkRect(clipSkRect);
|
||||
CGPathRef path = CGPathCreateWithRect(clipRect, nil);
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
|
||||
[self addTransformedPath:path matrix:matrixInPoints];
|
||||
paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]);
|
||||
CGAffineTransform affine = [self affineWithMatrix:matrixInPoints];
|
||||
// Make sure the rect is not rotated (only translated or scaled).
|
||||
if (affine.b == 0 && affine.c == 0) {
|
||||
rectSoFar_ = CGRectIntersection(rectSoFar_, CGRectApplyAffineTransform(clipRect, affine));
|
||||
} else {
|
||||
containsNonRectPath_ = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix {
|
||||
containsNonRectPath_ = YES;
|
||||
CGPathRef pathRef = nullptr;
|
||||
switch (clipSkRRect.getType()) {
|
||||
case SkRRect::kEmpty_Type: {
|
||||
@ -321,7 +363,7 @@ static BOOL _preparedOnce = NO;
|
||||
// TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that
|
||||
// the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge
|
||||
// clipping on iOS.
|
||||
[self addTransformedPath:pathRef matrix:matrixInPoints];
|
||||
paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
|
||||
}
|
||||
|
||||
- (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix {
|
||||
@ -331,6 +373,7 @@ static BOOL _preparedOnce = NO;
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
containsNonRectPath_ = YES;
|
||||
CGMutablePathRef pathRef = CGPathCreateMutable();
|
||||
|
||||
// Loop through all verbs and translate them into CGPath
|
||||
@ -386,15 +429,20 @@ static BOOL _preparedOnce = NO;
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
|
||||
[self addTransformedPath:pathRef matrix:matrixInPoints];
|
||||
paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
|
||||
}
|
||||
|
||||
- (void)addTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix {
|
||||
CGAffineTransform affine =
|
||||
CGAffineTransformMake(matrix.m11, matrix.m12, matrix.m21, matrix.m22, matrix.m41, matrix.m42);
|
||||
CGPathAddPath(pathSoFar_, &affine, path);
|
||||
[self shapeLayer].path = pathSoFar_;
|
||||
- (CGAffineTransform)affineWithMatrix:(CATransform3D)matrix {
|
||||
return CGAffineTransformMake(matrix.m11, matrix.m12, matrix.m21, matrix.m22, matrix.m41,
|
||||
matrix.m42);
|
||||
}
|
||||
|
||||
- (fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix {
|
||||
CGAffineTransform affine = [self affineWithMatrix:matrix];
|
||||
CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(path, &affine);
|
||||
|
||||
CGPathRelease(path);
|
||||
return fml::CFRef<CGPathRef>(transformedPath);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -358,14 +358,23 @@ final _skipTestsForImpeller = [
|
||||
'ScenariosUITests/MultiplePlatformViewsTest/testPlatformView',
|
||||
'ScenariosUITests/NonFullScreenFlutterViewPlatformViewUITests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipPathTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipPathMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipPathWithTransformTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipPathWithTransformMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectAfterMovedTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectAfterMovedMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectWithTransformTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRectWithTransformMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRRectTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRRectMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRRectWithTransformTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationClipRRectWithTransformMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationLargeClipRRectTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationLargeClipRRectMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationOpacityTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewMutationTransformTests/testPlatformView',
|
||||
'ScenariosUITests/PlatformViewRotation/testPlatformView',
|
||||
@ -374,8 +383,11 @@ final _skipTestsForImpeller = [
|
||||
'ScenariosUITests/PlatformViewWithOtherBackdropFilterTests/testPlatformView',
|
||||
'ScenariosUITests/RenderingSelectionTest/testSoftwareRendering',
|
||||
'ScenariosUITests/TwoPlatformViewClipPathTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewClipPathMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewClipRectTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewClipRectMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewClipRRectTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewClipRRectMultipleClipsTests/testPlatformView',
|
||||
'ScenariosUITests/TwoPlatformViewsWithOtherBackDropFilterTests/testPlatformView',
|
||||
'ScenariosUITests/UnobstructedPlatformViewTests/testMultiplePlatformViewsWithOverlays',
|
||||
].map((name) => '-skip-testing:$name').toList();
|
||||
|
||||
@ -73,6 +73,18 @@
|
||||
68C9D8092AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68C9D8082AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; };
|
||||
68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1DE2C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1DF2C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E02C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E12C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E22C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E32C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E42C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E52C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E62C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E72C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E82C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
E0D5A1E92C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; };
|
||||
F26F15B8268B6B5600EC54D3 /* iPadGestureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -249,6 +261,18 @@
|
||||
68D4017B2564859300ECD91A /* ContinuousTexture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContinuousTexture.h; sourceTree = "<group>"; };
|
||||
68D4017C2564859300ECD91A /* ContinuousTexture.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContinuousTexture.m; sourceTree = "<group>"; };
|
||||
68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = "<group>"; };
|
||||
F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iPadGestureTests.m; sourceTree = "<group>"; };
|
||||
F72114B628EF99F500184A2D /* Info_Impeller.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info_Impeller.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@ -433,6 +457,18 @@
|
||||
684FFF7B29F9C10700281002 /* golden_platform_view_with_other_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
684FFF7A29F9C10700281002 /* golden_spawn_engine_works_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
684FFF6E29F9C10400281002 /* golden_two_platform_views_with_other_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */,
|
||||
);
|
||||
name = Goldens;
|
||||
sourceTree = "<group>";
|
||||
@ -623,6 +659,18 @@
|
||||
684FFF8729F9C10700281002 /* golden_platform_view_multiple_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
3BFD97202A990CF50094F51B /* golden_bogus_font_text_impeller_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1DE2C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1DF2C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E02C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E12C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E22C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E32C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E42C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E52C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E62C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E72C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E82C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
E0D5A1E92C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
68C9D8092AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
684FFF8D29F9C10700281002 /* golden_platform_view_large_cliprrect_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
684FFF8329F9C10700281002 /* golden_platform_view_transform_iPhone SE (3rd generation)_17.0_simulator.png in Resources */,
|
||||
|
||||
@ -60,14 +60,27 @@
|
||||
@"--platform-view-multiple-background-foreground" :
|
||||
@"platform_view_multiple_background_foreground",
|
||||
@"--platform-view-cliprect" : @"platform_view_cliprect",
|
||||
@"--platform-view-cliprect-multiple-clips" : @"platform_view_cliprect_multiple_clips",
|
||||
@"--platform-view-cliprrect" : @"platform_view_cliprrect",
|
||||
@"--platform-view-cliprrect-multiple-clips" : @"platform_view_cliprrect_multiple_clips",
|
||||
@"--platform-view-large-cliprrect" : @"platform_view_large_cliprrect",
|
||||
@"--platform-view-large-cliprrect-multiple-clips" :
|
||||
@"platform_view_large_cliprrect_multiple_clips",
|
||||
@"--platform-view-clippath" : @"platform_view_clippath",
|
||||
@"--platform-view-clippath-multiple-clips" : @"platform_view_clippath_multiple_clips",
|
||||
@"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform",
|
||||
@"--platform-view-cliprrect-with-transform-multiple-clips" :
|
||||
@"platform_view_cliprrect_with_transform_multiple_clips",
|
||||
@"--platform-view-large-cliprrect-with-transform" :
|
||||
@"platform_view_large_cliprrect_with_transform",
|
||||
@"--platform-view-large-cliprrect-with-transform-multiple-clips" :
|
||||
@"platform_view_large_cliprrect_with_transform_multiple_clips",
|
||||
@"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform",
|
||||
@"--platform-view-cliprect-with-transform-multiple-clips" :
|
||||
@"platform_view_cliprect_with_transform_multiple_clips",
|
||||
@"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform",
|
||||
@"--platform-view-clippath-with-transform-multiple-clips" :
|
||||
@"platform_view_clippath_with_transform_multiple_clips",
|
||||
@"--platform-view-transform" : @"platform_view_transform",
|
||||
@"--platform-view-opacity" : @"platform_view_opacity",
|
||||
@"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter",
|
||||
@ -91,10 +104,18 @@
|
||||
@"--pointer-events" : @"pointer_events",
|
||||
@"--platform-view-scrolling-under-widget" : @"platform_view_scrolling_under_widget",
|
||||
@"--platform-views-with-clips-scrolling" : @"platform_views_with_clips_scrolling",
|
||||
@"--platform-views-with-clips-scrolling-multiple-clips" :
|
||||
@"platform_views_with_clips_scrolling_multiple_clips",
|
||||
@"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved",
|
||||
@"--platform-view-cliprect-after-moved-multiple-clips" :
|
||||
@"platform_view_cliprect_after_moved_multiple_clips",
|
||||
@"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect",
|
||||
@"--two-platform-view-clip-rect-multiple-clips" : @"two_platform_view_clip_rect_multiple_clips",
|
||||
@"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect",
|
||||
@"--two-platform-view-clip-rrect-multiple-clips" :
|
||||
@"two_platform_view_clip_rrect_multiple_clips",
|
||||
@"--two-platform-view-clip-path" : @"two_platform_view_clip_path",
|
||||
@"--two-platform-view-clip-path-multiple-clips" : @"two_platform_view_clip_path_multiple_clips",
|
||||
@"--darwin-system-font" : @"darwin_system_font",
|
||||
};
|
||||
__block NSString* flutterViewControllerTestName = nil;
|
||||
|
||||
@ -29,14 +29,27 @@ const double kDefaultRmseThreshold = 0.5;
|
||||
@"--platform-view-multiple-background-foreground" :
|
||||
@"platform_view_multiple_background_foreground",
|
||||
@"--platform-view-cliprect" : @"platform_view_cliprect",
|
||||
@"--platform-view-cliprect-multiple-clips" : @"platform_view_cliprect_multiple_clips",
|
||||
@"--platform-view-cliprrect" : @"platform_view_cliprrect",
|
||||
@"--platform-view-cliprrect-multiple-clips" : @"platform_view_cliprrect_multiple_clips",
|
||||
@"--platform-view-large-cliprrect" : @"platform_view_large_cliprrect",
|
||||
@"--platform-view-large-cliprrect-multiple-clips" :
|
||||
@"platform_view_large_cliprrect_multiple_clips",
|
||||
@"--platform-view-clippath" : @"platform_view_clippath",
|
||||
@"--platform-view-clippath-multiple-clips" : @"platform_view_clippath_multiple_clips",
|
||||
@"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform",
|
||||
@"--platform-view-cliprrect-with-transform-multiple-clips" :
|
||||
@"platform_view_cliprrect_with_transform_multiple_clips",
|
||||
@"--platform-view-large-cliprrect-with-transform" :
|
||||
@"platform_view_large_cliprrect_with_transform",
|
||||
@"--platform-view-large-cliprrect-with-transform-multiple-clips" :
|
||||
@"platform_view_large_cliprrect_with_transform_multiple_clips",
|
||||
@"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform",
|
||||
@"--platform-view-cliprect-with-transform-multiple-clips" :
|
||||
@"platform_view_cliprect_with_transform_multiple_clips",
|
||||
@"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform",
|
||||
@"--platform-view-clippath-with-transform-multiple-clips" :
|
||||
@"platform_view_clippath_with_transform_multiple_clips",
|
||||
@"--platform-view-transform" : @"platform_view_transform",
|
||||
@"--platform-view-opacity" : @"platform_view_opacity",
|
||||
@"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter",
|
||||
@ -50,9 +63,17 @@ const double kDefaultRmseThreshold = 0.5;
|
||||
@"--bogus-font-text" : @"bogus_font_text",
|
||||
@"--spawn-engine-works" : @"spawn_engine_works",
|
||||
@"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved",
|
||||
@"--platform-view-cliprect-after-moved-multiple-clips" :
|
||||
@"platform_view_cliprect_after_moved_multiple_clips",
|
||||
@"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect",
|
||||
@"--two-platform-view-clip-rect-multiple-clips" :
|
||||
@"two_platform_view_clip_rect_multiple_clips",
|
||||
@"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect",
|
||||
@"--two-platform-view-clip-rrect-multiple-clips" :
|
||||
@"two_platform_view_clip_rrect_multiple_clips",
|
||||
@"--two-platform-view-clip-path" : @"two_platform_view_clip_path",
|
||||
@"--two-platform-view-clip-path-multiple-clips" :
|
||||
@"two_platform_view_clip_path_multiple_clips",
|
||||
@"--app-extension" : @"app_extension",
|
||||
@"--darwin-system-font" : @"darwin_system_font",
|
||||
};
|
||||
|
||||
@ -98,6 +98,25 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
// Clip Rect Tests
|
||||
@interface PlatformViewMutationClipRectWithMultiupleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipRectWithMultiupleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager =
|
||||
[[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprect-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRectAfterMovedTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -128,6 +147,36 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRectAfterMovedMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipRectAfterMovedMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-cliprect-after-moved-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
// This test needs to wait for several frames for the PlatformView to settle to
|
||||
// the correct position. The PlatformView accessiblity is set to platform_view[10000] when it is
|
||||
// ready.
|
||||
XCUIElement* element = self.application.otherElements[@"platform_view[10000]"];
|
||||
BOOL exists = [element waitForExistenceWithTimeout:kSecondsToWaitForPlatformView];
|
||||
if (!exists) {
|
||||
XCTFail(@"It took longer than %@ second to find the platform view."
|
||||
@"There might be issues with the platform view's construction,"
|
||||
@"or with how the scenario is built.",
|
||||
@(kSecondsToWaitForPlatformView));
|
||||
}
|
||||
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRRectTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -146,6 +195,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRRectMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipRRectMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager =
|
||||
[[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprrect-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationLargeClipRRectTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -164,6 +231,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationLargeClipRRectMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationLargeClipRRectMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-large-cliprrect-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipPathTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -182,6 +267,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipPathMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipPathMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager =
|
||||
[[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-clippath-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRectWithTransformTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -200,6 +303,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRectWithTransformMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipRectWithTransformMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-cliprect-with-transform-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRRectWithTransformTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -218,6 +339,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipRRectWithTransformMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipRRectWithTransformMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-cliprrect-with-transform-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationLargeClipRRectWithTransformTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -236,6 +375,25 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests
|
||||
: GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-large-cliprrect-with-transform-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipPathWithTransformTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -254,6 +412,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationClipPathWithTransformMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewMutationClipPathWithTransformMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-clippath-with-transform-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipRectTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -272,6 +448,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipRectMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation TwoPlatformViewClipRectMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager =
|
||||
[[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-rect-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipRRectTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -290,6 +484,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipRRectMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation TwoPlatformViewClipRRectMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--two-platform-view-clip-rrect-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipPathTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -308,6 +520,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface TwoPlatformViewClipPathMultipleClipsTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation TwoPlatformViewClipPathMultipleClipsTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager =
|
||||
[[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-path-multiple-clips"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewMutationTransformTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
@ -528,3 +758,41 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewWithClipsScrollingMultipleClips : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewWithClipsScrollingMultipleClips
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
self.continueAfterFailure = NO;
|
||||
}
|
||||
|
||||
- (void)testPlatformViewsWithClipsScrolling {
|
||||
XCUIApplication* app = [[XCUIApplication alloc] init];
|
||||
app.launchArguments = @[
|
||||
@"--platform-views-with-clips-scrolling", @"platform_views_with_clips_scrolling-multiple-clips"
|
||||
];
|
||||
[app launch];
|
||||
|
||||
XCUIElement* platformView = app.textViews.firstMatch;
|
||||
BOOL exists = [platformView waitForExistenceWithTimeout:kSecondsToWaitForPlatformView];
|
||||
if (!exists) {
|
||||
XCTFail(@"It took longer than %@ second to find the platform view."
|
||||
@"There might be issues with the platform view's construction,"
|
||||
@"or with how the scenario is built.",
|
||||
@(kSecondsToWaitForPlatformView));
|
||||
}
|
||||
|
||||
// Wait and let the scenario app scroll a bit.
|
||||
XCTWaiterResult waitResult = [XCTWaiter
|
||||
waitForExpectations:@[ [[XCTestExpectation alloc] initWithDescription:@"Wait for 5 seconds"] ]
|
||||
timeout:5];
|
||||
// If the waiter is not interrupted, we know the app is in a valid state after timeout, thus the
|
||||
// test passes.
|
||||
XCTAssert(waitResult != XCTWaiterResultInterrupted);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 31 KiB |
@ -680,6 +680,33 @@ class PlatformViewClipRectScenario extends Scenario with _BasePlatformViewScenar
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rect, with multiple clips.
|
||||
class PlatformViewClipRectMultipleClipsScenario extends Scenario with _BasePlatformViewScenarioMixin {
|
||||
/// Constructs a platform view with clip rect scenario.
|
||||
PlatformViewClipRectMultipleClipsScenario(
|
||||
super.view, {
|
||||
required this.id,
|
||||
});
|
||||
|
||||
/// The platform view identifier.
|
||||
final int id;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder()
|
||||
..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400))
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rect then the PlatformView is moved for 10 frames.
|
||||
///
|
||||
/// The clip rect moves with the same transform matrix with the PlatformView.
|
||||
@ -735,6 +762,64 @@ class PlatformViewClipRectAfterMovedScenario extends Scenario with _BasePlatform
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Platform view with clip rect with multiple clips then the PlatformView is moved for 10 frames.
|
||||
///
|
||||
/// The clip rect moves with the same transform matrix with the PlatformView.
|
||||
class PlatformViewClipRectAfterMovedMultipleClipsScenario extends Scenario with _BasePlatformViewScenarioMixin {
|
||||
/// Constructs a platform view with clip rect scenario.
|
||||
PlatformViewClipRectAfterMovedMultipleClipsScenario(
|
||||
super.view, {
|
||||
required this.id,
|
||||
});
|
||||
|
||||
/// The platform view identifier.
|
||||
final int id;
|
||||
|
||||
int _numberOfFrames = 0;
|
||||
|
||||
double _y = 100.0;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Matrix4 translateMatrix = Matrix4.identity()..translate(0.0, _y);
|
||||
final SceneBuilder builder = SceneBuilder()
|
||||
..pushTransform(translateMatrix.storage)
|
||||
..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400))
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
_numberOfFrames == 10? 10000: id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
// Add a translucent rect that has the same size of PlatformView.
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTWH(0, 0, 500, 500),
|
||||
Paint()..color = const Color(0x22FF0000),
|
||||
);
|
||||
final Picture picture = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture);
|
||||
|
||||
finishBuilder(builder);
|
||||
super.onBeginFrame(duration);
|
||||
}
|
||||
|
||||
@override
|
||||
void onDrawFrame() {
|
||||
if (_numberOfFrames < 10) {
|
||||
_numberOfFrames ++;
|
||||
_y -= 10;
|
||||
view.platformDispatcher.scheduleFrame();
|
||||
}
|
||||
super.onDrawFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Platform view with clip rrect.
|
||||
class PlatformViewClipRRectScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rrect scenario.
|
||||
@ -768,6 +853,40 @@ class PlatformViewClipRRectScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect, with multiple clips.
|
||||
class PlatformViewClipRRectMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rrect scenario.
|
||||
PlatformViewClipRRectMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
100,
|
||||
100,
|
||||
400,
|
||||
400,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect.
|
||||
/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView.
|
||||
class PlatformViewLargeClipRRectScenario extends PlatformViewScenario {
|
||||
@ -802,6 +921,41 @@ class PlatformViewLargeClipRRectScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect, with multiple clips.
|
||||
/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView.
|
||||
class PlatformViewLargeClipRRectMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with large clip rrect scenario.
|
||||
PlatformViewLargeClipRRectMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
0,
|
||||
0,
|
||||
500,
|
||||
500,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip path.
|
||||
class PlatformViewClipPathScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip path scenario.
|
||||
@ -829,6 +983,35 @@ class PlatformViewClipPathScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip path, with multiple clips.
|
||||
class PlatformViewClipPathMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip path scenario.
|
||||
PlatformViewClipPathMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Path path = Path()
|
||||
..moveTo(100, 100)
|
||||
..quadraticBezierTo(50, 250, 100, 400)
|
||||
..lineTo(350, 400)
|
||||
..cubicTo(400, 300, 300, 200, 350, 100)
|
||||
..close();
|
||||
|
||||
final SceneBuilder builder = SceneBuilder()..pushClipPath(path)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rect after transformed.
|
||||
class PlatformViewClipRectWithTransformScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rect with transform scenario.
|
||||
@ -867,6 +1050,45 @@ class PlatformViewClipRectWithTransformScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rect after transformed, with multiple clips.
|
||||
class PlatformViewClipRectWithTransformMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rect with transform scenario.
|
||||
PlatformViewClipRectWithTransformMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Matrix4 matrix4 = Matrix4.identity()
|
||||
..rotateZ(1)
|
||||
..scale(0.5, 0.5, 1.0)
|
||||
..translate(1000.0, 100.0);
|
||||
|
||||
final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage);
|
||||
builder..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400))
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
// Add a translucent rect that has the same size of PlatformView.
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTWH(0, 0, 500, 500),
|
||||
Paint()..color = const Color(0x22FF0000),
|
||||
);
|
||||
final Picture picture = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect after transformed.
|
||||
class PlatformViewClipRRectWithTransformScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rrect with transform scenario.
|
||||
@ -914,6 +1136,55 @@ class PlatformViewClipRRectWithTransformScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect after transformed, with multiple clips.
|
||||
class PlatformViewClipRRectWithTransformMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip rrect with transform scenario.
|
||||
PlatformViewClipRRectWithTransformMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Matrix4 matrix4 = Matrix4.identity()
|
||||
..rotateZ(1)
|
||||
..scale(0.5, 0.5, 1.0)
|
||||
..translate(1000.0, 100.0);
|
||||
|
||||
final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage);
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
100,
|
||||
100,
|
||||
400,
|
||||
400,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
// Add a translucent rect that has the same size of PlatformView.
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTWH(0, 0, 500, 500),
|
||||
Paint()..color = const Color(0x22FF0000),
|
||||
);
|
||||
final Picture picture = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect after transformed.
|
||||
/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView.
|
||||
class PlatformViewLargeClipRRectWithTransformScenario extends PlatformViewScenario {
|
||||
@ -962,6 +1233,56 @@ class PlatformViewLargeClipRRectWithTransformScenario extends PlatformViewScenar
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip rrect after transformed, with multiple clips.
|
||||
/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView.
|
||||
class PlatformViewLargeClipRRectWithTransformMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with large clip rrect with transform scenario.
|
||||
PlatformViewLargeClipRRectWithTransformMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Matrix4 matrix4 = Matrix4.identity()
|
||||
..rotateZ(1)
|
||||
..scale(0.5, 0.5, 1.0)
|
||||
..translate(1000.0, 100.0);
|
||||
|
||||
final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage);
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
0,
|
||||
0,
|
||||
500,
|
||||
500,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
// Add a translucent rect that has the same size of PlatformView.
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTWH(0, 0, 500, 500),
|
||||
Paint()..color = const Color(0x22FF0000),
|
||||
);
|
||||
final Picture picture = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip path after transformed.
|
||||
class PlatformViewClipPathWithTransformScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip path with transform scenario.
|
||||
@ -1006,6 +1327,52 @@ class PlatformViewClipPathWithTransformScenario extends PlatformViewScenario {
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with clip path after transformed, with multiple clips.
|
||||
class PlatformViewClipPathWithTransformMultipleClipsScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with clip path with transform scenario.
|
||||
PlatformViewClipPathWithTransformMultipleClipsScenario(
|
||||
super.view, {
|
||||
super.id = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final Matrix4 matrix4 = Matrix4.identity()
|
||||
..rotateZ(1)
|
||||
..scale(0.5, 0.5, 1.0)
|
||||
..translate(1000.0, 100.0);
|
||||
|
||||
final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage);
|
||||
final Path path = Path()
|
||||
..moveTo(100, 100)
|
||||
..quadraticBezierTo(50, 250, 100, 400)
|
||||
..lineTo(350, 400)
|
||||
..cubicTo(400, 300, 300, 200, 350, 100)
|
||||
..close();
|
||||
|
||||
builder..pushClipPath(path)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
);
|
||||
|
||||
// Add a translucent rect that has the same size of PlatformView.
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTWH(0, 0, 500, 500),
|
||||
Paint()..color = const Color(0x22FF0000),
|
||||
);
|
||||
final Picture picture = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture);
|
||||
|
||||
finishBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// Two platform views, both have clip rects
|
||||
class TwoPlatformViewClipRect extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
@ -1055,6 +1422,59 @@ class TwoPlatformViewClipRect extends Scenario
|
||||
}
|
||||
}
|
||||
|
||||
/// Two platform views, both have clip rects, with multiple clips.
|
||||
class TwoPlatformViewClipRectMultipleClips extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Creates the PlatformView scenario.
|
||||
TwoPlatformViewClipRectMultipleClips(
|
||||
super.view, {
|
||||
required this.firstId,
|
||||
required this.secondId,
|
||||
});
|
||||
|
||||
/// The platform view identifier to use for the first platform view.
|
||||
final int firstId;
|
||||
|
||||
/// The platform view identifier to use for the second platform view.
|
||||
final int secondId;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
builder.pushOffset(0, 600);
|
||||
builder..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400))
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
firstId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 1',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
|
||||
// Use a different rect to differentiate from the 1st clip rect.
|
||||
builder..pushClipRect(const Rect.fromLTRB(100, 100, 300, 300))
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
addPlatformView(
|
||||
secondId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 2',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
final Scene scene = builder.build();
|
||||
view.render(scene);
|
||||
scene.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Two platform views, both have clip rrects
|
||||
class TwoPlatformViewClipRRect extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
@ -1124,6 +1544,81 @@ class TwoPlatformViewClipRRect extends Scenario
|
||||
}
|
||||
}
|
||||
|
||||
/// Two platform views, both have clip rrects, with multiple clips.
|
||||
class TwoPlatformViewClipRRectMultipleClips extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Creates the PlatformView scenario.
|
||||
TwoPlatformViewClipRRectMultipleClips(
|
||||
super.view, {
|
||||
required this.firstId,
|
||||
required this.secondId,
|
||||
});
|
||||
|
||||
/// The platform view identifier to use for the first platform view.
|
||||
final int firstId;
|
||||
|
||||
/// The platform view identifier to use for the second platform view.
|
||||
final int secondId;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
builder.pushOffset(0, 600);
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
0,
|
||||
0,
|
||||
500,
|
||||
500,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
|
||||
addPlatformView(
|
||||
firstId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 1',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
|
||||
// Use a different rrect to differentiate from the 1st clip rrect.
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
0,
|
||||
0,
|
||||
500,
|
||||
500,
|
||||
topLeft: const Radius.circular(100),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
|
||||
addPlatformView(
|
||||
secondId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 2',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
final Scene scene = builder.build();
|
||||
view.render(scene);
|
||||
scene.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Two platform views, both have clip path
|
||||
class TwoPlatformViewClipPath extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
@ -1187,6 +1682,76 @@ class TwoPlatformViewClipPath extends Scenario
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Two platform views, both have clip path, with multiple clips.
|
||||
class TwoPlatformViewClipPathMultipleClips extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Creates the PlatformView scenario.
|
||||
TwoPlatformViewClipPathMultipleClips(
|
||||
super.view, {
|
||||
required this.firstId,
|
||||
required this.secondId,
|
||||
});
|
||||
|
||||
/// The platform view identifier to use for the first platform view.
|
||||
final int firstId;
|
||||
|
||||
/// The platform view identifier to use for the second platform view.
|
||||
final int secondId;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
builder.pushOffset(0, 600);
|
||||
final Path path = Path()
|
||||
..moveTo(100, 100)
|
||||
..quadraticBezierTo(50, 250, 100, 400)
|
||||
..lineTo(350, 400)
|
||||
..cubicTo(400, 300, 300, 200, 350, 100)
|
||||
..close();
|
||||
|
||||
builder..pushClipPath(path)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
|
||||
addPlatformView(
|
||||
firstId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 1',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
|
||||
// Use a different path to differentiate from the 1st clip path.
|
||||
final Path path2 = Path()
|
||||
..moveTo(100, 100)
|
||||
..quadraticBezierTo(100, 150, 100, 400)
|
||||
..lineTo(350, 350)
|
||||
..cubicTo(400, 300, 300, 200, 350, 200)
|
||||
..close();
|
||||
|
||||
builder..pushClipPath(path2)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600));
|
||||
|
||||
|
||||
addPlatformView(
|
||||
secondId,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view 2',
|
||||
);
|
||||
|
||||
builder.pop();
|
||||
builder.pop();
|
||||
final Scene scene = builder.build();
|
||||
view.render(scene);
|
||||
scene.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform view with transform.
|
||||
class PlatformViewTransformScenario extends PlatformViewScenario {
|
||||
/// Constructs a platform view with transform scenario.
|
||||
@ -1885,6 +2450,94 @@ class PlatformViewsWithClipsScrolling extends Scenario
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a scenario where many platform views with clips scrolling, with multiple clips.
|
||||
class PlatformViewsWithClipsScrollingMultipleClips extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Creates the PlatformView scenario.
|
||||
PlatformViewsWithClipsScrollingMultipleClips(
|
||||
super.view, {
|
||||
required int firstPlatformViewId,
|
||||
required int lastPlatformViewId,
|
||||
}) : _firstPlatformViewId = firstPlatformViewId,
|
||||
_lastPlatformViewId = lastPlatformViewId;
|
||||
|
||||
final int _firstPlatformViewId;
|
||||
|
||||
final int _lastPlatformViewId;
|
||||
|
||||
double _offset = 0;
|
||||
|
||||
bool _movingUp = true;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
_buildOneFrame(_offset);
|
||||
}
|
||||
|
||||
@override
|
||||
void onDrawFrame() {
|
||||
// Scroll up until -1000, then scroll down until -1.
|
||||
if (_offset < -500) {
|
||||
_movingUp = false;
|
||||
} else if (_offset > -1) {
|
||||
_movingUp = true;
|
||||
}
|
||||
|
||||
if (_movingUp) {
|
||||
_offset -= 100;
|
||||
} else {
|
||||
_offset += 100;
|
||||
}
|
||||
view.platformDispatcher.scheduleFrame();
|
||||
super.onDrawFrame();
|
||||
}
|
||||
|
||||
Future<void> _buildOneFrame(double offset) async {
|
||||
const double cellWidth = 1000;
|
||||
double localOffset = offset;
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
const double cellHeight = 300;
|
||||
for (int i = _firstPlatformViewId; i <= _lastPlatformViewId; i++) {
|
||||
// Build a list view with platform views.
|
||||
builder.pushOffset(0, localOffset);
|
||||
bool addedClipRRect = false;
|
||||
if (localOffset > -1) {
|
||||
addedClipRRect = true;
|
||||
builder..pushClipRRect(
|
||||
RRect.fromLTRBAndCorners(
|
||||
100,
|
||||
100,
|
||||
400,
|
||||
400,
|
||||
topLeft: const Radius.circular(15),
|
||||
topRight: const Radius.circular(50),
|
||||
bottomLeft: const Radius.circular(50),
|
||||
),
|
||||
)
|
||||
..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600));
|
||||
|
||||
}
|
||||
addPlatformView(
|
||||
i,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
text: 'platform view $i',
|
||||
width: cellWidth,
|
||||
height: cellHeight,
|
||||
);
|
||||
if (addedClipRRect) {
|
||||
builder.pop();
|
||||
}
|
||||
builder.pop();
|
||||
localOffset += cellHeight;
|
||||
}
|
||||
|
||||
final Scene scene = builder.build();
|
||||
view.render(scene);
|
||||
scene.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, int> _createdPlatformViews = <String, int> {};
|
||||
final Map<String, bool> _calledToBeCreatedPlatformViews = <String, bool> {};
|
||||
|
||||
|
||||
@ -37,14 +37,23 @@ Map<String, _ScenarioFactory> _scenarios = <String, _ScenarioFactory>{
|
||||
'platform_view_surrounding_layers_fractional_coordinate': (FlutterView view) => PlatformViewSurroundingLayersFractionalCoordinateScenario(view, id: _viewId++),
|
||||
'platform_view_partial_intersection_fractional_coordinate': (FlutterView view) => PlatformViewPartialIntersectionFractionalCoordinateScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect': (FlutterView view) => PlatformViewClipRectScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect_multiple_clips': (FlutterView view) => PlatformViewClipRectMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect_with_transform': (FlutterView view) => PlatformViewClipRectWithTransformScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipRectWithTransformMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect_after_moved': (FlutterView view) => PlatformViewClipRectAfterMovedScenario(view, id: _viewId++),
|
||||
'platform_view_cliprect_after_moved_multiple_clips': (FlutterView view) => PlatformViewClipRectAfterMovedMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_cliprrect': (FlutterView view) => PlatformViewClipRRectScenario(view, id: _viewId++),
|
||||
'platform_view_cliprrect_multiple_clips': (FlutterView view) => PlatformViewClipRRectMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_large_cliprrect': (FlutterView view) => PlatformViewLargeClipRRectScenario(view, id: _viewId++),
|
||||
'platform_view_large_cliprrect_multiple_clips': (FlutterView view) => PlatformViewLargeClipRRectMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_cliprrect_with_transform': (FlutterView view) => PlatformViewClipRRectWithTransformScenario(view, id: _viewId++),
|
||||
'platform_view_cliprrect_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipRRectWithTransformMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_large_cliprrect_with_transform': (FlutterView view) => PlatformViewLargeClipRRectWithTransformScenario(view, id: _viewId++),
|
||||
'platform_view_large_cliprrect_with_transform_multiple_clips': (FlutterView view) => PlatformViewLargeClipRRectWithTransformMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_clippath': (FlutterView view) => PlatformViewClipPathScenario(view, id: _viewId++),
|
||||
'platform_view_clippath_multiple_clips': (FlutterView view) => PlatformViewClipPathMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_clippath_with_transform': (FlutterView view) => PlatformViewClipPathWithTransformScenario(view, id: _viewId++),
|
||||
'platform_view_clippath_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipPathWithTransformMultipleClipsScenario(view, id: _viewId++),
|
||||
'platform_view_transform': (FlutterView view) => PlatformViewTransformScenario(view, id: _viewId++),
|
||||
'platform_view_opacity': (FlutterView view) => PlatformViewOpacityScenario(view, id: _viewId++),
|
||||
'platform_view_with_other_backdrop_filter': (FlutterView view) => PlatformViewWithOtherBackDropFilter(view, id: _viewId++),
|
||||
@ -61,9 +70,13 @@ Map<String, _ScenarioFactory> _scenarios = <String, _ScenarioFactory>{
|
||||
'platform_view_gesture_accept_with_overlapping_platform_views': (FlutterView view) => PlatformViewForOverlappingPlatformViewsScenario(view, foregroundId: _viewId++, backgroundId: _viewId++),
|
||||
'platform_view_scrolling_under_widget':(FlutterView view) => PlatformViewScrollingUnderWidget(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16),
|
||||
'platform_views_with_clips_scrolling':(FlutterView view) => PlatformViewsWithClipsScrolling(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16),
|
||||
'platform_views_with_clips_scrolling_multiple_clips':(FlutterView view) => PlatformViewsWithClipsScrollingMultipleClips(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16),
|
||||
'two_platform_view_clip_rect': (FlutterView view) => TwoPlatformViewClipRect(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'two_platform_view_clip_rect_multiple_clips': (FlutterView view) => TwoPlatformViewClipRectMultipleClips(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'two_platform_view_clip_rrect': (FlutterView view) => TwoPlatformViewClipRRect(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'two_platform_view_clip_rrect_multiple_clips': (FlutterView view) => TwoPlatformViewClipRRectMultipleClips(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'two_platform_view_clip_path': (FlutterView view) => TwoPlatformViewClipPath(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'two_platform_view_clip_path_multiple_clips': (FlutterView view) => TwoPlatformViewClipPathMultipleClips(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'tap_status_bar': (FlutterView view) => TouchesScenario(view),
|
||||
'initial_route_reply': (FlutterView view) => InitialRouteReply(view),
|
||||
'platform_view_with_continuous_texture': (FlutterView view) => PlatformViewWithContinuousTexture(view, id: _viewId++),
|
||||
|
||||
@ -110,14 +110,23 @@ if set -o pipefail && xcodebuild -sdk iphonesimulator \
|
||||
-skip-testing ScenariosUITests/MultiplePlatformViewsTest/testPlatformView \
|
||||
-skip-testing ScenariosUITests/NonFullScreenFlutterViewPlatformViewUITests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipPathTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipPathMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipPathWithTransformTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipPathWithTransformMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectAfterMovedTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectAfterMovedMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectWithTransformTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRectWithTransformMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRRectTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRRectMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRRectWithTransformTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationClipRRectWithTransformMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationOpacityTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewMutationTransformTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/PlatformViewRotation/testPlatformView \
|
||||
@ -126,8 +135,11 @@ if set -o pipefail && xcodebuild -sdk iphonesimulator \
|
||||
-skip-testing ScenariosUITests/PlatformViewWithOtherBackdropFilterTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/RenderingSelectionTest/testSoftwareRendering \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipPathTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipPathMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipRectTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipRectMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipRRectTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewClipRRectMultipleClipsTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/TwoPlatformViewsWithOtherBackDropFilterTests/testPlatformView \
|
||||
-skip-testing ScenariosUITests/UnobstructedPlatformViewTests/testMultiplePlatformViewsWithOverlays \
|
||||
# Plist with FLTEnableImpeller=YES, all projects in the workspace requires this file.
|
||||
|
||||