Commit graph

5635 commits

Author SHA1 Message Date
Ell
522e497457 app: in GimpChunkIterator, avoid preparing rect before merging
In GimpChunkIterator, avoid preparing the current rect before
merging it back to the iterator's region, to save some work.

Additionally, strengthen the iterator's invariants and simplify
code.

(cherry picked from commit c95502266a)
2019-03-31 05:03:47 -04:00
Ell
191c9812f3 app: small fix to GimpChunkIterator
(cherry picked from commit d182c41f8f)
2019-03-30 16:36:33 -04:00
Ell
4d2a5d1a94 app: more responsiveness improvements to GimpChunkIterator
Improve GimpChunkIterator's responsiveness to changes in processing
speed.

(cherry picked from commit 91f4c809d8)
2019-03-30 11:18:05 -04:00
Ell
f0b5080f83 app: don't invalidate viewable preview when thawed unless explicitly requested
In GimpViewable, don't invalidate the preview when thawed, unless
there was an explicit call to gimp_viewable_invalidate_preview()
while it was frozen.  This avoids invalidating the previews of an
invisible drawable's ancestors when the drawable's preview is
frozen/thawed.

(cherry picked from commit 9dabad4cb9)
2019-03-29 04:54:12 -04:00
Ell
c8ea2f45f9 app: avoid risky alloca() in gimp_brush_save()
Replace an arbitrarily-sized g_alloca() with g_malloc() in
gimp_brush_save().

(cherry picked from commit 24ed9dbdf5)
2019-03-28 16:56:01 -04:00
Ell
c347f8770c app: avoid freezing image preview if drawable is not attached
When freezing/thawing a top-level drawable's preview, only freeze/
thaw the image preview if the drawable is attached.

(cherry picked from commit de36e33347)
2019-03-28 12:36:48 -04:00
Ell
b9ca245736 app: when freezing a drawable's preview, freeze ancestors' previews
Add GimpViewable::preview_{freeze,thaw}() virtual functions, which
get called when the viewable's preview is frozen/thawed.  Implement
the functions in GimpDrawable, recursively freezing the parent
drawable's preview (or the image's preview, for top-level
drawables) while the drawable's preview is frozen.  For layer
masks, freeze the associated layer's parent.

This avoids updating layer-group/image previews while painting on,
or applying a filter to, a descendant layer.  This both reduces
lag, and fixes a discrepancy between the layer's preview, which
isn't updated, and its parents' previews.

(cherry picked from commit e2ea2e4a82)
2019-03-28 12:26:54 -04:00
Jehan
273a0c4395 app: change antialias feature in fill by line art into Feather Edges.
This was actually more of a feathering feature I added earlier, and we
already have a function for that: gimp_gegl_apply_feather(). This is
using a gaussian blur, just as what I was doing anyway. This commit also
adds the "Feather Radius" scale, similar to other tools with the
"Feather Edges". So that makes it consistent (and more useful as you can
adapt to your needs).

(cherry picked from commit d821b088e2)
2019-03-28 14:12:12 +01:00
Ell
7edbad3144 app: include system gtkrc file in themerc
Include the system-wide gtkrc file, in addition to the user-
specific gtkrc file, in the generated themerc file, instead of
copying the former into the latter when creating the user's
gimpdir.  This allows us to modify the system-wide gtkrc file, and
having the changes take effect in existing installations.
2019-03-27 20:15:50 -04:00
Ell
9063b937fe app: use gimp:fill-source in gimp_drawable_edit_fill()
In gimp_drawable_edit_fill(), when performing a non-direct fill,
use a GimpDrawableFilter with gimp:fill-source, added in the
previous commit, instead of using gimp_drawable_apply_buffer() with
an intermediate fill buffer.  This avoids allocating a full-size
fill buffer, which may occupy a lot of space in pattern fills.

(cherry picked from commit 234f76b6fb)
2019-03-27 15:48:22 -04:00
Ell
2341117517 app: improve gimp_drawable_fill_buffer() for patterns
In gimp_drawable_fill_buffer(), when the fill-source is a pattern,
avoid going through an intermediate buffer when there's no profile
transform, and use the destination-buffer format for the
intermediate buffer, instead of the pattern format, when there is a
profile transform.

(cherry picked from commit 3c1634ee0d)
2019-03-27 15:48:21 -04:00
Ell
1416571389 app: use compositing format for fill buffer
Add gimp_fill_options_get_format(), which returns the format to be
used for the fill buffer; this is the same format used during
compositing.  Use this format in gimp_fill_options_create_buffer(),
instead of the drawable format.

