-
-
Notifications
You must be signed in to change notification settings - Fork 853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix box/block clipping when no stroke set #2526
Conversation
64dfa8d
to
54e4655
Compare
I wonder whether the fallback stroke should have default width or rather 0pt width. cc: @Dherse |
Just an observation, but when I was experimenting with it yesterday, the width of the stroke did not affect the clipping result. Though I guess it would make sense to default it to 0pt, just in case the width is ever taken into account when clipping. |
The stroke width is taken into account when computing the border radius, so I think it might have an effect here. Not entirely sure about this though. |
If I analyzed the code path correctly, it does seem that stroke width will default to 0, which is considered in calculations: typst/crates/typst/src/geom/rect.rs Lines 161 to 170 in 8fd5467
However, that doesn't explain why setting stroke to |
Okay, I ran a debugger, and the difference is that the typst/crates/typst/src/geom/rect.rs Lines 146 to 149 in 8fd5467
Note that just changing the top stroke to I believe the PR as is, thus, will likely produce regressions when not all strokes are |
Therefore, in principle, it could work to apply the following fix instead (which, locally, seems to solve the problem at hand): diff --git a/crates/typst/src/geom/rect.rs b/crates/typst/src/geom/rect.rs
index 37b94527..319270f6 100644
--- a/crates/typst/src/geom/rect.rs
+++ b/crates/typst/src/geom/rect.rs
@@ -143,7 +143,7 @@ fn segmented_path_rect(
last = current;
path_segment(start, end, &corners, &mut path);
}
- } else if strokes.top.is_some() {
+ } else if strokes.top.is_some() || strokes.iter().all(Option::is_none) {
// single segment
path_segment(Corner::TopLeft, Corner::TopLeft, &corners, &mut path);
} However:
In particular, the change above can cause regressions in other locations which use that function (all tests currently pass, but caution is advised). It might be better, thus, to use a safer alternative from within diff --git a/crates/typst-library/src/layout/container.rs b/crates/typst-library/src/layout/container.rs
index 36b62864..252f23e6 100644
--- a/crates/typst-library/src/layout/container.rs
+++ b/crates/typst-library/src/layout/container.rs
@@ -421,6 +421,13 @@ impl Layout for BlockElem {
let outset = self.outset(styles).relative_to(frame.size());
let size = frame.size() + outset.sum_by_axis();
let radius = self.radius(styles);
+ let stroke = if stroke.iter().all(Option::is_none) {
+ stroke.clone().map(|_| {
+ Some(FixedStroke { thickness: Abs::zero(), ..Default::default() })
+ })
+ } else {
+ stroke.clone()
+ };
frame.clip(path_rect(size, radius, &stroke));
}
} I'm not sure which one is better as I didn't write the original code, so I'll let others give their opinions! |
@PgBiel I don't think you need my approval to fix a bug 😂 , this is indeed an issue, did it exist before my clip fix PR? I also noticed another issue, in SVG, it seems that boxes always clip. |
With limited knowledge about clipping. It looks like At the moment the middle of the stroke is used for clipping, which ignores the radius. |
Sorry if I didn't make myself clear; I meant approval as in make sure I'm not spitting out a bunch of lies about your code since I know next to nothing about it 😅 |
What's the status of this? |
I believe the PR shouldn't be merged as is, as I believe it could cause regressions. I proposed two alternative patches (one of which is very unlikely to cause regressions) as a stopgap, but that's likely a worse alternative than finding a proper solution in the clipping logic. @antonWetzel proposed two more lengthy alternative solutions instead, which are likely more appropriate than mine. Perhaps their solutions should be proposed separately and tested. |
Superseded by #2626, which resulted from the discussion here. Thanks everybody! |
The clipping had no effect when no stroke was set, which I found a bit unexpected. This PR attempts to fix that by falling back to a default for the purpose of clipping.
For reference, the original fix for clipping was implemented in #2338.