blob: 955a2898735040710101a995242e21225e7215f9 [file] [log] [blame]
// Copyright 2025 the Vello Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
use crate::renderer::Renderer;
use crate::util::{stops_blue_green_red_yellow, stops_green_blue};
use smallvec::smallvec;
use vello_common::color::palette::css::{BLACK, BLUE, WHITE, YELLOW};
use vello_common::color::{ColorSpaceTag, DynamicColor};
use vello_common::kurbo::{Point, Rect};
use vello_common::peniko::{ColorStop, ColorStops, Gradient, GradientKind};
use vello_dev_macros::vello_test;
pub(crate) const fn tan_45() -> f64 {
1.0
}
#[vello_test(width = 600, height = 32)]
fn gradient_on_3_wide_tiles(ctx: &mut impl Renderer) {
let rect = Rect::new(4.0, 4.0, 596.0, 28.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(0.0, 0.0),
end: Point::new(600.0, 0.0),
},
stops: stops_green_blue(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_with_global_alpha(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(10.0, 0.0),
end: Point::new(90.0, 0.0),
},
stops: stops_blue_green_red_yellow(),
..Default::default()
}
.multiply_alpha(0.5);
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
fn gradient_with_color_spaces(ctx: &mut impl Renderer, stops: ColorStops) {
const COLOR_SPACES: &[ColorSpaceTag] = &[
ColorSpaceTag::Srgb,
ColorSpaceTag::LinearSrgb,
ColorSpaceTag::Oklab,
];
let mut cur_y = 10.0;
for cs in COLOR_SPACES {
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(10.0, 0.0),
end: Point::new(190.0, 0.0),
},
stops: stops.clone(),
interpolation_cs: *cs,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&Rect::new(10.0, cur_y, 190.0, cur_y + 30.0));
cur_y += 40.0;
}
}
#[vello_test(width = 200, height = 130)]
fn gradient_with_color_spaces_1(ctx: &mut impl Renderer) {
let stops = ColorStops(smallvec![
ColorStop {
offset: 0.0,
color: DynamicColor::from_alpha_color(BLACK),
},
ColorStop {
offset: 1.0,
color: DynamicColor::from_alpha_color(WHITE),
},
]);
gradient_with_color_spaces(ctx, stops);
}
#[vello_test(width = 200, height = 130)]
fn gradient_with_color_spaces_2(ctx: &mut impl Renderer) {
let stops = ColorStops(smallvec![
ColorStop {
offset: 0.0,
color: DynamicColor::from_alpha_color(BLUE),
},
ColorStop {
offset: 1.0,
color: DynamicColor::from_alpha_color(YELLOW),
},
]);
gradient_with_color_spaces(ctx, stops);
}
#[vello_test(width = 200, height = 130)]
fn gradient_with_color_spaces_3(ctx: &mut impl Renderer) {
gradient_with_color_spaces(ctx, stops_blue_green_red_yellow());
}
mod linear {
use crate::gradient::tan_45;
use crate::renderer::Renderer;
use crate::util::{
crossed_line_star, stops_blue_green_red_yellow, stops_green_blue,
stops_green_blue_with_alpha,
};
use peniko::Extend;
use std::f64::consts::PI;
use vello_common::kurbo::{Affine, Point, Rect};
use vello_common::peniko::{self, Gradient, GradientKind};
use vello_dev_macros::vello_test;
#[vello_test]
fn gradient_linear_2_stops(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(10.0, 0.0),
end: Point::new(90.0, 0.0),
},
stops: stops_green_blue(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_2_stops_with_alpha(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(10.0, 0.0),
end: Point::new(90.0, 0.0),
},
stops: stops_green_blue_with_alpha(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
fn directional(ctx: &mut impl Renderer, start: Point, end: Point) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear { start, end },
stops: stops_green_blue(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_negative_direction(ctx: &mut impl Renderer) {
directional(ctx, Point::new(90.0, 0.0), Point::new(10.0, 0.0));
}
#[vello_test]
fn gradient_linear_with_downward_y(ctx: &mut impl Renderer) {
directional(ctx, Point::new(20.0, 20.0), Point::new(80.0, 80.0));
}
#[vello_test]
fn gradient_linear_with_upward_y(ctx: &mut impl Renderer) {
directional(ctx, Point::new(20.0, 80.0), Point::new(80.0, 20.0));
}
#[vello_test]
fn gradient_linear_vertical(ctx: &mut impl Renderer) {
directional(ctx, Point::new(0.0, 10.0), Point::new(0.0, 90.0));
}
fn gradient_pad(ctx: &mut impl Renderer, extend: Extend) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(40.0, 40.0),
end: Point::new(60.0, 60.0),
},
stops: stops_blue_green_red_yellow(),
extend,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_spread_method_pad(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Pad);
}
#[vello_test]
fn gradient_linear_spread_method_repeat(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Repeat);
}
#[vello_test]
fn gradient_linear_spread_method_reflect(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Reflect);
}
#[vello_test]
fn gradient_linear_4_stops(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(10.0, 0.0),
end: Point::new(90.0, 0.0),
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_complex_shape(ctx: &mut impl Renderer) {
let path = crossed_line_star();
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(0.0, 0.0),
end: Point::new(100.0, 0.0),
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_path(&path);
}
#[vello_test]
fn gradient_linear_with_y_repeat(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(47.5, 47.5),
end: Point::new(50.5, 52.5),
},
stops: stops_blue_green_red_yellow(),
extend: Extend::Repeat,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_with_y_reflect(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(47.5, 47.5),
end: Point::new(50.5, 52.5),
},
stops: stops_blue_green_red_yellow(),
extend: Extend::Reflect,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
fn gradient_with_transform(
ctx: &mut impl Renderer,
transform: Affine,
l: f64,
t: f64,
r: f64,
b: f64,
) {
let rect = Rect::new(l, t, r, b);
let gradient = Gradient {
kind: GradientKind::Linear {
start: Point::new(l, t),
end: Point::new(r, b),
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_transform(transform);
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_linear_with_transform_identity(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::IDENTITY, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_linear_with_transform_translate(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::translate((25.0, 25.0)), 0.0, 0.0, 50.0, 50.0);
}
#[vello_test]
fn gradient_linear_with_transform_scale(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::scale(2.0), 12.5, 12.5, 37.5, 37.5);
}
#[vello_test]
fn gradient_linear_with_transform_negative_scale(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::translate((100.0, 100.0)) * Affine::scale(-2.0),
12.5,
12.5,
37.5,
37.5,
);
}
#[vello_test]
fn gradient_linear_with_transform_scale_and_translate(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::new([2.0, 0.0, 0.0, 2.0, 25.0, 25.0]),
0.0,
0.0,
25.0,
25.0,
);
}
#[vello_test]
fn gradient_linear_with_transform_rotate_1(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_linear_with_transform_rotate_2(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(-PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_linear_with_transform_scaling_non_uniform(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::scale_non_uniform(1.0, 2.0),
25.0,
12.5,
75.0,
37.5,
);
}
#[vello_test]
fn gradient_linear_with_transform_skew_x_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((-50.0, 0.0)) * Affine::skew(tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_linear_with_transform_skew_x_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((50.0, 0.0)) * Affine::skew(-tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_linear_with_transform_skew_y_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, 50.0)) * Affine::skew(0.0, -tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_linear_with_transform_skew_y_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, -50.0)) * Affine::skew(0.0, tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
}
mod radial {
use crate::gradient::tan_45;
use crate::renderer::Renderer;
use crate::util::{
crossed_line_star, stops_blue_green_red_yellow, stops_green_blue,
stops_green_blue_with_alpha,
};
use peniko::Extend;
use std::f64::consts::PI;
use vello_common::kurbo::{Affine, Point, Rect};
use vello_common::peniko::GradientKind::Radial;
use vello_common::peniko::{self, ColorStops, Gradient};
use vello_dev_macros::vello_test;
fn simple(ctx: &mut impl Renderer, stops: ColorStops) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: Radial {
start_center: Point::new(50.0, 50.0),
start_radius: 10.0,
end_center: Point::new(50.0, 50.0),
end_radius: 40.0,
},
stops,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_radial_2_stops(ctx: &mut impl Renderer) {
simple(ctx, stops_green_blue());
}
#[vello_test]
fn gradient_radial_4_stops(ctx: &mut impl Renderer) {
simple(ctx, stops_blue_green_red_yellow());
}
#[vello_test]
fn gradient_radial_2_stops_with_alpha(ctx: &mut impl Renderer) {
simple(ctx, stops_green_blue_with_alpha());
}
fn gradient_pad(ctx: &mut impl Renderer, extend: Extend) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: Radial {
start_center: Point::new(50.0, 50.0),
start_radius: 20.0,
end_center: Point::new(50.0, 50.0),
end_radius: 25.0,
},
stops: stops_blue_green_red_yellow(),
extend,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_radial_spread_method_pad(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Pad);
}
#[vello_test]
fn gradient_radial_spread_method_reflect(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Reflect);
}
#[vello_test]
fn gradient_radial_spread_method_repeat(ctx: &mut impl Renderer) {
gradient_pad(ctx, Extend::Repeat);
}
fn offset(ctx: &mut impl Renderer, point: Point) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: Radial {
start_center: point,
start_radius: 2.0,
end_center: Point::new(50.0, 50.0),
end_radius: 40.0,
},
stops: stops_blue_green_red_yellow(),
extend: Extend::Repeat,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_radial_center_offset_top_left(ctx: &mut impl Renderer) {
offset(ctx, Point::new(30.0, 30.0));
}
#[vello_test]
fn gradient_radial_center_offset_top_right(ctx: &mut impl Renderer) {
offset(ctx, Point::new(70.0, 30.0));
}
#[vello_test]
fn gradient_radial_center_offset_bottom_left(ctx: &mut impl Renderer) {
offset(ctx, Point::new(30.0, 70.0));
}
#[vello_test]
fn gradient_radial_center_offset_bottom_right(ctx: &mut impl Renderer) {
offset(ctx, Point::new(70.0, 70.0));
}
#[vello_test]
fn gradient_radial_c0_bigger(ctx: &mut impl Renderer) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: Radial {
start_center: Point::new(50.0, 50.0),
start_radius: 40.0,
end_center: Point::new(50.0, 50.0),
end_radius: 10.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
fn non_overlapping(ctx: &mut impl Renderer, radius: f32) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: Radial {
start_center: Point::new(30.0, 50.0),
start_radius: radius,
end_center: Point::new(70.0, 50.0),
end_radius: 20.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_radial_non_overlapping_same_size(ctx: &mut impl Renderer) {
non_overlapping(ctx, 20.0);
}
#[vello_test]
fn gradient_radial_non_overlapping_c0_smaller(ctx: &mut impl Renderer) {
non_overlapping(ctx, 15.0);
}
#[vello_test]
fn gradient_radial_non_overlapping_c0_larger(ctx: &mut impl Renderer) {
non_overlapping(ctx, 25.0);
}
#[vello_test]
fn gradient_radial_non_overlapping_cone(ctx: &mut impl Renderer) {
non_overlapping(ctx, 5.0);
}
#[vello_test]
fn gradient_radial_complex_shape(ctx: &mut impl Renderer) {
let path = crossed_line_star();
let gradient = Gradient {
kind: Radial {
start_center: Point::new(50.0, 50.0),
start_radius: 5.0,
end_center: Point::new(50.0, 50.0),
end_radius: 35.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_path(&path);
}
fn gradient_with_transform(
ctx: &mut impl Renderer,
transform: Affine,
l: f64,
t: f64,
r: f64,
b: f64,
) {
let rect = Rect::new(l, t, r, b);
let point = Point::new((l + r) / 2.0, (t + b) / 2.0);
let gradient = Gradient {
kind: Radial {
start_center: point,
start_radius: 5.0,
end_center: point,
end_radius: 35.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_transform(transform);
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_radial_with_transform_identity(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::IDENTITY, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_radial_with_transform_translate(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::translate((25.0, 25.0)), 0.0, 0.0, 50.0, 50.0);
}
#[vello_test]
fn gradient_radial_with_transform_scale(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::scale(2.0), 12.5, 12.5, 37.5, 37.5);
}
#[vello_test]
fn gradient_radial_with_transform_negative_scale(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::translate((100.0, 100.0)) * Affine::scale(-2.0),
12.5,
12.5,
37.5,
37.5,
);
}
#[vello_test]
fn gradient_radial_with_transform_scale_and_translate(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::new([2.0, 0.0, 0.0, 2.0, 25.0, 25.0]),
0.0,
0.0,
25.0,
25.0,
);
}
#[vello_test]
fn gradient_radial_with_transform_rotate_1(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_radial_with_transform_rotate_2(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(-PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_radial_with_transform_scale_non_uniform(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::scale_non_uniform(1.0, 2.0),
25.0,
12.5,
75.0,
37.5,
);
}
#[vello_test]
fn gradient_radial_with_transform_skew_x_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((-50.0, 0.0)) * Affine::skew(tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_radial_with_transform_skew_x_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((50.0, 0.0)) * Affine::skew(-tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_radial_with_transform_skew_y_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, 50.0)) * Affine::skew(0.0, -tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_radial_with_transform_skew_y_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, -50.0)) * Affine::skew(0.0, tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
}
mod sweep {
use crate::gradient::tan_45;
use crate::renderer::Renderer;
use crate::util::{
crossed_line_star, stops_blue_green_red_yellow, stops_green_blue,
stops_green_blue_with_alpha,
};
use peniko::Extend;
use std::f64::consts::PI;
use vello_common::kurbo::{Affine, Point, Rect};
use vello_common::peniko::{self, ColorStops, Gradient, GradientKind};
use vello_dev_macros::vello_test;
fn basic(ctx: &mut impl Renderer, stops: ColorStops, center: Point) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Sweep {
center,
start_angle: 0.0,
end_angle: 360.0,
},
stops,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_sweep_2_stops(ctx: &mut impl Renderer) {
basic(ctx, stops_green_blue(), Point::new(50.0, 50.0));
}
#[vello_test]
fn gradient_sweep_2_stops_with_alpha(ctx: &mut impl Renderer) {
basic(ctx, stops_green_blue_with_alpha(), Point::new(50.0, 50.0));
}
#[vello_test]
fn gradient_sweep_4_stops(ctx: &mut impl Renderer) {
basic(ctx, stops_blue_green_red_yellow(), Point::new(50.0, 50.0));
}
#[vello_test]
fn gradient_sweep_not_in_center(ctx: &mut impl Renderer) {
basic(ctx, stops_green_blue(), Point::new(30.0, 30.0));
}
#[vello_test]
fn gradient_sweep_complex_shape(ctx: &mut impl Renderer) {
let path = crossed_line_star();
let gradient = Gradient {
kind: GradientKind::Sweep {
center: Point::new(50.0, 50.0),
start_angle: 0.0,
end_angle: 360.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_path(&path);
}
fn spread_method(ctx: &mut impl Renderer, extend: Extend) {
let rect = Rect::new(10.0, 10.0, 90.0, 90.0);
let gradient = Gradient {
kind: GradientKind::Sweep {
center: Point::new(50.0, 50.0),
start_angle: 150.0,
end_angle: 210.0,
},
stops: stops_blue_green_red_yellow(),
extend,
..Default::default()
};
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_sweep_spread_method_pad(ctx: &mut impl Renderer) {
spread_method(ctx, Extend::Pad);
}
#[vello_test]
fn gradient_sweep_spread_method_repeat(ctx: &mut impl Renderer) {
spread_method(ctx, Extend::Repeat);
}
#[vello_test]
fn gradient_sweep_spread_method_reflect(ctx: &mut impl Renderer) {
spread_method(ctx, Extend::Reflect);
}
fn gradient_with_transform(
ctx: &mut impl Renderer,
transform: Affine,
l: f64,
t: f64,
r: f64,
b: f64,
) {
let rect = Rect::new(l, t, r, b);
let gradient = Gradient {
kind: GradientKind::Sweep {
center: Point::new((l + r) / 2.0, (t + b) / 2.0),
start_angle: 150.0,
end_angle: 210.0,
},
stops: stops_blue_green_red_yellow(),
..Default::default()
};
ctx.set_transform(transform);
ctx.set_paint(gradient);
ctx.fill_rect(&rect);
}
#[vello_test]
fn gradient_sweep_with_transform_identity(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::IDENTITY, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_sweep_with_transform_translate(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::translate((25.0, 25.0)), 0.0, 0.0, 50.0, 50.0);
}
#[vello_test]
fn gradient_sweep_with_transform_scale(ctx: &mut impl Renderer) {
gradient_with_transform(ctx, Affine::scale(2.0), 12.5, 12.5, 37.5, 37.5);
}
#[vello_test]
fn gradient_sweep_with_transform_negative_scale(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::translate((100.0, 100.0)) * Affine::scale(-2.0),
12.5,
12.5,
37.5,
37.5,
);
}
#[vello_test]
fn gradient_sweep_with_transform_scale_and_translate(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::new([2.0, 0.0, 0.0, 2.0, 25.0, 25.0]),
0.0,
0.0,
25.0,
25.0,
);
}
#[vello_test]
fn gradient_sweep_with_transform_rotate_1(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_sweep_with_transform_rotate_2(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::rotate_about(-PI / 4.0, Point::new(50.0, 50.0)),
25.0,
25.0,
75.0,
75.0,
);
}
#[vello_test]
fn gradient_sweep_with_transform_scale_non_uniform(ctx: &mut impl Renderer) {
gradient_with_transform(
ctx,
Affine::scale_non_uniform(1.0, 2.0),
25.0,
12.5,
75.0,
37.5,
);
}
#[vello_test]
fn gradient_sweep_with_transform_skew_x_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((-50.0, 0.0)) * Affine::skew(tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_sweep_with_transform_skew_x_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((50.0, 0.0)) * Affine::skew(-tan_45(), 0.0);
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_sweep_with_transform_skew_y_1(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, 50.0)) * Affine::skew(0.0, -tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
#[vello_test]
fn gradient_sweep_with_transform_skew_y_2(ctx: &mut impl Renderer) {
let transform = Affine::translate((0.0, -50.0)) * Affine::skew(0.0, tan_45());
gradient_with_transform(ctx, transform, 25.0, 25.0, 75.0, 75.0);
}
}