prevent encoding empty paths for layers too

This commit is contained in:
Chad Brokaw 2022-11-22 15:17:50 -05:00
parent f19dbdb1b5
commit c1e91cb233
3 changed files with 22 additions and 34 deletions

View file

@ -226,7 +226,7 @@ pub fn render_blend_grid(sb: &mut SceneBuilder) {
fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affine) {
// Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.));
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::BLACK, Color::WHITE]);
let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]);
sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect);
const GRADIENTS: &[(f64, f64, Color)] = &[
(150., 0., Color::rgb8(255, 240, 64)),
@ -236,7 +236,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
for (x, y, c) in GRADIENTS {
let mut color2 = c.clone();
color2.a = 0;
let radial = RadialGradient::new((*x, *y), 100.0).stops([c.clone(), color2]);
let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]);
sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect);
}
const COLORS: &[Color] = &[
@ -246,17 +246,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
];
sb.push_layer(Mix::Normal.into(), transform, &rect);
for (i, c) in COLORS.iter().enumerate() {
// let stops = &[
// GradientStop {
// color: Color::rgb8(255, 255, 255),
// offset: 0.0,
// },
// GradientStop {
// color: c.clone(),
// offset: 1.0,
// },
// ][..];
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, c.clone()]);
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]);
sb.push_layer(blend, transform, &rect);
// squash the ellipse
let a = transform

View file

@ -24,7 +24,7 @@ use smallvec::SmallVec;
/// Builder for constructing a scene or scene fragment.
pub struct SceneBuilder<'a> {
scene: &'a mut SceneData,
layers: SmallVec<[BlendMode; 8]>,
layers: SmallVec<[(BlendMode, bool); 8]>,
}
impl<'a> SceneBuilder<'a> {
@ -54,15 +54,23 @@ impl<'a> SceneBuilder<'a> {
pub fn push_layer(&mut self, blend: BlendMode, transform: Affine, shape: &impl Shape) {
self.maybe_encode_transform(transform);
self.linewidth(-1.0);
self.encode_path(shape, true);
self.begin_clip(blend);
self.layers.push(blend);
if self.encode_path(shape, true) {
self.begin_clip(blend);
self.layers.push((blend, true));
} else {
// When the layer has an empty path, record an entry to prevent
// the stack from becoming unbalanced. This is handled in
// pop_layer.
self.layers.push((blend, false));
}
}
/// Pops the current layer.
pub fn pop_layer(&mut self) {
if let Some(layer) = self.layers.pop() {
self.end_clip(layer);
if let Some((blend, active)) = self.layers.pop() {
if active {
self.end_clip(blend);
}
}
}
@ -117,8 +125,8 @@ impl<'a> SceneBuilder<'a> {
/// Completes construction and finalizes the underlying scene.
pub fn finish(mut self) {
while let Some(layer) = self.layers.pop() {
self.end_clip(layer);
while !self.layers.is_empty() {
self.pop_layer();
}
}
}

View file

@ -133,7 +133,7 @@ pub fn render_blend_grid(sb: &mut SceneBuilder) {
fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affine) {
// Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.));
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::BLACK, Color::WHITE]);
let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]);
sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect);
const GRADIENTS: &[(f64, f64, Color)] = &[
(150., 0., Color::rgb8(255, 240, 64)),
@ -143,7 +143,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
for (x, y, c) in GRADIENTS {
let mut color2 = c.clone();
color2.a = 0;
let radial = RadialGradient::new((*x, *y), 100.0).stops([c.clone(), color2]);
let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]);
sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect);
}
const COLORS: &[Color] = &[
@ -153,17 +153,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
];
sb.push_layer(Mix::Normal.into(), transform, &rect);
for (i, c) in COLORS.iter().enumerate() {
// let stops = &[
// GradientStop {
// color: Color::rgb8(255, 255, 255),
// offset: 0.0,
// },
// GradientStop {
// color: c.clone(),
// offset: 1.0,
// },
// ][..];
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, c.clone()]);
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]);
sb.push_layer(blend, transform, &rect);
// squash the ellipse
let a = transform