mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-26 12:41:59 +03:00
LibGfx: Fix winding order of segments on elliptical arcs
for_each_line_segment_on_elliptical_arc() flips the start/end points for negative theta deltas. When doing this we have to make sure the line segments emitted swap the start/end points back, so that the (correct) winding order can be calculated from them. This makes nonzero fills not totally broken for a lot of SVGs.
This commit is contained in:
parent
48fa8f97d3
commit
6685656d2d
Notes:
sideshowbarker
2024-07-16 22:51:10 +09:00
Author: https://github.com/MacDue Commit: https://github.com/SerenityOS/serenity/commit/6685656d2d Pull-request: https://github.com/SerenityOS/serenity/pull/19191
@ -2323,10 +2323,12 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
|
||||
auto start = p1;
|
||||
auto end = p2;
|
||||
|
||||
bool start_swapped = false;
|
||||
if (theta_delta < 0) {
|
||||
swap(start, end);
|
||||
theta_1 = theta_1 + theta_delta;
|
||||
theta_delta = fabsf(theta_delta);
|
||||
start_swapped = true;
|
||||
}
|
||||
|
||||
auto relative_start = start - center;
|
||||
@ -2351,6 +2353,13 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
|
||||
p.set_y(original_x * sin_x_axis + original_y * cos_x_axis);
|
||||
};
|
||||
|
||||
auto emit_point = [&](auto p0, auto p1) {
|
||||
// NOTE: If we swap the start/end we must swap the emitted points, so correct winding orders can be calculated.
|
||||
if (start_swapped)
|
||||
swap(p0, p1);
|
||||
callback(p0, p1);
|
||||
};
|
||||
|
||||
for (float theta = theta_1; theta <= theta_1 + theta_delta; theta += theta_step) {
|
||||
float s, c;
|
||||
AK::sincos(theta, s, c);
|
||||
@ -2358,12 +2367,12 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
|
||||
next_point.set_y(b * s);
|
||||
rotate_point(next_point);
|
||||
|
||||
callback(current_point + center, next_point + center);
|
||||
emit_point(current_point + center, next_point + center);
|
||||
|
||||
current_point = next_point;
|
||||
}
|
||||
|
||||
callback(current_point + center, end);
|
||||
emit_point(current_point + center, end);
|
||||
}
|
||||
|
||||
// static
|
||||
|
Loading…
Reference in New Issue
Block a user