This fixes:
> app/core/gimpitemlist.c:632:7: warning: ‘g_pattern_match_string’ is deprecated: Use 'g_pattern_spec_match_string' instead [-Wdeprecated-declarations]
The new function appeared in GLib 2.70 which is our current minimum GLib
requirement, so the replacement is fine.
Since we now generate actions for GEGL ops, we might as well generate menu items
for these too.
What I did:
- Move the "GEGL Operation…" tool (generic dialog with a drop-down list of all
non-ignored GEGL ops) to Tools menu.
- Create a "GEGL Operations" submenu in Filters > Generic.
- Move "GEGL Graph" to the top of this new submenu.
- Generate a new menu item for each generated action tied to a GEGL plug-in,
alphabetically sorted.
Also get rid of various old references to menurc and don't install it anymore to
etc/ (neither the new shortcutsrc as it doesn't look like it brings much value
to do so).
Right now, our actions are added both in the GActionMap (a.k.a. as
GApplication|GtkApplication) and with the old GtkActionGroup API. The later code
is meant to be removed soon.
A major difference with the old implementation is that we don't add the actions
in separate action groups. Even though GLib has a GActionGroup concept, these
don't seem to be used at all when adding actions on the GtkApplication level.
It might mean that eventually we will even remove the GimpActionGroup code and
move everything up one level.
Of course, I am still evaluating if we really want an action group concept, in
which case, we could simply recreate it, but I'm actually unsure how useful it
is. The only place where I see a use to this is in the shortcut settings (to
organize actions by groups), but even there, it was rarely useful to me. I
usually rather search for actions by text search anyway.
GIMP expects CSS palettes to end with a ";" when importing. However,
GIMP exports CSS lines without ";". This means GIMP can't reopen its
own exported CSS palettes.
The ";" was removed from the regex since CSS2 does not require
the last line to end with a ";". However, CSS3 and above
require ending all lines with a ";", so it is added to the
export script.
gimp_display_shell_render() writes to a GeglBuffer backed by allocated memory
(shell->profile_data). Unfortunately while converting prevision in
gimp_image_convert_precision(), we change the "precision" property (hence the
source format) first, hence end up trying to write data in a too small buffer.
This crash was hard to find as it was not showing up on my machine (though it
did produce rendering artifacts!), unless I built both GIMP and babl with
`b_sanitize=address`.
Note that an alternate fix was to make sure that the profile_data buffer is big
enough (by calling gimp_display_shell_profile_update() before rendering), but
anyway the image is in an inconsistent state while conversion is in progress:
whereas the `src_format` is the new one, the `src_profile` is still the old one
(and cannot be changed before we finish converting).
Moreover the render happen regularly on progress signals, once after each
converted drawable. So each of these rendering step happens in an inconsistent
state, with the wrong profile set, some of the drawables converted and others
not yet.
We could still render properly if each drawable's buffer used space-aware format
(thus allowing different drawables to use different profiles/spaces), but it
feels over-engineering the problem. It might be much better to ignore rendering
steps while converting the image precision. Moreover it would obviously make a
faster conversion.
See discussions in #9136 for this crash, which didn't have dedicated report
AFAIK.
(cherry picked from commit de25be9210)
Note: on the `master` branch, even with sanitized code, I don't get the crash.
Yet this change seems relevant enough that I'm adding it.
Simplifies chooser widgets (e.g. GimpBrushSelect) by eliminating attributes (e.g. opacity) of chosen resource.
See #8745, but this commit fixes that by first refactoring the code.
Refactors GUI widgets (e.g. GimpBrushSelectButton and GimpBrushSelect etc.)
Refactor by "Extract class" GimpResourceSelectButton from GimpBrushSelectButton etc.
This moves common code into an inherited class (formerly called GimpSelectButton)
but the subclasses still exist.
The subclasses mainly just do drawing now.
Refactor by "Extract module" GimpResourceSelect from GimpBrushSelect etc.
Moves common code into one file, generic at runtime on type of GimpResource,
that is, the new code dispatches on type i.e. switch statements.
In the future, when core is changed some of that can be deleted.
The files gimpbrushselect.[c,h] etc. are deleted.
The module adapts the API from core to the API of callbacks to libgimp.
Note that core is running the resource chooser (select) widgets remotely.
Core is still calling back over the wire via PDB with more attributes
than necessary.
The new design gets the attributes from the resource themselves,
instead of receiving them from core callback.
The libgimp side adapts by discarding unneeded attributes.
In the future, core (running choosers for plugins) can be simplified also.
Fix gimp_prop_chooser_brush_new same as other resources.
Finish changes, and clean style.
Annotations
So procedures can declare args and GimpProcedureDialog show chooser
widgets
Fix so is no error dialog on id_is_valid for resources
Palette.pdb changes and testing
Memory mgt changes
Gradient pdb
Font and Pattern tests
Test brush, palette
Cleanup, remove generator
Rebase, edit docs, install test-dialog.py
Whitespace, and fix failed distcheck
Fix some clang-format, fix fail distcheck
Fix distcheck
Cleanup from review Jehan
These are not used anymore anywhere in our codebase! I'm sure some issues still
exist in various places, yet we can now consider that the multi-item awareness
project is finally over! Wouhou! 🥳
One big question which remains is whether I want to get back to the old naming
of "active" items, rather than "selected" items. The main reason to change the
wording globally was to be able to easily find remnants of non-multi-item aware
code. Now that it's all gone, I could very simply revert to the old naming.
This is in particular a big question for the public API for plug-ins, as the
"active" wording has been used for decades litterally. The only difference now
with how it used to be is that we could have several active items at once.
This is because gimp_drawable_edit_clear() would also clear the full drawable in
the special case when there is no selection at all. So as we were inverting the
"all" selection, we were ending up in this special-case.
This second GIMP_IS_ITEM() test was obviously for the iter2->data item. This
fixes handling cases when aligning/distributing a mix of GimpItem-s and guides.
I'm not sure if there are a lot of cases where we might want to use the layer
extents for items to align while using the contents extents for the reference
(or the other way around). It looks to me you either want one of the other for
all the items in the most common case.
So for now, let's apply this option to both the items to align and the reference
item. We'll see if anyone wants a separate option some day and has a good use
case to submit for this.
Trying to arranging both doesn't make sense and only end up in weird result. If
both the parent (layer group) and one or several child items are selected, just
arrange the parent.
These are typically debug outputs and we don't want them to appear on stderr of
release builds. They confuse people (some tester would report these on IRC when
we last release GIMP 2.99.14).
So let's not show these debug text on release versions.
When the clipboard contains raw image data or single layers, it's the same as
the normal "Paste" (and "Paste In Place" respectively). These actions are useful
if you want to copy a bunch of layers and paste them "merged" into a single
layers (since now the copy-paste of multiple layers will create multiple
layers).
It is somehow similar to the "Copy Visible" action except that it works on
selected layers only and work at paste time, making the action more versatile.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
After further discussions with Aryeom, we had to make decisions about a few
problems. The main problem was: what happens when we copy a selection of a layer
whose bounds don't intersect with the selection?
The silent treatment of discarding the layer was not acceptable, because e.g. it
could happen on huge set of selected layers (like say you copy 100 layers with a
selection: you expect 100 created layers and if you realize you don't have them
all — e.g. you have 99! — after hours of work, trying to find the missing one
can be a huge time loss).
The status bar notification (or even error) did not feel right either because
this can typically be missed easily. Also it doesn't give a lot of feedback
(e.g. you might want hint to find the non-intersecting layers, in case it was
not supposed to happen).
An error box was even considered, possibly proposing to ignore the problematic
layers, or even giving easy ways to find them.
Finally what if we let the selection happen regardless the non-intersecting
layers? What should the dimension and offset of said layers be?
In the end, we went with the more consistent behavior of always creating new
layers of the exact same size as the selection. It can be considered as a rule
which would make the behavior predictable. For the non-intersecting layers, we'd
just have new layers with the dimension/offset of the selection bounding box,
and no contents. For other layers, they'd be also this same dimension, possibly
increasing the dimension of the source layers (though any new pixel is fully
transparent obviously). Aryeom wondered if some people might absolutely need for
their workflow that the new layers stick to the origin bounding box. But we felt
it was enough of a stretch that we'd try this way for now.
Note: of course if some day we get infinite canvas/layers, this whole discussion
could be less of a problem anyway! This was Aryeom's conclusion! Ahahah!
This is also work-in-progress for better copy-paste handling for multi-items.
Until now, I had decided that, if a selection existed, a copy would copy a
merged version of the selected items. But sometimes you want to have a piece of
each layer, each piece in its own layer. Also you may always merge the pasted
layers afterwards.
So now we will indeed create as many layers out as there are layers in. Being
able to copy a merged down version of all selected layers is still an
interesting feature though. We might add a dedicated "Copy Merged" action,
similarly to the fact we have a "Copy Visible" (which does the same thing but
for all visible layers, not specifically the selected ones).
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
When several drawables were selected, it was pasting at the top of the layer
stack. Instead, paste over the top selected layer ("top" visually in the Layers
dockable).
There was the question of: what should we do when pasting over a layer group.
Should we consistently paste the new layers above the group or inside the group?
After discussions with Aryeom, we decided to stay consistent and paste above, at
least for now.
This changes the default selection pasting behavior to be a new layer,
rather than a floating selection. It also removes the
"Paste as New Layer" submenu options as they are now redundant.
It's clearly broken right now. I can see it might have been used even to
progressively shift aligned items, but this was not used anymore. As for being
used while distributing, it doesn't make any sense anymore with the new logic of
not moving the extreme (first/last in coordinates) items.
I can see how an additional concept of offset can be useful in some situations,
but for now, let's get rid of this. We'll see in the future if someone asks for
it and provides valid use cases to work from.
There was one case in Inkscape which we could not do: distributing objects
keeping even gaps between them. Until now, we could only distribute keeping even
distance between anchor points (top, left, bottom, right or center).
With these 2 additional distribute options, I believe that GIMP is able to do
all the Alignment and Distribution options available in Inkscape (not the
"Rearrange" or node features, neither the text align/distrib; I just mean the
common align/distribute on objects), and even a bit more thanks to the anchor
point system (e.g. in Inkscape, we can't left or right-align to a reference
object/image center, or we can't center to a reference left/right/bottom/top
border; but we can do it in GIMP).
The icons are hopefully temporary, until we can make better ones.
After discussing with Aryeom, we decided that "Distribute" should work within
the current horizontal or vertical bounds, as this is how it is usually done in
other software (e.g. Inkscape). For instance, if there are 4 items, the first
and last (coordinate-wise) stay untouched, and only the 2 intermediate items get
distributed evenly.
Since the Reference is not relevant anymore for "Distribute", I undo part of my
previous commit, where I was organizing the reference setting into its own
section of the Alignment tool options. This setting is back as part of the
"Align" section.
- Adding a separate pivot widget to allow choosing which point of the items we
align or distribute. E.g. until now, we could only align the right side of
objects to the right side of the reference object, left to left and center to
center. Now these are independent. Therefore I can align the left side of
objects to the right border of a selection or a layer, and so on.
- Only keep 2 "distribute" buttons (for now). Most of the distribution actions
were basically broken or extremely hard to understand. Also they were
apparently mixing concepts of alignments with distributions. Now let's
basically only keep the bases: horizontal or vertical distributions.
Everything is still possible using a mix of alignment and distribution
buttons, and it's much clearer.
- Since the GimpAlignmentType was used nearly only there (except for some usage
like to store dock side or filter preview split direction, but these
GIMP_ARRANGE_* values were unused there), I removed the various enum values
which we don't use anymore.
- The Reference settings gets its own subsection in the Align tool options.
Until now, it looked like it only applied to alignment, whereas it applies to
distribution too.
Note: this is still work-in-progress, mostly some initial dev work to put some
algorithmic bases. We had some UI and specification discussions with Aryeom
already and some things might still change a lot.
When the reference is a guide in particular, no distribution is possible (on one
dimension, the size is 0, on the other, it's infinite) and alignment is only
possible in one direction (depending on guide orientation).
Instead of storing vectors as properties, they have their own structure, which
make them able to store and load all the usual and common properties of other
items. In other words, it makes XCF now able to store locks, color tags and
several selected paths.
Instead of using the layer borders, we use the bounding box for the contents.
This is similar to first run "Crop to Content" on every selected layer except
we don't actually need to crop. Therefore we can work on bigger layer than the
actual content while still arranging them based on content bounds.
So often the result of alignment/distribution feels wrong because it doesn't
correspond to the content we are seeing. With this option, we'll have the option
to choose the desired behavior.
The old interaction was quite horrible. I don't think I ever really got a good
use of it. It was so hard to understand what you were picking and so on.
Now that we can multi-select items, let's just use this as the base of what we
want to align or distribute. Clicking on canvas will now mostly be used to pick
an item as reference. From now on, only the reference object will get on-canvas
handle, making it very obvious how your alignment or distribution will work.
I leave only an alternative picking method (with Alt or Shift-Alt pick) to add
guides to objects to align or distributes, as these don't have a selection
dockable.
I'm also improving the selection of stacked layers by looping through them
(similar as the layer selection on canvas feature) so that we can select even
background layers which have a lot of layers showing above.
I am planning to improve this tool even further, but this is a first step to
make it actually usable within the new multi-item interaction logic.
This ports Massimo’s code to work in the latest version of GIMP.
It adds new outline-related properties to GimpText and GimpTextOptions.
These are controlled via the Text Tool Editor.
Cairo is currently used to draw the outline around the text.
Now text layers are proper types, which means that the binding API will also be
nicer (e.g. `txt_layer.set_text('hello world')` in Python).
This commit also adds the param specs allowing to create plug-in procedures with
text layer parameters.
Finally it fixes the few calls in file-pdf-save (apparently the only plug-in
using specific text layer API right now) with explicit type conversion.
Now that we bumped our meson requirement, meson is complaining about
several features now deprecated even in the minimum required meson
version:
s/meson.source_root/meson.project_source_root/ to fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': meson.source_root. use meson.project_source_root() or meson.global_source_root() instead.
s/meson.build_root/meson.project_build_root/ to fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': meson.build_root. use meson.project_build_root() or meson.global_build_root() instead.
Fixing using path() on xdg_email and python ExternalProgram variables:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.55.0': ExternalProgram.path. use ExternalProgram.full_path() instead
s/get_pkgconfig_variable *(\([^)]*\))/get_variable(pkgconfig: \1)/ to
fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': dependency.get_pkgconfig_variable. use dependency.get_variable(pkgconfig : ...) instead
Creates two new parasites to save the black point compensation status
and rendering intent simulation settings in GimpImage.
The parasites are saved and loaded as part of the image in the
.xcf file.
We should set these explicitly, otherwise it will usually default to the
first of the enum, which is perceptual (which is usually not a proper
choice).
Relative colorimetric is usually the recommended default.
Adds a dropdown for Simulation Profile, Intent, and BPC
to the Create a New Image dialog.
This allows users to assign a soft-proofing profile when the image is
first created. It defaults to "None", however. Users can also set the
default simulation rendering intent and BPC status per image.
These options are also removed from the Preferences dialog.
Adds a simulation_bpc and simulation_intent to GimpImage to allow
plug-ins to access it
for CMYK import/export.
Four pdb functions were added to enable this access:
image_get_simulation_bpc (), image_set_simulation_bpc (),
image_get_simulation_intent (), and image_set_simulation_intent ().
Next, it updates menu options and code to support GimpImage's
internal simulation intent and bpc.
New 'simulation-intent-changed' and 'simulation-bpc-changed signal
are emitted via
GimpColorManagedInterface so that relevant tools
(such as the
CYMK color picker, GimpColorFrame, and future pop-overs)
are aware of these changes.
Generated *enums.c now have an additional stamp no-op header include
(see last 2 commits). Sync this change into the autotools generation
scripts to prevent back and forth useless generation of these files each
time we switch from one build system to another.
They are nearly the same as initially, except that now they include an
intermediate stamp header which will be generated by the build system.
The only 2 enums which don't need these includes (and are not versioned)
are libgimp/gimpenums.c and libgimpthumb/gimpthumb-enums.c.
Our meson build system was not properly building the enums.c file,
because they are versionned.
I did a similar trick as what I did for the pdbgen, which is that I used
a wrapper script around the existing perl script, which sets proper
options and generate a stamp file in the end (which is considered by
meson as the actual custom target, not the C file since it is generated
in the source dir).
The most important part is that the stamp file is a generated header
source (not just a random text file) which is **included** by the
generated C file. This is what will force meson to regenerate the C file
if the header is updated, **then** build using this new version, not use
an outdated versionned version (which would make for hard to diagnose
bugs), through the indirection of the intermediate stamp header.
See #4201.
See also: https://github.com/mesonbuild/meson/issues/10196#issuecomment-1080742592
Adds a parasite to .xcf that stores the soft-proofing profile.
Existing color profile saving/loading functions now take in a
parasite name parameter so they can be used for either profile.
Since localization is fully handled plug-in side now (see #8124), we
need to make sure the query functions are run again for all plug-ins
when the UI language changes (otherwise we might end up with
localizations from the previously used languages).
We were already reloading plug-ins when explicitly changing the lang in
the Preferences, but this new implementation is much better as it's
generic. In particular, it will also handle the case when the system
language changes (or when you play with locale environment variables).
Adds a simulation_profile to GimpImage to allow plug-ins to access it
for CMYK import/export.
Two pdb functions were added to enable this access:
image_get_simulation_profile () and image_set_simulation_profile()
Next, it updates menu options and code to support GimpImage's
internal simulation profile. Menu items are moved from View to Image's
Color Management section.
New 'simulation-profile-changed' signal is emitted via
GimpColorManagedInterface so that relevant tools (such as the
CYMK color picker, GimpColorFrame, and future dockable
dialogue) are aware of these changes.
gimp_channel_is_empty returns FALSE if channel is NULL. This causes
gimp_layer_invalidate_boundary to crash if the mask channel is NULL.
With a NULL channel gimp_channel_is_empty should return TRUE, just like
the similar gimp_image_is_empty does, because returning FALSE here
suggests we have a non empty channel.
With large image sizes a 32-bit int is not enough for the intermediate
computations, which byte per pixel, width and height are.
So, just like the function below it does: gimp_gegl_pyramid_get_memsize,
we will cast these to gint64.
Thanks to Massimo Valentini for finding the cause.
Even if the container is empty, then we return a GStrv of length 1 (i.e.
an array of length 1, terminating with NULL).
In particular, it improves gimp_container_get_filtered_name_array() as
well, and in turn various list-returning functions in libgimp. This
makes the API more consistent after changes from commit 8eb7f6df9e.
Note that a NULL return can be acceptable for error cases, but an empty
list because this is the expected result for the request should be an
empty GStrv, not NULL.
Since GStrv are NULL-terminated arrays, there is always one additional
pointer (NULL).
This is a detail, but still, wrong since commit 8eb7f6df9e which
replaced GimpStringArray by GStrv usage.
Reviewer (Jehan) note: cherry picked from MR !274. Still deciding
whether this will be pushed to gimp-2-10 branch too.
Fixed Conflicts from !274:
app/dialogs/preferences-dialog.c
app/display/gimpdisplayshell-draw.c
app/plug-in/gimppluginmanager-call.c
libgimp/gimp.c
libgimp/gimp.h
libgimpwidgets/gimppreviewarea.c
libgimpwidgets/gimppreviewarea.h
libgimpwidgets/gimpscrolledpreview.c
… plug-in code.
In particular, we should not hardcode this in core code anymore. The
behavior is otherwise exactly the same, except that we made the core
code generic as it should be.
The CLI options now know which procedures are batch procedures or not.
First it means that it won't just randomly try any procedure name one
may pass and will properly output an error if you pass a non-existing
interpreter procedure.
Secondly, there is no default interpreter anymore (unless only one
interpreter exists). If you don't set an interpreter procedure with
--batch-interpreter or if you pass a wrong one, it will output the list
of available batch procedure, thus helping you understanding how to use
the --batch option.
If you call GIMP with batch commands and ask it to quit immediately, you
are likely interested by failure information. For this reason, let's now
report exit code other than success, but only in such case. In
particular, even if the batch commands fail, but GIMP is not set to exit
immediately, we continue reporting SUCCESS run at the very end (when
exiting interactively).
Note that I hardcode a few exit values, as standardly found on Linux
(but not using headers which may not be found on all platforms; in
particular, Windows apparently doesn't use any standard code other than
0 for success, from what my searches return).
Additionally, when several commands are requested, GIMP will now stop at
the first failing and will return its error code, and print a message on
stderr to easily report the failed command for easier debugging.
Since commit 4cf38d784f, when loading an indexed image, we would first
initialize a palette with 0 colors, then set it to the right colors.
Babl outputs the following message when initializing to 0 colors:
> ../../src/babl/babl/babl-internal.h:214 babl_log()
> attempt to create a palette with 0 colors. using default palette instead.
Let's only set the palette to Babl when it has colors.
… whether the program is really ready to accept various commands.
In particular, on macOS, one could drop an image to the app icon in the
dock while starting up (visible splash). Then if the profile convert
dialog appears *behind* the splash, it would block loading until an
action is taken (unfortunately as it's hidden, people may miss it and
would think GIMP froze), as reported by cyril and reproduced by lukaso.
I can't test myself, but I'm hoping this will fix the issue (similar to
commit a86ed68870 where we had a similar issue with dbus file opening
on Linux).
What it means is that we will be a bit strict over our <release>
formatting which will have to always be a <p> introduction followed by a
list of items. This is what gimp_appstream_to_pango_markups() expects.
Since so far, this is how all our <release> tags were formatted anyway,
this is not too much of a problem.
Note that I keep the less strict gimp_appstream_to_pango_markup() and
use it for extension's appstream description as we will have no control
over these.
The main reason for this new rule and new display of our release notes
is that I am going to add the ability to click independent release items
so that people can get "blinking" indications of what changed when
relevant.
This is the same thing as setting the max gap length to 0, except that
it would mean constantly having to play with the gap length and possibly
losing settings you carefully tweaked. Instead with this additional
settings, we hide the gap length settings when automatic closure is
disabled.
Also it makes kind of a nice parallel with the "Manual closure" settings
which can also be enabled/disabled similarly.
Currently the option is quite simple. What should happen to make it more
usable:
* Right now, it uses the last stroke options (e.g. as used in a
previously run "Stroke Selection" or "Stroke Path"). We should have
some dedicated GUI in the bucket fill options.
* The bucket fill options GUI should really be redesigned. The more we
add options, the less understandable it is.
* There is a question whether we want to just use whatever brush size is
being set or if we want to have it vary and follow the line art width
(since we have proper distance map, we could use this to tweak the
stroke per-coords).
As usual, this feature was suggested by Aryeom who was still very
saddened that despite all the fancy features in this tool, it is not
able to produce nice rendering. So she proposed that the tool could
stroke the fill region borders.
Many features can only be run on items belonging to an image, and in
particular attached. It makes sense, but in the same time, there are
often some types of processing you'd like to do in background on
temporary items, not visible in GUI, and without any undo steps.
You could work on buffers directly, but sometimes it's also nice to
attach the semantics of the various items, and reuse logics (in
particular class method implementations) already existing. So I am
adding a concept of "hidden items" which is where you'd put items in
some temporary processing state when you don't want them to go anywhere
visible publicly.
I'm going to reuse this code in other parts of the file so make it a
utils function.
While doing so, I'm also improving a tiny bit the formatting of lists.
XCF 17 includes the new visibility locks and the ability to add position
and alpha locks on layer groups.
I am going to push the various commits implementing these different
features together which is why we gather them as a single XCF version.
We want it to work whatever the level in the item tree. We only care
about whether the items are selected or not.
Also fixing the AppStream release tag for the description of this
feature.
Unlike other locks, visibility lock is less useful for locking a whole
hierarchy of item and their children. On the other hand, being able to
lock a group visibility while editing the children visibility is quite
useful.
It can be argued that layer groups can't be painted on, and that's
probably the original reason, but it's really just the same as "Lock
pixels". It is interesting to be able to lock alpha channels on a layer
group to simply lock all its contents alpha channels.
Since we are now allowed to move groups (which is the same thing as
multi-selecting all its children and moving them), it makes no sense
that this lock is disabled.
This works the same way as "Lock pixels" in that a locked grouped also
forbid moving children. And there was already some logics so that you
can't move a layer group if one of it's children is locked. So this lock
really works both ways and is a bit special.
Finally I cleaned up a bit the multi-layer selection logics and
messaging, as well as which lock to blink (similar to the previous
commit) for the "Lock position" case.
In particular, if painting on a layer whose parent's pixels are locked,
we were blinking an empty lock spot, which is confusing. Now
gimp_item_is_content_locked() will also return the proper item (when
relevant, i.e. when returning TRUE) which is locked. It may or may not
the same item as passed in (it may also be a parent item in particular).
GLib has a specific type of NULL-terminated string arrays:
`G_TYPE_STRV`, which is the `GType` of `char**` aka `GStrv`.
By using this type, we can avoid having a `GimpStringArray` which is a
bit cumbersome to use for both the C API, as well as bindings. By using
`GStrv`, we allow other languages to pass on string lists as they are
used to, while the bindings will make sure to do the right thing.
In the end, it makes the API a little bit simpler for everyone, and
reduces confusion for people who are used to working with string arrays
in other C/GLib based code (and not having 2 different types to denote
the same thing).
Related: https://gitlab.gnome.org/GNOME/gimp/-/issues/5919
There were some comments claiming we don't care about thumbnail creation
errors, only thumbnail saving. It's not true. Thumbnail creation errors
are probably even more important (in this specific usage). For instance,
trying to debug a thumbnail load procedure, I had no clue on the error
even though our system was able to report the issue. It's not cool for
plug-in developers.
Now we will check the thumbnail creation error, write down the error
message on stderr and clear the error for the fallback round (using the
normal file load proc). Then if it errors out again, we will keep this
error as the finale one because it's probably more important if we can't
even open images than the unrelated thumbnail saving error. We will
still return the saving error if the load proc failed without error.
The line art algorithm is useful but not always accurate enough and
sometimes it can even be counter-productive to fast painters.
A technique of advanced painters which Aryeom uses and teaches when she
wants to close an area without actually closing the line art (i.e. the
non-closed line is a stylistic choice) is to close with a brush the area
on the color layer. It has also a great advantage over the line art
"smart" closing algorithm: you control the brush style and the exact
shape of the closure (therefore something you'd usually have to redo
with a closure made by an algorithm as you would likely not find it
pretty enough).
This new feature takes this technique into account. Basically rather
than relying on the closure algorithm, you would close yourself and the
tool is able to recognize closure pixels by the color proximity with the
fill color.
Final point is that this additional step is made after line art
computation i.e. in particular the target drawable is not added to the
sources for line art logics. This allows to stay fast otherwise the line
art would have to recompute itself after each fill.
This also shows why the previous commit of moving the line art object
was necessary, because a painter would likely want to move regularly
from bucket fill to a brush tool to create area closures and we want to
avoid recomputation every time.
… fill tool finalizes.
The idea is that you may want to quickly switch tool to do something and
back to the bucket fill for line art selection. If the input drawable(s)
did not change, the previously computed data is still valid, so let's
hang on the line art object a little longer.
Since we are resetting the input when we get back, we would still
recompute anyway *if needed*, and the line art object does follow
changes on the input pickable so we would not get any deprecated data
anyway. Still we move around ownership a tiny bit to optimize for
common case of tool switching.
In order not to keep forever this data (buffer and distmap in
particular) forever just because one tried the line art once, I add a
timer to free it after a few minutes.
Moreover it will be useful for other cases, such as being able to share
the same line art object with the fuzzy select tool (if we end up adding
the line art option there). In a coming commit, the usage will be even
more obvious for use case where you want to edit the filled area with
other paint tools, then back to bucket fill while not touching the line
art source layer.
Fixes#4333
If the checkbox is unchecked: dynamics falls back to "Dynamics Off",
the current dynamics name and its options are hidden in the UI.
If the checkbox is checked: dynamics is set to previously used one
or the default one, all dynamics options are seen in the UI.
Now the source images are in the build dirs.
Also:
- clean the EXTRA_DIST contents on autotools;
- add dependencies rules in meson gresources to make sure icons are
built before resource build;
- finally remove a duplicate build rule in Color Makefile.
We now save and load layer and channel item sets. Only missing set types
are path ones, but the whole path item is just its own exception in the
XCF format, and adding support for it, while keeping compatibility with
older XCF seem like a small headache. I could do it, but I actually
wonder if it is worth it. Would people really need to store sets of
paths?
Also this commit finally gets rid of any remnant of the old item "link"
concept (I think), so we are getting close to merging the branch.
I cleaned many remaining places where the concept of linked item still
survived.
On loading an XCF file with linked items, we are now going to create a
named sets for the linked items, allowing people to easily select these
back if the relation was still needed.
We don't remove gimp_item_get_linked() yet and in particular, we don't
save stored items into XCF files. This will come in an upcoming change.
- removing the GIMP_ITEM_SET_LINKED enum value.
- removing gimp_image_item_list_linked(). Now we should directly use
gimp_image_item_list_filter() instead.
- "preview-linked" option for transform tools is no more.
This should fix these errors when running `ninja test` or `make check`:
> GIMP-Error: Failed to open file ?/builds/GNOME/gimp/_install/etc/gimp/2.99/templaterc?: open() failed: No such file or directory
> GIMP-Error: Failed to open file ?/builds/GNOME/gimp/_install/etc/gimp/2.99/controllerrc?: open() failed: No such file or directory