[metacity] libmetacity: add MetaHSLA



commit b61d600613414bfbca41a35abaf0bfbc48ac1ed1
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sun Jan 24 13:29:53 2016 +0200

    libmetacity: add MetaHSLA

 libmetacity/Makefile.am |    2 +
 libmetacity/meta-hsla.c |  217 ++++++++++++++++++++++++++++++++++++++++++
 libmetacity/meta-hsla.h |   46 +++++++++
 src/Makefile.am         |    3 +-
 src/ui/theme.c          |  240 +++++------------------------------------------
 5 files changed, 289 insertions(+), 219 deletions(-)
---
diff --git a/libmetacity/Makefile.am b/libmetacity/Makefile.am
index 7158c80..d556b96 100644
--- a/libmetacity/Makefile.am
+++ b/libmetacity/Makefile.am
@@ -3,6 +3,8 @@ NULL =
 noinst_LTLIBRARIES = libmetacity.la
 
 libmetacity_la_SOURCES = \
+       meta-hsla.c \
+       meta-hsla.h \
        $(NULL)
 
 libmetacity_la_CPPFLAGS = \
diff --git a/libmetacity/meta-hsla.c b/libmetacity/meta-hsla.c
new file mode 100644
index 0000000..c94eb61
--- /dev/null
+++ b/libmetacity/meta-hsla.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "meta-hsla.h"
+
+/**
+ * meta_hsla_from_rgba:
+ * @hsla: (out): location to store #MetaHSLA color
+ * @rgba: #GdkRGBA color
+ *
+ * Convert RGBA color to HSLA color.
+ */
+void
+meta_hsla_from_rgba (MetaHSLA      *hsla,
+                     const GdkRGBA *rgba)
+{
+  gdouble min;
+  gdouble max;
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble delta;
+
+  g_return_if_fail (hsla != NULL || 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->hue = 0;
+  hsla->saturation = 0;
+  hsla->lightness = (max + min) / 2;
+  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;
+    }
+}
+
+/**
+ * meta_hsla_to_rgba:
+ * @hsla: #MetaHSLA color
+ * @rgba: (out): location to store #GdkRGBA color
+ *
+ * Convert HSLA color to RGBA color.
+ */
+void
+meta_hsla_to_rgba (const MetaHSLA *hsla,
+                   GdkRGBA        *rgba)
+{
+  gdouble hue;
+  gdouble saturation;
+  gdouble lightness;
+  gdouble m1;
+  gdouble m2;
+
+  g_return_if_fail (hsla != NULL || rgba != NULL);
+
+  saturation = hsla->saturation;
+  lightness = hsla->lightness;
+
+  if (lightness <= 0.5)
+    m2 = lightness * (1 + saturation);
+  else
+    m2 = lightness + saturation - lightness * saturation;
+
+  m1 = 2 * lightness - m2;
+
+  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;
+    }
+
+  rgba->alpha = hsla->alpha;
+}
+
+/**
+ * meta_hsla_shade:
+ * @source: #MetaHSLA color
+ * @factor: amount to scale saturation and lightness
+ * @destination: (out): location to store #MetaHSLA color
+ *
+ * Takes a @source color, scales saturation and lightness by @factor and
+ * sets @destionation to the resulting color.
+ */
+void
+meta_hsla_shade (const MetaHSLA *source,
+                 const gdouble   factor,
+                 MetaHSLA       *destination)
+{
+  g_return_if_fail (source != NULL || destination != NULL);
+
+  destination->hue = source->hue;
+
+  destination->saturation = source->saturation * factor;
+  destination->saturation = CLAMP (destination->saturation, 0.0, 1.0);
+
+  destination->lightness = source->lightness * factor;
+  destination->lightness = CLAMP (destination->lightness, 0.0, 1.0);
+
+  destination->alpha = source->alpha;
+}
diff --git a/libmetacity/meta-hsla.h b/libmetacity/meta-hsla.h
new file mode 100644
index 0000000..07959c2
--- /dev/null
+++ b/libmetacity/meta-hsla.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_HSLA_H
+#define META_HSLA_H
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+  gdouble hue;
+  gdouble saturation;
+  gdouble lightness;
+  gdouble alpha;
+} MetaHSLA;
+
+void meta_hsla_from_rgba (MetaHSLA       *hsla,
+                          const GdkRGBA  *rgba);
+
+void meta_hsla_to_rgba   (const MetaHSLA *hsla,
+                          GdkRGBA        *rgba);
+
+void meta_hsla_shade     (const MetaHSLA *source,
+                          const gdouble   factor,
+                          MetaHSLA       *destination);
+
+G_END_DECLS
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index ead31a4..5cc4e97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,7 @@ AM_CPPFLAGS = \
        -DG_LOG_DOMAIN=\"metacity\" \
        -DSN_API_NOT_YET_FROZEN=1 \
        -I$(srcdir)/include \
+       -I$(top_srcdir) \
        @METACITY_CFLAGS@ \
        $(WARN_CFLAGS) \
        $(AM_CFLAGS) \
@@ -126,7 +127,7 @@ libmetacity_private_la_SOURCES =            \
        $(NULL)
 
 libmetacity_private_la_LDFLAGS = -no-undefined -version-info 4:0:0 $(WARN_LDFLAGS) $(AM_LDFLAGS)
