diff --git a/Base/res/html/misc/border-radius.html b/Base/res/html/misc/border-radius.html
index bae2b9334d..5502d26089 100644
--- a/Base/res/html/misc/border-radius.html
+++ b/Base/res/html/misc/border-radius.html
@@ -70,6 +70,22 @@
border-left: 20px solid blue;
}
+ .box-1-13 {
+ border-radius: 15px;
+ border-color: black;
+ border: 3px solid black;
+ border-top-width: 0;
+ border-bottom-width: 0;
+ }
+
+ .box-1-14 {
+ border-radius: 15px;
+ border-color: black;
+ border: 3px solid black;
+ border-left-width: 0;
+ border-right-width: 0;
+ }
+
.box-3 {
border: 1px solid black;
border-top-right-radius: 10px;
@@ -418,6 +434,12 @@
Four border with different colors
+ Border radius with top and bottom zero width
+
+
+ Border radius with left and right zero width
+
+
top-left 10px
diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
index 303712664d..e9d204d5df 100644
--- a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
@@ -205,10 +205,22 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
}
};
- auto compute_midpoint = [](int horizontal_radius, int vertical_radius) {
+ auto compute_midpoint = [&](int horizontal_radius, int vertical_radius, int joined_border_width) {
if (horizontal_radius == 0 && vertical_radius == 0) {
return Gfx::FloatPoint(0, 0);
}
+ if (joined_border_width == 0) {
+ switch (edge) {
+ case BorderEdge::Top:
+ case BorderEdge::Bottom:
+ return Gfx::FloatPoint(horizontal_radius, 0);
+ case BorderEdge::Right:
+ case BorderEdge::Left:
+ return Gfx::FloatPoint(0, vertical_radius);
+ default:
+ VERIFY_NOT_REACHED();
+ }
+ }
// FIXME: this middle point rule seems not exacly the same as main browsers
// compute the midpoint based on point whose tangent slope of 1
// https://math.stackexchange.com/questions/3325134/find-the-points-on-the-ellipse-where-the-slope-of-the-tangent-line-is-1
@@ -235,17 +247,14 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
Gfx::FloatPoint joined_corner_endpoint_offset;
Gfx::FloatPoint opposite_joined_border_corner_offset;
- if (borders_data.left.width == 0) {
- joined_corner_endpoint_offset = Gfx::FloatPoint(-radius.horizontal_radius, radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius);
+
+ {
+ auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius, joined_border_width.value());
joined_corner_endpoint_offset = Gfx::FloatPoint(-midpoint.x(), radius.vertical_radius - midpoint.y());
}
- if (borders_data.right.width == 0) {
- opposite_joined_border_corner_offset = Gfx::FloatPoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
+ {
+ auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius, opposite_joined_border_width.value());
opposite_joined_border_corner_offset = Gfx::FloatPoint(midpoint.x(), opposite_radius.vertical_radius - midpoint.y());
}
@@ -256,7 +265,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (joined_corner_has_inner_corner) {
Gfx::FloatPoint midpoint = compute_midpoint(
radius.horizontal_radius - joined_border_width.value(),
- radius.vertical_radius - device_pixel_width.value());
+ radius.vertical_radius - device_pixel_width.value(),
+ joined_border_width.value());
Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint(
-midpoint.x(),
radius.vertical_radius - device_pixel_width.value() - midpoint.y());
@@ -272,7 +282,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (opposite_joined_corner_has_inner_corner) {
Gfx::FloatPoint midpoint = compute_midpoint(
opposite_radius.horizontal_radius - opposite_joined_border_width.value(),
- opposite_radius.vertical_radius - device_pixel_width.value());
+ opposite_radius.vertical_radius - device_pixel_width.value(),
+ opposite_joined_border_width.value());
Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint(
midpoint.x(),
opposite_radius.vertical_radius - device_pixel_width.value() - midpoint.y());
@@ -305,17 +316,14 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
Gfx::FloatPoint joined_corner_endpoint_offset;
Gfx::FloatPoint opposite_joined_border_corner_offset;
- if (borders_data.top.width == 0) {
- joined_corner_endpoint_offset = Gfx::FloatPoint(-radius.horizontal_radius, -radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius);
+
+ {
+ auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius, joined_border_width.value());
joined_corner_endpoint_offset = Gfx::FloatPoint(midpoint.x() - radius.horizontal_radius, -midpoint.y());
}
- if (borders_data.bottom.width == 0) {
- opposite_joined_border_corner_offset = Gfx::FloatPoint(-opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
+ {
+ auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius, opposite_joined_border_width.value());
opposite_joined_border_corner_offset = Gfx::FloatPoint(midpoint.x() - opposite_radius.horizontal_radius, midpoint.y());
}
@@ -326,7 +334,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
radius.horizontal_radius - device_pixel_width.value(),
- radius.vertical_radius - joined_border_width.value());
+ radius.vertical_radius - joined_border_width.value(),
+ joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(
-(radius.horizontal_radius - midpoint.x() - device_pixel_width.value()),
-midpoint.y());
@@ -340,7 +349,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (opposite_joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
opposite_radius.horizontal_radius - device_pixel_width.value(),
- opposite_radius.vertical_radius - opposite_joined_border_width.value());
+ opposite_radius.vertical_radius - opposite_joined_border_width.value(),
+ opposite_joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(
-(opposite_radius.horizontal_radius - midpoint.x() - device_pixel_width.value()),
midpoint.y());
@@ -371,17 +381,14 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
Gfx::FloatPoint joined_corner_endpoint_offset;
Gfx::FloatPoint opposite_joined_border_corner_offset;
- if (borders_data.right.width == 0) {
- joined_corner_endpoint_offset = Gfx::FloatPoint(radius.horizontal_radius, -radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius);
+
+ {
+ auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius, joined_border_width.value());
joined_corner_endpoint_offset = Gfx::FloatPoint(midpoint.x(), midpoint.y() - radius.vertical_radius);
}
- if (borders_data.left.width == 0) {
- opposite_joined_border_corner_offset = Gfx::FloatPoint(-opposite_radius.horizontal_radius, -opposite_radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
+ {
+ auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius, opposite_joined_border_width.value());
opposite_joined_border_corner_offset = Gfx::FloatPoint(-midpoint.x(), midpoint.y() - opposite_radius.vertical_radius);
}
@@ -392,7 +399,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
radius.horizontal_radius - joined_border_width.value(),
- radius.vertical_radius - device_pixel_width.value());
+ radius.vertical_radius - device_pixel_width.value(),
+ joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(midpoint.x(), -(radius.vertical_radius - midpoint.y() - device_pixel_width.value()));
points.append(Gfx::FloatPoint(rect.top_right().to_type()) + inner_corner);
points.append(Gfx::FloatPoint(rect.top_right().to_type()));
@@ -404,7 +412,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (opposite_joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
opposite_radius.horizontal_radius - opposite_joined_border_width.value(),
- opposite_radius.vertical_radius - device_pixel_width.value());
+ opposite_radius.vertical_radius - device_pixel_width.value(),
+ opposite_joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(
-midpoint.x(),
-(opposite_radius.vertical_radius - midpoint.y() - device_pixel_width.value()));
@@ -434,17 +443,14 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
Gfx::FloatPoint joined_corner_endpoint_offset;
Gfx::FloatPoint opposite_joined_border_corner_offset;
- if (borders_data.bottom.width == 0) {
- joined_corner_endpoint_offset = Gfx::FloatPoint(radius.horizontal_radius, radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius);
+
+ {
+ auto midpoint = compute_midpoint(radius.horizontal_radius, radius.vertical_radius, joined_border_width.value());
joined_corner_endpoint_offset = Gfx::FloatPoint(radius.horizontal_radius - midpoint.x(), midpoint.y());
}
- if (borders_data.top.width == 0) {
- opposite_joined_border_corner_offset = Gfx::FloatPoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
- } else {
- auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius);
+ {
+ auto midpoint = compute_midpoint(opposite_radius.horizontal_radius, opposite_radius.vertical_radius, opposite_joined_border_width.value());
opposite_joined_border_corner_offset = Gfx::FloatPoint(opposite_radius.horizontal_radius - midpoint.x(), -midpoint.y());
}
@@ -455,7 +461,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
radius.horizontal_radius - device_pixel_width.value(),
- radius.vertical_radius - joined_border_width.value());
+ radius.vertical_radius - joined_border_width.value(),
+ joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(radius.horizontal_radius - device_pixel_width.value() - midpoint.x(), midpoint.y());
points.append(Gfx::FloatPoint(rect.bottom_right().to_type()) + inner_corner);
points.append(Gfx::FloatPoint(rect.bottom_right().to_type()));
@@ -467,7 +474,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
if (opposite_joined_corner_has_inner_corner) {
auto midpoint = compute_midpoint(
opposite_radius.horizontal_radius - device_pixel_width.value(),
- opposite_radius.vertical_radius - opposite_joined_border_width.value());
+ opposite_radius.vertical_radius - opposite_joined_border_width.value(),
+ opposite_joined_border_width.value());
Gfx::FloatPoint inner_corner = Gfx::FloatPoint(
opposite_radius.horizontal_radius - device_pixel_width.value() - midpoint.x(),
-midpoint.y());