Commit graph

5595 commits

Author SHA1 Message Date
Jehan
82fbfdf9d4 app: do not stop the measurement when straightening.
Instead just transform the measurement extremities appropriately to
still map to the same points.
To do so, I also added out parameters to gimp_image_resize_to_layers()
so that calling code can get offsets from old origin (as well as new
image dimensions).

(cherry picked from commit d56a8d439e)
2018-06-05 23:36:24 +02:00
Michael Natterer
226367d6cb app: add GimpDataLoaderFactory which loads data from an array of formats
specified by GimpDataLoaderEntry structs. Remove the same code from
GimpDataFactory and make it an abstract base class that only serves as
an interface for actual implementations. Also move around some stuff
in GimpDataFactory and remove virtual functions that were a bad idea
in the first place.

(cherry picked from commit 73da7c9a54)
2018-06-04 14:35:51 +02:00
Michael Natterer
e7ef28ef78 app: make gimp_data_factory_data_foreach() public
...this time without additional shit.

(cherry picked from commit 0b4677ec58)
2018-06-04 14:35:36 +02:00
Michael Natterer
aae538a4e5 app: add "new-func" and "get-standard-func" properties to GimpDataFactory
to make it behave better, and as preparation for further subclassing.

(cherry picked from commit 2ca408d146)
2018-06-04 14:35:18 +02:00
Michael Natterer
3220dc25f9 app: we always need to freeze/thaw around gimp_font_factory_data_init()
so pull it to the parent class. Also remove the "no_data" parameter
from the data_init() virtual function and handle it in
gimp_font_factory_data_init() itself.

(cherry picked from commit d1b9f74c6f)
2018-06-04 02:16:52 +02:00
Michael Natterer
bc0447bc1b app: handle fonts more correctly in gimp_context_deserialize_property()
The "no_data" case for fonts is gimp->no_fonts, not gimp->no_data.

(cherry picked from commit 1d2ff6aa1b)
2018-06-04 02:16:18 +02:00
Michael Natterer
7764f661d9 app: make gimp_font_get_standard() return a GimpData
like all other GimpData sublasses.

(cherry picked from commit 40b95227af)
2018-06-03 22:50:52 +02:00
Michael Natterer
78aac439d4 app: don't leak the identifier if gimp_data_make_internal() is called again
(cherry picked from commit f23958407c)
2018-06-03 22:50:38 +02:00
Michael Natterer
5401066631 app: move the GimpAsyncSet and the waiting code to GimpDataFactory
it's potentially useful for all data factories.

(cherry picked from commit c563659ed8)
2018-06-03 22:50:20 +02:00
Michael Natterer
12f6a06070 app: add gimp_data_factory_get_data_path[_writable]()
which return GLists of GFiles. Use the new API in GimpDataFactory's
default implementations.

(cherry picked from commit 68cf2641f8)
2018-06-03 20:48:46 +02:00
Michael Natterer
a8657b057d app: remove all old font management code, switch to GimpFontFactory[View]
Biggest change in this commit is reordering stuff in GimpContext
because GimpFont is now a first class citizen.

(cherry picked from commit e88fb8e9c7)
2018-06-03 20:48:34 +02:00
Michael Natterer
0c04d3784b app: make GimpDataFactory properly derivable
Virtualize a lot of functions and move their code into the default
implementation. Also connect to changes of the "path" property and
reload data automatically when the path changes. Add "wait" method
which is by default empty but is to be implemented by fonts.

(cherry picked from commit 01e4104236)
2018-06-03 20:47:35 +02:00
Ell
65f1895d4d app: strengthen gimp_async_set_{wait,cancel}()
Make sure gimp_async_set_wait() and gimp_async_set_cancel() work
correctly, even if the set changes in nontrivial ways as a result
of waiting-on/canceling individual operations.  This is purely
theoretic right now, but why not.

(cherry picked from commit ec5f4d03fa)
2018-06-03 10:05:10 -04:00
Michael Natterer
52e3eb32f3 Use g_set_object() in a lot of places, and splrinkle some g_clear_object()
This is mostly core code which we want to keep in sync with master as
long as possible, so I picked this one even though not strictly
neccessary.

(cherry picked from commit 1b7d63cce9)
2018-06-01 13:14:47 +02:00
Ell
476742b93d app: more cleanup
(cherry picked from commit e806a92c49)
2018-05-30 03:02:05 -04:00
Ell
b16ea49ca1 app: code cleanup in previous commits
(cherry picked from commit c27316093e)
2018-05-30 02:23:03 -04:00
Michael Natterer
93c337896c Issue #1520 - GIMP 2.10 Crashes when trying to convert 8bit colour...
...mode image to 1 bit.

Don't try to remove unused colors from the mono black/white palette,

(cherry picked from commit 0ff95b66b7)
2018-05-30 02:19:39 +02:00
Ell
4527390cd6 app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function.  The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime.  The default implementation simply
prints the message to STDERR.

Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog.  Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object.  Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 16:07:48 -04:00
Ell
953ee1dea5 app: use GimpAsyncSet for keeping track of font loading
Replace the boolean fonts_loading member of Gimp with
fonts_async_set, which is a GimpAsyncSet object.  This allows us
to easily respond to the completion of font loading and reloading,
as will be done in the next commits.

Additionally, move the call to FcConfigSetCurrent(), used to
activate the loaded font configuration, from the async thread to
the main thread, just to be on the safe side, and avoid calling
FcInitReinitialize() in gimp_fonts_reset() if font loading is still
in progress, which is unsafe.
2018-05-29 16:07:48 -04:00
Ell
67c8b00595 app: fix indentation in core-types.h 2018-05-29 16:07:48 -04:00
Ell
8fae111509 app: add GimpAsyncSet
GimpAsyncSet represents a dynamic set of running GimpAsync objects.
The objects are automatically removed from the set once they're
synced.

GimpAsyncSet implements the GimpWaitable and GimpCancelable
interfaces, allowing the entire set to be waited-on or canceled.

Additionally, GimpAsyncSet provides an "empty" property, which
indicates whether the set is empty or not.  This allows responding
to the completion of all the GimpAsync objects through the set's
"notify::empty" signal, or drive UI changes through property
bindings.
2018-05-29 16:07:48 -04:00
Ell
5c6ca1f16e app: add GimpTriviallyCancelableWaitable
GimpTriviallyCancelableWaitable is a proxy object for another
GimpWaitable object, implementing both the GimpWaitable interface
and the GimpCancelable interface.  While waiting on the proxy
simply waits on the underlying waitable, canceling the proxy
doesn't affect the underlying waitable, even if it implements
the GimpCancelable interface as well, but rather causes subsequent
wait operations on the proxy to successfully complete immediately.

This essentially causes cancelation to abort only the wait, rather
than the underlying operation.
2018-05-29 16:07:48 -04:00
Ell
7660891d8c app: add GimpUncancelableWaitable
GimpUncancelableWaitable is a simple proxy object for another
GimpWaitable object, implementing only the GimpWaitable interface.
Its main purpose is to mask away the cancelability of an object
implementing both GimpWaitable and GimpCancelable.
2018-05-29 16:07:48 -04:00
Ell
7740f0f830 app: implement GimpWaitable::try_wait() in GimpAsync 2018-05-29 16:07:48 -04:00
Ell
04a7b2c53a app: add GimpWaitable::try_wait() vfunc
... which should never block, but rather return TRUE or FALSE
immediately, depending on whether or not the waitable is ready.
2018-05-29 16:07:48 -04:00
Ell
85a1b1ece7 app: lower thread priority of independent async operations
In gimp_parallel_run_async(), lower the priority of threads
executing independent async operations.  Independent operations
are generally potentially long-standing background tasks, which we
don't want to bog down the rest of the program.

This is currently only implemented on Linux and Windows.
2018-05-29 16:07:48 -04:00
Ell
1dff8d40c1 app: fix gimp_parallel_run_async() cancelation
In gimp_parallel_run_async(), when aborting a GimpAsync operation
in reponse to its "cancel" signal, properly clean up internal data
attached to the object, to avoid use-after-free if the signal is
emitted again.

(cherry picked from commit 3fa4c01bcf)
2018-05-27 13:59:42 -04:00
Ell
ddc9daceca app: add "independent" parameter to gimp_parallel_run_async()
Add a boolean "independent" parameter to gimp_parallel_run_async().
When FALSE, the passed function is run in the shared async thread
pool; when TRUE, the passed function is run in an independent
thread.

Generally, async operations should run in the async pool, however,
it might be desirable to run long-standing operations, especially
ones that can't be canceled, in independent threads.  This avoids
stalling quicker operations, and shutdown.

Adapt the rest of the code for the change.  In particular,
initialize the font cache in an independent thread.

(cherry picked from commit ad8add6808)
2018-05-27 13:18:56 -04:00
Ell
3ae1eec240 app: abort canceled pending operations in gimp_parallel_run_async()
In gimp_parallel_run_async(), connect to the returned GimpAsync's
"cancel" signal, and abort the operation in response if it's still
enqueued, i.e., if its execution hasn't started yet.

(cherry picked from commit 3958ffbe50)
2018-05-27 13:18:56 -04:00
Ell
fd1e5883f8 app: implement GimpWaitable and GimpCancelable in GimpAsync
Have GimpAsync implement the GimpWaitable and GimpCancelable
interfaces, added in the previous two commits, instead of providing
its own public version of the corresponding functions.

Add gimp_async_cancel_and_wait() as a convenience function for both
canceling an async operation, and waiting for it to complete.

Adapt the rest of the code to the change.

(cherry picked from commit e2c56ef407)
2018-05-27 13:18:56 -04:00
Ell
6f8892dc2d app: add GimpCancelable interface
... which provides a method for canceling an operation managed by
an object.

(cherry picked from commit 722f92d011)
2018-05-27 13:18:56 -04:00
Ell
028a33cf8a app: add GimpWaitable interface
... which provides methods for waiting on an object.

(cherry picked from commit 0fe066890e)
2018-05-27 13:18:56 -04:00
Ell
40a9736bbf app: port all interfaces to G_DEFINE_INTERFACE()
... instead of calling g_type_register_static() ourselves.

(cherry picked from commit cdd96059f7)
2018-05-27 05:56:57 -04:00
Ell
c820764d4f app: code cleanup in GimpAsync
(cherry picked from commit 770634f84e)
2018-05-27 05:56:57 -04:00
Jehan
ce5821639e app: output proper info message while fonts are loading.
To this effect, I add a variable to differentiate the "no-fonts on the
system" case from "fonts still loading".

(cherry picked from commit cfaa3103e7)
2018-05-27 03:45:07 +02:00
Jehan
89c829a242 Issue #1211: Load fonts in background after startup.
Fonts should not be blocking startup as this provides a very bad
experience when people have a lot of fonts. This was experienced even
more on Windows where loading time are often excessively long.
We were already running font loading in a thread, yet were still
blocking startup (thread was only so that the loading status GUI could
get updated as a feedback). Now we will only start loading and proceed
directly to next steps.
While fonts are not loaded, the text tool will not be usable, yet all
other activities can be performed.

(cherry picked from commit 2484dec7d5)
2018-05-27 02:36:39 +02:00
Ell
2d19f29200 app: various GimpAsync improvements
Improve the formalism of a GimpAsync object being "sycned"
(previously referred to as the main thread being "synced" with the
async thread), by both providing a gimp_async_is_synced() function,
separate from gimp_async_is_stopped(), and by improving the type
and function descriptions.

Make sure all previously added callbacks have been called after a
call to gimp_async_wait[_until](), even if these functions are
called from within a callback.

(cherry picked from commit a901c3c1f4)
2018-05-26 14:22:32 -04:00
Ell
c96c6802e8 app: add gimp_async_remove_callback()
... which removes a callback previously added through
gimp_async_add_callback().

(cherry picked from commit 85f67e196c)
2018-05-26 14:22:32 -04:00
Ell
89e9c8d9b3 app: add gimp_async_wait_until()
... which is similar to gimp_async_wait(), taking an 'end_time'
parameter, controlling how long to wait for the async operation to
complete.

(cherry picked from commit 68c57548fd)
2018-05-26 11:33:16 -04:00
Ell
448fa97b85 app: fix progress text when applying shaped gradient through PDB
In gimp_drawable_gradient(), pass the undo description ("Gradient")
to gimp_gegl_apply_operation(), so that its displayed as the
progress text while rendering the gradient, even when applying a
shaped gradient, in which case we end the progress after
calculating the distance map, causing the progress text be NULL
during rendering unless explicitly set.

(cherry picked from commit deee2f14f5)
2018-05-25 12:44:10 -04:00
Ell
b67c1e33f1 app: use gimp_gegl_buffer_copy() all over the place
Replace all uses of gegl_buffer_copy() in app/ with
gimp_gegl_buffer_copy(), added in the previous commit.

(cherry picked from commit 08ff2ac8c8)
2018-05-25 08:20:56 -04:00
Ell
25490b0251 app: implement GimpPickable::get_pixel_average() in various classes
Implement GimpPickable::get_pixel_average(), added in the previous
commit, in GimpDrawable, GimpImage, and GimpProjection, using
gimp_gegl_average_color(), added in the commit before last.  This
is significantly faster than the default implementation.
2018-05-18 15:07:32 -04:00
Ell
b98a04aadc app: add GimpPickable::get_pixel_average() vfunc
... which calculates the average color of the pickable over a given
area.  Use this function in gimp_pickable_pick_color() when
sample_average is TRUE, and provide a default implementation which
calculates the average color using GimpPickable::get_pixel_at(), as
gimp_pickable_pick_color() did before.