-libmetacity_private_la_LIBADD  = @METACITY_LIBS@
+libmetacity_private_la_LIBADD  = @METACITY_LIBS@ $(top_builddir)/libmetacity/libmetacity.la
 
 libmetacityincludedir = $(includedir)/metacity/metacity-private
 
diff --git a/src/ui/theme.c b/src/ui/theme.c
index ef9d439..f90605b 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -55,6 +55,7 @@
 #include "util.h"
 #include "gradient.h"
 #include <gtk/gtk.h>
+#include <libmetacity/meta-hsla.h>
 #include <string.h>
 #include <stdlib.h>
 #define __USE_XOPEN
@@ -78,16 +79,6 @@
 #define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
 
-static void gtk_style_shade            (GdkRGBA         *a,
-                                        GdkRGBA         *b,
-                                        gdouble          k);
-static void rgb_to_hls                 (gdouble         *r,
-                                        gdouble         *g,
-                                        gdouble         *b);
-static void hls_to_rgb                 (gdouble         *h,
-                                        gdouble         *l,
-                                        gdouble         *s);
-
 /**
  * The current theme. (Themes are singleton.)
  */
@@ -1710,6 +1701,27 @@ get_background_color (GtkStyleContext *context,
   gdk_rgba_free (c);
 }
 
+/**
+ * Takes a colour "a", scales the lightness and saturation by a certain amount,
+ * and sets "b" to the resulting colour.
+ * gtkstyle.c cut-and-pastage.
+ *
+ * \param a  the starting colour
+ * \param b  [out] the resulting colour
+ * \param k  amount to scale lightness and saturation by
+ */
+static void
+gtk_style_shade (GdkRGBA *a,
+                 GdkRGBA *b,
+                 gdouble  k)
+{
+  MetaHSLA hsla;
+
+  meta_hsla_from_rgba (&hsla, a);
+  meta_hsla_shade (&hsla, k, &hsla);
+  meta_hsla_to_rgba (&hsla, b);
+}
+
 /* Based on set_color() in gtkstyle.c */
 #define LIGHTNESS_MULT 1.3
 #define DARKNESS_MULT  0.7
@@ -6600,214 +6612,6 @@ meta_gtk_state_from_string (const char *str)
 }
 
 /**
- * Takes a colour "a", scales the lightness and saturation by a certain amount,
- * and sets "b" to the resulting colour.
- * gtkstyle.c cut-and-pastage.
- *
- * \param a  the starting colour
- * \param b  [out] the resulting colour
- * \param k  amount to scale lightness and saturation by
- */
-static void
-gtk_style_shade (GdkRGBA *a,
-                 GdkRGBA *b,
-                 gdouble  k)
-{
-  gdouble red;
-  gdouble green;
-  gdouble blue;
-
-  red = a->red;
-  green = a->green;
-  blue = a->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);
-
-  b->red = red;
-  b->green = green;
-  b->blue = blue;
-  b->alpha = a->alpha;
-}
-
-/**
- * Converts a red/green/blue triplet to a hue/lightness/saturation triplet.
- *
- * \param r  on input, red; on output, hue
- * \param g  on input, green; on output, lightness
- * \param b  on input, blue; on output, saturation
- */
-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;
-}
-
-/**
- * Converts a hue/lightness/saturation triplet to a red/green/blue triplet.
- *
- * \param h  on input, hue; on output, red
- * \param l  on input, lightness; on output, green
- * \param s  on input, saturation; on output, blue
- */
-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;
-    }
-}
-
-/**
  * Returns the earliest version of the theme format which required support
  * for a particular button.  (For example, "shade" first appeared in v2, and
  * "close" in v1.)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]