Add a new Gimp::tool_item_ui_list, which is a GimpTreeProxy over
Gimp::tool_item_list. This allows us to use either a hierarchical
or a flat tool list in the UI, by setting the "flat" property of
the new list.
Use Gimp::tool_item_ui_list in GimpToolPalette, so that the toolbox
layout is affected by this choice.
Add a "Use tool groups" toggle to the toolbox preferences, and bind
it to the "flat" property of Gimp::tool_item_ui_list.
Add a new GimpTreeProxy container class, which proxies a
GimpViewable tree. The proxy has a dynamically-settable boolean
"flat" property, which controls if the tree hierarchy is preserved,
or if it's viewed as a flat list.
Add a new GimpContainer::search() virtual function, and a
corresponding gimp_container_search() function, which works
similarly to gimp_container_foreach(), except that the callback
returns a boolean. When the callback returns TRUE, the search is
stopped, and the current object is returned.
Implement GimpContainer::search() in GimpList.
Add a new read-only GimpToolItem::shown property, and a
corresponding GimpToolItem::shown-changed signal, which determines
if a tool item is visible throughtout the hierarchy, i.e., if it
and all its ancestors are visible. This replaces
gimp_tool_item_is_visible().
Use the new property and signal in GimpToolPalette and
GimpToolEditor, to simplify the code, and in preparation for a flat
toolbox view.
In GimpToolManager, use a weak pointer for tracking the active tool
group, instead of taking a reference on it. This avoids
erroneously extending the group's lifetime, which can cause
problems with the tool-item hierarchy.
In GimpToolGroup, make sure that newly-added tools don't already
have a parent.
Move the logic for translating a tool identifier to a corresponding
action name to GimpToolInfo. It's currently only used in
tools-actions.c, but the next commits will use it in tool buttons.
Allow creating GimpToolInfo objects with a NULL menu label, and do
that for GimpOperationTool. The previous commit effectively
removed it from the Preferences tool editor, and this commit also
removes it from the action search.
Add a new Gimp::tool_item_list list, in addition to
Gimp::tool_info_list. The latter may contain arbitrary tool items,
including tool groups, and is intended for use in the UI (namely,
the toolbox and the preferences tool editor).
In gimp-tools, use Gimp::tool_item_list for representing the UI
tool order (while still using Gimp::tool_info_list as a flat list
of all GimpToolInfo objects), and add support for saving and
loading tool groups to/from toolrc.
Introduce file-version tracking in toolrc, and drop its contents on
version mismatch, or when new tools are introduced. This is
slightly disruptive, but merging new changes with existing toolrc
files is non-trivial, and it doesn't happen very often.
Add support for a sysconf toolrc file, which is used if there's no
user toolrc file (i.e., on first use). If neither file is found,
the hard-coded flat tool order is used. This commit doesn't
provide a default toolrc file, but the next commits will.
Make the gimp-tools serialization and deserialization functions
public, for use in GimpToolEditor in the next commits.
... if not using unique names
Add a new GimpContainer::get_unique_names() virtual function, and a
corresponding gimp_container_get_unique_names() function, which
determines if the container uses unique names for its objects.
Override get_unique_names() in GimpList, to return the corresponding
property.
In gimp_container_deserialize(), don't merge new objects with
existing objects sharing the same name if the container doesn't use
unique names.
Add GimpToolGroup as a new subclass of GimpToolItem, representing a
collection of tools. The end goal is to display tool groups using
a single button in the toolbox.
Tool groups are not recursive: they can only contain individual
tools, not other groups. Each group has a single "active tool",
normally the most-recently-used tool of the group, which is
activated when clicking on the tool's button.
Add GimpToolItem as a common base class for toolbox items.
Derive GimpToolInfo from GimpToolItem, representing an individual
tool. The next commits add support for tool groups, represented by
an alternative subclass of GimpToolItem.
Most of the tool-info properties remain in GimpToolInfo, however,
GimpToolItem takes care of tool-item visibility.
Changed the reflection method to find the middle of the slice the
user is drawing on, and reflecting on that. This reflects the slice
in place, making it easier to rotate it to the intended location.
This fix preserves the order the dabs are drawn on the
slices, to be counterclockwise.
Fixed the brush transform, by setting the reflect output variable,
and calculating accordingly.
When dowscaling an image (or a layer group), empty layer groups
can be discarded as a result of their new dimensions being too
small, since we're calculating their new dimensions according to
their fake 1x1 dimensions. However, these dimensions are purely an
implementation detail and shouldn't affect the result, and neither
do we show a warning for them.
Instead, simply avoid discarding empty layer groups.
Restrict last commit's workaround to layer groups only (which is
the only relevant case ATM), since it negatively impacts the warp
tool, which does rely on the ability to perform (accurate) partial
updates with filters to improve performance. It's only a temporary
hack anyway.
When a drawable has filters attached, they may influence the area
affected by drawable updates. Currently, we ignore that, updating
the original region regardless. This can lead to drawable updates
not affecting the correct regions. This couldn't be triggered
until now, but since layer groups can now have a transform op
attached as a filter, updates to their sublayers -- which can
happen while the transform tool is active -- run into this problem.
Fix it for now by simply updating the full drawable region when the
drawable has filters. This is a very conservative approach -- we
don't even bother checking if we're only dealing with point
filters, as this change only influences transformed groups right
now. Ultimately, we need to rely on node invalidation to drive
updates, which takes this into account.
Using any clipping mode other than ADJUST is currently broken for
layer groups, since each layer in the group is clipped
individually, instead of clipping being applied to the group as a
whole. Ultimately, we should fix that, but for now, simply disable
clipping for layer groups, by overriding GimpItem::get_clip() to
always return ADJUST.
... (used to add one automatically)
In GimpFilterTool and gimp_drawable_apply_operation(), use
gimp_drawable_filter_set_add_alpha() to add an alpha channel when
applying an operation that specifies "needs-alpha" to a drawable
that can have alpha.
Don't disable gegl:color-to-alpha (which has "needs-alpha") when
the drawable doesn't have an alpha channel, if one can be added.
Add a new GimpDrawable::supports_alpha() virtual function, and a
corresponding gimp_drawable_supports_alpha() function, which
determine if the drawable supports an alpha channel. The default
implementation returns FALSE, and GimpLayer overrides it to return
TRUE.
The crop-to-result and crop-with-aspect transform-boundary
algorithms seem to consistently fail in some cases, and spit out a
warning, which can be too verbose if it triggers the debug dialog.
Demote the warning to a g_printerr(), with an eye to just dropping
these algorithms altogether.
In GimpDrawableFilter, add a
gimp_drawable_filter_set_override_constraints() function, which
allows bypassing certain constraints applied to the filter, based
on the drawable type and state.
Yes, this is a bit of a hack, added mostly as a quick-and-dirty way
to allow us to add filters to layer masks that affect their
bounding box, in preparation for composited transform previews.
Add an optional "format" parameter to gimp_drawable_merge_filter(),
which specifies the format to use for the output, possibly changing
the drawable's format.
In GimpDrawableFilter, add a gimp_drawable_filter_set_add_alpha()
function, which allows the filter to add an alpha channel to the
drawable when committed (by passing an appropriate format to
gimp_drawable_merge_filter()).
Change the default implementation of
GimpDrawable::get_bounding_box() to return the drawable source
node's bounding box, instead of the drawable's item bounds. This
allows filters to affect the size of all drawables, including, in
particular, layer masks.
Change GimpLayer's implementation of get_bounding_box() to return
the intersection of the layer's own bounding box, and the layer
mask's bounding box (if it has one), and update the layer's
bounding box when the mask is enabled/disabled, or when its
bounding box changes.
... by synchronously flushing the group's projection. This is
necessary for pass-through groups, since their projection is
normally flushed asynchronously.
Add a "clip" property to GimpCanvasTransformPreview, specifying the
transform's clipping mode, and clip the preview accordingly.
In GimpTransformGridTool, sync the tool's clipping mode with the
preview's clipping mode.
Which is a linear transform of xyY that is more perceptually
uniform, and so well-suited for eventually adding chromaticity
diagrams to GIMP color tools. ACES documentation uses this color
space instead of xyY for showing chromaticity diagrams. Moving
forward I expect other venues also will start using Yu'v' as
the advantages over xyY chromaticity diagrams are fairly obvious.
... or copied RGB channel
In gimp_drawable_merge_filter(), make sure the drawable's source
node is constructed before applying the operation. The
construction of the source node connects the drawable's filter
stack to the udnerlying source node (usually, the buffer-source
node), which we rely on when calling
gimp_gegl_apply_cached_operation(), since we pass
connect_src_buffer == FALSE. Otherwise, the operation is applied
to an empty input, instead of the drawable content.
We are running gimp_image_set_imported_file() when saving, with NULL to
drop the tie with the imported file. Let's only change the default
resolutions when we actually set an imported file.
Also set the `resolution_set` flag even when it doesn't change the
current values (hence no undo or signals), for instance setting from 300
to 300 PPI. In such case, even though nothing changes, the resolution
has to still be considered as explicitly set.
In the reporter case, any one of these 2 fixes is enough.
See also commit fef9b1d2a3 (set to 72 PPI as default for imported files
only) and commit a8f552da2f (set imported file to NULL).
Just fixing previous commit like this instead of wasting time in gitlab
with useless reviews for oneliners. When will gitlab allow us to amend
patches directly before merge?!
In GimpLineArt, add support for arbitrary input-buffer extents,
by shifting/unshifting the input/output buffers before/after
passing them to the main algorithm, so that the algorithm keeps
working with buffers whose top-left corner is at (0, 0).
In GimpImageProxy, implement the GimpPickable interface, so that
the proxy can be used as both a viewable and a pickable for the
image projection, with direct control over the show-all mode. This
will allow us to use a GimpImageProxy as input for a GimpLineArt.
Add an internal gimp_image_get_preview_format(), which returns the
format to use for preview buffers, and use it in both
gimpimage-preview and GimpImageViewable, to reduce duplication.
Add an n_components parameter to gimp_histogram_clear_values(),
which allows to set the new component count when clearing the
histogram. This is useful to seed the histogram with the correct
number of channels, for display purposes, before starting an async
histogram calculation. We use this in GimpHistogramEditor, to
avoid resetting the view's channel back to "Value" each time the
active drawable changes.
In GimpHistogram, get rid of the "n-channels" property and
corresponding gimp_histogram_n_channels() function. The former
returned the actual number of channels, but this wasn't too useful,
as channel values may not be sequential; the latter returned the
number of components. Instead, add an "n-components" property and
a corresponding gimp_histogram_n_components() function, both of
which return the number of components. Furthermore, add a
gimp_histogram_has_channel() function, which determines if the
histogram has a given channel; this allows for simple testing for
channel availability, which was done wrong in various places.
Adjust the GimpHistogram code for the changes, and clean it up,
fixing a few bugs.
Adjust users of GimpHisotgram for the changes. In particular,
in GimpHisotgramView, fix the channel-availability test when
setting the view's histogram (which happens whenever the active
drawable's preview is frozen), to avoid erroneously swithcing the
view's channel back to "Value" when a non-RGB channel is selected.
More of the files were wrong, or at least not absolutely identical to
the files generated by the autotools. I am not doing any code change
other than trying to make both build systems produce identical files
(except for slight differences on 2 files not worth the effort) even
though maybe some things can be improved (especially on the include
list). Maybe to be improved later.
Also fixing 2 of the previously autotools-generated files because of
space typos which should have been committed earlier.
Finally it is to be noted that there is no logics to copy the generated
files back to the source directory in the meson rules. I am not sure
anyway this is really worth it and maybe we should just stop tracking
these generated files eventually.
New images should obviously still default to the template pixel density
(defaulting to 300.0 PPI when no specific template is selected).
Loaded images though should use a more conservative default of 72 PPI,
first because this is what other software defaults to when no density is
set (so we should keep consistent when possible), and this is also what
the Exif standard (I checked both last version 2.32, and older 2.3)
recommends when no resolution is set.
Technically we differentiate a loaded from a newly created image by
whether or not an imported_file has been set. Of course, any explicitly
set resolution will always override whatever default.
Alawys clip a floating selection to its base layer, if the layer
has no alpha channel. This avoids arbitrarily filling the extended
regions of the layer with, or compositing the floating selection
against, black color.
This is a temporary solution. Ideally, we'd automatically add an
alpha channel to the layer as necessary.
In gimp_gegl_apply_cached_operation(), add a boolean
connect_src_buffer parameter, which determines whether to connect
the source buffer to the operation-node's input, or to use its
existing input. In gimp_drawable_merge_filter(), pass FALSE for
connect_src_buffer, so that the existing filter-node input is used.
This produces an equivalent result, however, it avoids invalidating
the filter node, and dropping cached data as a result. In
operations that cache larger areas than the ROI, this avoids
reprocessing already-cached data when processing the rest of the
operation.
Additionally, in gimp_gegl_apply_cached_operation(), use an empty
input for the operation if src_buffer is NULL and
connect_src_buffer is TRUE; previously, we'd use the operation-
node's existing input when src_buffer was NULL. Furthermore, crop
the operation-node's input to the destination rect when crop_input
is TRUE, even if connect_src_buffer is FALSE.
When the bounding box of a floating selection changes, update the
bounding box of the associated drawable, since floating selections
are no longer clipped to the drawable's bounds in general.
When attaching a floating selection to a layer, don't clip the
floating selection to the layer's boundary, and instead resize the
layer to include the entire floating selection when it's anchored.
As per the last commit, this can be prevented by locking the
layer's position.
When applying a filter to a layer whose position and size are
locked, avoid resizing the layer to the result size in ADJUST mode.
We do this by always returning GIMP_TRANSFORM_RESIZE_CLIP in
gimp_item_get_clip() when the position is locked, and properly
updating the drawable-filter's clip mode, and the filter-tool's UI,
when the position lock changes.
Add internal gimp_image_{freeze,thaw}_bounding_box() functions, and
use them in gimp_image_reorder_item() to avoid updating the
bounding box multiple times while moving a layer across group
boundary, to prevent flickering.
In GimpImage, update the image's bounding box in response to the
layer container's "add" and "remove" signals, instead of during
gimp_image_{add,remove}_layer(), so that the bounding box is
properly updated when moving an existing layer inside/outside of a
layer group, instead of only when adding/removing a new layer.
Even though moving a layer across group boundary doesn't change the
overall image bounding box, it does change the group's bounding
box, affecting the image bounding box. It's therefore necessary to
update the image bounding box again when the layer is re-added to
the layer stack, so that the bounding box doesn't get stuck in an
intermediate state.
It's an ancient concept from ancient times when we didn't have URIs
and only filenames (not to speak of GFile), and actually even from
before the ancient time before that ancient time when we first had
ones and zeros, and only had zeros.
In gimp_group_layer_mask_changed(), avoid recalculating the group's
bounding box if it hasn't been calculated yet, since, not only is
this unnecessary in this case, but it causes the group's mask to
be erroneously clipped upon duplication, when set by
gimp_layer_duplicate() while the group is still empty.
paste as brush, paste as pattern, select to new brush, select to new pattern
fill selection outline, fill path, stroke selection, distort, rounded rectangle
indexed color conversion, merge visible layers, new guide, new guide (by percent)
image properties, newsprint, fractal explorer, sample colorize, new layer
metadata editor (just a button), spyroplus (only common buttons)
In the bucket-fill tool, allow using the tool outside the canvas
bounds with "sample merged" active in "fill similar colors" mode,
when the current display is in "show all" mode. Additionally,
ignore "sample merged" in "fill whole selection" mode, on which it
has no effect.
Add a show_all parameter to gimp_image_pick_color(), which, when
TRUE, allows picking colors outside the canvas bounds in sample-
merged mode. Forward the display's "show all" mode through this
parameter where applicable (in particular, in the color-picker tool
and the pointer dockable).
Add a new GimpImageViewable class, which acts as a proxy viewable
for an image. Unlike the image itself, whose preview is always
restricted to the size of the canvas, a GimpImageViewable provides
a show-all property, which controls whether the preview includes
the full image contents. We're going to use GimpImageViewable as
the source viewable for GimpNavigationView.
In GimpImage, make sure the image's pickable interface keeps
behaving as before (i.e., restricted to the canvas size), even when
the image is in "show all" mode. In contrast, the image's
projection, when used as a pickable, *is* affected by "show all".
... which invalidates the entire image. This replaces all calls to
gimp_image_invalidate() with the full canvas size, since the image
content can now be larger than the canvas.
Add a "show all" mode to GimpImage, which, when active, causes the
image projection's bounding box to be adjusted dynamically to the
combined bounding box of all layers and the canvas. This mode is
controlled through the new gimp_image_{inc,dec}_show_all()
functions, which should be called by the display; a corresponding
display toggle will be added in the following commits.
Note that from the user's perspective, "show all" is a display
mode, rather than an image mode. The GimpImage "show all" mode is
therefore merely an implementation detail, and shouldn't have any
effect on displays that don't use "show all" mode, or the PDB.
The ability to use the image with or without taking its "show all"
mode into account will be facilitated by the next commits.
In GimpProjection, avoid erroneously invalidating the projectable's
preview when flushing the projection and there's nothing to be
flushed, if the chunk renderer is still running, and hence the
projection is not fully rendered yet.
move the code to gimpparamspecs-body.c and include it from both app/
and libgimp/. They are the same apart from a minor difference which we
Also share the entire libgimp/gimpparamspecs.h header with the core.
GimpDisplay contains only the ID logic and the "gimp" and "config"
pointers, and lives in the core.
GimpDisplayImpl is a subclass and contains all the actual display
stuff. The subclass is only an implementation detail and doesn't
appear in any API.
Remove all hacks which pass displays as gpointer, GObject or
GimpObject through the core, or even lookup its type by name,
just use GimpDisplay.
Turn all ID param specs into object param specs (e.g. GimpParamImageID
becomes GimpParamImage) and convert between IDs and objects in
gimpgpparams.c directly above the the wire protocol, so all of app/,
libgimp/ and plug-ins/ can deal directly with objects down to the
lowest level and not care about IDs.
Use the actual object param specs for procedure arguments and return
values again instead of a plain g_param_spec_object() and bring back
the none_ok parameter.
This implies changing the PDB type checking functions to work on pure
integers instead of IDs (one can't check whether object creation is
possible if performing that check requires the object to already
exist).
For example gimp_foo_is_valid() becomes gimp_foo_id_is_valid() and is
not involved in automatic object creation magic at the protocol
level. Added wrappers which still say gimp_foo_is_valid() and take the
respective objects.
Adapted all code, and it all becomes nicer and less convoluted, even
the generated PDB wrappers in app/ and libgimp/.
Fixes the error:
> Critical error: gimp_line_art_thaw: assertion 'line_art->priv->frozen'
This may happen in cases when we didn't actually freeze the line art at
pointer click, because we were in an invalid case (for instance,
clicking out of selection), hence we must not thaw the line art either
at button release.
It's just too weird to be public. Remove its properties from the wire
protocol and from pluginrc. Instead, have all GParamSpecs' flags on
the wire and in pluginrc, so we can use stuff like
GIMP_PARAM_NO_VALIDATE.
Port the remaining few places to GIMP_PROC_ARG_STRING().
I'm sure something is broken now wrt UTF-8 validation,
will add tighter checks in the next commit.
GimpConfigWriter contains several constructors with the convention
`gimp_config_writer_new_* ()`. This will lead to problems however with
languages like Vala, where it cannot disambiguate the following:
```
// calls config_writer_new_string()
Gimp.ConfigWriter w = new ConfigWriter.string("xxx");
// calls config_writer_string()
w.string("xxx")
```
Using `from_` in constructors is general practice in GObject-bsed
libraries because of this.
This also fixes an error when trying to use vapigen on the GIMP .GIR
file.
In GimpProjection, when the projectable's size changes, while its
offset remains the same, simply update the projection buffer's
extent, instead of allocating a new buffer and copying the contents
over.
In gimp_init(), call gimp_enums_init(). We need to make all enum types
known to the type system by name because the PDB is now based on enum
type names.
Add a new gimp_image_transform() function, which transforms the
entire image, including all layers, channels (including selection
mask), vectors, guides, and sample points, according to a
transformation matrix. The canvas is resized according to the
clip_result parameter, the same way drawables are resized during
transformation; the layers are resized using ADJUST mode
regardless.
... which takes the symmetry axis as a parameter, instead of hard-
coding the axis to the middle of the image, and which additionally
takes the clipping mode as a parameter, controlling whether to clip
or resize the canvas. Note that the actual canvas size never
changes, but it may be offset when flipped around an off-center
axis, without clipping.
Implement gimp_image_flip() in terms of gimp_image_flip_full().
Remove the special clipping-mode handling for channels throughout
the transform (and drawable-filter) code, and rather use
gimp_item_get_clip(), added in the previous commit, instead. As
mentioned in the previous commit, we only modify the clipping mode
in top-level code, while having lower-level code use the clipping
mode as-is. This not only hides the actual clipping-mode logic
from the transform code, but, in particular, allows code performing
transformation internally to use arbitrary clipping modes.
Also, this commit fixes a bunch of PDB bugs all over the place :)
Add a new GimpItem::get_clip() virtual function, and a
corresponding gimp_item_get_clip() function, which return the
actual clipping mode to be used when transforming (or applying a
filter to) a given item, given the original clipping mode. This
applies only to whole-item transformations (i.e., when not creating
a floating selection), and should be used by the top-level code
applying the transformation, rather than by the actual
transformation code, so that the item can be transformed using a
different clipping mode internally.
Provide a default implementation that simply returns the input
clipping mode, and override for GimpChannel (to always return CLIP)
and for GimpVecotrs (to always return ADJUST).
Apart from being less code, this actually gives us a nice performance
improvement. Up until a few years ago, if you pass `NULL` as the
marshaller for a signal, GLib would fall back to
`g_cclosure_marshal_generic` which uses libffi to pack/unpack its
arguments. One could avoid this by specifying a more specific
marshaller which would then be used to immediately pack and unpack into
GValues with the correct type.
Lately however, as a way of optimizing signal emission (which can be
quite expensive), GLib added a possibility to set a va_marshaller, which
skips the unnecessary GValue packing and unpacking and just uses a
valist variant.
Since the performance difference is big enough, if the marshaller
argument is NULL, `g_signal_new()` will now check for the simple
marshallers (return type NONE and a single argument) and set both the
generic and the valist marshaller. In other words, less code for us with
bigger optimizations.
In case you also want va_marshallers for more complex signals, you can
use `g_signal_set_va_marshaller()`.
In gimp_palette_mru_add(), if the added color doesn't match an
existing color, don't look for two duplicate existing colors (which
has quadratic complexity), since there shouldn't be any under
normal circumstances (as we're not adding duplicates to begin
with).
`g_object_notify()` actually takes a global lock to look up the property
by its name, which means there is a performance hit (albeit tiny) every
time this function is called. For this reason, always try to use
`g_object_notify_by_pspec()` instead.
Basically this commit makes sure that all return values that are marked
as "Returns:" also have a `(nullable)` annotation if it is mentioned on
the same line that NULL can also be returned.
This will prevent a few problems in GObject-introspection.
Documentation-wise in C, this doesn't matter a lot, but it allows
GObject-Introspection based bindings to use their built-in versions when
they want to render any kind of documentation (for example, docs for
Python plugins can render `%NULL` as `None`).
In GimpDrawableFilter, add a new gimp_drawable_filter_set_clip()
function, which controls whether the filter clips the result to the
drawable's boundary, or extends it past it. The latter is only
possible for layers, when the selection mask is empty.
Add a new "clip" parameter to gimp_drawable_merge_filter(). When
set to FALSE, the function resizes the drawable to the bounding box
of the filter's output, instead of clipping the output to the
drawable's boundary.
In GimpGroupLayer, when recalculating the group's size as a result
of a change to one of the child layers (now including in response
to a child layer's GimpDrawable::bounding-box-changed signal),
calculate the group's bounding box (the bounding box of all its
child layers' bounding boxes) alongside its logical bounds. Like
in GimpLayer, use the logical bounds as the bounding box if the
group has a mask.
This bounding box is passed to the group's projection, via
GimpGroupLayer's GimpProjectable::get_bounding_box()
implementation, resulting in a buffer whose extent is the same as
the bounding box.
In GimpProjectable, replace gimp_projectable_get_size(), which only
returned a width and a height, with
gimp_projectable_get_bounding_box(), which returns a full
rectangle. This allows projectables to have an arbitrary bounding
box, not limited to a (0, 0) top-left corner.
Adapt GimpProjection, creating a buffer with corresponding extent
to the projectable's bounding box.
Adapt GimpImage and GimpGroupLayer.
Implement GimpDrawable::get_bounding_box() for GimpLayer, by
returning the bounding box of its source node. If the layer has a
mask, we simply return its logical boundary, since the layer can't
extend past the mask.
Maintain the bounding box of drawables (i.e., the bounds of their
actual rendered content) separately from their logical boundary (as
shown in the UI).
The bounding box is calculated through the new
GimpDrawable::get_bounding_box() virtual function, which has a
corresponding gimp_drawable_get_bounding_box() function; the
default implementation simply returns the drawable's logical
boundary. The bounding box is specified in drawable coordinates,
i.e., it's not affected by the drawable's offset.
The bounding box is recalculated through
gimp_drawable_update_bounding_box(), which should be called
whenever a change may affect the bounding box (for example, when
setting a new buffer, as done implicitly by GimpDrawable's
::set_buffer() implementation, or when a drawable filter's
properties change, as will be done by GimpDrawableFilter in a
following commit). When the bounding box changes, the affected
regions of the drawable are updated, and the
GimpDrawable::bounding-box-changed signal is emitted.
When gimp_drawable_update() is called with negative width/height
values, the entire drawable's bounding box is updated, rather than
only its logical boundary.
Likewise, GimpDrawableStack and GimpLayerStack are adapted to use
the bounding box, instead of the logical bounds, when updating the
drawable's area.
In GimpDrawable::set_buffer(), and the corresponding
gimp_drawable_set_buffer_full() function, take a bounds rectangle,
which specifies both the drawable's new offset and its new size,
instead of only taking the new offset. In
gimp_drawable_real_set_buffer(), set the item size according to the
rect dimensions, instead of the buffer dimensions. The rect's
width/height may be 0, in which case the buffer's dimensions are
used.
Adapt the rest of the code.
We do this in preparation for maintaining the drawable's bounding
box separately from its logical bounds, allowing the drawable
content to extend beyond its bounds.
which means that it's now included normally via gimpbase.h
and not any longer via gimpbasetypes.h which we only did out
of lazyness. A *lot* of files in libgimp* and app/ now need to
The latter is broken and doesn't guarantee a decimal point with the
current bug. Also, g_ascii_dtostr() doesn't need the format parameter
and produces nicer output.
- Change the wire protocol's GPProcInstall to transmit the entire
information needed for constructing all GParamSpecs we use, don't
use GimpPDBArgType in GPProcInstall but an enum private to the wire
protocol plus the GParamSpec's GType name. Bump the wire protocol
version.
- Add gimpgpparamspecs.[ch] in both app/plug-in/ and libgimp/ which
take care of converting between GPParamDef and GParamSpec. They
share code as far as possible.
- Change pluginrc writing and parsing to re-use GPParamDef and the
utility functions from gimpgpparamspecs.
- Remove gimp_pdb_compat_param_spec() from app/pdb/gimp-pdb-compat.[ch],
the entire core uses proper GParamSpecs from the wire protocol now,
the whole file will follow down the drain once we use a GValue
representation on the wire too.
- In gimp_plug_in_handle_proc_install(), change the "run-mode"
parameter to a GParamSpecEnum(GIMP_TYPE_RUN_MODE) (if it is not
already an enum). and change all places in app/ to treat it as an
enum value.
- plug-ins: fix cml-explorer to register correctly, a typo in
"run-mode" was never noticed until now.
- Add gimpgpcompat.[ch] in libgimp to deal with all the transforms
between old-style wire communication and using GParamSpec and
GValue, it contains some functions that are subject to change or
even removal in the next steps.
- Change the libgimp GimpProcedure and GimpPlugIn in many ways to be
able to actually install procedures the new way.
- plug-ins: change goat-exercise to completely use the new GimpPlugIn
and GimpProcedure API, look here to see how plug-ins will look in
the future, of course subject to change until this is finished.
- Next: changing GPParam to transmit all information about a GValue.
all the stuff from app/core/gimpparamspecs.[ch] that is not about
image, drawable etc IDs, these will have to go to libgimp with
different implementations than in app/.
When translating a layer group, avoid separately updating the
original area of the child layers before translating them (as per
the fix to issue #3484), as this results in quadratic time
complexity w.r.t. to the maximal subgroup nesting level. Instead,
simply defer the updating of the group's offset until *after*
translating the child layers, so that their original area isn't
clipped by the parent, while their new area is still properly
updated even if the parent's size changes (see comment in code).
There are no replacements. Just we must make sure that all GTK+/GDK
calls are run from the main thread, which is already what we were doing.
Actually I don't even think these were doing anything as we were not
calling gdk_threads_init() so the default lock functions were not set
anyway. These were just bogus calls.
Revert the previous commit 786686a541 and comes up with a better fix.
Let's actually change the image base type and add its colormap as close
as possible without any GUI calls in-between. I also add an explicative
comment so that people are aware of this call proximity requirement to
avoid future problems when the code gets remixed.
It should be better than hacking around with exception in GUI code, and
should (hopefully) avoid other similar bugs.
Make the returned values of g_list_length() a gint to avoid implicit
type conversion converting a possibly negative integer numberator into
unsigned int (which ends as a huge unsigned int instead of being
negative).
Found by Massimo!
Change all action callbacks so they can be invoked by a GAction:
- add GimpActionCallback typedef:
void (* cb) (GimpAction*, GVariant*, gpointer)
- change all action callbacks to the GimpActionCallback signature
- add "gimp-activate" and "gimp-change-state" signals to GimpAction,
with the same signature as the resp. GAction signals
- remove all other custom action signals and only use the new
GimpAction signals
- pass around appropriate GVariants containing booleans, int32,
strings
- badly hack around to force a GimpProcedure pointer into a
uint64 variant
- remove all G_CALLBACK() casts from all action callbacks,
they all have the same signature now
so gimp_curve_equal() doesn't fail on random uninitialized padding
bits. Fixes finding previously used settings in the curves tool (they
were piling up just by re-applying a previously used setting).