diff options
| author | Tom Binford <tjbof123@gmail.com> | 2023-06-24 05:28:02 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-24 14:28:02 +0200 |
| commit | fa42a26f6fa2f6e1132aec4977df2e1bccf9fc99 (patch) | |
| tree | 74d42516ca10308f4cc0d1756b857fbedf906dd7 /src/export | |
| parent | 622cef8e0052532e9b71f7a2484e6637095b9b79 (diff) | |
Improve image rendering under rotation when exporting to PNG (#1547)
Diffstat (limited to 'src/export')
| -rw-r--r-- | src/export/render.rs | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/export/render.rs b/src/export/render.rs index 3a5f0d0e..02c10e61 100644 --- a/src/export/render.rs +++ b/src/export/render.rs @@ -489,13 +489,19 @@ fn render_image( let view_height = size.y.to_f32(); let aspect = (image.width() as f32) / (image.height() as f32); - let scale = ts.sx.max(ts.sy); - let w = (scale * view_width.max(aspect * view_height)).ceil() as u32; + // For better-looking output, resize `image` to its final size before painting it to `canvas`. + // See https://github.com/typst/typst/issues/1404#issuecomment-1598374652 for the math. + let theta = f32::atan2(-ts.kx, ts.sx); + // To avoid division by 0, choose the one of { sin, cos } that is further from 0. + let prefer_sin = theta.sin().abs() > std::f32::consts::FRAC_1_SQRT_2; + let scale_x = + f32::abs(if prefer_sin { ts.kx / theta.sin() } else { ts.sx / theta.cos() }); + let w = (scale_x * view_width.max(aspect * view_height)).ceil() as u32; let h = ((w as f32) / aspect).ceil() as u32; let pixmap = scaled_texture(image, w, h)?; - let scale_x = view_width / pixmap.width() as f32; - let scale_y = view_height / pixmap.height() as f32; + let paint_scale_x = view_width / pixmap.width() as f32; + let paint_scale_y = view_height / pixmap.height() as f32; let paint = sk::Paint { shader: sk::Pattern::new( @@ -503,7 +509,7 @@ fn render_image( sk::SpreadMode::Pad, sk::FilterQuality::Nearest, 1.0, - sk::Transform::from_scale(scale_x, scale_y), + sk::Transform::from_scale(paint_scale_x, paint_scale_y), ), ..Default::default() }; |
