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)
{
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)
{

View File

@ -1313,7 +1313,7 @@ gimp_palette_load_css (GimpContext *context,
GeglColor *color;
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 (! gimp_palette_find_entry (palette, color, NULL))

View File

@ -366,7 +366,7 @@ gimp_paned_box_drop_indicator_draw (GtkWidget *widget,
gdouble rgba[4];
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);
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:
* @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
* @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`).
* 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_name] (`red`).
*
* Additionally the `rgba()`, `hsl()` and `hsla()` functions are supported too.
*
@ -223,8 +275,8 @@ static const ColorEntry named_colors[] =
* Since: 2.2
**/
GeglColor *
gimp_color_parse_css (const gchar *css,
gint len)
gimp_color_parse_css_substring (const gchar *css,
gint len)
{
gchar *tmp;
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
* @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
**/
GeglColor *
gimp_color_parse_hex (const gchar *hex,
gint len)
gimp_color_parse_hex_substring (const gchar *hex,
gint len)
{
GeglColor *result;
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)
* @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
**/
GeglColor *
gimp_color_parse_name (const gchar *name,
gint len)
gimp_color_parse_name_substring (const gchar *name,
gint len)
{
gchar *tmp;
GeglColor *result;

View File

@ -33,8 +33,11 @@ EXPORTS
gimp_color_managed_simulation_intent_changed
gimp_color_managed_simulation_profile_changed
gimp_color_parse_css
gimp_color_parse_css_substring
gimp_color_parse_hex
gimp_color_parse_hex_substring
gimp_color_parse_name
gimp_color_parse_name_substring
gimp_color_profile_get_copyright
gimp_color_profile_get_description
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,
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);
GeglColor * gimp_color_parse_hex (const gchar *hex,
GeglColor * gimp_color_parse_hex_substring (const gchar *hex,
gint len);
GeglColor * gimp_color_parse_name (const gchar *name,
GeglColor * gimp_color_parse_name_substring (const gchar *name,
gint len);
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);
if (len > 0 &&
((color = gimp_color_parse_hex (text, len)) ||
(color = gimp_color_parse_name (text, -1))))
((color = gimp_color_parse_hex_substring (text, len)) ||
(color = gimp_color_parse_name (text))))
{
gimp_color_hex_entry_set_color (entry, color);
g_object_unref (color);
@ -355,7 +355,7 @@ gimp_color_hex_entry_matched (GtkEntryCompletion *completion,
COLUMN_NAME, &name,
-1);
if ((color = gimp_color_parse_name (name, -1)))
if ((color = gimp_color_parse_name (name)))
gimp_color_hex_entry_set_color (entry, color);
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.
*/
if (! (color = gimp_color_parse_css (name_of_default, -1)))
if (! (color = gimp_color_parse_css (name_of_default)))
{
result = FALSE;
}
@ -178,5 +178,5 @@ sf_color_get_repr_from_gegl_color (GeglColor *color)
GeglColor *
sf_color_get_color_from_name (gchar *color_name)
{
return gimp_color_parse_css (color_name, -1);
return gimp_color_parse_css (color_name);
}