This fixes the result of fill operations when the fill color/
pattern is not representable in the drawable format, and speeds up
color fills by avoiding color-conversion for the fill buffer during
processing.

(cherry picked from commit 245a17c79f)
2019-03-27 15:48:20 -04:00
Ell
6e06e5e856 app: in GimpDrawableFilter, set underlying operation
In GimpDrawableFilter, use
gimp_gegl_node_set_underlying_operation() to the the input
operation node as the underlying operation of the filter node.

(cherry picked from commit b0dfc1e7c7)
2019-03-27 15:48:20 -04:00
Ell
55569d512e app: in gimp_drawable_apply_buffer(), work in chunks
In gimp_drawable_real_apply_buffer(), use GimpChunkIterator to blit
the applicator's output to the drawable's buffer in chunks, to
minimize the space used for intermediate results.

(cherry picked from commit 8f845d3a51)
2019-03-27 15:47:39 -04:00
Ell
7c6125ce67 app: improve responsiveness of GimpChunkIterator
In GimpChunkIterator, redajust the target area at each step,
instead of at each iteration, to adapt more quickly to the current
processing speed.  To avoid creating uneven chunks as a result,
only change the chunk height at the beginning of rows, unless the
resulting area would be more than twice as big as the target area.

(cherry picked from commit e904b71242)
2019-03-27 15:47:38 -04:00
Ell
f81c1cac10 app: preserve projection priority rect across structure/bounds changes
In GimpProjection, store the priority rect in image coordinates,
and only convert it to projectable coordinates when initializing
the chunk-iterator's priority rect.  This allows us to preserve the
priority rect across projectable structure/bounds changes.

(cherry picked from commit 9d80ccc3e6)
2019-03-26 04:58:57 -04:00
Ell
ebaf09e7cc app: don't disable filter format conversion if != drawable format
In gimp_drawable_merge_filter(), don't disable the filter
applicator's output-format conversion node if the output format is
different than the drawable's format, since it may change the
result.

(cherry picked from commit 30da2f3d6f)
2019-03-25 09:16:26 -04:00
Ell
269f2ca0fc app: skip cache and format conversion when merging a drawable filter
In gimp_drawable_merge_filter(), disable the filter applicator's
cache and output-format conversion nodes before processing the
uncached region of the filter, so that the result is written
directly to the drawable's buffer.

(cherry picked from commit 733a6ec01c)
2019-03-25 09:02:31 -04:00
Ell
9ac360a125 Issue #3142 - Filters on-canvas preview doesn't work ...
... immediately after an image precision change

When flushing a projection, make sure it has a buffer, instead of
bailing if it doesn't.  We rely on the image projection's "update"
signal to update the display after certain operations that free the
buffer, which would previously fail to happen, and cause subsequent
flushes to be ignored until the buffer is explicitly accessed.

This fixes commit b07f810273.

(cherry picked from commit 106df3b794)
2019-03-24 03:20:43 -04:00
Alex Samorukov
8f3da0e8c4 Allow compilation on MacOS 10.5 leopard: issues #2923, #2924 and #2925 2019-03-23 23:33:07 +00:00
Ell
b8d94342ca Issue #3134 - Deleting last layer of group not updating image
In gimp_group_layer_get_size(), make sure to always set *width and
*height, even when the group is empty, so that when the function is
called through gimp_projectable_get_size() by the group's
projection, the correct size is reported.  This makes sure we
update the correct area when the group becomes empty.

(cherry picked from commit a712308f20)
2019-03-20 17:51:21 -04:00
Ell
dc8fad6ac6 app: improve gimpchannel-{combine,select}
In gimpchannel-select, move some of the common functionality of the
various gimp_channel_select_foo() functions to gimpchannel-combine.
Furthermore, don't special-case CHANNEL_OP_INTERSECT, but rather
pass it over to gimpchannel-combine, which is now prepared to
handle it in all functions, as per the previous commits.

In gimpchannel-combine, factor out the common functionality of the
various gimp_channel_combine_foo() functions into a pair of
gimp_channel_combine_{start,end}() functions, which are called
before/after the actual gimp_gegl_mask_combine_foo() function,
respectively.  In particular, these functions deal with calculating
the new channel bounds.  Previously, the various
gimp_gegl_mask_combine_foo() functions would implicitly invalidate
the channel bounds (since commit
d0ae244fe8), rendering the bounds-
recalculation code ineffective.  This avoids manually recalculating
the bounds in many cases, speeding up selection operations.

