mirror of
https://github.com/RGBCube/serenity
synced 2025-06-16 21:12:10 +00:00
LibGfx: Add support to draw radial gradients with an rotation angle
This commit is contained in:
parent
81dd29f713
commit
abcfaca3da
2 changed files with 15 additions and 4 deletions
|
@ -213,18 +213,28 @@ static auto create_conic_gradient(ReadonlySpan<ColorStop> color_stops, FloatPoin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto create_radial_gradient(IntRect const& physical_rect, ReadonlySpan<ColorStop> color_stops, IntPoint center, IntSize size, Optional<float> repeat_length)
|
static auto create_radial_gradient(IntRect const& physical_rect, ReadonlySpan<ColorStop> color_stops, IntPoint center, IntSize size, Optional<float> repeat_length, Optional<float> rotation_angle = {})
|
||||||
{
|
{
|
||||||
// A conservative guesstimate on how many colors we need to generate:
|
// A conservative guesstimate on how many colors we need to generate:
|
||||||
auto max_dimension = max(physical_rect.width(), physical_rect.height());
|
auto max_dimension = max(physical_rect.width(), physical_rect.height());
|
||||||
auto max_visible_gradient = max(max_dimension / 2, min(size.width(), max_dimension));
|
auto max_visible_gradient = max(max_dimension / 2, min(size.width(), max_dimension));
|
||||||
GradientLine gradient_line(max_visible_gradient, color_stops, repeat_length);
|
GradientLine gradient_line(max_visible_gradient, color_stops, repeat_length);
|
||||||
auto center_point = FloatPoint { center }.translated(0.5, 0.5);
|
auto center_point = FloatPoint { center }.translated(0.5, 0.5);
|
||||||
|
AffineTransform rotation_transform;
|
||||||
|
if (rotation_angle.has_value()) {
|
||||||
|
auto angle_as_radians = rotation_angle.value() * (AK::Pi<float> / 180);
|
||||||
|
rotation_transform.rotate_radians(angle_as_radians);
|
||||||
|
}
|
||||||
|
|
||||||
return Gradient {
|
return Gradient {
|
||||||
move(gradient_line),
|
move(gradient_line),
|
||||||
[=](int x, int y) {
|
[=](int x, int y) {
|
||||||
// FIXME: See if there's a more efficient calculation we do there :^)
|
// FIXME: See if there's a more efficient calculation we do there :^)
|
||||||
auto point = FloatPoint(x, y) - center_point;
|
auto point = FloatPoint(x, y) - center_point;
|
||||||
|
|
||||||
|
if (rotation_angle.has_value())
|
||||||
|
point.transform_by(rotation_transform);
|
||||||
|
|
||||||
auto gradient_x = point.x() / size.width();
|
auto gradient_x = point.x() / size.width();
|
||||||
auto gradient_y = point.y() / size.height();
|
auto gradient_y = point.y() / size.height();
|
||||||
return AK::sqrt(gradient_x * gradient_x + gradient_y * gradient_y) * max_visible_gradient;
|
return AK::sqrt(gradient_x * gradient_x + gradient_y * gradient_y) * max_visible_gradient;
|
||||||
|
@ -257,12 +267,13 @@ void Painter::fill_rect_with_conic_gradient(IntRect const& rect, ReadonlySpan<Co
|
||||||
conic_gradient.paint(*this, a_rect);
|
conic_gradient.paint(*this, a_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::fill_rect_with_radial_gradient(IntRect const& rect, ReadonlySpan<ColorStop> color_stops, IntPoint center, IntSize size, Optional<float> repeat_length)
|
void Painter::fill_rect_with_radial_gradient(IntRect const& rect, ReadonlySpan<ColorStop> color_stops, IntPoint center, IntSize size, Optional<float> repeat_length, Optional<float> rotation_angle)
|
||||||
{
|
{
|
||||||
auto a_rect = to_physical(rect);
|
auto a_rect = to_physical(rect);
|
||||||
if (a_rect.intersected(clip_rect() * scale()).is_empty())
|
if (a_rect.intersected(clip_rect() * scale()).is_empty())
|
||||||
return;
|
return;
|
||||||
auto radial_gradient = create_radial_gradient(a_rect, color_stops, center * scale(), size * scale(), repeat_length);
|
|
||||||
|
auto radial_gradient = create_radial_gradient(a_rect, color_stops, center * scale(), size * scale(), repeat_length, rotation_angle);
|
||||||
radial_gradient.paint(*this, a_rect);
|
radial_gradient.paint(*this, a_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
void fill_rect_with_gradient(IntRect const&, Color gradient_start, Color gradient_end);
|
void fill_rect_with_gradient(IntRect const&, Color gradient_start, Color gradient_end);
|
||||||
void fill_rect_with_linear_gradient(IntRect const&, ReadonlySpan<ColorStop>, float angle, Optional<float> repeat_length = {});
|
void fill_rect_with_linear_gradient(IntRect const&, ReadonlySpan<ColorStop>, float angle, Optional<float> repeat_length = {});
|
||||||
void fill_rect_with_conic_gradient(IntRect const&, ReadonlySpan<ColorStop>, IntPoint center, float start_angle, Optional<float> repeat_length = {});
|
void fill_rect_with_conic_gradient(IntRect const&, ReadonlySpan<ColorStop>, IntPoint center, float start_angle, Optional<float> repeat_length = {});
|
||||||
void fill_rect_with_radial_gradient(IntRect const&, ReadonlySpan<ColorStop>, IntPoint center, IntSize size, Optional<float> repeat_length = {});
|
void fill_rect_with_radial_gradient(IntRect const&, ReadonlySpan<ColorStop>, IntPoint center, IntSize size, Optional<float> repeat_length = {}, Optional<float> rotation_angle = {});
|
||||||
void fill_rect_with_rounded_corners(IntRect const&, Color, int radius);
|
void fill_rect_with_rounded_corners(IntRect const&, Color, int radius);
|
||||||
void fill_rect_with_rounded_corners(IntRect const&, Color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius);
|
void fill_rect_with_rounded_corners(IntRect const&, Color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius);
|
||||||
void fill_ellipse(IntRect const&, Color);
|
void fill_ellipse(IntRect const&, Color);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue