instead of simply reffing drawable->tiles. Add boolean property "copy-tiles"
and a boolean parameter to gimp_image_undo_push_drawable_mod() to control
the new feature. However, pass FALSE in gimp_drawable_real_set_tiles() (which
currently is the undo's only user)
Add gimp_markup_extract_text() which does just what it says (includes
code stolen from gmarkup.c), and use it if the layer's text object
doesn't have any text set.
and get rid of the brainfuck idea that app/ has to use _gimp_unit_foo()
functions, passing a gimp pointer. Instead, simply use the libgimpbase
API all over the place. Should we ever allow more than one gimp instance,
they will simply have to share one unit database.
gimp_drawable_get_mode_node() was calling gimp_drawable_get_node()
instead of gimp_item_get_node() if the mode_node didn't already exist.
Fortunately that was never the case i nthe current code. Added
warnings in the GimpItem::get_node() impls that would go off in such a
situation.
because the device info container wants to be displayed in a container
view soon. Also we are about to get lists of tool presets and stuff,
which are also contexts.
Add gimp_image_new_from_drawable(), from_component() and from_pixbuf()
and remove that duplicated code from gimptoolbox-dnd.c and
gimpdisplayshell-dnd.c
Don't write to the string returned by gimp_object_get_name(). Pull
most of the code out of the inner loop (which also means to allocate
only one instead of three strings in the inner loop). Don't use the
object as storage for the name that gets generated in the inner loop.
Also, a space can't hurt so it's now "Foo #1" instead of "Foo#1".
Switch off unique names for all individual item stacks and make sure
that all items in a GimpItemTree have unique names across all
containers. Uses a hash table and thus gets rid of the O(n**2)
complexity of the unique name code in GimpList.
this is pretty pointless from an abstraction point of view, but using
these functions will make the code a lot more readable by getting rid
of tons of ugly casts to and from GimpViewable whenever getting an
item's parent.
and use them from gimp_image_add,remove_layer,channel,vectors().
Removes quite some code duplication from the remove() functions but
almost none from add() because of the ongoing floating selection
madness. We need the calls to the item tree anyway because it's
going to ensure unique names of its items.
- get rid of the individual undo types and add GIMP_UNDO_ITEM_REORDER.
- replace the pushing functions by a single one.
- merge all the actual undo code into gimpitempropundo.[ch].
- use gimp_item_tree_reorder_item() to do the actual reordering.
- fix gimp_item_tree_reorder_item() to use an ordinary "push_undo"
boolean again instead of a pointer to an undo function.
GimpVectorsPropUndo is now a completely empty skeleton. Keep it around
anyway, maybe we'll get vectors properties to undo soon.
and remove the code duplication in gimp_image_reorder_layer(),
_channel() and _vectors(), which now consist of a single call to
gimp_item_tree_reorder_item().
This commit is basically just an exchange of the stack-keeping
objects and one big replacement of e.g. private->layers by
private->layers->container. Useful code will follow :)
Instead, use the proper "add" APIs and remove checks for the guides /
sample points being at the right positions (they might be out of image
when an image resize or rotation is undone). Add comments to make
clear that these functions are internal API, also add comments to the
proper public APIs so it's clear which one to use in which situation.
In order to make a clear separation between the core modules and the
UI modules, move the necessary enums from display-enums.h and
widgets-enums.h to config-enums.h and the files
gimpdisplayoptions.[ch] from the display to the config module. This
removes the config -> display dependency.
This change has three main benefits
* It lets us remove includes of display files from the config module
* We don't have to link gimp-console and test-config with a subset of
object files from the display module
* It is reflected in devel-docs/gimp-module-dependencies.svg that the
application is made up of core modules and UI modules and that no
core module depends on any UI module
Add GIMP_LOG_FLOATING_SELECTION domain to get rid of the somewhat
annoying debug prints. Floating selection is likely to require further
debuggin later on, so instead of just removing the output, use
GIMP_LOG for it.
For generated brushes, dynamic input is applied on top of the set hardness as a factor.
For pixmaps, it influences the amount of blur applied to the stamp. Be warned, process is slow
for large pixmaps. The odd feature previously advertised as hardness is left in but disabled.
If I figure out what it should be exposed as, it might be made available again.
By default, get the operation from gimp_layer_mode_to_gegl_operation()
and special-case all modes except from "normal", so the special cases
actually become less as the new operations are filled with code.
Makes gegl-curves about 1/3 faster for a simple case where only
the "value" curve was changed. The speedup should be better when
multiple curves are changed from the identity mapping.
Spacing is now dynamically controllable. Unlike other parameters it
made little sense to scale down from default spacing so it scales between
current and maximum spacing.
* app/core/gimpdata.c (gimp_data_get_identifier): check if the data's
path starts with either of those and use the symbolic paths in that
case.
* data/tags/gimp-tags-default.xml.in: use them here too instead of
/home/martin/foo/bar/...
This way we can ship a default file that makes sense, and need much
less identifier remapping. The identifiers even stay the same when
upgrading GIMP.
(gimp_data_factory_refresh_cache_add): don't add data objects without
filename to the refresh cache. Regardless why they have no filename,
they can't be reloaded anyway (in this case it's newly created objects
that couldn't be saved because there is no folder to save them).
Make the function do what is says also if the callback doesn't remove
the data from the factory, argh... also add "gboolean skip_internal"
parameter because doing that unconditionally feels equally broken.
(gimp_data_factory_get_save_dir): add GError and return an error
message telling why exactly a writable folder could not be found.
Show that error message instead of silently failing of just giving a
useless generic error so the user knows how to fix the problem.
Keeping gimp_data_factory_data_reload() separate from
gimp_data_factory_data_refresh() is more confusing than helpful
because the function is an integral part of the refresh logic and
implemented everything but saving all dirty objects.
Because that warns badly. The functionality is unchanged though
because the code does properly check for 0 quarks. Also moved some
variables to local scopes.
Rename gimp_get_image_window_iter() to gimp_get_image_windows() and
make it return a copy of the list of windows. Typically we will kill
or create new windows when we use this function which is why we do a
copy.
Always run user_install_create_files(), even if
user_install_migrate_files() was run before, but make sure not to
overwrite stuff that has been copied by user_install_mirgate_files().
This reverts commit 793be22da9.
This commit makes single factor dynamics not work.
The result of a no-factor mixing needs to be 1.0,
result of all other cases needs to be value of total divided by factors.
Adding extra logic for the case whe factors=1 makes less sense than
allowing for occational division by 1 to happen.
* app/core/gimpdynamics.c: remove all boolean properties and add the
outputs as properties instead. Make sure changes on the outputs get
notified on the dynamics object.
* app/widgets/gimpdynamicseditor.c: change widget creation accordingly,
also copy around the properties correctly when copying between
dynamics objects (fixes NULL filenames on GimpData).
The actual algorithm is still the same sick algorithm that was used
before. But instead of iterating the mask row-by-row and filling
it in small spans, we now use one pixel_regions_process() loop to
process the whole mask. Makes a significant difference for large
elliptical selections.
Remove gimp_channel_add_segment() and gimp_channel_sub_segment()
as they are not needed any longer and were responsible for the
bad performance.
Solved a bug in the bilinear interpolated brush transform algorithm that
sometimes caused pixel artifacts to appear on brush edges for brushes
rotated 90, -90, -180, 180 degrees.
Make sure the duplicated group layer actually has a properly set up
tile manager taken from its projection, and not just a dumb copy of
the original group's tiles. Also optimizes away useless calls to
gimp_group_layer_update_size().
(gimp_image_merge_visible_layers): merge the visible layers in the
active layer's group. We can't possibly merge across different groups
anyway because there is no logical place to add the merged layer.
Moreoever, this change makes the group behave more like a sub-image,
which is our metaphor anyway.
There is no reason to disallow this, the merged-down group layer will
simply disappear from the image just as a normal layer, and its
projection composited with the layer below.
(gimp_group_layer_duplicate): change the allowed type of the duplicate
from GIMP_TYPE_GROUP_LAYER to GIMP_TYPE_DRAWABLE. The former was
simply a braino when copying and modifying the GimpLayer code.
* app/core/gimpdrawable.[ch]: add "gboolean push_undo" to
GimpDrawable::convert_type().
* app/core/gimpdrawable-convert.[ch]: same here for the gray and rgb
conversion functions.
* app/core/gimpchannel.c
* app/core/gimplayer.c: pass FALSE when called from GimpItem::convert()
because it can be called on unattached items only.
* app/core/gimpimage-convert.c: pass TRUE.
* app/core/core-enums.[ch]
* app/core/gimpgrouplayerundo.[ch]
* app/core/gimpimage-undo-push.[ch]: add GIMP_UNDO_GROUP_LAYER_CONVERT
which simply calls gimp_drawable_convert_type() with the old type
when undone/redone.
* app/core/gimpgrouplayer.c: push a group layer convert undo so this
can be properly undone/redone.
Needed because a group layer's projection can have a different type
than its image, at least at some pathologic moment during image type
conversion. But even if it didn't, it's cleaner this way anyway.
* app/core/gimpprojectable.[ch]: add the new vfunc plus public API.
* app/core/gimpprojection.c: use it instead of using the type of the
image returned by gimp_projectable_get_image(). The get_image()
function is now unused in the projection and only needs to stay
because the projection is also a GimpPickable.
* app/core/gimpgrouplayer.c: implement GimpProjectable::get_image_type().
Move pixel conversion code from gimp_layer_convert() to the new
gimp_layer_convert_type() implementation and call
gimp_drawable_convert_type() from convert(). In convert_type(), simply
chain up to convert to gray and rgb and only implement indexed
conversion ourselves.
This may look like duplication of GimpItem::convert() but in fact will
fix the longstanding uglyness that GimpItem::convert() both transfers
an item to another image *and* converts the image type of drawables.
When this refactoring is done, GimpItem::convert() will only move an
item to another image, and its implementation in GimpDrawable classes
will call GimpDrawable::convert_type() to convert the pixels to
whatever format.
Takes a "dest_image" parameter anyway because for converting to
indexed we need the destination colormap. The default impl in
GimpDrawable can only convert to gray and rgb however.
Don't blindly fill the dest region's alpha channel even if it has
none. Fixes longstanding bug that made things without alpha dropped
to indexed images to arrive broken.
The new functions reall convert the drawable this time, using the
previously renamed convert_tiles functions. Remove tile manager
fiddling from all callers and leave it there only for converting to
indexed.
Rename them from gimp_drawable_convert_foo() to
gimp_drawable_convert_tiles_foo() because they don't convert the
drawable itself, they convert its tiles into passed-in tiles.
* app/core/gimpgrouplayer.[ch]: add gimp_group_layer_suspend_resize()
and gimp_group_layer_resume_resize() and call them around functions
where all a group's children are transformed (translated, resized
etc). This way we go from the worst case of reallocating the
group's projection tiles once for each child down to exactly one
reallocation.
* app/core/Makefile.am
* app/core/core-enums.[ch]
* app/core/core-types.h
* app/core/gimpimage-undo-push.[ch]
* app/core/gimpgrouplayerundo.[ch]: add new undo class
GimpGroupLayerUndo which implements undos for suspend/resume of
group layers and calls them in reverse order when undoing.
When the projectable's size or image type changes, stop the idle
renderer and remove all queued update area because everything needs to
be re-rendered anyway. Also honor the projectable's offset when
invalidating the entire projection after clearing the pyramid.
The optimization here which would change only the group layer's offset
if the extents of the union of its children has not changed is
completely bogus. That case can only happen if one of the chldren was
moved in a way that does not change the extents of all children's
union, but this doesn't mean that the childrens' positions relative to
each other have not changed.
Instead, invalidate the entire projection to at least avoid constant
reallocation of the tile pyramid.
Found by group layer testing hero Tobias Jakobs.
(will have to optimize real translations of the entire group (or of the
only child in the group) differently)
Having a function that only abstracts whether there is an active
layer or not is pretty useless. This also doesn't make the code in
selection_generate_segs() more complex but rather more obvious.
When attaching/detaching a floating selection to/from its drawable,
connect/disconnect the floating selection's "update" signal and update
the drawable in the callback, because changes to the floating
selection affect the drawable and not the projection directly. Fixes
floating selection compositing in layer trees and is the right thing
to do anyway.
The opposite of gimp_item_get_path(), just that it doesn't return an
item, it returns a parent item and an index that can be used to add
the item to an item tree.
Use the new API whenever we want to determine the item's effective
lock state (whether we can write to the item's content or not). Use
gimp_item_get_lock_content() only in code that actually deals with
*this* item's locked state, which is only the PDB wrappers and GUI to
modify the flag on the item itself.
Begin to consider GimpObject::name as private and always use
gimp_object_get_name(). Change gimp_object_get_name() to take an
untyped pointer so we don't have to do so awfully many casts. There is
a runtime check for the type inside the function anyway.
Make sure a group layer really emits all needed size change signals
when children get added and removed, so the group layer above it can
also update itself based on these signals. Spotted (again) by tobi.