(cherry picked from commit 8e77347cac)
2019-03-20 16:27:55 -04:00
Ell
9b76ea070d app: improve gimp_gegl_mask_combine_ellipse[_rect]()
Improve gimp_gegl_mask_combine_ellipse_rect() -- the funciton
responsible for rendering ellipse/rounded-rectangle selections.

Most notably, this commit significantly improves the function's
performance, by identifying whole tiles, whole rows, or parts of a
row, that are fully inside, or fully outside, the ellipse, and
filling them in bulk, instead of calculating the anti-aliasing
value at each pixel, which is now only done along the
circumference.

This commit also improves anti-aliasing, by more accurately
approximating the distance from a pixel to the ellipse, and by
normalizing the distance according to the pixel's cross-section
length in the direction of the said point.  In particular, we
guarantee that pixels that are fully inside/outside the ellipse
have a value of 1/0, respectively, facilitating the aforementioned
optimization.

Additionally, this commit fixes various edge cases where several
primitives coincide at a single pixel (in the rounded-rectangle
case), adds support for CHANNEL_OP_INTERSECT, and parallelizes
processing.

(cherry picked from commit 1044342393)
2019-03-20 16:27:55 -04:00
Jehan
127fc91603 Issue #3087: error compiling for Windows.
s/THREAD_MODE_ABOVE_NORMAL/THREAD_PRIORITY_ABOVE_NORMAL/
Thanks to Sylvie Alexandre for noticing and searching this.

(cherry picked from commit ebc3ef3c5e)
2019-03-08 17:36:13 +01:00
Jehan
c91d37eff2 Issue #3041: Color Picker no longer selects Colormap entry.
Do not take "Sample merge" into account when picking colors in a
single-layer image. The reason is to be able to get the index
information on indexed image. This information is lost otherwise when
using the whole image as a pickable.

Of course, other exceptions are possible, when you'd pick exactly a
colormap color, but I don't think it's worth making the code
extra-complicated for these. My previous commit will anyway already
select the right color in the colormap on common cases. Though it will
still fail to select the right index when several indexes store the same
color, on a multi-layer image, if you check "Sample merged" while the
right index was not the first one amongst the duplicates.

(cherry picked from commit 31b2b55b28)
2019-03-08 15:17:47 +01:00
Jehan
812a0f6689 app: save the accurate color in the colormap palette when possible.
The colormap saves colors as unsigned char, which can be very inaccurate
compared to high precision colors. When adding colors from GimpRGB into
the colormap, use the original value to fill the colormap palette
instead of making a round trip conversion from double to uchar, then
back to double.

This also fixes a direct bug I encountered when adding the current
foreground color in the image colormap. Yet the GimpFgBgEditor or the
GimpColorHistory would still show the color out-of-gamut in cases when
the returned RGB after the roundtrip was not close enough to the
original RGB (even despite using an epsilon in GimpPalette code).

(cherry picked from commit f1cca8ee2e)
2019-03-08 15:17:47 +01:00
Ell
dfca360b66 app: various fixes to last commit
(cherry picked from commit caad9ca649)
2019-03-06 15:56:12 -05:00
Ell
977c4d0718 app: allow canceling line-art computation
Line-art computation can take a long time, and it's therefore
desirable for it to be interruptable.  While we do cancel the line-
art async when its result is no longer needed, most parts of the
computation don't respond to the cancelation request, leaving the
async operation running in the background, blocking subsequent
async operations.

Implement cancelation support of line-art computation, by passing
down the async object to the various functions, and periodically
checking for its cancelation at various points.  When the async is
canceled, we quickly abort the operation.

Even though cancelation now happens relatively quickly, some parts
of the computation are still uninterruptable and may incur some
latency, so we avoid waiting for the async opration to be aborted
after cancelation, as we did before.

(cherry picked from commit d8e69d66bc)
2019-03-06 15:24:18 -05:00
Ell
d918502aac app: use gimp_gegl_buffer_copy() in various places
... instead of gegl_buffer_copy().  The former parallelizes the
format conversion.

(cherry picked from commit bb7f61c919)
2019-03-06 06:00:10 -05:00
Ell
cd159e4bd4 app: fix indepndent-async thread priority on Windows
Positive and negative priorities got swapped...

(cherry picked from commit 190095c97b)
2019-03-06 00:08:05 -05:00
Ell
a3cd8c96d0 app: add gimp_parallel_run_async_independent_full()
... which is equivalent to gimp_parallel_run_async_independent(),
except that it takes an additional "priority" parameter, which
specifies the task's priority, with 0 being the default priority,
and lower values indicating higher priority.  Unlike
gimp_parallel_run_async_full(), the priority parameter doesn't
directly control the task's priority in a queue, but rather, we use
it to control the priority of the task's dedicated thread, on
supported platforms (previously, all independent async tasks would
run with low priority.)

