gsk: Handle hue-interpolation in ops

Make all our gradient ops adjust the hue according to
the hue interpolation.

This is currently modifying the values in the vertex array.
If reading those values back is bad, we may need to change that.
This commit is contained in:
Matthias Clasen 2024-08-10 18:56:26 -04:00
parent 8083456599
commit 3bce60c433
4 changed files with 100 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}