The default implementation is rather slow; classes that implement
the GimpPickable interface can provide a faster specialized version
(see the next commit).
2018-05-18 15:07:32 -04:00
Michael Natterer
2f629072f1 Bug 787919 - Tool options are lost when switching device
GimpDeviceInfo is the only way to store per-device settings like
color, brush etc. It used to be derived from GimpContext and therefore
limited to the context's properties, causing everything else (all
tool-individual options) to be lost on device change.

Derive it from GimpToolPreset instead, so it's capable of storing
arbitrary tool options.

Adapt things to the new class hierarchy and add a bunch of signal
handlers that make sure the active device's GimpDeviceInfo is updated
properly when the tool changes. Also change device switching
accordingly.

Change GimpDeviceStatus to only show the stuff that is relevant to
each device's tool.

And various small changes to make things work properly...
2018-05-16 02:09:19 +02:00
Michael Natterer
d6e0ca5054 Bug 796090 - (wrong) true-color preview of GEGL filter ops, ...
...like gaussian blur in indexed mode

In GimpDrawable's source node, after the filter stack, insert a node
that converts the pixels back to the drawable's format if the drawable
is indexed.
2018-05-16 02:09:19 +02:00
Ell
5c7064fb9f app: make gimp-atomic parameters volatile 2018-05-15 12:58:38 -04:00
Ell
03141fc30a app: don't use mask sampler in gimp_pickable_contiguous_region_by_seed()
In gimp_pickable_contiguous_region_by_seed(), use gegl_buffer_get()
to sample the mask buffer, instead of using a sampler.  The sampler
is created at the beginning of the operation, and is subsequently
used after modifying the mask buffer, which should be avoided,
since the sampler may return outdated cached data.
2018-05-14 03:12:40 -04:00
Ell
a6bee79e0d app: in gimp_pickable_contiguous_region_by_seed(), use sampler object ...
... instead of gegl_buffer_sample()

Ditto.
2018-05-13 19:40:46 -04:00
Ell
3c95928031 app: in GimpIScissorsTool, use sampler object ...
... instead of gegl_buffer_sample()

Ditto.
2018-05-13 19:40:46 -04:00
Ell
b296496a65 app: in gimp_atomic_slist_pop_head(), don't warn on empty list
Allow trying to pop the head of an empty GSList, and just return
NULL.
2018-05-13 15:33:15 -04:00
Ell
5ed79b65bb app: in GimpHistogram, parallelize histogram calculation
Use gimp_parallel_distribute_area() to parallelize the histogram
calculation, which seems to scale very well.
2018-05-13 15:21:28 -04:00
Ell
398474ff58 app: add gimp-atomic
... which provides a set of higher-level lock-free atomic
operations.

Currently, the only two operations are
gimp_atomic_slist_push_head() and gimp_atomic_slist_pop_head(),
which atomically push/pop the first element of a GSList.
2018-05-13 15:21:28 -04:00
Ell
16a24ff081 app: various GimpAsync improvements
Code cleanup.

Improve function descriptions.

Improve function precondition checks.

Make sure the main thread is properly synced with the async thread
before calling the completion callbacks in the idle function.

Guarantee that all callbacks are called in FIFO order, even
callbacks added during the execution of other callbacks.
2018-05-13 15:21:28 -04:00
Ell
4c767b4f03 app: fix gimp-parallel shutdown
Some leftover from an earlier version.  Caused gimp_parallel_exit()
to hang, although we could only notice that in GIMP_UNSTABLE
builds.
2018-05-13 11:55:16 -04:00
luz.paz
69b2e84924 Source and trivial typos
Found via `codespell` and `grep`
2018-05-12 23:44:47 +02:00
Ell
d5b0b08431 app: cancel async histogram calculation in gimp_histogram_clear_values()
Cancel any on-going asynchronous histogram calculation, started
through gimp_histogram_calculate_async(), upon calling
gimp_histogram_clear_values().
2018-05-12 09:29:11 -04:00
Ell
729240db34 app: improve GimpAsync description 2018-05-12 09:29:11 -04:00
Ell
1923fa8b44 app: add gimp_drawable_calculate_histogram_async()
... which is similar to gimp_drawable_calculate_histogram(),
calculating the histogram asynchronously on a separate thread.

Note that when calculating the histogram of the drawable's source
node, the node is rendered synchronously on the main thread (if
necessary), and the histogram of the result is calculated
asynchronously on a separate thread.
2018-05-11 14:01:42 -04:00
Ell
9ea560d4a9 app: add gimp_histogram_calculate_async()
... which is similar to gimp_histogram_calculate(), calculating the
histogram asynchronously on a separate thread.
2018-05-11 14:01:42 -04:00
Ell
1b646804ea app: add gimp_parallel_run_async()
... which runs a user-provided function asynchronously, returning a
corresponding GimpAsync object.  This can be used to execute code
off the main thread, using the GimpAsync object to synchronize as
necessary.

Note that while the code allows for running multiple asynchronous
functions in parallel in a thread pool, we currently limit the pool
to a single thread, queueing overlapping async function, since we
have no use for parallel asynchronous functions at the moment.
2018-05-11 14:01:42 -04:00
Ell
e1d15feff7 app: add GimpAsync
GimpAsync represents an asynchronous task, running without blocking
the main thread.  It provides functions that allow waiting for
completion, queueing completion callbacks, and requesting
calcelation.  See the code for more details.

The interface and the implementation are intentionally limited for
the time being, to keep things simple, and are geared toward
asynchronous tasks executed on a separate thread (see the next
commit).  The public interface is relatively general, however, and
we may extend the implementation to support other kinds of tasks at
some point, who knows...
2018-05-11 14:01:42 -04:00
Jehan
66db143502 Bug 796014 - Cannot open some older .xcf files made with 2.8.22 in 2.10.
To avoid an infinite loop, gimp_item_linked_is_locked() was temporarily
unlinking items before calling gimp_item_is_position_locked(). This
worked only based on gimp_item_real_is_position_locked() code which
called gimp_item_linked_is_locked() only when it was linked. It did not
take into account the fact that it was an abstract method which could
have other implementations. In particular the group layer implementation
would call in turn gimp_item_is_position_locked() on each child layer.

Basically temporarily unsetting the link was anyway a very ugly hack.
The point is simply that we are only interested by the value of the
`lock_position` flag for this item, without further "intelligence". For
this, use gimp_item_get_lock_position() instead.
2018-05-11 18:04:31 +02:00
Ell
bc09c71818 Bug 795909 - Multiple images opened with floating selection ...
... closing one of them crashes GIMP

GimpSymmetry keeps a strong reference to the drawable passed to
gimp_symmetry_set_origin() until the next call to set_origin(), or
until it's destroyed.  This can unnecessarily extend the lifetime
of the drawable.  In particular, it can extend the lifetime of a
floating selection past the destruction of the image mask, during
image destruction, which results in a NULL mask pointer in
gimp_layer_invalidate_boundary(), called when detaching the
floating selection as part of its destructor.

Add gimp_symmetry_clear_origin(), which clears the origin set using
gimp_symmetry_set_origin(), dropping the reference to the drawable,
and call it in gimp_paint_core_paint() after painting.  This avoids
extending the lifetime of the drawable, and fixes the bug.
2018-05-08 10:22:46 -04:00
Ell
084cbc3102 app: fix pass-through group histograms (proactively)
In gimp_drawable_calculate_histogram(), when including the
drawable's filters in the histogram (i.e., when calculating the
histogram of the drawable's source node, rather than its buffer),
if the drawable is a projectable, call
gimp_projectable_{begin,end}_render() before/after calculating the
histogram, respectively.  This is necessary for pass-through
groups, whose {begin,end}_render() functions disconnect/reconnect
the group's backdrop from/to the group's layer stack.  If we fail
to do this, the backdrop is erroneously included in the histogram.

Note that currently layer groups can't have any filters applied to
them, so we never run into this situation, but once we have non-
destructive editing we probably will.
2018-05-08 03:43:49 -04:00
Ell
f3febfe343 Bug 795866 - Transparent gradient on transparent layer ...
... drifts/sharpens when applying additional gradients

In GimpDrawableFilter, don't use gegl:over for operations without
an input pad, since this only works if the filter's mode is
REPLACE.  If the filter's mode is different, in particular, if it's
NORMAL, we end up compositing the operation's output against the
input twice: once in gegl:over, and again in the filter's
applicator.  Notably, this happens for the gradient tool.

Instead, revert commit 5b80d3d3be
(with some additions to avoid constructing unnecessary nodes when
the operation has no input) and simply change the applicator's mode
to NORMAL if the oepration doesn't have an input, and the filter's
mode is REPLACE.
2018-05-07 14:35:40 -04:00
Michael Natterer
29cf157f69 app: add +gimp_container_freeze_count() which returns the freeze_count 2018-05-07 10:25:45 +02:00
Jehan
33a92e2447 app: get rid of gimp_get_backtrace().
It is not used anywhere anymore and can be replaced by the more powerful
gimp_stack_trace_print() (which can also allocate a string containing
the backtrace, hence is a proper replacement call).
2018-05-05 20:18:25 +02:00
Michael Natterer
62279047b1 Bug 795763 - Update gimp.org links to https://
Update links to https:// in "About". the "Help" menu, and several
user-visible error messages.
2018-05-03 00:27:29 +02:00
Jehan
e796e3a50a app: popup error at startup when some fonts fail to load.
As proposed on IRC. This will allow people to debug their fonts (for
instance when there are permission issues or whatnot) by knowing the
list of problematic fonts in an error dialog at startup (and not only on
terminal).
2018-05-01 03:25:58 +02:00
Jehan
f6b586237c app: identifier of MyPaint brush GimpData using ${mypaint_brushes_dir}.
Absolute paths not to be used in $XDG_CONFIG/GIMP/{version}/tags.xml.
These are actually only an identifier, and not used as a path at all
anyway. Moreover MyPaint brushes even generate checksum (which allows
to remap the GimpData appropriately even if the paths are changing).
But anyway it's better not to have absolute paths when we can prevent
so.
2018-04-29 00:40:26 +02:00
Michael Natterer
a007ad4b98 app: remove debug output from gimp_image_create_color_transforms() 2018-04-28 16:42:01 +02:00
luz.paz
4a77ff2d3d Bug 795557 - Misc. typo fixes in source, comments and doxygen (pt3)
Found via `codespell` and grep.
2018-04-25 23:49:06 +02:00
Ell
6e87ceb896 app: use half the cache size for symmetric conical gradients
Symmetric conical gradients only span half a revolution (unlike
assymetric ones, which span an entire revolution), and therefore
require only half the cache size.
2018-04-25 17:42:52 -04:00
Ell
d6a7302678 app: crop GimpDrawableFilter output
Add a crop node to the GimpDrawableFilter graph, applied after the
filter's output, cropping the output to the filter area (the same
area used for the input crop node).  If we fail to do this, filters
whose op's bounding box is bigger than the input region can affect
areas outside the drawable, when the filter is rendered as part of
the image graph (in contrast to being comitted).  This is
particularly relevant to source ops, that may have an infinite
bounding box.

We probably didn't notice this until now, since before the recent
GimpProjection update-area changes, only the drawable's area would
get invalidated in response to changes in the filter, so regions
outside the drawable wouldn't normally get rendered.  However, this
could still have been triggered by causing regions outside the
drawable to be invalidated by other means.
2018-04-25 15:58:24 -04:00
Ell
5970046e25 app: use gradient cache for conical gradients
Add gimp_drawable_gradient_adjust_coords(), which adjusts the
gradient segment coords according to the gradient type, so that, in
cases where the gradient span is unrelated to the segment length,
the gradient cache (in GimpOperationGradient) is big enough not to
produce banding.  Use the new function in gimp_drawable_gradient()
and in the gradient tool, instead of duplicating the logic.

Move the shapreburst coordinate-adjustment logic to the new
function, and add appropriate logic for conical gradients.

Remove the code that avoids using the gradient cache for conical
gradients from GimpOperationGradient.
2018-04-25 14:05:19 -04:00
Michael Natterer
ef5bd98e99 app: protect GimpContext's "parent" pointer against dangling
with a weak ref and call set_parent(NULL) in dispose().
2018-04-25 19:20:12 +02:00
Ell
45be8b2591 app: use paint composite-mode, instead of AUTO, in more places
In the various types of fill operations, and in fade operations,
use the paint composite-mode of the current paint mode, which is
the composite mode we use during painting, instead of AUTO, which
results in the default mode we use for layer compositing.  This
effectively means that filling using any non-legacy, non-
subtractive mode can paint over transparent areas, rather than
being limited to nontransparent areas.
2018-04-25 11:20:48 -04:00
Ell
4fce5d2518 Bug 793714 - Error when merging layer group with Pass through mode
When merging a pass-through group, change its mode to NORMAL first,
to avoid a critical when duplicating the group as a regular layer.
Preserve the group's blend/composite space/mode while changing its
mode (note that only the composite space currently matters, since
the other parmaeters are immutable for pass-through groups.)
2018-04-25 08:43:57 -04:00
Michael Natterer
9ac34bda70 app: change the default paint mode in GimpContext to GIMP_LAYER_MODE_NORMAL 2018-04-24 14:00:34 +02:00
Michael Natterer
5b80d3d3be app: fix source operations on layers with alpha
They are not supposed to completely overwrite the layer's alpha
channel. Instead, composite them on top of the layer using gegl:over.
2018-04-23 02:59:35 +02:00
Michael Natterer
7256f18447 app: change offsets parameters of GimpItem::translate() from int to double
so we can use it to precisely position paths; use SIGNED_ROUND() in
channel, layer etc. to snap to pixels.
2018-04-23 01:27:56 +02:00
Michael Natterer
b1a36b044b app: cast another argument to g_object_ref() in gimp_tool_info_new() 2018-04-23 01:25:17 +02:00
Jehan
33d9336083 app: gimp_get_temp_file() / gimp_temp_name() should create tmp/ if...
... it doesn't exist.
The tmp/ dir in the config folder should already be created by GIMP, but
just in case it is not there, try and create it, since all code calling
these assumes that it exists.
2018-04-23 00:35:01 +02:00
Ell
a6a8147b19 app: fix indentation of GimpUndoType enum descriptions 2018-04-22 04:05:36 -04:00
Ell
37742a9fee Bug 795410 - Deleting a layer group and then undoing the deletion ...
... raises a CRITICAL

