aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/misc')
-rw-r--r--widgets/misc/e-hsv-utils.c166
-rw-r--r--widgets/misc/e-hsv-utils.h31
2 files changed, 197 insertions, 0 deletions
diff --git a/widgets/misc/e-hsv-utils.c b/widgets/misc/e-hsv-utils.c
new file mode 100644
index 0000000000..31561436dd
--- /dev/null
+++ b/widgets/misc/e-hsv-utils.c
@@ -0,0 +1,166 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-hsv-utils.c: utilites for manipulating colours in HSV space
+ *
+ * Author:
+ * Seth Nickell <seth@eazel.com>
+ *
+ * Copyright (C) 1995-2001 Seth Nickell, Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ */
+
+#include <config.h>
+
+#include "e-hsv-utils.h"
+
+/* tweak_hsv is a really tweaky function. it modifies its first argument, which
+ should be the colour you want tweaked. delta_h, delta_s and delta_v specify
+ how much you want their respective channels modified (and in what direction).
+ if it can't do the specified modification, it does it in the oppositon direction */
+void
+e_hsv_tweak (GdkColor *colour, gdouble delta_h, gdouble delta_s, gdouble delta_v)
+{
+ gdouble h, s, v, r, g, b;
+
+ r = colour->red / 65535.0f;
+ g = colour->green / 65535.0f;
+ b = colour->blue / 65535.0f;
+
+ e_rgb_to_hsv (r, g, b, &h, &s, &v);
+
+ if (h + delta_h < 0) {
+ h -= delta_h;
+ } else {
+ h += delta_h;
+ }
+
+ if (s + delta_s < 0) {
+ s -= delta_s;
+ } else {
+ s += delta_s;
+ }
+
+ if (v + delta_v < 0) {
+ v -= delta_v;
+ } else {
+ v += delta_v;
+ }
+
+ e_hsv_to_rgb (h, s, v, &r, &g, &b);
+
+ colour->red = r * 65535.0f;
+ colour->green = g * 65535.0f;
+ colour->blue = b * 65535.0f;
+}
+
+/* Copy n' Paste code from the GTK+ colour selector (gtkcolorsel.c) */
+/* Originally lifted, I suspect, from "Foley, van Dam" */
+void
+e_hsv_to_rgb (gdouble h, gdouble s, gdouble v,
+ gdouble *r, gdouble *g, gdouble *b)
+{
+ gint i;
+ gdouble f, w, q, t;
+
+ if (s == 0.0)
+ s = 0.000001;
+
+ if (h == -1.0)
+ {
+ *r = v;
+ *g = v;
+ *b = v;
+ }
+ else
+ {
+ if (h == 360.0)
+ h = 0.0;
+ h = h / 60.0;
+ i = (gint) h;
+ f = h - i;
+ w = v * (1.0 - s);
+ q = v * (1.0 - (s * f));
+ t = v * (1.0 - (s * (1.0 - f)));
+
+ switch (i)
+ {
+ case 0:
+ *r = v;
+ *g = t;
+ *b = w;
+ break;
+ case 1:
+ *r = q;
+ *g = v;
+ *b = w;
+ break;
+ case 2:
+ *r = w;
+ *g = v;
+ *b = t;
+ break;
+ case 3:
+ *r = w;
+ *g = q;
+ *b = v;
+ break;
+ case 4:
+ *r = t;
+ *g = w;
+ *b = v;
+ break;
+ case 5:
+ *r = v;
+ *g = w;
+ *b = q;
+ break;
+ }
+ }
+}
+
+void
+e_rgb_to_hsv (gdouble r, gdouble g, gdouble b,
+ gdouble *h, gdouble *s, gdouble *v)
+{
+ double max, min, delta;
+
+ max = r;
+ if (g > max)
+ max = g;
+ if (b > max)
+ max = b;
+
+ min = r;
+ if (g < min)
+ min = g;
+ if (b < min)
+ min = b;
+
+ *v = max;
+
+ if (max != 0.0)
+ *s = (max - min) / max;
+ else
+ *s = 0.0;
+
+ if (*s == 0.0)
+ *h = -1.0;
+ else
+ {
+ delta = max - min;
+
+ if (r == max)
+ *h = (g - b) / delta;
+ else if (g == max)
+ *h = 2.0 + (b - r) / delta;
+ else if (b == max)
+ *h = 4.0 + (r - g) / delta;
+
+ *h = *h * 60.0;
+
+ if (*h < 0.0)
+ *h = *h + 360;
+ }
+}
+
+
diff --git a/widgets/misc/e-hsv-utils.h b/widgets/misc/e-hsv-utils.h
new file mode 100644
index 0000000000..774d18585c
--- /dev/null
+++ b/widgets/misc/e-hsv-utils.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_HSV_UTILS_H_
+#define _E_HSV_UTILS_H_
+
+#include <libgnome/gnome-defs.h>
+#include <gdk/gdk.h>
+
+BEGIN_GNOME_DECLS
+
+void e_hsv_to_rgb (gdouble h,
+ gdouble s,
+ gdouble v,
+ gdouble *r,
+ gdouble *g,
+ gdouble *b);
+
+void e_rgb_to_hsv (gdouble r,
+ gdouble g,
+ gdouble b,
+ gdouble *h,
+ gdouble *s,
+ gdouble *v);
+
+void e_hsv_tweak (GdkColor *colour,
+ gdouble delta_h,
+ gdouble delta_s,
+ gdouble delta_v);
+
+END_GNOME_DECLS
+
+#endif /* _E_HSV_UTILS_H_ */