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());