Fix brush transforms

This fixes an incorrect application of the inverse transform for radial gradients in fine.

Also fixes an edge case in `SceneBuilder` where a brush transform is identical to the path transform leading to a corrupt encoding.
This commit is contained in:
Chad Brokaw 2023-02-22 20:10:00 -05:00
parent 0bb519c1ba
commit 033870d91e
3 changed files with 22 additions and 14 deletions

View file

@ -251,7 +251,7 @@ fn main(
for (var i = 0u; i < PIXELS_PER_THREAD; i += 1u) {
let my_xy = vec2(xy.x + f32(i), xy.y);
// TODO: can hoist y, but for now stick to the GLSL version
let xy_xformed = rad.matrx.xz * my_xy.x + rad.matrx.yw * my_xy.y - rad.xlat;
let xy_xformed = rad.matrx.xy * my_xy.x + rad.matrx.zw * my_xy.y - rad.xlat;
let ba = dot(xy_xformed, rad.c1);
let ca = rad.ra * dot(xy_xformed, xy_xformed);
let t = sqrt(ba * ba + ca) - ba - rad.roff;

View file

@ -120,10 +120,16 @@ impl Encoding {
}
/// Encodes a transform.
pub fn encode_transform(&mut self, transform: Transform) {
///
/// If the given transform is different from the current one, encodes it an
/// returns true. Otherwise, encodes nothing and returns false.
pub fn encode_transform(&mut self, transform: Transform) -> bool {
if self.transforms.last() != Some(&transform) {
self.path_tags.push(PathTag::TRANSFORM);
self.transforms.push(transform);
true
} else {
false
}
}

View file

@ -140,13 +140,14 @@ impl<'a> SceneBuilder<'a> {
});
if self.scene.encode_shape(shape, true) {
if let Some(brush_transform) = brush_transform {
self.scene
.encode_transform(Transform::from_kurbo(&(transform * brush_transform)));
self.scene.swap_last_path_tags();
self.scene.encode_brush(brush, 1.0);
} else {
self.scene.encode_brush(brush, 1.0);
if self
.scene
.encode_transform(Transform::from_kurbo(&(transform * brush_transform)))
{
self.scene.swap_last_path_tags();
}
}
self.scene.encode_brush(brush, 1.0);
}
}
@ -164,13 +165,14 @@ impl<'a> SceneBuilder<'a> {
self.scene.encode_linewidth(style.width);
if self.scene.encode_shape(shape, false) {
if let Some(brush_transform) = brush_transform {
self.scene
.encode_transform(Transform::from_kurbo(&(transform * brush_transform)));
self.scene.swap_last_path_tags();
self.scene.encode_brush(brush, 1.0);
} else {
self.scene.encode_brush(brush, 1.0);
if self
.scene
.encode_transform(Transform::from_kurbo(&(transform * brush_transform)))
{
self.scene.swap_last_path_tags();
}
}
self.scene.encode_brush(brush, 1.0);
}
}