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.
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.
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.
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.
Our own implementation is much better.
I don't make it into a GUI yet, but at least the CLI option will use the
new implementation in plug-ins as well, which will be quite useful.
Using g_get_user_data_dir() is maybe right on Win32 (for this roaming
vs. local directory logics), but not on Unix-like systems, where we end
up trying to write in the data directory (usually not even supposed to
be writable by applications).
Also while at it, I replace g_get_prgname() by PACKAGE_NAME. It turns
out that this function returns NULL, maybe because of the init order.
Actually ideally, this file should rather go under:
$XDG_CACHE_HOME/GIMP/<version>/
But last we discussed this, it was decided that files should not spread
too much (though I still disagree!).
If the backtrace() API is available, it should always be possible to
debug. Still, display a message whether or not gdb or lldb are present,
as preferred debugging solutions (much better traces).
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.
I missed a few of the syntax bugs ("%n" and these sort of things), but
also a broken link to the bugtracker URL (don't add spaces). Also I
reformated the long lines by running "make update-po" again.
Note by Jehan: this was initially contributed on the github mirror:
https://github.com/GNOME/gimp/pull/16
I would usually just tell them (which I did!) to post the patch to our
official bugtracker, and/or get in touch with the translation team, but
that was a brand new language support for the Windows installer so even
though I don't understand Indonesian, at least I know that doesn't break
anyone's previous work. Moreover setting up the new `.po` file requires
a bit of knowledge which a first-timer (contributor said he was) may
choke on. So that's me being nice and not wanting to waste a good first
contribution. :-)
I still had to manually copy-paste the translation since the translator
was attempting to modify setup.isl.in directly. Also I fixed a few
format syntax things (%n, %1, &Something… these sorts of things).
... stacktrace into a file on non-Win32 systems.
This has a few advantages:
- First, we don't need to duplicate stacktrace code inside the
independent gimp-debug-tool (I even noticed that the version in the
tool was gdb-only and not updated for lldb fallback; proof that code
duplication is evil!). Instead, even on a crash, we can create the
stacktrace from the main binary and simply pass it as a file.
- Secondly, that allows to fallback to the backtrace() API even for
crashes (this was not possible if the backtrace was done from a
completely different process). That's nice because this makes that we
will always get backtraces in Linux (even though backtrace() API is
not as nice as gdb/lldb, it's better than nothing).
- Finally this makes the code smaller (i.e. easier to maintain), more
consistent and similar on all platforms.
... our own implementation.
Though the GUI stacktrace is better for most (because it is visible even
when not run in a terminal), the CLI options are quite useful too and
may still be preferred by some, in particular developers. So it may as
well be benefiting from the better implementation. Glib traces are quite
weak even though they also use gdb and debug info are present (often,
even though I had these traces, I had to run gdb separately; now it
won't be necessary in many cases). My traces include more information.
Note that I didn't implement gimp_print_stack_trace() from previous
gimp_get_stack_trace() because I cannot allocate a string after some
types of crash (e.g. segmentation faults). So instead,
gimp_print_stack_trace() now take care optionally of both cases: either
allocating a string, or directly pipe to a file descriptor.
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.
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.
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 :).
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.
It seems the current code simply forgot to break on indexed types and
therefore hit some g_return_*if_reached() code breaking the logics.
Looking further, I see some code taking care of indexed images and
converting them to RGB. And testing after adding breaks looks like it
works just fine.
So I am assuming this was just forgotten breaks indeed, and not on
purpose not allowing indexed images (if that were the intent though,
this is not how it should be done).
This avoids warnings when the handle positions the handle-transform
tool result in a matrix that transforms the TransformGrid's handles
(which are all invisible) to coordinates that are outside of the
corresponding properties' range.
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.
Normally, the model would try to avoid notifications when a set()
doesn't change anything, but with g_object_set() that's not possible.
Do the same in the propwidgets' callbacks and avoid potentially
expensive notifications at the cost of a cheap g_object_get().
Also fix the syntax of "Since:" and "Deprecated:" annotations.
I was directed by Massimo to some bug which was repeatedly generating
dozens of thousands of GEGL WARNINGs and that was completely taking over
the GUI if redirected to GimpErrorDialog. Currently GEGL warnings are
not redirected there, but the problem is still there, and we don't want
GIMP warnings to freeze the whole GUI either.
So only increment the repeat variable upon gimp_message_box_repeat() and
delay actual GUI update to a later low-priority idle function.
Override GimpStroke::transform() for GimpBezierStroke, using
gimp_transform_bezier_coords() to transform the stroke's segments,
so that clipping done properly.
The next commit is going to perform clipping when transforming
Bezier strokes. When parts of the stroke get clipped, the result
consists of multiple strokes.
Adapt gimp_stroke_transform() in preparation, to allow for the
transformation to result in multiple strokes, by adding a GQueue*
parameter that receives the transformed strokes.
For convenience, we allow passing NULL as the argument, in which
case the current behavior is maintained. However, NULL should only
be passed when clipping is known to be unnecessary.
Adapt the rest of the code for the change.
Note that this technically affects public API: existing stroke
object IDs now become invalid after transforming their containing
vectors object. However, this is unlikely to affect code in
practice.
... which transforms a single cubic Bezier segment, performing
clipping by the near plane, to avoid erroneously transforming parts
of the curve behind the camera.
... 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().
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.