app: don't modify paint buffer when pasting to canvas

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.
This commit is contained in:
Ell 2019-05-15 09:44:41 -04:00
parent 669bd398a7
commit f24bca5156
2 changed files with 14 additions and 76 deletions

View File

@ -1232,7 +1232,7 @@ struct CombinePaintMaskToCanvasBufferToPaintBufAlpha : Base
}
};
static AlgorithmDispatch<
static SuppressedAlgorithmDispatch<
CombinePaintMaskToCanvasBufferToPaintBufAlpha,
GIMP_PAINT_CORE_LOOPS_ALGORITHM_COMBINE_PAINT_MASK_TO_CANVAS_BUFFER |
GIMP_PAINT_CORE_LOOPS_ALGORITHM_CANVAS_BUFFER_TO_PAINT_BUF_ALPHA,
@ -1405,7 +1405,7 @@ struct CanvasBufferToPaintBufAlpha : Base
}
};
static AlgorithmDispatch<
static SuppressedAlgorithmDispatch<
CanvasBufferToPaintBufAlpha,
GIMP_PAINT_CORE_LOOPS_ALGORITHM_CANVAS_BUFFER_TO_PAINT_BUF_ALPHA,
decltype (dispatch_paint_buf),
@ -1477,7 +1477,7 @@ struct PaintMaskToPaintBufAlpha : Base
}
};
static AlgorithmDispatch<
static SuppressedAlgorithmDispatch<
PaintMaskToPaintBufAlpha,
GIMP_PAINT_CORE_LOOPS_ALGORITHM_PAINT_MASK_TO_PAINT_BUF_ALPHA,
decltype (dispatch_paint_buf),

View File

@ -886,7 +886,7 @@ gimp_paint_core_paste (GimpPaintCore *core,
}
/* Write canvas_buffer to paint_buf */
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_CANVAS_BUFFER_TO_PAINT_BUF_ALPHA;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_CANVAS_BUFFER_TO_COMP_MASK;
/* undo buf -> paint_buf -> dest_buffer */
params.src_buffer = core->undo_buffer;
@ -901,7 +901,7 @@ gimp_paint_core_paste (GimpPaintCore *core,
params.paint_mask_offset_y = paint_mask_offset_y;
params.paint_opacity = paint_opacity;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_PAINT_MASK_TO_PAINT_BUF_ALPHA;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_PAINT_MASK_TO_COMP_MASK;
/* dest_buffer -> paint_buf -> dest_buffer */
params.src_buffer = params.dest_buffer;
@ -1108,77 +1108,15 @@ gimp_paint_core_replace (GimpPaintCore *core,
}
else
{
GimpPaintCoreLoopsParams params = {};
GimpPaintCoreLoopsAlgorithm algorithms = GIMP_PAINT_CORE_LOOPS_ALGORITHM_NONE;
params.paint_buf = gimp_gegl_buffer_get_temp_buf (core->paint_buffer);
params.paint_buf_offset_x = core->paint_buffer_x;
params.paint_buf_offset_y = core->paint_buffer_y;
if (! params.paint_buf)
return;
params.dest_buffer = gimp_drawable_get_buffer (drawable);
if (mode == GIMP_PAINT_CONSTANT)
{
params.canvas_buffer = core->canvas_buffer;
/* This step is skipped by the ink tool, which writes
* directly to canvas_buffer
*/
if (paint_mask != NULL)
{
/* Mix paint mask and canvas_buffer */
params.paint_mask = paint_mask;
params.paint_mask_offset_x = paint_mask_offset_x;
params.paint_mask_offset_y = paint_mask_offset_y;
params.stipple = GIMP_IS_AIRBRUSH (core);
params.paint_opacity = paint_opacity;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_COMBINE_PAINT_MASK_TO_CANVAS_BUFFER;
}
/* Write canvas_buffer to the compositing mask */
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_CANVAS_BUFFER_TO_COMP_MASK;
/* undo buf -> paint_buf -> dest_buffer */
params.src_buffer = core->undo_buffer;
}
else
{
g_return_if_fail (paint_mask);
/* Write paint_mask to the compositing mask, does not modify
* canvas_buffer
*/
params.paint_mask = paint_mask;
params.paint_mask_offset_x = paint_mask_offset_x;
params.paint_mask_offset_y = paint_mask_offset_y;
params.paint_opacity = paint_opacity;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_PAINT_MASK_TO_COMP_MASK;
/* dest_buffer -> paint_buf -> dest_buffer */
params.src_buffer = params.dest_buffer;
}
params.mask_buffer = core->mask_buffer;
params.mask_offset_x = core->mask_x_offset;
params.mask_offset_y = core->mask_y_offset;
params.image_opacity = image_opacity;
params.paint_mode = GIMP_LAYER_MODE_REPLACE;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_DO_LAYER_BLEND;
if (affect != GIMP_COMPONENT_MASK_ALL)
{
params.affect = affect;
algorithms |= GIMP_PAINT_CORE_LOOPS_ALGORITHM_MASK_COMPONENTS;
}
gimp_paint_core_loops_process (&params, algorithms);
gimp_paint_core_paste (core, paint_mask,
paint_mask_offset_x,
paint_mask_offset_y,
drawable,
paint_opacity,
image_opacity,
GIMP_LAYER_MODE_REPLACE,
mode);
return;
}
/* Update the undo extents */