gimp_item_{start,end}_move() currently serves two different
purposes:  It is used by GimpLayer to suspend/resume mask resizing
of the layer's ancestors; this is necessary whenever an operation
on a layer might affect the size of its ancestors.  It is also used
by GimpGroupLayer to suspend/resume its own mask resizing; this, on
the other hand, is only necessary before applying one of the
transformation functions to the group, so that mask modification is
handled by GimpLayer.  In other words, the effects of
gimp_item_{start,end}_move() on group layers are only necessary in
a subset of the cases in which these functions are used.

While in itself this isn't a problem, it does cause issues when
removing a group layer:  gimp_image_remove_layer() calls
gimp_item_start_move() before removing the layer, and
gimp_item_end_move() afterwards.  While the former function is
called while the layer is still attached to the image, the latter
function is called after the layer is no longer attached.  Since
GimpGroupLayer pushes an undo step in response to these calls, only
the call to start_move() results in an undo step, while the call to
end_move() doesn't, resulting in an unbalanced
GIMP_UNDO_GROUP_LAYER_START_MOVE undo step on the stack.  This
causes problems when undoing the operation.

Add gimp_item_{start,end}_transform() functions, and corresponding
GimpItem::{start,end}_transform() virtual functions, which are more
specialized versions of gimp_item_{start,end}_move(), which should
be used instead of the former before/after transforming an item; in
other cases, such as when removing ot reordering an item,
gimp_item_{start,end}_move() should still be used.  The default
implementation of GimpItem::{start,end}_transform() calls
gimp_item_{start,end}_move(), respectively, so subclasses that
override these functions don't have to do that themselves.

In GimpGroupLayer, override GimpItem::{start,end}_transform(),
instead of GimpItem::{start,end}_move(), for the same purpose of
suspending mask resize.  This avoids these functions from being
called when removing a layer group, fixing the bug.
2018-04-22 04:05:36 -04:00
Ell
eeae5b48ca app: avoid pushing undo for nested gimp_group_layer_{suspend,resume}_mask()
... in order not to overshoot the undo-stack estimated memory-
usage.  See comment in the code.
2018-04-22 04:05:36 -04:00
Ell
577e17032a app: fix undo when moving a group-layer child outside the group
In gimp_image_reorder_item(), call gimp_item_start/end_move()
before/after reordering the item (and use an undo group, so that
the resulting undo actions are grouped together with the reordering
undo action,) so that if the item is a child of a group layer, and
reordering moves it out of the group in a way that causes the
group's mask to be resized, the mask will be properly restored when
undoing the operation.
2018-04-22 04:05:35 -04:00
Ell
66bc050df8 app: indentation fix to last commit 2018-04-19 05:17:47 -04:00
Ell
87e6653c9a app: improve drawable flipping speed
In gimp_drawable_transform_buffer_flip(), perform flipping tile-by-
tile, instead of row-by-row/column-by-column.
2018-04-19 05:13:42 -04:00
Michael Natterer
428110f63f app: remove non-cut/copy/paste functions from gimp-edit.[ch]
Move them to the new files gimpdrawable-edit.[ch] and
gimpimage-fade.[ch].
2018-04-18 23:48:33 +02:00
Michael Natterer
9dbf919d46 app: speed up gradient rendering a lot
by using a cache of colors that is calculated once, instead of
calling gimp_gradient_get_color_at() for each rendered pixel.
2018-04-18 01:18:09 +02:00
Michael Natterer
2da25576c3 app: fix duplication of GeglParamSpecSeed, we missed its limits before
(which are probably never used, but still)
2018-04-17 00:12:01 +02:00
Ell
02808e8072 Merge branch 'fix-gradient-history'
This fixes the history of app/core/gimpdrawable-gradient.h, and
app/tools/gimpgradienttool{.c,-editor.{c,h}}.
2018-04-15 03:30:52 -04:00
Michael Natterer
721ce91d75 Bug 795230 - Rename Blend tool and provide PDB compatibility
Redo the part of commits 4f2e078ccb
and 5f6dfc7617, reverted by commit
e30a32d56e.
2018-04-15 03:30:07 -04:00
Michael Natterer
9fd44d5e44 Bug 795230 - Rename Blend tool and provide PDB compatibility
Rename gimpdrawable-blend.h to gimpdrawable-gradient.h.  Note that
this commit only renames the file; the actual changes are done in
the next commit, so that git doesn't consider this a new file.
2018-04-15 03:30:05 -04:00
Ell
e30a32d56e Bug 795230 - Rename Blend tool and provide PDB compatibility
Partially revert commits 4f2e078ccb
and b0beb0197a, since the changes
they introduced to some of the renamed files were big enough for
git to consider them entirely new files, hence we lost their
history.  The next few commits fix this.

This commit also partially or entirely undoes followup commits
5f6dfc7617,
c3f98cccbd,
6b0f5136e0,
and 3736bfd189, which will be
restored by the next few commits as well.
2018-04-15 03:28:41 -04:00
Michael Natterer
0c066f311e app: drop alpha from all fishes in gimpgradient.c
Alpha is calculated separately, ne need to run it through babl.
Also some formatting cleanup.
2018-04-14 21:09:01 +02:00
Øyvind Kolås
6d6da684f1 app: add handling of CIE Lab blend space to gradient
Using CIE Lab yields gradients that more closely resemble the perceptual
gradients but without the gamma based blending problems of linear-RGB / CIE
XYZ.
2018-04-14 18:12:30 +02:00
Jehan
063a83c1ec app: migrate configuration files for s/Blend/Gradient/ tool renaming.
This includes migrating properly any custom shortcut (menurc), as well
as a few strings in tool-presets/, and finally "gimp-blend-tool" in
contextrc and devicerc.
File toolrc also has some occurrences, but we are already skipping it
anyway, same as whatever is under tool-options/.
Hopefully I missed nothing.
2018-04-14 04:01:32 +02:00
Michael Natterer
5f6dfc7617 app: add GimpGradientBlendColorSpace parameter to gimp_drawable_gradient() 2018-04-14 01:34:50 +02:00
Michael Natterer
b0beb0197a Bug 795230 - Rename Blend tool and provide PDB compatibility
Rename the tool and its options, and the gradient sub-struct of paint
options.
2018-04-14 00:52:20 +02:00
Michael Natterer
4f2e078ccb Bug 795230 - Rename Blend tool and provide PDB compatibility
Rename gimpdrawable-blend.[ch] to gimpdrawable-gradient.[ch]
2018-04-13 23:43:27 +02:00
Michael Natterer
b55c116755 Bug 795230 - Rename Blend tool and provide PDB compatibility
Rename GimpOperationBlend to GimpOperationGradient.
2018-04-13 23:36:16 +02:00
Michael Natterer
99ea6f91e2 app: fix the build after the GimpGradientBlendColorSpace commit
Somehow, gimppalette-import.c was not rebuilt on my system,
leaving one gimp_gradient_get_color_at() unchanged.
2018-04-13 23:12:21 +02:00
Michael Natterer
ebb9d83d63 Bug 795230 - Rename Blend tool and provide PDB compatibility
Step 1: rename the icon to GIMP_ICON_TOOL_GRADIENT (gimp-tool-gradient)
2018-04-13 23:07:08 +02:00
Michael Natterer
bf49b47620 Bug 795207 - Add color space to blend(gradient) tool options
First WIP commit, adds:

- enum GimpGradientBlendColorSpace { RGB_PERCEPTUAL, RGB_LINEAR }
- linear blending mode for gradient segments
- tool options GUI for the blend and paint tools which use gradients
2018-04-13 22:33:16 +02:00
Michael Natterer
421c9fc51a Bug 795050 - ‘strncpy’ output truncated before terminating nul
Use memcpy() because we really dont' want to copy the terminating nul,
but we don't want a warning either.
2018-04-11 11:31:02 +02:00
Jehan
1993d8a4a7 Bug 768872 - Tiling Symmetry doesn't wrap vertical coordinates over...
... edges for MyPaint brush.

Adding the concept of "stateful" symmetry when a tool needs to make sure
of corresponding stroke numbers and orders while painting (i.e. stroke N
at time T+1 is the continuation of stroke N at time T). This is the case
for the MyPaint brushes and the ink tool.
2018-04-11 02:09:21 +02:00
Michael Natterer
3f95dc52d3 Bug 791519 - Unexpected selection from channel
Make sure a channel -> selection -> channel roundtrip never does any
gamma conversion.

In gimp_channel_duplicate(), make sure a created channel has the
right format, and the right data. Fixes selection -> channel.

When switching off quick mask, call gimp_item_to_selection() instead
if gimp_selection_load(), the latter was implementing a shortcut which
is now wrong.

Remove gimp_selection_load() which is now unused.

Unrelated: also remove gimp_selection_save(), it was an obvious
3-liner used only twice.
2018-04-10 02:00:23 +02:00
Michael Natterer
bba8f69594 Revert "Bug 791512 - make the selection boundary detection the same as 2.8"
This commit was fixing only a symptom of our channel/selection
problem, making it appear things were fine.

This reverts commit 27512d802b.
2018-04-10 00:26:01 +02:00
Ell
f5cb1fed85 Bug 795081 - Crash when using a brush combined with a dynamics
In GimpPaintTool, brush outline generation took place during
gimp_paint_tool_draw() even while painting.  This function is run
concurrently with the paint thread.  When using dynamics, this
introduced a race conidition between updating the brush mask in the
paint thread, and updating the brush boundary in the main thread.

Move brush outline generation during painting to
gimppainttool-paint.c, and perform it in the display-update
timeout, while the main thread and the paint thread are
synchronized.
2018-04-09 14:27:48 -04:00
luz.paz
7fdb963e01 Bug 794996 - Misc. typo fixes in comments in app/
Found via `codespell -q 3 --skip="./po*"`
2018-04-08 21:25:56 +02:00
Michael Natterer
bb4ac7c829 Bug 791519 - Unexpected selection from channel
Storing selections and layer masks as linear grayscale, but channels
as whatever-the-layers-are caused severe problems in images with
gamma-corrected layers: when combining channels with the selection,
they would go thorugh a gamma conversion before being combined, giving
unexpected results.

This commit changes all channels to always be linear, except in 8-bit
images, where they continue to be "Y' u8", for compatibility with old
XCF files, and because linear 8-bit can't really be used in
compositing (channels can be visible too).

To fix channel -> selection combinations also for these images, add a
small hack to gimp_gegl_mask_combine_buffer() which makes sure the
to-be-combined channel's pixels are always read as-is, without any
gamma conversion. After changing channels to linear, this makes no
difference except in the 8-bit images where we need this hack.
2018-04-08 19:26:48 +02:00
Ell
ce9ca03ed4 app: add gimp_drawable_{start,end,flush}_paint()
gimp_drawable_start/end_paint() are used to enter/exit paint mode
for a given drawable.  While the drawable is in paint mode,
gimp_drawable_get_buffer() returns a copy of the real drawable's
buffer, referred to as the paint buffer, so that modifications to
the returned buffer don't immediately affect the projection, and
calls to gimp_drawable_update() queue the updated region, instead
of emitting an "update" signal.

gimp_drawable_flush_paint() can be called while the drawable is in
paint mode, in order to copy the updated region of the paint buffer
back to the drawable's real buffer, and to emit "update" signals
for the queued region.

We use these functions in the next commit, to move painting to a
separate thread in the paint tools.
2018-04-08 09:42:47 -04:00
Ell
6ebc3f1b09 Makefiles: don't use -xobjective-c when linking files on Mac
Last commit caused -xobjective-c to be passed during linking on
Mac, causing object files to be treated as source files.  Add a
-xnone flag to AM_LDFLAGS, canceling the effect of -xobjective-c.

Additinally, add a -xobjective-c++ flag to AM_CXXFLAGS, so that we
can use Objective-C in C++ files on Mac, if we ever need to.
2018-04-08 04:03:55 -04:00
Ell
06950be7f0 Makefiles: don't use -xobjective-c when compiling C++ files on Mac
On Mac, pass -xobjective-c to the compiler through AM_CFLAGS, not
AM_CPPFLAGS, so that it's only used for C sources, and not C++
sources.  In the latter case, it clashes with the -std=... flag,
spewing an error.  Thanks, Partha :)
2018-04-07 16:57:52 -04:00
Massimo Valentini
81e1e3967d app: silence gcc warning
gimp-templates.c:143:15: warning: ‘strncpy’ output truncated before terminating nul copying 3 bytes from a string of the same length [-Wstringop-truncation]
               strncpy (dpi, "ppi", 3);
               ^~~~~~~~~~~~~~~~~~~~~~~
