Brush blend modes and erase/restore (#1261)

* Made blit node numerically stable.

* Added blend mode parameter to brush strokes.

* Fixed difference blend mode.

* Added erase/restore blend modes.

* Added blend mode and draw mode widgets.

* Added comment explaining the ImageFrame.transform.

* Initial blit/blend version.

* Working version of erase/restore.

* Improved inlining for blend functions.

* Dsiable the blend mode selector in erase/draw mode.

* Fixed incorrect bounds calculation.

* Use factor instead of percentage for opacity

* Rearrange options bar widgets

* Tidy up blend modes

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Orson Peters
2023-06-02 21:59:55 +02:00
committed by Keavon Chambers
parent 4e1bfddcd8
commit 5558deba5e
13 changed files with 397 additions and 153 deletions

View File

@@ -279,6 +279,17 @@ fn blend_image<_P: Alpha + Pixel + Debug, MapFn, Frame: Sample<Pixel = _P> + Tra
) -> Background
where
MapFn: for<'any_input> Node<'any_input, (_P, _P), Output = _P>,
{
blend_image_closure(foreground, background, |a, b| map_fn.eval((a, b)))
}
pub fn blend_image_closure<_P: Alpha + Pixel + Debug, MapFn, Frame: Sample<Pixel = _P> + Transform, Background: RasterMut<Pixel = _P> + Transform + Sample<Pixel = _P>>(
foreground: Frame,
mut background: Background,
map_fn: MapFn,
) -> Background
where
MapFn: Fn(_P, _P) -> _P,
{
let background_size = DVec2::new(background.width() as f64, background.height() as f64);
// Transforms a point from the background image to the forground image
@@ -299,7 +310,7 @@ where
if let Some(src_pixel) = foreground.sample(fg_point, area) {
if let Some(dst_pixel) = background.get_pixel_mut(x, y) {
*dst_pixel = map_fn.eval((src_pixel, *dst_pixel));
*dst_pixel = map_fn(src_pixel, *dst_pixel);
}
}
}