summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshinyfelix <101457412+shinyfelix@users.noreply.github.com>2024-07-20 14:26:57 +0200
committerGitHub <noreply@github.com>2024-07-20 12:26:57 +0000
commit3aa18beacf84e8e982a1cb28170d281769c06dd0 (patch)
treef565a4b5162c1e660f9cf71bbe93c997cb802115
parent3ef0991fbb688c22c1d6d0a78c52a5bae3f56f7d (diff)
Fix approximated size of `reflow: true` transformations (#4462)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
-rw-r--r--crates/typst/src/layout/transform.rs33
-rw-r--r--tests/ref/transform-scale-relative-sizing.pngbin1975 -> 2033 bytes
-rw-r--r--tests/ref/transform-scale.pngbin1802 -> 1804 bytes
3 files changed, 18 insertions, 15 deletions
diff --git a/crates/typst/src/layout/transform.rs b/crates/typst/src/layout/transform.rs
index ad3668d1..dcb178fd 100644
--- a/crates/typst/src/layout/transform.rs
+++ b/crates/typst/src/layout/transform.rs
@@ -12,6 +12,7 @@ use crate::layout::{
Abs, Alignment, Angle, Axes, BlockElem, FixedAlignment, Frame, HAlignment, Length,
Point, Ratio, Region, Regions, Rel, Size, VAlignment,
};
+use crate::utils::Numeric;
/// Moves content without affecting layout.
///
@@ -153,12 +154,11 @@ fn layout_rotate(
let align = elem.origin(styles).resolve(styles);
// Compute the new region's approximate size.
- let size = region
- .size
- .to_point()
- .transform_inf(Transform::rotate(angle))
- .map(Abs::abs)
- .to_size();
+ let size = if region.size.is_finite() {
+ compute_bounding_box(region.size, Transform::rotate(-angle)).1
+ } else {
+ Size::splat(Abs::inf())
+ };
measure_and_layout(
engine,
@@ -248,7 +248,10 @@ fn layout_scale(
) -> SourceResult<Frame> {
// Compute the new region's approximate size.
let scale = elem.resolve_scale(engine, locator.relayout(), region.size, styles)?;
- let size = region.size.zip_map(scale, |r, s| s.of(r)).map(Abs::abs);
+ let size = region
+ .size
+ .zip_map(scale, |r, s| if r.is_finite() { Ratio::new(1.0 / s).of(r) } else { r })
+ .map(Abs::abs);
measure_and_layout(
engine,
@@ -489,7 +492,7 @@ fn measure_and_layout(
.pre_concat(Transform::translate(-x, -y));
// Compute the bounding box and offset and wrap in a new frame.
- let (offset, size) = compute_bounding_box(&frame, ts);
+ let (offset, size) = compute_bounding_box(frame.size(), ts);
frame.transform(ts);
frame.translate(offset);
frame.set_size(size);
@@ -512,20 +515,20 @@ fn measure_and_layout(
}
}
-/// Computes the bounding box and offset of a transformed frame.
-fn compute_bounding_box(frame: &Frame, ts: Transform) -> (Point, Size) {
+/// Computes the bounding box and offset of a transformed area.
+fn compute_bounding_box(size: Size, ts: Transform) -> (Point, Size) {
let top_left = Point::zero().transform_inf(ts);
- let top_right = Point::new(frame.width(), Abs::zero()).transform_inf(ts);
- let bottom_left = Point::new(Abs::zero(), frame.height()).transform_inf(ts);
- let bottom_right = Point::new(frame.width(), frame.height()).transform_inf(ts);
+ let top_right = Point::with_x(size.x).transform_inf(ts);
+ let bottom_left = Point::with_y(size.y).transform_inf(ts);
+ let bottom_right = size.to_point().transform_inf(ts);
- // We first compute the new bounding box of the rotated frame.
+ // We first compute the new bounding box of the rotated area.
let min_x = top_left.x.min(top_right.x).min(bottom_left.x).min(bottom_right.x);
let min_y = top_left.y.min(top_right.y).min(bottom_left.y).min(bottom_right.y);
let max_x = top_left.x.max(top_right.x).max(bottom_left.x).max(bottom_right.x);
let max_y = top_left.y.max(top_right.y).max(bottom_left.y).max(bottom_right.y);
- // Then we compute the new size of the frame.
+ // Then we compute the new size of the area.
let width = max_x - min_x;
let height = max_y - min_y;
diff --git a/tests/ref/transform-scale-relative-sizing.png b/tests/ref/transform-scale-relative-sizing.png
index d10bd3ff..a6c18a98 100644
--- a/tests/ref/transform-scale-relative-sizing.png
+++ b/tests/ref/transform-scale-relative-sizing.png
Binary files differ
diff --git a/tests/ref/transform-scale.png b/tests/ref/transform-scale.png
index c95b90f1..ea113aa1 100644
--- a/tests/ref/transform-scale.png
+++ b/tests/ref/transform-scale.png
Binary files differ