Commit Graph

43858 Commits

Author SHA1 Message Date
Jehan b6e6f0b71b libgimp: gimplegacy not introspected anymore.
Also remove several functions which never made it to a GIMP release.
They were really meant as temporary anyway from the start, waiting for
the new API to be usable.
And GimpParam is not boxed anymore. This is made useless by the fact it
is not an introspected type now.
2019-08-03 09:46:56 +02:00
Jehan 58b3ca816a plug-ins: port python-console to new API. 2019-08-03 09:46:52 +02:00
Jehan 6a1df5be31 libgimpwidgets: fix a copy-paste bug in function docs. 2019-08-03 09:38:46 +02:00
Jehan 04598b1522 plug-ins: use new gimp_procedure_add_*_from_property() in Python.
Since GParamSpec are not working fine (cf. pygobject#227), we have this
trick of initializing new arguments or return values with properties.
Use this trick in the palette-to-gradient plug-in.
2019-08-03 09:38:46 +02:00
Jehan 2c4a8c89ed libgimp, app: allow usage of GParamSpecString procedure arguments.
Just consider these as a GimpParamSpecString with default allow_non_utf8
and non_empty values (FALSE).
2019-08-03 09:38:46 +02:00
Jehan 0787510810 libgimp: add gimp_procedure_add_(argument|return_value)_from_property().
This will be used at least for the Python plug-ins. There is currently a
bug preventing to set a GParamSpec in a binded API.
See pygobject#227.

Please don't revert this. At least it allows to use the new GimpPlugIn
API for Python plug-ins. Anyway even with the old API, I had to add ugly
temporary API for the introspection (which I will now remove as they
never made it to release). So we are trading an ugly situation for a
less ugly one.
We can always remove these 2 new functions before release if we find or
implement better solutions before.
2019-08-03 09:38:21 +02:00
Ell 95429ad704 Issue #3723 - Symmetry Painting with random colour isn't symmetrical
In GimpPaintbrush, calculate grad_point in
_gimp_paintbrush_motion() independently of any stroke, and pass
its value down to GimpPaintbrush::get_paint_params() at each
stroke, so that the color is the same for all strokes, even when
using a color/random dynamics.
2019-08-02 22:28:59 +03:00
Michael Natterer 219fa33eb2 libgimp: create the GimpPlugIn much later in gimp_main_internal()
it will soon get some construct properties that are not known earlier.
2019-08-02 20:53:43 +02:00
Michael Natterer a50069e176 libgimp: change the return values of GimpPlugIn::init_procedures()
and ::query_procedures() to a GList* of strings.
2019-08-02 19:10:13 +02:00
Michael Natterer e3374e7d4e libgimp: make gimp_close() static to gimp.c again
Instead of calling _gimp_close() and returning from both the main
plug-in loop variants, simply only return and call gimp_close() from
where both loops return to, at the end of gimp_main_internal().
2019-08-02 18:48:07 +02:00
Øyvind Kolås 05d47f197a build: require babl-0.1.70 2019-08-02 18:44:15 +02:00
Michael Natterer 366047f423 libgimp: move _gimp_read_expect_msg() back to gimp.c
and make it distinguish between old and new plug-in running.
2019-08-02 18:26:52 +02:00
Michael Natterer 856fe16070 libgimp: add _gimp_plug_in_run() and copy the main plug-in loop to GimpPlugIn
Move the legacy loop code to gimplegacy.c. Also remove some more stuff
from gimp.c, old and new are now completely separate apart from one
glitch which wll go next...
2019-08-02 17:05:51 +02:00
Jehan bc7b358802 libgimp, plug-ins: remove n_procedures from (init|query)_procedures().
The way currently implemented plug-ins are, they are already
NULL-terminating the returned arrays. Since a procedure name cannot be
NULL itself by definition, defining the array length by a terminal NULL
is enough. There is no need to also add a n_procedures parameters which
is just one more possible bug source, even more as we were already
expecting the NULL termination by using g_strfreev() to free the memory.

Anyway a length parameter does not bring any advantage since a plug-in
can still "lie" about its array size (just as it can forget to
NULL-terminate it) and when this happens, the plug-in will segfault.
That's it, it's just a plug-in programming error.

Last but not least, some binding seem to have issues with returned array
setting an (out) parameter as the length. In pygobject at least, the
length parameter doesn't disappear and we end up with this ugly
signature:

> In [3]: Gimp.PlugIn.do_query_procedures.__doc__
> Out[3]: 'query_procedures(self) -> list, n_procedures:int'

See bug report pygobject#352.
To avoid this, we should either set both the array and the length as
(out) parameters or just set the returned array as NULL-terminated
(which is the solution I chose).
2019-08-02 13:50:38 +02:00
Jehan 3945701bd6 plug-ins: localization calls must happens inside query().
It's a bit weird because this has to happen during the query() step, but
plug-ins don't have access to this step anymore, apart from
query_procedures(), which then turns out to be badly named.
2019-08-02 12:58:37 +02:00
Jehan ed619d9ebd libgimpbase: add documentations on gimpparasite public functions.
Once again, the "Since:" is the result of a bit of `git log` archeology.
Hopefully it's right (should be according to tags. Still…).
2019-08-02 12:22:25 +02:00
Michael Natterer 1e2efcf95e libgmp: reorder GimpPlugIn's query(), init(), quit()
in plug-in lifecycle order.
2019-08-02 12:05:28 +02:00
Michael Natterer 5f8d0ef27b libgimp: add gimp_plug_in_extension_enable() and _extension_process()
Start copying all the actual wire communication to GimpPlugIn, and
move the legacy versions to gimplegacy.c.

This implies having the entire protocol code twice, but without any
if(PLUG_IN) { plug_in_stuff(); } else { legacy_stuff(); }

At the moment it is a wild mixture of old and new, but when finished
the wire code in gimplegacy.c will be entirely separate from the wire
code in GimpPlugIn, which will make it easy to g_assert() that only
one API is used by a plug-in.
2019-08-02 12:02:20 +02:00
Jehan 19fbb1d9a8 libgimpwidgets: add documentation for many functions and fix...
... an annotation.
s/(transfer-none)/(transfer none)/
For the "Since:" value, I did some git log archeology. Hopefully I got
these right.
2019-08-02 11:46:39 +02:00
Jehan 3a4b17e8b5 libgimpmath: make GimpVector[23] boxed types.
This way, all functions using these types are now introspectable.
2019-08-02 03:47:23 +02:00
Jehan 0411c7ef97 libgimp: fix some annotations. 2019-08-02 03:21:59 +02:00
Jehan 512d2279af libgimp: fix various docs typos or small errors. 2019-08-02 03:03:52 +02:00
Jehan 17667b7ddf plug-ins: start porting palette-to-gradient to new GimpPlugIn API.
Several aspects of the new API are kind of broken in the Python binding,
especially the arguments. So this first version has no arguments at all.
This also means it cannot be installed in "<Palettes>" menu for the time
being. This is work-in-progress and the missing parts will be
uncommented later when we figure out how to fix the problems.
2019-08-02 03:03:47 +02:00
Michael Natterer ed86de48d2 app, libgimpbase: s/author/authors/ here too 2019-08-02 01:39:09 +02:00
Michael Natterer f86279fd1f libgimp: more GimpPlugIn and GimpProcedure docs and annotations
They are now GI-warning-free.
2019-08-02 01:32:16 +02:00
Michael Natterer 0bec2bcdec libgimp: add gimp_procedure_set_menu_label() and _set_documentation()
which replace _set_strings(). Add more docs.
2019-08-02 00:56:00 +02:00
Michael Natterer d1d56f136e libgimp: set a procedure's arguments and return values to defaults
We need this for named parameters, and it's cleaner anyway.
2019-08-02 00:39:22 +02:00
Michael Natterer b511cf34cf libgimp: add gimp_procedure_set_attribution()
Also rename "author" to "authors" and add some docs.
2019-08-02 00:35:17 +02:00
Michael Natterer 53ca87d693 libgimp: cleanup and more docs for GimpProcedure 2019-08-01 23:46:55 +02:00
Michael Natterer 82afcf5c85 plug-ins: help: use gimp_procedure_extension_ready() 2019-08-01 23:46:55 +02:00
Ell eaec9443c3 app: in GimpFilterTool, add "clipping" option
In GimpFilterTool, add a new "clipping" option, which can be either
Adjust or Clip.  This option is controllable for layers, when
there's no selection mask.

When set to Adjust, which is used by default, the filter's output
may extent past the drawable's boundary, and the drawable will be
resized to match the output when committed.
2019-08-02 00:40:01 +03:00
Ell b7f53262fc app: add gimp_drawable_filter_set_clip()
In GimpDrawableFilter, add a new gimp_drawable_filter_set_clip()
function, which controls whether the filter clips the result to the
drawable's boundary, or extends it past it.  The latter is only
possible for layers, when the selection mask is empty.
2019-08-02 00:40:01 +03:00
Ell 89a9cf7e49 app: add "clip" parameter to gimp_drawable_merge_filter()
Add a new "clip" parameter to gimp_drawable_merge_filter().  When
set to FALSE, the function resizes the drawable to the bounding box
of the filter's output, instead of clipping the output to the
drawable's boundary.
2019-08-02 00:40:01 +03:00
Ell 35729ee02a app: in gimp_gegl_apply_cached_operation(), copy cached result *before* rejigging graph
In gimp_gegl_apply_cached_operation(), copy the cached results to
the destination buffer *before* reconnecting the operation node, as
this may cause the cache to be cleared (see commit
gegl@4347255cd9d5031e6757c70fdde5c63539d5f508).
2019-08-02 00:40:01 +03:00
Ell 998f89e3cb app: in gimp:replace, implement GeglOperation::get_bounding_box()
... similarly to gimp:layer-mode, however, assume the destnation
(backdrop) is not included when the layer's opacity is 1, and
there's no mask.
2019-08-02 00:40:01 +03:00
Ell 89c97bcf26 app: in gimp:layer-mode, implement GeglOperation::get_bounding_box()
... to take the layer's composite mode and opacity into account.
2019-08-02 00:40:01 +03:00
Ell 9900fb74f2 app: in gimp:mask-components, implement GeglOperation::get_bounding_box()
... to forward the input/aux bounding box when the component mask
is fully clear/set, respectively.
2019-08-02 00:40:01 +03:00
Ell 332f662cda app: in gimp:compose-crop, fix x/y properties lower bound
... from 0 to G_MININT.
2019-08-02 00:40:01 +03:00
Ell ad1f3d20fb app: calculate bounding box of group layers
In GimpGroupLayer, when recalculating the group's size as a result
of a change to one of the child layers (now including in response
to a child layer's GimpDrawable::bounding-box-changed signal),
calculate the group's bounding box (the bounding box of all its
child layers' bounding boxes) alongside its logical bounds.  Like
in GimpLayer, use the logical bounds as the bounding box if the
group has a mask.

This bounding box is passed to the group's projection, via
GimpGroupLayer's GimpProjectable::get_bounding_box()
implementation, resulting in a buffer whose extent is the same as
the bounding box.
2019-08-02 00:40:01 +03:00
Ell 8ff43942d6 app: add support for projectables with an arbitrary bounding box
In GimpProjectable, replace gimp_projectable_get_size(), which only
returned a width and a height, with
gimp_projectable_get_bounding_box(), which returns a full
rectangle.  This allows projectables to have an arbitrary bounding
box, not limited to a (0, 0) top-left corner.

Adapt GimpProjection, creating a buffer with corresponding extent
to the projectable's bounding box.

Adapt GimpImage and GimpGroupLayer.
2019-08-02 00:40:01 +03:00
Ell 7a05d15f7e app: implement GimpDrawable::get_bounding_box() for GimpLayer
Implement GimpDrawable::get_bounding_box() for GimpLayer, by
returning the bounding box of its source node.  If the layer has a
mask, we simply return its logical boundary, since the layer can't
extend past the mask.
2019-08-02 00:40:01 +03:00
Ell 153cb33eec app: maintain drawable bounding box separately from its logical boundary
Maintain the bounding box of drawables (i.e., the bounds of their
actual rendered content) separately from their logical boundary (as
shown in the UI).

The bounding box is calculated through the new
GimpDrawable::get_bounding_box() virtual function, which has a
corresponding gimp_drawable_get_bounding_box() function; the
default implementation simply returns the drawable's logical
boundary.  The bounding box is specified in drawable coordinates,
i.e., it's not affected by the drawable's offset.

The bounding box is recalculated through
gimp_drawable_update_bounding_box(), which should be called
whenever a change may affect the bounding box (for example, when
setting a new buffer, as done implicitly by GimpDrawable's
::set_buffer() implementation, or when a drawable filter's
properties change, as will be done by GimpDrawableFilter in a
following commit).  When the bounding box changes, the affected
regions of the drawable are updated, and the
GimpDrawable::bounding-box-changed signal is emitted.

When gimp_drawable_update() is called with negative width/height
values, the entire drawable's bounding box is updated, rather than
only its logical boundary.

Likewise, GimpDrawableStack and GimpLayerStack are adapted to use
the bounding box, instead of the logical bounds, when updating the
drawable's area.
2019-08-02 00:40:01 +03:00
Ell 3afdd7c5c2 app: in GimpDrawable::set_buffer(), take bounds rect instead of offset only
In GimpDrawable::set_buffer(), and the corresponding
gimp_drawable_set_buffer_full() function, take a bounds rectangle,
which specifies both the drawable's new offset and its new size,
instead of only taking the new offset.  In
gimp_drawable_real_set_buffer(), set the item size according to the
rect dimensions, instead of the buffer dimensions.  The rect's
width/height may be 0, in which case the buffer's dimensions are
used.

Adapt the rest of the code.

We do this in preparation for maintaining the drawable's bounding
box separately from its logical bounds, allowing the drawable
content to extend beyond its bounds.
2019-08-02 00:40:01 +03:00
Michael Natterer 0601b7f9a8 libgimp: add gimp_procedure_extension_ready()
which must be called by GIMP_EXTENSION procedures when they are ready
to run their temporary procedures. Move gimp_extension_ack() to
gimpobsolete.[ch].
2019-08-01 23:24:49 +02:00
Michael Natterer a841e0fb06 libgimp: add gimp_procedure_set_image_types()
and remove the "image_types" parameter from gimp_procedure_set_strings(),
which is only a bad hack copied from the core procedure class.
2019-08-01 23:09:01 +02:00
Michael Natterer e0a6eb38da libgimp: add run_data and run_data_destroy parameters to procedure_new()
so bindings work properly. Change plug-ins accordingly.
2019-08-01 22:45:49 +02:00
Jehan 71d0251d2c app: do not assume procedures always have a run mode.
This is especially true since procedures are defined by plug-ins,
possibly third-party. So they may not have a first run mode parameter.
Also we don't want plug-ins to generate CRITICALs in the core
application.
Therefore before trying to get and/or set the run mode parameter, always
check that this first parameter exists, and if so, is it a GimpRunMode
enum?

Fixes similar errors:
> GIMP-CRITICAL: gimp_value_array_index: assertion 'index < value_array->n_values' failed

Moreover it also makes sense to allow plug-ins to not have such
parameter. What if you make a plug-in which always work in a single mode
and don't ever plan/want to make it work interactively for instance?

Lastly old Python 2 plug-ins didn't even have a run mode parameter (I
guess our old Python 2 wrapper was getting rid of it?).
2019-08-01 18:27:33 +02:00
Jehan c059839e78 libgimpbase: use g_try_new0() when allocating the parameters.
Basically the number of parameters comes from plug-ins which could write
whatever crap on the wire. I had a case (playing with Python plug-ins)
where GIMP tried to allocate insane amount of parameters. This is bad
as it allows third-party plug-ins to crash GIMP core.

Instead only *try* to allocate, then return as though there were no
parameters if allocation fails. I also print some info on stderr, but
don't output WARNING/CRITICAL (this is not a core error, but a plug-in
error). Fixes:

> GLib-ERROR **: 16:30:23.357: gmem.c:135: failed to allocate 187186442160 bytes
2019-08-01 18:09:14 +02:00
Michael Natterer 0cfaeb7a90 pdb: remove the section docs for the plug-in group
it was duplicated with the GimpPlugIn class section docs.
2019-08-01 16:15:27 +02:00
Jehan 67a0451ac5 libgimp: transfer ownership of @error parameter to...
... gimp_procedure_new_return_values().
When we see how this has been used in help or goat-exercise plug-ins so
far, we clearly see that we expect this function to be used as last call
in a run callback. Well we could save the result, free the error, then
return the result, but it's cumbersome.
So instead let's officially expect gimp_procedure_new_return_values() to
take ownership of the GError (i.e. it will free it in the end).
For this reason, remove the `const`.
2019-08-01 16:04:58 +02:00