204 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_hsla_shade (GtkHSLA       *dest,
 | |
|                  const GtkHSLA *src,
 | |
|                  double         factor)
 | |
| {
 | |
|   g_return_if_fail (dest != NULL);
 | |
|   g_return_if_fail (src != NULL);
 | |
| 
 | |
|   dest->hue = src->hue;
 | |
| 
 | |
|   dest->lightness = src->lightness * factor;
 | |
|   dest->lightness = CLAMP (dest->lightness, 0.0, 1.0);
 | |
| 
 | |
|   dest->saturation = src->saturation * factor;
 | |
|   dest->saturation = CLAMP (dest->saturation, 0.0, 1.0);
 | |
| 
 | |
|   dest->alpha = src->alpha;
 | |
| }
 | 