2018-04-07 14:45:45 +02:00
Jehan
0009794d9d app: migrate tool-presets with s/GimpImageMapOptions/GimpFilterOptions/.
As requested!
2018-04-05 11:46:49 +02:00
Ell
c8d4c079a2 app: parallelize gimpbrush-transform.cc
Use gimp_parallel_distribute_foo() to parallelize the brush
transform functions.
2018-04-04 17:49:46 -04:00
Ell
565f1f2aa4 app: switch gimpbrush-transform.c to C++
The next commit is going to parallelize gimpbrush-transform using
the gimp_parallel_distribute_foo() functions.  To spare us a lot of
boilerplate code, we're going to use C++ lambdas as callback
arguments to these functions.

This commit does the initial conversion of gimpbrush-transform.c to
C++, renaming it to gimpbrush-transform.cc.  We do this in a
separate commit, so that the changes are small enough for git to
register this as a renamed file, rather than a new file, so that we
don't lose the file's history.
2018-04-04 17:49:46 -04:00
Ell
86b89cf62a app: add gimp-parallel
Add gimp-parallel.[cc,h], which provides a set of parallel
algorithms.

These currently include:

  - gimp_parallel_distribute():  Calls a callback function in
    parallel on multiple threads, passing it the current thread
    index, and the total number of threads.  Allows specifying the
    maximal number of threads used.

  - gimp_parallel_distribute_range():  Splits a range of integers
    between multiple threads, passing the sub-range to a callback
    function.  Allows specifying the minimal sub-range size.

  - gimp_parallel_distribute_area():  Splits a rectangular area
    between multiple threads, passing the sub-area to a callback
    function.  Allows specifying the minimal sub-area.

The callback function is passed using an appropriately-typed
function pointer, and a user-data pointer.  Additionally, when used
in a C++ file, each of the above functions has an overloaded
template version, taking the callback through a generic parameter,
without a user-data pointer, which allows using function objects.
2018-04-04 17:49:46 -04:00
Michael Natterer
65a697ff67 app: switch the first two args of gimp_channel_new_from_buffer() 2018-04-03 21:57:43 +02:00
Jehan
d779c13891 app: do not edit symmetry variables but properties.
If variables are edited directly, in some cases, the GUI and the
symmetries may end up out-of-sync. The variable can only be edited
through property setting.
2018-04-02 18:49:23 +02:00
Jehan
3c1516ea50 app: mirror positions 0.0 are accepted.
This value is actually used as a special value when removing a guide to
get rid of a symmetry, in particular it is set in the guides' callback
gimp_mirror_guide_removed_cb() for "removed" signal.
If not setting to 0, when adding back a symmetry, it starts with weird
low or high values near to border (whereas when set to 0, it is reset to
default position afterwards).
2018-04-02 17:44:01 +02:00
Jehan
c9df2a6879 app: do not raise a warning when failing to deserialize symmetry...
... parasite.
Not sure if that should be considered a bug. On one hand, it should
because that's core code. On the other hand, symmetry saving currently
uses parasites, which is a feature which can also be used by people
randomly. So "theoretically", there could be any data in a parasite and
we should not assume specific format.
Anyway still keep the error message but just print to standard error
output instead. Also print a bit more details (parasite name and
contents) as it would help for debugging when such a case were to occur.
2018-04-01 18:20:26 +02:00
Jehan
e0029d31b4 Bug 792520 - Image symmetries should be saved: version the properties.
Care for future changes of symmetries, by adding a version property. For
now, all symmetries are at version 0, and no real check is done. If any
symmetry bumps its settings in the future, it will have to override also
update_version() to change settings properly if necessary, according to
any new behavior.
2018-04-01 17:51:07 +02:00
Ell
49285463e6 app: align projection update area to coarse grid
When adding a rectangle to a projection's update area, align the
rectangle to a coarse grid, to reduce the complexity of the overall
area.  We currently align the rectangle to a 32x32 grid, which
seems to be a good tradeoff between the overhead of processing a
complex area, and the overhead of processing a large area.
2018-03-31 08:19:18 -04:00
Ell
53c145c0be app: add --show-debug-menu command-line option
The debug menu is currently not included in stable versions.

Include the menu unconditionally, but hide it, and its associated
actions, by default in stable versions.  Allow enabling the menu
using a new --show-debug-menu command-line option, in the same vein
as --show-playground.
2018-03-29 05:26:03 -04:00
Ell
3265797f3e Bug 794753 - do not dither image mask and channels for imported images
By the same logic of commit
44f293bcdb, we shouldn't dither the
alpha channel either.
2018-03-29 03:30:31 -04:00
Ell
9cabee5451 app: call gimp_progress_end() at gimp_image_convert_dither_u8() exit 2018-03-29 03:30:31 -04:00
Thomas Manni
44f293bcdb Bug 794753 - do not dither image mask and channels for imported images
When "Dither images when promoting to floating point" is checked in
Preferences, apply dithering on layers and keep image mask and channels
unaltered.
2018-03-28 17:15:06 +02:00
Michael Natterer
60e01f5593 app: fix error reporting in gimp_tool_preset_deserialize_property()
when setting a custom parse error with g_scanner_error() we *must*
return G_TOKEN_NONE as expected token, or general GimpConfig error
handling will try to overwrite our error with its generic "unexpected
token" message, which triggers a warning.
2018-03-28 01:17:39 +02:00
Ell
5614cd444d app: in gimp_image_convert_precision(), report progress for selection mask 2018-03-27 09:39:52 -04:00
Ell
cf658f64b5 Bug 794721 - CRITICAL converting image precision
In gimp_image_convert_precision(), don't overwrite the 'progress'
parameter with the object queue, since we need to call
gimp_progress_end() on it at the end of the process.
2018-03-27 09:39:52 -04:00
Michael Natterer
7c4f7c53ea Bug 794679 - warning on scrolling in the gradient dock
Validate all enum fields in gimp_gradient_load(), and reject
gradients with out-of-range values.
2018-03-26 18:54:43 +02:00
Ell
806d1b0510 app: fix resizing of image-sized layers when resizing canvas
In gimp_image_resize_with_layers(), calculate the set of resized
layers before changing the image size, so that we correctly
identify image-sized layers w.r.t. the old image size.  (Fixes
commit 139a23451ddc588c91610f67daa799afc2f89080.)
2018-03-26 04:38:47 -04:00
Ell
5763b50d45 app: round layer bounds to global pixel grid when scaling image/group
Add gimp_item_scale_by_factors_with_origin(), which is an extension
of gimp_item_scale_by_factors(), taking the input/output points of
origin for the transformation (both of which are (0, 0) in the case
of gimp_item_scale_by_factors()).  Implement
gimp_item_scale_by_factors() in terms of the new function, and Use
the new function when scaling group layers, instead of manually
calculating the children boundaries, so that the behavior is
uniform across whole-image scaling and group-layer scaling.

The new function rounds all four edges of the boundary to the
image-global pixel grid, instead of only rounding the top/left
edges to the global grid, and the bottom/right edges to the item-
local grid.  This preserves layer-adjacency when scaling.
2018-03-25 11:46:42 -04:00
Ell
139a23451d app: use GimpObjectQueue in lots of places
Use GimpObjectQueue, added in the previous commit, in various
instances where we perform an action on a set of objects.  This
improves progress reporting, by using a single progress for the
entire operation, rather than reporting the progress of each object
individually, and by taking the relative cost of each object into
account, instead of assuming a uniform cost for all objects.

In particular, this affects the various whole-image operations
(i.e., transformations and color conversions), operations on linked
items, and operations on layer groups.  This also affects layers
with masks, whose progress is now reported together instead of
individually.

Additionally, this commit fixes erroneous group-layer mask cropping
during undo when resizing the image, by properly calling
{start,end}_move() on all the resized layers before starting the
operation, and when scaling the image, by only scaling top-level
layers, and letting group layers scale their children themselves.
2018-03-25 11:46:42 -04:00
Ell
3ee5054eb7 app: add GimpObjectQueue
GimpObjectQueue implements a queue of GimpObjects.  It derives from
GimpSubProgress, and hence can be used as a GimpProgress object.
It keeps track of the total memsize of the objects that were
pushed-to and popped-from the queue, and uses these numbers to set
the corresponding subrange of the progress object when an object is
popped.

This provides an easy way to perform an operation on a set of
objects, correctly reporting progress based on the relative sizes
of the objects, which is assumed to be a good estimate of the
relative cost of processing each object.
2018-03-25 11:46:42 -04:00
Ell
0f532787c9 app: add "progress" property to GimpSubProgress
Make the parent GimpProgress object of a GimpSubProgress instance
settable through a property during construction, so that we can use
it as a base class.
2018-03-25 11:46:42 -04:00
Ell
76a88cc60a app: fix layer-group mask cropping during move operation undo
In gimp_group_layer_{start,end}_move(), push corresponding undo
steps, which perform the opposite operation during undo, and make
sure that mask-cropping is frozen during group-layer move
operations.

This fixed erroneous group-layer mask cropping when undoing/redoing
a group-layer move operation multiple times.
2018-03-25 11:46:42 -04:00
Ell
8f07d76786 app: fix paste-in-place when pasting over a layer group/locked item
When pasting in place over a layer group or a content-locked item,
change the paste type to NEW_LAYER_IN_PLACE, rather than NEW_LAYER,
so that the new layer is still pasted in the right location.

Additionally, avoid showing the "Pasted as new layer because ..."
message when pasting over a layer group or a content-locked item,
when the paste type is NEW_LAYER[_IN_PLACE] to begin with.
2018-03-24 12:50:16 -04:00
Ell
e1b1611ec4 app: add crop_input parameter to gimp_gegl_apply_operation()
Add a crop_input parameter to gimp_gegl_apply_[cached_]operation().
When TRUE, the functions crop the op's input to the destination
rect.  This is particularly useful for functions that process the
entire input in one go (by means of get_cached_region()).  See the
next commit.

Pass crop_input = FALSE at all call sites for now, to keep the
current behavior.
2018-03-22 13:46:28 -04:00
Michael Natterer
829d44d900 app: make "color" parameter of gimp_palettes_add_color_history() const 2018-03-21 19:10:55 +01:00
Michael Natterer
28d9e43f53 Bug 792686 - Colormap widget not updated when adding entry
gimp_image_add_colormap_entry(): increment private->n_colors *before*
calling gimp_image_colormap_set_palette_entry() so it actually adds an
entry.
2018-03-20 00:53:57 +01:00
Jehan
a1b4f4aef5 Bug 793638 - (gimp-edit-stroke ...) crashes gimp-console-2.9 unless...
... (gimp-context-set-paint-method...) is called.
GimpContext initialized with standard paint info at constructed() time
to ensure there is always a paint_info even if none were set manually.
2018-03-18 15:07:50 +01:00
Jehan
e164aee7a9 app, libgimp, pdb: add "distance-metric" property to GimpPDBContext.
This property is currently only used for gimp_edit_blend() to control
how are computed distances. In the future, it could be used for more
functions making use of "gegl:distance-transform" operation, or even for
other algorithms, if relevant.
This new property obviously comes with 2 new PDB calls:
gimp_context_get_distance_metric() & gimp_context_set_distance_metric()
2018-03-18 01:03:40 +01:00
Jehan
c3ef34b496 Revert "app: "distance-metric" is now a property of GimpContext."
This reverts commit 2c799d4af9.
Ok. I misunderstood Mitch. This belongs in GimpPDBContext.
2018-03-17 20:05:54 +01:00
Jehan
2c799d4af9 app: "distance-metric" is now a property of GimpContext.
Remove the property from Blend tool and make it use the context one.
2018-03-17 18:18:56 +01:00
Jehan
acc0a97eed app: updating the previous commit following enum update in GEGL.
Enums have been renamed to s/GEGL_DISTANCE_FOO/GEGL_DISTANCE_METRIC_FOO/
Make the change in GIMP too.
2018-03-17 16:19:31 +01:00
Jehan
9b11fb2b91 app, libgimp, libgimpbase, pdb: s/GimpDistanceMetric/GeglDistanceMetric/
GeglDistanceMetric has just been added as a public enum in GEGL. Basing
our code on this, and getting rid of the newly added GimpDistanceMetric.
2018-03-17 14:57:31 +01:00
Jehan
87330a7746 app: add "distance-metric" property to the Blend tool options.
It seems old blend tool (from GIMP 2.8) was using manhattan distance,
whereas the new one uses euclidean. I guess there must be use cases for
both. In any case, it is a good idea to simply propose the option since
the property exists in the "gegl:distance-transform" operation.
See also bug 781621.
2018-03-15 13:24:59 +01:00
Ell
a7f3a2dd9f app, pdb, libgimp, plug-ins, menus: rename layer composite modes
Our composite modes don't correspond directly to the Porter-Duff
operators after which they're named, and these names aren't too
descriptive anyway.

Rename the composite modes as follows:

  Source Over       =>  Union
  Source Atop       =>  Clip to Backdrop
  Destination Atop  =>  Clip to Layer
  Source In         =>  Intersection

Update relevant code, including UI text, enumerator names, function
names, and action names.
2018-03-14 16:19:09 -04:00
Jehan
5751bb114e Bug 781621 - PDB shapeburst gradient is slower than the blend tool.
PDB function gimp_edit_blend() was based on "gimp:shapeburst" operation
whereas the rest of GIMP (in particular, the Blend tool) used
"gegl:distance-transform" which is much faster.
Setting the operation to "manhattan" metric ensures that it still
renders the same way as in 2.8 while being a lot faster.

There was still a problem regarding as how it renders differently from
the Blend tool, but it turns out that the Blend tool is the one
rendering differently from how it used to in 2.8. We should discuss
adding the "metric" property in the tool options.
2018-03-14 16:07:18 +01:00
Ell
b590b59542 app: fix #include order in gimp-spawn.c
... so that GLib is included before the platform-specific headers,
so that we can check for G_OS_WIN32.

