- The "Healing Brush" paper URL is dead. It now leads to one of these
horrible parasitic websites which reuse domain names. And we for sure
don't want to promote this! I'm using instead the associated page on
our developer website. I just created this page and right now it's on
testing only. But this will be the URL for the main website.
- The URL for the foreground extraction paper is still valid, but from
my small research today when writing various algorithm' pages, I think
our own implementation diverged from this original paper (though it
may still have part of this original paper's algorithm; only a deeper
check of the code would tell).
See: https://testing.developer.gimp.org/core/algorithm/foreground-extraction/
Also this PDB procedure is called generically gimp_drawable_foreground_extract()
and it even has an argument to choose the algorithm (even though right
now, there is only a single choice, which is "Matting" algorithm, and
even there you can't choose which one; it's always Matting Global;
Matting Levin cannot be chosen for instance).
So anyway it is not a good idea to point to one specific algorithm,
and even less to leave an external URL (which may also disappear some
day) in API docs. So I am just getting rid of this paper title and
URL, and replace it with actually useful information, which is how to
set the trimap to represent foreground, background and uncertain
pixels (note: I notice that it would have been different with Matting
Levin where uncertain pixels must apparently be set transparent).
This last argument in libmypaint's mypaint_brush_stroke_to_2() is called
barrel_rotation. If you look at MyPaint's code (in particular file
gui/freehand.py), you see it is taken from GDK_AXIS_WHEEL of the input
event, which corresponds to our coords->wheel (there is this
long-standing question about the difference with GDK_AXIS_ROTATION
because as far as we know, this is probably the same value anyway; as
was explained to us by a Wacom developer long ago).
Unfortunately I can't test as we don't have any stylus with such barrel
rotation feature (and unfortunately this hardware feature is
discontinued and getting a stylus with this is extra-hard now), but that
should work. And at the very least, it does match with MyPaint's
implementation.
Our build files were relying 'sysroot' to find gexiv2.h but this is
not possible with Apple Clang om which sysroot points to macOS SDK.
So, exotic environments like Homebrew were failing. Let's fix this.
In ea8b9dc1, PROP_RADIUS was incorrectly used for the
view-zoom and view-rotation property IDs. This patch
removes the duplication and makes the IDs distinct.
* Anders Jonsson noticed a typo where the
'r' in "pressure" was left off in the Gain
parameter description
* Since 0.0 is an invalid value for the viewzoom
parameter in MyPaint, the cut off is adjusted
to be greater than 0, not greater than or
equal to 0.
* The default viewzoom value is set to 1.0f,
100%, rather than 0.0001, very zoomed out.
This patch ports our MyPaint code to use the
MyPaintSurface2 API, allowing us to support
version 2 MyPaint Brushes correctly.
The API update lets us take into account
the zoom factor and rotation of the canvas
when drawing. It also adds a "Gain" option
to the GUI in order to control the strength
of the input's pressure (tablet or mouse).
As a caveat, this patch does not yet
implement spectral/pigment blending.
The Smudge Tool gets accumulated buffers from its
history via g_list_nth_data (). However, this function can
return NULL if we go out of bounds. We did not check for
this before trying to use it as a GeglBuffer, which caused
crashes if we ran out of accumulated buffers (e.g. if we
were partially smudging off-canvas).
This patch adds NULL checks to prevent the crashes.
Resolves#13501
When painting with "Expand Layers" on, we call gimp_get_fill_params ()
to get the color to fill in the new area. However, if the user has set the
fill type to Pattern, the color is NULL. This caused a crash because we
immediately try to set the alpha channel of the color to 1.0 if the layer
has no transparency - and if the color is NULL, that's not possible.
This patch checks if we received a valid GeglColor before trying to
set its alpha channel.
Generated libgimp functions' arguments are normally tested through the
PDB, so that you get proper error messages when trying to call a
function with invalid arguments.
This is not true anymore for array arguments since the size argument is
not a PDB arg, only in the C function. Therefore I'm adding an
infrastructure asserting on invalid size, using the same PDB type
annotations as other args. It is important to assert valid input on
plug-in side (i.e. libgimp) so that the core doesn't make any assumption
on having received valid input when it has not.
Also changing size argument of gimppainttools PDB-generated functions to
proper gsize.
This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes#10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
...to path.
Changes the names of
gimp_vectors_* () API to
gimp_path[s]_* (). Renames related files
to [path] instead of [vectors], along with
relevant enums and functions.
This commit renames the GimpVectors
object to GimpPath in both app/core and
in libgimp. It also renames the files
to gimppath.[ch] and updates the relevant
build and translation files.
There are still outstanding gimp_vectors_* ()
functions on the app side that need to be renamed
in a subsequent commit.
I'm a bit unsure about the GimpMyBrushCore which doesn't have much
indication on which color space we are working in, but the new code
should not be worse than the old one (if wrong, color-wise, it should be
the same wrong as before).
I also changed a bit the new color serialization by adding a (color …)
symbol framing the contents, for cases where we don't have a specific
property name, e.g. for the color history list stored in colorrc, unlike
for GimpConfig GeglColor properties.
While doing this, I moved GeglColor property deserialization code into
gimp_scanner_parse_color() which is now able to recognize both older
(color-rgb|rgba|hsv|hsva with no color space) and newer serialization
formats ("color", color model agnostic and space aware).
I still see some limitations in GimpGradient, and in particular, they are still
always stored as RGB in GGR files. It would be nice if we could store the actual
color format. This way, if someone chooses a gradient stop as Lab or CMYK color,
that's what the gradient file would keep track of. But also even storing the
space of a color (instead of storing/loading always in sRGB, even though this
may still work fine as we store unbounded double values). This might warrant for
a v2 of GGR file format.
This commit also fixes loading of SVG gradient which was apparently broken
regarding hexadecimal color parsing.
Finally I improve gegl_color_set_alpha() by adding an alpha channel when the
initial format had none.
- app: gimp_context_get_(foreground|background)() are now returning a GeglColor.
- libgimp: PDB functions named similarly in libgimp are returning a newly
allocated GeglColor too.
- A few other PDB functions (the ones using these functions) were updated and
their signature changed to use GeglColor too, when relevant. Plug-ins which
use any of the changed libgimp functions were fixed.
- GimpContext: signals "(foreground|background)-changed" are now passing a
GeglColor.
- libgimpconfig: new macro GIMP_CONFIG_PROP_COLOR using gegl_param_spec_color().
- GimpContext: properties "foreground" and "background" are now GeglParamColor
properties.
- app: All code interacting with GimpContext objects were updated to receive a
GeglColor (that they may still convert, or no, to GimpRGB for now).
- app: gimp_prop_gegl_color_button_new() was added as an alternative to
gimp_prop_color_button_new() when the property is a GeglParamColor. Eventually
the former should replace completely the latter.
- libgimpwidgets: gimp_prop_color_area_new() now works on GeglParamColor
properties only.
- libgimp: gimp_procedure_dialog_get_widget() will generate a GimpColorArea for
GeglTypeParamColor arguments.
These are not generic undo function, but specific to the resize case (and even
more particularly when calling the GimpItem's resize() class method).
Also the variable was wrongly named no_undo when it actually was meant for the
opposite meaning, i.e. when we want to push an undo for a resize() call. This
made the call harder to understand. Furthermore the usage of double negation did
not help with understanding the code.
This is a fixup commit to MR !961, fixing a particular commit 5c2373a125 saying
that when canceling painting with layer expansion, strokes outside of the layer
remain visible.
Also added option in Edit->Preferences->"Tool Options"->"Paint Options
Shared Between Tools" that decides weather the options should be shared
between different tools.
Canceling a paint stroke restores the layer and mask (if present) to the
original size if they were expanded during the stroke. The part of
stroke that is outside the layer remains visible though.
In ink tool, if last_blobs is empty, the copy of blobs present in
last_blobs and blobs_to_render was same. Due to this, when layer
boundary is expanded, we move same blobs twice. Due to this a straight
line was drawn when starting painting from outside layer boundary. Fixed
the issue by storing a duplicate version in blobs_to_render. Updated
free part accordingly.
In layer expansion if user is trying to draw outside the layer boundary
with expand option turned on but the "Lock position and size" enabled,
the lock square will be blinked. If user is painting on layer mask, the
corresponding layer's lock will be blinked. It will be blinked only
once per stroke.
When resizing drawable for dynamic layers, the resize drawable function
would push Modified Layer/Channel item to undo stack. Initially, I was
checking if the drawable is being painted upon and used it to disable
the undo, but this when using resizing layers with layer mask, even if
mask is being painted upon, we still want to resize the main layer and
vice versa. But the main layer is not being painted upon so it would
push the undo to stack. To prevent this, I was using
gimp_drawable_paint_start before resizing, but this method is very
inefficient, as this function duplicates buffers. So added a new member
to drawable->private that will store weather to push undo or not.
Added option to tool settings that will decide how newly created parts
of layer and layer mask should be filled. For layer, same options are
provided as present in "Set Layer Boundary Size" dialog. For layer mask,
first two options from "Add a Mask to the Layer" i.e. "White" and
"Black" are added.
This commit changes gimp_channel_resize function to actually use the
passed fill type instead of using hardcoded GIMP_FILL_TRANSPARENT.
Hardcoding this value if required should be done in function calling
this function (which is already the case with all the instances already
present afaik).
Modified gimp_gegl_buffer_resize function to add three new parameters,
pattern, pattern_offset_x and pattern_offset_y. If pattern is not NULL,
then we set the pattern of buffet to this value. Like in
gimp_gegl_buffer_resize function, this logic is mostly copied from
gimp_drawable_fill_buffer function with minor changes.
This function returns resized version of the input buffer. It also takes
in a color argument. The layer background will be filled with this
color. Fill background logic is similar to gimp_drawable_fill_buffer.
The lock in the layers tab only sets lock for the actual layer and not
for its mask, so also check the lock on the actual layer and not just on
the mask when editing layer mask.
Everytime the layer expands, if the undo extents are empty, then make
them non zero. If the undo extents are zero, then user will not be able
to undo the expansion of the layer. This is perticularly required by
MyPaintBrush as just clicking the image without any motion does not draw
anything, but expands layer if required.
This function returns TRUE if the drawable is expanded. Otherwise, it
will return FALSE. This removes the need to check width and height of
the drawable to infer the same.
When painting the layers with a layer mask, if the layer need to be
expanded, the layer mask is also expanded with it. The same is done even
if layer mask is being painted upon.
Undo works with these layers by adding resizing of both the layer and
mask to the undo group if the layer is resized during painting.
Now layers will expand when trying to draw beyond layer borders with ink tool.
Tool options similar to paint tools have been added (expand_use and
expand_amount).
When painting with "Expand Layers" option turned on but "show all"
turned off, layer will not expand beyond image borders.
Layer will not expand if "Lock size and postion" is turned on.
Created a separate function gimp_paint_core_expand_drawable that handles
layer expansion while painting. The gimp_brush_core_get_buffer function
now uses this function to expand drawable. It has been separated so that
it can be reused for ink tool.