mirror of
https://github.com/typst/typst
synced 2025-05-18 02:55:28 +08:00
Fix approximated size of reflow: true
transformations (#4462)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
parent
3ef0991fbb
commit
3aa18beacf
@ -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;
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Loading…
x
Reference in New Issue
Block a user