Add GIMP_DESATURATE_LUMINANCE to enum GimpDesaturateMode and rename
GIMP_DESATURATE_LUMINOSITY to GIMP_DESATURATE_LUMA.
Keep GIMP_DESATURATE_LUMINOSITY as deprecated compat value and add it
to the script-fo and pygimp compat constants.
Change GimpOperationDesaturate to process GIMP_DESATURATE_LUMINANCE
with linear "RGBA float".
When converting and image with a color profileimage between linear and
gamma, create a new profile using the new API in GimpColorProfile,
convert the layers to that profile and tag the image with the new
profile.
If creating a new profile fails, convert to the right builtin profile
(linear rgb or sRGB from GimpColorProfile), but that code should be
considered a fallback that will be prevented from happening in the
convert dialog (at least the user will be informed).
gimp_suggest_modifiers(): change "shift_format" and "control_format"
parameters to "extend_selection_format" and "toggle_behavior_format",
which fixes the longstanding problem that the function did the right
thing only by accident.
tools: use gimp_get_extend_selection_mask() instead of GDK_SHIFT_MASK
which is not 100% semantically correct in all cases, but at least a
step in the right direction to make the tool modifiers easier to
improve.
Add new XCF property FLOAT_OPACITY and always save both the old 8-bit
and the new float opacity of layers and channels. Float opacity is
saved after the 8-bit one so when loading, it overwrites the limited
8-bit value with the proper precision. Do not increase the XCF version
number because old GIMP versions will simply skip the unknown
FLOAT_OPACITY and keep using the 8-bit value.
This (doesn't quite) fix an obscure part of the tool preset bugs: when
changing the brush on a GimpPaintOptions instance, we might or might
not change the brush size, aspect etc. to the set brush's native
values, possibly overwriting the intended values from a tool preset.
Implement GimpConfig::copy() and copy the affected values again after
the entire object has been copied, so we actually use the value of
gimp_config_copy()'s "source" object.
This would fix that particular tool preset problem if there wasn't
another bug that is still unfixed, stay tuned...
In order to make things more obvious here. Before, a tool preset could
only be rstored from the list by selecting it, which only worked if
another preset was active before. Now the selected preset can easily
be restored again.
This reverts commit 2cef834198.
This feature is "undiscoverable" according to Mitch, and we are not sure
how much the endpoint colors are special to the user.
This reverts commit 15b5b2c8b3.
This feature is "undiscoverable" according to Mitch, and we are not sure
how much the endpoint colors are special to the user.
Now the history of recently used colors is not updated when selecting
in the color dialog anymore, but when a color is actually used.
Tools supported right now are: Ink, MyPaint brush, all PaintBrush tools,
bucket fill and eraser (background color on non-alpha drawables).
Moreover from now on, colors already saved are properly moved to first
position when reused.
Fix color managed layer previews when adding/removing alpha:
Implement GimpDrawable::alpha_changed() in GimpLayer and emit
GimpColorManaged::profile_changed() so all cached color transforms are
nuked.
...when a color profile is active
This commit adds more (still unused) infrastructure to fix this bug:
Ee now keep around color transforms from layer pixels to "R'G'B'A
double" (which is GimpRGB's format) and back. Also add utility
function gimp_image_color_profile_pixel_to_srgb() which converts a
picked pixel to GimpRGB, using the cached color transform.
Since commit 867b1f7e the window did always pop if it was set to
visible once, even if closed and "Use info window" disabled.
Fix this by adapting the show logic to the fact that we now keep the
widget alive across images/displays.
...from tool options crashes GIMP
Applied a modified patch that actually removes the target list if it
became empty. This may or may not fix the bug; I can't tell because I
couldn't reproduce it any longer.
...being displayed
Need to call gimp_image_flush() on all newly opened images so whatever
image states are properly updated:
Call file_open_sanitize_image() at the end of loading (after profile
import), and re-enable the flush() call in the function.
Also, don't fiddle with undo disabling and enabling in
gimp_image_import_color_profile(). Instead, disable undo before
calling the function.
...in initially active tab
We intend reuse the dialog across displays, so don't destroy the
dialog in GIMP_TOOL_CONTROL_HALT, only hide it. This way the dialog
keeps its detached state.
Don't hardcode modifier masks in the wheel and keyboard input
controllers. Instead, hardcode accelerator strings and get the right
modifier mask from gtk_accelerator_parse() at runtime.
This turns e.g. "<Shift><Primary>" into Shift+Cmd on OS X and into
Shift+Ctrl on X11 and Windows.
Also rename the events accordingly and change the event names in the
default controllerrc.
Unrelated: reorder the actions so the ones with less modifiers are
listed first, and change the order of action matching to match the
actions with most modifiers (the last ones) first.
...in initially active tab
gimp_tool_gui_update_shell(): implement the "overlay" case and hide the
gui on the previous shell, then show it on the new one.
Based on GimpPopup as parent, this is a generic search popup widget,
which can display any list of action. The results construction logics
is not part of the widget, and is built through a callback instead,
which could allow to use it to create different dialogs.
gimp_drawable_get_sub_preview(): both the preview buffer's scale
factor and the src coordinates in the drawable were calculated
wrongly. Found by Massimo.
While loading an image with color profile, gimp offers the possibility to convert it to the builtin profile. Setting the new color profile before converting, deletes the old one and results in a segmentation fault.
The "map" signal does not mean a widget is mapped. It may be emitted
before. Yet pointer and keyboard grabs won't work on non viewable
widgets and will fail with GDK_GRAB_NOT_VIEWABLE.
For some reason, a GtkWindow with type GTK_WINDOW_POPUP was always
mapped when "map" is emitted but not yet with type GTK_WINDOW_TOPLEVEL
(at least in my tests). Thus switch to "map-event" to make sure the
widget is actually mapped.
Implement color management in GimpViewRenderer: if the viewable is a
GimpColorManaged (true for images and layers), keep around a
GimpColorTransform and convert the preview image to display colors.
to not return a reference that has to be dropped. Also allow NULL to
be returned if the managed cannot have a profile. If it can have one,
get_color_profile() still always returns a profile (either the
assigned one, or a generated built-in one).
and change GimpImage and GimpItemStack to emit the "profile-changed"
signal when the image's profile changed. Also connect GimpViewRenderer
to "profile-changed" if the viewable is a GimpColorManaged and
invalidate the preview.
We will need the widget for color managing previews; it's also more
consistent to pass the widget to all render_foo() functions, not only
to render_icon().
gimp_image_constructed(): connect to "notify" on GimpColorConfig
and call gimp_color_managed_profile_changed() on the image.
Remove the "notify" handler on GimpColorConfig from
gimpdisplayshell-handlers.c because it already connects to the
image's "profile-changed" signal.
Additionally, implement GimpColorManaged::profile_changed() in
GimpImage and invalidate the image and all layer previews. One step
closer to color managing image and layer previews.
By default, it only saves the current file filter, but it allows a child
to implement its own state. It has been implemented by GimpSaveDialog to
save the preferred compatibility mode as well.
The code refactoring allows better readability which will allow in turn
to add more complex specific features making good use of the save/export
split concept.
which currently all end in a call to gimp_color_managed_get_color_profile()
except for channels and masks. This is currently unused infrastructure but
will be used for things like layer previews, and return NULL if called
on a mask or channel, or if color management is disabled, or whatever.
This would typically happen if the compat mode was set earlier through
the save dialog, then later changes in the image render it inapplicable.
When this happens, we unset the compat mode, and saves without error,
but still emit a warning for the user to know the compatibility got
dropped.
Call gimp_layer_update_mode_node() also when removing a mask, and
change it to only do its magic if there actually is a mask (don't only
look at the "show_mask" boolean).
...in the Levels dialog explain the difference between them
Improve the tooltips of the pick buttons to say
"Pick FOO point for {all channels|the selected channel}"
gimp_image_duplicate(): set the new image's color profile *before*
copying layers to it, or the new layers will be automatically
converted to "no color profile aka sRGB", but then tagged with the
original profile anyway.
and call it when an "icc-profile" parssite is attached or detached.
This removes code duplication and creates a place to conveniently
update more cached profiles and transforms, such as from/to sRGB for
color picking and applying.
if the same name is set via gimp_object_set_static_name() or
gimp_object_take_name() (gimp_object_set_name() and
gimp_object_set_name_safe() already had the check).
Since this is a slight behavior change it might have subtle side
effects; it definitely fixes GimpThumbBox thumbnail state to not
always re-create the thumbnail on click, which was happening since
porting to GFile (which switched from gimp_object_set_name() to
gimp_object_take_name()).
...when a color profile is active
This commit doesn't fix anything, but it prepares the code to do the
right thing:
It passes the actual raw image pixels through the entire color picking
mechanism to the widgets which display colors, particularly
GimpColorFrame.
This is needed for GimpColorFrame's "Pixel" mode (as opposed to its
RGB, HSV etc. modes) which is supposed to show the raw pixel values
from the image.
Before this commit, it was recreating the raw pixel values from the
GimpRGB value it knows, which will become impossible when we correctly
pick color managed GimpRGB values soon.
Add gimp_image_import_color_profile(), a GUI vtable entry
query_profile_policy() and a new dialog which returns the profile
policy and the profile to convert to. Get rid of the wrapper that
calls the lcms plug-in for that dialog, the plug-in is now completely
unused.
This commit doesn't add any new features, it's just the former lcms
plug-in dialog implemented in app/ (except the little fix that it is
now aware of linear vs. gamma images).
Get rid of the "configurable RGB working space profile".
Instead, turn GimpColorConfig's "rgb-profile" property into a
"Preferred RGB profile" thing that is only a hint and never used
without explicit user interaction. Present it next to the built-in
profile in the profile combo boxes and call it "Preferred" in the
prefs dialog and its tooltip.
Most importantly, don't use it as the image's profile when the image
is not tagged with a profile. Untagged images are now always in the
sRGB or linear RGB built-in color spaces.
This commit reduces the "Apply color profile" dialog on file import to
a simple "Convert to built-in RGB", but that dialog is about to be
moved to the core and improved anyway.
not only as parasite. This way we avoid having to create the profile
in each call to gimp_image_get_color_profile(). Also keep the built-in
profiles around in gimp_image_get_builtin_color_profile(). Add/remove
refs and unrefs as needed in all users of these functions.
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.
which converts a buffer with a profile into another one with another
profile. The function tries to avoid the lcms transform by checking if
a simple gegl_buffer_copy() has the same result.
gimp_layer_new_convert_profile(): if there is a profile, always use
lcms to copy between the buffers, to avoid the additional gamma
conversion gegl_buffer_copy/get() would do in some cases. This should
fix copying between linear and gamma images.
In gimplayer-new.c, convert new layers to the image's profile if color
management is not disabled in prefs. This should convert pixels from
whatever source if they have a profile attached. If they don't have a
profile, no conversion is done. I'm not entirely sure if this
automatic conversion is always the right thing to do, please test.
Uncomment and implement the menu items and actions to invoke the
dialog. This new code also does the (alomst) right thing to linear
images, unlike the lcms plug-in.
Ref/unref the dialog around saving the image insatead of connecting to
"destroy" and NULLifying the local dialog variable on destruction,
which has caused weird crashes on fedora.
- gimp-image-set-filename PDB wrapper: implement the same there in
a few lines
- xcf-load.c: use gimp_image_set_file() instead, and get rid of the
last use of filename in xcf/ in favor of GFile
The possible failure of `g_file_replace()` was overlooked, as well as
the error which may have been created and could be useful information
for the developers.
The "filename" parameter must be in UTF-8 and in URI format (for
instance file://path for local files, and not just a path).
Cf. `g_file_new_for_uri()` documentation:
@uri: a UTF-8 string containing a URI
it used to be a typedef to gpointer and actually was a cmsHPROFILE.
Change its API to be more "standard", remove the public close()
function. The object caches both the cmsHPROFILE and the data/length
ICC blob, so conversions between the two become obsolete (simply call
get_lcms_profile() or get_icc_profile()).
Adapt everything to the new API, but port it in a naive way for now,
the code doesn't take advantage of the new possibilities yet (like
refcounting).
The object offset is calculated correctly for channels in the
GIMP_IS_ITEM() case using gimp_item_bounds().
Also did some general formatting cleanup in the entire file.
Which returns a boolean indicating if there is content at all, and the
bounds as double x, y, width, height because for most use cases that's
better than x1, y1, x2, y2. Wrap the method with two functions
gimp_item_bounds() which returns integer bounds and
gimp_item_bounds_f() which returns the original double bounds.
...but they aren't clipped
gimp_display_shell_profile_can_convert_to_u8(): allow the shortcut of
converting directly to 8-bit for display only for GIMP_COMPONENT_TYPE_U8.
This might be an lcms bug, the code can be enabled again for U16 and
U32 if it's indeed an lcms bug and it gets fixed.
...certain sets of linked layers
Fix the move tool (GimpEditSelectionTool) using the same principle
as the other "linked item" features, just a bit more complicated...
Never translate the active item and its linked items separately,
always translate the entire list at once.
The linked logic was distributed across the entire file. Changed the
code to prepare lists of items that are translated live (layers and
vectors), and items that are translated at the end (channels, masks
and the selection). In the motion and button release functions, simply
use the prepared lists without any further duplicated checking.
Also clean up the stuff a bit, there is more cleanup needed but first
the fix...
...certain sets of linked layers
Fix for translating layers from the PDB, and with the cursor keys
for gimpeditselectiontool. Moving layers with the mouse is still broken.
The approach is exactly the same as in 25a696c7.
...certain sets of linked layers
Fix this bug for flip, rotate and general transforms (not for move yet):
gimp_item_linked_flip,rotate,transform(): always transform the passed
item too (do not filter it out of the list of items), so these functions
do the entire job of transforming a linked group now. Transforming the
active item separately didn't work (and is not implementable) if both
a layer and its parent layer group were linked.
flip tool, transform tool, layer->transform callbacks: don't call
gimp_item_foo() *and* (if the item is linked) gimp_item_linked_foo().
Instead call gimp_item_linked_foo() if the item is linked, and
gimp_item_foo() otherwise.
This commit also kills the mis-feature of transforming the selected
pixels of the active layer, and then the linked items completely. We
now either only transform the selected area *or* the linked group.
In gimp_group_layer_update_size(), when the new size happens to be the
same as the old size, we need to call gimp_pickable_flush() on the
group projection so it is ready to be used for rendering the image,
just like in gimp_group_layer_stack_update().
and pass them where we know the buffer could be from another image.
Pass "NULL, 0" if we know it's the same image.
Add gimp_layer_new_convert_profile() which takes the newly created
layer and the ICC data/length; call it from both
gimp_layer_new_from_gegl_buffer() and gimp_layer_new_from_pixbuf().
gimp_layer_new_convert_profile() is empty, this is just
infrastructure.
Set the profile when the buffer is copied from a layer, and when it's
created from a GdkPixbuf from the clipboard. The profile is not yet
used for anything.
Add Image -> Color Management -> Discard Color Profile which simply
removes the profile without any conversion.
Also added actions and callbacks for "Assign" and "Convert" but these
are only stubs to be filled as replacement for the remaining code in
the lcms plug-in.
and move the color profile menu entries there. Add a mapping so 3rd
party plug-ins get moved to the new location automatically.
Also, add a separator after "Duplicate" and move the "Transform"
submenu to the top of the group that has "Scale", "Resize" etc.
...when opened by the "Edit these settings as Curves" button on the
Levels dialog
The code to configure the entire GUI correctly was not even called
when initially creating the curves dialog (the color bars probably
looked right just because of default values of their own).
Factor out gimp_curves_tool_update_channel() which properly updates
the GUI. Call it after the dialog has been created, and when the
active channel changes.
Implement GimpConfigInterface::duplicate() and after duplicating the
paint options, copy the brush-related properties again, because they
might have been changed by setting the brush on the copy (if they are
set to be linked to the brush's native values).
For instance, modifying a layer and going directly to draw in the canvas
should not cancel the layer name.
You can still cancel a layer renaming in progress with ESC.
but they aren't clipped
Add gimp_display_shell_profile_can_convert_to_u8() which returns
whether the lcms transform can safely write directly into an u8 buffer
without destroying out-of-gammut pixel values, which we assume is the
case for all integer formats. If the function returns FALSE, always
convert via the R'G'B'A float filter_buffer.
Also connect to the image's "precision-changed" signal and update the
profile transform when it's emitted.
The lcms plug-in is on its way out: add compat procedures implementing
plug-in-icc-profile-info and plug-in-icc-profile-file-info and remove
that code from lcms.c.
GIMP_IS_TAGGED error and possible Gimp crash (core segfault)
Fix again by restoring code I accidentially deleted in
ae708d6419. I don't really understand
what it is doing but better not remove it without understanding.
Which will have proper API to deal with an image's color profile (no
parasites, no ICC blobs). So far contains gimp_image_get_color_profile()
and gimp_image_set_color_profile().
gimp_color_config_get_foo_profile() -> get_foo_color_profile()
because the old names clash with possible future accessors for the raw
filename properties.
also remove the fallback-to-colorconfig code from
gimp_image_get_color_profile() and move it to
gimp_image_color_managed_get_icc_profile(), so
gimp_image_get_color_profile() returns NULL if the image has no own
profile.
- disable auto-adding of the lcms display filter module
- change profile convert dest formats to be always R'G'B'A, a display
profile transform outputs something that can be displayed directly,
so no additional gamma transform must happen when the pixels are
copied to a cairo-ARGB32 buffer
- add a medium forest of if() branches to gimpdisplayshell-filter.c
which cover all combinations of profile and display filter
transforms
- all of this is still very broken when changing an image to linear,
because the configured RGB profile from prefs will do horrible
nonsense (things work fine though with a per-image profile that is
for linear data)