diff options
| author | Eric Biedert <github@ericbiedert.de> | 2024-08-05 12:24:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-05 10:24:22 +0000 |
| commit | ed247797ac17e0975d6663d65b0976ab92130d80 (patch) | |
| tree | 32e957ed0ce6da03a780fee0952452a8322d5cce | |
| parent | dfdcc197c019b4ca5bc09487ee5f36030704b334 (diff) | |
Fix alignment of gradients and patterns on strokes in PNG (#4634)
| -rw-r--r-- | crates/typst-render/src/paint.rs | 16 | ||||
| -rw-r--r-- | tests/ref/gradient-linear-stroke-relative-parent.png | bin | 0 -> 139 bytes | |||
| -rw-r--r-- | tests/ref/pattern-stroke-relative-parent.png | bin | 0 -> 757 bytes | |||
| -rw-r--r-- | tests/ref/pattern-stroke.png | bin | 248 -> 383 bytes | |||
| -rw-r--r-- | tests/suite/visualize/gradient.typ | 16 | ||||
| -rw-r--r-- | tests/suite/visualize/pattern.typ | 24 |
6 files changed, 54 insertions, 2 deletions
diff --git a/crates/typst-render/src/paint.rs b/crates/typst-render/src/paint.rs index 2b5c19c9..3a507ca4 100644 --- a/crates/typst-render/src/paint.rs +++ b/crates/typst-render/src/paint.rs @@ -185,6 +185,12 @@ pub fn to_sk_paint<'a>( .container_transform .post_concat(state.transform.invert().unwrap()), }; + + let gradient_map = match relative { + RelativeTo::Self_ => gradient_map, + RelativeTo::Parent => None, + }; + let width = (container_size.x.to_f32().abs() * state.pixel_per_pt).ceil() as u32; let height = @@ -225,6 +231,13 @@ pub fn to_sk_paint<'a>( let canvas = render_pattern_frame(&state, pattern); *pixmap = Some(Arc::new(canvas)); + let offset = match relative { + RelativeTo::Self_ => { + gradient_map.map(|(offset, _)| -offset).unwrap_or_default() + } + RelativeTo::Parent => Point::zero(), + }; + // Create the shader sk_paint.shader = sk::Pattern::new( pixmap.as_ref().unwrap().as_ref().as_ref(), @@ -232,7 +245,8 @@ pub fn to_sk_paint<'a>( sk::FilterQuality::Nearest, 1.0, fill_transform - .pre_scale(1.0 / state.pixel_per_pt, 1.0 / state.pixel_per_pt), + .pre_scale(1.0 / state.pixel_per_pt, 1.0 / state.pixel_per_pt) + .pre_translate(offset.x.to_f32(), offset.y.to_f32()), ); } } diff --git a/tests/ref/gradient-linear-stroke-relative-parent.png b/tests/ref/gradient-linear-stroke-relative-parent.png Binary files differnew file mode 100644 index 00000000..60da4ee8 --- /dev/null +++ b/tests/ref/gradient-linear-stroke-relative-parent.png diff --git a/tests/ref/pattern-stroke-relative-parent.png b/tests/ref/pattern-stroke-relative-parent.png Binary files differnew file mode 100644 index 00000000..fe9b1174 --- /dev/null +++ b/tests/ref/pattern-stroke-relative-parent.png diff --git a/tests/ref/pattern-stroke.png b/tests/ref/pattern-stroke.png Binary files differindex 8b03783b..a9f30aa8 100644 --- a/tests/ref/pattern-stroke.png +++ b/tests/ref/pattern-stroke.png diff --git a/tests/suite/visualize/gradient.typ b/tests/suite/visualize/gradient.typ index c3794150..61f6b6d0 100644 --- a/tests/suite/visualize/gradient.typ +++ b/tests/suite/visualize/gradient.typ @@ -175,6 +175,22 @@ ) ) +--- gradient-linear-stroke-relative-parent --- +// The image should look as if there is a single gradient that is being used for +// both the circle stroke and the block fill. +#align( + center + horizon, + block( + width: 50pt, + height: 50pt, + fill: gradient.linear(red, blue).sharp(4), + circle( + radius: 18pt, + stroke: 5pt + gradient.linear(red, blue, relative: "parent").sharp(4), + ) + ) +) + --- gradient-linear-line --- // Test gradient on lines #set page(width: 100pt, height: 100pt) diff --git a/tests/suite/visualize/pattern.typ b/tests/suite/visualize/pattern.typ index b0c92efa..b87b7755 100644 --- a/tests/suite/visualize/pattern.typ +++ b/tests/suite/visualize/pattern.typ @@ -101,13 +101,35 @@ center + top, square( size: 50pt, - stroke: 5pt + pattern( + fill: pattern( size: (5pt, 5pt), align(horizon + center, circle(fill: blue, radius: 2.5pt)) + ), + stroke: 7.5pt + pattern( + size: (5pt, 5pt), + align(horizon + center, circle(fill: red, radius: 2.5pt)) ) ) ) +--- pattern-stroke-relative-parent --- +// Test pattern on strokes with relative set to `"parent"` +// The pattern on the circle should align with the pattern on the square. +#align( + center + top, + block( + width: 50pt, + height: 50pt, + fill: pattern(size: (5pt, 5pt), circle(radius: 2.5pt, fill: blue)), + align(center + horizon, circle( + radius: 15pt, + stroke: 7.5pt + pattern( + size: (5pt, 5pt), circle(radius: 2.5pt, fill: red), relative: "parent" + ), + )) + ) +) + --- pattern-text --- // Test a pattern on some text // You shouldn't be able to see the text, if you can then |
