mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-19 18:00:09 +00:00
259 lines
4.9 KiB
C
259 lines
4.9 KiB
C
/* Color utilities
|
|
*
|
|
* Copyright (C) 1999 The Free Software Foundation
|
|
*
|
|
* Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
|
|
* Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
|
|
* Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
|
|
*
|
|
* 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/>.
|
|
*/
|
|
|
|
/*
|
|
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
|
* file for a list of people on the GTK+ Team. See the ChangeLog
|
|
* files for a list of changes. These files are distributed with
|
|
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include "gtkcolorutils.h"
|
|
|
|
|
|
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
|
|
|
|
/* Converts from HSV to RGB */
|
|
static void
|
|
hsv_to_rgb (gdouble *h,
|
|
gdouble *s,
|
|
gdouble *v)
|
|
{
|
|
gdouble hue, saturation, value;
|
|
gdouble f, p, q, t;
|
|
|
|
if (*s == 0.0)
|
|
{
|
|
*h = *v;
|
|
*s = *v;
|
|
*v = *v; /* heh */
|
|
}
|
|
else
|
|
{
|
|
hue = *h * 6.0;
|
|
saturation = *s;
|
|
value = *v;
|
|
|
|
if (hue == 6.0)
|
|
hue = 0.0;
|
|
|
|
f = hue - (int) hue;
|
|
p = value * (1.0 - saturation);
|
|
q = value * (1.0 - saturation * f);
|
|
t = value * (1.0 - saturation * (1.0 - f));
|
|
|
|
switch ((int) hue)
|
|
{
|
|
case 0:
|
|
*h = value;
|
|
*s = t;
|
|
*v = p;
|
|
break;
|
|
|
|
case 1:
|
|
*h = q;
|
|
*s = value;
|
|
*v = p;
|
|
break;
|
|
|
|
case 2:
|
|
*h = p;
|
|
*s = value;
|
|
*v = t;
|
|
break;
|
|
|
|
case 3:
|
|
*h = p;
|
|
*s = q;
|
|
*v = value;
|
|
break;
|
|
|
|
case 4:
|
|
*h = t;
|
|
*s = p;
|
|
*v = value;
|
|
break;
|
|
|
|
case 5:
|
|
*h = value;
|
|
*s = p;
|
|
*v = q;
|
|
break;
|
|
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Converts from RGB to HSV */
|
|
static void
|
|
rgb_to_hsv (gdouble *r,
|
|
gdouble *g,
|
|
gdouble *b)
|
|
{
|
|
gdouble red, green, blue;
|
|
gdouble h, s, v;
|
|
gdouble min, max;
|
|
gdouble delta;
|
|
|
|
red = *r;
|
|
green = *g;
|
|
blue = *b;
|
|
|
|
h = 0.0;
|
|
|
|
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;
|
|
}
|
|
|
|
v = max;
|
|
|
|
if (max != 0.0)
|
|
s = (max - min) / max;
|
|
else
|
|
s = 0.0;
|
|
|
|
if (s == 0.0)
|
|
h = 0.0;
|
|
else
|
|
{
|
|
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 /= 6.0;
|
|
|
|
if (h < 0.0)
|
|
h += 1.0;
|
|
else if (h > 1.0)
|
|
h -= 1.0;
|
|
}
|
|
|
|
*r = h;
|
|
*g = s;
|
|
*b = v;
|
|
}
|
|
|
|
/**
|
|
* gtk_hsv_to_rgb:
|
|
* @h: Hue
|
|
* @s: Saturation
|
|
* @v: Value
|
|
* @r: (out): Return value for the red component
|
|
* @g: (out): Return value for the green component
|
|
* @b: (out): Return value for the blue component
|
|
*
|
|
* Converts a color from HSV space to RGB.
|
|
*
|
|
* Input values must be in the [0.0, 1.0] range;
|
|
* output values will be in the same range.
|
|
*
|
|
* Since: 2.14
|
|
*/
|
|
void
|
|
gtk_hsv_to_rgb (gdouble h, gdouble s, gdouble v,
|
|
gdouble *r, gdouble *g, gdouble *b)
|
|
{
|
|
g_return_if_fail (h >= 0.0 && h <= 1.0);
|
|
g_return_if_fail (s >= 0.0 && s <= 1.0);
|
|
g_return_if_fail (v >= 0.0 && v <= 1.0);
|
|
|
|
hsv_to_rgb (&h, &s, &v);
|
|
|
|
if (r)
|
|
*r = h;
|
|
|
|
if (g)
|
|
*g = s;
|
|
|
|
if (b)
|
|
*b = v;
|
|
}
|
|
|
|
/**
|
|
* gtk_rgb_to_hsv:
|
|
* @r: Red
|
|
* @g: Green
|
|
* @b: Blue
|
|
* @h: (out): Return value for the hue component
|
|
* @s: (out): Return value for the saturation component
|
|
* @v: (out): Return value for the value component
|
|
*
|
|
* Converts a color from RGB space to HSV.
|
|
*
|
|
* Input values must be in the [0.0, 1.0] range;
|
|
* output values will be in the same range.
|
|
*
|
|
* Since: 2.14
|
|
*/
|
|
void
|
|
gtk_rgb_to_hsv (gdouble r, gdouble g, gdouble b,
|
|
gdouble *h, gdouble *s, gdouble *v)
|
|
{
|
|
g_return_if_fail (r >= 0.0 && r <= 1.0);
|
|
g_return_if_fail (g >= 0.0 && g <= 1.0);
|
|
g_return_if_fail (b >= 0.0 && b <= 1.0);
|
|
|
|
rgb_to_hsv (&r, &g, &b);
|
|
|
|
if (h)
|
|
*h = r;
|
|
|
|
if (s)
|
|
*s = g;
|
|
|
|
if (v)
|
|
*v = b;
|
|
}
|