Merge pull request #283 from linebender/brush-fix

Fix brush transforms
This commit is contained in:
Arman Uguray 2023-02-22 22:28:00 -08:00 committed by GitHub
commit 61ae3cde03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 18 deletions

View file

@ -192,14 +192,25 @@ fn brush_transform(sb: &mut SceneBuilder, params: &mut SceneParams) {
]); ]);
sb.fill( sb.fill(
Fill::NonZero, Fill::NonZero,
Affine::translate((200.0, 200.0)), Affine::rotate(25f64.to_radians()) * Affine::scale_non_uniform(2.0, 1.0),
&Gradient::new_radial((200.0, 200.0), 80.0).with_stops([
Color::RED,
Color::GREEN,
Color::BLUE,
]),
None,
&Rect::from_origin_size((100.0, 100.0), (200.0, 200.0)),
);
sb.fill(
Fill::NonZero,
Affine::translate((200.0, 600.0)),
&linear, &linear,
Some(around_center(Affine::rotate(th), Point::new(200.0, 100.0))), Some(around_center(Affine::rotate(th), Point::new(200.0, 100.0))),
&Rect::from_origin_size(Point::default(), (400.0, 200.0)), &Rect::from_origin_size(Point::default(), (400.0, 200.0)),
); );
sb.stroke( sb.stroke(
&Stroke::new(40.0), &Stroke::new(40.0),
Affine::translate((800.0, 200.0)), Affine::translate((800.0, 600.0)),
&linear, &linear,
Some(around_center(Affine::rotate(th), Point::new(200.0, 100.0))), Some(around_center(Affine::rotate(th), Point::new(200.0, 100.0))),
&Rect::from_origin_size(Point::default(), (400.0, 200.0)), &Rect::from_origin_size(Point::default(), (400.0, 200.0)),

View file

@ -151,8 +151,7 @@ fn main(
let r1 = bitcast<f32>(scene[dd + 6u]); let r1 = bitcast<f32>(scene[dd + 6u]);
let inv_det = 1.0 / (matrx.x * matrx.w - matrx.y * matrx.z); let inv_det = 1.0 / (matrx.x * matrx.w - matrx.y * matrx.z);
let inv_mat = inv_det * vec4(matrx.w, -matrx.y, -matrx.z, matrx.x); let inv_mat = inv_det * vec4(matrx.w, -matrx.y, -matrx.z, matrx.x);
var inv_tr = inv_mat.xz * translate.x + inv_mat.yw * translate.y; let inv_tr = mat2x2(inv_mat.xy, inv_mat.zw) * -translate - p0;
inv_tr += p0;
let center1 = p1 - p0; let center1 = p1 - p0;
let rr = r1 / (r1 - r0); let rr = r1 / (r1 - r0);
let ra_inv = rr / (r1 * r1 - dot(center1, center1)); let ra_inv = rr / (r1 * r1 - dot(center1, center1));

View file

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

View file

@ -120,10 +120,16 @@ impl Encoding {
} }
/// Encodes a transform. /// Encodes a transform.
pub fn encode_transform(&mut self, transform: Transform) { ///
/// If the given transform is different from the current one, encodes it and
/// returns true. Otherwise, encodes nothing and returns false.
pub fn encode_transform(&mut self, transform: Transform) -> bool {
if self.transforms.last() != Some(&transform) { if self.transforms.last() != Some(&transform) {
self.path_tags.push(PathTag::TRANSFORM); self.path_tags.push(PathTag::TRANSFORM);
self.transforms.push(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 self.scene.encode_shape(shape, true) {
if let Some(brush_transform) = brush_transform { if let Some(brush_transform) = brush_transform {
self.scene if self
.encode_transform(Transform::from_kurbo(&(transform * brush_transform))); .scene
self.scene.swap_last_path_tags(); .encode_transform(Transform::from_kurbo(&(transform * brush_transform)))
self.scene.encode_brush(brush, 1.0); {
} else { self.scene.swap_last_path_tags();
self.scene.encode_brush(brush, 1.0); }
} }
self.scene.encode_brush(brush, 1.0);
} }
} }
@ -164,13 +165,14 @@ impl<'a> SceneBuilder<'a> {
self.scene.encode_linewidth(style.width); self.scene.encode_linewidth(style.width);
if self.scene.encode_shape(shape, false) { if self.scene.encode_shape(shape, false) {
if let Some(brush_transform) = brush_transform { if let Some(brush_transform) = brush_transform {
self.scene if self
.encode_transform(Transform::from_kurbo(&(transform * brush_transform))); .scene
self.scene.swap_last_path_tags(); .encode_transform(Transform::from_kurbo(&(transform * brush_transform)))
self.scene.encode_brush(brush, 1.0); {
} else { self.scene.swap_last_path_tags();
self.scene.encode_brush(brush, 1.0); }
} }
self.scene.encode_brush(brush, 1.0);
} }
} }