mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:27:45 +00: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
1 changed files with 11 additions and 2 deletions
|
@ -2323,10 +2323,12 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
|
||||||
auto start = p1;
|
auto start = p1;
|
||||||
auto end = p2;
|
auto end = p2;
|
||||||
|
|
||||||
|
bool start_swapped = false;
|
||||||
if (theta_delta < 0) {
|
if (theta_delta < 0) {
|
||||||
swap(start, end);
|
swap(start, end);
|
||||||
theta_1 = theta_1 + theta_delta;
|
theta_1 = theta_1 + theta_delta;
|
||||||
theta_delta = fabsf(theta_delta);
|
theta_delta = fabsf(theta_delta);
|
||||||
|
start_swapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto relative_start = start - center;
|
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);
|
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) {
|
for (float theta = theta_1; theta <= theta_1 + theta_delta; theta += theta_step) {
|
||||||
float s, c;
|
float s, c;
|
||||||
AK::sincos(theta, 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);
|
next_point.set_y(b * s);
|
||||||
rotate_point(next_point);
|
rotate_point(next_point);
|
||||||
|
|
||||||
callback(current_point + center, next_point + center);
|
emit_point(current_point + center, next_point + center);
|
||||||
|
|
||||||
current_point = next_point;
|
current_point = next_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(current_point + center, end);
|
emit_point(current_point + center, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue