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.
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.
Add a new GimpDrawable::update_all() virtual function, and a
corresponding gimp_drawable_update_all() function, which updates
the full contents of the drawable. Unlike calling
`gimp_drawable_update (drawable, 0, 0, -1, -1)`, which updates the
entire drawable area, gimp_drawable_update_all() only updates the
area that has actual content. While the default implentation does
simply update the entire drawable area, GimpGroupLayer overrides
this function to recursively update its child layers, rather than
the its entire area.
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.
In GimpLineArt, use the "invalidate-preview" signal of the input
viewable, instead of its "painted" or "rendered" signals, for
asynchronously computing the line art. Subsequently, remove the
aforementioned signals from GimpDrawable and GimpProjection,
respectively. This simplifies the code, and reduces the number of
signals.
The "update" signal on drawable or projection can actually be emitted
many times for a single painting event. Just add new signals ("painted"
on GimpDrawable and "rendered" on GimpProjection) which are emitted once
for a single update (from user point of view), at the end, after actual
rendering is done (i.e. after the various "update" signals).
Also better support the sample merge vs current drawable paths for
bucket fill.
...linear and perceptual precision
Under certain circumstances (e.g. the image has no color profile),
GimpLayer's implementation of GimpDrawable::convert_type() didn't have
enough information to do the right color space conversion.
Intead of messing with stuff like "set profile in between doing a and b",
simply add a "src_profile" parameter to GimpDrawable::convert_type() so
the complete color space conversion information is available without
relying on obscure states that could change in the future.
Make sure all callers pass the right src_profile, particularly in
gimp_image_convert_precision(), which also needed fixing.
... which specifies whether or not to update the drawable in
response to the buffer change.
Pass TRUE for "update" at all existing call sites, to keep the
current behavior.
Add gimp_drawable_set_format() as low-level part of
gimp_layer_fix_format_space(), and add a special undo type for it that
only remembers the format and not the entire drawable buffer, because
all pixels stay the same.
All babl formats now have a space equivalent to a color profile,
determining the format's primaries and TRCs. This commit makes GIMP
aware of this.
libgimp:
- enum GimpPrecision: rename GAMMA values to NON_LINEAR and keep GAMMA
as deprecated aliases, add PERCEPTUAL values so we now have LINEAR,
NON_LINEAR and PERCPTUAL for each encoding, matching the babl
encoding variants RGB, R'G'B' and R~G~B~.
- gimp_color_transform_can_gegl_copy() now returns TRUE if both
profiles can return a babl space, increasing the amount of fast babl
color conversions significantly.
- TODO: no solution yet for getting libgimp drawable proxy buffers in
the right format with space.
plug-ins:
- follow the GimpPrecision change.
- TODO: everything else unchanged and partly broken or sub-optimal,
like setting a new image's color profile too late.
app:
- add enum GimpTRCType { LINEAR, NON_LINEAR, PERCEPTUAL } as
replacement for all "linear" booleans.
- change gimp-babl functions to take babl spaces and GimpTRCType
parameters and support all sorts of new perceptual ~ formats.
- a lot of places changed in the early days of goat invasion didn't
take advantage of gimp-babl utility functions and constructed
formats manually. They all needed revisiting and many now use much
simpler code calling gimp-babl API.
- change gimp_babl_format_get_color_profile() to really extract a
newly allocated color profile from the format, and add
gimp_babl_get_builtin_color_profile() which does the same as
gimp_babl_format_get_color_profile() did before. Visited all callers
to decide whether they are looking for the format's actual profile,
or for one of the builtin profiles, simplifying code that only needs
builtin profiles.
- drawables have a new get_space_api(), get_linear() is now get_trc().
- images now have a "layer space" and an API to get it,
gimp_image_get_layer_format() returns formats in that space.
- an image's layer space is created from the image's color profile,
change gimpimage-color-profile to deal with that correctly
- change many babl_format() calls to babl_format_with_space() and take
the space from passed formats or drawables
- add function gimp_layer_fix_format_space() which replaces the
layer's buffer with one that has the image's layer format, but
doesn't change pixel values
- use gimp_layer_fix_format_space() to make sure layers loaded from
XCF and created by plug-ins have the right space when added to the
image, because it's impossible to always assign the right space upon
layer creation
- "assign color profile" and "discard color profile" now require use
of gimp_layer_fix_format_space() too because the profile is now
embedded in all formats via the space. Add
gimp_image_assign_color_profile() which does all that and call it
instead of a simple gimp_image_set_color_profile(), also from the
PDB set-color-profile functions, which are essentially "assign" and
"discard" calls.
- generally, make sure a new image's color profile is set before
adding layers to it, gimp_image_set_color_profile() is more than
before considered know-what-you-are-doing API.
- take special precaution in all places that call
gimp_drawable_convert_type(), we now must pass a new_profile from
all callers that convert layers within the same image (such as
image_convert_type, image_convert_precision), because the layer's
new space can't be determined from the image's layer format during
the call.
- change all "linear" properties to "trc", in all config objects like
for levels and curves, in the histogram, in the widgets. This results
in some GUI that now has three choices instead of two.
TODO: we might want to reduce that back to two later.
- keep "linear" boolean properties around as compat if needed for file
pasring, but always convert the parsed parsed boolean to
GimpTRCType.
- TODO: the image's "enable color management" switch is currently
broken, will fix that in another commit.
In GimpPaintTool, brush outline generation took place during
gimp_paint_tool_draw() even while painting. This function is run
concurrently with the paint thread. When using dynamics, this
introduced a race conidition between updating the brush mask in the
paint thread, and updating the brush boundary in the main thread.
Move brush outline generation during painting to
gimppainttool-paint.c, and perform it in the display-update
timeout, while the main thread and the paint thread are
synchronized.
gimp_drawable_start/end_paint() are used to enter/exit paint mode
for a given drawable. While the drawable is in paint mode,
gimp_drawable_get_buffer() returns a copy of the real drawable's
buffer, referred to as the paint buffer, so that modifications to
the returned buffer don't immediately affect the projection, and
calls to gimp_drawable_update() queue the updated region, instead
of emitting an "update" signal.
gimp_drawable_flush_paint() can be called while the drawable is in
paint mode, in order to copy the updated region of the paint buffer
back to the drawable's real buffer, and to emit "update" signals
for the queued region.
We use these functions in the next commit, to move painting to a
separate thread in the paint tools.
... which transfers a buffer from one drawable to another in a safe
manner, leaving the source drawable empty.
There are already two ad-hoc instances where we steal a drawable's
buffer through simple pointer assignment, however, this avoids
performing potentially necessary cleanup and setup. In particular,
since commit d0ae244fe8 this causes
actual errors. The next two commits replace those instances with
calls to gimp_drawable_steal_buffer().
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.
Largely based on a patch by Ell, with the enum type renamed and
various small changes. Adds another axis of configurability to the
existing layer mode madness, and is WIP too.
with proper value names. Mark most values as _BROKEN because they use
weird alpha compositing that has to die. Move GimpLayerModeEffects to
libgimpbase, deprecate it, and set it as compat enum for GimpLayerMode.
Add the GimpLayerModeEffects values as compat constants to script-fu
and pygimp.
making its external API "complete". Remove the redundant
"new_base_type" and "new_precision" from the internal (vfunc) API (the
Babl format has the same information).
They are unreliable because every type checking cast discards them,
they are useless anyway, visual clutter, added inconsistently, and
generally suck. Wanted to do this a long time ago, it was a bad idea
in the first place.
instead of just a boolean "convert_profile". This takes the logic to
figure the right target profile out of gimp_layer_convert_type(), it
can't possibly know everything about how to convert anyway, and having
the logic in the callers conveniently splits it up and distributes its
parts to the places they belong.
This commit should cause no behavor change and is just preparation for
fixing bug 765176.
also add "GType old_type" to GimpItem::convert() so implementations
can do things depending on the type of the original item.
In gimp_layer_convert(), if the original item is also a layer, and
color management is not off (with a FIXME because this is the wrong
check), pass convert_profile = TRUE to gimp_drawable_convert_type().
There is no color profile conversion anywhere behind this, this is
just an API change commit.
- 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.
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.
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.
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.
Add GimpOperationMaskComponents, enum GimpComponentMask, and image and
drawable infrastructure to get the right mask, and plug the mask
operation into gimp_gegl_create_apply_buffer_node().