This commit adds support for moving together an intersecting pair
of guides using the Move tool, by dragging the guides at their
point of intersection. This is useful when the guides are used to
mark a point, rather than a pair of lines (e.g., as is the case for
the mandala symmetry guides, which mark the symmetry's point of
origin).
Add gimp_image_pick_guides(), which can return a set of guides,
rather than a single guide. The API allows an arbitrary set of
guides to be returned, but, in practice, at most two intersecting
guides are returned, as per the above.
In GimpMoveTool and GimpGuideTool, add support for moving multiple
guides together, and, in GimpMoveTool, use gimp_image_pick_guides()
to potentially pick multiple guides.
...to the Configure Keyboard Shortcuts dialog
Add the button, based on an old patch from Sven Neumann, and make the
buttons in the keyboard shortcuts and input devices dialogs look and
behave the same.
In gimp_gegl_apply_[cached_]operation(), add support for output
buffers whose extent's top-left corner is not (0, 0). This is
needed by the previous commit.
In GimpSourceCore, when applying a symmetry transform to the source
content, combine the transform op with translation to the paint-
buffer coordinates, so that subclasses (namely, GimpClone and
GimpHeal) can use the op to apply the transformation directly from
the source buffer to the paint buffer in a single step. This is
both more efficient, and avoids incorrect symmetry transforms when
the paint buffer is cropped to the bounds of the drawable.
Remove the GimpSymmetry::get_operation() virtual function, and
instead implement gimp_symmetry_get_operation() by returning an
appropriate gegl:transform node based on the matrix returned by
gimp_symmetry_get_matrix(). The returned node is owned by the
caller; since we no longer use the node's identity for caching
trnasformed brushes, we no longer cache the transformation nodes.
Remove the function's paint_width and paint_height parameters, and
instead return a transformation that should be applied at the
center of the brush. This simplifies the application of the
transformation in the Clone and Heal tools, as per the next commit.
Remove the implementation of GimpSymmetry::get_operation() from all
its subclasses, which should now only implement
GimpSymmetry::get_transform().
Add GimpPaintbrush::get_color_history_color() virtual function,
which should return the color to be added to the color history upon
painting, if any. The default implementation returns the
foreground color, when not using a pixmap brush or color-from-
gradient.
Override this function in GimpEraser, to return the background
color when the affected drawable has no alpha channel, instead of
overriding GimpPaintCore::paint() for this purpose. This avoids
erroneously adding both the background and foreground colors to the
history.
As suggested by LRN, change gimp_sigfatal_handler() on Windows to
dstinguish between fatal and non-fatal exceptions so we don't abort on
each minor hickup.
Further improvements should load screenshots in a thread, especially
since we are loading from a URL taken from metadata, so it makes the GUI
non-responsive for a bit too long. But this is a first working version
for now.
This first version of this API only returns the default screenshot.
Further improvements should allow to return all the available extension
screenshots.
Use GtkGrid instead of GtkBox (docs says GtkBox will eventually go
away). Also remove this horrible frame in a frame (though GUI is still
not perfect yet). Finally fix the "extension" object data.
In GimpClone and GimpHeal, use gimp_gegl_apply_operation(), instead
of gegl_node_process(), to apply the symmetry transform, which both
performs chunking and avoids aliasing problems.
...-last positioned- monitor
Use gimp_dialog_factory_position_dialog() in GimpColormapEditor and
GimpPaletteEditor so the color dialogs appear where they were before.
which is the logic that used to be in color_area_color_clicked()
factored out to proper API. It makes sure that a dialog that was
visible before (and was only hidden not destroyed) appears at the same
point on the same monitor as before. See issue #1093.
In GimpPaintbrush, factor out the code responsible for determining
the current dab's paint parameters and content to a new
GimpPaintbrush::get_paint_params() virtual function.
Derive GimpEraser from GimpPaintbrush, instead of directly from
GimpBrushCore, implementing get_paint_params() appropriately.
This allows GimpEraser to reuse the paint-buffer content across
dabs, improving performance.
Use gimp_symmetry_get_transform() instead of
gimp_symmetry_get_operation() throughout the paint code, where
possible. This allows us to combine the symmetry transform with
the ordinary brush transform, simplifying the code, improving
performance, and avoiding multiple resamplings. This also fixes
the paint-buffer size when using mandala symmetry with non-round
brushes, avoiding artifacts.
Add a GimpSymmetry::get_transform() virtual function, and a
corresponding gimp_symmetry_get_transform() function, which return
the brush transform corresponding to a given symmetry stroke in
terms of the rotation angle and reflection flag (in contrast to
gimp_symmetry_get_operation() which returns the same transforation
in terms of a GeglNode). This would allow us to simplify, fix, and
improve the painting-code perofmrnace in the next commits.
Implement GimpSymmetry::get_transform() in its various subclasses.
...in a color image/colour image
gimp_edit_paste_get_layer(): only use the pasted-to drawable's format
with alpha if this is really a floating paste, use the image's layer
format with alpha for "as new layer" cases.
...when overwriting existing text
gimp_text_tool_enter_text(): when replacing a selection, use the text
properties from the text style editor for the entered text, otherwise
the style of the text before the selection will be used.
Extend last commit to also disregard the composite space when the
layer mode is trivial and only the source region is included in
compositing, since, in this case, the source color is unmodified.
In gimp_layer_mode_get_format(), disregard the requested composite
space when selecting the format, if the input layer mode is alpha-
only, and the requested composite mode is not UNION, since, in this
case, the layer mode doesn't combine the layer/backdrop colors, and
rather only modifies the alpha of one of them. This allows us to
use the preferred format, avoiding gamma conversion.
This particularly improves the performance of the Eraser tool in
perceptual images.
In gimp_drawable_transform_get_effective_clip(), always return
RESIZE_CLIP when the input drawable is the image mask, since the
presence of a selection doesn't matter in this case. This avoids
erroneously displaying a result-size warning when transforming the
selection using any of the selection tools.
Initialize GimpBacktrace earlier on in the startup process, so that
the Windows backend installs the thread-name exception handler
early enough to catch threads created before app_run() (in
particular, the GEGL worker threads).
In GimpPaintbrush, avoid refilling the paint buffer at each dab if
the paint color/pixmap hasn't changed, as gimp_paint_core_paste()
no longer modifies the buffer since the commit before last.
Additionally, fix color-from-gradient dynamics when the image has a
profile.
In GimpBrushCore, replace the private
gimp_brush_core_transform_pixmap() function with a public
gimp_brush_core_get_brush_pixmap() function, which, similarly to
gimp_brush_core_get_brush_mask(), returns the transformed brush
pixmap, and can be used by subclasses.
We now have enough machinery in gimppaintcore-loops to avoid
modifying the paint buffer in gimp_paint_core_paste() in the no-
applicator case, by using the same set of algorithms as
gimp_paint_core_replace(). Other than reducing the number of
different code paths we have, this is both more efficient, and
allows us to reuse the paint buffer across dabs, as done in the
following commits.
Implement gimp_paint_core_replace() in terms of
gimp_paint_core_paste(). We keep the two functions separate, since
their implementation is still differnet when using an applicator.
Suppress the paint-buffer-modifying algorithms in
gimppaintcore-loops, but keep them around; using the same logic for
normal painting as we use for REPLACE painting is possible due to
the fact that all our current non-REPLACE modes treat alpha values
and mask values interchangeably. In the future we might have modes
that distinguish between alpha and mask values, requiring the old
algorithms.
In gimp_brush_core_get_paint_buffer(), when allocating a new paint
buffer, clear the old buffer *before* allocating the new one, to
reduce the amount of simultaneously allocated memory.
Add a tile-alloc-total varaible to the dashboard's memory and misc
groups, showing the total amount of memory used by the tile
allocator (see commit
gegl@137e66e45138e8316f6403e53e8aa9a02ad523e7.)