diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm index 20e3b15bf36..14988329a4a 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm @@ -538,7 +538,7 @@ static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) { break; } [self clipViewSetMaskView:clipView]; - [(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRRect() + [(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRSEApproximation() matrix:transformMatrix]; break; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 4c781e60dee..c42eb14036a 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -4619,4 +4619,84 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertEqual(*submit_info->buffer_damage, SkIRect::MakeWH(400, 600)); } +- (void)testClipSuperellipse { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/GetDefaultTaskRunner(), + /*raster=*/GetDefaultTaskRunner(), + /*ui=*/GetDefaultTaskRunner(), + /*io=*/GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); + auto platform_view = std::make_unique( + /*delegate=*/mock_delegate, + /*rendering_api=*/flutter::IOSRenderingAPI::kMetal, + /*platform_views_controller=*/flutterPlatformViewsController, + /*task_runners=*/runners, + /*worker_task_runner=*/nil, + /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; + FlutterResult result = ^(id result) { + }; + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; + + XCTAssertNotNil(gMockPlatformView); + + UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; + flutterPlatformViewsController.flutterView = flutterView; + // Create embedded view params + flutter::MutatorsStack stack; + // Layer tree always pushes a screen scale factor to the stack + flutter::DlScalar screenScale = [UIScreen mainScreen].scale; + flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1}); + stack.PushTransform(screenScaleMatrix); + // Push a clip superellipse + flutter::DlRect rect = flutter::DlRect::MakeXYWH(3, 3, 5, 5); + stack.PushClipRSE(flutter::DlRoundSuperellipse::MakeOval(rect)); + + auto embeddedViewParams = std::make_unique( + flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack); + + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView: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]; + + CGPoint corners[] = {CGPointMake(rect.GetLeft(), rect.GetTop()), + CGPointMake(rect.GetRight(), rect.GetTop()), + CGPointMake(rect.GetLeft(), rect.GetBottom()), + CGPointMake(rect.GetRight(), rect.GetBottom())}; + for (auto point : corners) { + int alpha = [self alphaOfPoint:point onView:flutterView]; + XCTAssertNotEqual(alpha, 255); + } + CGPoint center = + CGPointMake(rect.GetLeft() + rect.GetWidth() / 2, rect.GetTop() + rect.GetHeight() / 2); + int alpha = [self alphaOfPoint:center onView:flutterView]; + XCTAssertEqual(alpha, 255); +} + @end