libgimpcolor, app: gimp_color_parse_(css|hex|name)() renamed with _substring() suffix.

New functions with the same name as these functions are created, except without
the length argument (i.e. it's equivalent to calling these with -1).

The reason for this is that using strings with a length variant which may be
negative to switch to NUL-terminated strings are not bindable. At least in our
case, when testing in Python, the input string ended up as corrupted garbage and
GObject Introspection docs warns about such interfaces:

> In particular, avoid functions taking a const char * with a signed length that
> can be set to a negative value to let the function compute the string length
> in bytes. These functions are hard to bind, and require manual overrides.

(see: https://gi.readthedocs.io/en/latest/writingbindableapis.html#strings)

So instead, I create a simple version which runs on NUL-terminated strings only
and which is bound, whereas unbinding the generic length-version (making it
C-only, or maybe usable in some other bindings which ignore the (skip)
annotation; apparently some do this).
This commit is contained in:
Jehan 2024-04-20 12:24:52 +02:00
parent d51cde85c1
commit 106d18605a
8 changed files with 81 additions and 22 deletions

View File

@ -504,7 +504,7 @@ svg_parse_gradient_stop_style_prop (SvgStop *stop,
if (strcmp (name, "stop-color") == 0) if (strcmp (name, "stop-color") == 0)
{ {
g_clear_object (&stop->color); g_clear_object (&stop->color);
stop->color = gimp_color_parse_css (value, -1); stop->color = gimp_color_parse_css (value);
} }
else if (strcmp (name, "stop-opacity") == 0) else if (strcmp (name, "stop-opacity") == 0)
{ {

View File

@ -1313,7 +1313,7 @@ gimp_palette_load_css (GimpContext *context,
GeglColor *color; GeglColor *color;
gchar *word = g_match_info_fetch_named (matches, "param"); gchar *word = g_match_info_fetch_named (matches, "param");
color = gimp_color_parse_css (word, -1); color = gimp_color_parse_css (word);
if (color) if (color)
{ {
if (! gimp_palette_find_entry (palette, color, NULL)) if (! gimp_palette_find_entry (palette, color, NULL))

View File

@ -366,7 +366,7 @@ gimp_paned_box_drop_indicator_draw (GtkWidget *widget,
gdouble rgba[4]; gdouble rgba[4];
gsize i; gsize i;
color = gimp_color_parse_hex (DROP_HIGHLIGHT_COLOR, -1); color = gimp_color_parse_hex (DROP_HIGHLIGHT_COLOR);
gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), rgba); gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), rgba);
for (i = 0; i < G_N_ELEMENTS (paned_box->p->dnd_highlights); i++) for (i = 0; i < G_N_ELEMENTS (paned_box->p->dnd_highlights); i++)

View File

@ -207,13 +207,65 @@ static const ColorEntry named_colors[] =
/** /**
* gimp_color_parse_css: * gimp_color_parse_css:
* @css: (type utf8): a string describing a color in CSS notation
*
* 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 [func@color_parse_hex] (`##ff0000`) or
* a color name as parsed by [func@color_parse_css] (`red`).
*
* Additionally the `rgba()`, `hsl()` and `hsla()` functions are supported too.
*
* Returns: (transfer full): a newly allocated [class@Gegl.Color] if @css was
* parsed successfully, %NULL otherwise
**/
GeglColor *
gimp_color_parse_css (const gchar *css)
{
return gimp_color_parse_css_substring (css, -1);
}
/**
* gimp_color_parse_hex:
* @hex: (type utf8): a string describing a color in hexadecimal notation
*
* Attempts to parse a string describing a sRGB color in hexadecimal
* notation (optionally prefixed with a '#').
*
* Returns: (transfer full): a newly allocated color representing @hex.
**/
GeglColor *
gimp_color_parse_hex (const gchar *hex)
{
return gimp_color_parse_hex_substring (hex, -1);
}
/**
* gimp_color_parse_name:
* @name: (type utf8): a color name (in UTF-8 encoding)
*
* Attempts to parse a color name. This function accepts [SVG 1.1 color
* keywords](https://www.w3.org/TR/SVG11/types.html#ColorKeywords).
*
* Returns: (transfer full): a sRGB color as defined in "4.4. Recognized color
* keyword names" list of SVG 1.1 specification, if @name was parsed
* successfully, %NULL otherwise
**/
GeglColor *
gimp_color_parse_name (const gchar *name)
{
return gimp_color_parse_name_substring (name, -1);
}
/**
* gimp_color_parse_css_substring: (skip)
* @css: (array length=len): a string describing a color in CSS notation * @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 * @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 * 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%)`) * be either a numerical representation (`rgb(255,0,0)` or `rgb(100%,0%,0%)`) or
* or a hexadecimal notation as parsed by gimp_color_parse_hex() * a hexadecimal notation as parsed by [func@color_parse_hex] (`##ff0000`) or a
* (`##ff0000`) or a color name as parsed by gimp_color_parse_name() (`red`). * color name as parsed by [func@color_parse_name] (`red`).
* *
* Additionally the `rgba()`, `hsl()` and `hsla()` functions are supported too. * Additionally the `rgba()`, `hsl()` and `hsla()` functions are supported too.
* *
@ -223,8 +275,8 @@ static const ColorEntry named_colors[] =
* Since: 2.2 * Since: 2.2
**/ **/
GeglColor * GeglColor *
gimp_color_parse_css (const gchar *css, gimp_color_parse_css_substring (const gchar *css,
gint len) gint len)
{ {
gchar *tmp; gchar *tmp;
GeglColor *color; GeglColor *color;
@ -244,7 +296,7 @@ gimp_color_parse_css (const gchar *css,
} }
/** /**
* gimp_color_parse_hex: * gimp_color_parse_hex_substring: (skip)
* @hex: (array length=len): a string describing a color in hexadecimal notation * @hex: (array length=len): a string describing a color in hexadecimal notation
* @len: the length of @hex, in bytes. or -1 if @hex is nul-terminated * @len: the length of @hex, in bytes. or -1 if @hex is nul-terminated
* *
@ -258,8 +310,8 @@ gimp_color_parse_css (const gchar *css,
* Since: 2.2 * Since: 2.2
**/ **/
GeglColor * GeglColor *
gimp_color_parse_hex (const gchar *hex, gimp_color_parse_hex_substring (const gchar *hex,
gint len) gint len)
{ {
GeglColor *result; GeglColor *result;
gchar *tmp; gchar *tmp;
@ -276,7 +328,7 @@ gimp_color_parse_hex (const gchar *hex,
} }
/** /**
* gimp_color_parse_name: * gimp_color_parse_name_substring: (skip)
* @name: (array length=len): a color name (in UTF-8 encoding) * @name: (array length=len): a color name (in UTF-8 encoding)
* @len: the length of @name, in bytes. or -1 if @name is nul-terminated * @len: the length of @name, in bytes. or -1 if @name is nul-terminated
* *
@ -290,8 +342,8 @@ gimp_color_parse_hex (const gchar *hex,
* Since: 2.2 * Since: 2.2
**/ **/
GeglColor * GeglColor *
gimp_color_parse_name (const gchar *name, gimp_color_parse_name_substring (const gchar *name,
gint len) gint len)
{ {
gchar *tmp; gchar *tmp;
GeglColor *result; GeglColor *result;

View File

@ -33,8 +33,11 @@ EXPORTS
gimp_color_managed_simulation_intent_changed gimp_color_managed_simulation_intent_changed
gimp_color_managed_simulation_profile_changed gimp_color_managed_simulation_profile_changed
gimp_color_parse_css gimp_color_parse_css
gimp_color_parse_css_substring
gimp_color_parse_hex gimp_color_parse_hex
gimp_color_parse_hex_substring
gimp_color_parse_name gimp_color_parse_name
gimp_color_parse_name_substring
gimp_color_profile_get_copyright gimp_color_profile_get_copyright
gimp_color_profile_get_description gimp_color_profile_get_description
gimp_color_profile_get_format gimp_color_profile_get_format

View File

@ -53,11 +53,15 @@ void gimp_color_set_alpha (GeglColor *color,
gboolean gimp_color_is_perceptually_identical (GeglColor *color1, gboolean gimp_color_is_perceptually_identical (GeglColor *color1,
GeglColor *color2); GeglColor *color2);
GeglColor * gimp_color_parse_css (const gchar *css, GeglColor * gimp_color_parse_css (const gchar *css);
GeglColor * gimp_color_parse_hex (const gchar *hex);
GeglColor * gimp_color_parse_name (const gchar *name);
GeglColor * gimp_color_parse_css_substring (const gchar *css,
gint len); gint len);
GeglColor * gimp_color_parse_hex (const gchar *hex, GeglColor * gimp_color_parse_hex_substring (const gchar *hex,
gint len); gint len);
GeglColor * gimp_color_parse_name (const gchar *name, GeglColor * gimp_color_parse_name_substring (const gchar *name,
gint len); gint len);
gboolean gimp_color_is_out_of_self_gamut (GeglColor *color); gboolean gimp_color_is_out_of_self_gamut (GeglColor *color);

View File

@ -320,8 +320,8 @@ gimp_color_hex_entry_events (GtkWidget *widget,
gsize len = strlen (text); gsize len = strlen (text);
if (len > 0 && if (len > 0 &&
((color = gimp_color_parse_hex (text, len)) || ((color = gimp_color_parse_hex_substring (text, len)) ||
(color = gimp_color_parse_name (text, -1)))) (color = gimp_color_parse_name (text))))
{ {
gimp_color_hex_entry_set_color (entry, color); gimp_color_hex_entry_set_color (entry, color);
g_object_unref (color); g_object_unref (color);
@ -355,7 +355,7 @@ gimp_color_hex_entry_matched (GtkEntryCompletion *completion,
COLUMN_NAME, &name, COLUMN_NAME, &name,
-1); -1);
if ((color = gimp_color_parse_name (name, -1))) if ((color = gimp_color_parse_name (name)))
gimp_color_hex_entry_set_color (entry, color); gimp_color_hex_entry_set_color (entry, color);
g_free (name); g_free (name);

View File

@ -109,7 +109,7 @@ sf_color_arg_set_default_by_name (SFArg *arg,
/* Create a default value for the old-style interface. /* Create a default value for the old-style interface.
*/ */
if (! (color = gimp_color_parse_css (name_of_default, -1))) if (! (color = gimp_color_parse_css (name_of_default)))
{ {
result = FALSE; result = FALSE;
} }
@ -178,5 +178,5 @@ sf_color_get_repr_from_gegl_color (GeglColor *color)
GeglColor * GeglColor *
sf_color_get_color_from_name (gchar *color_name) sf_color_get_color_from_name (gchar *color_name)
{ {
return gimp_color_parse_css (color_name, -1); return gimp_color_parse_css (color_name);
} }