Unverified Commit 5f9ad01e authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Prepare the framework for having RRect assert on negative radii (#111515)

parent fb90be4a
...@@ -392,13 +392,19 @@ class BorderRadius extends BorderRadiusGeometry { ...@@ -392,13 +392,19 @@ class BorderRadius extends BorderRadiusGeometry {
Radius get _bottomEnd => Radius.zero; Radius get _bottomEnd => Radius.zero;
/// Creates an [RRect] from the current border radius and a [Rect]. /// Creates an [RRect] from the current border radius and a [Rect].
///
/// If any of the radii have negative values in x or y, those values will be
/// clamped to zero in order to produce a valid [RRect].
RRect toRRect(Rect rect) { RRect toRRect(Rect rect) {
// Because the current radii could be negative, we must clamp them before
// converting them to an RRect to be rendered, since negative radii on
// RRects don't make sense.
return RRect.fromRectAndCorners( return RRect.fromRectAndCorners(
rect, rect,
topLeft: topLeft, topLeft: topLeft.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: topRight, topRight: topRight.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: bottomLeft, bottomLeft: bottomLeft.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: bottomRight, bottomRight: bottomRight.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
); );
} }
......
...@@ -232,7 +232,18 @@ abstract class BoxBorder extends ShapeBorder { ...@@ -232,7 +232,18 @@ abstract class BoxBorder extends ShapeBorder {
canvas.drawRRect(borderRadius.toRRect(rect), paint); canvas.drawRRect(borderRadius.toRRect(rect), paint);
} else { } else {
final RRect borderRect = borderRadius.toRRect(rect); final RRect borderRect = borderRadius.toRRect(rect);
final RRect inner = borderRect.deflate(side.strokeInset); RRect inner = borderRect.deflate(side.strokeInset);
// Clamp the inner border's radii to zero, until deflate does this
// automatically, so that we can start asserting non-negative values
// in the engine without breaking the framework.
// TODO(gspencergoog): Remove this once https://github.com/flutter/engine/pull/36062 rolls into the framework.
inner = RRect.fromLTRBAndCorners(
inner.left, inner.top, inner.right, inner.bottom,
topLeft: inner.tlRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: inner.trRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: inner.blRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: inner.brRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
final RRect outer = borderRect.inflate(side.strokeOutset); final RRect outer = borderRect.inflate(side.strokeOutset);
canvas.drawDRRect(outer, inner, paint); canvas.drawDRRect(outer, inner, paint);
} }
......
...@@ -132,7 +132,18 @@ class RoundedRectangleBorder extends OutlinedBorder { ...@@ -132,7 +132,18 @@ class RoundedRectangleBorder extends OutlinedBorder {
final Paint paint = Paint() final Paint paint = Paint()
..color = side.color; ..color = side.color;
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect); final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
final RRect inner = borderRect.deflate(side.strokeInset); RRect inner = borderRect.deflate(side.strokeInset);
// Clamp the inner border's radii to zero, until deflate does this
// automatically, so that we can start asserting non-negative values
// in the engine without breaking the framework.
// TODO(gspencergoog): Remove this once https://github.com/flutter/engine/pull/36062 rolls into the framework.
inner = RRect.fromLTRBAndCorners(
inner.left, inner.top, inner.right, inner.bottom,
topLeft: inner.tlRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: inner.trRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: inner.blRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: inner.brRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
final RRect outer = borderRect.inflate(side.strokeOutset); final RRect outer = borderRect.inflate(side.strokeOutset);
canvas.drawDRRect(outer, inner, paint); canvas.drawDRRect(outer, inner, paint);
} }
......
...@@ -271,7 +271,18 @@ class TableBorder { ...@@ -271,7 +271,18 @@ class TableBorder {
paintBorder(canvas, rect, top: top, right: right, bottom: bottom, left: left); paintBorder(canvas, rect, top: top, right: right, bottom: bottom, left: left);
} else { } else {
final RRect outer = borderRadius.toRRect(rect); final RRect outer = borderRadius.toRRect(rect);
final RRect inner = outer.deflate(top.width); RRect inner = outer.deflate(top.width);
// Clamp the inner border's radii to zero, until deflate does this
// automatically, so that we can start asserting non-negative values
// in the engine without breaking the framework.
// TODO(gspencergoog): Remove this once https://github.com/flutter/engine/pull/36062 rolls into the framework.
inner = RRect.fromLTRBAndCorners(
inner.left, inner.top, inner.right, inner.bottom,
topLeft: inner.tlRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: inner.trRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: inner.blRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: inner.brRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
final Paint paint = Paint()..color = top.color; final Paint paint = Paint()..color = top.color;
canvas.drawDRRect(outer, inner, paint); canvas.drawDRRect(outer, inner, paint);
} }
......
...@@ -129,6 +129,17 @@ class _MulticastCanvas implements Canvas { ...@@ -129,6 +129,17 @@ class _MulticastCanvas implements Canvas {
@override @override
void drawDRRect(RRect outer, RRect inner, Paint paint) { void drawDRRect(RRect outer, RRect inner, Paint paint) {
// Clamp the inner border's radii to zero, until deflate does this
// automatically, so that we can start asserting non-negative values
// in the engine without breaking the framework.
// TODO(gspencergoog): Remove this once https://github.com/flutter/engine/pull/36062 rolls into the framework.
inner = RRect.fromLTRBAndCorners(
inner.left, inner.top, inner.right, inner.bottom,
topLeft: inner.tlRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: inner.trRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: inner.blRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: inner.brRadius.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
_main.drawDRRect(outer, inner, paint); _main.drawDRRect(outer, inner, paint);
_screenshot.drawDRRect(outer, inner, paint); _screenshot.drawDRRect(outer, inner, paint);
} }
......
...@@ -553,7 +553,7 @@ void main() { ...@@ -553,7 +553,7 @@ void main() {
..drrect( ..drrect(
color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000), color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)), outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, const Radius.circular(-1.0)), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
), ),
); );
...@@ -568,7 +568,7 @@ void main() { ...@@ -568,7 +568,7 @@ void main() {
..drrect( ..drrect(
color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000), color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)), outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, const Radius.circular(-1.0)), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
), ),
); );
}); });
...@@ -1420,7 +1420,7 @@ void main() { ...@@ -1420,7 +1420,7 @@ void main() {
..drrect( ..drrect(
color: borderColor, color: borderColor,
outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)), outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
inner: RRect.fromLTRBR(19, 19, 29, 29, const Radius.circular(-3)), inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
), ),
); );
} }
...@@ -1479,7 +1479,7 @@ void main() { ...@@ -1479,7 +1479,7 @@ void main() {
..drrect( ..drrect(
color: borderColor, color: borderColor,
outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)), outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
inner: RRect.fromLTRBR(19, 19, 29, 29, const Radius.circular(-3)), inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
), ),
); );
} }
......
...@@ -249,12 +249,7 @@ Future<void> main() async { ...@@ -249,12 +249,7 @@ Future<void> main() async {
350.0, 200.0, 450.0, 300.0, 350.0, 200.0, 450.0, 300.0,
topRight: const Radius.circular(10.0), topRight: const Radius.circular(10.0),
), ),
inner: RRect.fromLTRBAndCorners( inner: RRect.fromLTRBAndCorners(360.0, 210.0, 440.0, 290.0),
360.0, 210.0, 440.0, 290.0,
topLeft: const Radius.circular(-10.0),
bottomRight: const Radius.circular(-10.0),
bottomLeft: const Radius.circular(-10.0),
),
) )
..circle(x: 400.0, y: 350.0, radius: 45.0), ..circle(x: 400.0, y: 350.0, radius: 45.0),
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment