Commit Graph

1213 Commits

Author SHA1 Message Date
Jehan 75e6f1062e app: fix "Luma Lighten/Darken only" layer modes.
This is a continuation of #5888 as I realized that most layer modes were
fixed with my commit b3fc24268a (and follow-up f40dc40cbc) but at least
2 were still crashing GIMP: "Luma Lighten/Darken only" modes.

There were 2 bugs here:

* The first bug was that when gimp_operation_layer_mode_real_process()
  ran, gimp_operation_layer_mode_prepare() had not been run yet.
  prepare() is called before the process() of GeglOperation, but it
  would seem the process() of GimpOperationLayerMode on the other end
  happens before GeglOperation's prepare() is run. I am absolutely
  unsure if this is expected or not and have a hard time figuring out
  all the details of the C/C++ cohabitation.
  As a solution, I am moving out the fish caching (the needed part
  inside gimp_operation_layer_mode_real_process()) in its own function
  so that I can easily call it separately before inspecting the fishes.

* The second issue was that some blend functions needed more than a
  GeglOperation alone. E.g. blend_function() for luma lighten
  gimp_operation_layer_mode_blend_luma_lighten_only() would call
  gegl_operation_get_source_space() which requires the node to exist.
  Similarly for the Luma darken only mode. So I keep both the node and
  operation around, and when finalizing, I free the node (which in turn
  frees the operation).

Ell > if you are reading our commits, I would really appreciate your
review (or fixes) of my code here! :)
2020-11-10 17:25:34 +01:00
Jehan f40dc40cbc app: fix autotools build.
My previous commit broke the autotools build. Apparently when using
g_object_unref(), some C++ symbol leaked into libapppaint.a archive
library, hence the main binaries (e.g. gimp-2.99) could not be linked
without adding -lstdc++ flag:

> /usr/bin/ld: paint/libapppaint.a(gimppaintcore-loops.o): undefined reference to symbol '__gxx_personality_v0@@CXXABI_1.3'
> /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line

Not exactly sure why using this GLib function in particular caused this,
but let's just try another approach in order not to link the main binary
with C++ standard lib.
Instead let's manage all GeglOperation allocation in gimp-layer-modes.c
by adding a gimp_layer_modes_exit() function and some static array for
storing operation object of each layer mode.
2020-11-10 12:52:01 +01:00
Jehan b3fc24268a Issue #5888: GIMP 2.99.2 crash when using brush in multiply mode.
The GimpOperationLayerMode variable member in DoLayerBlend was not
properly constructed. C++ class constructor can be called by creating
object variables, but with GObject, we have to do it with pointers.
Otherwise here we were only allocating the memory for the struct, but
not actually calling any initialization functions.

Also it would seem that the struct was not initialized at zero, as the
space_fish variable was not NULL when it should (i.e. even with same
composite and blend space), hence composite_to_blend_fish was not NULL
and since the operation was not a valid GeglOperation when entering
gimp_operation_layer_mode_real_process(), we crashed.
Not sure how it went unseen for so long!

So instead let's make the layer_mode class member into a pointer. As
such, I have to properly allocate and free it. This is also why I am
adding a copy constructor which will ref the pointer (otherwise we unref
more than we ref as the default copy constructor would just copy the
pointer).
2020-11-10 01:11:01 +01:00
santouits 6e00a19fd0 Don't compile gimpmarshal source file many times
Also, removes gimpmarshal.h from a source file that didn't need it.
2020-09-13 18:13:29 +03:00
Niels De Graef 878804fb01 Cleanup GObject signal marshallers
* Don't generate our own marshallers if they are available in GLib
  already
* Don't set the c_marshaller parameter in `g_signal_new()` if it's a
  default marshaller provided by GLib. See commit message of commit
  39e4aa3c57 on why this is the case.
2020-04-01 21:20:01 +00:00
Sabri Ünal 48d71bf6ab Issue #4094 - Corrects some tools descriptions
This patch corrects some inconsitent Tool Options Tab Title using tools tooltips.
Scissors > Scissors Select
Heal > Healing
Align > Aligment

