I specifically moved the file opening/closing logic to the common
code. This makes the code easier to understand for me since there
is less duplication. In fact, this commit removes more lines than
it adds.
The new by-row iteration doesn't re-write the length
value for each row. In general it is not safe to modify
the iterator data because the internal logic depends
on the public data, but this specific case is new.
Call gimp_filter_set_is_last_node() directly from the
GimpContainer::add(), ::remove() and ::reorder() implementations so it
is always called and things always have the correct state. More
precisely, don't call it in functions that are only called if the
stack has a graph, or that are called while the graph is being
created, because it has the side effect of emitting a signal that
might (and in fact did) trigger another recursive creation of the same
graph.
removing the area that is going to be rendered from the dirty area
before rendering it, prevents tile-handler-projection to render it
again.
This was the reason why caching showed an improvement also during
the construction of the projection. And it was a regression that
I introduced in a previous commit
when toggling the visibility of a single layer image with
alpha channel, zoomed at 50%, the projection wasn't
properly redrawn. It seems there's a GEGL bug exposed
by normal layer mode operation fast path.
measure the time it takes to render projection chunks and continue
rendering until 0.01 seconds have passed. This ways we avoid excessive
expose roundtrips.
so we can control how much time it takes, and can further optimize it.
This is needed for gtk3 because it should happen between clock ticks,
not in the expose handler, and in gtk2 the old code would have the
unfortunate property to potentially render at very high frame rates,
including all the overhead of exposing.
In gimpgrouplayer.c always gimp_pickable_flush() after
gimp_projectable_structure_changed() so all queued updates are
actually flushed to the projection buffer's invalid area, and are
constructed upon reading. This would have been neccessary before for
group layers, but worked anyway until we changed
gimp_projection_get_buffer() to construct the buffer on idle time
initially in order to make images appear more responsively after
loading.
and separate the chunk rendering logic from the fact that it's invoked
from an idle callback. Idle rendering no longer works in GTK+ 3.8 and
later because the expose logic was changed from an idle function to a
frame clock, and when we switch to that in gtk3-port, the diff to
master should stay readable (and rebasable) in this critical part of
the code.
Make sure an indexed image always has a colormap. This was the case
before, except one could set a NULL colormap via the PDB.
Add gimp_image_unset_colormap(), and make gimp_image_set_colormap()
never set the colormap to NULL, even if NULL is passed. Change the
only places where actual unsetting makes sense to use unset().
Make some GUI places deal gracefully with palettes/colormaps with zero
entries.
during an image rescale, while spinning the main-loop,
layer-groups preview generation used to start before their
layers were fully rescaled, so it tried to access tiles that
were not yet there
and invert masks using invert-linear and other drawables using
invert-gamma. drawable_invert_cmd_callback() still always uses
invert-gamma even though it can be used on layer masks.
- Add new enum GimpComponentType which contains u8, u16, u32 etc.
- Change GimpPrecision to be u8-linear, u8-gamma, u16-linear etc.
- Add all the needed formats to gimp-babl.c
- Bump the XCF version to 5 and make sure version 4 with the old
GimpPrecision enum values is loaded correctly
This change blows up the precision enums in "New Image" and
Image->Precision so we can test all this stuff. It is undecided what
format will be user-visible options in 2.10.
Call gimp_cpu_accel_set_use() in app_run(). Add "use_cpu_accel"
parameter to gimp_new() and keep it around in the Gimp instance. Pass
the flag to plug-ins again.
so we can make histograms of the gamma-corrected image data. Pass
TRUE all over the place so the histogram works perceptually. This
needs more thinking...
if the gradient itself isn't changed.
GimpData: implement GimpObject::name_changed() and set the "dirty"
flag to TRUE. Don't set dirty in GimpData::dirty()'s default impl
because that calls gimp_object_name_changed() anyway.
...PNG Description encoding error.
Don't unconditionally display all error messages from thumbnail saving.
Instead, return the error from gimp_imagefile_create_thumbnai()
and gimp_imagefile_save_thumbnail() and display it only if thumbnail
creation was the actual user-intended action (like clicking the preview
in a file dialog). Do not display the error when thumbnailing is just
a side effect of loading/saving an image.
because it made applying of expensive filters pretty unresponsive.
Don't revert commit b7b504d624 tho
because it also moves the #defines to a proper place.
It was misnamed from the beginning and has no relation to GimpImageMap
except that it happens to be used by GimpImageMapTools. Now it feels
less weird to potentially use it for other settings too.
which sets either SELECTION or DRAWABLE. In SELECTION mode (the
previous hardcoded default), the effect is offset to the selection
boundary, in DRAWABLE mode, the effect's coordinates are drawable
coordinates.
and only update the drawable in that area if it's not NULL. Useful for
expensive interactive operations like warp, where the tool exactly
knows which area has changed.
Keep track of whether we have actually added a filter to the drawable,
and of the filtered rectangle, so we don't run into broken states in
commit() or abort(). Also make sure we remove the filter on bailing
out in apply().
gimp_image_map_apply(): don't let the filter affect the drawable
projection's alpha, because it can't affect the drawable buffer's
alpha either when finally merged.
Add "linear" parameter to GimpApplicator. Pass the drawable's "linear"
to the applicator, and to all calls to gimp_gegl_mode_node_set_mode(),
instead of hardcoding FALSE everywhere.
...one image onto another
gimp_dock_window_display_changed(): make sure the "auto-follow-active"
logic works both ways: when the active image or display is changed in
a dockable, update the global context. Fixes multi-window mode.
gimp_context_real_set_display(): make sure a context's display and
image are always in a consistent state and never have a display that
is not display->image: when display is the same as context->display,
check that the context's image matches display->image, so that after a
gimp_context_set_display(), the context is consistent in all
cases. Fixes single-window mode.
The filter does absolutely nothing with the applicator, this API is
just for associating an applicator with a filter so it can be found by
other parts of the code.
which is part of the drawable's source_node, so we can generically
filter a drawable's pixels. Reading from the source_node will
transparently give the filtered results.
Turn floating selection compositing into a GimpFilter and add it to
the filter stack while we have a floating selection on the drawable.
This reverts commit c204b0ac41, it's
a nice speedup we should keep, but we can't return a GimpChannel
of != image precision from that function. Needs more thinking.
Let GimpTileHandlerProjection know how large the projection is so it
can calculate the number of levels in the pyramid, and always
invalidate all levels.
Adds an icon-pixbuf property to GimpViewable that is used for a default
implementation of new_pixbuf.
Extend gimp_icon_picker to allow the user to pick non-stock icons for tool
presets (or any other class derived from GimpViewable). Icons can come
from any file GdkPixbuf can load or from image data on the clipboard.
Make gimp_context_get|set_font_name() actually deal with
context->font_name, so the context can do its job of keeping the name
of an unavailable object around.
This does not make any difference for normal images, but for images
without display (like when creating thumbnails, or for GUI-less
scripting), this is now needed because we create the initial
projection much more lazily, and got an empty projection.
This is a generic system based off regular expressions so it can be used
for any configuration file.
Some of the use cases would be for instance to clean out outdated custom
actions (hence remove some loading burden), or rename them (so that
users don't lose their customization if we rename actions), etc.
Add a boolean "is-last-node" property to GimpDrawable and set it from
GimpDrawableStack, which is the place that easily has the information.
In GimpLayer, connect to "notify" and make sure we use NORMAL mode
unless the layer is in NORMAL or DISSOLVE mode.
New configuration directory scheme, consistent across platforms, and
following standards.
UNIX platforms (except OSX): $XDG_CONFIG_HOME/GIMP/{GIMP_APP_VERSION}
Windows: %APPDATA%/GIMP/{GIMP_APP_VERSION}
OSX: NSApplicationSupportDirectory/GIMP/{GIMP_APP_VERSION}
When checking if any linked item is position-locked in
gimp_item_linked_is_locked(), temporarily set the items to not being
linked, or gimp_item_real_is_position_locked() will call
gimp_item_linked_is_locked() again, and so on...
For conversions that have no dither options (like RGB -> GRAY or u8 ->
u16), always preserve text editability, for conversions that have
dither options (like RGB -> INDEXED or u16 -> u8), give the user the
choice whether to enable dithering.
Apply and heavily modify patch from remyDev which adds "lock position"
to GimpItem, similar to "lock content". Lock position disables all
sorts of translation and transform, from the GUI and the PDB.
Cleaned up some aspects of the lock content code as well because a
second instance of similar code always shows what went wrong the first
time.
but only to the virtual function, not the public API. Implement it in
GimpSelection and GimpLayerMask, and pass the correct mask format down
to the parent class which does the actual conversion.
Add "layer_dither_type" and "mask_dither_type" to
GimpDrawable::convert_type(), pass around the dither type from the
dialog, and implement dithering using gegl:color-reduction.
Use gimp_config_writer_string() instead of gimp_config_writer_printf()
to serialize module-load-inhibit so backslashes and other stuff gets
properly escaped.
and make the blend tool (Shape: Shaped (angular)) sligthly
more efficient
with an opaque layer (400x300) goes from:
gradient_fill_region: gradient_fill_region took 52.69 seconds
EEEEeEeek! 2 GeglBuffers leaked
to:
gradient_fill_region: gradient_fill_region took 5.90 seconds
Reset the tool on image changes again, but not if only the active
drawable changes, so keep bug #678890 closed:
Introduce new dirty flag GIMP_DIRTY_ACTIVE_DRAWABLE and set it on all
tools' dirty_mask except for rect select. Check the new flag when
reseting the active tool because of a drawable change.
gimp_viewable_get_pixbuf(): if there is a cached pixbuf of the right
size, actually return it, instead of the local "pixbuf" variable which
is always NULL.
Another attempt to fix paste/drop positions for good.
Paste/drop target is either the selected area of a drawable, the
drawable itself, or the image:
- if the paste is larger than the target, center on the target
- if there is a viewport, and the viewport intersects with the
target, center on the intersection
- otherwise, center on the target
Finally, if we did viewport-centered pasting, make sure the paste is
as completely within image bounds as possible.
Fix this and other issues more globally by moving the logic that
formats the image's display name into the GimpImage object, and return
the properly formatted name, e.g. "Foo.xcf", or "[Foo] (imported)"
from gimp_image_get_display_name().
Also add gimp_image_get_display_path() which returns the full path
instead. Use the two functions for formatting the image title, and
apply various other fixes that make sure the UI always uses the same
string to identify the image.
Call gimp_object_name_changed() whenever the save/export status
changes, so the image's cached display name and path get cleared.
==7785== 96 bytes in 4 blocks are definitely lost in loss record 16,947 of 20,720
==7785== at 0x4A0884D: malloc (/builddir/build/BUILD/valgrind-3.7.0/coregrind/m_replacemalloc/vg_replace_malloc.c:263)
==7785== by 0x87F52DE: g_malloc (glib/glib/gmem.c:159)
==7785== by 0x8809741: g_slice_alloc (glib/glib/gslice.c:1003)
==7785== by 0x87EBF0D: g_list_prepend (glib/glib/glist.c:275)
==7785== by 0x6FA596: gimp_item_stack_get_item_list (gimp/app/core/gimpitemstack.c:175)
==7785== by 0x6D97B4: gimp_image_convert_precision (gimp/app/core/gimpimage-convert-precision.c:55)
==7785== by 0x49B62E: image_convert_precision_cmd_callback (gimp/app/actions/image-commands.c:236)
gimp-2.9 used to print:
(gimp-2.9:3): GEGL-gegl-node.c-WARNING **: gegl_node_pads_exist:
Can't find source property outout of gegl:translate 0x10cbde10
before crashing
And along with it a lot of stuff like the drawable preview cache, the
gegl tile manager backend, temporary gimp_gegl_buffer_foo() stuff, and
the remaining bits of performance.
The projection is in an evil semi-ported state which makes it work
ok-ish for stuff like layer moving, but absolutely unbearable for
painting, there is also an off-by-one rendering glitch at some zoom
levels.