1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00
Files
gimp/libgimpbase/gimpparamspecs.c
Jehan dc3e815ff0 app, libgimp*, pdb, plug-ins: rename various public API name s/float/double/.
Several types functions were using the wording "float" historically to
mean double-precision, e.g. the float array type (which was in fact a
double array). Or the scanner function gimp_scanner_parse_float() was in
fact returning a double value. What if we wanted someday to actually add
float (usually this naming means in C the single-precision IEEE 754
floating point representation) support? How would we name this?

Now technically it's not entirely wrong (a double is still a floating
point). So I've been wondering if that is because maybe we never planned
to have float and double precision may be good enough for all usage in a
plug-in API (which doesn't have to be as generic so the higher precision
is enough)? But how can we be sure? Also we already had some functions
using the wording double (e.g. gimp_procedure_add_double_argument()), so
let's just go the safe route and use the accurate wording.

The additional change in PDB is internal, but there too, I was also
finding very confusing that we were naming double-precision float as
'float' type. So I took the opportunity to update this. It doesn't
change any signature.

In fact the whole commit doesn't change any type or code logic, only
naming, except for one bug fix in the middle which I encountered while
renaming: in gimp_scanner_parse_deprecated_color(), I discovered a
hidden bug in scanning (color-hsv*) values, which was mistakenly using a
double type for an array of float.
2024-11-02 15:00:03 +01:00

