Fix clipping with outset (#5295)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
Eric Biedert 2024-10-28 15:31:00 +01:00 committed by GitHub
parent 6dd05cc17a
commit 45377f25ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 41 additions and 6 deletions

View File

@ -84,8 +84,7 @@ pub fn layout_single_block(
// Clip the contents, if requested.
if elem.clip(styles) {
let size = frame.size() + outset.relative_to(frame.size()).sum_by_axis();
frame.clip(clip_rect(size, &radius, &stroke));
frame.clip(clip_rect(frame.size(), &radius, &stroke, &outset));
}
// Add fill and/or stroke.
@ -231,8 +230,7 @@ pub fn layout_multi_block(
// Clip the contents, if requested.
if clip {
let size = frame.size() + outset.relative_to(frame.size()).sum_by_axis();
frame.clip(clip_rect(size, &radius, &stroke));
frame.clip(clip_rect(frame.size(), &radius, &stroke, &outset));
}
// Add fill and/or stroke.

View File

@ -61,8 +61,7 @@ pub fn layout_box(
// Clip the contents, if requested.
if elem.clip(styles) {
let size = frame.size() + outset.relative_to(frame.size()).sum_by_axis();
frame.clip(clip_rect(size, &radius, &stroke));
frame.clip(clip_rect(frame.size(), &radius, &stroke, &outset));
}
// Add fill and/or stroke.

View File

@ -412,7 +412,11 @@ pub fn clip_rect(
size: Size,
radius: &Corners<Rel<Abs>>,
stroke: &Sides<Option<FixedStroke>>,
outset: &Sides<Rel<Abs>>,
) -> Path {
let outset = outset.relative_to(size);
let size = size + outset.sum_by_axis();
let stroke_widths = stroke
.as_ref()
.map(|s| s.as_ref().map_or(Abs::zero(), |s| s.thickness / 2.0));
@ -441,6 +445,7 @@ pub fn clip_rect(
}
}
path.close_path();
path.translate(Point::new(-outset.left, -outset.top));
path
}

View File

@ -1,4 +1,5 @@
use kurbo::ParamCurveExtrema;
use typst_utils::Numeric;
use self::PathVertex::{AllControlPoints, MirroredControlPoint, Vertex};
use crate::diag::{bail, SourceResult};
@ -228,6 +229,25 @@ impl Path {
self.0.push(PathItem::ClosePath);
}
/// Translate all points in this path by the given offset.
pub fn translate(&mut self, offset: Point) {
if offset.is_zero() {
return;
}
for item in self.0.iter_mut() {
match item {
PathItem::MoveTo(p) => *p += offset,
PathItem::LineTo(p) => *p += offset,
PathItem::CubicTo(p1, p2, p3) => {
*p1 += offset;
*p2 += offset;
*p3 += offset;
}
PathItem::ClosePath => (),
}
}
}
/// Computes the size of bounding box of this path.
pub fn bbox_size(&self) -> Size {
let mut min_x = Abs::inf();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -251,6 +251,19 @@ First!
image("/assets/images/rhino.png", width: 30pt)
)
--- box-clip-outset ---
// Test clipping with `outset`.
#set page(height: 60pt)
#box(
outset: 5pt,
stroke: 2pt + black,
width: 20pt,
height: 20pt,
clip: true,
image("/assets/images/rhino.png", width: 30pt)
)
--- container-layoutable-child ---
// Test box/block sizing with directly layoutable child.
//