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
Background follow ups #25594
Background follow ups #25594
Changes from 1 commit
68edef1
42bec01
6901bf9
c8c198a
9fedade
ea4882a
f39c3ff
632e731
923cddf
37ccefb
File filter...
Jump to…
Fix combinations of `border-radius` and `background-clip`
- Loading branch information
| @@ -141,6 +141,8 @@ struct BuilderForBoxFragment<'a> { | ||||||||||||||||||
| content_rect: OnceCell<units::LayoutRect>, | ||||||||||||||||||
| border_radius: wr::BorderRadius, | ||||||||||||||||||
| border_edge_clip_id: OnceCell<Option<wr::ClipId>>, | ||||||||||||||||||
| padding_edge_clip_id: OnceCell<Option<wr::ClipId>>, | ||||||||||||||||||
| content_edge_clip_id: OnceCell<Option<wr::ClipId>>, | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| impl<'a> BuilderForBoxFragment<'a> { | ||||||||||||||||||
| @@ -178,6 +180,8 @@ impl<'a> BuilderForBoxFragment<'a> { | ||||||||||||||||||
| padding_rect: OnceCell::new(), | ||||||||||||||||||
| content_rect: OnceCell::new(), | ||||||||||||||||||
| border_edge_clip_id: OnceCell::new(), | ||||||||||||||||||
| padding_edge_clip_id: OnceCell::new(), | ||||||||||||||||||
| content_edge_clip_id: OnceCell::new(), | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @@ -201,38 +205,51 @@ impl<'a> BuilderForBoxFragment<'a> { | ||||||||||||||||||
| }) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn with_border_edge_clip( | ||||||||||||||||||
| &mut self, | ||||||||||||||||||
| builder: &mut DisplayListBuilder, | ||||||||||||||||||
| common: &mut wr::CommonItemProperties, | ||||||||||||||||||
| ) { | ||||||||||||||||||
| let initialized = self.border_edge_clip_id.init_once(|| { | ||||||||||||||||||
| if self.border_radius.is_zero() { | ||||||||||||||||||
| None | ||||||||||||||||||
| } else { | ||||||||||||||||||
| Some(builder.wr.define_clip( | ||||||||||||||||||
| &builder.current_space_and_clip, | ||||||||||||||||||
| self.border_rect, | ||||||||||||||||||
| Some(wr::ComplexClipRegion { | ||||||||||||||||||
| rect: self.border_rect, | ||||||||||||||||||
| radii: self.border_radius, | ||||||||||||||||||
| mode: wr::ClipMode::Clip, | ||||||||||||||||||
| }), | ||||||||||||||||||
| None, | ||||||||||||||||||
| )) | ||||||||||||||||||
| } | ||||||||||||||||||
| }); | ||||||||||||||||||
| if let Some(clip_id) = *initialized { | ||||||||||||||||||
| common.clip_id = clip_id | ||||||||||||||||||
| } | ||||||||||||||||||
| fn border_edge_clip(&self, builder: &mut DisplayListBuilder) -> Option<wr::ClipId> { | ||||||||||||||||||
| *self | ||||||||||||||||||
| .border_edge_clip_id | ||||||||||||||||||
| .init_once(|| clip_for_radii(self.border_radius, self.border_rect, builder)) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn padding_edge_clip(&self, builder: &mut DisplayListBuilder) -> Option<wr::ClipId> { | ||||||||||||||||||
| *self.padding_edge_clip_id.init_once(|| { | ||||||||||||||||||
| clip_for_radii( | ||||||||||||||||||
| inner_radii( | ||||||||||||||||||
| self.border_radius, | ||||||||||||||||||
| self.fragment | ||||||||||||||||||
| .border | ||||||||||||||||||
| .to_physical(self.fragment.style.writing_mode) | ||||||||||||||||||
| .to_webrender(), | ||||||||||||||||||
| ), | ||||||||||||||||||
| self.border_rect, | ||||||||||||||||||
| builder, | ||||||||||||||||||
| ) | ||||||||||||||||||
| }) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn content_edge_clip(&self, builder: &mut DisplayListBuilder) -> Option<wr::ClipId> { | ||||||||||||||||||
| *self.content_edge_clip_id.init_once(|| { | ||||||||||||||||||
|
||||||||||||||||||
| clip_for_radii( | ||||||||||||||||||
| inner_radii( | ||||||||||||||||||
| self.border_radius, | ||||||||||||||||||
| (&self.fragment.border + &self.fragment.padding) | ||||||||||||||||||
| .to_physical(self.fragment.style.writing_mode) | ||||||||||||||||||
| .to_webrender(), | ||||||||||||||||||
| ), | ||||||||||||||||||
| self.border_rect, | ||||||||||||||||||
| builder, | ||||||||||||||||||
| ) | ||||||||||||||||||
| }) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn build(&mut self, builder: &mut DisplayListBuilder) { | ||||||||||||||||||
| let hit_info = hit_info(&self.fragment.style, self.fragment.tag, Cursor::Default); | ||||||||||||||||||
| if hit_info.is_some() { | ||||||||||||||||||
| let mut common = builder.common_properties(self.border_rect); | ||||||||||||||||||
| common.hit_info = hit_info; | ||||||||||||||||||
| self.with_border_edge_clip(builder, &mut common); | ||||||||||||||||||
| if let Some(clip_id) = self.border_edge_clip(builder) { | ||||||||||||||||||
mrobinson
Member
|
||||||||||||||||||
| // FIXME: use this for the `overflow` property or anything else that clips an entire subtree. | |
| #[allow(unused)] | |
| fn clipping_and_scrolling_scope<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { | |
| let previous = self.current_space_and_clip; | |
| let result = f(self); | |
| self.current_space_and_clip = previous; | |
| result | |
| } |
… which I copied from Layout 2013 code, but ended up not using for backgrounds because each background layer has a potentially-different background-clip value that only applies to one display item, so pushing/popping to the stack isn’t as useful.
Nice use of init_once here and above!