1212 lines
32 KiB
C

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
* gimpparamspecs.c
*
* 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
* 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
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gio/gio.h>
#include "gimpbase.h"
/*
* GIMP_TYPE_PARAM_OBJECT
*/
static void gimp_param_object_class_init (GimpParamSpecObjectClass *klass);
static void gimp_param_object_init (GimpParamSpecObject *pspec);
static void gimp_param_object_finalize (GParamSpec *pspec);
static void gimp_param_object_value_set_default (GParamSpec *pspec,
GValue *value);
static GParamSpec * gimp_param_spec_object_real_duplicate (GParamSpec *pspec);
static GObject * gimp_param_spec_object_real_get_default (GParamSpec *pspec);
GType
gimp_param_object_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GimpParamSpecObjectClass),
NULL, NULL,
(GClassInitFunc) gimp_param_object_class_init,
NULL, NULL,
sizeof (GimpParamSpecObject),
0,
(GInstanceInitFunc) gimp_param_object_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamObject", &info, G_TYPE_FLAG_ABSTRACT);
}
return type;
}
static void
gimp_param_object_class_init (GimpParamSpecObjectClass *klass)
{
GParamSpecClass *pclass = G_PARAM_SPEC_CLASS (klass);
klass->duplicate = gimp_param_spec_object_real_duplicate;
klass->get_default = gimp_param_spec_object_real_get_default;
pclass->value_type = G_TYPE_OBJECT;
pclass->finalize = gimp_param_object_finalize;
pclass->value_set_default = gimp_param_object_value_set_default;
}
static void
gimp_param_object_init (GimpParamSpecObject *ospec)
{
ospec->_default_value = NULL;
}
static void
gimp_param_object_finalize (GParamSpec *pspec)
{
GimpParamSpecObject *ospec = GIMP_PARAM_SPEC_OBJECT (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (GIMP_TYPE_PARAM_OBJECT));
g_clear_object (&ospec->_default_value);
parent_class->finalize (pspec);
}
static void
gimp_param_object_value_set_default (GParamSpec *pspec,
GValue *value)
{
GObject *default_value;
g_return_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec));
default_value = gimp_param_spec_object_get_default (pspec);
g_value_set_object (value, default_value);
}
static GParamSpec *
gimp_param_spec_object_real_duplicate (GParamSpec *pspec)
{
GimpParamSpecObject *ospec;
GimpParamSpecObject *duplicate;
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec), NULL);
ospec = GIMP_PARAM_SPEC_OBJECT (pspec);
duplicate = g_param_spec_internal (G_TYPE_FROM_INSTANCE (pspec),
pspec->name,
g_param_spec_get_nick (pspec),
g_param_spec_get_blurb (pspec),
pspec->flags);
duplicate->_default_value = ospec->_default_value ? g_object_ref (ospec->_default_value) : NULL;
duplicate->_has_default = ospec->_has_default;
return G_PARAM_SPEC (duplicate);
}
static GObject *
gimp_param_spec_object_real_get_default (GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec), NULL);
g_return_val_if_fail (GIMP_PARAM_SPEC_OBJECT (pspec)->_has_default, NULL);
return GIMP_PARAM_SPEC_OBJECT (pspec)->_default_value;
}
/**
* gimp_param_spec_object_get_default:
* @pspec: a #GObject #GParamSpec
*
* Get the default object value of the param spec.
*
* If the @pspec has been registered with a specific default (which can
* be verified with [func@Gimp.ParamSpecObject.has_default]), it will be
* returned, though some specific subtypes may support returning dynamic
* default (e.g. based on context).
*
* Returns: (transfer none): the default value.
*/
GObject *
gimp_param_spec_object_get_default (GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec), NULL);
return GIMP_PARAM_SPEC_OBJECT_GET_CLASS (pspec)->get_default (pspec);
}
/**
* gimp_param_spec_object_set_default:
* @pspec: a #GObject #GParamSpec
* @default_value: (transfer none) (nullable): a default value.
*
* Set the default object value of the param spec. This will switch the
* `has_default` flag so that [func@Gimp.ParamSpecObject.has_default]
* will now return %TRUE.
*
* A %NULL @default_value still counts as a default (unless the specific
* @pspec does not allow %NULL as a default).
*/
void
gimp_param_spec_object_set_default (GParamSpec *pspec,
GObject *default_value)
{
g_return_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec));
GIMP_PARAM_SPEC_OBJECT (pspec)->_has_default = TRUE;
g_set_object (&GIMP_PARAM_SPEC_OBJECT (pspec)->_default_value, default_value);
}
/**
* gimp_param_spec_object_has_default:
* @pspec: a #GObject #GParamSpec
*
* This function tells whether a default was set, typically with
* [func@Gimp.ParamSpecObject.set_default] or any other way. It
* does not guarantee that the default is an actual object (it may be
* %NULL if valid as a default).
*
* Returns: whether a default value was set.
*/
gboolean
gimp_param_spec_object_has_default (GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec), FALSE);
return GIMP_PARAM_SPEC_OBJECT (pspec)->_has_default;
}
/**
* gimp_param_spec_object_duplicate:
* @pspec: a [struct@Gimp.ParamSpecObject].
*
* This function duplicates @pspec appropriately, depending on the
* accurate spec type.
*
* Returns: (transfer floating): a newly created param spec.
*/
GParamSpec *
gimp_param_spec_object_duplicate (GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_OBJECT (pspec), NULL);
return GIMP_PARAM_SPEC_OBJECT_GET_CLASS (pspec)->duplicate (pspec);
}
/*
* GIMP_TYPE_ARRAY
*/
/**
* gimp_array_new:
* @data: (array length=length):
* @length:
* @static_data:
*/
GimpArray *
gimp_array_new (const guint8 *data,
gsize length,
gboolean static_data)
{
GimpArray *array;
g_return_val_if_fail ((data == NULL && length == 0) ||
(data != NULL && length > 0), NULL);
array = g_slice_new0 (GimpArray);
array->data = static_data ? (guint8 *) data : g_memdup2 (data, length);
array->length = length;
array->static_data = static_data;
return array;
}
GimpArray *
gimp_array_copy (const GimpArray *array)
{
if (array)
return gimp_array_new (array->data, array->length, FALSE);
return NULL;
}
void
gimp_array_free (GimpArray *array)
{
if (array)
{
if (! array->static_data)
g_free (array->data);
g_slice_free (GimpArray, array);
}
}
G_DEFINE_BOXED_TYPE (GimpArray, gimp_array, gimp_array_copy, gimp_array_free)
/*
* GIMP_TYPE_PARAM_ARRAY
*/
static void gimp_param_array_class_init (GParamSpecClass *klass);
static void gimp_param_array_init (GParamSpec *pspec);
static gboolean gimp_param_array_validate (GParamSpec *pspec,
GValue *value);
static gint gimp_param_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
GType
gimp_param_array_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_array_class_init,
NULL, NULL,
sizeof (GParamSpecBoxed),
0,
(GInstanceInitFunc) gimp_param_array_init
};
type = g_type_register_static (G_TYPE_PARAM_BOXED,
"GimpParamArray", &info, 0);
}
return type;
}
static void
gimp_param_array_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_ARRAY;
klass->value_validate = gimp_param_array_validate;
klass->values_cmp = gimp_param_array_values_cmp;
}
static void
gimp_param_array_init (GParamSpec *pspec)
{
}
static gboolean
gimp_param_array_validate (GParamSpec *pspec,
GValue *value)
{
GimpArray *array = value->data[0].v_pointer;
if (array)
{
if ((array->data == NULL && array->length != 0) ||
(array->data != NULL && array->length == 0))
{
g_value_set_boxed (value, NULL);
return TRUE;
}
}
return FALSE;
}
static gint
gimp_param_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GimpArray *array1 = value1->data[0].v_pointer;
GimpArray *array2 = value2->data[0].v_pointer;
/* try to return at least *something*, it's useless anyway... */
if (! array1)
return array2 != NULL ? -1 : 0;
else if (! array2)
return array1 != NULL ? 1 : 0;
else if (array1->length < array2->length)
return -1;
else if (array1->length > array2->length)
return 1;
return 0;
}
/**
* gimp_param_spec_array:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecArray specifying a
* [type@Array] property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer floating): The newly created #GimpParamSpecArray.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpec *array_spec;
array_spec = g_param_spec_internal (GIMP_TYPE_PARAM_ARRAY,
name, nick, blurb, flags);
return array_spec;
}
static const guint8 *
gimp_value_get_array (const GValue *value)
{
GimpArray *array = value->data[0].v_pointer;
if (array)
return array->data;
return NULL;
}
static guint8 *
gimp_value_dup_array (const GValue *value)
{
GimpArray *array = value->data[0].v_pointer;
if (array)
return g_memdup2 (array->data, array->length);
return NULL;
}
static void
gimp_value_set_array (GValue *value,
const guint8 *data,
gsize length)
{
GimpArray *array = gimp_array_new (data, length, FALSE);
g_value_take_boxed (value, array);
}
static void
gimp_value_set_static_array (GValue *value,
const guint8 *data,
gsize length)
{
GimpArray *array = gimp_array_new (data, length, TRUE);
g_value_take_boxed (value, array);
}
static void
gimp_value_take_array (GValue *value,
guint8 *data,
gsize length)
{
GimpArray *array = gimp_array_new (data, length, TRUE);
array->static_data = FALSE;
g_value_take_boxed (value, array);
}
/*
* GIMP_TYPE_INT32_ARRAY
*/
typedef GimpArray GimpInt32Array;
G_DEFINE_BOXED_TYPE (GimpInt32Array, gimp_int32_array, gimp_array_copy, gimp_array_free)
/**
* gimp_int32_array_get_values:
* @array: the #GimpArray representing #int32 values.
* @length: the number of #int32 values in the returned array.
*
* Returns: (array length=length) (transfer none): a C-array of #gint32.
*/
const gint32 *
gimp_int32_array_get_values (GimpArray *array,
gsize *length)
{
g_return_val_if_fail (array->length % sizeof (gint32) == 0, NULL);
if (length)
*length = array->length / sizeof (gint32);
return (const gint32 *) array->data;
}
/**
* gimp_int32_array_set_values:
* @array: the array to modify.
* @values: (array length=length): the C-array.
* @length: the number of #int32 values in @data.
* @static_data: whether @data is a static rather than allocated array.
*/
void
gimp_int32_array_set_values (GimpArray *array,
const gint32 *values,
gsize length,
gboolean static_data)
{
g_return_if_fail ((values == NULL && length == 0) || (values != NULL && length > 0));
if (! array->static_data)
g_free (array->data);
array->length = length * sizeof (gint32);
array->data = static_data ? (guint8 *) values : g_memdup2 (values, array->length);
array->static_data = static_data;
}
/*
* GIMP_TYPE_PARAM_INT32_ARRAY
*/
static void gimp_param_int32_array_class_init (GParamSpecClass *klass);
static void gimp_param_int32_array_init (GParamSpec *pspec);
GType
gimp_param_int32_array_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_int32_array_class_init,
NULL, NULL,
sizeof (GParamSpecBoxed),
0,
(GInstanceInitFunc) gimp_param_int32_array_init
};
type = g_type_register_static (GIMP_TYPE_PARAM_ARRAY,
"GimpParamInt32Array", &info, 0);
}
return type;
}
static void
gimp_param_int32_array_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_INT32_ARRAY;
}
static void
gimp_param_int32_array_init (GParamSpec *pspec)
{
}
/**
* gimp_param_spec_int32_array:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecInt32Array specifying a
* %GIMP_TYPE_INT32_ARRAY property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer floating): The newly created #GimpParamSpecInt32Array.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_int32_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpec *array_spec;
array_spec = g_param_spec_internal (GIMP_TYPE_PARAM_INT32_ARRAY,
name, nick, blurb, flags);
return array_spec;
}
/**
* gimp_value_get_int32_array:
* @value: A valid value of type %GIMP_TYPE_INT32_ARRAY
* @length: the number of returned #int32 elements.
*
* Gets the contents of a %GIMP_TYPE_INT32_ARRAY #GValue
*
* Returns: (transfer none) (array length=length): The contents of @value
*/
const gint32 *
gimp_value_get_int32_array (const GValue *value,
gsize *length)
{
GimpArray *array;
g_return_val_if_fail (GIMP_VALUE_HOLDS_INT32_ARRAY (value), NULL);
array = value->data[0].v_pointer;
g_return_val_if_fail (array->length % sizeof (gint32) == 0, NULL);
if (length)
*length = array->length / sizeof (gint32);
return (const gint32 *) gimp_value_get_array (value);
}
/**
* gimp_value_dup_int32_array:
* @value: A valid value of type %GIMP_TYPE_INT32_ARRAY
* @length: the number of returned #int32 elements.
*
* Gets the contents of a %GIMP_TYPE_INT32_ARRAY #GValue
*
* Returns: (transfer full) (array length=length): The contents of @value
*/
gint32 *
gimp_value_dup_int32_array (const GValue *value,
gsize *length)
{
GimpArray *array;
g_return_val_if_fail (GIMP_VALUE_HOLDS_INT32_ARRAY (value), NULL);
array = value->data[0].v_pointer;
g_return_val_if_fail (array->length % sizeof (gint32) == 0, NULL);
if (length)
*length = array->length / sizeof (gint32);
return (gint32 *) gimp_value_dup_array (value);
}
/**
* gimp_value_set_int32_array:
* @value: A valid value of type %GIMP_TYPE_INT32_ARRAY
* @data: (array length=length): A #gint32 array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data.
*/
void
gimp_value_set_int32_array (GValue *value,
const gint32 *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_INT32_ARRAY (value));
gimp_value_set_array (value, (const guint8 *) data,
length * sizeof (gint32));
}
/**
* gimp_value_set_static_int32_array:
* @value: A valid value of type %GIMP_TYPE_INT32_ARRAY
* @data: (array length=length): A #gint32 array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data, without copying the data.
*/
void
gimp_value_set_static_int32_array (GValue *value,
const gint32 *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_INT32_ARRAY (value));
gimp_value_set_static_array (value, (const guint8 *) data,
length * sizeof (gint32));
}
/**
* gimp_value_take_int32_array:
* @value: A valid value of type %GIMP_TYPE_int32_ARRAY
* @data: (transfer full) (array length=length): A #gint32 array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data, and takes ownership of @data.
*/
void
gimp_value_take_int32_array (GValue *value,
gint32 *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_INT32_ARRAY (value));
gimp_value_take_array (value, (guint8 *) data,
length * sizeof (gint32));
}
/*
* GIMP_TYPE_DOUBLE_ARRAY
*/
typedef GimpArray GimpDoubleArray;
G_DEFINE_BOXED_TYPE (GimpDoubleArray, gimp_double_array, gimp_array_copy, gimp_array_free)
/**
* gimp_double_array_get_values:
* @array: the #GimpArray representing #double values.
* @length: the number of #double values in the returned array.
*
* Returns: (array length=length) (transfer none): a C-array of #gdouble.
*/
const gdouble *
gimp_double_array_get_values (GimpArray *array,
gsize *length)
{
g_return_val_if_fail (array->length % sizeof (gdouble) == 0, NULL);
if (length)
*length = array->length / sizeof (gdouble);
return (const gdouble *) array->data;
}
/**
* gimp_double_array_set_values:
* @array: the array to modify.
* @values: (array length=length): the C-array.
* @length: the number of #double values in @data.
* @static_data: whether @data is a static rather than allocated array.
*/
void
gimp_double_array_set_values (GimpArray *array,
const gdouble *values,
gsize length,
gboolean static_data)
{
g_return_if_fail ((values == NULL && length == 0) || (values != NULL && length > 0));
if (! array->static_data)
g_free (array->data);
array->length = length * sizeof (gdouble);
array->data = static_data ? (guint8 *) values : g_memdup2 (values, array->length);
array->static_data = static_data;
}
/*
* GIMP_TYPE_PARAM_DOUBLE_ARRAY
*/
static void gimp_param_double_array_class_init (GParamSpecClass *klass);
static void gimp_param_double_array_init (GParamSpec *pspec);
GType
gimp_param_double_array_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_double_array_class_init,
NULL, NULL,
sizeof (GParamSpecBoxed),
0,
(GInstanceInitFunc) gimp_param_double_array_init
};
type = g_type_register_static (GIMP_TYPE_PARAM_ARRAY,
"GimpParamDoubleArray", &info, 0);
}
return type;
}
static void
gimp_param_double_array_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_DOUBLE_ARRAY;
}
static void
gimp_param_double_array_init (GParamSpec *pspec)
{
}
/**
* gimp_param_spec_double_array:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecDoubleArray specifying a
* %GIMP_TYPE_DOUBLE_ARRAY property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer floating): The newly created #GimpParamSpecDoubleArray.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_double_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpec *array_spec;
array_spec = g_param_spec_internal (GIMP_TYPE_PARAM_DOUBLE_ARRAY,
name, nick, blurb, flags);
return array_spec;
}
/**
* gimp_value_get_double_array:
* @value: A valid value of type %GIMP_TYPE_DOUBLE_ARRAY
* @length: the number of returned #double elements.
*
* Gets the contents of a %GIMP_TYPE_DOUBLE_ARRAY #GValue
*
* Returns: (transfer none) (array length=length): The contents of @value
*/
const gdouble *
gimp_value_get_double_array (const GValue *value,
gsize *length)
{
GimpArray *array;
g_return_val_if_fail (GIMP_VALUE_HOLDS_DOUBLE_ARRAY (value), NULL);
array = value->data[0].v_pointer;
g_return_val_if_fail (array->length % sizeof (gdouble) == 0, NULL);
if (length)
*length = array->length / sizeof (gdouble);
return (const gdouble *) gimp_value_get_array (value);
}
/**
* gimp_value_dup_double_array:
* @value: A valid value of type %GIMP_TYPE_DOUBLE_ARRAY
* @length: the number of returned #double elements.
*
* Gets the contents of a %GIMP_TYPE_DOUBLE_ARRAY #GValue
*
* Returns: (transfer full) (array length=length): The contents of @value
*/
gdouble *
gimp_value_dup_double_array (const GValue *value,
gsize *length)
{
GimpArray *array;
g_return_val_if_fail (GIMP_VALUE_HOLDS_DOUBLE_ARRAY (value), NULL);
array = value->data[0].v_pointer;
g_return_val_if_fail (array->length % sizeof (gdouble) == 0, NULL);
if (length)
*length = array->length / sizeof (gdouble);
return (gdouble *) gimp_value_dup_array (value);
}
/**
* gimp_value_set_double_array:
* @value: A valid value of type %GIMP_TYPE_DOUBLE_ARRAY
* @data: (array length=length): A #gdouble array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data.
*/
void
gimp_value_set_double_array (GValue *value,
const gdouble *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_DOUBLE_ARRAY (value));
gimp_value_set_array (value, (const guint8 *) data,
length * sizeof (gdouble));
}
/**
* gimp_value_set_static_double_array:
* @value: A valid value of type %GIMP_TYPE_DOUBLE_ARRAY
* @data: (array length=length): A #gdouble array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data, without copying the data.
*/
void
gimp_value_set_static_double_array (GValue *value,
const gdouble *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_DOUBLE_ARRAY (value));
gimp_value_set_static_array (value, (const guint8 *) data,
length * sizeof (gdouble));
}
/**
* gimp_value_take_double_array:
* @value: A valid value of type %GIMP_TYPE_DOUBLE_ARRAY
* @data: (transfer full) (array length=length): A #gdouble array
* @length: The number of elements in @data
*
* Sets the contents of @value to @data, and takes ownership of @data.
*/
void
gimp_value_take_double_array (GValue *value,
gdouble *data,
gsize length)
{
g_return_if_fail (GIMP_VALUE_HOLDS_DOUBLE_ARRAY (value));
gimp_value_take_array (value, (guint8 *) data,
length * sizeof (gdouble));
}
/*
* GIMP_TYPE_COLOR_ARRAY
*/
GType
gimp_color_array_get_type (void)
{
static gsize static_g_define_type_id = 0;
if (g_once_init_enter (&static_g_define_type_id))
{
GType g_define_type_id =
g_boxed_type_register_static (g_intern_static_string ("GimpColorArray"),
(GBoxedCopyFunc) gimp_color_array_copy,
(GBoxedFreeFunc) gimp_color_array_free);
g_once_init_leave (&static_g_define_type_id, g_define_type_id);
}
return static_g_define_type_id;
}
/**
* gimp_color_array_copy:
* @array: an array of colors.
*
* Creates a new #GimpColorArray containing a deep copy of a %NULL-terminated
* array of [class@Gegl.Color].
*
* Returns: (transfer full): a new #GimpColorArray.
**/
GimpColorArray
gimp_color_array_copy (GimpColorArray array)
{
GeglColor **copy;
gint length = gimp_color_array_get_length (array);
copy = g_malloc0 (sizeof (GeglColor *) * (length + 1));
for (gint i = 0; i < length; i++)
copy[i] = gegl_color_duplicate (array[i]);
return copy;
}
/**
* gimp_color_array_free:
* @array: an array of colors.
*
* Frees a %NULL-terminated array of [class@Gegl.Color].
**/
void
gimp_color_array_free (GimpColorArray array)
{
gint i = 0;
while (array[i] != NULL)
g_object_unref (array[i++]);
g_free (array);
}
/**
* gimp_color_array_get_length:
* @array: an array of colors.
*
* Returns: the number of [class@Gegl.Color] in @array.
**/
gint
gimp_color_array_get_length (GimpColorArray array)
{
gint length = 0;
while (array[length] != NULL)
length++;
return length;
}
/*
* GIMP_TYPE_CORE_OBJECT_ARRAY
*/
static GimpCoreObjectArray gimp_core_object_array_copy (GimpCoreObjectArray array);
GType
gimp_core_object_array_get_type (void)
{
static gsize static_g_define_type_id = 0;
if (g_once_init_enter (&static_g_define_type_id))
{
GType g_define_type_id =
g_boxed_type_register_static (g_intern_static_string ("GimpCoreObjectArray"),
(GBoxedCopyFunc) gimp_core_object_array_copy,
(GBoxedFreeFunc) g_free);
g_once_init_leave (&static_g_define_type_id, g_define_type_id);
}
return static_g_define_type_id;
}
/**
* gimp_core_object_array_get_length:
* @array: a %NULL-terminated array of objects.
*
* Returns: the number of [class@GObject.Object] in @array.
**/
gsize
gimp_core_object_array_get_length (GObject **array)
{
gsize length = 0;
while (array && array[length] != NULL)
length++;
return length;
}
/**
* gimp_core_object_array_copy:
* @array: an array of core_objects.
*
* Duplicate a new #GimpCoreObjectArray, which is basically simply a
* %NULL-terminated array of [class@GObject.Object]. Note that you
* should only use this alias type for arrays of core type objects
* internally hold by `libgimp`, such as layers, channels, paths, images
* and so on, because no reference is hold to the element objects.
*
* As a consequence, the copy also makes a shallow copy of the elements.
*
* Returns: (transfer container) (array zero-terminated=1): a new #GimpCoreObjectArray.
**/
static GimpCoreObjectArray
gimp_core_object_array_copy (GimpCoreObjectArray array)
{
GObject **copy;
gsize length = gimp_core_object_array_get_length (array);
copy = g_malloc0 (sizeof (GObject *) * (length + 1));
for (gint i = 0; i < length; i++)
copy[i] = array[i];
return copy;
}
/*
* GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY
*/
static void gimp_param_core_object_array_class_init (GParamSpecClass *klass);
static void gimp_param_core_object_array_init (GParamSpec *pspec);
static gboolean gimp_param_core_object_array_validate (GParamSpec *pspec,
GValue *value);
static gint gimp_param_core_object_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
GType
gimp_param_core_object_array_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_core_object_array_class_init,
NULL, NULL,
sizeof (GimpParamSpecCoreObjectArray),
0,
(GInstanceInitFunc) gimp_param_core_object_array_init
};
type = g_type_register_static (G_TYPE_PARAM_BOXED,
"GimpParamCoreObjectArray", &info, 0);
}
return type;
}
static void
gimp_param_core_object_array_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_CORE_OBJECT_ARRAY;
klass->value_validate = gimp_param_core_object_array_validate;
klass->values_cmp = gimp_param_core_object_array_values_cmp;
}
static void
gimp_param_core_object_array_init (GParamSpec *pspec)
{
}
static gboolean
gimp_param_core_object_array_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecCoreObjectArray *array_spec = GIMP_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec);
GObject **array = value->data[0].v_pointer;
if (array)
{
gsize length = gimp_core_object_array_get_length (array);
gsize i;
if (length == 0)
{
g_value_set_boxed (value, NULL);
return FALSE;
}
for (i = 0; i < length; i++)
{
if (array[i] && ! g_type_is_a (G_OBJECT_TYPE (array[i]), array_spec->object_type))
{
g_value_set_boxed (value, NULL);
return TRUE;
}
}
}
return FALSE;
}
static gint
gimp_param_core_object_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GObject **array1 = value1->data[0].v_pointer;
GObject **array2 = value2->data[0].v_pointer;
/* try to return at least *something*, it's useless anyway... */
if (! array1)
return array2 != NULL ? -1 : 0;
else if (! array2)
return array1 != NULL ? 1 : 0;
else if (gimp_core_object_array_get_length (array1) < gimp_core_object_array_get_length (array2))
return -1;
else if (gimp_core_object_array_get_length (array1) > gimp_core_object_array_get_length (array2))
return 1;
for (gsize i = 0; i < gimp_core_object_array_get_length (array1); i++)
if (array1[0] != array2[0])
return 1;
return 0;
}
/**
* gimp_param_spec_core_object_array:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @object_type: GType of the array's elements.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecCoreObjectArray specifying a
* [type@CoreObjectArray] property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer floating): The newly created #GimpParamSpecCoreObjectArray.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_core_object_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType object_type,
GParamFlags flags)
{
GimpParamSpecCoreObjectArray *array_spec;
g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
array_spec = g_param_spec_internal (GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY,
name, nick, blurb, flags);
g_return_val_if_fail (array_spec, NULL);
array_spec->object_type = object_type;
return G_PARAM_SPEC (array_spec);
}