diff --git a/gsk/gpu/gskgpuconicgradientop.c b/gsk/gpu/gskgpuconicgradientop.c index 3232047e21..69aa6b8ff5 100644 --- a/gsk/gpu/gskgpuconicgradientop.c +++ b/gsk/gpu/gskgpuconicgradientop.c @@ -1,6 +1,7 @@ #include "config.h" #include "gskgpuconicgradientopprivate.h" +#include "gskgpulineargradientopprivate.h" #include "gskgpuframeprivate.h" #include "gskgpuprintprivate.h" @@ -97,4 +98,11 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame, instance->offsets0[1] = stops[1].offset; gsk_gpu_color_to_float (&stops[0].color, ics, opacity, instance->color0); instance->offsets0[0] = stops[0].offset; + + gsk_adjust_hue (ics, hue_interp, instance->color0, instance->color1); + gsk_adjust_hue (ics, hue_interp, instance->color1, instance->color2); + gsk_adjust_hue (ics, hue_interp, instance->color2, instance->color3); + gsk_adjust_hue (ics, hue_interp, instance->color3, instance->color4); + gsk_adjust_hue (ics, hue_interp, instance->color4, instance->color5); + gsk_adjust_hue (ics, hue_interp, instance->color5, instance->color6); } diff --git a/gsk/gpu/gskgpulineargradientop.c b/gsk/gpu/gskgpulineargradientop.c index 8b4668e50a..aa17a170d5 100644 --- a/gsk/gpu/gskgpulineargradientop.c +++ b/gsk/gpu/gskgpulineargradientop.c @@ -52,6 +52,78 @@ static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = { gsk_gpu_lineargradient_setup_vao }; +void +gsk_adjust_hue (GdkColorState *ics, + GskHueInterpolation interp, + const float color1[4], + float color2[4]) +{ + float h1, h2; + float d; + + if (!gdk_color_state_equal (ics, GDK_COLOR_STATE_OKLCH)) + return; + + h1 = color1[2]; + h2 = color2[2]; + d = h2 - h1; + + while (d > 360) + { + h2 -= 360; + d = h2 - h1; + } + while (d < -360) + { + h2 += 360; + d = h2 - h1; + } + + g_assert (fabsf (d) <= 360); + + switch (interp) + { + case GSK_HUE_INTERPOLATION_SHORTER: + { + if (d > 180) + h2 -= 360; + else if (d < -180) + h2 += 360; + } + g_assert (fabsf (h2 - h1) <= 180); + break; + + case GSK_HUE_INTERPOLATION_LONGER: + { + if (0 < d && d < 180) + h2 -= 360; + else if (-180 < d && d <= 0) + h2 += 360; + g_assert (fabsf (h2 - h1) >= 180); + } + break; + + case GSK_HUE_INTERPOLATION_INCREASING: + if (h2 < h1) + h2 += 360; + d = h2 - h1; + g_assert (h1 <= h2); + break; + + case GSK_HUE_INTERPOLATION_DECREASING: + if (h1 < h2) + h2 -= 360; + d = h2 - h1; + g_assert (h1 >= h2); + break; + + default: + g_assert_not_reached (); + } + + color2[2] = h2; +} + void gsk_gpu_linear_gradient_op (GskGpuFrame *frame, GskGpuShaderClip clip, @@ -102,4 +174,11 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame, instance->offsets0[1] = stops[1].offset; gsk_gpu_color_to_float (&stops[0].color, ics, opacity, instance->color0); instance->offsets0[0] = stops[0].offset; + + gsk_adjust_hue (ics, hue_interp, instance->color0, instance->color1); + gsk_adjust_hue (ics, hue_interp, instance->color1, instance->color2); + gsk_adjust_hue (ics, hue_interp, instance->color2, instance->color3); + gsk_adjust_hue (ics, hue_interp, instance->color3, instance->color4); + gsk_adjust_hue (ics, hue_interp, instance->color4, instance->color5); + gsk_adjust_hue (ics, hue_interp, instance->color5, instance->color6); } diff --git a/gsk/gpu/gskgpulineargradientopprivate.h b/gsk/gpu/gskgpulineargradientopprivate.h index ee1c0a4872..5bc4343807 100644 --- a/gsk/gpu/gskgpulineargradientopprivate.h +++ b/gsk/gpu/gskgpulineargradientopprivate.h @@ -23,5 +23,10 @@ void gsk_gpu_linear_gradient_op (GskGpuF gsize n_stops); +void gsk_adjust_hue (GdkColorState *ics, + GskHueInterpolation interp, + const float color1[4], + float color2[4]); + G_END_DECLS diff --git a/gsk/gpu/gskgpuradialgradientop.c b/gsk/gpu/gskgpuradialgradientop.c index 5015f2886a..b54186b2ba 100644 --- a/gsk/gpu/gskgpuradialgradientop.c +++ b/gsk/gpu/gskgpuradialgradientop.c @@ -1,6 +1,7 @@ #include "config.h" #include "gskgpuradialgradientopprivate.h" +#include "gskgpulineargradientopprivate.h" #include "gskgpuframeprivate.h" #include "gskgpuprintprivate.h" @@ -106,4 +107,11 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame, instance->offsets0[1] = stops[1].offset; gsk_gpu_color_to_float (&stops[0].color, ics, opacity, instance->color0); instance->offsets0[0] = stops[0].offset; + + gsk_adjust_hue (ics, hue_interp, instance->color0, instance->color1); + gsk_adjust_hue (ics, hue_interp, instance->color1, instance->color2); + gsk_adjust_hue (ics, hue_interp, instance->color2, instance->color3); + gsk_adjust_hue (ics, hue_interp, instance->color3, instance->color4); + gsk_adjust_hue (ics, hue_interp, instance->color4, instance->color5); + gsk_adjust_hue (ics, hue_interp, instance->color5, instance->color6); }