@@ -32,6 +32,16 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
32
32
}
33
33
@end
34
34
35
+ static bool ClipBoundsContainsPlatformViewBoundingRect (const SkRect& clipBounds,
36
+ const SkRect& platformViewBoundingRect,
37
+ const SkMatrix& transformMatrix,
38
+ CGFloat screenScale) {
39
+ SkRect transformedClipBounds = transformMatrix.mapRect (clipBounds);
40
+ SkMatrix reverseScreenScale = SkMatrix::Scale (1 / screenScale, 1 / screenScale);
41
+ SkRect scaledBoundingRect = reverseScreenScale.mapRect (platformViewBoundingRect);
42
+ return transformedClipBounds.contains (scaledBoundingRect);
43
+ }
44
+
35
45
namespace flutter {
36
46
// Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied.
37
47
BOOL canApplyBlurBackdrop = YES ;
@@ -404,7 +414,8 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
404
414
}
405
415
406
416
void FlutterPlatformViewsController::ApplyMutators (const MutatorsStack& mutators_stack,
407
- UIView* embedded_view) {
417
+ UIView* embedded_view,
418
+ const SkRect& bounding_rect) {
408
419
if (flutter_view_ == nullptr ) {
409
420
return ;
410
421
}
@@ -418,7 +429,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
418
429
// 500 points in UIKit. And until this point, we did all the calculation based on the flow
419
430
// resolution. So we need to scale down to match UIKit's logical resolution.
420
431
CGFloat screenScale = [UIScreen mainScreen ].scale ;
421
- CATransform3D finalTransform = CATransform3DMakeScale (1 / screenScale, 1 / screenScale, 1 );
432
+ SkMatrix transformMatrix = SkMatrix::Scale (1 / screenScale, 1 / screenScale);
422
433
423
434
UIView* flutter_view = flutter_view_.get ();
424
435
FlutterClippingMaskView* maskView = [[[FlutterClippingMaskView alloc ]
@@ -429,22 +440,41 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
429
440
NSMutableArray * blurFilters = [[[NSMutableArray alloc ] init ] autorelease ];
430
441
431
442
auto iter = mutators_stack.Begin ();
443
+ BOOL needMask = NO ;
432
444
while (iter != mutators_stack.End ()) {
433
445
switch ((*iter)->GetType ()) {
434
446
case kTransform : {
435
- CATransform3D transform = GetCATransform3DFromSkMatrix ((*iter)->GetMatrix ());
436
- finalTransform = CATransform3DConcat (transform, finalTransform);
447
+ transformMatrix = SkMatrix::Concat ((*iter)->GetMatrix (), transformMatrix);
437
448
break ;
438
449
}
439
- case kClipRect :
440
- [maskView clipRect: (*iter)->GetRect () matrix: finalTransform];
450
+ case kClipRect : {
451
+ if (ClipBoundsContainsPlatformViewBoundingRect ((*iter)->GetRect (), bounding_rect,
452
+ transformMatrix, screenScale)) {
453
+ break ;
454
+ }
455
+ [maskView clipRect: (*iter)->GetRect () matrix: GetCATransform3DFromSkMatrix (transformMatrix)];
456
+ needMask = YES ;
441
457
break ;
442
- case kClipRRect :
443
- [maskView clipRRect: (*iter)->GetRRect () matrix: finalTransform];
458
+ }
459
+ case kClipRRect : {
460
+ if (ClipBoundsContainsPlatformViewBoundingRect (
461
+ (*iter)->GetRRect ().getBounds (), bounding_rect, transformMatrix, screenScale)) {
462
+ break ;
463
+ }
464
+ [maskView clipRRect: (*iter)->GetRRect ()
465
+ matrix: GetCATransform3DFromSkMatrix (transformMatrix)];
466
+ needMask = YES ;
444
467
break ;
445
- case kClipPath :
446
- [maskView clipPath: (*iter)->GetPath () matrix: finalTransform];
468
+ }
469
+ case kClipPath : {
470
+ if (ClipBoundsContainsPlatformViewBoundingRect (
471
+ (*iter)->GetPath ().getBounds (), bounding_rect, transformMatrix, screenScale)) {
472
+ break ;
473
+ }
474
+ [maskView clipPath: (*iter)->GetPath () matrix: GetCATransform3DFromSkMatrix (transformMatrix)];
475
+ needMask = YES ;
447
476
break ;
477
+ }
448
478
case kOpacity :
449
479
embedded_view.alpha = (*iter)->GetAlphaFloat () * embedded_view.alpha ;
450
480
break ;
@@ -498,8 +528,13 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
498
528
// the mask view, whose origin is always (0,0) to the flutter_view.
499
529
CATransform3D reverseTranslate =
500
530
CATransform3DMakeTranslation (-clipView.frame .origin .x , -clipView.frame .origin .y , 0 );
501
- embedded_view.layer .transform = CATransform3DConcat (finalTransform, reverseTranslate);
502
- clipView.maskView = maskView;
531
+ embedded_view.layer .transform =
532
+ CATransform3DConcat (GetCATransform3DFromSkMatrix (transformMatrix), reverseTranslate);
533
+ if (needMask) {
534
+ clipView.maskView = maskView;
535
+ } else {
536
+ clipView.maskView = nil ;
537
+ }
503
538
}
504
539
505
540
void FlutterPlatformViewsController::CompositeWithParams (int view_id,
@@ -538,7 +573,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
538
573
CGFloat screenScale = [UIScreen mainScreen ].scale ;
539
574
clippingView.frame = CGRectMake (rect.x () / screenScale, rect.y () / screenScale,
540
575
rect.width () / screenScale, rect.height () / screenScale);
541
- ApplyMutators (mutatorStack, touchInterceptor);
576
+ ApplyMutators (mutatorStack, touchInterceptor, rect );
542
577
}
543
578
544
579
EmbedderPaintContext FlutterPlatformViewsController::CompositeEmbeddedView (int view_id) {
0 commit comments