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

Commit 8d3c0fb

Browse files
authored
[web] PathRef: do not use == with doubles in assertions (#31382)
1 parent 2d16729 commit 8d3c0fb

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

lib/web_ui/lib/src/engine/html/path/path_ref.dart

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,12 @@ class PathRef {
263263
// The location delta of control point specifies corner radius.
264264
if (vector1_0x != 0.0) {
265265
// For CW : Top right or bottom left corners.
266-
assert(vector2_1x == 0.0 && vector1_0y == 0.0);
267266
dx = vector1_0x.abs();
268267
dy = vector2_1y.abs();
269268
} else if (vector1_0y != 0.0) {
270-
assert(vector2_1x == 0.0 || vector2_1y == 0.0);
271269
dx = vector2_1x.abs();
272270
dy = vector1_0y.abs();
273271
} else {
274-
assert(vector2_1y == 0.0);
275272
dx = vector1_0x.abs();
276273
dy = vector1_0y.abs();
277274
}
@@ -288,9 +285,19 @@ class PathRef {
288285
radii.add(ui.Radius.elliptical(dx, dy));
289286
++cornerIndex;
290287
} else {
291-
assert((verb == SPath.kLineVerb &&
292-
((pts[2] - pts[0]) == 0 || (pts[3] - pts[1]) == 0)) ||
293-
verb == SPath.kCloseVerb);
288+
if (assertionsEnabled) {
289+
if (verb == SPath.kLineVerb) {
290+
final bool isVerticalOrHorizontal =
291+
SPath.nearlyEqual(pts[2], pts[0]) ||
292+
SPath.nearlyEqual(pts[3], pts[1]);
293+
assert(
294+
isVerticalOrHorizontal,
295+
'An RRect path must only contain vertical and horizontal lines.'
296+
);
297+
} else {
298+
assert(verb == SPath.kCloseVerb);
299+
}
300+
}
294301
}
295302
}
296303
return ui.RRect.fromRectAndCorners(bounds,
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:test/bootstrap/browser.dart';
6+
import 'package:test/test.dart';
7+
import 'package:ui/src/engine.dart';
8+
import 'package:ui/ui.dart';
9+
10+
// TODO(yjbanov): https://github.com/flutter/flutter/issues/76885
11+
const bool issue76885Exists = true;
12+
13+
void main() {
14+
internalBootstrapBrowserTest(() => testMain);
15+
}
16+
17+
void testMain() {
18+
test('PathRef.getRRect with radius', () {
19+
final SurfacePath path = SurfacePath();
20+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.circular(2));
21+
path.addRRect(rrect);
22+
expect(path.toRoundedRect(), rrect);
23+
});
24+
25+
test('PathRef.getRRect with radius larger than rect', () {
26+
final SurfacePath path = SurfacePath();
27+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.circular(20));
28+
path.addRRect(rrect);
29+
expect(
30+
path.toRoundedRect(),
31+
// Path.addRRect will correct the radius to fit the dimensions, so when
32+
// extracting the rrect out of the path we don't get the original.
33+
RRect.fromLTRBR(0, 0, 10, 10, const Radius.circular(5)),
34+
);
35+
});
36+
37+
test('PathRef.getRRect with zero radius', () {
38+
final SurfacePath path = SurfacePath();
39+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.circular(0));
40+
path.addRRect(rrect);
41+
expect(path.toRoundedRect(), isNull);
42+
expect(path.toRect(), rrect.outerRect);
43+
});
44+
45+
test('PathRef.getRRect elliptical', () {
46+
final SurfacePath path = SurfacePath();
47+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.elliptical(2, 4));
48+
path.addRRect(rrect);
49+
expect(path.toRoundedRect(), rrect);
50+
});
51+
52+
test('PathRef.getRRect elliptical zero x', () {
53+
final SurfacePath path = SurfacePath();
54+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.elliptical(0, 3));
55+
path.addRRect(rrect);
56+
expect(path.toRoundedRect(), isNull);
57+
expect(path.toRect(), rrect.outerRect);
58+
});
59+
60+
test('PathRef.getRRect elliptical zero y', () {
61+
final SurfacePath path = SurfacePath();
62+
final RRect rrect = RRect.fromLTRBR(0, 0, 10, 10, const Radius.elliptical(3, 0));
63+
path.addRRect(rrect);
64+
expect(path.toRoundedRect(), isNull);
65+
expect(path.toRect(), rrect.outerRect);
66+
});
67+
68+
// This test demonstrates the issue with attempting to reconstruct an RRect
69+
// with imprecision introduced by comparing double values. We should fix this
70+
// by removing the need to reconstruct rrects:
71+
// https://github.com/flutter/flutter/issues/76885
72+
test('PathRef.getRRect with nearly zero corner', () {
73+
final SurfacePath path = SurfacePath();
74+
final RRect original = RRect.fromLTRBR(0, 0, 10, 10, const Radius.elliptical(0.00000001, 5));
75+
path.addRRect(original);
76+
expect(path.toRoundedRect(), original);
77+
}, skip: issue76885Exists);
78+
}

0 commit comments

Comments
 (0)