diff options
author | Michael Howell <michael@notriddle.com> | 2016-04-08 13:50:42 -0700 |
---|---|---|
committer | Michael Howell <michael@notriddle.com> | 2016-04-12 14:39:13 -0700 |
commit | 6c9efbf383cfdf4590e2a03ea02e09483faeb2d0 (patch) | |
tree | 71b213f7f640c6b2605b01cdb60283cbf44322af /components | |
parent | 3b7e426d33e539303f46a0a153752683838186fc (diff) | |
download | servo-6c9efbf383cfdf4590e2a03ea02e09483faeb2d0.tar.gz servo-6c9efbf383cfdf4590e2a03ea02e09483faeb2d0.zip |
Take transform:translate into account when computing clipping regions.
Note that this only works for translation; a more general fix would
require major changes to how display lists work.
Closes #10431?
Diffstat (limited to 'components')
-rw-r--r-- | components/gfx/display_list/mod.rs | 3 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 51 |
2 files changed, 43 insertions, 11 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 16ac9a29ea7..ee40b1c75bc 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -1388,7 +1388,7 @@ impl DisplayItem { impl fmt::Debug for DisplayItem { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} @ {:?}", + write!(f, "{} @ {:?} {:?}", match *self { DisplayItem::SolidColorClass(ref solid_color) => format!("SolidColor rgba({}, {}, {}, {})", @@ -1408,6 +1408,7 @@ impl fmt::Debug for DisplayItem { DisplayItem::IframeClass(_) => "Iframe".to_owned(), }, self.bounds(), + self.base().clip ) } } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index d2ca90fa884..9b1c5bd0262 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -1743,15 +1743,46 @@ impl BlockFlowDisplayListBuilding for BlockFlow { }; // Add the box that starts the block context. - let translated_clip = if establishes_stacking_context { - Some(self.base.clip.translate(&-self.base.stacking_relative_position)) - } else { - None - }; - let clip = match translated_clip { - Some(ref translated_clip) => translated_clip, - None => &self.base.clip, - }; + let mut clip = self.base.clip.clone(); + + if establishes_stacking_context { + clip = clip.translate(&-self.base.stacking_relative_position) + } + + // TODO(notriddle): To properly support transformations, we either need + // non-rectangular clipping regions in display lists, or clipping + // regions in terms of the parent coordinate system instead of the + // child coordinate system. + // + // This is a workaround for a common idiom of transform: translate(). + if let Some(ref operations) = self.fragment.style().get_effects().transform.0 { + for operation in operations { + match *operation { + transform::ComputedOperation::Translate(tx, ty, _) => { + // N.B. When the clipping value comes from us, it + // shouldn't be transformed. + let tx = if let overflow_x::T::hidden = self.fragment.style().get_box() + .overflow_x { + Au(0) + } else { + model::specified(tx, self.base.block_container_inline_size) + }; + let ty = if let overflow_x::T::hidden = self.fragment.style().get_box() + .overflow_y.0 { + Au(0) + } else { + model::specified( + ty, + self.base.block_container_explicit_block_size.unwrap_or(Au(0)) + ) + }; + let off = Point2D::new(tx, ty); + clip = clip.translate(&-off); + } + _ => {} + }; + } + } self.fragment .build_display_list(state, @@ -1764,7 +1795,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { .relative_containing_block_mode, border_painting_mode, background_border_section, - clip, + &clip, &self.base.stacking_relative_position_of_display_port); self.base.build_display_items_for_debugging_tint(state, self.fragment.node); |