Use low priority when loading fonts, which can take a long time, to
keep the existing behavior.

(cherry picked from commit fa2e4dcce0)
2019-03-06 00:02:10 -05:00
Ell
a465b9c341 app: clean up last commit
Remove gimp_item_tree_clear(), added in last commit, and move its
code to gimp_item_tree_dispose().  Likewise, in
gimp_image_dispose(), use g_object_run_dispose() on the image item-
trees, instead of gimp_item_tree_clear().

(cherry picked from commit b0de51b6bf)
2019-03-05 16:42:50 -05:00
Ell
c76076ec14 app: fix segfault when closing an image with a floating selection
Add gimp_item_tree_clear(), which removes all the items of a
GimpItemTree, and clear the layers/channels/vectors item trees in
gimp_image_dispose(), *before* finalizing the image, so that the
corresponding items' desctructors are called while the image is
still alive.  In particular, this allows the destructors to safely
call gimp_item_is_attached(), which happens when the image has a
floating selection, since commit
8d4e5e0ff7.

(cherry picked from commit d7e3a1e226)
2019-03-05 09:33:07 -05:00
Ell
4eda127c52 Issue #3062 - Picking by hue using "Select by Color" goes awry ...
... in GIMP 2.10.9 from git

In gimppickable-contiguous-region's pixel_difference() function,
which is used, among other things, by the select-by-color and
fuzzy-select tools, when selecting by LCh/HSV hue, treat a pair of
colors as inifinitely far apart if one of them has positive chroma/
saturation, and the other has chroma/saturation that's very close
to 0; conversely, treat a pair of colors as equal if both of them
have chroma/sautation that's close to 0.

As a result, when the seed color is saturated, gray pixels are
never selected, while when the seed color is desaturated, all, and
only, gray pixels are selected.

(cherry picked from commit 9886b69dac)
2019-03-05 09:01:45 -05:00
Jehan
07080d4540 app: improve line art filling when clicking on a line art closure.
When clicking on a line art pixel, only this pixel gets colored, which
is fine for actual (original) line art pixels. But on generated ones
(closure pixels, which are internal only), you end up with a single
pixel colored while the whole surrounding area is empty. This feels like
a bug (even though it was not one technically) as you have no way to
guess you are clicking on a closure pixel.
Instead, when this happens, simulate clicks on all neighbour pixels,
hence potentially coloring all surrounding regions, which is most likely
what you wanted.

(cherry picked from commit f310db6c21)
2019-03-04 19:01:44 +01:00
Jehan
03744e3012 app: fixing the line art GimpBusyBox visibility.
Commit bc187cc5cc was a bit wrong as it was possible to get some race
conditions when changing settings quickly in a short time frame.

(cherry picked from commit 3a317e72aa)
2019-03-04 19:01:44 +01:00
Jehan
a9ec675b77 app: avoid useless line art closure recomputation.
On various property changes, only recompute the line art when the
property actually changed. Also add a gimp_line_art_bind_gap_length() to
avoid computing twice the line art when changing both type of closure
(splines and segments) together, as is currently the case.

(cherry picked from commit c0996241f6)
2019-03-04 19:01:44 +01:00
Jehan
4233d90961 app: add a GimpBusyBox near the "Line Art Detection" label in…
… Bucket Fill tool options.
This will provide feedback when the line art closure is being computed,
which may be useful on big images where it may take some time. Otherwise
painter may be left hanging without knowing what takes time.

(cherry picked from commit bc187cc5cc)
2019-03-04 19:01:44 +01:00
Michael Natterer
1c66573f4c app: optimize gimp_layer_invalidate_boundary()
Don't mess with the image's mask if the layer is not attached or not
visible.
2019-03-03 20:25:40 +01:00
Michael Natterer
d8aab75c09 app: factor out gimp_brush_pipe_set_params() from gimp_brush_pipe_load()
(cherry picked from commit e742b4a95b)
2019-03-03 20:00:25 +01:00
Ell
3f43c2ea12 Issue #1554 - Select by Color tool does not select pixel(s) or area(s) of pixel(s)
In gimp_pickable_contiguous_region_by_color(), add a small epsilon
to the threshold value, to allow for small errors due to the input
color and pickable pixel-colors being converted to the common
format through different paths.

