diff --git a/sparse_strips/vello_bench/src/fine/image.rs b/sparse_strips/vello_bench/src/fine/image.rs index fde9802c7..779417c47 100644 --- a/sparse_strips/vello_bench/src/fine/image.rs +++ b/sparse_strips/vello_bench/src/fine/image.rs @@ -11,6 +11,7 @@ use vello_common::kurbo::Affine; use vello_common::paint::{Image, ImageSource}; use vello_common::peniko; use vello_common::peniko::ImageQuality; +use vello_common::peniko::ImageSampler; use vello_common::pixmap::Pixmap; use vello_cpu::fine::{Fine, FineKernel}; @@ -148,10 +149,13 @@ fn get_colr_image(extend: peniko::Extend, quality: ImageQuality) -> Image { let pixmap = Pixmap::from_png(&data[..]).unwrap(); Image { - source: ImageSource::Pixmap(Arc::new(pixmap)), - x_extend: extend, - y_extend: extend, - quality, + image: ImageSource::Pixmap(Arc::new(pixmap)), + sampler: ImageSampler { + x_extend: extend, + y_extend: extend, + quality, + alpha: 1.0, + }, } } @@ -160,10 +164,13 @@ fn get_small_image(extend: peniko::Extend, quality: ImageQuality) -> Image { let pixmap = Pixmap::from_png(&data[..]).unwrap(); Image { - source: ImageSource::Pixmap(Arc::new(pixmap)), - x_extend: extend, - y_extend: extend, - quality, + image: ImageSource::Pixmap(Arc::new(pixmap)), + sampler: ImageSampler { + x_extend: extend, + y_extend: extend, + quality, + alpha: 1.0, + }, } } diff --git a/sparse_strips/vello_common/src/encode.rs b/sparse_strips/vello_common/src/encode.rs index 4720e2e1d..453e176c8 100644 --- a/sparse_strips/vello_common/src/encode.rs +++ b/sparse_strips/vello_common/src/encode.rs @@ -20,7 +20,8 @@ use core::hash::{Hash, Hasher}; use fearless_simd::{Simd, SimdBase, SimdFloat, f32x4, f32x16}; use peniko::color::cache_key::{BitEq, BitHash, CacheKey}; use peniko::{ - InterpolationAlphaSpace, LinearGradientPosition, RadialGradientPosition, SweepGradientPosition, + ImageSampler, InterpolationAlphaSpace, LinearGradientPosition, RadialGradientPosition, + SweepGradientPosition, }; use smallvec::ToSmallVec; // So we can just use `OnceCell` regardless of which feature is activated. @@ -430,7 +431,12 @@ impl EncodeExt for Image { fn encode_into(&self, paints: &mut Vec, transform: Affine) -> Paint { let idx = paints.len(); - let mut quality = self.quality; + let mut sampler = self.sampler; + + if sampler.alpha != 1.0 { + // If the sampler alpha is not 1.0, we need to force alpha compositing. + unimplemented!("Applying opacity to image commands"); + } let c = transform.as_coeffs(); @@ -441,9 +447,9 @@ impl EncodeExt for Image { && (c[3] as f32 - 1.0).is_nearly_zero() && ((c[4] - c[4].floor()) as f32).is_nearly_zero() && ((c[5] - c[5].floor()) as f32).is_nearly_zero() - && quality == ImageQuality::Medium + && sampler.quality == ImageQuality::Medium { - quality = ImageQuality::Low; + sampler.quality = ImageQuality::Low; } // Similarly to gradients, apply a 0.5 offset so we sample at the center of @@ -452,12 +458,11 @@ impl EncodeExt for Image { let (x_advance, y_advance) = x_y_advances(&transform); - let encoded = match &self.source { + let encoded = match &self.image { ImageSource::Pixmap(pixmap) => { EncodedImage { source: ImageSource::Pixmap(pixmap.clone()), - extends: (self.x_extend, self.y_extend), - quality, + sampler, // While we could optimize RGB8 images, it's probably not worth the trouble. has_opacities: true, transform, @@ -467,8 +472,7 @@ impl EncodeExt for Image { } ImageSource::OpaqueId(image) => EncodedImage { source: ImageSource::OpaqueId(*image), - extends: (self.x_extend, self.y_extend), - quality: self.quality, + sampler, has_opacities: true, transform, x_advance, @@ -510,10 +514,8 @@ impl From for EncodedPaint { pub struct EncodedImage { /// The underlying pixmap of the image. pub source: ImageSource, - /// The extends in the horizontal and vertical direction. - pub extends: (Extend, Extend), - /// The rendering quality of the image. - pub quality: ImageQuality, + /// Sampler + pub sampler: ImageSampler, /// Whether the image has opacities. pub has_opacities: bool, /// A transform to apply to the image. diff --git a/sparse_strips/vello_common/src/paint.rs b/sparse_strips/vello_common/src/paint.rs index 1c3e00bd0..4f4c0ed09 100644 --- a/sparse_strips/vello_common/src/paint.rs +++ b/sparse_strips/vello_common/src/paint.rs @@ -6,7 +6,7 @@ use crate::pixmap::Pixmap; use alloc::sync::Arc; use peniko::{ - Gradient, ImageQuality, ImageSampler, + Gradient, color::{AlphaColor, PremulRgba8, Srgb}, }; @@ -77,21 +77,8 @@ pub enum ImageSource { OpaqueId(ImageId), } -/// An image. -#[derive(Debug, Clone)] -pub struct Image { - /// The underlying pixmap of the image. - pub source: ImageSource, - /// Extend mode in the horizontal direction. - pub x_extend: peniko::Extend, - /// Extend mode in the vertical direction. - pub y_extend: peniko::Extend, - /// Hint for desired rendering quality. - pub quality: ImageQuality, -} - -impl Image { - /// Convert a [`peniko::ImageBrush`] to an [`Image`]. +impl ImageSource { + /// Convert a [`peniko::ImageData`] to an [`ImageSource`]. /// /// This is a somewhat lossy conversion, as the image data data is transformed to /// [premultiplied RGBA8](`PremulRgba8`). @@ -99,62 +86,59 @@ impl Image { /// # Panics /// /// This panics if `image` has a `width` or `height` greater than `u16::MAX`. - pub fn from_peniko_image(brush: &peniko::ImageBrush) -> Self { + pub fn from_peniko_image_data(image: &peniko::ImageData) -> Self { // TODO: how do we deal with `peniko::ImageFormat` growing? See also // . - if brush.image.format != peniko::ImageFormat::Rgba8 { - unimplemented!("Unsupported image format: {:?}", brush.image.format); - } - if brush.image.alpha_type != peniko::ImageAlphaType::Alpha { - unimplemented!("Unsupported image alpha type: {:?}", brush.image.alpha_type); - } + let do_alpha_multiply = image.alpha_type != peniko::ImageAlphaType::AlphaPremultiplied; assert!( - brush.image.width <= u16::MAX as u32 && brush.image.height <= u16::MAX as u32, + image.width <= u16::MAX as u32 && image.height <= u16::MAX as u32, "The image is too big. Its width and height can be no larger than {} pixels.", u16::MAX, ); - let width = brush.image.width.try_into().unwrap(); - let height = brush.image.height.try_into().unwrap(); - let ImageSampler { - x_extend, - y_extend, - quality, - alpha: global_alpha, - } = brush.sampler; - - #[expect(clippy::cast_possible_truncation, reason = "deliberate quantization")] - let global_alpha = u16::from((global_alpha * 255. + 0.5) as u8); + let width = image.width.try_into().unwrap(); + let height = image.height.try_into().unwrap(); // TODO: SIMD #[expect(clippy::cast_possible_truncation, reason = "This cannot overflow.")] - let pixels = brush - .image + let pixels = image .data .data() .chunks_exact(4) - .map(|rgba| { - let alpha = ((u16::from(rgba[3]) * global_alpha) / 255) as u8; - let multiply = |component| ((u16::from(alpha) * u16::from(component)) / 255) as u8; - PremulRgba8 { - r: multiply(rgba[0]), - g: multiply(rgba[1]), - b: multiply(rgba[2]), - a: alpha, + .map(|pixel| { + let rgba: [u8; 4] = match image.format { + peniko::ImageFormat::Rgba8 => pixel.try_into().unwrap(), + peniko::ImageFormat::Bgra8 => [pixel[2], pixel[1], pixel[0], pixel[3]], + format => unimplemented!("Unsupported image format: {format:?}"), + }; + let alpha = u16::from(rgba[3]); + let multiply = |component| ((alpha * u16::from(component)) / 255) as u8; + if do_alpha_multiply { + PremulRgba8 { + r: multiply(rgba[0]), + g: multiply(rgba[1]), + b: multiply(rgba[2]), + a: rgba[3], + } + } else { + PremulRgba8 { + r: rgba[0], + g: rgba[1], + b: rgba[2], + a: rgba[3], + } } }) .collect(); let pixmap = Pixmap::from_parts(pixels, width, height); - Self { - source: ImageSource::Pixmap(Arc::new(pixmap)), - x_extend, - y_extend, - quality, - } + Self::Pixmap(Arc::new(pixmap)) } } +/// An image. +pub type Image = peniko::ImageBrush; + /// A premultiplied color. #[derive(Debug, Clone, PartialEq, Copy)] pub struct PremulColor { @@ -193,30 +177,4 @@ impl PremulColor { } /// A kind of paint that can be used for filling and stroking shapes. -#[derive(Debug, Clone)] -pub enum PaintType { - /// A solid color. - Solid(AlphaColor), - /// A gradient. - Gradient(Gradient), - /// An image. - Image(Image), -} - -impl From> for PaintType { - fn from(value: AlphaColor) -> Self { - Self::Solid(value) - } -} - -impl From for PaintType { - fn from(value: Gradient) -> Self { - Self::Gradient(value) - } -} - -impl From for PaintType { - fn from(value: Image) -> Self { - Self::Image(value) - } -} +pub type PaintType = peniko::Brush; diff --git a/sparse_strips/vello_cpu/src/fine/common/image.rs b/sparse_strips/vello_cpu/src/fine/common/image.rs index ebe0b76dd..d3fe9fa57 100644 --- a/sparse_strips/vello_cpu/src/fine/common/image.rs +++ b/sparse_strips/vello_cpu/src/fine/common/image.rs @@ -38,7 +38,7 @@ impl<'a, S: Simd> PlainNNImagePainter<'a, S> { data.x_advances.1, data.y_advances.1, ), - image.extends.1, + image.sampler.y_extend, data.height, data.height_inv, ); @@ -68,7 +68,7 @@ impl Iterator for PlainNNImagePainter<'_, S> { let x_pos = extend( self.simd, self.cur_x_pos, - self.data.image.extends.0, + self.data.image.sampler.x_extend, self.data.width, self.data.width_inv, ); @@ -116,7 +116,7 @@ impl Iterator for NNImagePainter<'_, S> { self.data.x_advances.0, self.data.y_advances.0, ), - self.data.image.extends.0, + self.data.image.sampler.x_extend, self.data.width, self.data.width_inv, ); @@ -129,7 +129,7 @@ impl Iterator for NNImagePainter<'_, S> { self.data.x_advances.1, self.data.y_advances.1, ), - self.data.image.extends.1, + self.data.image.sampler.y_extend, self.data.height, self.data.height_inv, ); @@ -214,7 +214,7 @@ impl Iterator for FilteredImagePainter<'_, S> { extend( self.simd, x_positions + $offsets[$idx], - self.data.image.extends.0, + self.data.image.sampler.y_extend, self.data.width, self.data.width_inv, ) @@ -226,14 +226,14 @@ impl Iterator for FilteredImagePainter<'_, S> { extend( self.simd, y_positions + $offsets[$idx], - self.data.image.extends.1, + self.data.image.sampler.y_extend, self.data.height, self.data.height_inv, ) }; } - match self.data.image.quality { + match self.data.image.sampler.quality { ImageQuality::Low => unreachable!(), ImageQuality::Medium => { // diff --git a/sparse_strips/vello_cpu/src/fine/lowp/image.rs b/sparse_strips/vello_cpu/src/fine/lowp/image.rs index 4fb84b6c7..ad9d6c9b4 100644 --- a/sparse_strips/vello_cpu/src/fine/lowp/image.rs +++ b/sparse_strips/vello_cpu/src/fine/lowp/image.rs @@ -60,7 +60,7 @@ impl Iterator for BilinearImagePainter<'_, S> { extend( self.simd, x_pos, - self.data.image.extends.0, + self.data.image.sampler.x_extend, self.data.width, self.data.width_inv, ) @@ -70,7 +70,7 @@ impl Iterator for BilinearImagePainter<'_, S> { extend( self.simd, y_pos, - self.data.image.extends.1, + self.data.image.sampler.y_extend, self.data.height, self.data.height_inv, ) diff --git a/sparse_strips/vello_cpu/src/fine/mod.rs b/sparse_strips/vello_cpu/src/fine/mod.rs index 226f6526b..0b6326dad 100644 --- a/sparse_strips/vello_cpu/src/fine/mod.rs +++ b/sparse_strips/vello_cpu/src/fine/mod.rs @@ -573,7 +573,7 @@ impl> Fine { match (i.has_skew(), i.nearest_neighbor()) { (_, false) => { - if i.quality == ImageQuality::Medium { + if i.sampler.quality == ImageQuality::Medium { fill_complex_paint!( i.has_opacities, T::medium_quality_image_painter( diff --git a/sparse_strips/vello_cpu/src/render.rs b/sparse_strips/vello_cpu/src/render.rs index b8c8875f4..ebcb5ef37 100644 --- a/sparse_strips/vello_cpu/src/render.rs +++ b/sparse_strips/vello_cpu/src/render.rs @@ -508,6 +508,8 @@ impl GlyphRenderer for RenderContext { // We need to change the state of the render context // to render the bitmap, but don't want to pollute the context, // so simulate a `save` and `restore` operation. + + use vello_common::peniko::ImageSampler; let old_transform = self.transform; let old_paint = self.paint.clone(); @@ -521,10 +523,13 @@ impl GlyphRenderer for RenderContext { }; let image = vello_common::paint::Image { - source: ImageSource::Pixmap(Arc::new(glyph.pixmap)), - x_extend: crate::peniko::Extend::Pad, - y_extend: crate::peniko::Extend::Pad, - quality, + image: ImageSource::Pixmap(Arc::new(glyph.pixmap)), + sampler: ImageSampler { + x_extend: crate::peniko::Extend::Pad, + y_extend: crate::peniko::Extend::Pad, + quality, + alpha: 1.0, + }, }; self.set_paint(image); @@ -537,6 +542,8 @@ impl GlyphRenderer for RenderContext { } GlyphType::Colr(glyph) => { // Same as for bitmap glyphs, save the state and restore it later on. + + use vello_common::peniko::ImageSampler; let old_transform = self.transform; let old_paint = self.paint.clone(); let context_color = match old_paint { @@ -568,12 +575,15 @@ impl GlyphRenderer for RenderContext { }; let image = vello_common::paint::Image { - source: ImageSource::Pixmap(Arc::new(glyph_pixmap)), - x_extend: crate::peniko::Extend::Pad, - y_extend: crate::peniko::Extend::Pad, - // Since the pixmap will already have the correct size, no need to - // use a different image quality here. - quality: crate::peniko::ImageQuality::Low, + image: ImageSource::Pixmap(Arc::new(glyph_pixmap)), + sampler: ImageSampler { + x_extend: crate::peniko::Extend::Pad, + y_extend: crate::peniko::Extend::Pad, + // Since the pixmap will already have the correct size, no need to + // use a different image quality here. + quality: crate::peniko::ImageQuality::Low, + alpha: 1.0, + }, }; self.set_paint(image); diff --git a/sparse_strips/vello_cpu/src/util.rs b/sparse_strips/vello_cpu/src/util.rs index 9d3fbb28e..6acd24bde 100644 --- a/sparse_strips/vello_cpu/src/util.rs +++ b/sparse_strips/vello_cpu/src/util.rs @@ -130,7 +130,7 @@ impl EncodedImageExt for EncodedImage { } fn nearest_neighbor(&self) -> bool { - self.quality == ImageQuality::Low + self.sampler.quality == ImageQuality::Low } } diff --git a/sparse_strips/vello_example_scenes/src/image.rs b/sparse_strips/vello_example_scenes/src/image.rs index d1af998dd..27b5f9fdb 100644 --- a/sparse_strips/vello_example_scenes/src/image.rs +++ b/sparse_strips/vello_example_scenes/src/image.rs @@ -7,6 +7,7 @@ use std::f64::consts::PI; use vello_common::color::PremulRgba8; use vello_common::kurbo::{BezPath, Point, Shape, Vec2}; use vello_common::peniko::ImageFormat; +use vello_common::peniko::ImageSampler; use vello_common::pixmap::Pixmap; use vello_common::{ kurbo::{Affine, Rect}, @@ -42,10 +43,13 @@ impl ExampleScene for ImageScene { ); ctx.set_paint_transform(Affine::translate((0.0, 0.0))); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Pad, - y_extend: Extend::Pad, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Pad, + y_extend: Extend::Pad, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); @@ -56,19 +60,25 @@ impl ExampleScene for ImageScene { * Affine::scale(0.5), ); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Pad, - y_extend: Extend::Pad, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Pad, + y_extend: Extend::Pad, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); ctx.set_transform(root_transform * Affine::translate((0.0, 500.0))); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Pad, - y_extend: Extend::Pad, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Pad, + y_extend: Extend::Pad, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_path(&heart_shape()); @@ -76,10 +86,13 @@ impl ExampleScene for ImageScene { ctx.push_clip_layer(&circular_star(Point::new(300.0, 220.0), 5, 100.0, 150.0).to_path(0.1)); ctx.set_paint_transform(Affine::IDENTITY); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); ctx.pop_layer(); @@ -87,40 +100,52 @@ impl ExampleScene for ImageScene { ctx.set_transform(root_transform * Affine::translate((1000.0, 50.0))); ctx.set_paint_transform(Affine::scale(0.25)); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); ctx.set_transform(root_transform * Affine::translate((1000.0, 600.0))); ctx.set_paint_transform(Affine::scale(0.25)); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Reflect, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Reflect, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); ctx.set_transform(root_transform * Affine::translate((1000.0, 1200.0))); ctx.set_paint_transform(Affine::scale(0.25)); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Pad, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Pad, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); ctx.set_transform(root_transform * Affine::translate((100.0, 1000.0))); ctx.set_paint_transform(Affine::IDENTITY); ctx.set_paint(Image { - source: cowboy_id, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::High, + image: cowboy_id, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::High, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 800.0, 160.0)); @@ -132,10 +157,13 @@ impl ExampleScene for ImageScene { ); ctx.set_paint_transform(Affine::scale(0.25)); ctx.set_paint(Image { - source: splash_flower_id.clone(), - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: splash_flower_id.clone(), + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&Rect::new(0.0, 0.0, 640.0, 480.0)); } diff --git a/sparse_strips/vello_hybrid/src/render/webgl.rs b/sparse_strips/vello_hybrid/src/render/webgl.rs index c0bf3435e..1016c3776 100644 --- a/sparse_strips/vello_hybrid/src/render/webgl.rs +++ b/sparse_strips/vello_hybrid/src/render/webgl.rs @@ -403,9 +403,9 @@ impl WebGlRenderer { let image_size = pack_image_size(image_resource.width, image_resource.height); let image_offset = pack_image_offset(image_resource.offset[0], image_resource.offset[1]); let image_params = pack_image_params( - image.quality as u32, - image.extends.0 as u32, - image.extends.1 as u32, + image.sampler.quality as u32, + image.sampler.x_extend as u32, + image.sampler.y_extend as u32, image_resource.atlas_id.as_u32(), ); diff --git a/sparse_strips/vello_hybrid/src/render/wgpu.rs b/sparse_strips/vello_hybrid/src/render/wgpu.rs index 225f2e1ab..a86277659 100644 --- a/sparse_strips/vello_hybrid/src/render/wgpu.rs +++ b/sparse_strips/vello_hybrid/src/render/wgpu.rs @@ -346,9 +346,9 @@ impl Renderer { let image_size = pack_image_size(image_resource.width, image_resource.height); let image_offset = pack_image_offset(image_resource.offset[0], image_resource.offset[1]); let image_params = pack_image_params( - image.quality as u32, - image.extends.0 as u32, - image.extends.1 as u32, + image.sampler.quality as u32, + image.sampler.x_extend as u32, + image.sampler.y_extend as u32, image_resource.atlas_id.as_u32(), ); diff --git a/sparse_strips/vello_sparse_tests/tests/image.rs b/sparse_strips/vello_sparse_tests/tests/image.rs index 2798454f9..33b50f3cb 100644 --- a/sparse_strips/vello_sparse_tests/tests/image.rs +++ b/sparse_strips/vello_sparse_tests/tests/image.rs @@ -9,9 +9,10 @@ use std::f64::consts::PI; use std::sync::Arc; use vello_common::color::palette::css::REBECCA_PURPLE; use vello_common::kurbo::{Affine, Point, Rect}; +use vello_common::kurbo::{Shape, Triangle}; use vello_common::paint::{Image, ImageSource}; +use vello_common::peniko::ImageSampler; use vello_common::peniko::{Extend, ImageQuality}; -use vello_cpu::kurbo::{Shape, Triangle}; use vello_dev_macros::vello_test; fn rgb_img_10x10(ctx: &mut impl Renderer) -> ImageSource { @@ -50,10 +51,13 @@ fn repeat(ctx: &mut impl Renderer, x_extend: Extend, y_extend: Extend) { ctx.set_paint_transform(Affine::translate((45.0, 45.0))); ctx.set_paint(Image { - source: image_source, - x_extend, - y_extend, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend, + y_extend, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&rect); } @@ -88,10 +92,13 @@ fn transform(ctx: &mut impl Renderer, transform: Affine, l: f64, t: f64, r: f64, let image_source = rgb_img_10x10(ctx); let image = Image { - source: image_source, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_transform(transform); @@ -228,10 +235,13 @@ fn image_complex_shape(ctx: &mut impl Renderer) { let image_source = rgb_img_10x10(ctx); let image = Image { - source: image_source, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_paint(image); @@ -243,10 +253,13 @@ fn image_global_alpha(ctx: &mut impl Renderer) { let rect = Rect::new(10.0, 10.0, 90.0, 90.0); let image = Image { - source: rgb_img_10x10_alpha_multiplied(ctx, 75), - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: rgb_img_10x10_alpha_multiplied(ctx, 75), + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_paint(image); @@ -264,10 +277,13 @@ fn image_with_opacity(ctx: &mut impl Renderer) { let image_source = rgb_img_10x10(ctx); let image = Image { - source: image_source, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_paint(image); @@ -280,10 +296,13 @@ fn image_format(ctx: &mut impl Renderer, image_source: ImageSource) { let rect = Rect::new(10.0, 10.0, 90.0, 90.0); let image = Image { - source: image_source, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_paint(image); @@ -325,10 +344,13 @@ fn quality( ctx.set_paint_transform(transform); let image = Image { - source: image_source, - x_extend: extend, - y_extend: extend, - quality, + image: image_source, + sampler: ImageSampler { + x_extend: extend, + y_extend: extend, + quality, + alpha: 1.0, + }, }; ctx.set_paint(image); @@ -528,10 +550,13 @@ fn image_with_multiple_clip_layers(ctx: &mut impl Renderer) { ctx.push_clip_layer(&clipped_area2.to_path(0.1)); ctx.set_paint_transform(Affine::IDENTITY); ctx.set_paint(Image { - source: image_source, - x_extend: Extend::Repeat, - y_extend: Extend::Repeat, - quality: ImageQuality::Low, + image: image_source, + sampler: ImageSampler { + x_extend: Extend::Repeat, + y_extend: Extend::Repeat, + quality: ImageQuality::Low, + alpha: 1.0, + }, }); ctx.fill_rect(&image_rect); ctx.pop_layer(); diff --git a/sparse_strips/vello_sparse_tests/tests/mix.rs b/sparse_strips/vello_sparse_tests/tests/mix.rs index b82e1c363..f45d16a6a 100644 --- a/sparse_strips/vello_sparse_tests/tests/mix.rs +++ b/sparse_strips/vello_sparse_tests/tests/mix.rs @@ -11,7 +11,7 @@ use vello_common::paint::{Image, ImageSource}; use vello_common::peniko::{ BlendMode, Color, ColorStop, ColorStops, Compose, Extend, Gradient, ImageQuality, Mix, }; -use vello_cpu::peniko::LinearGradientPosition; +use vello_cpu::peniko::{ImageSampler, LinearGradientPosition}; use vello_dev_macros::vello_test; fn cowboy_img(ctx: &mut impl Renderer) -> ImageSource { @@ -55,10 +55,13 @@ fn mix(ctx: &mut impl Renderer, blend_mode: BlendMode) { }; let image = Image { - source: cowboy_img(ctx), - x_extend: Extend::Pad, - y_extend: Extend::Pad, - quality: ImageQuality::Low, + image: cowboy_img(ctx), + sampler: ImageSampler { + x_extend: Extend::Pad, + y_extend: Extend::Pad, + quality: ImageQuality::Low, + alpha: 1.0, + }, }; ctx.set_transform(Affine::translate((10.0, 10.0)));