Spotted by Partha, as usual :)
2018-03-10 02:22:40 -05:00
Ell
e4c79cb2d6 app: use gimp_cairo_rounded_rectangle() in GimpOverlayFrame
... instead of drawing it the hard way.
2018-03-07 09:40:19 -05:00
Ell
a6001f1941 app: add gimp_cairo_rounded_rectangle()
... which draws a rectangle with rounded corners.
2018-03-07 06:18:21 -05:00
Ell
efa8040780 app: rename gimp_cairo_foo() functions to follow cairo naming scheme
Really pedantic stuff :)  Rename the functions in gimp-cairo.h to
follow the naming scheme employed by cairo, so that they don't feel
out of place.
2018-03-07 06:18:20 -05:00
Ell
52b0e61001 app: in gimp-spawn.c, add missing #include on Windows
... and improve argument validation.
2018-03-07 01:41:21 -05:00
Ell
cdb541f81b app: add gimp_spawn_set_cloexec()
... which prevents child processes from inheriting a given pipe,
under *nix and Windows.
2018-03-06 16:31:17 -05:00
Ell
95af939903 app: verify input argumets in gimp_spawn_async() 2018-03-05 02:55:53 -05:00
Ell
e1ed39e3a3 app: in gimp-spawn.c, avoid warning when we don't have vfork() 2018-03-05 02:45:47 -05:00
Ell
0f2df18dde app: add gimp_spawn_async()
gimp_spawn_async() is similar to, but more limited than,
g_spawn_sync().  Unlike the latter, gimp_spawn_async() uses
vfork(), instead of fork(), when possible.

On Linux, a process that uses large amounts of memory (as GIMP may)
can hang during a fork() if overcommitting is enabled, and there's
not enough memroy.  Using vfork() avoids that, since it doesn't
duplicate the parent's address space.
2018-03-05 01:55:40 -05:00
Massimo Valentini
87525c8911 BUG 793634: CRITICAL loading psd file with disabled layer mask
Similarly to other layer setter functions, don't push undo
steps if the layer is not yet attached
2018-02-22 00:43:50 +01:00
Michael Natterer
d71ed88592 app: add buffering to reading data files
gimp_data_factory_load_data(): use a GBufferedInputStream so we don't
end up reading files byte-by-byte in the worst case.
2018-02-21 22:12:52 +01:00
Ell
91a947bbe5 app: don't allow setting NULL buffer to drawables; modify steal_buffer()
Revert commit 24fcabc1ca, which
allowed passing a NULL buffer to gimp_drawable_set_buffer[_full](),
leaving the drawable without a buffer in a semi-functional state --
this is too risky.

Instead, have gimp_drawable_steal_buffer() assign an empty 1x1
buffer to the stolen-from drawable, rather than leaving it without
a buffer at all.
2018-02-14 10:39:37 -05:00
Ell
b50be495cb app: add gimp_drawable_steal_buffer()
... which transfers a buffer from one drawable to another in a safe
manner, leaving the source drawable empty.

There are already two ad-hoc instances where we steal a drawable's
buffer through simple pointer assignment, however, this avoids
performing potentially necessary cleanup and setup.  In particular,
since commit d0ae244fe8 this causes
actual errors.  The next two commits replace those instances with
calls to gimp_drawable_steal_buffer().
2018-02-13 13:29:15 -05:00
Ell
24fcabc1ca app: allow passing a NULL buffer to gimp_drawable_set_buffer[_full]()
... which clears the drawable's buffer, performing any necessary
cleanup, without setting a new buffer.  While the drawable has no
buffer, it can only be used in a very limited way, in particular,
it may be destroyed, and it may be assigned a new buffer.

This is used by the next commit to implement
gimp_drawable_steal_buffer(), which transfers a buffer from one
drawable to another in a safe manner, leaving the source drawable
empty.
2018-02-13 13:29:15 -05:00
Jehan
77ed476113 app: add GIMP_MESSAGE_BUG_WARNING + GIMP_MESSAGE_BUG_CRITICAL severity.
Since a few commits, I don't generate the traces anymore in errors.c but
delay this to gui-message.c and rely on the message severity to decide
whether or not generating traces.
Unfortunately none of the current severities are properly describing
this new type of messages. Even GIMP_MESSAGE_ERROR is used everywhere in
our code NOT for actual programming bug, but often for data errors
(which are not bugs but proper messages and should obviously not prompt
a debug trace).
2018-02-12 18:22:15 +01:00
Michael Natterer
3bea6dce03 app: don't choke when being asked for GIMP_UNIT_PERCENT's factor or digits
Instead, return bogus default values just like libgimp/gimpunitcache.c
does.
2018-02-12 16:37:49 +01:00
Ell
ac3392477b app: don't disable undo for unattached items in gimp_item_{start,end}_move()
Setting push_undo to FALSE in these functions is premature -- let
this stuff be handled at the actual point where the undo is
pushed, which might correspond to a different item than the one for
which gimp_item_{start,end}_move() was called.

In particular, when removing a layer from the image,
gimp_item_end_move() is called (with push_undo == TRUE) on the
layer after it's been removed, but we still need the appropriate
undo enrties to be pushed for the affected group layers.
2018-02-12 05:18:26 -05:00
Ell
68e37f28c2 Bug 793373 - Crash when ctrl-alt-clicking, dragging then releasing...
... a selection.

The crash was the result of an unmatched gimp_item_end_move() call,
which is an error.  Add the matching gimp_item_start_move() call
when starting to drag a selection in GimpEditSelectionTool.  Revert
last commit, so that unmatched gimp_layer_end_move() calls are not
silently ignored, and add a check instead.
2018-02-12 05:18:26 -05:00
Jehan
d9987ea7f1 Bug 793373 - Crash when ctrl-alt-clicking, dragging then releasing...
... a selection.
The regression appeared with commit 10c125c627.
gimp_layer_end_move() may sometimes run even while a symmetric
gimp_layer_start_move() had not run. For instance this happens when
releasing the mouse button after dragging a ctrl-alt-click created
floating layer.
Therefore let's check that layer->move_stack is not NULL before
dereferencing it.
2018-02-12 08:29:32 +01:00
Jehan
34fe992f44 app: keep track of number of errors and traces in GimpCriticalDialog.
We don't want an infinite number of traces because it takes some time to
get. Until now I was keeping track of traces in app/errors.c, but that
was very sucky because then I was limiting traces per session. Instead
save them as a variable of a GimpCriticalDialog instance. Therefore only
generate the traces for WARNING/CRITICAL at the last second, when
calling the dialog.
When too many traces are displayed, just fallback to just add error
messages only. But then even errors without traces can be time-consuming
(if you have dozens of thousands of errors in a few seconds, as I had
the other day, updating the dialog for all of them would just freeze the
whole application for a long time).
So also keep track of errors as well and as last fallback, just send the
remaining errors to the stderr.
2018-02-12 02:09:15 +01:00
Michael Natterer
539927ebfa app: replace all g_assert() by the newly added gimp_assert()
which is just a #define to g_assert for now, but can now easily be
turned into something that does some nicer debugging using our new
stack trace infrastructure. This commit also reverts all constructed()
functions to use assert again.
2018-02-11 22:23:10 +01:00
Jehan
a5bc153343 app: fix a second switch with missing paste types.
Completing previous commit, the next switch was not raising any error,
but I believe the new "in place" variants of paste as floating selection
also have to be processed for mask removal.
2018-02-10 23:57:45 +01:00
Jehan
da3baa1cab Bug 793360 - Error when copy-pasting in place a full layer.
In a switch(), not all paste type were listed (the new "In Place"
versions in particular were missing), therefore we were hitting a
g_return_val_if_reached() error.
2018-02-10 23:46:58 +01:00
Ell
d0ae244fe8 app: invalidate channel boundary upon buffer "changed" signal
Have GimpChannel connect to the drawable buffer's "changed" signal,
so that we can invalidate the channel's boundary whenever the
buffer contents change.  Currently, the calls to
gimp_drawable_invalidate_boundary() dispersed throughout the code
are not enough.

Moreover, invalidate both the boundary and the bounds in
gimp_channel_invalidate_boundary(), since both are necessary when
the buffer changes.
2018-02-10 05:36:40 -05:00
Ell
10c125c627 app: keep ancestor set in gimp_layer_start_move(), for use in end_move()
In gimp_layer_start_move(), keep the set of ancestors for which for
which we suspended mask cropping, so that we can resume mask
cropping for the same groups in gimp_layer_end_move().  This is
necessary, since gimp_image_remove_layer() calls gimp_item
start_move() before removing the layer from the layer tree, and
gimp_item_end_move() after removing the layer from the layer tree,
at which point the layer has no ancestors.
2018-02-10 05:36:40 -05:00
Jehan
d5a67cb162 app: make debugging preference finer-grained than a boolean.
Replacing the boolean property "generate-backtrace" by an enum
"debug-policy". This property allows one to choose whether to debug
WARNING, CRITICAL and FATAL (crashes), or CRITICAL and FATAL only, or
only FATAL, or finally nothing.
By default, a stable release will debug CRITICAL and crashes, and
unstable builds will start debugging at WARNINGs.
The reason for the settings is that if you stumble upon a reccurring bug
in your workflow (and this bug is not major enough for data corruption,
and "you can live with it"), you still have to wait for a new release.
At some point, you may want to disable getting a debug dialog, at least
temporarily. Oppositely, even when using a stable build, you may want to
obtain debug info for lesser issues, even WARNINGs, if you wish to help
the GIMP project.
It can be argued though whether the value GIMP_DEBUG_POLICY_NEVER is
really useful. There is nothing to gain from refusing debugging info
when the software crashed anyway. But I could still imagine that someone
is not interested in helping at all. It's sad but not like we are going
to force people to report. Let's just allow disabling the whole
debugging system.
2018-02-08 20:48:16 +01:00
Ell
94554fcc0c app: resize group-layer mask after moving the group
We avoid resizing the mask as a result of changes in the group's
bounding box while the group is being moved (i.e., translated,
rotated, etc.), so that GimpLayer transforms the original mask,
rather than a cropped mask.  We still need to crop the mask after
we're finished moving the group, however.  This commit takes care
of that.
2018-02-07 09:54:08 -05:00
Ell
9befb8594e pdb: fail layer-remove-mask if applying a mask to a group layer
... which is not supported.
2018-02-05 15:15:22 -05:00
Ell
e7a2624a85 app: fix undo when resizing a group layer with a mask
Override GimpItem::resize(), instead of GimpLayer::resize(), when
resizing a group layer, so that GimpLayer doesn't try to resize the
mask.  Instead, the let the usual mask resizing logic in
GimpGroupLayer handle that.

Also, make sure that the mask is properly restored upon undo when
group resizing is suspended outside of any mask-suspension block,
which can happen when resizing the group.
2018-02-05 15:15:21 -05:00
Ell
17fb644787 app: add XCF version 13 for images with group-layer masks 2018-02-05 15:15:21 -05:00
Ell
36dec4e6b0 Bug 51112 - Support layer masks on layer groups
Add layer-mask support for group layers.  Group-layer masks work
similarly to ordinary-layer masks, with the following
considerations:

The group's mask size is the same as group's size (i.e., the
bounding box of its children) at all times.  When the group's size
changes, the mask is cropped to the new size -- areas of the mask
that fall outside of the new bounds are discarded and their data is
lost (sans undo), and newly added areas are filled with black (and
hence are transparent by default).

The new gimp_group_layer_{suspend,resume}_mask() functions can be
used to modify this behavior.  Between the outermost pair of
suspend/resume calls, the old mask data is remembered, and is used
to fill the newly added areas while cropping the mask when the
group is resized.  We override GimpItem::{start,end}_move() for
GimpLayer, to call these functions (suspend() in start_move(), and
resume() in end_move()) for each of the layer's ancestors.

As a result, while moving a layer, or a set of layers, atomically,
such as while dragging with the move tool, or moving linked layers,
the ancestors' mask data is not lost, and is only discarded at the
end of the operation.

This commit also takes care of properly handling undo for group-
layer mask crops, properly invalidating the image when the group
layer's mask is shown, and enabling the mask actions for group
layers (obviously :).
2018-02-05 12:08:54 -05:00
Ell
02a20c6c73 app: add gimp_item_{start,end}_move()
Add gimp_item_{start,end}_move(), and corresponding
GimpItem::{start,end}_move() virtual functions, which should be
called before/after "moving" the item (i.e., translating, scaling,
resizing, flipping, rotating, or transforming the item).  Moves
performed between the outermost pair of start/end calls are treated
atomically.

What exactly does "treated atomically" entail depends on the
subclasses -- GimpItem doesn't provide a default implementation for
these functions, so the current commit doesn't change any behavior.
The next commit, which adds layer-mask support for group layers,
uses the functions to avoid cropping the mask too early while a
child is moving.

