mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:17:36 +00:00
LibGfx: A few small radial gradient tweaks/fixups
A few very minor changes seemed to small to commit separately: - Fix typo postive -> positive - Remove swap(start, end) FIXME, that is the correct thing to do - Add FIXME for start_radius == end_radius case - Formatting tweaks
This commit is contained in:
parent
2b8a9ff2ae
commit
df58fa8653
1 changed files with 19 additions and 17 deletions
|
@ -445,16 +445,17 @@ void CanvasConicGradientPaintStyle::paint(IntRect physical_bounding_box, PaintFu
|
||||||
|
|
||||||
static auto create_radial_gradient_between_two_circles(Gfx::FloatPoint start_center, float start_radius, Gfx::FloatPoint end_center, float end_radius, ReadonlySpan<ColorStop> color_stops, Optional<float> repeat_length)
|
static auto create_radial_gradient_between_two_circles(Gfx::FloatPoint start_center, float start_radius, Gfx::FloatPoint end_center, float end_radius, ReadonlySpan<ColorStop> color_stops, Optional<float> repeat_length)
|
||||||
{
|
{
|
||||||
if (fabs(start_radius - end_radius) < 1)
|
|
||||||
start_radius += 1;
|
|
||||||
|
|
||||||
// Needed for the start circle > end circle case, but FIXME, this seems kind of hacky.
|
|
||||||
bool reverse_gradient = end_radius < start_radius;
|
bool reverse_gradient = end_radius < start_radius;
|
||||||
if (reverse_gradient) {
|
if (reverse_gradient) {
|
||||||
swap(end_radius, start_radius);
|
swap(end_radius, start_radius);
|
||||||
swap(end_center, start_center);
|
swap(end_center, start_center);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Handle the start_radius == end_radius special case separately.
|
||||||
|
// This hack is not quite correct.
|
||||||
|
if (end_radius - start_radius < 1)
|
||||||
|
end_radius += 1;
|
||||||
|
|
||||||
// Spec steps: Useless for writing an actual implementation (give it a go :P):
|
// Spec steps: Useless for writing an actual implementation (give it a go :P):
|
||||||
//
|
//
|
||||||
// 2. Let x(ω) = (x1-x0)ω + x0
|
// 2. Let x(ω) = (x1-x0)ω + x0
|
||||||
|
@ -495,48 +496,49 @@ static auto create_radial_gradient_between_two_circles(Gfx::FloatPoint start_cen
|
||||||
auto circle_distance_finder = [=](auto radius, auto center) {
|
auto circle_distance_finder = [=](auto radius, auto center) {
|
||||||
auto radius2 = radius * radius;
|
auto radius2 = radius * radius;
|
||||||
auto delta = center - start_point;
|
auto delta = center - start_point;
|
||||||
auto dx2_factor = (radius2 - delta.y() * delta.y());
|
auto delta_xy = delta.x() * delta.y();
|
||||||
auto dy2_factor = (radius2 - delta.x() * delta.x());
|
auto dx2_factor = radius2 - delta.y() * delta.y();
|
||||||
return [=](bool postive_root, auto vec) {
|
auto dy2_factor = radius2 - delta.x() * delta.x();
|
||||||
|
return [=](bool positive_root, auto vec) {
|
||||||
// This works out the distance to the nearest point on the circle
|
// This works out the distance to the nearest point on the circle
|
||||||
// in the direction of the "vec" vector.
|
// in the direction of the "vec" vector.
|
||||||
auto dx2 = vec.x() * vec.x();
|
auto dx2 = vec.x() * vec.x();
|
||||||
auto dy2 = vec.y() * vec.y();
|
auto dy2 = vec.y() * vec.y();
|
||||||
auto root = sqrtf(dx2 * dx2_factor + dy2 * dy2_factor
|
auto root = sqrtf(dx2 * dx2_factor + dy2 * dy2_factor
|
||||||
+ 2 * vec.x() * vec.y() * delta.x() * delta.y());
|
+ 2 * vec.x() * vec.y() * delta_xy);
|
||||||
auto dot = vec.x() * delta.x() + vec.y() * delta.y();
|
auto dot = vec.x() * delta.x() + vec.y() * delta.y();
|
||||||
return (((postive_root ? root : -root) + dot) / (dx2 + dy2));
|
return ((positive_root ? root : -root) + dot) / (dx2 + dy2);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto end_circle_dist = circle_distance_finder(end_radius, end_center);
|
auto end_circle_dist = circle_distance_finder(end_radius, end_center);
|
||||||
auto start_circle_dist = [=, dist = circle_distance_finder(start_radius, start_center)](bool postive_root, auto vec) {
|
auto start_circle_dist = [=, dist = circle_distance_finder(start_radius, start_center)](bool positive_root, auto vec) {
|
||||||
if (start_center == start_point)
|
if (start_center == start_point)
|
||||||
return start_radius;
|
return start_radius;
|
||||||
return dist(postive_root, vec);
|
return dist(positive_root, vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
return Gradient {
|
return Gradient {
|
||||||
move(gradient_line),
|
move(gradient_line),
|
||||||
[=](float x, float y) {
|
[=](float x, float y) {
|
||||||
auto get_gradient_location = [&] {
|
auto loc = [&] {
|
||||||
FloatPoint point { x, y };
|
FloatPoint point { x, y };
|
||||||
auto dist = point.distance_from(start_point);
|
auto dist = point.distance_from(start_point);
|
||||||
if (dist == 0)
|
if (dist == 0)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
// The "vec" (unit) vector points from the focal point to the current point.
|
// The "vec" (unit) vector points from the focal point to the current point.
|
||||||
|
auto dist = point.distance_from(start_point);
|
||||||
auto vec = (point - start_point) / dist;
|
auto vec = (point - start_point) / dist;
|
||||||
bool use_postive_root = inner_contained || reverse_gradient;
|
bool use_positive_root = inner_contained || reverse_gradient;
|
||||||
auto dist_end = end_circle_dist(use_postive_root, vec);
|
auto dist_end = end_circle_dist(use_positive_root, vec);
|
||||||
auto dist_start = start_circle_dist(use_postive_root, vec);
|
auto dist_start = start_circle_dist(use_positive_root, vec);
|
||||||
// FIXME: Returning nan is a hack for "Don't paint me!"
|
// FIXME: Returning nan is a hack for "Don't paint me!"
|
||||||
if (dist_end < 0)
|
if (dist_end < 0)
|
||||||
return AK::NaN<float>;
|
return AK::NaN<float>;
|
||||||
if (dist_end - dist_start < 0)
|
if (dist_end - dist_start < 0)
|
||||||
return float(gradient_length);
|
return float(gradient_length);
|
||||||
return (dist - dist_start) / (dist_end - dist_start);
|
return (dist - dist_start) / (dist_end - dist_start);
|
||||||
};
|
}();
|
||||||
auto loc = get_gradient_location();
|
|
||||||
if (reverse_gradient)
|
if (reverse_gradient)
|
||||||
loc = 1.0f - loc;
|
loc = 1.0f - loc;
|
||||||
return loc * gradient_length;
|
return loc * gradient_length;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue