Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a2cc737

Browse files
committed
Round SkRects in ClipRectContainsPlatformViewBoundingRect
1 parent a718337 commit a2cc737

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ static bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
4545
const SkRect& platformview_boundingrect,
4646
const SkMatrix& transform_matrix) {
4747
SkRect transformed_rect = transform_matrix.mapRect(clip_rect);
48-
return transformed_rect.contains(platformview_boundingrect);
48+
49+
// Tolerate floating point errors when comparing flow clipping view bounds
50+
// and quartz platform view bounds. Round to integers.
51+
SkIRect transformed_rect_rounded = transformed_rect.round();
52+
SkIRect platformview_boundingrect_rounded = platformview_boundingrect.round();
53+
54+
return transformed_rect_rounded.contains(platformview_boundingrect_rounded);
4955
}
5056

5157
// Determines if the `clipRRect` from a clipRRect mutator contains the

shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,17 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
15071507
SkMatrix finalMatrix;
15081508
finalMatrix.setConcat(screenScaleMatrix, rotateMatrix);
15091509

1510+
// The childclippingview's frame is set based on flow, but the platform view's frame is set based
1511+
// on quartz. Although they should be the same, we should tolerate small floating point
1512+
// errors.
1513+
// Push clip rects the same size as the platform view but faking a floating point error.
1514+
SkRect clipRectSmaller =
1515+
SkRect::MakeXYWH(0, 0, 300 - kFloatCompareEpsilon, 300 - kFloatCompareEpsilon);
1516+
stack.PushClipRect(clipRectSmaller);
1517+
SkRect clipRectLarger =
1518+
SkRect::MakeXYWH(0, 0, 300 + kFloatCompareEpsilon, 300 + kFloatCompareEpsilon);
1519+
stack.PushClipRect(clipRectLarger);
1520+
15101521
auto embeddedViewParams =
15111522
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
15121523

@@ -1516,9 +1527,7 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
15161527
toView:mockFlutterView];
15171528
XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
15181529
ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
1519-
// The childclippingview's frame is set based on flow, but the platform view's frame is set based
1520-
// on quartz. Although they should be the same, but we should tolerate small floating point
1521-
// errors.
1530+
// See above comment about tolerating small floating point errors.
15221531
XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
15231532
kFloatCompareEpsilon);
15241533
XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
@@ -1529,6 +1538,8 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
15291538
XCTAssertLessThan(
15301539
fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
15311540
kFloatCompareEpsilon);
1541+
1542+
XCTAssertNil(childClippingView.maskView);
15321543
}
15331544

15341545
- (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView {

0 commit comments

Comments
 (0)