diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp index 8d303f7c47..4813a8de10 100644 --- a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp +++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp @@ -26,6 +26,13 @@ void FastBoxBlur::apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bi Gfx::FastBoxBlurFilter filter(target_bitmap); if (m_use_asymmetric_radii) { + if (m_use_vector) { + auto radius_x = m_radius * fabs(cos((double)m_angle * M_DEG2RAD)); + auto radius_y = m_radius * fabs(sin((double)m_angle * M_DEG2RAD)); + filter.apply_single_pass(radius_x, radius_y); + return; + } + filter.apply_single_pass(m_radius_x, m_radius_y); return; } @@ -53,6 +60,7 @@ RefPtr FastBoxBlur::get_settings_widget() asymmetric_checkbox.on_checked = [&](bool checked) { m_use_asymmetric_radii = checked; if (m_use_asymmetric_radii) { + m_vector_checkbox->set_visible(true); m_radius_x_slider->set_value(m_radius); m_radius_y_slider->set_value(m_radius); m_asymmetric_radius_container->set_visible(true); @@ -62,6 +70,23 @@ RefPtr FastBoxBlur::get_settings_widget() m_asymmetric_radius_container->set_visible(false); m_radius_container->set_visible(true); m_gaussian_checkbox->set_visible(true); + m_vector_checkbox->set_visible(false); + } + update_preview(); + }; + + m_vector_checkbox = m_settings_widget->add("Use Direction and magnitude"); + m_vector_checkbox->set_checked(false); + m_vector_checkbox->set_visible(false); + m_vector_checkbox->set_fixed_height(15); + m_vector_checkbox->on_checked = [&](bool checked) { + m_use_vector = checked; + if (m_use_vector) { + m_asymmetric_radius_container->set_visible(false); + m_vector_container->set_visible(true); + } else { + m_asymmetric_radius_container->set_visible(true); + m_vector_container->set_visible(false); } update_preview(); }; @@ -121,6 +146,44 @@ RefPtr FastBoxBlur::get_settings_widget() update_preview(); }; + m_vector_container = m_settings_widget->add(); + m_vector_container->set_visible(false); + m_vector_container->set_fixed_height(50); + m_vector_container->set_layout(); + m_vector_container->layout()->set_margins({ 4, 0, 4, 0 }); + + auto& angle_container = m_vector_container->add(); + angle_container.set_fixed_height(20); + angle_container.set_layout(); + + auto& angle_label = angle_container.add("Angle:"); + angle_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + angle_label.set_fixed_size(60, 20); + + m_angle_slider = angle_container.add(Orientation::Horizontal, "°"); + m_angle_slider->set_range(0, 360); + m_angle_slider->set_value(m_angle); + m_angle_slider->on_change = [&](int value) { + m_angle = value; + update_preview(); + }; + + auto& magnitude_container = m_vector_container->add(); + magnitude_container.set_fixed_height(20); + magnitude_container.set_layout(); + + auto& magnitude_label = magnitude_container.add("Magnitude:"); + magnitude_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + magnitude_label.set_fixed_size(60, 20); + + m_magnitude_slider = magnitude_container.add(Orientation::Horizontal, "px"); + m_magnitude_slider->set_range(0, 50); + m_magnitude_slider->set_value(m_radius); + m_magnitude_slider->on_change = [&](int value) { + m_radius = value; + update_preview(); + }; + auto& gaussian_container = m_settings_widget->add(); gaussian_container.set_fixed_height(20); gaussian_container.set_layout(); diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h index cee731825b..bf48e5f6b8 100644 --- a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h +++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h @@ -28,12 +28,15 @@ private: bool m_use_vector { false }; size_t m_radius_x { 0 }; size_t m_radius_y { 0 }; + size_t m_angle { 0 }; bool m_approximate_gauss { false }; RefPtr m_radius_container { nullptr }; RefPtr m_asymmetric_radius_container { nullptr }; + RefPtr m_vector_container { nullptr }; RefPtr m_gaussian_checkbox { nullptr }; + RefPtr m_vector_checkbox { nullptr }; RefPtr m_radius_x_slider { nullptr }; RefPtr m_radius_y_slider { nullptr }; RefPtr m_angle_slider { nullptr };