mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-03 01:13:24 +00:00
app: GimpGradient now uses GeglColor.
I still see some limitations in GimpGradient, and in particular, they are still always stored as RGB in GGR files. It would be nice if we could store the actual color format. This way, if someone chooses a gradient stop as Lab or CMYK color, that's what the gradient file would keep track of. But also even storing the space of a color (instead of storing/loading always in sRGB, even though this may still work fine as we store unbounded double values). This might warrant for a v2 of GGR file format. This commit also fixes loading of SVG gradient which was apparently broken regarding hexadecimal color parsing. Finally I improve gegl_color_set_alpha() by adding an alpha channel when the initial format had none.
This commit is contained in:
parent
916d032f67
commit
b6856af9d8
28 changed files with 1330 additions and 722 deletions
481
libgimpcolor/gimpcolor-parse.c
Normal file
481
libgimpcolor/gimpcolor-parse.c
Normal file
|
@ -0,0 +1,481 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpcolor-parse.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* Some of the code in here was inspired and partly copied from pango
|
||||
* and librsvg.
|
||||
*
|
||||
* 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 3 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
|
||||
* Library 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
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <babl/babl.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "gimpcolor.h"
|
||||
|
||||
|
||||
static GeglColor * gimp_color_parse_name_internal (const gchar *name);
|
||||
static GeglColor * gimp_color_parse_hex_internal (const gchar *hex);
|
||||
static GeglColor * gimp_color_parse_css_numeric (const gchar *css);
|
||||
static GeglColor * gimp_color_parse_css_internal (const gchar *css);
|
||||
static gchar * gimp_color_parse_strip (const gchar *str,
|
||||
gint len);
|
||||
static gint gimp_color_entry_compare (gconstpointer a,
|
||||
gconstpointer b);
|
||||
static gboolean gimp_color_parse_hex_component (const gchar *hex,
|
||||
gint len,
|
||||
gdouble *value);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *name;
|
||||
const guchar red;
|
||||
const guchar green;
|
||||
const guchar blue;
|
||||
} ColorEntry;
|
||||
|
||||
static const ColorEntry named_colors[] =
|
||||
{
|
||||
{ "aliceblue", 240, 248, 255 },
|
||||
{ "antiquewhite", 250, 235, 215 },
|
||||
{ "aqua", 0, 255, 255 },
|
||||
{ "aquamarine", 127, 255, 212 },
|
||||
{ "azure", 240, 255, 255 },
|
||||
{ "beige", 245, 245, 220 },
|
||||
{ "bisque", 255, 228, 196 },
|
||||
{ "black", 0, 0, 0 },
|
||||
{ "blanchedalmond", 255, 235, 205 },
|
||||
{ "blue", 0, 0, 255 },
|
||||
{ "blueviolet", 138, 43, 226 },
|
||||
{ "brown", 165, 42, 42 },
|
||||
{ "burlywood", 222, 184, 135 },
|
||||
{ "cadetblue", 95, 158, 160 },
|
||||
{ "chartreuse", 127, 255, 0 },
|
||||
{ "chocolate", 210, 105, 30 },
|
||||
{ "coral", 255, 127, 80 },
|
||||
{ "cornflowerblue", 100, 149, 237 },
|
||||
{ "cornsilk", 255, 248, 220 },
|
||||
{ "crimson", 220, 20, 60 },
|
||||
{ "cyan", 0, 255, 255 },
|
||||
{ "darkblue", 0, 0, 139 },
|
||||
{ "darkcyan", 0, 139, 139 },
|
||||
{ "darkgoldenrod", 184, 134, 11 },
|
||||
{ "darkgray", 169, 169, 169 },
|
||||
{ "darkgreen", 0, 100, 0 },
|
||||
{ "darkgrey", 169, 169, 169 },
|
||||
{ "darkkhaki", 189, 183, 107 },
|
||||
{ "darkmagenta", 139, 0, 139 },
|
||||
{ "darkolivegreen", 85, 107, 47 },
|
||||
{ "darkorange", 255, 140, 0 },
|
||||
{ "darkorchid", 153, 50, 204 },
|
||||
{ "darkred", 139, 0, 0 },
|
||||
{ "darksalmon", 233, 150, 122 },
|
||||
{ "darkseagreen", 143, 188, 143 },
|
||||
{ "darkslateblue", 72, 61, 139 },
|
||||
{ "darkslategray", 47, 79, 79 },
|
||||
{ "darkslategrey", 47, 79, 79 },
|
||||
{ "darkturquoise", 0, 206, 209 },
|
||||
{ "darkviolet", 148, 0, 211 },
|
||||
{ "deeppink", 255, 20, 147 },
|
||||
{ "deepskyblue", 0, 191, 255 },
|
||||
{ "dimgray", 105, 105, 105 },
|
||||
{ "dimgrey", 105, 105, 105 },
|
||||
{ "dodgerblue", 30, 144, 255 },
|
||||
{ "firebrick", 178, 34, 34 },
|
||||
{ "floralwhite" , 255, 250, 240 },
|
||||
{ "forestgreen", 34, 139, 34 },
|
||||
{ "fuchsia", 255, 0, 255 },
|
||||
{ "gainsboro", 220, 220, 220 },
|
||||
{ "ghostwhite", 248, 248, 255 },
|
||||
{ "gold", 255, 215, 0 },
|
||||
{ "goldenrod", 218, 165, 32 },
|
||||
{ "gray", 128, 128, 128 },
|
||||
{ "green", 0, 128, 0 },
|
||||
{ "greenyellow", 173, 255, 47 },
|
||||
{ "grey", 128, 128, 128 },
|
||||
{ "honeydew", 240, 255, 240 },
|
||||
{ "hotpink", 255, 105, 180 },
|
||||
{ "indianred", 205, 92, 92 },
|
||||
{ "indigo", 75, 0, 130 },
|
||||
{ "ivory", 255, 255, 240 },
|
||||
{ "khaki", 240, 230, 140 },
|
||||
{ "lavender", 230, 230, 250 },
|
||||
{ "lavenderblush", 255, 240, 245 },
|
||||
{ "lawngreen", 124, 252, 0 },
|
||||
{ "lemonchiffon", 255, 250, 205 },
|
||||
{ "lightblue", 173, 216, 230 },
|
||||
{ "lightcoral", 240, 128, 128 },
|
||||
{ "lightcyan", 224, 255, 255 },
|
||||
{ "lightgoldenrodyellow", 250, 250, 210 },
|
||||
{ "lightgray", 211, 211, 211 },
|
||||
{ "lightgreen", 144, 238, 144 },
|
||||
{ "lightgrey", 211, 211, 211 },
|
||||
{ "lightpink", 255, 182, 193 },
|
||||
{ "lightsalmon", 255, 160, 122 },
|
||||
{ "lightseagreen", 32, 178, 170 },
|
||||
{ "lightskyblue", 135, 206, 250 },
|
||||
{ "lightslategray", 119, 136, 153 },
|
||||
{ "lightslategrey", 119, 136, 153 },
|
||||
{ "lightsteelblue", 176, 196, 222 },
|
||||
{ "lightyellow", 255, 255, 224 },
|
||||
{ "lime", 0, 255, 0 },
|
||||
{ "limegreen", 50, 205, 50 },
|
||||
{ "linen", 250, 240, 230 },
|
||||
{ "magenta", 255, 0, 255 },
|
||||
{ "maroon", 128, 0, 0 },
|
||||
{ "mediumaquamarine", 102, 205, 170 },
|
||||
{ "mediumblue", 0, 0, 205 },
|
||||
{ "mediumorchid", 186, 85, 211 },
|
||||
{ "mediumpurple", 147, 112, 219 },
|
||||
{ "mediumseagreen", 60, 179, 113 },
|
||||
{ "mediumslateblue", 123, 104, 238 },
|
||||
{ "mediumspringgreen", 0, 250, 154 },
|
||||
{ "mediumturquoise", 72, 209, 204 },
|
||||
{ "mediumvioletred", 199, 21, 133 },
|
||||
{ "midnightblue", 25, 25, 112 },
|
||||
{ "mintcream", 245, 255, 250 },
|
||||
{ "mistyrose", 255, 228, 225 },
|
||||
{ "moccasin", 255, 228, 181 },
|
||||
{ "navajowhite", 255, 222, 173 },
|
||||
{ "navy", 0, 0, 128 },
|
||||
{ "oldlace", 253, 245, 230 },
|
||||
{ "olive", 128, 128, 0 },
|
||||
{ "olivedrab", 107, 142, 35 },
|
||||
{ "orange", 255, 165, 0 },
|
||||
{ "orangered", 255, 69, 0 },
|
||||
{ "orchid", 218, 112, 214 },
|
||||
{ "palegoldenrod", 238, 232, 170 },
|
||||
{ "palegreen", 152, 251, 152 },
|
||||
{ "paleturquoise", 175, 238, 238 },
|
||||
{ "palevioletred", 219, 112, 147 },
|
||||
{ "papayawhip", 255, 239, 213 },
|
||||
{ "peachpuff", 255, 218, 185 },
|
||||
{ "peru", 205, 133, 63 },
|
||||
{ "pink", 255, 192, 203 },
|
||||
{ "plum", 221, 160, 221 },
|
||||
{ "powderblue", 176, 224, 230 },
|
||||
{ "purple", 128, 0, 128 },
|
||||
{ "red", 255, 0, 0 },
|
||||
{ "rosybrown", 188, 143, 143 },
|
||||
{ "royalblue", 65, 105, 225 },
|
||||
{ "saddlebrown", 139, 69, 19 },
|
||||
{ "salmon", 250, 128, 114 },
|
||||
{ "sandybrown", 244, 164, 96 },
|
||||
{ "seagreen", 46, 139, 87 },
|
||||
{ "seashell", 255, 245, 238 },
|
||||
{ "sienna", 160, 82, 45 },
|
||||
{ "silver", 192, 192, 192 },
|
||||
{ "skyblue", 135, 206, 235 },
|
||||
{ "slateblue", 106, 90, 205 },
|
||||
{ "slategray", 112, 128, 144 },
|
||||
{ "slategrey", 112, 128, 144 },
|
||||
{ "snow", 255, 250, 250 },
|
||||
{ "springgreen", 0, 255, 127 },
|
||||
{ "steelblue", 70, 130, 180 },
|
||||
{ "tan", 210, 180, 140 },
|
||||
{ "teal", 0, 128, 128 },
|
||||
{ "thistle", 216, 191, 216 },
|
||||
{ "tomato", 255, 99, 71 },
|
||||
{ "turquoise", 64, 224, 208 },
|
||||
{ "violet", 238, 130, 238 },
|
||||
{ "wheat", 245, 222, 179 },
|
||||
{ "white", 255, 255, 255 },
|
||||
{ "whitesmoke", 245, 245, 245 },
|
||||
{ "yellow", 255, 255, 0 },
|
||||
{ "yellowgreen", 154, 205, 50 }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* gimp_color_parse_css:
|
||||
* @css: (array length=len): a string describing a color in CSS notation
|
||||
* @len: the length of @css, in bytes. or -1 if @css is nul-terminated
|
||||
*
|
||||
* Attempts to parse a string describing an sRGB color in CSS notation. This can
|
||||
* be either a numerical representation (`rgb(255,0,0)` or `rgb(100%,0%,0%)`)
|
||||
* or a hexadecimal notation as parsed by gimp_color_parse_hex()
|
||||
* (`##ff0000`) or a color name as parsed by gimp_color_parse_name() (`red`).
|
||||
*
|
||||
* Additionally the `rgba()`, `hsl()` and `hsla()` functions are supported too.
|
||||
*
|
||||
* Returns: a newly allocated [class@Gegl.Color] if @css was parsed successfully
|
||||
* %NULL otherwise
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
GeglColor *
|
||||
gimp_color_parse_css (const gchar *css,
|
||||
gint len)
|
||||
{
|
||||
gchar *tmp;
|
||||
GeglColor *color;
|
||||
|
||||
g_return_val_if_fail (css != NULL, FALSE);
|
||||
|
||||
tmp = gimp_color_parse_strip (css, len);
|
||||
|
||||
color = gimp_color_parse_css_internal (tmp);
|
||||
|
||||
g_free (tmp);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
/* Private functions. */
|
||||
|
||||
static GeglColor *
|
||||
gimp_color_parse_name_internal (const gchar *name)
|
||||
{
|
||||
/* GeglColor also has name reading support. It supports HTML 4.01 standard
|
||||
* whereas here we have SVG 1.0 name support. Moreover we support a lot more
|
||||
* colors.
|
||||
*/
|
||||
ColorEntry *entry = bsearch (name, named_colors,
|
||||
G_N_ELEMENTS (named_colors), sizeof (ColorEntry),
|
||||
gimp_color_entry_compare);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
GeglColor *color = gegl_color_new (NULL);
|
||||
|
||||
gegl_color_set_rgba_with_space (color, (gdouble) entry->red / 255.0,
|
||||
(gdouble) entry->green / 255.0, (gdouble) entry->blue / 255.0,
|
||||
1.0, NULL);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GeglColor *
|
||||
gimp_color_parse_hex_internal (const gchar *hex)
|
||||
{
|
||||
GeglColor *color;
|
||||
gint i;
|
||||
gsize len;
|
||||
gdouble val[3];
|
||||
|
||||
if (hex[0] == '#')
|
||||
hex++;
|
||||
|
||||
len = strlen (hex);
|
||||
if (len % 3 || len < 3 || len > 12)
|
||||
return NULL;
|
||||
|
||||
len /= 3;
|
||||
|
||||
for (i = 0; i < 3; i++, hex += len)
|
||||
{
|
||||
if (! gimp_color_parse_hex_component (hex, len, val + i))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
color = gegl_color_new (NULL);
|
||||
gegl_color_set_pixel (color, babl_format ("R'G'B' double"), val);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static GeglColor *
|
||||
gimp_color_parse_css_numeric (const gchar *css)
|
||||
{
|
||||
GeglColor *color;
|
||||
gdouble values[4];
|
||||
gboolean alpha;
|
||||
gboolean hsl;
|
||||
gint i;
|
||||
|
||||
if (css[0] == 'r' && css[1] == 'g' && css[2] == 'b')
|
||||
hsl = FALSE;
|
||||
else if (css[0] == 'h' && css[1] == 's' && css[2] == 'l')
|
||||
hsl = TRUE;
|
||||
else
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
if (css[3] == 'a' && css[4] == '(')
|
||||
alpha = TRUE;
|
||||
else if (css[3] == '(')
|
||||
alpha = FALSE;
|
||||
else
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
css += (alpha ? 5 : 4);
|
||||
|
||||
for (i = 0; i < (alpha ? 4 : 3); i++)
|
||||
{
|
||||
const gchar *end = css;
|
||||
|
||||
while (*end && *end != ',' && *end != '%' && *end != ')')
|
||||
end++;
|
||||
|
||||
if (i == 3 || *end == '%')
|
||||
{
|
||||
values[i] = g_ascii_strtod (css, (gchar **) &end);
|
||||
|
||||
if (errno == ERANGE)
|
||||
return FALSE;
|
||||
|
||||
if (*end == '%')
|
||||
{
|
||||
end++;
|
||||
values[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glong value = strtol (css, (gchar **) &end, 10);
|
||||
|
||||
if (errno == ERANGE)
|
||||
return FALSE;
|
||||
|
||||
if (hsl)
|
||||
values[i] = value / (i == 0 ? 360.0 : 100.0);
|
||||
else
|
||||
values[i] = value / 255.0;
|
||||
}
|
||||
|
||||
/* CSS Color specs indicates:
|
||||
* > Values outside these ranges are not invalid, but are clamped to the
|
||||
* > ranges defined here at parsed-value time.
|
||||
* See: https://drafts.csswg.org/css-color/#rgb-functions
|
||||
* So even though we might hope being able to reach non-sRGB colors when
|
||||
* using the percentage syntax, the spec explicitly forbids it.
|
||||
*/
|
||||
values[i] = CLAMP (values[i], 0.0, 1.0);
|
||||
|
||||
while (*end == ',' || g_ascii_isspace (*end))
|
||||
end++;
|
||||
|
||||
css = end;
|
||||
}
|
||||
|
||||
if (*css != ')')
|
||||
return NULL;
|
||||
|
||||
color = gegl_color_new (NULL);
|
||||
if (hsl)
|
||||
{
|
||||
if (alpha)
|
||||
gegl_color_set_pixel (color, babl_format ("HSLA double"), values);
|
||||
else
|
||||
gegl_color_set_pixel (color, babl_format ("HSL double"), values);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha)
|
||||
gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), values);
|
||||
else
|
||||
gegl_color_set_pixel (color, babl_format ("R'G'B' double"), values);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static GeglColor *
|
||||
gimp_color_parse_css_internal (const gchar *css)
|
||||
{
|
||||
if (css[0] == '#')
|
||||
{
|
||||
return gimp_color_parse_hex_internal (css);
|
||||
}
|
||||
else if (strncmp (css, "rgb(", 4) == 0 ||
|
||||
strncmp (css, "hsl(", 4) == 0)
|
||||
{
|
||||
return gimp_color_parse_css_numeric (css);
|
||||
}
|
||||
else
|
||||
{
|
||||
return gimp_color_parse_name_internal (css);
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_color_parse_strip (const gchar *str,
|
||||
gint len)
|
||||
{
|
||||
gchar *result;
|
||||
|
||||
while (len > 0 && g_ascii_isspace (*str))
|
||||
{
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
while (g_ascii_isspace (*str))
|
||||
str++;
|
||||
|
||||
len = strlen (str);
|
||||
}
|
||||
|
||||
while (len > 0 && g_ascii_isspace (str[len - 1]))
|
||||
len--;
|
||||
|
||||
result = g_malloc (len + 1);
|
||||
|
||||
memcpy (result, str, len);
|
||||
result[len] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_color_entry_compare (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const gchar *name = a;
|
||||
const ColorEntry *entry = b;
|
||||
|
||||
return g_ascii_strcasecmp (name, entry->name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_color_parse_hex_component (const gchar *hex,
|
||||
gint len,
|
||||
gdouble *value)
|
||||
{
|
||||
gint i;
|
||||
guint c = 0;
|
||||
|
||||
for (i = 0; i < len; i++, hex++)
|
||||
{
|
||||
if (!*hex || !g_ascii_isxdigit (*hex))
|
||||
return FALSE;
|
||||
|
||||
c = (c << 4) | g_ascii_xdigit_value (*hex);
|
||||
}
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 1: *value = (gdouble) c / 15.0; break;
|
||||
case 2: *value = (gdouble) c / 255.0; break;
|
||||
case 3: *value = (gdouble) c / 4095.0; break;
|
||||
case 4: *value = (gdouble) c / 65535.0; break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -39,6 +39,10 @@
|
|||
* objects more easily.
|
||||
**/
|
||||
|
||||
|
||||
static const Babl * gimp_babl_format_get_with_alpha (const Babl *format);
|
||||
|
||||
|
||||
/**
|
||||
* gimp_color_set_alpha:
|
||||
* @color: a [class@Gegl.Color]
|
||||
|
@ -79,6 +83,7 @@ gimp_color_set_alpha (GeglColor *color,
|
|||
* Let's assume that since we use an unbounded 32-bit intermediate value
|
||||
* (float), the loss would be acceptable.
|
||||
*/
|
||||
format = gimp_babl_format_get_with_alpha (format);
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
gegl_color_set_pixel (color, format, pixel);
|
||||
}
|
||||
|
@ -138,3 +143,62 @@ gimp_color_is_perceptually_identical (GeglColor *color1,
|
|||
SQR (pixel1[2] - pixel2[2]) <= 1e-4));
|
||||
#undef SQR
|
||||
}
|
||||
|
||||
|
||||
/* Private functions. */
|
||||
|
||||
static const Babl *
|
||||
gimp_babl_format_get_with_alpha (const Babl *format)
|
||||
{
|
||||
const Babl *new_format = NULL;
|
||||
const gchar *new_model = NULL;
|
||||
const gchar *model;
|
||||
const gchar *type;
|
||||
gchar *name;
|
||||
|
||||
if (babl_format_has_alpha (format))
|
||||
return format;
|
||||
|
||||
model = babl_get_name (babl_format_get_model (format));
|
||||
/* Assuming we use Babl formats with same type for all components. */
|
||||
type = babl_get_name (babl_format_get_type (format, 0));
|
||||
|
||||
if (g_strcmp0 (model, "Y") == 0)
|
||||
new_model = "YA";
|
||||
else if (g_strcmp0 (model, "RGB") == 0)
|
||||
new_model = "RGBA";
|
||||
else if (g_strcmp0 (model, "Y'") == 0)
|
||||
new_model = "Y'A";
|
||||
else if (g_strcmp0 (model, "R'G'B'") == 0)
|
||||
new_model = "R'G'B'A";
|
||||
else if (g_strcmp0 (model, "Y~") == 0)
|
||||
new_model = "Y~A";
|
||||
else if (g_strcmp0 (model, "R~G~B~") == 0)
|
||||
new_model = "R~G~B~A";
|
||||
else if (g_strcmp0 (model, "CIE Lab") == 0)
|
||||
new_model = "CIE Lab alpha";
|
||||
else if (g_strcmp0 (model, "CIE xyY") == 0)
|
||||
new_model = "CIE xyY alpha";
|
||||
else if (g_strcmp0 (model, "CIE XYZ") == 0)
|
||||
new_model = "CIE XYZ alpha";
|
||||
else if (g_strcmp0 (model, "CIE Yuv") == 0)
|
||||
new_model = "CIE Yuv alpha";
|
||||
else if (g_strcmp0 (model, "CMYK") == 0)
|
||||
new_model = "CMYKA";
|
||||
else if (g_strcmp0 (model, "cmyk") == 0)
|
||||
new_model = "cmykA";
|
||||
else if (g_strcmp0 (model, "HSL") == 0)
|
||||
new_model = "HSLA";
|
||||
else if (g_strcmp0 (model, "HSV") == 0)
|
||||
new_model = "HSVA";
|
||||
else if (g_strcmp0 (model, "cairo-RGB24") == 0)
|
||||
new_model = "cairo-ARGB32";
|
||||
|
||||
g_return_val_if_fail (new_model != NULL, format);
|
||||
|
||||
name = g_strdup_printf ("%s %s", new_model, type);
|
||||
new_format = babl_format_with_space (name, format);
|
||||
g_free (name);
|
||||
|
||||
return new_format;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ EXPORTS
|
|||
gimp_color_managed_simulation_bpc_changed
|
||||
gimp_color_managed_simulation_intent_changed
|
||||
gimp_color_managed_simulation_profile_changed
|
||||
gimp_color_parse_css
|
||||
gimp_color_profile_get_copyright
|
||||
gimp_color_profile_get_description
|
||||
gimp_color_profile_get_format
|
||||
|
|
|
@ -47,11 +47,14 @@ G_BEGIN_DECLS
|
|||
#define GIMP_VALUE_HOLDS_COLOR(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GEGL_TYPE_COLOR))
|
||||
|
||||
|
||||
void gimp_color_set_alpha (GeglColor *color,
|
||||
gdouble alpha);
|
||||
void gimp_color_set_alpha (GeglColor *color,
|
||||
gdouble alpha);
|
||||
|
||||
gboolean gimp_color_is_perceptually_identical (GeglColor *color1,
|
||||
GeglColor *color2);
|
||||
gboolean gimp_color_is_perceptually_identical (GeglColor *color1,
|
||||
GeglColor *color2);
|
||||
|
||||
GeglColor * gimp_color_parse_css (const gchar *css,
|
||||
gint len);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -5,6 +5,7 @@ libgimpcolor_sources = files(
|
|||
'gimpcairo.c',
|
||||
'gimpcmyk.c',
|
||||
'gimpcolor.c',
|
||||
'gimpcolor-parse.c',
|
||||
'gimpcolormanaged.c',
|
||||
'gimpcolorprofile.c',
|
||||
'gimpcolorspace.c',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue