From abcfaca3da4cde641894e724cb6ab1541c6d93e6 Mon Sep 17 00:00:00 2001 From: Torstennator Date: Tue, 25 Apr 2023 17:45:45 +0200 Subject: [PATCH] LibGfx: Add support to draw radial gradients with an rotation angle --- Userland/Libraries/LibGfx/GradientPainting.cpp | 17 ++++++++++++++--- Userland/Libraries/LibGfx/Painter.h | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibGfx/GradientPainting.cpp b/Userland/Libraries/LibGfx/GradientPainting.cpp index 7d1cd65c60..f6826066ab 100644 --- a/Userland/Libraries/LibGfx/GradientPainting.cpp +++ b/Userland/Libraries/LibGfx/GradientPainting.cpp @@ -213,18 +213,28 @@ static auto create_conic_gradient(ReadonlySpan color_stops, FloatPoin }; } -static auto create_radial_gradient(IntRect const& physical_rect, ReadonlySpan color_stops, IntPoint center, IntSize size, Optional repeat_length) +static auto create_radial_gradient(IntRect const& physical_rect, ReadonlySpan color_stops, IntPoint center, IntSize size, Optional repeat_length, Optional rotation_angle = {}) { // A conservative guesstimate on how many colors we need to generate: auto max_dimension = max(physical_rect.width(), physical_rect.height()); auto max_visible_gradient = max(max_dimension / 2, min(size.width(), max_dimension)); GradientLine gradient_line(max_visible_gradient, color_stops, repeat_length); 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 / 180); + rotation_transform.rotate_radians(angle_as_radians); + } + return Gradient { move(gradient_line), [=](int x, int y) { // FIXME: See if there's a more efficient calculation we do there :^) 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_y = point.y() / size.height(); 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 color_stops, IntPoint center, IntSize size, Optional repeat_length) +void Painter::fill_rect_with_radial_gradient(IntRect const& rect, ReadonlySpan color_stops, IntPoint center, IntSize size, Optional repeat_length, Optional rotation_angle) { auto a_rect = to_physical(rect); if (a_rect.intersected(clip_rect() * scale()).is_empty()) 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); } diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h index 6ae0016426..508bcac814 100644 --- a/Userland/Libraries/LibGfx/Painter.h +++ b/Userland/Libraries/LibGfx/Painter.h @@ -57,7 +57,7 @@ public: void fill_rect_with_gradient(IntRect const&, Color gradient_start, Color gradient_end); void fill_rect_with_linear_gradient(IntRect const&, ReadonlySpan, float angle, Optional repeat_length = {}); void fill_rect_with_conic_gradient(IntRect const&, ReadonlySpan, IntPoint center, float start_angle, Optional repeat_length = {}); - void fill_rect_with_radial_gradient(IntRect const&, ReadonlySpan, IntPoint center, IntSize size, Optional repeat_length = {}); + void fill_rect_with_radial_gradient(IntRect const&, ReadonlySpan, IntPoint center, IntSize size, Optional repeat_length = {}, Optional rotation_angle = {}); 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_ellipse(IntRect const&, Color);