app: in gimp_paint_core_replace(), improve applicator path
In the applicator path of gimp_paint_core_replace(), actually use
the paint-core's applicator, instead of using
gimp_drawable_replace_buffer(). This improves speed, consolidates
code, and fixes some cases in which the latter is broken.
Furthermore, when using CONSTANT paint application-mode, use the
paint-core's undo_buffer as the compositing source, rather than the
drawable buffer, which is the correct behavior.
(cherry picked from commit 3451ffb62c
)
This commit is contained in:
@ -1006,59 +1006,126 @@ gimp_paint_core_replace (GimpPaintCore *core,
|
|||||||
if (core->applicator)
|
if (core->applicator)
|
||||||
{
|
{
|
||||||
GeglRectangle mask_rect;
|
GeglRectangle mask_rect;
|
||||||
GeglBuffer *paint_mask_buffer;
|
GeglBuffer *mask_buffer;
|
||||||
|
|
||||||
if (mode == GIMP_PAINT_CONSTANT &&
|
|
||||||
|
|
||||||
|
/* If the mode is CONSTANT:
|
||||||
|
* combine the paint mask to the canvas buffer, and use it as the mask
|
||||||
|
* buffer
|
||||||
|
*/
|
||||||
|
if (mode == GIMP_PAINT_CONSTANT)
|
||||||
|
{
|
||||||
/* Some tools (ink) paint the mask to paint_core->canvas_buffer
|
/* Some tools (ink) paint the mask to paint_core->canvas_buffer
|
||||||
* directly. Don't need to copy it in this case.
|
* directly. Don't need to copy it in this case.
|
||||||
*/
|
*/
|
||||||
paint_mask != NULL)
|
if (paint_mask != NULL)
|
||||||
{
|
{
|
||||||
paint_mask_buffer =
|
GeglBuffer *paint_mask_buffer =
|
||||||
gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);
|
gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);
|
||||||
|
|
||||||
/* combine the paint mask and the canvas buffer */
|
gimp_gegl_combine_mask_weird (paint_mask_buffer,
|
||||||
gimp_gegl_combine_mask_weird (paint_mask_buffer,
|
GEGL_RECTANGLE (paint_mask_offset_x,
|
||||||
GEGL_RECTANGLE (paint_mask_offset_x,
|
paint_mask_offset_y,
|
||||||
paint_mask_offset_y,
|
width, height),
|
||||||
width, height),
|
core->canvas_buffer,
|
||||||
core->canvas_buffer,
|
GEGL_RECTANGLE (core->paint_buffer_x,
|
||||||
GEGL_RECTANGLE (core->paint_buffer_x,
|
core->paint_buffer_y,
|
||||||
core->paint_buffer_y,
|
width, height),
|
||||||
width, height),
|
paint_opacity,
|
||||||
paint_opacity,
|
GIMP_IS_AIRBRUSH (core));
|
||||||
GIMP_IS_AIRBRUSH (core));
|
|
||||||
|
|
||||||
g_object_unref (paint_mask_buffer);
|
g_object_unref (paint_mask_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize the maskPR from the canvas buffer */
|
mask_buffer = g_object_ref (core->canvas_buffer);
|
||||||
paint_mask_buffer = g_object_ref (core->canvas_buffer);
|
mask_rect = *GEGL_RECTANGLE (core->paint_buffer_x,
|
||||||
|
core->paint_buffer_y,
|
||||||
|
width, height);
|
||||||
|
|
||||||
mask_rect = *GEGL_RECTANGLE (core->paint_buffer_x,
|
gimp_applicator_set_src_buffer (core->applicator,
|
||||||
core->paint_buffer_y,
|
core->undo_buffer);
|
||||||
width, height);
|
|
||||||
}
|
}
|
||||||
|
/* Otherwise:
|
||||||
|
* use the paint mask as the mask buffer directly
|
||||||
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
paint_mask_buffer =
|
mask_buffer =
|
||||||
gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);
|
gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);
|
||||||
|
mask_rect = *GEGL_RECTANGLE (paint_mask_offset_x,
|
||||||
|
paint_mask_offset_y,
|
||||||
|
width, height);
|
||||||
|
|
||||||
mask_rect = *GEGL_RECTANGLE (paint_mask_offset_x,
|
gimp_applicator_set_src_buffer (core->applicator,
|
||||||
paint_mask_offset_y,
|
gimp_drawable_get_buffer (drawable));
|
||||||
width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply the paint area to the image */
|
if (core->mask_buffer)
|
||||||
gimp_drawable_replace_buffer (drawable, core->paint_buffer,
|
{
|
||||||
GEGL_RECTANGLE (0, 0, width, height),
|
GeglBuffer *combined_mask_buffer;
|
||||||
FALSE, NULL,
|
GeglRectangle combined_mask_rect;
|
||||||
image_opacity,
|
GeglRectangle aligned_combined_mask_rect;
|
||||||
paint_mask_buffer, &mask_rect,
|
|
||||||
core->paint_buffer_x,
|
|
||||||
core->paint_buffer_y);
|
|
||||||
|
|
||||||
g_object_unref (paint_mask_buffer);
|
combined_mask_rect = *GEGL_RECTANGLE (core->paint_buffer_x,
|
||||||
|
core->paint_buffer_y,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
gimp_gegl_rectangle_align_to_tile_grid (
|
||||||
|
&aligned_combined_mask_rect, &combined_mask_rect,
|
||||||
|
gimp_drawable_get_buffer (drawable));
|
||||||
|
|
||||||
|
combined_mask_buffer = gegl_buffer_new (&aligned_combined_mask_rect,
|
||||||
|
babl_format ("Y float"));
|
||||||
|
|
||||||
|
gegl_buffer_copy (core->mask_buffer,
|
||||||
|
GEGL_RECTANGLE (aligned_combined_mask_rect.x -
|
||||||
|
core->mask_x_offset,
|
||||||
|
aligned_combined_mask_rect.y -
|
||||||
|
core->mask_y_offset,
|
||||||
|
aligned_combined_mask_rect.width,
|
||||||
|
aligned_combined_mask_rect.height),
|
||||||
|
GEGL_ABYSS_NONE,
|
||||||
|
combined_mask_buffer, &aligned_combined_mask_rect);
|
||||||
|
|
||||||
|
gimp_gegl_combine_mask (mask_buffer, &mask_rect,
|
||||||
|
combined_mask_buffer, &combined_mask_rect,
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
g_object_unref (mask_buffer);
|
||||||
|
|
||||||
|
mask_buffer = combined_mask_buffer;
|
||||||
|
mask_rect = combined_mask_rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
gimp_applicator_set_mask_buffer (core->applicator, mask_buffer);
|
||||||
|
gimp_applicator_set_mask_offset (core->applicator,
|
||||||
|
core->paint_buffer_x - mask_rect.x,
|
||||||
|
core->paint_buffer_y - mask_rect.y);
|
||||||
|
|
||||||
|
gimp_applicator_set_apply_buffer (core->applicator,
|
||||||
|
core->paint_buffer);
|
||||||
|
gimp_applicator_set_apply_offset (core->applicator,
|
||||||
|
core->paint_buffer_x,
|
||||||
|
core->paint_buffer_y);
|
||||||
|
|
||||||
|
gimp_applicator_set_opacity (core->applicator, image_opacity);
|
||||||
|
gimp_applicator_set_mode (core->applicator, GIMP_LAYER_MODE_REPLACE,
|
||||||
|
GIMP_LAYER_COLOR_SPACE_AUTO,
|
||||||
|
GIMP_LAYER_COLOR_SPACE_AUTO,
|
||||||
|
gimp_layer_mode_get_paint_composite_mode (
|
||||||
|
GIMP_LAYER_MODE_REPLACE));
|
||||||
|
|
||||||
|
/* apply the paint area to the image */
|
||||||
|
gimp_applicator_blit (core->applicator,
|
||||||
|
GEGL_RECTANGLE (core->paint_buffer_x,
|
||||||
|
core->paint_buffer_y,
|
||||||
|
width, height));
|
||||||
|
|
||||||
|
gimp_applicator_set_mask_buffer (core->applicator, core->mask_buffer);
|
||||||
|
gimp_applicator_set_mask_offset (core->applicator,
|
||||||
|
core->mask_x_offset,
|
||||||
|
core->mask_y_offset);
|
||||||
|
|
||||||
|
g_object_unref (mask_buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user