(cherry picked from commit a1af934d9d)
2020-03-10 21:39:06 +03:00
Ell 646c804c04 app: fix compositing of layers with masks, outside the mask bounds
In GimpOperationLayerMode, when the op has a mask connected, and
we're processing an area outside the mask bounds, set the op's
opacity to 0, so that the backdrop shows through.  The actual
process() function gets a NULL mask pointer in this case, and so
would composite the layer as if it had no mask, exposing areas that
should be masked out.

Add a GimpOperationLayerMode::parent_process() function, which
subclasses can override instead of GeglOperation::process(), and
make sure to update the GimpOperationLayerMode::opacity field
before calling this function (and, subsequently, before calling
GimpOperationLayerMode::process()).

Clean up the rest of the fields, and adjust the rest of the code.
2020-02-21 22:54:16 +02:00
Ell 6cd3c8bc74 app: increase the maximal airbrush stamp FPS
In the Airbrush tool, increase the maximal stamp FPS from 15 to 60,
and change the corresponding maximal Rate value from 150 to 100.
This technically affects tool presets, but we'll live.
2020-02-13 18:47:03 +02:00
Ell 9fe33702fb Issue #4354 - When using color to fade dynamics and gradient with transparency ...
... brush does not have transparency

In the PAINT_MASK_TO_COMP_MASK paintcore-loops algorithm, used when
painting incrementally, multiply the paint mask values by the paint
opacity.  Previously, the paint opacity was ignored, breaking
various dynamics affecting the opacity.
2020-01-09 22:36:41 +02:00
Sabri Ünal 371f9578cb CID 225808 Arguments in wrong order
Swapped arguments: height is passed to width. width is passed to height.

Please check the function in /app/core/gimpbrush.c at line: 606

void
gimp_brush_transform_size (GimpBrush     *brush,
                           gdouble        scale,
                           gdouble        aspect_ratio,
                           gdouble        angle,
                           gboolean       reflect,
                           gint          *width,
                           gint          *height)

(cherry picked from commit aeadaaeb6c)
2019-10-20 15:27:37 +02:00
Jehan b8d8424ae0 app, libgimp*: (meson) fix all the generated `*-enums.c`.
More of the files were wrong, or at least not absolutely identical to
the files generated by the autotools. I am not doing any code change
other than trying to make both build systems produce identical files
(except for slight differences on 2 files not worth the effort) even
though maybe some things can be improved (especially on the include
list). Maybe to be improved later.

Also fixing 2 of the previously autotools-generated files because of
space typos which should have been committed earlier.

Finally it is to be noted that there is no logics to copy the generated
files back to the source directory in the meson rules. I am not sure
anyway this is really worth it and maybe we should just stop tracking
these generated files eventually.
2019-10-19 22:32:29 +02:00
luzpaz 92cba86ac2 FIxed typos in app/
Found via `codespell`
2019-10-10 19:39:09 +00:00
Ell aa02f1f35c app: fix use of Clone tool with "sample merged" across images
In GimpSourceCore, when "sample merged" is enabled, derive the
source pickable from the source drawable's image according to the
paint-core's show-all flag manually, instead of using
gimp_paint_core_get_image_pickable(), which uses the destination
image, and would therefore only work when the source and
destination images are the same.

