diff options
Diffstat (limited to 'components/layout/display_list/clip_path.rs')
-rw-r--r-- | components/layout/display_list/clip_path.rs | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/components/layout/display_list/clip_path.rs b/components/layout/display_list/clip_path.rs deleted file mode 100644 index 419d15c3572..00000000000 --- a/components/layout/display_list/clip_path.rs +++ /dev/null @@ -1,259 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use app_units::Au; -use base::id::ScrollTreeNodeId; -use style::values::computed::basic_shape::{BasicShape, ClipPath}; -use style::values::computed::length_percentage::NonNegativeLengthPercentage; -use style::values::computed::position::Position; -use style::values::generics::basic_shape::{GenericShapeRadius, ShapeBox, ShapeGeometryBox}; -use style::values::generics::position::GenericPositionOrAuto; -use webrender_api::ClipChainId; -use webrender_api::units::{LayoutRect, LayoutSideOffsets, LayoutSize}; - -use super::{BuilderForBoxFragment, DisplayList, compute_margin_box_radius, normalize_radii}; - -pub(super) fn build_clip_path_clip_chain_if_necessary( - clip_path: ClipPath, - display_list: &mut DisplayList, - parent_scroll_node_id: &ScrollTreeNodeId, - parent_clip_chain_id: &ClipChainId, - fragment_builder: BuilderForBoxFragment, -) -> Option<ClipChainId> { - let geometry_box = match clip_path { - ClipPath::Shape(_, ShapeGeometryBox::ShapeBox(shape_box)) => shape_box, - ClipPath::Shape(_, ShapeGeometryBox::ElementDependent) => ShapeBox::BorderBox, - ClipPath::Box(ShapeGeometryBox::ShapeBox(shape_box)) => shape_box, - ClipPath::Box(ShapeGeometryBox::ElementDependent) => ShapeBox::BorderBox, - _ => return None, - }; - let layout_rect = match geometry_box { - ShapeBox::BorderBox => fragment_builder.border_rect, - ShapeBox::ContentBox => *fragment_builder.content_rect(), - ShapeBox::PaddingBox => *fragment_builder.padding_rect(), - ShapeBox::MarginBox => *fragment_builder.margin_rect(), - }; - if let ClipPath::Shape(shape, _) = clip_path { - match *shape { - BasicShape::Circle(_) | BasicShape::Ellipse(_) | BasicShape::Rect(_) => { - build_simple_shape( - *shape, - layout_rect, - parent_scroll_node_id, - parent_clip_chain_id, - display_list, - ) - }, - BasicShape::Polygon(_) | BasicShape::PathOrShape(_) => None, - } - } else { - Some(create_rect_clip_chain( - match geometry_box { - ShapeBox::MarginBox => compute_margin_box_radius( - fragment_builder.border_radius, - layout_rect.size(), - fragment_builder.fragment, - ), - _ => fragment_builder.border_radius, - }, - layout_rect, - parent_scroll_node_id, - parent_clip_chain_id, - display_list, - )) - } -} - -#[cfg_attr( - feature = "tracing", - tracing::instrument( - name = "display_list::build_simple_shape", - skip_all, - fields(servo_profiling = true), - level = "trace", - ) -)] -fn build_simple_shape( - shape: BasicShape, - layout_box: LayoutRect, - parent_scroll_node_id: &ScrollTreeNodeId, - parent_clip_chain_id: &ClipChainId, - display_list: &mut DisplayList, -) -> Option<ClipChainId> { - match shape { - BasicShape::Rect(rect) => { - let box_height = Au::from_f32_px(layout_box.height()); - let box_width = Au::from_f32_px(layout_box.width()); - let insets = LayoutSideOffsets::new( - rect.rect.0.to_used_value(box_height).to_f32_px(), - rect.rect.1.to_used_value(box_width).to_f32_px(), - rect.rect.2.to_used_value(box_height).to_f32_px(), - rect.rect.3.to_used_value(box_width).to_f32_px(), - ); - - // `inner_rect()` will cause an assertion failure if the insets are larger than the - // rectangle dimension. - let shape_rect = if insets.left + insets.right >= layout_box.width() || - insets.top + insets.bottom > layout_box.height() - { - LayoutRect::from_origin_and_size(layout_box.min, LayoutSize::zero()) - } else { - layout_box.to_rect().inner_rect(insets).to_box2d() - }; - - let corner = |corner: &style::values::computed::BorderCornerRadius| { - LayoutSize::new( - corner.0.width.0.to_used_value(box_width).to_f32_px(), - corner.0.height.0.to_used_value(box_height).to_f32_px(), - ) - }; - let mut radii = webrender_api::BorderRadius { - top_left: corner(&rect.round.top_left), - top_right: corner(&rect.round.top_right), - bottom_left: corner(&rect.round.bottom_left), - bottom_right: corner(&rect.round.bottom_right), - }; - normalize_radii(&layout_box, &mut radii); - Some(create_rect_clip_chain( - radii, - shape_rect, - parent_scroll_node_id, - parent_clip_chain_id, - display_list, - )) - }, - BasicShape::Circle(circle) => { - let center = match circle.position { - GenericPositionOrAuto::Position(position) => position, - GenericPositionOrAuto::Auto => Position::center(), - }; - let anchor_x = center - .horizontal - .to_used_value(Au::from_f32_px(layout_box.width())); - let anchor_y = center - .vertical - .to_used_value(Au::from_f32_px(layout_box.height())); - let center = layout_box - .min - .add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px())); - - let horizontal = - compute_shape_radius(center.x, &circle.radius, layout_box.min.x, layout_box.max.x); - let vertical = - compute_shape_radius(center.y, &circle.radius, layout_box.min.y, layout_box.max.y); - - // If the value is `Length` then both values should be the same at this point. - let radius = match circle.radius { - GenericShapeRadius::FarthestSide => horizontal.max(vertical), - GenericShapeRadius::ClosestSide => horizontal.min(vertical), - GenericShapeRadius::Length(_) => horizontal, - }; - let radius = LayoutSize::new(radius, radius); - let mut radii = webrender_api::BorderRadius { - top_left: radius, - top_right: radius, - bottom_left: radius, - bottom_right: radius, - }; - let start = center.add_size(&-radius); - let rect = LayoutRect::from_origin_and_size(start, radius * 2.); - normalize_radii(&layout_box, &mut radii); - Some(create_rect_clip_chain( - radii, - rect, - parent_scroll_node_id, - parent_clip_chain_id, - display_list, - )) - }, - BasicShape::Ellipse(ellipse) => { - let center = match ellipse.position { - GenericPositionOrAuto::Position(position) => position, - GenericPositionOrAuto::Auto => Position::center(), - }; - let anchor_x = center - .horizontal - .to_used_value(Au::from_f32_px(layout_box.width())); - let anchor_y = center - .vertical - .to_used_value(Au::from_f32_px(layout_box.height())); - let center = layout_box - .min - .add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px())); - - let width = compute_shape_radius( - center.x, - &ellipse.semiaxis_x, - layout_box.min.x, - layout_box.max.x, - ); - let height = compute_shape_radius( - center.y, - &ellipse.semiaxis_y, - layout_box.min.y, - layout_box.max.y, - ); - - let mut radii = webrender_api::BorderRadius { - top_left: LayoutSize::new(width, height), - top_right: LayoutSize::new(width, height), - bottom_left: LayoutSize::new(width, height), - bottom_right: LayoutSize::new(width, height), - }; - let size = LayoutSize::new(width, height); - let start = center.add_size(&-size); - let rect = LayoutRect::from_origin_and_size(start, size * 2.); - normalize_radii(&rect, &mut radii); - Some(create_rect_clip_chain( - radii, - rect, - parent_scroll_node_id, - parent_clip_chain_id, - display_list, - )) - }, - _ => None, - } -} - -fn compute_shape_radius( - center: f32, - radius: &GenericShapeRadius<NonNegativeLengthPercentage>, - min_edge: f32, - max_edge: f32, -) -> f32 { - let distance_from_min_edge = (min_edge - center).abs(); - let distance_from_max_edge = (max_edge - center).abs(); - match radius { - GenericShapeRadius::FarthestSide => distance_from_min_edge.max(distance_from_max_edge), - GenericShapeRadius::ClosestSide => distance_from_min_edge.min(distance_from_max_edge), - GenericShapeRadius::Length(length) => length - .0 - .to_used_value(Au::from_f32_px(max_edge - min_edge)) - .to_f32_px(), - } -} -fn create_rect_clip_chain( - radii: webrender_api::BorderRadius, - rect: LayoutRect, - parent_scroll_node_id: &ScrollTreeNodeId, - parent_clip_chain_id: &ClipChainId, - display_list: &mut DisplayList, -) -> ClipChainId { - let new_clip_id = if radii.is_zero() { - display_list - .wr - .define_clip_rect(parent_scroll_node_id.spatial_id, rect) - } else { - display_list.wr.define_clip_rounded_rect( - parent_scroll_node_id.spatial_id, - webrender_api::ComplexClipRegion { - rect, - radii, - mode: webrender_api::ClipMode::Clip, - }, - ) - }; - display_list.define_clip_chain(*parent_clip_chain_id, [new_clip_id]) -} |