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 {
Radius get _bottomEnd => Radius.zero;
/// 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) {
// 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(
rect,
topLeft: topLeft,
topRight: topRight,
bottomLeft: bottomLeft,
bottomRight: bottomRight,
topLeft: topLeft.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: topRight.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: bottomLeft.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: bottomRight.clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
}
......
......@@ -232,7 +232,18 @@ abstract class BoxBorder extends ShapeBorder {
canvas.drawRRect(borderRadius.toRRect(rect), paint);
} else {
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);
canvas.drawDRRect(outer, inner, paint);
}
......
......@@ -132,7 +132,18 @@ class RoundedRectangleBorder extends OutlinedBorder {
final Paint paint = Paint()
..color = side.color;
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);
canvas.drawDRRect(outer, inner, paint);
}
......
......@@ -271,7 +271,18 @@ class TableBorder {
paintBorder(canvas, rect, top: top, right: right, bottom: bottom, left: left);
} else {
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;
canvas.drawDRRect(outer, inner, paint);
}
......
......@@ -129,6 +129,17 @@ class _MulticastCanvas implements Canvas {
@override
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);
_screenshot.drawDRRect(outer, inner, paint);
}
......
......@@ -553,7 +553,7 @@ void main() {
..drrect(
color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000),
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() {
..drrect(
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)),
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() {
..drrect(
color: borderColor,
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() {
..drrect(
color: borderColor,
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 {
350.0, 200.0, 450.0, 300.0,
topRight: const Radius.circular(10.0),
),
inner: RRect.fromLTRBAndCorners(
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),
),
inner: RRect.fromLTRBAndCorners(360.0, 210.0, 440.0, 290.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