diff --git a/src/libsysprof-ui/sysprof-marks-aid.c b/src/libsysprof-ui/sysprof-marks-aid.c index 98744c91..4361dfab 100644 --- a/src/libsysprof-ui/sysprof-marks-aid.c +++ b/src/libsysprof-ui/sysprof-marks-aid.c @@ -46,6 +46,177 @@ typedef struct G_DEFINE_TYPE (SysprofMarksAid, sysprof_marks_aid, SYSPROF_TYPE_AID) +static void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b) +{ + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + if (red < blue) + min = red; + else + min = blue; + } + l = (max + min) / 2; + s = 0; + h = 0; + if (max != min) + { + if (l <= 0.5) + s = (max - min) / (max + min); + else + s = (max - min) / (2 - max - min); + delta = max - min; + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + h *= 60; + if (h < 0.0) + h += 360; + } + *r = h; + *g = l; + *b = s; +} + +static void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s) +{ + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + if (lightness <= 0.5) + m2 = lightness * (1 + saturation); + else + m2 = lightness + saturation - lightness * saturation; + m1 = 2 * lightness - m2; + if (saturation == 0) + { + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h + 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + if (hue < 60) + r = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1 + (m2 - m1) * (240 - hue) / 60; + else + r = m1; + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + if (hue < 60) + g = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1 + (m2 - m1) * (240 - hue) / 60; + else + g = m1; + hue = *h - 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + if (hue < 60) + b = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1 + (m2 - m1) * (240 - hue) / 60; + else + b = m1; + *h = r; + *l = g; + *s = b; + } +} + +static void +rgba_shade (const GdkRGBA *rgba, + GdkRGBA *dst, + gdouble k) +{ + gdouble red; + gdouble green; + gdouble blue; + + red = rgba->red; + green = rgba->green; + blue = rgba->blue; + + rgb_to_hls (&red, &green, &blue); + + green *= k; + + if (green > 1.0) + green = 1.0; + else if (green < 0.0) + green = 0.0; + + blue *= k; + + if (blue > 1.0) + blue = 1.0; + else if (blue < 0.0) + blue = 0.0; + + hls_to_rgb (&red, &green, &blue); + + dst->red = red; + dst->green = green; + dst->blue = blue; + dst->alpha = rgba->alpha; +} + static void present_free (gpointer data) { @@ -275,7 +446,7 @@ sysprof_marks_aid_present_finish (SysprofAid *aid, if (!g_hash_table_contains (seen, GUINT_TO_POINTER (span->kind))) { - dzl_rgba_shade (&rgba, &kind_rgba, 1 + (ratio * span->kind)); + rgba_shade (&rgba, &kind_rgba, 1 + (ratio * span->kind)); g_hash_table_insert (seen, GUINT_TO_POINTER (span->kind), g_memdup2 (&kind_rgba, sizeof kind_rgba));