Add a "paint_composite_mode" field to GimpLayerModeInfo and set the
mode of the eraser to SRC_ATOP. Defaulting to SRC_OVER for all
painting didn't quite do it for all modes.
set all legacy modes to completely immutable and the LAB modes'
blend mode to immutable. Change GimpLayer setters and the UI
accordingly. Remove the LAB color spaces from the GUI, they can
only be used with the LAB blend modes anyway and not changed.
Nobody has them anymore, and they are deprecated in GTK+ 3.x. This
also fixes all conflicting mnemonics except those I missed, but we can
fix them now.
Fix cage transform to refuse to work on locked, invisible and group
layers. Add GimpTool::initialize() implementation so the generic
"drawable has changed" mechanism triggers the right response.
They can be affected by the same problem described in
commit 4c3a772cd8, although in the
case of SRC_ATOP, the affected pixels are always fully transparent.
When the source alpha is zero, we don't calculate the blended color,
so `comp[b]` can be infinite or NaN, in which case the expression
`in[ALPHA] * (comp[b] - layer[b])` is NaN, rather than the expected
value of zero.
and to operations/layer-modes/, respectively.
Add gimp_layer_modes_init() which asserts on the correct order of the
GimpLayerModeInfo array, and switch to accessing the array directly in
gimp_layer_mode_info().
Similar to the Photoshop mode of the same name. Assigns
either 0 or 1 to each of the channels, depending on whether the
sum of source and destination channel values is less than, or
greater than (or equals to), one, respectively.
This is equivalent to inverting the source, and using it to perform
per-pixel, per-channel threshold against the destination, which is
useful for various effects.
Stuff like passing "input" directly if "aux"'s opacity is 0, etc.
Used to be partly handled by normal mode, even though it applies
to other modes too.
Adjust the logic for the new compositing modes.
Add a GimpLayerModeAffectMask enum, and a corresponding
get_affect_mask() function to GimpOperationLayerMode, which
specifies which of the op's inputs, if any, are affected by the
mode, apart from the overlapping regions. Most modes affect only
the overlapping regions, but dissolve and replace also affect the
rest of the input. This information is used for determining if
the optimizations are applicable.
Some of the generic files still contain SSE2 code, in particular
gimpoperationlayermode.c. The reason why it often works without is that
native gcc will usually pre-define SSE macros by default.
To check this: gcc -dM -E - < /dev/null | grep SSE
Yet I had a case on a small netbook where the SSE macros were not
pre-defined even though supported. Consequently the build failed.
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.
The colon-separated list used in the plugin originally comes from
gimp_help_get_locales() anyway. My previous code was using different
lists of locales in different places, which was inconsistent.
I know this looks absolutely horrible, please spare me comments about
that. This commit has the purpose to let everybody experiment with the
new modes, and suggest improvements of the GimpLayerModeBox widget; we
need *some* way of controlling the new layer mode madness.
These variations on darken only and lighten only have the advantage over the
componentvise versions that they always use the full triplet of either original
or new layer - meaning no new colors/hues will be introduced. This is similar
to how these modes operated/operates in picture publisher and photo-paint.
- set the filter_tool->drawable before showing the tool gui.
- set the sensitivity functions for channel combobox of threshold,
levels and curves tools dialogs only once during dialog creations.
- use the filter_tool->drawable inside the sensitivity functions
C++ won't allow us to use GimpLayerMode in the API where we used to
have GimpLayerModeEffects.
Move GimpLayerModeEffects to libgimpbase/gimpcompatenums.h so it's
not in the API any longer, and instead typedef and define stuff in
libgimp/gimptypes.h, and adapt the compat enum registering code
accordingly.
The porting from 8bit per component scaled some 8bit fractions up to huge
floating point numbers, this works for most values but causes trouble for near
transparent pixel values. This commit copies the inner blend loop from the new
divide layer mode, but keeps the old compositing logic.
... is fully transparent, instead of just src.
The blend func results only affect the intersection of dest and src.
Run time is currently dominated by the compositing step for most modes,
so the difference in performance is pretty negligible, but it does make
a difference for the more expensive modes, like the HSV ones.
The print size displayed in image property and title format should use
gimp_unit_get_scaled_digits() instead of gimp_unit_get_digits() and
adding 1, which is quite random or magic number-y.
For operations needing to override default behavior sub-classes should still be
used.
This commit also enables pinligh, vividlight and linearlight blend mode modes
We can't just switch to a GimpOperationTool by using the normal
gimp_context_set_tool() or gimp_context_tool_changed() because it
needs additional initialization like setting an operation at all.
In gimp_gegl_procedure_execute_async(), g_object_set_data() the used
procedure on the newly created tool.
In gimp_display_shell_initialize_tool(), when we re-create the active
tool because of a drawable change, check for the procedure and invoke
it again, instead of simply creating an empty operation tool by
calling gimp_context_tool_changed().
Optionally convert all imported (not XCFs) images to 32 bit linear
floating point, and optionally add a little noise in order to
distribute the colors minimally. The new options are on a new "Image
Import & Export" prefs page that needs a new icon. Original dithering
patch by pippin.
Since CIE Lab is one of the supported color spaces for doing the blending -
this enum is not only about transfer functions/curves or gamma. This finishes
already started cleanups.
... in status bar.
Follow-up of commits f836892 and d1c3c3d. With high resolutions, the
distance displayed in the status bar when shift-clicking in a paint tool
may lack digit precision and show the same value (in non-pixel unit) for
several consecutive pixels. Compute a more accurate precision than what
gimp_unit_get_digits() can provide in such cases.
When working with high resolution, you may have cases where measured
length won't be displayed with enough digits; i.e. several pixels length
would show up as 0. For instance at 4000 PPI, up to 7 pixels show up as
0 mm, then at 0.1 mm from the 8th pixel (actually reaching over 0.05 mm,
approximating as 0.1), then 0.2 at 24 pixels (actually: 0.152), and so
on. At such a resolution, 3 digits are needed for 'mm' instead of the
1 digit returned by gimp_unit_get_digits() so that we display reliable
lengths.
Therefore we need to compute ideal digit precision. Configured digits
for a given unit will now be used as a minimum value, but actually used
digits may be higher.
Compute the ideal decimal precision for cursor position and length
status so that you get the best precision on physical units depending
on the current resolution, yet avoiding over-precision (which can be
misleading). The unit's "digits" value is now used as a minimum
precision only.
It is used both for blending and compositing, the repeated use of the word
BLEND in code made the logic involving both blending and compositing hard to
read.
Note that in some cases the alloca may be unnecessary, but this keeps
the code clean, and we have to be able to *potentially* do the alloca
anyway, so what the hell.
Implement a common utility function gimp_blend_composite that uses utility
functions for implementing layer modes, with separate (possibly SIMD) optimized
loops for blending and compositing, with configured linear TRC, perceptual
gamma TRC or even using CIE Lab as the space.
from gimp_applicator_new() and gimp_gegl_mode_node_set_mode().
Compositing doesn't depend on the layer format any longer, only on the
layer mode. Painting with "use applicator" unchecked is still broken
in some cases and needs more fixing.
like all other function typedefs and add GimpBlendFunc typedef which
will be needed soon. Also rename get_layer_mode_function() to
gimp_get_layer_mode_function().
...layer group cause a bug in the existing layer size
Change gimp_group_layer_get_size() to return FALSE if there are no
children (there is no content).
In gimp_group_layer_update_size(), skip children where get_size()
returns FALSE. Fixes bogus size calculation.
Temporarily slower - but permits paint modes like overlay/softlight to work at
all for linear TRC pixel encodings. Should be reverted when the non-graph
approach works properly again.
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.
Make overlay, Lch color, Lch hue, Lch saturation and Lch lightness mode handle
alpha more like how normal does it. This is a change that we ideally might want
applied to other layer modes as well to get rid of MIN() calls.
when parsing of an object property fails, we need to set *expected to
G_TOKEN_NONE to tell the config parser that something has gone wrong,
or it will continue parsing and run into trouble with the inconsistent
state (it will try to set an error over the already set error, causing
a warning).
The "accumulated" (color value) adjective does not look like the best
word in both descriptions. Respectively, the first is an averaged
value whereas the second would be a "merged" or "composited" value.
If native speakers have comments or better propositions, they are
welcome to speak up.
...regardless of image color precision
Split enum value GIMP_COLOR_FRAME_MODE_RGB into RGB_PERCENT and RGB_U8,
which display the current % values, and values in a range of 0..255.
Move the entire drawing control logic to gimp_color_tool_oper_update()
which gets invoked on hovering, and don't mess with it in
button_press() and button_release(). Tested to work with the color
picker, paint and filter tools.
Disable the new "automatic window tabbing" feature introduced on macOS
Sierra. It breaks GTK+ applications and we would need proper support for
this in GTK+ if we want to use it.
Change GimpHistogram to take a "gboolean linear" parameter and always
honor that parameter, so both kinds of histograms can now be created
for all drawables.
Add a horrible "Linear" toggle to the histogram dockable which always
defaults to the active layer's actual pixel format, but can be
switched at any time. This UI is ugly and needs to change.
On the PDB, default to gamma-corrected if the plug-in is unaware of
higher precision, and to the drawable's native pixel format otherwise.
Other places using histograms (e.g. levels, curves) are unchanged.
Set gimp_tool_control_set_preserve() to TRUE and set an appropriate
dirty_mask, just like all tools which have a permanent on-canvas state
outside of a simple press-drag-release.
The white, gray and dark sliders of GimpHandleBar have a black contour.
This makes the white and gray slider visible even with similar colored
background. On the other hand, the black slider is barely visible on a
dark background (and could even be made totally invisible using the same
color). So let's use a light-gray contour on the dark slider, making now
all sliders working with any background color.
gimp_dialog_config_fill,stroke_options_notify(): ignore notifications
on the fill and stroke option's parent class properties, they are not
serialized and completely irrelevent here.
This reverts commit eab4929a78.
Oups it would seem gtk_accel_map_change_entry() could return FALSE even
when the expected shortcut is correctly set (my guess is that it was
already the same shortcut, so indeed no "change" happened, though it is
not a failure either; yet I haven't checked if that is the actual
reason).
Let's just revert this. It's not always a good thing to be too thorough!
Sorry for this!
These are used for display switching, and even though you could
remap these shortcuts, it would work only until you close an image,
open a new one, or reorder tabs in SWM, in which case your shortcut
would end up forcefully overrided, which is a bad user experience.
If we want to give more flexibility and allow one to map these
shortcuts, we must also make sure the display showing actions won't
override customized shortcuts. In the meantime, it is better to
simply forbid these in our preferences.
... for "windows-display-*" actions.
I should not happen, but let's be thorough and properly handle failure
with a message since this is a runtime issue.
gtk_action_group_remove_action() removes the action from the group while
not actually cleaning any accelerator. This is a problem for transient
actions which have only a meaning within the current session, such as
the display switching actions named with the display ID (unique within
the session only).
Current commit, combined with the previous one (commit c0ee959), fix
"windows-display-*" actions being saved inside menurc.
Some actions are not meant to be saved, in particular the
"windows-display-*" which have only a meaning during a same session
since display IDs are session-dependent. So let display deletion
happen first so that proper cleaning of action is done when writing
menurc.
Revert "app: action search should search accross all available actions."
This reverts commit 53b3673bd8.
Had to revert these two commits, quoting comment 6 of the bug:
Thinking again, that entire change is unfortunately wrong, the only
right UI manager is in fact
gimp_ui_managers_from_name ("<Image>")->data
because it's the global popup <Image> UI manager which is independent
of a display and it always in the right state for the currently
active image, all other UI managers are wrong.
Current defaults are from another time. Acceptable defaults could be
common screen resolutions. 1366x768 is apparently the most common
(according to various stats on the web), but since we target advanced
graphics artists, let's go for 1920x1080, which is the second most
common resolution, also known as Full HD.
For unstable builds, let's have at least one odd number, uncommon ratio
and higher values, encouraging tests with less common numbers and bigger
images. I chose 2001x1984. Feel free to update to any other funky values
following these "unstable" rules.
... with something more suitable.
72 PPI is from a time where people thought this was a common screen
resolution. This is not the case nowadays, and anyway images targetted
for screen display should not bother with PPI resolution at all, only
with actual pixel dimensions.
PPI resolution is more useful for printing. And for this case, 300 is
quite an accepted OK value for most cases. So this is likely a better
default for GIMP.
Add GimpMenuFactory can always be found in a GimpDialogManager, use
gimp_dialog_factory_get_menu_factory() where we have a dialog factory
instead of accessing "global_menu_factory" or redundantly passing a
menu factory around where we already pass around a dialog factory.
<Dockable> has this whole list of actions named similarly to dialogs-*
actions, and we don't want these to take precedence, especially since
they would always create a new dock instead of just showing the existing
one if already present.
Also fix the redundancy check on already added actions.
There is no reasons not to translate the "occurs" text which will be
in the color names in palettes extracted from images. It indicates on
how many pixels a given extracted color was occuring. We should also
translate the full string (not just "occurs") since some language will
have to reorder words, and may even use different bracket characters.
So I also add a translator comment to make sure the translators get
what the %s and %d stand for in this string.
Duplicate accelerators are not supposed to happen. It is not possible
to set them through the GUI in particular. Nevertheless
gtk_accel_map_load() would apparently let duplicates pass, which could
happen after editing the menurc directly, or using the development
version (no action name migration happens there), or simply after a
potential bug. This is then very annoying because you may see several
actions displaying the same shortcut but only one actually work. And
trying to re-set through GUI the shortcut to the one action you wish to
run does not fix the duplicate issue (you have to laboriously find which
other action use the same accelerator and delete it first).
Better be safe than sorry and make a quick check at startup, then delete
the accelerator on one of the duplicates (you can't guess which one was
actually wanted, but at least you will facilitate manual reset through
the GUI).
Redundant accelerators were:
- <Primary><Shift>y on dialogs-mypaint-brushes and edit-strong-redo.
Since the <Primary>z vs <Primary>y has quite a strong history for
undo/redo actions, and dialogs-mypaint-brushes is quite new, let's
unmap the latest.
- <shift>l on tools-seamless-clone and tools-unified-transform.
Since the Seamless clone tool is still in the playground and we
don't even know if it will make it out quite soon, let's give
priority to the Unified Transform tool.
Limit selection shrinking to MIN (sel_width, sel_height) / 2, larger
values make no sense.
Limit selection bordering to the same value and growing to
MAX (image_width, image_height).
Introduce virtual function GimpViewable::is_name_editable() and class
member "gboolean name_editable" for the default value. Default to
FALSE and only return TRUE if the name can actually be edited by the
user.
When attemting an edit, check the new API and beep instead of starting
the edit.
Don't rely on the exact modifier being pressed or released. Instead,
check if only the right modifier is pressed after *each* modifier
change, and switch to color picking if it is; disable color picking
otherwise. This greatly reduces the risk of missing the user's wish to
pick colors because of other modifiers being pressed and released in
whatever order.
Probably fixes bug #734743.
We handle multi-selection by letting GtkTreeView handle button press
when the widget is in GTK_SELECTION_MULTIPLE mode. Change that code to
only do that when one of the participating modifiers (shift and
control on Linux and Windows, shift and cmd on macOS) is pressed.
This makes sure that the same thing is not randomly handled by two
different pieces of code, and probably fixes bug #738440, tho I can't
be sure.
When calculating an overlap between two ranges, interpolate the hue
adjustment from config->hue[primary_range] and
config->hue[secondary_range] BEFORE mapping it to the input value.
This fixes odd edge cases where only one of the ranges crosses the
red/magenta wraparound, or if adjustments to different channels yield
more than 180 degree difference from each other.
In the "New Image" and "Convert Precision" dialogs. The "Gamma/Linear"
switches get adjusted automatically to the new defaults, but can be
changed manually.
Don't offer dithering options when converting to 16 bit, it doesn't
make much sense to dither for anything but 8 bit. Thanks to Elle for
testing that this assumption is indeed true.
Use a properly commented #define instead of just a hardcoded "8 bits"
to make clear that this is a pure GUI "restriction".
Disable the convert precision dialog's dithering controls when
converting to higher bit depths o to anything > 16 bit.
Make sure the disabled dithering widgets always says "None", which
implies duplicating the bit depth checking logic in both the dialog
and its callback, in order to protect the values in GimpDialogConfig
from being overwritten by NONE.
The new properties are "virtual", they share their storage with the
"precision" property and are not serialized, they are meant for GUI
property widgets.
...instead of transforming it
Add gimp_matrix3_will_explode() which determines if a transform
matrix will blow up something in a rectangle to infinity, and use
the function so set both the GIMP and GEGL code paths to clip the
transform to the input size.
This got lost when dropping the file-uri plug-in and switching to
interal download using GIO. The file-uri plug-in would just download
whatever remote thing and open it locally, using local magic matching.
We now do the same internally and try the magic matching again on the
downloaded file.
Don't migrate any paths from an older gimprc. This unfortunately kills
all manually added paths, but makes sure all paths default to the
files of the new GIMP version, could be improved by parsing the path
and replacing only the right elements.
Add color management to GimpDrawableFilter and GimpFilterTool, GEGL
ops applied to drawables can be applied in color managed space
now. Sadly, this is very slow, so disabled by default.
I'm sure the profile guessing based on the operation's format doesn't
always work, but this general bug counts as fixed now.
Fix cursor rotation jump when tablet pen is tilted horizontally.
This changes to the correct values for the special case of tilt_x == 0.0.
Reviewer (Jehan)'s note: computing the convergence of the tilt function
in the `else` block, when tilt_x approaches 0, tilt value indeed
converges to 0.25 with tilt_y > 0 and 0.75 (or -0.25 which is the same)
with tilt_y < 0.
Initialization was failing when a paint buffer could not be returned for
a stroke (which was bound to happen in tiling). Instead it must just
ignore the coordinates which won't result in painting, and continue to
the next ones.
gimp_drawable_equalize(): is mask_only is FALSE, suspend the selection
around gimp_drawable_apply_operation() so the operation affects the
entire drawable.
The code was still checking for "plug-in-recent-*". Also, rename the
actions to "filters-recent-*" instead of "filter-recent-*" for
consistency with the other filters actions.
so the threshold can now be based on the GimpHistogramChannel enum.
Add a channel menu to the threshold dialog and a channel argument to
the PDB procedure (which is new in 2.10).
If I hadn't forgotten what the "RGB" channel is supposed to do I would
have implemented the RGB mode in GimpOperationThreshold correctly.
Right now I'm just guessing. Anyone?
They used to be 0..255, inherited from the old gimp_histogram() and
gimp_threshold() procedures. This commit deprecates these old
procedures and changes the ranges in the new gimp_drawable_histogram()
and gimp_drawable_threshold() to double with a 0.0..1.0 range.
Add property "color-tag" of type enum GimpColorTag to GimpItem so all
layers, channels and paths can be tagged with a color.
For interoperability, use the color list from Krita which is a
superset of Photoshop's colors.
Features a "Color Tag" submenu in the layers, channels and paths
menus, a row of color radio buttons in the properties dialogs,
undo and PDB API.
As a side effect, some common code is now factores out into
items-actions.[ch] and items-commands.[ch] which adds visible, linked
and lock actions for layers and channels.
Introduce item-options-dialog.[ch] which abstracts this away and use
it from the layer, channel, vectors options dialogs. This is all
pretty ugly but better than duplicating that code three times. The
vector-options-dialog is now completely pointless but I kept it anyway
for now, let's see what unique path options we come up with.
Convert GimpRGB to CMYK using a color transform to the configured CMYK
profile instead of the naive gimp_rgb_to_cmyk().
Add gimp_color_frame_set_color_config() and call it on all color
frames in the GUI (color picker tool, cursor info, sample point view).
Keep a GimpColorTransform around that does the conversion.
Also color manages the frame's color area now (visible in the sample
point view), which was forgotten earlier. Addresses bug #467930.
Fix the check that keeps events on overlay widgets from entering the
tool event mechanism, they have no business there.
gimp_overlay_child_realize(): set the embedding widget's event mask on
all overlay children, so their windows will be used as event window,
so their events become distinguishable from events on the parent (the
canvas).
gimp_display_shell_canvas_tool_events(): fix the check for events on
overlays, and skip them for real this time.
Call gimp_context_tool_preset_changed() on the global user context,
not on the tool preset list's or tool preset editor's local
context. Fixes restoring of presets in MWM. Tracked down by Jose
Americo Gobbo.
Have "Save" and "Restore" buttons in both the tool preset list/grid
and the tool preset editor. The save button stores the active tool's
options in the preset, if possible.
This fixes restoring of brush properties (size, spacing angle etc.)
from presets, which was utterly broken before. The fix consists of
two parts:
- In tool_manager_preset_changed(), always copy the brush properties
again after setting the preview on the tool options, in order to
override brush properites that get copied from a linked brush when
that brush gets set on the tool options.
But no amount of copying stuff again and again would help without:
- In gimp_context_set_by_type(), don't use g_object_set() to set the
object (brush, pattern etc.). Instead, build a GValue and call
gimp_context_set_property(). This may seem odd, but avoids a
g_object_freeze_notify()/thaw_notify() around the g_object_set(),
which was causing "notify" to be emitted at the very end, after
everything this context change has triggered. GimpContext is an
essential core object and there is an expectation of a reasonable
order of signal emissions and callbacks being called. The "notify"
at the end was keeping any callbacks of the context's "foo-changed"
signals to override anything an earlier callback had done, if a
"notify" callback was overriding that overriding again.
This was probably the reason for a lot of odd behavior observed over
the years. In fact, I have been searching for this for at least 5
years.
...are not submitted to respective Tool Options sliders
Treat brush angle and aspect ratio like all other paint options values
that can be linked to brush defaults and take their default values
from the brush. They were special casing their defaults to constants,
and GimpBrushGenerated was adding the passed dynamic radius and aspect
values to its own. This was totally incomprehensible.
Now GimpBrushGenerated's transform_size() and transform_mask()
implementations just translate between these APIs value ranges and the
brush's own value range and only use the passed values (not the
brush's native values), which makes the editor <-> tool options
interaction and the painted brush shape predictable.
Also connect the active brush's property notifications to the paint
options properties, so the paint options follow a brush edit live if
the respective "linked" toggles are checked.
And some cleanup.
Add a GimpFillType argument to GimpItem::resize() and fill type
widgets to the canvas and layer resize dialogs. Fill the new parts of
the drawable according to fill type in gimp_drawable_resize(). Make
sure places that need the old behavior get GIMP_FILL_TRANSPARENT
passed by hardcoding it in the GimpItem::resize() implemetations of
channel, mask, selection etc.
We didn't convert patterns to the target drawable's profile when using
gimp_drawable_fill().
Introduce gimp_drawable_fill_buffer() as single filling utility
function that does things right and use it from gimp_drawable_fill()
and gimp_fill_options_create_buffer().
Use a GimpSpinScale in channel-options-dialog.c and clean up the
dialog layout. Affects the "Quick Mask Attributes", "New Channel" and
"Channel Attributes" dialogs.
Add new setting GimpGuiConfig:devices-share-tool. When TRUE, we never
copy any properties between the user context and the GimpDeviceInfo's
context, so no tool or anything changes.
We do however still keep track of the active device so the setting can
be enabled/disabled at any time. Also hide GimpDeviceStatus' tool,
brush etc. indicators in "shared" mode.
Otherwise the quit dialog is still in front yet it has no focus and
one doesn't see this immediately.
Hitting ctrl-d to exit and ignore any subsequent files for instance
duplicates the current active image instead.
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).
Rename "dialog" variables to "private" like in the other recently
cleaned up dialogs. Use less complicated code when connecting to the
container of dirty images.
Otherwise keyboard interaction (like hitting Escape or ctrl-d) ends up
broken and you may not realize immediately the dialog lost focus since
it is still the top window.
"There is one image" should not necessarily be translated to '1' in
other languages. It depends if their singular applies only to 1, like
in English. For instance in French, it can also apply to 0, so I fixed
the French translation.
...when moving guides
Show relative coordinates when moving guides and sample points, the
cursor display in the statusbar already shows absolute coordinates.
Add GimpCellRendererButton and use it to add a "Save" icon to each row
of dirty images. Click invokes the "edit-save" action, shift-click
invokes "edit-save-as". Also add a tooltip for the icon button.
Involves minor changes to GimpContainerTreeView to allow
GimpCellRendererButton to be added, and to allow external
"query-tooltip" handlers to run.
and use gimp_file_new_for_config_path() and _get_config_path() when
dealing with them. We used a weird mix of config paths and plain
(filesystem encoded) paths, waiting to to break on umlauts or
whatever. The code in gimpcolorconfig.c was particularly bad.
Add a SELECT_SOFTPROOF_PROFILE mode to the color profile dialog and
use it to select a profile from a newly added "Soft-Proofing Profile..."
menu item in view -> color management.
In a blocking operation we don't give the main loop time to lay out
the statusbar correctly after showing the progress bar. Force a size
on the progress bar using gtk_widget_size_allocate(). This sucks.
and call gimp_image_convert_indexed() in image-commands.c where it
belongs. Also remember the default values there, they will to to
GimpDialogConfig next.
and move the actual stroking code to select-commands.c,
vectors-commands.c and gimpvectorstool.c. Remember the active drawable
so the stroke always happens on the drawable the dialog was invoked
with.
and move the actual filling code to select-commands.c and
vectors-commands.c. Remember the active drawable so the fill always
happens on the drawable the dialog was invoked with.
Don't change the paste_type to NEW_LAYER just because there is a
complex thing in the clipboard. Instead, honor the request to paste
FLOATING or FLOATING_INTO and reduce the pasted thing to a simple flat
layer. Also remove the message and paste_type change from edit_paste()
in edit-commands.c, it had the same purpose, just with a user
notification.
In order to paste the full layer one needs to explicitly invoke
"Paste as new layer" now.
It still changes the paste_type to NEW_LAYER if it's impossible to
attach a floating selection to the target, the menu item was simply
insensitive before.
Instead, provide a custom GimpAddMaskCallback, connect to "response"
internally and call the callback. Takes clutter out of layers-commands.c.
Also attach the dialog to the layer so we don't show multiple add
mask dialogs. Should do the same to all dialogs with public structs,
the custom callback approach keep things more encapsulated.
the edge of a dock in multi-window-mode
when the pointer is grabbed do not process a
motion-notify-event having the wrong 'device' member.
This avoids a harmful device change.
They have a size of 1x1, treat them a image-sized when pasting layers
on top of them.
(my commit below was also about gimp_edit_get_paste_offset(), not
about gimp_edit_paste() as the log claims)
Use the newly added clipboard for entire images to copy/paste layers
(we only create single-layer clipboard images, and use only the first
layer of any recieved image, the layers can be arbitrarily complex
though):
- change gimp_edit_copy,cut,paste() to return/take a GimpObject
that can be a GimpImage or GimpBuffer
- cut/copy the whole layer if there is no selection
- always paste layers as new layers, not floating selections
- always paste news layers on top of the active layer, where
we would attach a floating selection
- add enum GimpPasteType { FLOATING, FLOATING_INTO, NEW_LAYER }
- add GimpPasteType parameter to gimp_edit_paste() and handle all
three cases there because there is now a lot of common code
involved
- change all callers accordingly, use only legacy buffer pasting
from the PDB for now
which can be used to load/save XCF from/to arbitrars streams. Use the
new functions from the load/save procedure invokers.
This commit also fixes a leaked open file ans input stream for each
loaded XCF.
...when threshold > 0
Add an "Antialias" toggle to the bucket fill options and set it on the
GimpFillOptions. In gimp_drawable_bucket_fill(), pass it to
gimp_pickable_contiguous_region_by_seed() instead of always defaulting
to TRUE.
The position of the toggle and its huge tooltip may need some
adjustment.
Add GimpFillOptions and GimpStrokeOptions to GimpDialogConfig and use
them in the Fill/Stroke Selection/Path dialogs and for the "with last
values" commands. Add GUI for them to Preferences -> Dialog Defaults.
This requires most of the stuff in my last few commits, and some
more changes:
GimpFillOptions is a GimpContext which has all sorts of connections to
everything, including a Gimp pointer. Hack around in GimpDialogConfig
to add a Gimp property, and add "gimp" parameters to quite some GimpRC
functions. Treat the Gimp* as a GObject* in all public API because
core/ stuff is not known in config/.
Move fonts, data factories, document list, paint methods and user
context creation to gimp_init() or gimp_constructed() so that most
members are created when gimp_new() is done. This does not load any
data earlier, it just makes sure that all containers exist when
gimp_load_config() is called. It's also cleaner and less fragile,
and initialize units in gimp_init(). This was completely
over-engineered but in the end boils down to a bad hack that needs a
static "the_unit_gimp" pointer anyway, so let's at least have the hacks
in one file.
Namely dialogs_attach_dialog(), _detach_dialog(), _get_dialog()
So we don't create the same dialogs multiple times, but raise the
already existing ones. Port some places that did this manually
to the new functions, and use it for many other dialogs.
...after entering single window mode
In GimpToolPalette, implement GtkWidget::hierarchy_changed() and
re-set the tooltips using the new toplevel's actions.
In gimp_widget_set_accel_help(), make sure we don't connect to the
same action twice, and make sure we disconnect everything if either
the widget or the accel_group go away.
It's deprecated in GTK+ 3.x, so we get rid of some deprecation
warnings. Also, it has always only been a utility function that hides
what is really going on in the widget hierarchy.
Try harder to show help when webkit is missing or the help browser
won't start:
- offer to switch to the web browser when the help browser is
present, but won't start for some reason
- in prefs, don't bother showing the help browser GUI when webkit
is missing, otherwise show a warning label if the help browser
is not installed even though webkit is there. Switch to the web
browser in both cases (modified patch from lisanet)
- add OS X replacement for gtk_show_uri() in plug-in-web-browser
(modified patch from lisanet)
(gimp-2.9:3): Gimp-Core-CRITICAL **: gimp_marshal_VOID__OBJECT_POINTER: assertion 'n_param_values == 3' failed
Conflict between signal marshal function
and signal emission.
AddressSanitizer output (paths manually shortened)
Direct leak of 96 byte(s) in 1 object(s) allocated from:
#0 0x7f543247d1d0 in realloc (/lib64/libasan.so.3+0xc71d0)
#1 0x7f542d3ad02f in g_realloc glib/glib/gmem.c:159
#2 0x57918d in gimp_color_history_set_property gimp/app/widgets/gimpcolorhistory.c:169
#3 0x7f542d681ec0 in object_set_property glib/gobject/gobject.c:1423
#4 0x7f542d681ec0 in g_object_new_internal glib/gobject/gobject.c:1817
#5 0x7f542d6839ed in g_object_new_valist glib/gobject/gobject.c:2042
#6 0x7f542d683c73 in g_object_new glib/gobject/gobject.c:1626
... standard icon names and GTK+ icon names as second choice.
We should only use GIMP specific icon names as last resort, when there
is no standard or GTK+ names dedicated to the function.
This is made possible thanks to commit 3cc77b0.
s/gimp-document-recent/document-open-recent/
s/gimp-indent/format-indent-more/
s/gimp-next/go-next/
s/gimp-previous/go-previous/
s/gimp-save/document-save/
s/gimp-save-as/document-save-as/
s/gimp-revert/document-revert/
s/gimp-open/document-open/
s/gimp-document-recent/document-open-recent/
s/gimp-quit/window-close/ ou s/gimp-quit/application-exit/
s/gimp-warning/dialog-warning/
s/gimp-edit-clear/edit-clear/
s/gimp-justify-.*/gtk-justify-.*/
s/gimp-font/gtk-select-font/
s/gimp-color-palette/gtk-select-color/
s/gimp-cancel/gtk-cancel/
Add gimp_prefs_box_set_page_scrollable() which does what it says, and
make the tallest pages of the prefs dialog scrollable. This method
allows the dialog's smaller pages to still enforce a minimum height
for the window.
Quite heavily modified by Mitch to address the more general issues
mentioned in comment 35 of the bug:
- Remember the added mask's type and the invert boolean in
GimpDialogConfig
- Add new prefs page "Dialog Defaults" which will contain
only stuff from GimpDialogConfig and can be reset separately
- Remove static mask variables from layers-commands.c and
use the new config values for both interactive mask adding
with the dialog, and for the shortcut based method
- Add a button to the layers dialog which supports add, add
with last values, delete, apply
- Add modifier-click shortcuts on the layer preview with the
same modifiers as on the button
... starting with toolbox buttons.
This is particularly a problem in single window mode (and sometimes in
multi-window mode) where canvas easily loses focus, hence key events.
Place the rulers' origin at the top-left corner of the canvas
(screen space) bounding box, and set their scale to the image-
space scale along the screen-space horizontal/vertical directions
(in other words, measuring a distance using the rulers should
give the same results as the measure tool; note that rotation
comes into play here only when the horizontal and vertical
image or screen resolutions are different, since otherwise the
scale is direction invariant.)
Make scrollbar step match ruler step under the new behavior.
...after entering single window mode
This commit fixes dangling pointers in GimpDockColumns, it doesn't fix
the bug but it's a prerequisite. Original patch by Massimo.
Separate clearing/creating the image's cached color transforms from
clearing/creating its color profile. Clear the transforms when the
color profile changes, and when image type or precision change. Create
the transforms only on demand, so clearing them multiple times doesn't
trigger any redundant (and expensive) transform creations.
... not screen space
Flip and rotate the canvas around the center of the viewport,
instead of the center of the image. Scroll the display as
necessary to keep the center of the viewport fixed during
these operations. This applies to both the corresponding
menu items, and rotation using Shift+Space.
Likewise, flip the canvas across the designated axis in
screen space, instead of image space. Rotate the display as
necessary, such that the reflection appears to happen in
screen space, regardless of the current rotation angle of the
canvas.
As proposed by Mitch. This completes first renaming attempt (commit
08ffc10) with even less ambiguous names.
"horizontal-axis-position" and "vertical-axis-position" are now
respectively "mirror-position-y" and "mirror-position-x".
"Horizontal position" and "Vertical position" could be mistaken as
meaning respectively the x and y coordinates, hence the vertical (resp.
horizontal) guide's positions.
The more accurate "horizontal-axis-position" and "vertical-axis-position"
namings are less misleading.
...selection on the canvas
if the editor dialog is active do not copy to the
clipboard the text selected, copy it instead when
selected with keys <Shift>-left/right.
Don't remove the GDK_KEY_space in GimpSearchPopup because that's
impossible and removes it from the entire GimpPopup class. Instead,
don't handle the "space -> confirm" binding manually if the focus
widget is a text widget.
Pass a GeglRectangle to all gimp_prop_gui_*() functions, and set
the soft limits to the rectangle's extents if the GParamSpec
metadata's "unit" is "pixel-coordinate" or "pixel-distance".
In GimpSymmetryEditor, pass the image extents, in GimpOperationTool
pass the drawable extents.
do not access progress object after destruction.
silence warnings like:
(gimp-2.8:1): GLib-GObject-WARNING **: gsignal.c:2635: instance '0x17083f0' has no handler with id '56146'
(gimp-2.8:1): Gimp-Plug-In-CRITICAL **: plug_in_icc_profile_apply_rgb: assertion 'progress == NULL || GIMP_IS_PROGRESS (progress)' failed
Mitch gets a better idea to deal with soft limits (i.e. min/max values
different from the property min/max) applied to a spin scale created by
gimp_prop_spin_scale_new().
So let's just remove the current implementation (using locale data on
the GimpConfig object). The symmetry spin scales are back with crazy
huge maximums, which makes quite a horrible GUI, but this is only
temporary until Mitch commits his new implementation.
... in gimp_drawable_bucket_fill()
gimp_drawable_apply_buffer() already takes the selection mask into
account. Intersecting the selection mask with the fill region
prior to that leads to wrong (too low) alpha values, in general,
when partial selection is involved.
This commit eliminates the intersection of the fill region and
selection mask data before the apply_buffer() call, although it
does calculate the intersection of their bounds, to avoid
processing regions that won't be visible anyway.
Add an icon button to the dynamics editor's "mapping matrix" page. It
looks just as ugly as the icon button of the tool preset editor, the
two should be visually improved together.
The code to reorder buttons was actually already there, yet the
alternative order was not taken into account unless the setting
"gtk-alternative-button-order" is TRUE.
Previously, activating quick mask while the selection was empty
would use the image's channel format for the mask, instead of its
mask format; these formats are different for sRGB images.
...XCF channel and layer properties
The properties PROP_ACTIVE_LAYER, PROP_FLOATING_SELECTION,
PROP_ACTIVE_CHANNEL saves the current object pointer the @info
structure. Others like PROP_SELECTION (for channel) and
PROP_GROUP_ITEM (for layer) will delete the current object and create
a new object, leaving the pointers in @info invalid (dangling).
Therefore, if a property from the first type will come before the
second, the result will be an UaF in the last lines of xcf_load_image
(when it actually using the pointers from @info).
I wasn't able to exploit this bug because that
g_object_instance->c_class gets cleared by the last g_object_unref and
GIMP_IS_{LAYER,CHANNEL} detects that and return FALSE.
Currently a GimpSpinScale created with gimp_prop_spin_scale_new() will
use the associated property's lower and upper values.
Unfortunately these generic values may not be always relevant and we
may want to construct a spin scale UI adapted to the current image.
For instance, several symmetry painting have a x/y property which has
to stay within the image's dimension, but changing the property's lower
and upper values would affect the symmetry on the class level (i.e. for
all similar symmetries on all images).
Let's allow setting data on object with key "property-name:min|max" to
provide locale min/max values specifically for this object.
This is used only on the symmetry dock for now, but could be used as
well on GEGL op UIs.
This operation produces NAN (0 / 0) and division
by zero when a layer component is zero.
Inline CLAMP to make sure it swallows also NAN.
A NAN is mapped to 1 for backward compatibility.
[the 2variate function comp (in[b], layer[b]) is
discontinuous at layer[b] = 0]
Whereas some IME would just cancel any preediting on IM context reset,
others would commit their preedit (for instance Ibus-Hangul).
Unfortunately it is not necessarily immediate, even after
gtk_im_context_reset() and gtk_im_context_focus_out(), so when switching
text layer, any preedit text is committed on the new layer.
Let's recreate the IM context on abort to make sure we don't share any
input between text layers.
The IM should be the one taking care of it by sending the proper
signals, and I would assume this should be done when we run:
gtk_im_context_focus_out ().
But it doesn't and leaves a dangling styled preedit text on leaving
a text layer, either because the IME is not properly implemented (not
reacting to the context leaving the focused widget), or GTK+2 is bugged,
or maybe we just don't understand exactly how this all works. Anyway
let's explicitly clean preedit text, not waiting for preedit-end or
commit signals on IM abort.
Honor them in gimp_widget_get_color_transform() and make them
configurable in prefs. The code and GUI avoid the negation in
the lcms "NOOPTIMIZE" flag.
With left gravity, the mark is moved back 1 character to the left of the
cursor, whereas with right gravity, it is right after newly-inserted
text. This resulted sometimes into non-deleted preedit characters.
I don't understand all the subtleties since the problem only occurred
for the first character of a text layer, at least in my tests.
Anyway now it should be good.
Japanese IME emits the preedit-commit before preedit-end (Hangul or
Unicode don't, but we could assume other IMEs may be doing the same).
As a consequence, the undo step was not pushed, thus breaking undo
history and consistency.
The solution is to simulate preediting end then restart when a commit
happens during preediting.
Since commit b593462, gimp_text_tool_apply() is a semi-public function
(only to be used from gimptexttool-editor.c). Therefore move it to the
"public functions" section.
Commit cd147a4 reintroduced the crash. The culprit was the idle function
gimp_text_tool_apply_idle() which may not have been processed when
gimp_text_tool_move_cursor() is called, resulting in inconsistencies
between the text in the text tool's pango layout and its buffer.
Force any pending text commits to be applied before moving the cursor.
to gimp_color_config_get_simulation_color_profile(), along with
various internal "printer" strings. Also reduce the number of
user-visible "print" stuff from the preferences color management page.
Use cmsFLAGS_NOOPTIMIZE only for actual image buffer or single color
transforms, but not for previews or the image display. Makes things a
lot more responsive again.
In the text tool editor code, connect to GtkIMContext::preedit-start
and introduce a boolean text_tool->preedit_active which indicates that
a preedit is going on.
Remove the new preedit-removal code from gimp_text_tool_reset_im_context()
because it was not reflecting the IM's internal state and made things
worse. Instead, added gimp_text_tool_abort_im_context() which really
gets rid of any ongoing preedit by force.
In the main text tool code, check for preedit_active and if TRUE,
apply any edits directly widhout pushing undo steps. Factored out
gimp_text_tool_apply_list() for that purpose in order not do
duplicate a lot of code.
On undo and on button_press, force-abort any ongoing preedit. This is
the right thing to do on undo, but not really on button_press, but I
don't see another way to keep states consistent.
The new gimp_text_tool_im_delete_preedit() also makes sure that
text_tool->preedit_string is non-NULL when modifying the buffer,
so it can be used as indication whether or not a preedit is
going on (in order to skip undo stuff while preediting).
Rather than just discovering them by chance, a simple grep and some
search and replace are much more efficient! :-)
Cleaning only done on C and automake files.
and update their color transforms with the new monitor's color
profile. A widget is considered changing monitors when its toplevel
window's center crosses, in order to let widgets within one window
have consistent colors.
In particular, I don't want the preedit foreground colors to be
displayed in the text style editor UI. They are only temporary hints
and should not be taken into account as user-chosen style.
When gtk_im_context_get_preedit_string(), we have to inspect the
returned Pango attributes, so that the preedit string can be displayed
in the expected fashion (i.e. as in other programs).
Some input methods in particular would even break the preedit strings
in several chunks of text displayed differently (for instance Japanese),
depending on the cursor position within the preedit string.
There is nothing in our UI to set background color to text, but this
can be used internally, for instance to display input method's preedit
texts with specific colors.
Now all previews and the display shell connect to the color config
itself, there is no need any longer to connect to the global color
config's "notify" any longer from GimpImage. Also, the settings there
are for display purposes only, so nothing in the image itself needs
to be notified of the config change.
Need to connect_after() to the shell's GimpColorConfig "notify" so the
profile transform cache in gimp_widget_get_color_transform() is
already invalidated when we call gimp_color_managed_profile_changed()
in the shell's notify callback.
This is a hack. Actually the shell should create its transform only on
demand, and a config change should simply get rid of the previous
transform, just as all other widgets are doing it.
... and image_resolution != screen_resolution.
Partially revert commit 26ea7a3530.
Also, reset shell->dot_for_dot in gimp_display_shell_fill(), so that new
images that use the first display don't inherit the dot-for-dot state of the
previous image that used the same display.
Which creates a buffer from GimpFillOptions that can be applied to a
drawable. Eliminates three slightly different copies of the same
code. Also adds to the color history for each color fill, we missed
two places before.
Now the max parameter from Windows is taken into account and takes
precedence over the saved session state if set.
This can be applied either through the "run" property of a shortcut,
or by command line: `start /max gimp-2.9.exe`.
There is a start for min handling as well but I can clearly see the
window being minimized and immediately re-raised. There must be a call
later which deiconifies the window. This will have to be fixed.
Automatically connect to the global GimpColorConfig unless a different
one is set manually (like for previews that belong to a
GimpDisplayShell and should follow its color management settings. Add
public API for subclasses to get to the renderer's color
transform. Automatically color manage rendered pixbufs, just as we
already manage temp_bufs.
Which takes two profiles and returns TRUE if converting between
them works correctly without a GimpColorTransform. Use it in
gimp_color_transform_new() to return a NULL transform if none
is needed. Took the code from gimp-gegl-loops.c.
which encapsulates a cmsHTRANSFORM and does all the pixel format
conversion magic. It has API to create transforms and proofing
transforms, and to convert pixels arrays and GeglBuffers.
Before, each place which has a transform had to keep around the
transform and its input and output Babl formats, and had to implement
lots of stuff itself. Now all that lives in GimpColorTransform,
removing lots of logic from many places, and pretty much removing lcms
from the public API entirely.
This removes including <lcms2.h>, LCMS_LIBS and LCMS_CFLAGS from
almost all directories and potentially allows to replace lcms by
something else.
which isn't really for "picking", but it just fits too nicely into
GimpPickable to not put it there.
Also add utility function gimp_pickable_srgb_to_image_color() which
takes a "real" (sRGB) GimpRGB value, transforms it to the pickable's
colorspace and puts it into an "image color" GimpRGB.
...when a color profile is active
Add GimpPickable::pixel_to_srgb() which puts a picked raw image
pixel into a GimpRGB. Default to gimp_rgba_set_pixel() but implement
pixel_to_srgb() in GimpLayer, GimpProjection and GimpImage and
run the pixel through gimp_image_color_profile_pixel_to_srgb().
Replace the 3-state "off", "display" and "softproof" radio items by
two toggles "enable" and "softproof". Also add separate controls for
display and softproof options.
Not only the logic was broken, a local variable was also shadowing the
"dest_profile" variable and preventing the broken logic to be applied
at all. Double fail.
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.
... layers with alpha channel
add an operation that selectively outputs aux
or source if out/inside the rectangle (x,y,width,height),
independently of the alpha channel and use it
in filters split preview.
mostly copied from gimp:mask-components
Instead, store only the action's name, and look it up upon searching.
Keeping a reference to the actions in the history extended the lifetime of
actions that sohuld have otherwise died, leading to all sorts of nastiness. In
particular, the Alt+[n] actions to switch between images would remain bound to
their accelerator after the image has been closed, holding a dangling display
pointer, which would lead to a segfault, or fail with a CRITICAL message, when
using the accelerator again.
... when the button is clicked
Previously, the old color retained its previous value, so when the color
selection dialog was canceled, the button's color would go back to a
potentially outdated value, instead of the color it had when it was
clicked (for continuously-updated color buttons, at least.)
Add rendering intent, black point compensation and gammut warning menu
items to View -> Color Management. They set the respective values of
the active color management mode, so both "color managed display" and
"print simulation" are almost completely configurable per-display
now. Setting the simulation profile is still missing.
Add a View -> Color Management submenu that allows to change
the color management mode per-display.
Internally, keep a GimpColorConfig object around per-display that
is synchronized with the global config except for the properties
that have a per-display GUI (currently the mode).
Also provide an "As in Preferences" menu item to follow the global
settings again.
Use the shell's color config for color managing the display and
various auxiliary widgets attached to it, like the notebook tab widget
and navigation popup.
The config is currently just a reference to the global prefs config,
so no behavior changed.
The values from the global GimpColorConfig are for displaying images
on screen, not default values for profile conversion. Instead, default
to intent = RELATIVE_COLORIMETRIC and bpc = TRUE.
First of all, derive GimpFilterOptions from GimpColorOptions, not the
other way around, which was a sick way of magically showing the right
options for various tools. That approach has failed and needed
additional hacks to do the right thing. Simply have the right class
hierarchy and call the right tool options GUI constructors and done.
Remove gimp_histogram_options_gui(), we don't need histogram scale
controls in tool options when we already have them next to the
histograms in the tool dialogs.
Also remove gimp_histogram_options_connect_view() and use a simple
g_object_bind_property() instead.
Remove the filter area calculation code from gimp_image_map_apply().
Instead, automatically update the area when adding the filter to the
drawable, and when the selection changes. Also, connect to the
drawable's "removed" and remove the filter when the drawable gets
removed from the image.
Reduces members and all sorts of duplication and is a much better
abstraction of what it does. Also make it a lot smarter and
self-updating, chop up the apply() function and move its parts where
they belong. Also, it's now aware of selection changes and does the
right thing.
Don't abort GimpImageMapTool on selection changes, it now nicely
handles that.
see commit below, they are not needed any longer. Also call
gimp_image_map_tool_preview() from gimp_image_map_tool_create_map()
and remove more other calls to preview().
- call it in gimp_image_map_tool_get_operation() so
gimp_operation_tool_set_operation() doesn't need to call it
- gimp_image_map_tool_settings_import() doesn't need to call it because
importing settings changes the config object anyway
Instead, emit "notify" in the config object, which is a hack,
but a temporary one. If should be the right code tho, if only
Gegl pads would be normal properties...
Keep GimpStatusbar progress messages at the front of the list.
Previously, gimp_statusbar_push() and friends would push progress
messages behind temporary messages, and would push normal messages,
added after a progress had started, in front of progress messages.
This resulted in the progress bar text not being updated if a
temporary message was active at the time the progress started, or
if a normal message was pushed after the progress started.
This commit fixes this by always keeping progress messages at the
front of the message list.
Add "gboolean color_managed" and "GFile *color_profile" to
GimpTemplate. Add a toggle and profile combo to GimpTemplateEditor.
Honor the new template properties in gimp_image_new_from_template().
Using a GFile property instead of a GIMP_TYPE_CONFIG_PATH is
preliminary, see the previous commit. I'd like to use GFile more
directly when dealing with config files, this is for testing that.
instead of the "Feather border" toggle, and pass the selected style
to gimp_channel_border().
The border style defaults to "Smooth", whereas the previous default
behavior corresponds to "Hard".
isntead of the feather parameter, and pass it to
gimp_gegl_apply_border().
Make the necessary changes to the rest of the code to maintain the
current behavior.
Mass parameter alignment changes to gimpchannel.h. Sigh #2...
instead of the feather parameter.
The BORDER_STYLE_HARD and BORDER_STYLE_FEATHERED styles are implemented
using the "gimp:border" operation, as was done previously. The
BORDER_STYLE_SMOOTH style is implemented by performing a "gimp:grow" and
a "gimp:shrink", and subtracting the shrunk image from the grown image
using "gegl:substract".
gimp_channel_border() is modified to pass either BORDER_STYLE_HARD or
BORDER_STYLE_FEATHER, depending on its feather parameter, to maintain
the current behavior. The next commit replaces it with a style
parameter as well.
Mass parameter alignment changes to gimp-gegl-apply-operation.h. Sigh...
Will be used as a parameter to control the behavior of
gimp_channel_border(), and the corresponding "Select -> Border..."
action, instead of the feather flag.
Can be one of:
- GIMP_CHANNEL_BORDER_STYLE_HARD: Current behavior, unfeathered.
- GIMP_CHANNEL_BORDER_STYLE_SMOOTH: Smooth border, better handling
partial selection, implemented as explained in the next commit.
- GIMP_CHANNEL_BORDER_STYLE_FEATHERED: Current behavior, feathered.
This doesn make any difference because a NULL profile would do the
same, but it's safer to pass the actual profile instead of relying on
the magic meaning of NULL in the call to
gimp_layer_new_from_gegl_buffer().
Don't use the (wrong) global display color managment switch to
determine whether or not to convert the buffer to the image's
profile. Use the image's "is color managed" switch.
We used to depend on the global color management OFF switch from
prefs, but that's meant for display color management. Now, don't do a
profile transform if the target image's color management is disabled.
Its API was too limited, and adding parameters for what we need next
would be equally random. It's a rarely used and mostly internal
widget, so simply use g_object_new().
This essentially reverts 1bf8eef14f
which tried to prefer file procedured that are GIO-enabled over
indirect loading via the file-uri plug-in. But file-uri is gone now so
we can treat all file procedured the same again, restoring the
original logic.
Now a file procedure which specifies only an extension is again
preferred over magic matching.
The bottom visible layer must be rendered in normal mode because
every other mode on top of nothing renders nothing.
Before, we would display a stack's last layer in normal mode, which
was a braindead attempt to make the layer stack look like in 2.8. Now
we set GimpFilter's "is-last-node" property the right way by looking
at the filters' visibility in GimpFilterStack.
When converting between RGB and GRAY and the image has a profile,
invoke the convert profile dialog with the newly added image type
conversion feature.
Get rid of individual constructors for assign and convert, instead
have one constructor that takes a dialog type enum. No new features
yet in this commit.
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.
Change file magic matching from using a simple boolean "magic matches"
logic to using a matching quality. The quality is measured by the
number of bytes that matched.
Matching a single file procedure's magics now tries all magics and
returns the best match quality.
Searching a file procedure for a given file now tries all file
procedures and returns the one with the best match quality.
This fixes raw camera files being opened as TIFF, given a better magic
than just the generic TIFF magic is provided.
g_free the lru 'unit' when removed from the cache
and keep track of the list length and last item
while looking for a duplicate already present in
the cache.
Don't skip the first 10 bytes. That code was there to skip the magic
"GIMP_XMP_1" of the old "gimp-metadata" parasite. Instead, properly
check for that magic in xcf_load_image() and pass only the actual XMP
to gimp_metadata_set_from_xmp(). Also remove the +10 hack in file-exr.
... to avoid long pause on start
On non-Linux operating systems the fontconfig cache is often not
initialized by default. The first time GIMP was launched, this led
to a non-responding application, confusing many users.
The initialization of fontconfig has now been moved to a separate
thread. The main thread will wait for this fontconfig thread to
complete, regularly pulsing the UI.
This patch was partly based on an earlier patch by Tor Lillqvist.
Startup functions can now make the progress bar pulse in order
to report that something of unknown duration is in progress.
Call status_callback (NULL, NULL, same_percentage)
We must not dither the alpha channel if it is fully opaque or fully
transparent. 2.8 did the same but the dithering of these values was
apparently consumed be putting the result into 8 bit values.
Disable "new-style" fullscreen mode on OS X, we need support in
GTK+ in order for this to work properly. The currently available
fullscreen option in View > Fullscreen works fine and we plan to
migrate to the "new-style" fullscreen support in the future.
... and improve input method UI. IM should not use some floating overlay
frame to display the preedit text. Instead it is now directly inserted
into the text tool box, as selected text. It permits redimensionning of
the text box while typing, and push the rest of the text when inserting
in the middle (instead of superimposing an overlay box over the current
text box, making everything unreadable).
Input methods still have a few more issues, but this fixes the main UI
weirdness as well as the crash with Hangul IM.
We needed to get rid of these images at a later point. This fixes (at
least) a crash seen on Mac OS X, where the images were being unreffed
before the last GimpActions (with a reference to the image) were
unreffed.
which connects the properties of a config GObject and a GeglNode, much
like g_object_bind_property() which we can't be used because GeglNode
properties can't be registered with the GObjectClass.
This fixes a problem where in some cases the item next to the edited
item was changed inadvertently. This was caused by the fact that
the change of the label within the tree_name_edited callback triggered
a re-ordering of the items, which triggered a stop editing signal, which
finally caused a re-entrance in the tree_name_edited callback. By this
time the item below "path_str" has changed, which caused the name of
another object to be edited.
Plus, implement GimpColorManaged so the view renderer can ask the
buffer for its profile.
This also fixes colors in cross-application copy & paste when GIMP
is the source.
Change gimp_viewable_get_[new]_preview() to return buffers of the
image's and layers' colorspace, but in u8. This way layer and image
previews can transform them correctly to the display profile.
Note: this makes plug-ins receive thumbnail buffers in that
pixel format too.
Also change gimp_viewable_get_[new]_pixbuf() to always return sRGB
buffers that can reasonably be put to screen directly, or put into DND
buffers. This is at least more correct now.
Keep around transforms not only to/from the image's pixels to
"R'G'B'A double" (GimpRGB's format), but also to/from "R'G'B'A u8"
(GdkPixbuf's format). Also add API to access all cached transforms
and the Babl formats expected when calling lcms.
...in "alt-pressed" mode
Menu activation doesn't cause a focus-out becaus menu keyboard
grabbing is implemented with a simple gtk_grab_add() (the menu popup
never gets the focus). Therefore, the canvas never gets a focus-out
event and the pressed modifiers are stuck.
Fixed by connecting to "grab-notify" on the canvas, and artificially
releasing all modifiers when the canvas is shadowed by a grab.
Change things so the guide is preferred over any color picking
interaction of the parent GimpColorTool. Needs a minor change in the
GimpCurvesTool subclass too.
...for the preview?
Change to allow for split previews in all 4 directions. Remove the
direction controls from the filter dialog, and instead implement
shift- and control-clicking on the split guide to switch
original/filtered sides, or orientation.
Rename profile constructors to say "d65_gray" instead of just "gray",
"srgb_trc" instead of "srgb_gamma", and drop the "srgb" from
"srgb_linear" because we now say "d65". This should be a naming scheme
that doesn't conflict with whatever future functions we might add.
Add more user friendly description to the PDB op.
Partially keep the technical description for the PDB op and add a
reference to the developer wiki.
Use the new "reference" key for the GEGL op.
After discussion in IRC some weeks ago give the Selection-Flood items
the more meaningful name Selection-Remove holes.
modified: app/actions/select-actions.c
modified: app/core/gimpselection.c
Add two new tools, GimpGuideTool and GimpSamplePointTool. They are
one-trick-ponies and can only create new or move existing guides and
sample points. They can't be selected from the toolbox, only
temporarily pushed as active tools on top of any active tool using
their public start() APIs.
Use that API to enable them when the rulers are clicked, and replace
the entire guide and sample point moving code in GimpMoveTool and
GimpColorTool by simple calls to that API.
This might look like overkill but can easily be used for other
features like moving guides from within the paint tools (mirror
painting) or gegl filters (preview curtain).
Gamma correction refers to correcting how an image is displayed on
various devices. Gamma adjustment is a more general phrase that also
applies to adjusting gamma as a step in image enhancement in a
color-managed workflow.
Pass the display scroll offset down to gimp_cairo_stipple_pattern_create()
and set it as offset on the created cairo pattern, so stipple patterns
look the same no matter how the display is scrolled.
Themes from 2.8 and before are not fully compatible with 2.10.
In particular, embedded icons would not work and you would end up with
the Symbolic icon theme (light colors), which may not work well with a
custom theme.
It is better to reset to the new defaults upon migration and users can
still try and configure the theming afterwards if they wish.
Add generic tool actions for spacing, hardness and force, and the
GimpToolControl infrasctructure to redirect them to tool-specific
actions. Add tool-specific actions for GimpBrushTool, GimpMybrushTool
and GimpWarpTool as redirect targets. Also fix some existing tool
action callbacks to use the right increase/decrease steps.
Since we have many themes now, this new name better indicates that it
is meant to follow your desktop theme settings.
Also it will likely not remain the default theme.
which are essentially a copy of the stroking GUI. We now can fill the
exact shape outlined by stroking selections and paths. Suggestions for
the menu item labels are welcome.
For selections, it's different from gimp_edit_fill() because it
ignores the selection while filling, just as stroking does. Currently
unused, stay tuned...
Fix GimpAirbrush to not keep a GimpSymmetry instance around across
paint strokes. The symmetry refs its drawable but lacks the code of
dropping the reference when the drawable is removed from the image, or
the image is closed.
Also cleaned up gimp_airbrush_paint() a bit.
When set, it crops the effect to that rectangle, using a cache for
quickly changing the previewed area. When disabling the preview rect,
make sure we don't lose the cached result by processing it into the
output cache through the mode and affect nodes which is cheap-ish.
and remove lots of labels from calls to gimp_prop_foo_new(). Also
had to manually remove some unwanted labels that are now added
automatically, fixes bug #761880.
I am still not sure whether custom guides should follow snapping rules.
Yet I could easily imagine you could want some normal guides with
snapping and in the same time symmetry without snapping to axis of
symmetry. So for the time being, let's disable snapping to custom guides
all the time and see if logic could be improved later.
This is not ideal since the scale widget is crazy huge, thus
impractical, but the solution used on properties of other symmetries
(updating min/max of the class property) is wrong since it applies to
the whole class.
For the time being, it avoid setting obviously bad values until we
figure out the ideal automatic UI construction.
Since commit 9c4dd96, a NULL label to gimp_prop_check_button_new()
generates a label from the property nick. Trying to add a GtkImage in
the button outputs a warning because a GtkBin can have only one child.
Fixes the warning:
Gtk-WARNING **: Attempting to add a widget with type GtkImage to a
GtkCheckButton, but as a GtkBin subclass a GtkCheckButton can only contain one
widget at a time; it already contains a widget of type GtkLabel
...behind main window on windows
Windows requires that the process with the
foreground window explicitely allows long
lasting background processes showing their
windows as foreground/focused
Remove GimpSymmetry::get_settings() and instead tag the properties that
should have a GUI with the GIMP_SYMMETRY_PARAM_GUI flag. Also use plain
g_object_class_install_property() because that allows for separate nick
and blurb. Finally, use gimp_prop_gui_new() to generate the GUI,
This reverts commit 6878b49491.
I didn't take into consideration that different themes could apply
various fonts, font sizes or label-scale for the widget. So the font
description needs to be reinitialized at every theme change.
Use a GType for the PROP_SYMMETRY property of GimpImage, and create
a default "identity" symmetry for an image.
I still use a GimpIntComboBox but store the property value in the
user-data column because gpointer isn't a subset of gint.
Adds in libgimpwidgets:
- gimp_int_combo_box_set_active_by_user_data()
- gimp_int_combo_box_get_active_user_data()
- gimp_int_store_lookup_by_user_data()
- gimp_prop_pointer_combo_box_new() to create a GimpIntComboBox and
attach it to a gpointer property.
Thanks Massimo and Mitch for reviewing my code.
You can now set any paint tool to mirror painting relatively
horizontal/vertical axis or a central point (any combination of these 3
symmetries).
This has been implemented as a new multi-stroke core, where every stroke
is actually handled as a multi-stroke (default of size 1).
This is also the first usage of custom guides for symmetry guiding.
Current version has to be activated in the playground.
With gimp_guide_custom_new(), you can create a custom guide with a different
style on canvas (other pattern/color/width). A custom guide won't be saved
and could be used, for instance, for specific GEGL op guiding.
Use a proper "progress" signal instead of a property "notify" one
to update the on-canvas progress widget.
This way the graph is not invalidated while processing it
which essentially means some cleanup and no more regressions:
- add state POINT_BOTH for moving the entire line
- use the move cursor for moving the entire line
- reorder some functions
- set the tool to handle click events
- make clicks and no-motion releases behave properly
- #if 0 the code for "shapeburst handles", they don't work yet
- return to gimp:shapeburst until we have figured progress for GEGL ops
- indentation, stuff...
While the tool should definitely use the new op, we want the code in
gimpdrawable-blend to use the old one for compat reasons. The new op
will be exposed via a separate pdb call in the future.
This reverts commit 8af3fec689.
This operation assigns to each pixel the minimum of the
maxima of all paths from it to the outside, as if the
input image represents a height map, and the operation
floods it with water.
Commit the old tool before even creating the new tool. Old and new
tool might be the same and share tool options, and we don't want
the new tool's initialization to mess up the old tool's state.
Fixes changing from one GEGL operation to another without explicitly
confirming the first operation. The bug only killed the cached filter
result, but that's bad enough.
The "Settings:" label should never be aligned with a label in the UI
below, because that suggests that are related. Also consistently
rename all GimpImageMapTool parameters and variables to "im_tool".
seems I didn't consistently group things in indented GimpFrame widgets
last time I cleaned up here. Should be better now. Also change the
"Auto" button to "Auto Input Levels" to make things clearer.
In gimp_display_shell_expose_region(), invalidate each rect rather
than rebuilding the cairo_region_t as GdkRegion and then invalidating
the entire GdkRegion. Improves performance for tools that invalidate
complex regions.
Use a GQueue instead of a GList in GimpCanvasGroup, so adding items
takes constant time instead of O(n). Also, removing items was
traversing the list twice. This should generally speed up tools with
lots of canvas items.
Also, add a private pointer to the instance struct instead of using a
GET_PRIVATE() macro.
Add new string members to GimpImageMapTool and use them instead of the
resp. fields of GimpToolInfo. Change ::get_operation() to return the
operation name and a lot of strings for the UI, and create both the
GeglNode and the config object in GimpOperationTool. Lots of various
cleanups in GimpImageMapTool subclasses. This is an intermediate state
on the way of making the whole filter applying mechanism more generic
and less depending on subclasses.
which registers config classes for operations that don't want their
config objects to be auto-generated. Register all color tools' config
objects. Change gimp_gegl_config_sync_node() to correctly handle ops
that have an object property of the right config object type.
Old themes should not be copied over to the GIMP 2.9/2.10 config at
first launch since they won't be compatible anyway. Let's go the less
painful way by dropping old themes rather than trying to salvage themes
which we know will be broken by design.
Add "title" and "help_id" parameters and members/properties to
GimpToolDialog, GimpToolGui, GimpOperationTool. Also make the order of
parameters more consistent.
When checked, diagonally neighboring pixels are considered connected
when calculating the affected area.
This commit also adds a corresponding diagonal_neighbors parameter to
gimp_drawable_bucket_fill(), and modifies the callers, other than the
bucket fill tool, to pass FALSE for this parameter, to retain the
current behavior.
...gimp_pickable_contiguous_region_by_seed(), in preperation
for adding a similar option to the relevant tools.
When this parameter is TRUE, all eight neighbors of each pixel
are considered when calculating the resulting region, instead
of just the four orthogonal ones.
This commit also modifies all callers to pass FALSE for this
parameter, to retain the current behavior.
There are still unused variables in gimp_mybrush_get_checksum() and
gimp_mybrush_get_memsize() but these seem to be because of pending
implementations. So I leave the warnings.
Fixed "gimpicons.c:30:45: fatal error: icons/Default/gimp-icon-pixbufs.c:
No such file or directory" after commits :
ee512b610dfa9e5b8f98
Fixed "ln: failed to create symbolic link ‘12/gimp-default-colors.png’:
File exists" by forcing new symlinking on creating get-default-colors.png
for Symbolic-inverted to prevent error during make.
Create GIMP_CONFIG_DEFAULT_(ICON_)?THEME in gimpguiconfig.h to set
defaults in a single place, except for libgimpwidgets/ which cannot
include from app/.
Call the suspend()/resume() from the previous commit around
gimp_display_shell_appearance_update() so the cancas is not
repositioned for each individual widget configuration.
Implement a mechanism to suspend/resume GimpImageWindow's "keep canvas
pos" logic which is used to keep the image in place across widget
changed such as show/hide rulers.
gimp_display_shell_fill(): call suspend()/resume() around
gimp_display_shell_appearance_update(), and center the image after
calculating the initial scale factor, so the image jumping at least
starts at the approximately right position.
because this should happen generically in the zoom model's "zoomed"
callback, and is done explicitly in a few special cases. The removed
calls should all be redundant.
...several different zooms tiled together
In gimp_display_shell_scale() don't shortcut things in the case where
we resize the window, but call gimp_display_shell_scale_resize() like
all other scaling functions do in the end.
Need to keep GimpPDBContext's stroke options (which is a context too)
in sync with the PDB context itself, so setting any of the context's
properties properly affects subsquent strokes, and also avoids running
into inconsistent states like happened in this bug.
gimp_plug_in_procedure_set_icon(): look at the passed icon_type,
not proc->icon_type. Introduced this when splitting the function
into set_icon() and take_icon() in d5255dc.
Change GimpFileDialog's file-procs properties to enum
GimpFileProcedureGroup and get them via the newly added API. Set
properties common to all dialogs in the parent class.
..."Operation not supported"
Add argument validation in the GimpPlugInProcedure impls of
GimpProcedure::execute() and ::execute_async().
When a file procedure is executed and it handles URIs not filenames,
run the resp. arguments through file_utils_filename_to_file() which
turns both URIs and filenames into a valid GFile which we can ask for
its URI.
Remove the code that links size, spacing etc. to brush defaults from
the GimpPaintOptions class impl and add it to gimppaintoptions-gui.c
as a callback instead.
It's not a core thing and that magic with side effects should only be
applied to the GimpPaintOptions behind the tool options GUI.
Call gimp_display_shell_scrolled() before gimp_overlay_box_scroll()
so the rotate transform is updated before the actual scrolling.
The explicit call to gimp_display_shell_rotate_update_transform() got
lost during the last commits, but this solution is cleaner and less
redundant anyway.
by changing it to always deal with the center of the viewport instead of
its upper-left corner.
Fix gimp_display_shell_scroll_center_image_coordinate() to use the
proper transform functions like in the last commit.
gimp_display_shell_scale_to(): calculate the point that should not
move with GimpDisplayShell's untransform/transform functions before
and after scaling, then scroll to the right point. Just using the
scale functions doesn't work any longer when a rotation is
active. Other functions are affected too, but this most important
issue can be fixed by fixing just this function.
Add PDB sample point API similar to how the guide API works. Add core
API similar to the core guide API to make guide and sample point APIs
as similar as possible.
Add GimpGeglProceure to keep track of recently used GEGL operations in
the filter history. The new procedure also takes care of running the
op in the GEGL tool, so filters-commands.c is almost empty now.
Change gimp-filter-history.c to find procedures by name instead of
comparing pointers.
The only thing missing now is rerunning a GEGL op with the last
settings (not just showing its UI).
file-procedure.[ch] is gone and its functions moved to
GimpPlugInManager where they belong (the manager keeps around the
lists of load, save and export procedures).
Utility functions from file-utils.[ch] that have nothing to do with
image files moved to core/gimp-utils.[ch].
This preparation commit only moves code around and renames it, the
history is still a list of plug-ins only:
- move app/core/gimp-filter-history.c
to app/plug-in/gimppluginmanager-history.c and clean it up
- move the actions that create the submenus under "Filters"
from the "plug-in" to the "filters" action group
- move the code that creates and updates the history actions
to the "filters" action group
- add menu setup code for the "filters" menu
- move the "history-changed" signal from GimpPlugInManager to Gimp
This adds a boolean to GimpCoords struct that is true for enabled
extended non-mouse devices and false for all the rest allowing
the mypaint brush to override the the pressure sent to the paint library.
New GimpColorHistory widget, replacing the code in GimpColorDialog, and
added to GimpColorEditor to have the color history accessible in the
color dock as well.
Thanks to Thomas Manni for the initial implementation attempt.
- GimpContext API and property
- a GimpDataFactory
- List and grid views with GimpDataFactoryView
- actions and a context menu
None of this is connected to the actual tool yet, or depends on
libmypaint in any way.
Metadata presence implies XCF version 6 or higher. Yet metadata are
stored in parasites which are perfecly supported in older GIMP versions
and are passed along through saving.
Therefore there is no need to keep XCF 6. We just add a warning telling
that metadata won't be visible in older GIMP when saving a file with
metadata and compatibility mode.
Allow to set profiles on grayscale images. Change profile validation
to check for image type and profile type. Actually the patch simply
makes some pieces of code less restrictive. Change user-visible
strings in the profile dialogs accordingly. Change PDB docs
accordingly.
Support creating linear/sRGB-gamma variants of gray profiles and
rename gimp_color_profile_new_linear_rgb_from_color_profile() to
gimp_color_profile_new_linear_gamma_from_color_profile() because it's
not RGB-specific any longer.
Remove the parameters from gimp_prefs_box_add_page() and instead
hardcode them once in GimpPrefsBox. This way they can also easily be
made configurable in the future.
Add gimp_stock_set_icon_theme() which can be called at any time, also
before gimp_stock_init(), in which case we avoid setting the configured
icon theme twice on startup. Call it from libgimp/gimpui.c and
from app/gui/icon-themes.c so the app and plug-ins use the same
icon theme.
Images originally created by Jakub Steiner and Barbara Muraus as the
"Art Libre" icon set.
The contributor jEsuSdA later worked on it.
It will now be available in the new icon theme selection through
preferences.
Many icons/size are still missing but this first commit makes a start
for complementary work.
which lets the user select a buffer from all available drawables and
projections to be used in a gegl:buffer-source node. The widget's
appearance is scheduled for improvement.
Keep only one menu item per precision, and have two separate radio
menu items for gamma/linear. Also add gamma/linear radio buttons to
the precision conversion dialog.
...selection on image in another tab
Fixed for rectangle select, ellipse select and crop, they now all
confirm the previous display's tool interaction instead of aborting it
when the tool is used on another display.
...selection on image in another tab
Make the free select tool behave when switching between displays.
Also clean up the code a bit and reduce utility function
fragmentation.
This reverts commit 56b6dbaa87.
It has been discussed and decided that the no-hash numbering scheme
would have unwanted side-effects for people using number-ending layer
names for other purposes than incrementation.
This revert has been modified to keep commit c402f10.
Add new PDB procedures gimp-context-get/set-stroke-method and honor
the new setting in gimp-edit-stroke and gimp-edit-stroke-vectors.
Internally, keep a GimpStrokeOptions around in GimpPDBContext to keep
track of the newly added PDB state, and use it for the stroke
operations instead of creating a scratch GimpStrokeOptions.
Ignore notifications on properties that are not "context properties",
which is for example the parent context's "gimp" property.
A notification on "gimp" is recieved when creating the child context
before the parent context is fully constructed, for example in the
parent's constructed() implementation.
The Curves tool is to be considered "enabled" as soon as it is selected,
not when it is initialized (usually at the first click on the image).
One of the main consequence of not being "enabled" was that the tool
cursor was wrong at selection.
Blurbs use third person and need a final point.
Some description were wrong or inaccurate. Add also units where
needed (radius in pixels, angle in degrees).
Some returned values have to be freed.
Add code to GimpOverlayChild which can render arbitrary children of
the widget fully opaque, ignoring the configured opacity.
Add gimp_widget_get,set_fully_opaque() which gets/sets a per-widget
boolean flag to trigger that code.
Set the color picker's and the text tool style widget's color areas to
fully opaque.
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)
GIMP_IS_TAGGED error and possible Gimp crash (core segfault)
Remove the object from GimpTagEntry's selected_items when it is
removed from the GimpContainer.
Block the config's "notify" signal when setting a NULL filename from a
GimpColorProfileComboBox. The notify callback was only introduced
because GimpColorConfig is now validating the profiles. Validation of
a NULL profile never fails, but the NULL notify from the config
prevented the profile file chooser dialog from appearing.
Looks like they were forgotten so messages from libs went to stdout
instead of being routed through the log handlers, which would show
them in a dialog, or in the error console.
The pipe index for velocity was being multiplied
by 3.0 and rounded, making it larger than the
available rank and always clamped to the last
brush image in velocity ranks.
Move some functions from libgimpwidgets/gimpwidgets.[ch]
and from app/widgets/gimpwidgets-utils.[ch]. Newly add
gimp_widget_get_color_profile() which is extracted from
modules/display-filter-lcms.c.
Remove the check for opening a regular file from
file_open_dialog_response() and call the functions in file-open
unconditionally. This is the actual fix because the check was simply
bailing out with no message or anything when trying to open a
non-regular file, whereas the checks in file-open return proper error
messsages.
In file_open_image(), do the checks for being a regular and readable
file first, so we don't run into reading from other files when trying
to figure the file format.
GIMP's OVERLAY mode was identical to SOFTLIGHT. This commit fixes the
issue and introduces a NEW_OVERLAY mode and enum value.
- change gimp:overlay-mode to be a real (svg-ish) overlay mode
- when compositing, map OVERLAY to gimp:softlight-mode
- when compisiting, map NEW_OVERLAY to gimp:overlay-mode
- bump the XCF version when NEW_OVERLAY is used
- map OVERLAY to SOFTLIGHT when loading and saving XCF
- map OVERLAY to softlight in all PDB setters
- map OVERLAY to softlight when deserializing a GimpContext
- change all paint mode menus to show an entry for NEW_OVERLAY
instead of OVERLAY
- change PSP, PSD and OpenRaster to use NEW_OVERLAY
These changes should (redundantly) make sure that no OVERLAY enum
value is used in the core any longer because it gets mapped to
SOFTLIGHT at all entry points, with the downside of introducing a
setter/getter asymmetry when OVERLAY was set in a PDB api.
Keep the config values around even if compiled without MyPaint brush
support, so we remember the values between sessions of differently
compiled GIMP versions.
With this patch, there should be no more need to set PATH on Windows
before running GIMP.
This patch was tested by me and drawoc, but there could be some
undetected issues lurking. Revert if any problems arise.
Implement GimpConfigInterface::equal() for the brightness-contrast,
colorize, and threshold config objects, to prevent the parent class'
timestamp being compared by the generic default implementation.
Get rid of most seeking by writing the tile offsets to a table in
memory, instead of directly to the file after each tile. Only seek
back after writing all tiles, in order to save the entire table at
once.
Reorganize tool modes to be { ADD_TRANSFORM, MOVE, REMOVE }, where
ADD_TRANSFORM is the default and allows to add handles *and* transform
the image in one click-drag. MOVE moves handles without transforming
(shift) and REMOVE removes handles (control). Also improve cursors to
accurately show the result of a click.
The work-in-progress was using a source tree of libmypaint embedded
into GIMP tree. This is a cleaning with pkg-config test in configure,
and correct includes.
Add undo to the Isissors tool, along with some refactoring:
- Always modify the actual curve, instead of a set of obscure states
kept around in the tool instance
- On cancel, simply go back to the curve on the undo stack
- Draw handles on top of curve segments
- Draw the currently edited segments and handles in the highlight color
Iterators might only give us a small chunk of the source buffer,
but until now convolve assumed it gave us the entire buffer at once.
This simply switches to gegl_buffer_get so we always have the
entire buffer.
This fixes iscissors.
The interaction is fully restored, it's also ported to the new halt()
and commit() API of tools and semi-properly GEGLized: the gradient map
is now constructed on the fly using a GimpTileHandlerValidate
subclass.
The only problem is that it doesn't find any edges in the image and is
totally useless. Pushing anyway to put an end to the bitrot, any help
with debugging is greatly appreciated...
Add virtual function validate() so subclasses can construct arbitrary
buffers on-the-fly. The default implementation blits from the
projection graph like before. Add boolean property "whole-tile" which
allows for switching between always validating entire tiles, and
validating the parts of the tile that are actually dirty.
Add new tool GimpHandleTransformTool which allows to freely place up
to 4 handles on the image, then move any one of them, which transforms
the image so that the remaining handles keep their position.
Did quite some cleanup on the code before pushing --Mitch
by getting rid of the complicated "previous selected points" handling
and simply keeping around the last motion event's coords for
calculating the deltas to move the selected points.
- Formatting and indentation
- Handle GIMP_TOOL_ACTION_COMMIT
- Fix calls to gimp_tool_control_activate()/halt()
- Move variables to local scopes
- Remove and reorder includes
- Remove redundant members from the tool struct
- Set members to NULL after freeing them
- And whatnot...
They were also serialized correctly before, but only because many
GimpData objects were (bogusly) always dirty after loading, which
caused them to always be written do disk on exit. This commit fixes
this problem and updates by-name references explicitly as things are
renamed, instead of relying on bugs.
Add gimp_data_factory_data_clean() which clears the dirty flags from
all a factory's objects. Call the new function on all factories at the
end of gimp_restore(), when all data has been loaded. This might be
total overkill, but ensures that everything is clean in the beginning.
Add new signal GimpContext::prop_name_changed() which is emitted when
any of the context's object properties (brush, gradient etc) is
renamed.
In GimpToolPreset, connect to the new signal and dirty the preset if a
relevant object propery was renamed, making sure the preset is saved
to disk later. Also optmize updates quite a bit by ignoring
notifications on tool option properties that are irrelevant to the
preset.
This might or might not address the issues discussed in bug #739487.
gimp_brush_editor_update_brush(): only set the brush property whose
GtkAdjustment has changed, and only set it if it is different from the
current value. Before, simply setting a brush on the editor would
cause all properties to be written back to the brush unconditionally.
gimp_brush_editor_notify_brush(): unrelated cleanup: use brush
accessors instead of direct struct access, remove an update of the
radius property from the shape updating code that was probably left
over from copy and paste.
Fix the return values of drag_motion() and drag_drop() callbacks.
Commit 7b85cf4de8 started mixing up
the two unrelated concepts
- the widgets has handled the event
- a drop here would do something / did something successfully
into one boolean value being both the function's return value and
a success indicator for the DND operation.
Untangle the concepts again by returning FALSE when
gimp_paned_box_will_handle_drag() returns TRUE (indicating that the
docking DND mechanism will kick in), and always returning TRUE
otherwise; and by using the state "drop was / would be successful"
only for calling gdk_drag_status() and gtk_drag_finish().
This way we make sure that:
- drag_leave() is called reliably again (because we return TRUE if no
other widget will handle the event)
- drag data is freed reliably again (because we always call
gtk_drag_finish())
Add gimp_file_show_in_file_manager() to libgimpbase and a menu item
in app which shows the image's file (if any) in the file manager.
Implemented calling the org.freedesktop.FileManager1 interface
and dropped snippets found on stackoverflow for somebody to
turn into working code for OSX and Windows.
gimp_tool_preset_deserialize_property(): initialize all object
properties (brush, pattern, gradient, ...) of the preset's
GimpToolOptions with non-NULL values from the user context,
so loading a broken preset never results in NULL objects being
used.
Add "link" buttons to the tool options that are duplicates of brush
properties, so the tool options values can be set to change along with
the current brush.
Add "action-group" signal to GimpActionGroup, such that we can
properly set the accel group and connect the accelerator on actions
that are created after the initial setup of the menus.
This would have crashed if we ever replaced or removed something in
that hash table. Instead, use g_object_unref() as value_destroy_func
because the table keeps GimpContainers which we would leak if we ever
removed anything from the table.
after text box moved using Alt key
In gimp_text_tool_button_release(), handle the "moving" case
separately instead of running into the default else branch that
assumes the user clicked outside and made a new text layer.
It used to be { NEW, UPDATE } but that didn't allow to distinguish the
final END update, which we will soon need for automatic color history
updating. Make sure all places that handle motion events on colors
(pick from canvas, gradient editor) correctly send and handle END
events.
Add a generated palette which contains the color history. For now it's
only updated when the color dialog's color history gets updated, but
should be updated whenever a color is chosen in any way.
Since the first action of the list can be run directly with Enter while
the entry is focused, hitting "Down" means one wants to select the next
item of the list. So let's jump directly to the second item on the first
"Down" key pressed.
Separate fallback use of a cursor from using a plain size
indicator cursor. Ink tool uses a plain circle as primary
drawing indicator instead of outline, totally different
use than a fallback, when brush is too small to be drawn.
Conflicts:
app/tools/gimppainttool.c
...bring focus back to GIMP image window
When showing docks in multi-window-mode, try to set the keyboard focus
back to the active display because it might have been stolen by a dock.
Change gimp_brush_generated_get_half_size() to get_size() and
calculate its exact size in float. This is really a minor change that
seems to work well.
- add gimp_image_get,get_xcf_compat_mode()
- add a compat toggle to GimpFileDialog which is shown and sensitive
only for a save (not export), and if the image structure allows
to save an old version at all. The button also has a tooltip
which explains why it is sensitive and what it does
- add "gboolean xcf_compat" to file_save_dialog_save_image()
- in file_save_dialog_save_image(), call image_set_xcf_compat_mode(TRUE)
only around the call to file_save() and set it to FALSE after saving
- in xcf_save_invoker(), honor the image's XCF compat flag and save an
RLE-compressed XCF if possible
The above is very convoluted and doesn't pass the "xcf_compat" boolean
directly because we can't change the parameters of gimp-xcf-save, and
because the gimp-xcf-save might be called indirectly.
Change XCF saving to never seek past the end of the partially written
file. The only places where we still did this was when skipping the
offset tables for layers, channels, levels and tiles.
Now we write an all-zero offset table first, and then only seek around
in areas of the file that already exist. This also simplifies the code
a bit. Changed comments to make it clear what happens.
Don't use xcf_seek_end() because that seems to be broken on certain
file systems / operating systems / FUSE mounts / whatever. Instead,
seek to explicitly calculated file offsets.
Ported Massimo's patch to master and added comments --Mitch
The same commit in gimp-2-8 is a57e49b1bb
It was introduced in e7ade3f8ec. The
g_return_if_fail() is IMO useless, the actual fix (which I kept) was
pulling the call to gimp_tool_options_editor_presets_update() inside
the if().
- use G_FILE_CREATE_NONE instead of 0
- don't put "Could not open <file> for writing: <error>" around the
returned error, the returned message is already verbose
...and layer opacity
Use a temporary variable to store intermediate result instead of
writting 2 times to the output buffer, because input and output
buffer might be the same.
Add gimp_image_get_xcf_version() and use it when saving XCFs. The
function also returns GIMP versions in integer (comparable) and string
form to be used by GUI logic that allows to save compatible files.
GimpOperationPosterize: also posterize the alpha channel. Seems like a
no-brainer to me, and is actually useful (see bug). The old behavior
is still available by simply disabling the alpha channel in the
channels dialog.
Don't hardcode "black" for the "Value" curve in GimpCurvesTool.
Instead, pass a NULL color to GimpCurveView, which is then interpreted
as the theme's text color (the curve's background is the theme's text
background color). We still hardcode pure red, green and blue for the
other curves.
and g_warning() for programming errors only.
Use g_printerr() for "normal" errors which may happen in a program
lifetime (in particular corrupted XCF file errors are not necessarily
programming errors).
I now normalize with g_str_tokenize_and_fold() which uses standard
Unicode normalization.
I don't use g_str_match_string() directly though, because I want to
run additional checks to order the results by relevance. For instance
I still want actions whose labels starts with the search string to be
at the top, and results with same order as search token before those
with a different order. Then results with match in the tooltip. Finally
I also returns results with partial match in the label, and the rest in
the tooltip, though at the bottom of the list.
Other than that, this returns the same results as g_str_match_string()
with a similar algorithm. In particular now we only match the start of
tokens (a substring in the middle of a token won't match anymore).
I kept the small 2-character trick matching the first letters of the
first 2 words of the label, but I got rid of the fuzzy search (that none
really found ever relevant anyway).
It's now either $XDG_CONFIG_HOME/$gimpdir/2.9 or directly $gimpdir,
depending on whether $gimpdir is a relative or absolute path. Build
the resulting string in configure and put it into the manpage_gimprc
variable so it can be used in the manpage sources.
Our code was planning zlib and fractal compressions for eons, but would
crash against a file which would be actually using these. It means that
if we implement one of these compressions for 2.10, anyone with GIMP 2.8
(and likely earlier too) would crash when opening a legit file using the
new compressions. That's very bad.
Never use g_error() in non-fatale, expected, situations!
Don't try to load palettes and gradients with unknown extension. We
introduced extensions for these files a *lot* of years ago, so we're
dropping this legacy feature now, everybody can just rename their old
files to have the right extensions (the file formats have not
changed).
The page is shown by default in unstable but needs --show-playground
in stable versions. There is nothing yet on that page. Also, the icon
needs improvement...
Return a new enum GimpAutoShrink { SHRINK, EMPTY, UNSHRINKABLE } from
gimp_pickable_auto_shrink() because a simply boolean FALSE doesn't
distinguish between "not further shrinkable" and "no content". Change
the callers accordingly add a special "already cropped" message where
we only had a "no content" message before.
gimp_pickable_contiguous_region_by_seed(): don't call
find_contiguous_region() with start coords outside the buffer, or it
will run into an infinite loop.
g_test_init() makes any warning message fatale by default. While it
makes sense for the main OS that we build on (Linux), I believe that
our tests on Windows are more useful when they finish, even with some
warnings, than stopping because some stupid font warning would occur
(case I encountered, did not know the solution of, and is not really
relevant to the rest of the test).
gdk_test_simulate_key() has currently no win32 implementation.
Add this implementation in our code until a patch to GTK+ for this is
merged. This fixes 2 `make check` tests for win32.
In particular, we were not building these for win32, which has no
symbolic link concept. So let's use $(LN_S) defined by autoconf for this
purpose, as it will copy files for platforms without ln support.
Moreover this way, we don't create one such folder for each and every
test run and fill up the tmp directory with countless directories, that
we never clean up.
On Win32, this fixes 3 tests which were failing because of the missing
icons.
Use gimp_image_get_format() instead of gimp_babl_format() in
gimp_drawable_real_estimate_memsize() because the latter can't handle
indexed formats and returns NULL.
It is advised to use the more accurate g_io_channel_win32_new_fd() or
g_io_channel_win32_new_socket() because GLib can't differentiate between
file descriptors and sockets on Windows, which outputs a warning when
there is ambiguity.
this implies passing the UTF-8 encoded raw module path from gimprc to
gimp_module_db_load() and gimp_module_db_refresh(), which is strictly
speaking an API break, but I seriously doubt that anyone but GIMP is
actually using libgimpmodule.
gimp_directory_file(), gimp_data_directory_file() etc. The new
functions take a variable list of path elements to the file,
the list has to be NULL-terminated. Remove the newly added
gimp_personal_rc_gfile(). Start using the new functions in app/.
We need to mount every non-native GFile's volume, regardless of
whether the file procedure uses GIO directly or needs file-remote to
download/upload the file. Move the entire mount logic to a new
file-remote function and change gimp-gui.c and gui-vtable.c to only
return a GMountOperation. Try to mount every non-native file in
file-open.c and file-save.c and bail out if mounting fails. Simplify
the uploading and downloading code accordingly.
The context can now be null unless the gradient specifically needs
the foreground/background colors, in which case
gimp_context_get_{foreground,background} will do the check and warn.
- change start() and set_text() to use "format" and "..." instead of
"message", allowing to format progress messages in place
- s/cancelable/cancellable/
- move "cancellable" to be the second argument of start()
- Move all GimpGuide members to a private struct
- Remove cruft checks for position < 0, we don't keep removed guides
around in the image's guide list since a long time ago
- Add #define GIMP_GUIDE_POSITION_UNDEFINED G_MININT and use that
instead of -1 (this is also a prerequisite for having guides
outside of the image)
Don't iterate the lists with for() because the loops can remove items,
which makes us say g_list_next() on a removed list item. Instead, use
while() and get the next item before possibly removing the current
one.
We optimized away so much redundant processing that we now need to
copy the region already processed by the GimpApplicator from its
cache, when it would previously have been created "for free" by all
the redundant processing.
In gimp_drawable_merge_filter(), use that feature to make filter
applying cancelable. Stop projection rendering first, because we have
to run the event loop manually in order to receive input for
canceling, but we don't want the projection to be constructed from
that manual loop running.
In gimp_tool_progress_start(), if the progress is cancelable, grab on
an invisible widget and emit the progress' "cancel" signal when Escape
is pressed.
...causes layer folders to expand
In gimp_image_remove_layer(), don't use the top element of
image->layer_stack as the new active layer, because it is simply some
arbitrary layer that was previously selected. That stack is only good
for finding the last active layer when returning from the channels
dialog. Instead, let the proper logic run and use the new active item
returned by gimp_item_tree_remove_item(), which is the layer below the
removed one, if any, or the one above it otherwise.
- don't allow to create a GimpImageMap of an operation without output
- make "region", "mode" and "gamma-hack" settable on a map that
already has a graph
- don't insert a useless "over" if the operation is a source op
- do the gamma-hack always on formats with alpha, so we don't lose
intermediate alpha results on source ops
- simplify graph connection a lot
- in GimpImageMap tool, don't recreate the map when reconfiguring
"region" and "gamma-hack"
So the adjustment's value is always what is shown (and can be entered
manually) in the widget. This way a GimpSpinScale will never change
its adjustment on focus-out, and not cause whatever unexpected updates
of its model and whatever is connected to it (like changing the
properties and thus unvalidating the caches of a Gegl graph).
Add "gboolean use_cache" to gimp_applicator_new(). Don't use a cache
anywhere but in GimpImageMap because it incrementally fills that cache
via the projection update. In gimp_drawable_merge_filter(), get that
cache and pass it to gimp_gegl_apply_cached_operation() which then
avoids doing the work twice for the already cached results. Win!
which does the same as gimp_gegl_apply_operation() but takes
additional arguments which are a cache buffer and a list of rectangles
that specify the already computed region in the cache buffer.
- connect double click on the list of channels
- actually allow channels to be picked
- repopulate the channel view when the image changes
This must have been a late night hack...
This maps threshold changes by moving the mouse more uniformly to the
growing/shrinking of the selected area, and the tools should work
perceptually anyway. Also, it makes things another 10 times as fast on
gamma-corrected drawables.
Don't special case on view_iface->model_is_tree and always run
gimp_container_view_remove_foreach(), also on the view's toplevel
container. Run gimp_container_view_clear_items() anyway on the
toplevel as an optimization, but with a big comment. This makes all
views (on list *and* tree models) behave the same way, and makes
view_iface->model_is_tree practically obsolete, will remove it later.
during the lifetime of the widget. Leaving that up to the GtkTreeView
was working for mysterious reasons even during destruction of the
widget. It's safer and cleaner this way.
Move the extraction graph from the foreground select tool there.
Enable the PDB wrapper again, using default values for now.
Some sytle cleanup in the foreground select tool.
which returns an error if there is no pattern for GIMP_FILL_PATTERN.
Use it instead of having the same code in 3 variants, and make error
handling consistent with bucket fill.
Allow for more tiles to update, making it possible to see more of the updated
image when tuning paremters / dragging items interactively. Lower frame rate
for more image content is better than 60fps for a small rectangle in the upper
left.
...(crop, rectangle, etc) in large image zoomed-to-fit
Default to GIMP_MOTION_MODE_COMPRESS in all tools, and override it to
GIMP_MOTION_MODE_EXACT if the tool really needs the exact path of
motion events. This greatly reduces the events processed by the
rectangle tools and makes them much more responsive.
In GimpProjection, use gimp_rectangle_intersect() instead of ad-hoc
CLAMP() constructs to sanitize rectangles, and don't let rectangles
enter the projection if they don't intersect with the projectable.
(apparently I have killed some check that did the same when porting
to cairo regions).
Pull freeing the update regions into gimp_projection_free_buffer()
because freeing the buffer definitely obsoletes them. Get rid of
the last x1, y1, x2, y2 and use x, y, w, h inatead.
The functions don't need to know about sample_merged, in fact they
used the boolean only to either use the passed image or drawable and
otherwise ran the same code. The sample_merged logic belongs into
their callers (and sometimes not even there).
Set the active display's viewport as priority rectangle on the image.
Update the rectangle in the default implementations of
GimpDisplayShell::scaled(), ::scrolled() and ::rotated(), which isn't
entirely correct yet but much better than before, and the only "bad"
thing that can happen with a bogus priority rectangle is that the
image is updated as out-of-viewport as before, just differently.
Remove member "running" it was always identical to "idle_id != 0".
Rename and reorder variables to make more sense. Simplify
gimp_projection_chunk_render_iteration() work area calculation.
This may or may not remove some logic that avoids drawing tiny update
regions, and may or may not improve things or make them worse. Will
add code that actually tile-aligns update areas later.
...(crop, rectangle, etc) in large image zoomed-to-fit
Introduce a hash of the last 16 used icons in GimpStatusbar, it was
loading icons at a very high frequency. Found by Massimo.
Add GIMP_DIRTY_ACTIVE_DRAWABLE to the warp tool's dirty mask, so it
correctly switches to the new active layer. Also remove
GIMP_DIRTY_IMAGE_STRUCTURE, I don't know why that was there in the
first place.
Add a combo that switches between "selection" and "entire layer".
Need to find a way to hide that thing when the setting makes no
difference. Also the combo is generally pretty much experimantal.
If the removed plug operated on the selection bounds, translate and
crop the GEGL op accordingly to get the same result. Also adapt to
new relative coordinates in some GEGL ops.
gimp_group_layer_update_size(): update the group layer's offset node
before reallocating the group's projection, or we might render the
group projection's buffer with the old offsets.
Always round grid spacings and offsets to integer precision when
using them for snapping and grid drawing. While we might *want* to
have subpixel precision grids, all the UI is pretending it to be
on pixel boundaries. Make that pretense an fact.
because that's what they are and what most menu labels in there says.
Keep the "Clouds" menu around for 3rd party plug-ins, not sure if it's
right to auto-map it to "Noise" automatically.
Foreground and background are GIMP concepts; the annotations on GEGL ops
should be about how the operation makes use of the meta-data; not where
it comes from in one particular application using GEGL.
old names:
"role", "foreground-color",
"role", "background-color",
new names:
"role", "color-primary",
"role", "color-secondary",
instead of passing N_()-strings; and remove gettext() calls on these
strings when using them. Reduces complexitx, and fixes double- and
untranslated strings. Also enables to treat properties of GIMP and
GEGL objects the same way, which was totally broken before.
gimp_gegl_mask_bounds(): when we succeed avoiding iterating a tile by
checking its upper-left and bottom-right, use the function's internal
meaning of x2, y2, which is the rightmost/bottommost selected pixel,
while the external meaning is the pixel right/below it.
Short: use "foo - 1" not "foo".
It makes little sense to keep them in one header and parse them with a
pile of perl, just to generate them in another header. Simply keep
them in a place everybody depends on.
and keep GIMP_ICON_TYPE_STOCK_ID as a deprecated alias. Change all
plug-ins accordingly and increase the pluginrc file version number so
it gets regenerated with "icon-name" instead of "stock-id".
Rename them and move them into folders, e.g.:
stock-foo-16.png -> 16/gimp-foo.png
This change only moves internal stuff around,
it's not visible on any API.
Add a utility function to wrap PDB compat nodes in gimp:cast-format
ops, so we can use ops that are now implemented in linear RGB for
plug-in compat procedures, which are all supposed to work on gamma
corrected RGB.
Which when enabled casts between linear and gamma-corrected data at
the operation's input and output. This is experimental stuff meant to
properly check ported gegl ops and prepare for plug-in removal.
In gimp_image_window_new(), place the window on the right
monitor manually if we are not in single-window-mode.
In gimp_image_window_switch_page(), make sure we don't use an
unrealized new window's monitor for updating the session info, because
the monitor of an unrealized window is always where the pointer is.
Change gimp_get_display_name() to also return the screen, and its
implementation in the GUI to return the initial monitor during
startup. Retrieve that information in app.c using a weird callback
construct and pass the monitor to file_open_from_command_line().
Half-related, add screen and monitor parameters to GimpDisplayShell
and use these initial values for calculating the canvas's initial
extents.
The image windows still don't position themselves correctly though
because we have no mechanism for that whatsoever just yet, but we now
at least pass the needed monitor information to the right objects.
Add a "monitor" parameter and return something reasonable, instead
of a useless resolution average of all the screen's monitors. Also
require a screen to be passed now.