186 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.2 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;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |