@@ -1856,6 +1856,102 @@ - (void)testClipRect {
1856
1856
}
1857
1857
}
1858
1858
1859
+ - (void )testClipRect_multipleClips {
1860
+ flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1861
+
1862
+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
1863
+ /* platform=*/ GetDefaultTaskRunner (),
1864
+ /* raster=*/ GetDefaultTaskRunner (),
1865
+ /* ui=*/ GetDefaultTaskRunner (),
1866
+ /* io=*/ GetDefaultTaskRunner ());
1867
+ auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
1868
+ flutterPlatformViewsController->SetTaskRunner (GetDefaultTaskRunner ());
1869
+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1870
+ /* delegate=*/ mock_delegate,
1871
+ /* rendering_api=*/ mock_delegate.settings_ .enable_impeller
1872
+ ? flutter::IOSRenderingAPI::kMetal
1873
+ : flutter::IOSRenderingAPI::kSoftware ,
1874
+ /* platform_views_controller=*/ flutterPlatformViewsController,
1875
+ /* task_runners=*/ runners,
1876
+ /* worker_task_runner=*/ nil ,
1877
+ /* is_gpu_disabled_jsync_switch=*/ std::make_shared<fml::SyncSwitch>());
1878
+
1879
+ FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
1880
+ [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc ] init ];
1881
+ flutterPlatformViewsController->RegisterViewFactory (
1882
+ factory, @" MockFlutterPlatformView" ,
1883
+ FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
1884
+ FlutterResult result = ^(id result) {
1885
+ };
1886
+ flutterPlatformViewsController->OnMethodCall (
1887
+ [FlutterMethodCall
1888
+ methodCallWithMethodName: @" create"
1889
+ arguments: @{@" id" : @2 , @" viewType" : @" MockFlutterPlatformView" }],
1890
+ result);
1891
+
1892
+ XCTAssertNotNil (gMockPlatformView );
1893
+
1894
+ UIView* flutterView = [[UIView alloc ] initWithFrame: CGRectMake (0 , 0 , 10 , 10 )];
1895
+ flutterPlatformViewsController->SetFlutterView (flutterView);
1896
+ // Create embedded view params
1897
+ flutter::MutatorsStack stack;
1898
+ // Layer tree always pushes a screen scale factor to the stack
1899
+ SkMatrix screenScaleMatrix =
1900
+ SkMatrix::Scale ([UIScreen mainScreen ].scale , [UIScreen mainScreen ].scale );
1901
+ stack.PushTransform (screenScaleMatrix);
1902
+ // Push a clip rect
1903
+ SkRect rect1 = SkRect::MakeXYWH (2 , 2 , 3 , 3 );
1904
+ stack.PushClipRect (rect1);
1905
+ // Push another clip rect
1906
+ SkRect rect2 = SkRect::MakeXYWH (3 , 3 , 3 , 3 );
1907
+ stack.PushClipRect (rect2);
1908
+
1909
+ auto embeddedViewParams =
1910
+ std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make (10 , 10 ), stack);
1911
+
1912
+ flutterPlatformViewsController->PrerollCompositeEmbeddedView (2 , std::move (embeddedViewParams));
1913
+ flutterPlatformViewsController->CompositeWithParams (
1914
+ 2 , flutterPlatformViewsController->GetCompositionParams (2 ));
1915
+
1916
+ gMockPlatformView .backgroundColor = UIColor.redColor ;
1917
+ XCTAssertTrue ([gMockPlatformView .superview.superview isKindOfClass: ChildClippingView.class ]);
1918
+ ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView .superview .superview ;
1919
+ [flutterView addSubview: childClippingView];
1920
+
1921
+ [flutterView setNeedsLayout ];
1922
+ [flutterView layoutIfNeeded ];
1923
+
1924
+ /*
1925
+ clip 1 clip 2
1926
+ 2 3 4 5 6 2 3 4 5 6
1927
+ 2 + - - + 2
1928
+ 3 | | 3 + - - +
1929
+ 4 | | 4 | |
1930
+ 5 + - - + 5 | |
1931
+ 6 6 + - - +
1932
+
1933
+ Result should be the intersection of 2 clips
1934
+ 2 3 4 5 6
1935
+ 2
1936
+ 3 + - +
1937
+ 4 | |
1938
+ 5 + - +
1939
+ 6
1940
+ */
1941
+ CGRect insideClipping = CGRectMake (3 , 3 , 2 , 2 );
1942
+ for (int i = 0 ; i < 10 ; i++) {
1943
+ for (int j = 0 ; j < 10 ; j++) {
1944
+ CGPoint point = CGPointMake (i, j);
1945
+ int alpha = [self alphaOfPoint: CGPointMake (i, j) onView: flutterView];
1946
+ if (CGRectContainsPoint (insideClipping, point)) {
1947
+ XCTAssertEqual (alpha, 255 );
1948
+ } else {
1949
+ XCTAssertEqual (alpha, 0 );
1950
+ }
1951
+ }
1952
+ }
1953
+ }
1954
+
1859
1955
- (void )testClipRRect {
1860
1956
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1861
1957
@@ -1959,6 +2055,126 @@ - (void)testClipRRect {
1959
2055
}
1960
2056
}
1961
2057
2058
+ - (void )testClipRRect_multipleClips {
2059
+ flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2060
+
2061
+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
2062
+ /* platform=*/ GetDefaultTaskRunner (),
2063
+ /* raster=*/ GetDefaultTaskRunner (),
2064
+ /* ui=*/ GetDefaultTaskRunner (),
2065
+ /* io=*/ GetDefaultTaskRunner ());
2066
+ auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
2067
+ flutterPlatformViewsController->SetTaskRunner (GetDefaultTaskRunner ());
2068
+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2069
+ /* delegate=*/ mock_delegate,
2070
+ /* rendering_api=*/ mock_delegate.settings_ .enable_impeller
2071
+ ? flutter::IOSRenderingAPI::kMetal
2072
+ : flutter::IOSRenderingAPI::kSoftware ,
2073
+ /* platform_views_controller=*/ flutterPlatformViewsController,
2074
+ /* task_runners=*/ runners,
2075
+ /* worker_task_runner=*/ nil ,
2076
+ /* is_gpu_disabled_jsync_switch=*/ std::make_shared<fml::SyncSwitch>());
2077
+
2078
+ FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
2079
+ [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc ] init ];
2080
+ flutterPlatformViewsController->RegisterViewFactory (
2081
+ factory, @" MockFlutterPlatformView" ,
2082
+ FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
2083
+ FlutterResult result = ^(id result) {
2084
+ };
2085
+ flutterPlatformViewsController->OnMethodCall (
2086
+ [FlutterMethodCall
2087
+ methodCallWithMethodName: @" create"
2088
+ arguments: @{@" id" : @2 , @" viewType" : @" MockFlutterPlatformView" }],
2089
+ result);
2090
+
2091
+ XCTAssertNotNil (gMockPlatformView );
2092
+
2093
+ UIView* flutterView = [[UIView alloc ] initWithFrame: CGRectMake (0 , 0 , 10 , 10 )];
2094
+ flutterPlatformViewsController->SetFlutterView (flutterView);
2095
+ // Create embedded view params
2096
+ flutter::MutatorsStack stack;
2097
+ // Layer tree always pushes a screen scale factor to the stack
2098
+ SkMatrix screenScaleMatrix =
2099
+ SkMatrix::Scale ([UIScreen mainScreen ].scale , [UIScreen mainScreen ].scale );
2100
+ stack.PushTransform (screenScaleMatrix);
2101
+ // Push a clip rrect
2102
+ SkRRect rrect = SkRRect::MakeRectXY (SkRect::MakeXYWH (2 , 2 , 6 , 6 ), 1 , 1 );
2103
+ stack.PushClipRRect (rrect);
2104
+ // Push a clip rect
2105
+ SkRect rect = SkRect::MakeXYWH (4 , 2 , 6 , 6 );
2106
+ stack.PushClipRect (rect);
2107
+
2108
+ auto embeddedViewParams =
2109
+ std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make (10 , 10 ), stack);
2110
+
2111
+ flutterPlatformViewsController->PrerollCompositeEmbeddedView (2 , std::move (embeddedViewParams));
2112
+ flutterPlatformViewsController->CompositeWithParams (
2113
+ 2 , flutterPlatformViewsController->GetCompositionParams (2 ));
2114
+
2115
+ gMockPlatformView .backgroundColor = UIColor.redColor ;
2116
+ XCTAssertTrue ([gMockPlatformView .superview.superview isKindOfClass: ChildClippingView.class ]);
2117
+ ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView .superview .superview ;
2118
+ [flutterView addSubview: childClippingView];
2119
+
2120
+ [flutterView setNeedsLayout ];
2121
+ [flutterView layoutIfNeeded ];
2122
+
2123
+ /*
2124
+ clip 1 clip 2
2125
+ 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9
2126
+ 2 / - - - - \ 2 + - - - - +
2127
+ 3 | | 3 | |
2128
+ 4 | | 4 | |
2129
+ 5 | | 5 | |
2130
+ 6 | | 6 | |
2131
+ 7 \ - - - - / 7 + - - - - +
2132
+
2133
+ Result should be the intersection of 2 clips
2134
+ 2 3 4 5 6 7 8 9
2135
+ 2 + - - \
2136
+ 3 | |
2137
+ 4 | |
2138
+ 5 | |
2139
+ 6 | |
2140
+ 7 + - - /
2141
+ */
2142
+ CGRect clipping = CGRectMake (4 , 2 , 4 , 6 );
2143
+ for (int i = 0 ; i < 10 ; i++) {
2144
+ for (int j = 0 ; j < 10 ; j++) {
2145
+ CGPoint point = CGPointMake (i, j);
2146
+ int alpha = [self alphaOfPoint: CGPointMake (i, j) onView: flutterView];
2147
+ if (i == 7 && (j == 2 || j == 7 )) {
2148
+ // Upper and lower right corners should be partially transparent.
2149
+ XCTAssert (0 < alpha && alpha < 255 );
2150
+ } else if (
2151
+ // left
2152
+ (i == 4 && j >= 2 && j <= 7 ) ||
2153
+ // right
2154
+ (i == 7 && j >= 2 && j <= 7 ) ||
2155
+ // top
2156
+ (j == 2 && i >= 4 && i <= 7 ) ||
2157
+ // bottom
2158
+ (j == 7 && i >= 4 && i <= 7 )) {
2159
+ // Since we are falling back to software rendering for this case
2160
+ // The edge pixels can be anti-aliased, so it may not be fully opaque.
2161
+ XCTAssert (alpha > 127 );
2162
+ } else if ((i == 3 && j >= 1 && j <= 8 ) || (i == 8 && j >= 1 && j <= 8 ) ||
2163
+ (j == 1 && i >= 3 && i <= 8 ) || (j == 8 && i >= 3 && i <= 8 )) {
2164
+ // Since we are falling back to software rendering for this case
2165
+ // The edge pixels can be anti-aliased, so it may not be fully transparent.
2166
+ XCTAssert (alpha < 127 );
2167
+ } else if (CGRectContainsPoint (clipping, point)) {
2168
+ // Other pixels inside clipping should be fully opaque.
2169
+ XCTAssertEqual (alpha, 255 );
2170
+ } else {
2171
+ // Pixels outside clipping should be fully transparent.
2172
+ XCTAssertEqual (alpha, 0 );
2173
+ }
2174
+ }
2175
+ }
2176
+ }
2177
+
1962
2178
- (void )testClipPath {
1963
2179
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1964
2180
@@ -2063,6 +2279,127 @@ - (void)testClipPath {
2063
2279
}
2064
2280
}
2065
2281
2282
+ - (void )testClipPath_multipleClips {
2283
+ flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2284
+
2285
+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
2286
+ /* platform=*/ GetDefaultTaskRunner (),
2287
+ /* raster=*/ GetDefaultTaskRunner (),
2288
+ /* ui=*/ GetDefaultTaskRunner (),
2289
+ /* io=*/ GetDefaultTaskRunner ());
2290
+ auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
2291
+ flutterPlatformViewsController->SetTaskRunner (GetDefaultTaskRunner ());
2292
+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2293
+ /* delegate=*/ mock_delegate,
2294
+ /* rendering_api=*/ mock_delegate.settings_ .enable_impeller
2295
+ ? flutter::IOSRenderingAPI::kMetal
2296
+ : flutter::IOSRenderingAPI::kSoftware ,
2297
+ /* platform_views_controller=*/ flutterPlatformViewsController,
2298
+ /* task_runners=*/ runners,
2299
+ /* worker_task_runner=*/ nil ,
2300
+ /* is_gpu_disabled_jsync_switch=*/ std::make_shared<fml::SyncSwitch>());
2301
+
2302
+ FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
2303
+ [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc ] init ];
2304
+ flutterPlatformViewsController->RegisterViewFactory (
2305
+ factory, @" MockFlutterPlatformView" ,
2306
+ FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
2307
+ FlutterResult result = ^(id result) {
2308
+ };
2309
+ flutterPlatformViewsController->OnMethodCall (
2310
+ [FlutterMethodCall
2311
+ methodCallWithMethodName: @" create"
2312
+ arguments: @{@" id" : @2 , @" viewType" : @" MockFlutterPlatformView" }],
2313
+ result);
2314
+
2315
+ XCTAssertNotNil (gMockPlatformView );
2316
+
2317
+ UIView* flutterView = [[UIView alloc ] initWithFrame: CGRectMake (0 , 0 , 10 , 10 )];
2318
+ flutterPlatformViewsController->SetFlutterView (flutterView);
2319
+ // Create embedded view params
2320
+ flutter::MutatorsStack stack;
2321
+ // Layer tree always pushes a screen scale factor to the stack
2322
+ SkMatrix screenScaleMatrix =
2323
+ SkMatrix::Scale ([UIScreen mainScreen ].scale , [UIScreen mainScreen ].scale );
2324
+ stack.PushTransform (screenScaleMatrix);
2325
+ // Push a clip path
2326
+ SkPath path;
2327
+ path.addRoundRect (SkRect::MakeXYWH (2 , 2 , 6 , 6 ), 1 , 1 );
2328
+ stack.PushClipPath (path);
2329
+ // Push a clip rect
2330
+ SkRect rect = SkRect::MakeXYWH (4 , 2 , 6 , 6 );
2331
+ stack.PushClipRect (rect);
2332
+
2333
+ auto embeddedViewParams =
2334
+ std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make (10 , 10 ), stack);
2335
+
2336
+ flutterPlatformViewsController->PrerollCompositeEmbeddedView (2 , std::move (embeddedViewParams));
2337
+ flutterPlatformViewsController->CompositeWithParams (
2338
+ 2 , flutterPlatformViewsController->GetCompositionParams (2 ));
2339
+
2340
+ gMockPlatformView .backgroundColor = UIColor.redColor ;
2341
+ XCTAssertTrue ([gMockPlatformView .superview.superview isKindOfClass: ChildClippingView.class ]);
2342
+ ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView .superview .superview ;
2343
+ [flutterView addSubview: childClippingView];
2344
+
2345
+ [flutterView setNeedsLayout ];
2346
+ [flutterView layoutIfNeeded ];
2347
+
2348
+ /*
2349
+ clip 1 clip 2
2350
+ 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9
2351
+ 2 / - - - - \ 2 + - - - - +
2352
+ 3 | | 3 | |
2353
+ 4 | | 4 | |
2354
+ 5 | | 5 | |
2355
+ 6 | | 6 | |
2356
+ 7 \ - - - - / 7 + - - - - +
2357
+
2358
+ Result should be the intersection of 2 clips
2359
+ 2 3 4 5 6 7 8 9
2360
+ 2 + - - \
2361
+ 3 | |
2362
+ 4 | |
2363
+ 5 | |
2364
+ 6 | |
2365
+ 7 + - - /
2366
+ */
2367
+ CGRect clipping = CGRectMake (4 , 2 , 4 , 6 );
2368
+ for (int i = 0 ; i < 10 ; i++) {
2369
+ for (int j = 0 ; j < 10 ; j++) {
2370
+ CGPoint point = CGPointMake (i, j);
2371
+ int alpha = [self alphaOfPoint: CGPointMake (i, j) onView: flutterView];
2372
+ if (i == 7 && (j == 2 || j == 7 )) {
2373
+ // Upper and lower right corners should be partially transparent.
2374
+ XCTAssert (0 < alpha && alpha < 255 );
2375
+ } else if (
2376
+ // left
2377
+ (i == 4 && j >= 2 && j <= 7 ) ||
2378
+ // right
2379
+ (i == 7 && j >= 2 && j <= 7 ) ||
2380
+ // top
2381
+ (j == 2 && i >= 4 && i <= 7 ) ||
2382
+ // bottom
2383
+ (j == 7 && i >= 4 && i <= 7 )) {
2384
+ // Since we are falling back to software rendering for this case
2385
+ // The edge pixels can be anti-aliased, so it may not be fully opaque.
2386
+ XCTAssert (alpha > 127 );
2387
+ } else if ((i == 3 && j >= 1 && j <= 8 ) || (i == 8 && j >= 1 && j <= 8 ) ||
2388
+ (j == 1 && i >= 3 && i <= 8 ) || (j == 8 && i >= 3 && i <= 8 )) {
2389
+ // Since we are falling back to software rendering for this case
2390
+ // The edge pixels can be anti-aliased, so it may not be fully transparent.
2391
+ XCTAssert (alpha < 127 );
2392
+ } else if (CGRectContainsPoint (clipping, point)) {
2393
+ // Other pixels inside clipping should be fully opaque.
2394
+ XCTAssertEqual (alpha, 255 );
2395
+ } else {
2396
+ // Pixels outside clipping should be fully transparent.
2397
+ XCTAssertEqual (alpha, 0 );
2398
+ }
2399
+ }
2400
+ }
2401
+ }
2402
+
2066
2403
- (void )testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
2067
2404
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2068
2405
0 commit comments