GimpItem calls {start,end}_move() in the various "move" functions
(gimp_item_{translate,scale,...}(), before performing the actual
operation.  Additionally we call the functions in the
gimp_image_item_list_foo() functions, for each participating item,
so that the items are moved as a unit.  We call the functions in
the various gimp_image_remove_foo() functions, since removing an
item may affect the size of its ancestors, and is therefore akin to
moving.  We also call the functions in GimpEditSelectionTool, so
that the move tool moves items atomically while dragging.
2018-02-05 12:08:54 -05:00
Ell
dee7dbc399 app: subdivide perspective-transformed Bezier curves
The result of applying a perspective-transform to a Bezier curve is
only an approximation.  When the curve is highly nonlinear, the
result may diverge significantly from the real transformed curve.

Subdivide the curve as necessary in gimp_transform_bezier_coords()
to counter that.  Adjust gimp_bezier_stroke_transform()
accordingly.
2018-02-04 14:45:24 -05:00
Ell
53f7da0408 app: fix a few comments in last commits 2018-02-03 10:15:03 -05:00
Ell
9bf1e1c884 app: add gimp_transform_bezier_coords()
... which transforms a single cubic Bezier segment, performing
clipping by the near plane, to avoid erroneously transforming parts
of the curve behind the camera.
2018-02-03 05:58:43 -05:00
Ell
6b62cce03b app: add gimp_transform_polygon_coords()
... which is the same as gimp_transform_polygon(), but using
GimpCoords for the vertices, instead of GimpVector2.

Specify when the input and output arguments may alias, in the
description of gimp_transform_polygon().
2018-02-03 05:58:42 -05:00
Ell
ea34bbc92b app: add gimp_coords_interpolate_bezier_at()
... which calculates the position and/or velocity of a Bezier curve
at a given point.
2018-02-03 05:58:42 -05:00
Ell
275815c808 app: misc cleanup in gimpcoords-interpolate
Fix indentation, typos, style.  Use array parameters for the
control points, instead of using individual by-value parameters.
Use GArray* for the results, instead of GArray**.  Verify
arguments.

Adapt the rest of the code to the changes.
2018-02-03 05:58:42 -05:00
Ell
91b35591c6 app: add comment to gimp_transform_polygon()
.. describing the function, and, in particular, specifying upper
bounds for the resulting number of vertices.
2018-01-31 10:11:55 -05:00
Ell
17ec3d130e app: fix gimp_transform_matrix_generic()
When the resulting matrix transforms all input points behind the
camera, negate the matrix, instead of failing, which results in a
matrix that transforms the input points to the corresponding points
in front of the camera.  This avoids rejecting certain valid
transforms as invalid, in the generic transform tools (unified,
perspective, and handle transform).

Make the number of input and output points explicit in the
function's signature, and add comments.
2018-01-31 10:11:55 -05:00
Michael Natterer
04b4bccbb3 app: #include <string.h> in gimp-transform-resize.c 2018-01-28 22:58:26 +01:00
Ell
5f58a7a260 app: pass near-plane z-coordinate to gegl:transform
... so that GEGL performs the same clipping we do.
2018-01-28 16:37:34 -05:00
Ell
3c0787e4c3 app: use gimp_transform_polygon() in gimp_transform_resize_boundary()
... so that the transformed boundary is properly clipped.

Adjust the boundary-size algorithms to operate on arbitrary
polygons.

Avoid using gimp_matrix3_will_explode() in
gimp_drawable_transform_buffer_affine() and falling back to
cropping the result, and avoid setting the "clip-to-input" property
of gegl:transform.  Neither of those in needed anymore.

This effectively reverts the app/ part of commit
768d06614f.  The next commit revets
the libgimpmath/ part.
2018-01-28 16:37:34 -05:00
Ell
cc20cb41f3 app: add gimp_transform_polygon()
gimp_transform_polygon() transforms an (open or closed) polygon by
a GimpMatrix3, performing clipping to the near plane, to avoid
erroneously transforming points behind the camera.
2018-01-28 16:37:33 -05:00
Jehan
9fdf35550b app: new error dialog to backtrace and encourage people to report bugs.
GIMP will now try to get a backtrace (on Unix machines only for now,
using g_on_error_stack_trace(); for Windows, we will likely have to look
into DrMinGW).
This is now applied to CRITICAL errors only, which usually means major
bugs but are currently mostly hidden unless you run GIMP in terminal. We
limit to 3 backtraces, because many CRITICAL typically get into domino
effect and cause more CRITICALs (for instance when a g_return*_if_fail()
returns too early).
2018-01-28 15:43:07 +01:00
Ell
442be72630 app: port relevant transform tools to GimpGenericTransformTool
Derive GimpUnifiedTransformTool, GimpPerspectiveTool, and
GimpHandleTransformTool from GimpGenericTransformTool, eliminating
their common logic.

Remove gimp_transform_matrix_handles(), which is no longer used.
2018-01-27 07:30:30 -05:00
Ell
4c71ee8e7a app: add GimpGenericTransformTool
A subclass of GimpTransformTool, to be used as a base class for
transform tools that calculate their matrix based on 4 pairs of
input/output points, and that display the transform matrix as their
GUI (this includes the unified, perspective, and handle transform
tools; the next commit ports them over to
GimpGenericTransformTool).

When the resulting matrix of the input/output mapping sends any of
the output points to, or past, infinity, GimpGenericTransformTool
sets GimpTransformTool::transform_valid to FALSE, and displays an
appropriate message in the tool GUI, instead of showing the matrix.
2018-01-27 07:30:29 -05:00
Ell
e7b6103cc8 app: improve stability of Gaussian elimination in transform-utils
When picking a row whose leading coefficient is nonzero, use fuzzy
comparison against an epsilon, instead of exact comparison against
zero, to minimize the effect of numerical errors.
2018-01-27 07:30:28 -05:00
Michael Natterer
6d075aa10a app: some cleanup in the first of the two assert removals below 2018-01-23 19:50:07 +01:00
Sebastian Rasmussen
0c34db8aac Bug 792792 - Typo fix for an error message.
s/currupt/corrupt/
2018-01-22 19:13:56 +01:00
Jehan
4c2df9b365 app: all remaining g_assert() replaced by critical warning and return...
... in app/core.
Continuing on my crusade against asserting and crashing GIMP.
2018-01-22 16:20:04 +01:00
Jehan
b4c7dd8fd8 app: run gimp_projectable_get_graph() before gegl_node_get_parent()...
... on top-level layers.
There was even a comment for this, but I missed this when I moved some
code to the top of the function in commit b9577a783d. Now moving this
call up as well. This appeared to be more of a problem when merging
layers without a GUI (script-fu). I'm guessing the GUI calls this anyway
before.
2018-01-22 15:35:22 +01:00
Jehan
f87bc3fe09 app: we should not have any g_assert*() code if possible.
Replace all g_assert_not_reached() in app/core/ by g_return_if_reached()
or g_return_val_if_reached(). GIMP may handle a lot of creative work,
sometimes unsaved for hours. We should not just crash on purpose.
g_assert*() could theoretically be turned off on a glib build, but this
is nearly never done, and is not a solution either (actually it is
probably even worse because the broken code would just continue on a
forbidden path). It is much better to return with a warning on such
forbidden code paths, allowing someone to report a bug without
experiencing a crash and data loss.

For now, I only took care of g_assert_not_reached() inside app/core.
More g_assert*() code should be replaced.
Note: assert are acceptable in plug-ins though, but not in the main
executable, unless absolutely necessary (something happening so bad that
crash is better than continuing).
2018-01-22 12:46:37 +01:00
Michael Natterer
af2cb761de Bug 792744 - Gimp crashes attempting to merge down a hidden layer
gimp_image_merge_down(): return an error if the current layer is not
visible.
2018-01-21 23:58:42 +01:00
Jehan
b9577a783d Bug 792744 - Gimp crashes attempting to merge down a hidden layer.
Don't use g_assert(). Instead use g_return_val_if_fail().
This commit therefore does not fix the actual bug, but at least it does
not crash. GIMP simply outputs a warning upon trying to merge down a
hidden layer. The actual fix will follow later.
2018-01-21 21:12:21 +01:00
Michael Natterer
895c0f558f app: add small hack to make the generic operation tool always invisible
so it can't be added to the toolbox. It's entirely useless when
activated on its own.
2018-01-04 19:23:39 +01:00
Michael Natterer
84fab474a7 Bug 788870 - Abr corrupted files crashing GIMP
Fix the crashes from the third zip:

- forgot to guard the other writing place in the RLE decoder
- one byte after the buffer is still one byte too much
- protect against seeking to bogus offsets
2018-01-02 19:19:59 +01:00
Michael Natterer
221e18ab09 Bug 788870 - Abr corrupted files crashing GIMP
Add brush dimension/depth/compression sanity checks for v6 brushes,
and make sure we don't overrun the RLE decoder's destination buffer.

This properly rejects all brushes from the second zip in the bug.
2018-01-02 15:36:07 +01:00
Massimo Valentini
31a6796fa8 Bug 788870 - Abr corrupted files crashing GIMP when saved...
...in brushes user directory

Consider 8bim section size unsigned, to avoid seeking backward when a
malicious brush includes an 8bim section unknown to GIMP.

This avoids the possibility to start an infinite loop on GIMP start.

Found just a water drop in the ocean, GIMP is still not secure.

Mitch: Added more sanity checks on the Abr's width/height/bytes so now
all brushes in the zip attached to the bug are properly rejected
instead of crashing GIMP.
2018-01-02 13:04:12 +01:00
Tobias Stoeckmann
f98d1b3a76 Bug 789613 - core: Fix integer overflow on 64 bit systems
The C language only promotes data values up to (un)signed int,
which is 32 bit, if no larger data type is used within the
calculation. Having a multiplication of two gint variables,
even if the expected target variable is of type gsize (64 bit),
leads to a possible integer overflow.

This bug can be triggered in gimp_temp_buf_new, which is used
to allocate memory for given supplied dimensions and bytes per
pixel. If triggered, less memory than needed is allocated and
therefore allows out of boundary accesses, either resulting in
possible code execution or information leakage.

While at it, make sure that the supplied format can actually be
resolved to a bytes per pixel value. If not, return NULL.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2018-01-01 17:10:01 +01:00
Michael Natterer
8df06eb5cd app: get rid of GParameter and g_object_newv() (deprecated in GLib 2.54)
Replace gimp_parameter_*() utility functions with equivalent
gimp_properties_*() functions which deal with separate arrays of names
and values, and use g_object_new_with_properties() instead of
g_object_newv().
2018-01-01 15:20:05 +01:00
Michael Natterer
d91487e6af Revert "app: do not forbid merging down floating layers, instead anchor them."
This reverts commit 40bc5307dc.

It's not *exactly* the same. The floating selection can belong to a
channel or layer mask. Also, this belongs into the GUI layer, not the
core.
2017-12-31 13:56:00 +01:00
Jehan
9da25e6261 app: get_set_error() with domain == 0 is forbidden.
That makes critical errors:
> GLib-CRITICAL **: g_error_new_literal: assertion 'domain != 0' failed
2017-12-31 01:46:34 +01:00
Jehan
40bc5307dc app: do not forbid merging down floating layers, instead anchor them.
Anchoring a floating layer is basically equivalent to merge down. This
is already what we do in other merging actions (flatten image and merge
visible layers).
2017-12-31 00:19:14 +01:00
Jehan
cc47597aae app: gimp_image_merge_down() on a floating selection crashes GIMP.
Forbid merging down a floating selection.
Probably we can do something better. But that's a first step.
2017-12-30 23:30:19 +01:00
Jehan
d89ed759ef app: small logics improvement.
Current migration code would still return TRUE for success if the copy
of a regular file failed for any reason.
Also getting rid of some weird block and making sure we free dirname
only when it has been assigned a value.
2017-12-27 04:10:57 +01:00
Jehan
f14be48e74 app: protect user_install_dir_copy() against infinite recursivity.
When recursively browsing folders, there is always the risk of infinite
recursivity, in particular with symbolic links which can create loops.
Let's just assume that we don't have any data over 5 levels of
directories to avoid a security risk.
2017-12-27 03:56:53 +01:00
Jehan
cdfffc6924 app: add some warning for code which should not happen. 2017-12-26 17:47:05 +01:00
Jehan
88f33dc0b3 Bug 791934 - gimpressionist contains 2 identical brushes.
paintbrush.pgm and paintbrush01.pgm are binary identical. If they were
brushes we ship as data, that would be more annoying because they could
be used in scripts or in various other places. But here it looks they
are used for gimpressionist plug-in only, which means they are probably
not used in some random script. All it takes is probably only to
properly migrate gimpressionist presets.
Presets using "paintbrush.pgm" will be migrated to use
"paintbrush01.pgm" instead.
2017-12-26 17:39:30 +01:00
Jehan
cf67441782 app: make user_install_dir_copy() recursive.
In particular, I noticed that some data can be on 2 levels (or more?).
For instance gimpressionist presets were not migrated from 2.8 to 2.9
because of this.
2017-12-26 16:46:33 +01:00
Ell
c6cb985733 app: fix rotated brush boundary position
... after commit a0b73420ec.
2017-12-24 09:13:25 -05:00
Ell
eded91e118 Bug 753412 - New Canvas rotation feature rotates brush.
Replace the "lock brush size to zoom" paint option with a "lock
brush to view" option, which links the entire brush transform to
the view transform, so that the brush remains invariant in display
space under scaling, rotation, and reflection.
2017-12-22 17:52:29 -05:00
Ell
a0b73420ec app: add support for brush reflection
Add support for reflecting brushes as part of their transformation.
The reflection is performed as the last step of the transformation,
across the vertical axis.

The option to reflect the brush is not exposed in the UI, or
through the PDB, but is intended to be used for linking the brush
transformation to the view transformation, in the next commit.
2017-12-22 17:52:29 -05:00
Ell
27688ee752 app: fix angle calculation of generated brushes
... so that we don't effectively take the absolute values of
angles.
2017-12-22 17:52:29 -05:00
Ell
984ed6cefd app: constrain line angles in display space, not image space
Add an offset_angle parameter to gimp_constrain_line(), which
offsets the radial lines by a given angle.

Add gimpdisplayshell-utils.[ch], with two new functions:

  - gimp_display_shell_get_constrained_line_offset_angle():
    Returns the offset angle to be passed to
    gimp_constrain_line(), in order to constrain line angles in
    display space, according to the shell's rotation angle and
    flip mode.

  - gimp_display_shell_constrain_line():  A convenience function
    which calls gimp_constrain_line() with the said offset angle.

Use the new functions in all instances where we constrain line
angles, so that angles are constrained in display space, rather
than image space.

The only exception is GimpEditSelectionTool, which keeps
constraining angles in image space, since it's not entirely obvious
that we want to constrain angles of dragged layers/selections in
display space.
2017-12-22 06:32:24 -05:00
Tobias Stoeckmann
4fa0cd4dcf gbr/pat: Fix out of boundary read on illegal names
The file formats GBR and PAT contain names which are supposed to be
NUL-terminated within the files. If no such terminating NUL byte
exists, the parsers of GBR and PAT trigger an out of boundary read
during utf-8 conversion.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2017-12-21 22:09:54 +01:00
Jehan
5b9e277625 app, plug-ins: clean up previous commit by using g_error_set()...
... instead of g_message().
2017-12-21 21:55:04 +01:00
Massimo Valentini
657a754f98 Bug 789610: invalid gbr brush crashing GIMP 2017-12-21 21:50:09 +01:00
Thomas Manni
27512d802b Bug 791512 - make the selection boundary detection the same as 2.8
Replace the GIMP_BOUNDARY_HALF_WAY macro by two others : one for perceptual and
one for linear gamma.

Use the GIMP_BOUNDARY_HALF_WAY_LINEAR to compute channels and floating selection
boundaries.
2017-12-18 21:01:30 +01:00
Michael Natterer
b05cfc6050 pdb: (try 3) move PDB generation and sources to toplevel/pdb
It never belonged inside "tools". Also rename its "pdb" subdirectory
to "groups". This had to happen before 2.10 so cherry-picking between
branches doesn't become a nightmare in the future.
2017-12-17 14:16:08 -05:00
Ell
4c55417951 app: copy expanded state of duplicated items
... so that duplicated group layers maintain the expanded state of
the original.
2017-12-08 11:12:33 -05:00
Ell
06f41db6aa app: remove redundant opacity clamp from gimp_layer_new()
The opacity will be clamped by gimp_layer_set_opacity().
2017-12-08 09:12:36 -05:00
Ell
776b4a9a6b Bug 791386 - New layer with AUTO everything always uses normal mode
In gimp_layer_new(), set opacity and mode using the setter
functions, instead of modifying the members directly, so that all
the necessary side effects take place.
2017-12-08 09:04:18 -05:00
Ell
0beef7d97d app: in GimpItemTreeView, use color tag of parent for children with no tag
Add gimp_item_get_merged_color_tag(), which returns the color tag
of the nearest ancestor (including the current item) that has a
color tag other than NONE.  Use this function in GimpItemTreeView,
instead of gimp_item_get_color_tag(), to set the cell color of
items, so that item's with a NONE color tag inherit the color of
their parent.  Add a boolean "inherited" parameter to
gimp_get_color_tag_color(), which indicates if the color tag is the
item's actual color tag, or an inherited color tag, and modify the
returned color accordingly, so that inherited colors are less
saturated/lighter than non-inherited ones.
2017-12-07 17:02:05 -05:00
Ell
fa9a023c27 app: strength-reduce pass-through groups to normal groups
Override GimpLayer::get_effective_mode() in GimpGroupLayer, to
perform strength-reduction of pass-through groups to normal groups
under certain conditions (see gimp_group_layer_get_effective_mode()
for the logic.)

The main motivation for this is the fact that Photoshop uses pass-
through mode as the default mode for groups, resulting in many PSDs
using pass-through groups generously and unnecessarily.  Since
pass-through groups are more expensive that normal groups, reducing
them to normal groups when possible can make a big difference.

Note that, while the results of the strength-reduced composition
are theoretically equivalent, there may be small differences in
practice due to numerical errors, especially when using low
precision.  This is unlikely to be an issue, but, just in case,
allow disabling this optimization using the
GIMP_NO_PASS_THROUGH_STRENGTH_REDUCTION environment variable.
2017-12-06 14:51:47 -05:00
Ell
bdba43e495 app: add gimp_layer_get_effective_mode()
gimp_layer_get_effective_mode() returns the actual layer mode,
blend space, comosite space, and composite mode used for the
layer's mode node, allowing them to be different from the values of
the corresponding layer properties.  The aim is to allow us to
replace expensive layer configurations with cheaper but equivalent
ones transparently.  This is used in the next commit to replace
pass-through groups with normal groups under certain conditions.

The effective values are computed by the new
GimpLayer::get_effective_mode() virtual function.  The default
implementation provided by GimpLayer returns the corresponding
layer properties as-is (replaceing AUTO with concrete values).
Subclasses can override this function, providing more
sophisticated logic.
2017-12-06 14:51:47 -05:00
Ell
93ed1048c6 app: remove gimp_filter_is_active() prototype
Leftover from commit f5d1686a21, not
actually defined.
2017-12-06 10:20:01 -05:00
Ell
6a7c0d623d app: handle visbility/excludes-backdrop changes in floating sel.
When attaching a layer as a floating selection to a drawable,
unbind its visiblility from its activeness, as per the previous
commit, and use its visibility to control the activeness of the
drawable's floating selection filter.

Properly update the drawable when the floating selection's
visibility and excludes-backdrop properties change.
2017-12-05 16:17:48 -05:00
Ell
f5d1686a21 app: add GimpFilter::active property; move ::visible to GimpItem
Add an "active" property to GimpFilter, which replaces its
"visible" property.  The new property assumes the lower-level role
"visible" had -- controlling whether the filter has any effect as
part of its parent filter-stack.

Add a "visible" property to GimpItem, separate from the "active"
property, which assumes the higher-level role "visible" had --
controlling whether the item is considered "visible", as per the
GUI.  By default, the item's "visible" property is bound to the
filter's "active" property, so that changes in visibility directly
affect the filter's "activeness"; this binding can be controlled
using the new gimp_item_bind_visible_to_active() function.

This distinction is currently necessary for floating selections.
Floating selection layers must not be active in their parent stack,
regardless of their visibility, in particular, so that their mode
node doesn't hide the entire backdrop when their composite mode
excludes the backdrop (i.e., when it's dst-atop or src-in).
Instead, their visibility should affect the activeness of the
floating-selection filter of the drawable they're attached to.
This is handled by the next commit.
2017-12-05 16:12:46 -05:00
Ell
e02cb6adfe app: exclude invisible filters from filter-stack graph
Currently, when a GimpFilter's visibility changes, we rely on its
various visibility-changed signal handlers to rewire the filter
node's graph to reflect the change.  This has two main
disadvantages:

  - There's no easy, generic way to toggle a filter's  effect,
    especially one that is not subclassed, since GimpFilter only
    takes care of the case where visibility becomes FALSE, and does
    nothing by itself when it becomes TRUE again.

  - While GimpDrawable does handle the visibility => TRUE case, it
    doesn't disconnect the filter's input from its mode and
    (potentially) source nodes when it becomes invisible.  As a
    result, while none of the drawable's graph is processed as part
    of the composition when not visible, the mode and source nodes
    do get invalidated when the filter's input is invalidated, such
    as while painting on a layer below the drawable.  This is
    particularly bad for pass-through groups, since their source
    node can be an arbitrarily complex graph, whose invlidation
    incurs a nontrivial overhead.

Instead, don't touch the filter's node at all when visibility
changes, and rather have GimpFilterStack remove it from the graph
entirely when the filter becomes invisible, and re-add it once it
becomes visible again.  This solves both of the above problems, as
well as simplifies the code.
2017-12-05 16:12:08 -05:00
Jehan
5aa9428445 app: migrate plug-in-gauss shortcuts to filters-gaussian-blur.
Since commit ff59aebbe8, blur-gauss plug-in and the associated
"plug-in-gauss" action don't exist anymore. Migrate any custom shortcut
to "filters-gaussian-blur", which is the expected replacement.
See also bug 775931.
2017-12-05 02:07:16 +01:00
Jehan
482b907cb7 app: reorder alphabetically changed action paths in migration code.
This allows for easier code reading and changing.
2017-12-05 02:07:16 +01:00
Ell
4e4c1cd57e Bug 790810 - Nested layer groups lead to a deadlock with multithreading
Use gimp:buffer-source-validate, introduced in the previous commit,
for the source node of GimpDrawables.  This avoids threading issues
with layer groups, or any other drawables that may use a validating
buffer, by making sure the buffer is validated before any
succeeding operations, and hence the associated graph is processed
on the same thread as the parent composition.

Restore multithreaded processing in GimpOperationLayerMode.
2017-12-04 16:03:15 -05:00
Ell
e042c82d59 app: flush group proj. switching from pass-through to non-pass-through
When switching a group layer from pass-through mode to a non-pass-
through mode, flush the projection synchrnously, to make sure that
the projection's buffer gets properly invalidated at that point,
and can be subsequently used as a source for the rest of the
composition.

Add a boolean 'pass_through' member to GimpGroupLayerPrivate, which
indicates if the group is a pass-through group, and use it instead
of checking the group's mode, so that we can detect that the group
used to be a pass-through group when the mode changes, and to
simplify the rest of the code.
2017-12-02 15:35:08 -05:00
Ell
9f79be44f8 app: flush pass-through groups' projection asynchronously
The source node of pass-through groups doesn't use the projection's
buffer, hence there's no need to invalidate it synchronously, which
is faster.
2017-12-02 10:38:34 -05:00
Ell
61ae3089ad app: avoid begin_render()/end_render() when flushing projections
... since we don't actually render anything, only invalidate.
2017-12-02 10:38:34 -05:00
Ell
be97b97a2b app: set group layer projection priority according to depth
Set the priority of group-layer projections according to the group
layer's depth, so that top-level groups have a priority of 1
(compared to a priority of 0 for the image projection), and nested
groups have a priority one greater than their parent (in other
words, shallower groups have higher priority than deeper groups,
all of which have lower priority than the image.)

This makes pass-through groups much faster, in particular.
2017-12-02 10:38:34 -05:00
Ell
1a2c0e8198 app: add gimp_projection_{get,set}_priority()
... which control the priority of the projection's idle source.

The projection's priority is specified relatively to
GIMP_PRIORITY_PROJECTION_IDLE (i.e., a priority of 1 results in an
idle source with priority GIMP_PRIORITY_PROJECTION_IDLE + 1, etc.)
2017-12-02 10:38:34 -05:00
Ell
a52ff51990 app: add GimpViewable::ancestry-changed signal, get_depth() function
Add GimpViewable::ancestry-changed signal, which is emitted when
the viewable's ancestry changes, i.e., when its parent, or the
parent of one of its ancestors, changes.

Add gimp_viewable_get_depth() function, which returns the
viewable's depth in the hierarchy, i.e., its ancestor count.
2017-12-02 10:38:34 -05:00
Piotr Drąg
33d4095fd5 app: fix a typo (transarent) 2017-11-30 16:23:32 +01:00
Ell
a08a9171d7 app: modify unabbreviated value descriptions of GimpGradientColor
... to match the old gradient editor menu labels.
2017-11-30 04:45:08 -05:00
Ell
d3e527a959 libgimpbase, app: add abbreviations to gradient enums
The value descriptions of GimpGradientColor,
GimpGradientSegmentColor, and GimpGradientSegmentType enums appear
in the on-canvas gradient editor UI, as combo-box items in the tool
GUI overlay.  Since we want to keep the overlay as small as
possible, we previously used abbreviations for these descriptions
(e.g., "FG (t)", instead of "Foreground (transparent)").

Replace the abbreviated descriptions with unabbreviated ones, and
move the abbreviations to the "abbrev" parameter.  This way we get
the abbreviated version in the combo-box, and the full version in
the combo-box's menu.
2017-11-30 03:10:15 -05:00
Ell
f7d6805ebb */Makefile.am: add abbreviations to generated enum files
Update the dprod production of generated enum files to include
abbreviated value descriptions, as per the previous commits.

Add a comment for translators above the abbreviated descriptions,
specifying the full description they abbreviate.
2017-11-30 03:10:14 -05:00
shark0r
10e3295581 Bug 790911 - fix jaggy stroke in Tiling Symmetry Painting 2017-11-29 01:13:48 +01:00
Jehan
d228e76ebe app: fix memory leak.
GMatchInfo data created by g_regex_match() must be freed.
2017-11-26 04:01:19 +01:00
Ell
35b0f6102e app: update group-layer item offset after updating offset node
When the group's offset changes, update the item's offset *after*
updating the group's offset node, so that the item's offset nodes
and the group's offset node are in sync when the corresponding
"notify" signals are emitted.
2017-11-24 12:34:25 -05:00
Tobias Stoeckmann
30d29e03f8 Bug 789614 - Fix heap overflow in pattern handling
It is possible to trigger a heap overflow while opening a malicious
pattern due to integer overflows.

The validation is adopted from plugin-parser. It also takes a proper
cast to gsize to avoid integer overflow in size calculation.
2017-11-20 23:10:36 +01:00
Michael Natterer
7e613516a2 Bug 788403 - When importing an image, don't change to "untitled"...
...after exporting the image

Call gimp_image_name_changed() in both gimp_image_clean_all() and
gimp_image_export_clean_all() so we clear the cached displayed URI in
all cases, even if this means we're emitting "name-changed"
redundantly some times.
2017-11-19 19:21:15 +01:00
Ell
e19958c5f1 app: use SAFE_CLAMP() in histogram bin calculation
The current code relies on undefined behavior, which, while seems
to work, is fragile.  Use SAFE_CLAMP() instead.
2017-11-19 07:13:24 -05:00
Ell
6036217d20 app: improve elimination of trivial blend-tool edit actions
... from the undo stack

When a blend-tool edit action modifies the gradient, do a deep
comparison of the original gradient against the current gradient,
to test if anything changed, instead of just assuming that
something did change.
2017-11-16 11:55:13 -05:00
Michael Natterer
19a28cc709 Revert "app: do not add undo step when clearing an already empty channel."
This reverts commit 9c94072213.

Such things do not belong into the core but into the GUI.
2017-11-12 23:42:43 +01:00
Michael Natterer
f12d0d8c29 Bug 789764 - Please add Paste In Place feature
Add "In Place" variants for all sorts of pasting:

- extend the GimpPasteType enum with IN_PLACE values
- add the needed actions and menu items
- merge the action callbacks into one, taking an enum value as parameter
- refactor the pasting code in gimp-edit.c into smaller functions

We probably have too menu items in the "Edit" menu now, needs to be
sorted out.
2017-11-12 18:41:05 +01:00
Ell
4ded26c4f1 app: update group layer offset before calling gimp_pickable_flush()
In gimp_group_layer_update_size(), when the layer's bounds have
changed, update the group layer's offset before the call to
gimp_pickable_flush() when reallocating the projection.  Otherwise,
if the group layer's graph isn't constructed yet, it will get
constructed during the call to gimp_pickable_flush(), however,
gimp_group_layer_get_graph() will pick up the old coordinates for
the offset node.
2017-11-11 17:51:02 -05:00
Ell
c49a21d95c app: improve histogram bin calculation
A fix to last commit: map values greater than G_MAXINT to the top
bin, not the bottom bin.
2017-11-08 04:58:04 -05:00
Ell
b2b6552f1f Bug 788394 - Crash (segmentation fault) when calculating a histogram ...
... upon NaN values

Make the histogram bin calculation NaN-safe, by mapping NaNs to 0.
Ideally, NaNs should probably not be counted at all, but since we
already count negative values as 0, and > 1 values as 1, we might
as well not pessimize performance over it, at least until we add
support for unbounded histograms.

At the same time, improve rounding in the bin calculation, so that
the result is more accurate.
2017-11-07 18:21:31 -05:00
Ell
bc9f179edf app: add gimp_data_is_{copyable,duplicatable}() to gimp_data.h
Forgot to add it to last commit :P
2017-11-04 22:13:31 -04:00
Ell
2fe6575d7e Bug 789901 - Gimp allows duplicating non-duplicatable data objects ...
... leading to a crash

Add gimp_data_is_copyable() and gimp_data_is_dulicatable().

Use gimp_data_is_duplicatable() when setting the sensitivity of the
various "foo-duplicate" actions, instead of inspecting the object's
GimpDataClass::duplicate pointer directly, since this is no longer
an indication of whether a GimpData object is duplicatable or not
(since commit 33de4d5530).
2017-11-04 22:00:29 -04:00
Ell
089bfe4e3d app: copy brush spacing when copying generated brushes
When copying a generated brush, copy its "spacing" property, in
addition to the other properties, which hasn't been previously
copied by ::duplicate().
2017-11-04 22:00:29 -04:00
Ell
880d3bd182 app: port GimpData subclasses from ::duplicate() to ::copy()
Finish up commit 17583ff04a, which
ported GimpGradient from ::duplicate() to ::copy(), by doing the
same for the rest of the GimpData subclasses that implement
::duplicate().

We still keep GimpData's ::duplicate() virtual function around,
even though it now points to the default implementation (which uses
::copy()) for all subclasses, since ::copy() is stronger than
::duplicate(), and we might want to have certain GimpData types
that are duplicatable, but not copyable.
2017-11-04 22:00:29 -04:00
Ell
bccef43049 app, pdb: prevent custom gradient from being renamed
Make internal data objects non-renamable, even if they're writable,
through gimp_data_is_name_editable().  Currently, the only such
object is the custom gradient.

Prevent changing the name of non-renamable data by making the name
entry of GimpDataEditor non-editable whenever
gimp_viewable_is_name_editable() is FALSE, even if the data is
otherwise editable.

Prevent the vairous PDB -rename() functions from renaming non-
renamable data, by adding a GimpPDBDataAccess flags type,
specifying the desired access mode for the data -- any combination
of READ, WRITE, and RENAME -- and replacing the 'writable'
parameter of the gimp_pdb_get_foo() functions with an 'access'
parameter.  Change the various .pdb files to use READ where they'd
used FALSE, and WRITE where they'd used TRUE; use RENAME, isntead
of WRITE, in the -rename() functions.
2017-10-30 17:22:29 -04:00
Ell
9eb75cde00 app: use G_FILE_CREATE_NONE for saved internal data files
Use G_FILE_CREATE_NONE, instead of G_FILE_CREATE_REPLACE_DESTINATION,
when saving internal data files, for consistency with the other files
we save.
2017-10-30 07:40:53 -04:00
Ell
e4440e3fdb app: save custom gradient across sessions
Add a framework for saving and restoring internal data objects, in
gimp-internal-data.c.  Internal data objects are saved in separate
files under a new "internal-data" subdirectory of the user's gimp
directory.  The internal data is saved, restored, and cleared
together with the tool options.

Use this to save and restore the custom gradient.  In the future,
we might add similar writable internal data objects that we'd want
to save.
2017-10-29 10:19:07 -04:00
Ell
3b15ff5d30 app: convert bg color to image color space when removing alpha
When removing a layer's alpha channel, convert the background color
from sRGB to the image color space before compositing the layer on
top of it.
2017-10-24 14:35:05 -04:00
Ell
d027a059ef app: respond to viewable expanded state changes in container views
Add an "expanded-changed" signal to GimpViewable, which should be
emitted by subclasses when the viewable's expanded state changes.
Emit this signal when the expanded state of group layers changes.
Respond to this signal in GimpContainerView, by calling a new
expand_item() virtual function.  Implement expand_item() in
GimpContainerTreeView, expanding or collapsing the item as
necessary.
2017-10-22 12:30:21 -04:00
Ell
0c305bdb0f app: use the layer's composite space when flattening it
Add a composite_space parameter to gimp_gegl_create_flatten_node()
and gimp_gegl_apply_flatten(), which controld the color space --
linear or perceptual RGB -- used for the operation (instead of
hardcoding it to linear).

When removing a layer's alpha channel, use the layer's composite
space for the flattening.  When flattening an image, use the bottom
layer's composite space.  Keep using linear space when creating a
channel or a mask from a drawable with alpha.
2017-10-21 11:44:27 -04:00
Ell
96efde0f22 app: add gimp_layer_get_real_{blend,composite}_{space,mode}()
... which return the layer's blend/composite space/mode.  However,
unlike the non-"_real" versions, these functions never return AUTO
-- instead, they return the actual space/mode that AUTO maps to for
the current layer mode.

When changing a layer's blend/composite space/mode, avoid
updating the drawable if the real space/mode didn't change (i.e.,
if changing from AUTO to the concrete value, or vice versa.)
2017-10-21 11:42:39 -04:00
Ell
8d12fada8a app: implement blend tool gui for gradient endpoints
Allows setting the endpoint's position, its color, and its color
type.
2017-10-09 12:48:55 -04:00
Ell
1f3030eb41 app: improve curved gradient segment sampling
Improve the sampling performance of curved gradient segments, and
its behavior when the segment's midpoint is close to one of its
limits.
2017-10-09 12:48:52 -04:00
Ell
1b2a395e88 app: improve num. stability of gimp_gradient_segment_range_compress()
When using gimp_gradient_segment_range_compress() to expand a 0-
length segment, redistribute the range's endpoints and midpoints
uniformly, rather than using the regular code path, which would
result in NaN values.

Make sure that the left and right endpoints of the range are
*exactly* equal to the new left and right values.  Previously,
they could be slightly off due to numerical errors.
2017-10-09 12:48:52 -04:00
Ell
3aff0a1a0e app: treat gradient segments as clopen ranges
Treat gradient segment exents as [left, right) ranges, instead of
[left, right], so that they don't overlap, and each point
corresponds to a unique color.

Perform less comparisons in gimp_gradient_get_segment_at_internal().
2017-10-09 12:48:52 -04:00
Ell
d710773aba app: add gimp_gradient_segment_range_merge()
... which merges a segment range into a single segment, that spans
the entire range, and has the same endpoint colors.  The merged
segment's midpoint is at its center, and its blend function and
coloring type are those of the range's segments if they're uniform,
or the default ones otherwise.
2017-10-09 12:48:51 -04:00
Ell
082f6a4122 app: add gimp_gradient_segment_range_get_n_segments()
... which returns the number of segments in a range.
2017-10-09 12:48:51 -04:00
Ell
c5faf02759 app: add gimp_gradient_split_at()
... which splits a gradient segment at an arbitrary position.

Implement gimp_gradient_segment_split_midpoint() in terms of the new
function.
2017-10-09 12:48:51 -04:00
Ell
6840dabad4 app: add gimp_gradient_segment_get_{left,right}_flat_color()
... which returns the flat (context-independent) left and right
colors of a egment.  Replace code that calculates the flat color
explicitly with calls to these functions.
2017-10-09 12:48:51 -04:00
Ell
6971b89397 app: implement compare() for GimpGradient
Order the custom gradient before all the other gradients, and use
the default ordering for the rest.
2017-10-09 12:48:51 -04:00
Ell
17583ff04a app: implement copy() for GimpGradient
... instead of duplicate().
2017-10-09 12:48:51 -04:00
Ell
2ad9f40dbe app: add "custom" gradient
An internal gradient object, that will be used by the blend tool
when editing a gradient.  By default, the active gradient will not
be edited directly, but rather, upon editing, the active gradient's
contents will be copied to the custom gradient, which will then
become the active gradient and be edited.  This allows editing both
writable and nonwritable gradients without modifying them, and
without having to duplicate them.
2017-10-09 12:48:50 -04:00
Ell
f36f234fc0 app: add compare() virtual function to GimpData
... which subclasses can override to refine comparison.  Provide a
default implementation that uses the current logic.
2017-10-09 12:48:50 -04:00
Ell
33de4d5530 app: add gimp_data_copy()
... which copies the contents of a GimpData into an existing GimpData,
without creating a new instance.

Add a copy() virtual function to GimpData, which subclasses can
override to implement copying; gimp_data_copy() may only be called
for types that implement copy().  Keep the duplicate() virtual
function around, but provide a default implementation that creates
a new object of the source type, and uses copy() to copy the source
object into it.
2017-10-09 12:48:50 -04:00
Ell
9e26d7ea5f app: add handle-clicked signal to GimpToolLine
... which is emitted when a handle is single/double/tripple clicked.

The signal handler returns a boolean value.  A return value of TRUE
stops further event processing, while a return value of FALSE allows
it.
2017-10-09 12:48:50 -04:00
Ell
50acb6690d app: add prepare-to-remove-slider signal to GimpToolLine
The signal is emitted when a slider is dragged away from the line,
and will be removed when the button is released, and when the
slider is dragged back to the vicinity of the line, and won't be
removed.  The last parameter of the signal is a boolean flag
differentiating between the two cases.

Note that a remove-slider signal may be emitted without a preceeding
prepare-to-remove-slider signal, however, is a prepare-to-remove-
slider signal is emitted with a TRUE last parameter, it must be
eventually followed by a remove-slider signal, or by another
prepare-to-remove-slider signal with a FALSE last parameter.
2017-10-09 12:48:49 -04:00
Ell
bac7dac4ba app: allow adding and removing sliders to/from a GimpToolLine
Add support for adding and removing sliders to/from a GimpToolLine,
using three new signals:

  - can-add-slider:  Takes a double argument in the range [0,1],
    indicating a location along the line, and returns a boolean
    value, indicating whether a slider can be added at that
    location.

  - add-slider:  Takes a double argument in the range [0,1],
    indicating a location along the line, for which can-add-slider
    returned TRUE.  In response, should add a new slider at that
    location, and return its index, or a negative value if no
    slider was added.

  - remove-slider:  Takes a slider index.  In response, may remove
    the slider.

On the UI side, when the cursor is close enough to the line, but
not within the hit area of an existing handle, GimpToolLine checks
if a slider can be added at the cursor position, using can-add-
slider.  If a slider can be added, a dashed circle appears at the
cursor position along the line, indicating where a slider will be
added.  The cursor is added by clicking, which emits an add-slider
signal; if the signal returns a slider index, the new slider is
selected, and can be subsequently dragged.

Removing a slider is done by either selecting the slider and
pressing backspace (or delete, although we don't actually forward
it to the tool atm,) or by "tearing" the slider: when dragging
the slider, if the cursor is far enough from the liner, a dashed
circle appears around the slider, and releasing the mouse removes
the slider.
2017-10-09 12:48:49 -04:00
Michael Natterer
ebbcaddae7 app: enable XCF version 12 which finally saves big-endian tile data only 2017-10-01 17:28:20 +02:00
Michael Natterer
6dfe04e928 Bug 787848 - Duplicate image crashes if there is an empty layer group
An empty gorup layer has no extent, so we fake its extents to be at
least 1x1 whenever its projection is being recreated, because we can't
have a 0x0 buffer in a drawable. This safeguard was forgotten in
gimp_group_layer_convert_type() which gets called on image duplicate.
2017-09-18 20:31:21 +02:00
Jehan
9c94072213 app: do not add undo step when clearing an already empty channel.
See also bug 787545 about single-clicking with a selection tool creating
an undo step even when there were already no selections.
2017-09-13 13:02:00 +02:00
Michael Natterer
c63d812be8 libgimpcolor: rename gimp_color_profile_get_format() to _get_lcms_format() 2017-09-02 18:47:04 +02:00