Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions lib/web_ui/lib/src/engine/dom_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {

@override
void drawRect(ui.Rect rect, SurfacePaintData paint) {
_drawRect(rect, paint, 'draw-rect');
}

html.Element _drawRect(ui.Rect rect, SurfacePaintData paint, String tagName) {
assert(paint.shader == null);
final html.Element rectangle = html.Element.tag('draw-rect');
final html.Element rectangle = html.Element.tag(tagName);
assert(() {
rectangle.setAttribute('flt-rect', '$rect');
rectangle.setAttribute('flt-paint', '$paint');
Expand Down Expand Up @@ -104,8 +108,8 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
..transformOrigin = '0 0 0'
..transform = effectiveTransform;

final String cssColor =
paint.color == null ? '#000000' : colorToCssString(paint.color);
final String cssColor = paint.color == null ? '#000000'
: colorToCssString(paint.color);

if (paint.maskFilter != null) {
style.filter = 'blur(${paint.maskFilter.webOnlySigma}px)';
Expand All @@ -124,11 +128,13 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
}

currentElement.append(rectangle);
return rectangle;
}

@override
void drawRRect(ui.RRect rrect, SurfacePaintData paint) {
throw UnimplementedError();
html.Element element = _drawRect(rrect.outerRect, paint, 'draw-rrect');
element.style.borderRadius = '${rrect.blRadiusX.toStringAsFixed(3)}px';
}

@override
Expand Down
4 changes: 3 additions & 1 deletion lib/web_ui/lib/src/engine/surface/recording_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ class RecordingCanvas {
}

void drawRRect(ui.RRect rrect, SurfacePaint paint) {
_hasArbitraryPaint = true;
if (!rrect.webOnlyUniformRadii) {
_hasArbitraryPaint = true;
}
_didDraw = true;
final double strokeWidth =
paint.strokeWidth == null ? 0 : paint.strokeWidth;
Expand Down
26 changes: 25 additions & 1 deletion lib/web_ui/lib/src/ui/geometry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ class RRect {
blRadiusY: radiusY,
brRadiusX: radiusX,
brRadiusY: radiusY,
uniformRadii: radiusX == radiusY,
);

/// Construct a rounded rectangle from its left, top, right, and bottom edges,
Expand All @@ -1103,6 +1104,7 @@ class RRect {
blRadiusY: radius.y,
brRadiusX: radius.x,
brRadiusY: radius.y,
uniformRadii: radius.x == radius.y,
);

/// Construct a rounded rectangle from its bounding box and the same radii
Expand All @@ -1121,6 +1123,7 @@ class RRect {
blRadiusY: radiusY,
brRadiusX: radiusX,
brRadiusY: radiusY,
uniformRadii: radiusX == radiusY,
);

/// Construct a rounded rectangle from its bounding box and a radius that is
Expand All @@ -1139,6 +1142,7 @@ class RRect {
blRadiusY: radius.y,
brRadiusX: radius.x,
brRadiusY: radius.y,
uniformRadii: radius.x == radius.y,
);

/// Construct a rounded rectangle from its left, top, right, and bottom edges,
Expand Down Expand Up @@ -1167,6 +1171,13 @@ class RRect {
blRadiusY: bottomLeft.y,
brRadiusX: bottomRight.x,
brRadiusY: bottomRight.y,
uniformRadii: topLeft.x == topLeft.y &&
topLeft.x == topRight.x &&
topLeft.x == topRight.y &&
topLeft.x == bottomLeft.x &&
topLeft.x == bottomLeft.y &&
topLeft.x == bottomRight.x &&
topLeft.x == bottomRight.y,
);

/// Construct a rounded rectangle from its bounding box and and topLeft,
Expand All @@ -1191,6 +1202,13 @@ class RRect {
blRadiusY: bottomLeft.y,
brRadiusX: bottomRight.x,
brRadiusY: bottomRight.y,
uniformRadii: topLeft.x == topLeft.y &&
topLeft.x == topRight.x &&
topLeft.x == topRight.y &&
topLeft.x == bottomLeft.x &&
topLeft.x == bottomLeft.y &&
topLeft.x == bottomRight.x &&
topLeft.x == bottomRight.y,
);

const RRect._raw({
Expand All @@ -1206,6 +1224,7 @@ class RRect {
this.brRadiusY = 0.0,
this.blRadiusX = 0.0,
this.blRadiusY = 0.0,
bool uniformRadii = false,
}) : assert(left != null),
assert(top != null),
assert(right != null),
Expand All @@ -1217,7 +1236,8 @@ class RRect {
assert(brRadiusX != null),
assert(brRadiusY != null),
assert(blRadiusX != null),
assert(blRadiusY != null);
assert(blRadiusY != null),
this.webOnlyUniformRadii = uniformRadii;

/// The offset of the left edge of this rectangle from the x axis.
final double left;
Expand Down Expand Up @@ -1264,6 +1284,10 @@ class RRect {
/// The bottom-left vertical radius.
final double blRadiusY;

/// If radii is equal for all corners.
// webOnly
final bool webOnlyUniformRadii;

/// The bottom-left [Radius].
Radius get blRadius => Radius.elliptical(blRadiusX, blRadiusY);

Expand Down
84 changes: 84 additions & 0 deletions lib/web_ui/test/rrect_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,88 @@ void main() {
expect(rrect.contains(const Offset(1.7, 1.97)), isTrue);
expect(rrect.contains(const Offset(1.0, 1.99)), isTrue);
});

test('RRect.webOnlyUniformRadii returns true when all corner radii are equal',
() {
final RRect rect1 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect1.webOnlyUniformRadii, isTrue);

final RRect rect2 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(1000, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect2.webOnlyUniformRadii, isFalse);

final RRect rect3 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 1000),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect3.webOnlyUniformRadii, isFalse);

final RRect rect4 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(1000, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect4.webOnlyUniformRadii, isFalse);

final RRect rect5 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 1000),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect5.webOnlyUniformRadii, isFalse);

final RRect rect6 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(1000, 5),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect6.webOnlyUniformRadii, isFalse);

final RRect rect7 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 1000),
bottomRight: const Radius.elliptical(5, 5),
);
expect(rect7.webOnlyUniformRadii, isFalse);

final RRect rect8 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(1000, 5),
);
expect(rect8.webOnlyUniformRadii, isFalse);

final RRect rect9 = RRect.fromRectAndCorners(
const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0),
topLeft: const Radius.elliptical(5, 5),
topRight: const Radius.elliptical(5, 5),
bottomLeft: const Radius.elliptical(5, 5),
bottomRight: const Radius.elliptical(5, 1000),
);
expect(rect9.webOnlyUniformRadii, isFalse);
});
}