mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Apply superellipse clipping to iOS platform views using an approximated round rect (#172033)
Fixes https://github.com/flutter/flutter/issues/171966
This commit is contained in:
parent
c845f06094
commit
d18e28d855
@ -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;
|
||||
}
|
||||
|
||||
@ -4619,4 +4619,84 @@ fml::RefPtr<fml::TaskRunner> 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<flutter::PlatformViewIOS>(
|
||||
/*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<fml::SyncSwitch>());
|
||||
|
||||
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::EmbeddedViewParams>(
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user