In GimpSourceTool, override GimpPaintTool::paint_prepare() to set
the paint-core's show-all flag according to the source display,
rather than the destination display.
2019-10-02 17:14:36 +03:00
Ell 4fc345183b app, meson.build: fix a bunch of warnings in C++ files 2019-09-12 20:04:50 +03:00
Félix Piédallu 65eff6f150 Meson port. 2019-09-11 16:42:04 +02:00
Ell 19c693a937 app: add "show all" support to the Perspective Clone tool
... by adapting GimpPerspectiveClone to handle buffers with
arbitrary extents.  Note that the tool doesn't seem to work well in
"sample merged" mode to begin with, but this is unrelated.
2019-09-06 20:10:31 +03:00
Ell c5bf595fe6 app: add "show all" support to the Clone tool
... by using gimp_paint_core_get_image_pickable() in
GimpSourceCore, and adapting it to handle source buffers with
arbitrary extents.
2019-09-06 20:10:31 +03:00
Ell 84656cb3d4 app: add "show all" support to the Smudge tool
... by using gimp_paint_core_get_image_pickable() in GimpSmude.
2019-09-06 20:10:30 +03:00
Ell 2523808e4a app: add gimp_paint_core_{set_show_all,get_image_pickable}()
GimpPaintCore operates indipendently of a display, and hence needs
to be explictly told when operating in "show all" mode, affecting
the result of paint tools operating in "sample merged" mode.  Add
gimp_paint_core_set_show_all() for that purpose, and call it,
passing the current display's "show all" mode, in GimpPaintTool.
This controls which pickable (the image itself, or its projection)
is used as the sampling source, as per
GimpPaintCore::saved_proj_buffer, and as returned by the new
gimp_paint_core_get_image_pickable() function.
2019-09-06 20:10:30 +03: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 63695b4b21 libgimbase: merge gimpparam.h into gimpparamspecs.h
which means that it's now included normally via gimpbase.h
and not any longer via gimpbasetypes.h which we only did out
of lazyness. A *lot* of files in libgimp* and app/ now need to
2019-07-31 10:16:21 +02:00
Ell fb679f9efa app: guarantee fully-COWed copies in more cases in paint code 2019-07-30 20:32:43 +03:00
Ell 2d80d4d138 app: use gimp_gegl_buffer_dup() everywhere
... instead of gegl_buffer_dup().
2019-07-30 20:32:41 +03:00
Ell ab94251ae9 app: remove gimp_gegl_rectangle_align_to_tile_grid()
... and replace it with gegl_rectangle_align_to_buffer().
2019-07-30 20:32:08 +03:00
Ell a701032b4e app: fix symmetry transform in Clone/Heal tools when brush is cropped
In GimpSourceCore, when applying a symmetry transform to the source
content, combine the transform op with translation to the paint-
buffer coordinates, so that subclasses (namely, GimpClone and
GimpHeal) can use the op to apply the transformation directly from
the source buffer to the paint buffer in a single step.  This is
both more efficient, and avoids incorrect symmetry transforms when
the paint buffer is cropped to the bounds of the drawable.
2019-05-29 05:26:43 -04:00
Ell 117734f45f app: use gimp_symmetry_get_matrix() in GimpInk
... instead of calculating the matrix manually.
2019-05-29 05:26:41 -04:00
Ell 86f4d4d41d app: don't add fg color to history in GimpEraser
Add GimpPaintbrush::get_color_history_color() virtual function,
which should return the color to be added to the color history upon
painting, if any.  The default implementation returns the
foreground color, when not using a pixmap brush or color-from-
gradient.

Override this function in GimpEraser, to return the background
color when the affected drawable has no alpha channel, instead of
overriding GimpPaintCore::paint() for this purpose.  This avoids
erroneously adding both the background and foreground colors to the
history.
2019-05-29 05:26:40 -04:00
Ell 024bc4cd3f Issue #886 - Artifacts symmetry painting with big brushes
In GimpClone and GimpHeal, use gimp_gegl_apply_operation(), instead
of gegl_node_process(), to apply the symmetry transform, which both
performs chunking and avoids aliasing problems.
2019-05-27 11:09:52 -04:00
Ell 39e1a6dfea app: fix Ink tool symmetry transform
... to take tilt into account.
2019-05-27 02:16:30 -04:00
Ell aba4eef916 app: derive GimpEraser from GimpPaintbrush
In GimpPaintbrush, factor out the code responsible for determining
the current dab's paint parameters and content to a new
GimpPaintbrush::get_paint_params() virtual function.

Derive GimpEraser from GimpPaintbrush, instead of directly from
GimpBrushCore, implementing get_paint_params() appropriately.
This allows GimpEraser to reuse the paint-buffer content across
dabs, improving performance.
2019-05-26 14:47:44 -04:00
Ell 3b56bd7a9a app: add symmetry-transform support to the Ink tool
In GimpInk, apply the current symmetry transform, as per
gimp_symmetry_get_transform(), to rendered blobs.
2019-05-26 14:45:40 -04:00
Ell b63af476bd app: use gimp_symmetry_get_transform() in paint code
Use gimp_symmetry_get_transform() instead of
gimp_symmetry_get_operation() throughout the paint code, where
possible.  This allows us to combine the symmetry transform with
the ordinary brush transform, simplifying the code, improving
performance, and avoiding multiple resamplings.  This also fixes
the paint-buffer size when using mandala symmetry with non-round
brushes, avoiding artifacts.
2019-05-26 14:45:39 -04:00
Ell a5962e4049 app: disregard composite space in non-union alpha-only layer modes
In gimp_layer_mode_get_format(), disregard the requested composite
space when selecting the format, if the input layer mode is alpha-
only, and the requested composite mode is not UNION, since, in this
case, the layer mode doesn't combine the layer/backdrop colors, and
rather only modifies the alpha of one of them.  This allows us to
use the preferred format, avoiding gamma conversion.

