mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibWeb: Fix border painting with border-radius and zero-width sides
When joined border width is zero width, then the midpoint of the joined corner is no longer need to be computed anymore. Just set the mid point to be the endpoint of the corner.
This commit is contained in:
parent
8f7b269bf1
commit
94491ead67
Notes:
sideshowbarker
2024-07-17 02:39:10 +09:00
Author: https://github.com/zhiyuang Commit: https://github.com/SerenityOS/serenity/commit/94491ead67 Pull-request: https://github.com/SerenityOS/serenity/pull/20177 Issue: https://github.com/SerenityOS/serenity/issues/20164 Reviewed-by: https://github.com/MacDue
2 changed files with 71 additions and 41 deletions
|
@ -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 @@
|
|||
<em>Four border with different colors</em>
|
||||
<div class="box box-1-12"></div>
|
||||
<br>
|
||||
<em>Border radius with top and bottom zero width</em>
|
||||
<div class="box box-1-13"></div>
|
||||
<br>
|
||||
<em>Border radius with left and right zero width</em>
|
||||
<div class="box box-1-14"></div>
|
||||
<br>
|
||||
<em>top-left 10px</em>
|
||||
<div class="box box-2"></div>
|
||||
<br>
|
||||
|
|
|
@ -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<int>()) + inner_corner);
|
||||
points.append(Gfx::FloatPoint(rect.top_right().to_type<int>()));
|
||||
|
@ -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<int>()) + inner_corner);
|
||||
points.append(Gfx::FloatPoint(rect.bottom_right().to_type<int>()));
|
||||
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue