summaryrefslogtreecommitdiff
path: root/gtk/gtkhsla.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2012-11-08 15:26:33 +0100
committerBenjamin Otte <otte@redhat.com>2012-11-08 23:34:05 +0100
commite063a0fdf13a09ca44588862d6b0b4f04232759f (patch)
tree69c88ef57b6c2d4eeaa383d6ab62afcb03532ab3 /gtk/gtkhsla.c
parentcff4718e9189969191e4dab5062bea4a8ad52d45 (diff)
downloadgtk+-e063a0fdf13a09ca44588862d6b0b4f04232759f.tar.gz
symboliccolor: Split out HSLA code
Diffstat (limited to 'gtk/gtkhsla.c')
-rw-r--r--gtk/gtkhsla.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/gtk/gtkhsla.c b/gtk/gtkhsla.c
new file mode 100644
index 0000000000..a78849789d
--- /dev/null
+++ b/gtk/gtkhsla.c
@@ -0,0 +1,185 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkhslaprivate.h"
+
+#include <math.h>
+
+void
+_gtk_hsla_init (GtkHSLA *hsla,
+ double hue,
+ double saturation,
+ double lightness,
+ double alpha)
+{
+ g_return_if_fail (hsla != NULL);
+
+ if (hue >= 0)
+ hsla->hue = fmod (hue, 360);
+ else
+ hsla->hue = fmod (hue, 360) + 360;
+ hsla->saturation = CLAMP (saturation, 0, 1);
+ hsla->lightness = CLAMP (lightness, 0, 1);
+ hsla->alpha = CLAMP (alpha, 0, 1);
+}
+
+void
+_gtk_hsla_init_from_rgba (GtkHSLA *hsla,
+ const GdkRGBA *rgba)
+{
+ gdouble min;
+ gdouble max;
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+ gdouble delta;
+
+ g_return_if_fail (hsla != NULL);
+ g_return_if_fail (rgba != NULL);
+
+ red = rgba->red;
+ green = rgba->green;
+ blue = rgba->blue;
+
+ 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;
+ }
+
+ hsla->lightness = (max + min) / 2;
+ hsla->saturation = 0;
+ hsla->hue = 0;
+ hsla->alpha = rgba->alpha;
+
+ if (max != min)
+ {
+ if (hsla->lightness <= 0.5)
+ hsla->saturation = (max - min) / (max + min);
+ else
+ hsla->saturation = (max - min) / (2 - max - min);
+
+ delta = max -min;
+ if (red == max)
+ hsla->hue = (green - blue) / delta;
+ else if (green == max)
+ hsla->hue = 2 + (blue - red) / delta;
+ else if (blue == max)
+ hsla->hue = 4 + (red - green) / delta;
+
+ hsla->hue *= 60;
+ if (hsla->hue < 0.0)
+ hsla->hue += 360;
+ }
+}
+
+void
+_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
+ const GtkHSLA *hsla)
+{
+ gdouble hue;
+ gdouble lightness;
+ gdouble saturation;
+ gdouble m1, m2;
+
+ lightness = hsla->lightness;
+ saturation = hsla->saturation;
+
+ if (lightness <= 0.5)
+ m2 = lightness * (1 + saturation);
+ else
+ m2 = lightness + saturation - lightness * saturation;
+ m1 = 2 * lightness - m2;
+
+ rgba->alpha = hsla->alpha;
+
+ if (saturation == 0)
+ {
+ rgba->red = lightness;
+ rgba->green = lightness;
+ rgba->blue = lightness;
+ }
+ else
+ {
+ hue = hsla->hue + 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->red = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->red = m2;
+ else if (hue < 240)
+ rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->red = m1;
+
+ hue = hsla->hue;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->green = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->green = m2;
+ else if (hue < 240)
+ rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->green = m1;
+
+ hue = hsla->hue - 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->blue = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->blue = m2;
+ else if (hue < 240)
+ rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->blue = m1;
+ }
+}
+