This particularly improves the performance of the Eraser tool in
perceptual images.
2019-05-24 01:43:20 -04:00
Ell 86a7c053cc app: fix indentation in gimppaintbrush.h 2019-05-15 13:32:59 -04:00
Ell edc99531e6 app: in GimpPaintbrush, reuse existing paint buffer
In GimpPaintbrush, avoid refilling the paint buffer at each dab if
the paint color/pixmap hasn't changed, as gimp_paint_core_paste()
no longer modifies the buffer since the commit before last.

Additionally, fix color-from-gradient dynamics when the image has a
profile.
2019-05-15 10:54:45 -04:00
Ell fcd19a2aeb app: add gimp_brush_core_get_brush_pixmap()
In GimpBrushCore, replace the private
gimp_brush_core_transform_pixmap() function with a public
gimp_brush_core_get_brush_pixmap() function, which, similarly to
gimp_brush_core_get_brush_mask(), returns the transformed brush
pixmap, and can be used by subclasses.
2019-05-15 10:53:13 -04:00
Ell f24bca5156 app: don't modify paint buffer when pasting to canvas
We now have enough machinery in gimppaintcore-loops to avoid
modifying the paint buffer in gimp_paint_core_paste() in the no-
applicator case, by using the same set of algorithms as
gimp_paint_core_replace().  Other than reducing the number of
different code paths we have, this is both more efficient, and
allows us to reuse the paint buffer across dabs, as done in the
following commits.

Implement gimp_paint_core_replace() in terms of
gimp_paint_core_paste().  We keep the two functions separate, since
their implementation is still differnet when using an applicator.

Suppress the paint-buffer-modifying algorithms in
gimppaintcore-loops, but keep them around; using the same logic for
normal painting as we use for REPLACE painting is possible due to
the fact that all our current non-REPLACE modes treat alpha values
and mask values interchangeably.  In the future we might have modes
that distinguish between alpha and mask values, requiring the old
algorithms.
2019-05-15 10:53:12 -04:00
Ell bea1a44672 app: in GimpBrushCore, free old paint buffer before allocating new one
In gimp_brush_core_get_paint_buffer(), when allocating a new paint
buffer, clear the old buffer *before* allocating the new one, to
reduce the amount of simultaneously allocated memory.
2019-05-11 05:14:24 -04:00
Ell 83184d1626 app: add incremental mode to the Dodge/Burn tool
Add an "Incremental" option to the Dodge/Burn tool, which,
similarly to the Paintbrush, Pencil, and Eraser tools, applies the
effect incrementally as the pointer moves.
2019-04-17 10:02:42 -04:00
Ell bb7f61c919 app: use gimp_gegl_buffer_copy() in various places
... instead of gegl_buffer_copy().  The former parallelizes the
format conversion.
2019-03-06 05:59:57 -05:00
Ell 03810861d2 app: in gimppaintcore-loops, improve CanvasBufferIterator algorithm helper-class
In gimppaintcore-loops, fix the CanvasBufferIterator algorithm
helper-class so that it may appear more than twice in the
hierarchy, and integrate it into the normal dispatch-dependency
system, instead of having dependent algorithms inherit it directly.
2019-03-02 16:24:48 -05:00
Ell fb5987fd57 app: in GimpSmudge, avoid copying brush pixmap when flow = 0
In GimpSmudge, avoid copying the brush's dab to the paint buffer
when using a pixmap brush if the flow parameter is 0 -- it has no
effect in this case.
2019-02-24 13:22:22 -05:00
Ell 5b09af4390 app: improve gimp_brush_core_color_area_with_pixmap()
Reimplement gimp_brush_core_color_area_with_pixmap(), which copies
the brush's dab to the paint buffer when using a pixmap brush, in
terms of gimp-gegl-loops.  This simplifies the functions,
parallelizes processing, and transparently handles float brushes.

