Initialize GimpColorHexEntry's text (to "000000") in constructed(),
instead of init(). Otherwise, it gets cleared during construction,
so that color entries set initially to black are empty.
Use SRC_OVER, instead of SRC_ATOP, as the composite mode for all
layers (or use AUTO, when it results in SRC_OVER), to match
Photoshop's behavior. Use RGB_PERCEPTUAL as the blend and composite
space, instead of AUTO, whose interpretation depends on the specific
layer mode, to match Photoshop's behavior for RGB images. Use NORMAL
mode, instead of NORMAL_LEGACY, with the above properties, for normal
layers, for consistency with the other layer modes, which don't (and,
indeed, can't) use the legacy modes.
The section-divider (lsct) layer resource may contain blend mode
information, which apparently overrides the blend mode specified in
the layer record. When reading such a resource, replace the layer's
blend mode with the one specified by the resource.
It seems like pass-through group layers specify normal mode in their
layer record, but pass-through in their section-divider resource, so
this commit allows correctly loading such layers.
... and fix flatten-image along the way. *And* do some cleanup.
Currently, gimp_image_merge_layers() combines the layers on its own,
one by one. This is incompatible with pass-through groups, because
the group's buffer is rendered independently of its backdrop, while
we need to take the backdrop into account when mergeing the group.
Instead, render the subgraph of the parent graph, corresponding to
the set of merged layers, directly into the new layer. Since the
layers we merge are always visible and continuous, all we need is a
minor massage to the parent graph to make it work. This takes care
of pass-through groups intrinsicly.
This commit also changes the behavior of flatten-image: Currently,
the flattened layers are rendered directly on top of the opaque
background, which can make previously-hidden areas (due to layers
using composite modes other than src-over, or legacy layer modes)
visible. This is almost certainly not desirable.
Instead, construct the graph such that the flattened layers are
combined with the background only after being merged with one
another.
GimpFilter's is_last_node field only reflects the item's position
within the parent stack. When a layer is contained in a pass-
through group, it can be the last layer of the group, while not
being the last layer in the graph as a whole (paticularly, if
there are visible layers below the group). In fact, when we have
nested pass-through groups, whether or not a layer is the last
node depends on which group we're considering as the root (since
we exclude the backdrop from the group's projection, resulting in
different graphs for different groups).
Instead of rolling our own graph traversal, just move the relevant
logic to GimpOperationLayerMode, and let GEGL do the work for us.
At processing time, we can tell if we're the last node by checking
if we have any input.
For this to work, GimpOperationLayerMode's process() function needs
to have control over what's going on. Replace the derived op
classes, which override process(), with a call to the layer mode's
function (as per gimp_layer_mode_get_function()) in
GimpOperationLayerMode's process() function. (Well, actually, this
commit keeps the ops around, and just hacks around them in
gimp_layer_mode_get_operation(), because laziness :P)
Keep using the layer's is_last_node property to do the invalidation.
GimpTileHandlerProjectable is similar to GimpTileHandlerValidate,
except that it calls {begin,end}_render() on its associated
projectable before validating.
In pass-through mode, the group layer-stack's input is connected to
the backdrop. However, when rendering the group's projection, we
want to render the stack independently of the backdrop.
Unfortunately, we can't use the stack's graph as a subgraph of two
different graphs.
To work around that, the next few commits add a mechanism for a
projectable to be notified before and after its graph is being
rendered. We use this mechanism to disconnect the stack's graph
from the backdrop before rendering the projection, and reconnect
it afterwards. Yep, it's ugly, but it's better than having to
maintain n copies of (each node of) the graph (each nesting level
requires an extra copy.)
This commit adds {begin,end}_render() functions to GimpProjectable.
These functions should be called right before/after rendering the
projectable's graph.
When any of the children of a pass-through group excludes its
backdrop, the group itself should exclude the backdrop too. Override
get_excludes_backdrop() to follow this logic, and call
update_excludes_backdrop() when this condition might change.
Note that we always composite pass-through groups using src-over mode,
so to actually hide the backdrop, we need to disconnect it from the
group's mode node's input pad (and reconnect it, when the backdrop is
no longer hidden).
Override GimpDrawable::get_source_node() for GimpGroupLayer. Use
a node that contains both the drawable's buffer-source node, and the
layer stack's graph node. Choose which one of these to connect to
the source node's output based on the group's layer mode: the stack
graph for pass-through mode, and the buffer-source node for all the
rest.
When in pass-through mode, connect the source node's input (which
receives the backdrop) to the stack graph's input. Keep maintaining
the projection in pass-through mode. ATM, the projection uses the
same graph as the source node, so it's rendered against the group's
backdrop -- we don't want that. The next few commits fix it.
Update the group's drawable directly upon filter stack update in
pass-though mode, because the group's graph doesn't go through the
projection.
TODO: if any of the group's children (or a child of a nested pass-
through group, etc.) uses dst-atop/src-in, this needs special
attention.
Make sure the input of the layer's filter node is connected to its
source node (when it has an input pad), so that, once we implement
pass-though mode, the group's source node can see the backdrop.
For pass-through groups, we want to use the group's layer-stack
graph directly in its filter node, in place of the drawable's
buffer-source node. Add a get_source_node() vfunc to GimpDrawable,
which defaults to returning the buffer-source node, and use it in
gimp_drawable_get_source_node() instead of using the buffer-source
node directly. We'll later override this function for
GimpGroupLayer.
... causing compilation to fail on 32 bit targets
Use SSE2 compiler flags when building libappgegl, since it's used by
the new smudge tool code.
Avoid using SSE for the smudge tool if SSE acceleration is disabled
at runtime, or if the buffers are not properly aligned.
Add "gboolean with_filters" to gimp_drawable_calculate_histogram(),
which is passed as FALSE in almost all places, except the histogram
dockable where we want to see both the drawable's unmodified histogram
*and* the histogram after filters are applied.
The hint text was shown on kmax change, but not when it was 0 or 1 from
start (i.e. when previous export was 0/1 so these were the saved
values). Run the callback upon construction to initialize properly this
hint label.
They are sub-libraries of libwebp, enabled by build options
(--enable-libwebp(de)?mux), and therefore I don't think it makes sense
to have separate version prerequisites.
Also let's improve the config output by testing for libwebp(de)?mux only
when libwebp check is successful and displaying more accurate info
(instead of saying "WebP not found", "WebP not built with libwebpmux" is
much more accurate for instance, in order to understand the problem if
you are sure you installed the proper version of libwebp).
Since libwebp 0.6, the keyframe max distance (kmax) has been changed,
and in particular all special cases are now handled by kmax (it used to
be weird cases of kmin and kmax intertwined with no logics, for instance
kmax == 0 AND kmin > 0 would mean all frames are keyframes).
Now it is much more logical, and kmax == 0 means no keyframes, whereas
kmax == 1 means all frames are keyframes. See also:
2dc0bdcaee
The signature of the original file-raw-save procedure must not change,
so change it to use the old parameters.
Change the other procedure (with additional arguments) to
file-raw-save2.
During constrained motion, round the slider value before clamping
it, so that the slider limits are always enforced. Additionally,
snap the slider to 1/12-ths of the line length, rather than
1/24-ths.
Make sure that sliders can never have negative-zero values, which
can result in a -inf base for spiral.
Shift-click should actually toggle only within a given group. The new
capability of toggling only a sub-item, brought by commit 970e9ac is
still feasible in 2 steps: first toggling the parent (item group), then
the desired child.
It brings now a third possibility with exclusive toggle among many
children items, without touching other groups and top-level items.
... so that when the base and balance sliders overlap, the base
slider is the one that's picked, since the balance slider is
constrained by the base, but not the other way around.