While we *could* special-case threshold == 0 when the input color
comes from the same pickable, as is the case for the select-by-
color tool, and perform an exact comparison in the original format,
in the more general case the input color can come from an arbitrary
source, such as a plug-in.

(cherry picked from commit a6c79770c3)
2019-02-28 09:27:48 -05:00
Ell
5d37a244dd app: merge layers in chunks, and show progress
In gimp_image_merge_layers() -- the internal function used by the
various layer-merging/flattenning functions -- process the merged-
layer graph in chunks, using gimp_gegl_apply_operation(), instead
of in one go, using gegl_node_blit_buffer().  Processing in chunks
better utilizes the cache, since it reduces the size of
intermediate buffers, reducing the chances of hitting the swap when
merging large images (see, for example, issue #3012.)

Additionally, this allows us to show progress indication.  Have the
relevant gimpimage-merge functions take a GimpProgress, and pass it
down to gimp_image_merge_layers().  Adapt all callers.

(cherry picked from commit e83d8ac4f2)
2019-02-25 05:10:59 -05:00
Ell
25ed35af62 app: accept a const GimpTempBuf in more temp-buf functions
In gimp_temp_buf_{ref,unref}(), and
gimp_temp_buf_create_{buffer,pixmap}(), accept a const GimpTempBuf
argument.

(cherry picked from commit 0a1e62768a)
2019-02-24 13:22:28 -05:00
Michael Natterer
db675d84e3 app: implement saving of GimpBrushPipes in the core
Just the GimpData::save() and ::copy() part that is needed to
duplicate and rename them, the image-to-pipe logic from the export
plug-in remains to be ported.

(cherry picked from commit aee097fa97)
2019-02-23 19:44:23 +01:00
Ell
a5130c7f66 app: add temp-buf-total varaible to the dashboard
Add a temp-buf-total variable to the dashboard's misc group,
showing the total size of all GimpTempBuf objects.

(cherry picked from commit bb645bae17)
2019-02-22 08:47:13 -05:00
Michael Natterer
45d3a054a4 app: some changes to GimpBrushPipe in preparation for .git image loading
- don't clear the names of the individual brushes, we need them for
  a load -> save roundtrip
- for the same reason, and for convenience, store the parameter string
  in the object
- clean up gimp_brush_pipe_finalize()

(cherry picked from commit 4b456e6079)
2019-02-19 23:48:09 +01:00
Ell
d424a418cb app: in GimpDrawableFilter, don't mask-out alpha comonent for alpha-less drawables
In gimp_drawable_filter_sync_affect(), don't mask-out the filter's
alpha component when the drawable doesn't have an alpha channel,
since this is no longer necessary -- we now explicitly convert the
output to the drawable format as part of the graph -- and it
prevents the gimp:mask-components node from becoming a NOP.

(cherry picked from commit af2c7d1b33)
2019-02-16 13:10:12 -05:00
Ell
353951a44f app: set/clear component-mask alpha-bit of alpha-less drawables, to make mask uniform
In gimp_drawable_get_active_mask(), when the drawable doesn't have
an alpha channel, set or clear the mask's alpha bit, according to
the state of the other bits, so that it never gets in the way of a
fully set/clear mask.  The value of the alpha bit doesn't matter
when there's no alpha channel, however, having a uniform mask
allows us to skip component masking altogether.

Additionally, provide a default implementation for
GimpDrawable::get_active_mask() which returns a full mask, and
remove the equivalent implementation for GimpChannel.

(cherry picked from commit 1b900bfa16)
2019-02-16 13:10:11 -05:00
Ell
116e8a6d4b app: remove gimp_drawable_replace_buffer()
Remove gimp_drawable_replace_buffer(), which is no longer used
anywhere since commits ddb69b77a7 and
3451ffb62c.  This eliminates
redundancy, since all compositing is now done through the layer-
mode code.

Furthermore, gimp_drawable_replace_buffer() used the drawable's
active-component array, whose layout depends on the image mode, as
an argument to gimp_gegl_replace(), which always expects an RGBA
component array, resulting in broken component masking in non-RGB
images.

(cherry picked from commit 2074accb60)
2019-02-14 11:05:19 -05:00
Jehan
0fef0a55f8 app: gimp_edgel_region_area() may return < 0 for non-closed zones.
The algorithm to compute a zone area by following its border only works
well for fully closed zones. It may return negative values otherwise.
Let's just assume the created zone is big in this case (which may or may
not be the case, but this is the safe case as it does not prevent
closure creation).

(cherry picked from commit 0636c302a3)
2019-02-14 13:54:24 +01:00