Replace the "mode" parameter of the function with an "apply_mask"
parameter, which specifies whether to apply the brush's mask to
the dab as part of copying.  Avoid applying the mask in
GimpPaintbrush; previously, we would erroneously apply the mask
twice when using the paintbrush tool: once when copying the
dab to the paint buffer, and again when pasting the paint buffer
to the canvas.

We still apply the mask in GimpSmudge, which results in the same
double-application behavior, however, this might be less practical
to fix.
2019-02-24 13:22:20 -05:00
Ell 7489f0aece app: replace use of deprecated dont-cache/no_cache with cache-policy
Replace the use of the deprecated GeglNode::dont-cache property,
and GeglOperationClass::no_cache field, with GeglNode::cache-policy
and GeglOperationClass::cache_policy, respectively.

See commit gegl@7f24430cda0d8c3eff311868823d445edc2a4e12.
2019-02-21 13:09:45 -05:00
Ell 6fe57a946b app: in gimppaintcore-loops, unsuppress COMBINE_PAINT_MASK_TO_CANVAS_BUFFER algorithm
In gimppaintcore-loops, unsuppress the
COMBINE_PAINT_MASK_TO_CANVAS_BUFFER algorithm (partially
reverts commit b717ead1abd487f663668ac131883dff0ffe4557.)

In gimp_paint_core_paste() it's always used together with
CANVAS_BUFFER_TO_PAINT_BUF_ALPHA, which matches a combined
algorithm, preventing it from being called, however, it can still
be called through gimp_paint_core_replace(), which uses it
together with CANVAS_BUFFER_TO_COMP_MASK, which doesn't have a
combined algorithm.  We can, however, filter out
CANVAS_BUFFER_TO_PAINT_BUF_ALPHA whenver
COMBINE_PAINT_MASK_TO_CANVAS_BUFFER is matched (since the combined
algorithm will be matched beforehand when both algorithms are
included).
2019-02-16 14:19:09 -05:00
Ell e513e9e054 app: in gimppaintcore-loops, in MaskComponents::finalize_step(), chain up 2019-02-16 10:11:00 -05:00
Ell c7d8d9ba2e app: use MASK_COMPONENTS algorithm in gimp_paint_core_{paste,replace}()
Remove the mask_components_onto() gimppaintcore-loops function, and
the GimpPaintCore::comp_buffer member.  Instead, in
gimp_paint_core_paste() and gimp_paint_core_replace(), use the
MASK_COMPONENTS algorithm, added in the previous commit.
2019-02-16 09:56:30 -05:00
Ell 08fa46ea41 app: in gimppaintcore-loops, add MASK_COMPONENTS algorithm
In gimppaintcore-loops, add a new MASK_COMPONENTS algorithm, which
masks the output of compositing into the destination buffer,
according to a component mask.  The algorithm uses the same code as
gimp:mask-comopnents, and can be used as part of a
gimp_paint_core_loops_process() pipeline, instead of using a
separate function.
2019-02-16 09:56:30 -05:00
Ell 858f30a609 app: in gimppaintcore-loops, add [Temp]CompBuffer algorithm helper-classes
In gimppaintcore-loops, add a CompBuffer algorithm helper-class,
which provides access to the output buffer used for compositing,
to be used by the DO_LAYER_BLEND algorithm instead of the
destination buffer.

CompVuffer itself doesn't provide the storage for the buffer; this
is rather the responsibility of the algorithms that use it.  The
TempCompBuffer algorithm helper-class provides temporary storage
for the compositing buffer, and can be used by algorithms that need
a temporary buffer.
2019-02-16 09:56:30 -05:00
Ell b717ead1ab app: in gimppaintcore-loops, mark algorithms as mandatory/suppressed
In gimppaintcore-loops, use {Mandatory,Supressed}AlgorithmDispatch,
added in the previous commit, to mark certain algorithms as always
occuring, or never occuring, in all hierarchies.
2019-02-16 09:56:30 -05:00