diff options
-rw-r--r-- | components/gfx/display_list/mod.rs | 3 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 51 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/translate_clip.html | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/translate_clip_ref.html | 23 |
5 files changed, 114 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); diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index a8dc3b3dd29..6bb6318f051 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5031,6 +5031,18 @@ "url": "/_mozilla/css/transition_calc.html" } ], + "css/translate_clip.html": [ + { + "path": "css/translate_clip.html", + "references": [ + [ + "/_mozilla/css/translate_clip_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/translate_clip.html" + } + ], "css/upper_id_attr.html": [ { "path": "css/upper_id_attr.html", @@ -11525,6 +11537,18 @@ "url": "/_mozilla/css/transition_calc.html" } ], + "css/translate_clip.html": [ + { + "path": "css/translate_clip.html", + "references": [ + [ + "/_mozilla/css/translate_clip_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/translate_clip.html" + } + ], "css/upper_id_attr.html": [ { "path": "css/upper_id_attr.html", diff --git a/tests/wpt/mozilla/tests/css/translate_clip.html b/tests/wpt/mozilla/tests/css/translate_clip.html new file mode 100644 index 00000000000..96f538039a8 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/translate_clip.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="match" href="translate_clip_ref.html"> +<style> + body { + margin: 0; + } + .red { + height: 100px; + width: 100px; + overflow: hidden; + background-color: red; + } + .green { + width: 100px; + height: 100px; + position: absolute; + left: -50px; + transform: translateX(50px); + background-color: green; + } +</style> + +<div class="red"><div class="green"></div></div> diff --git a/tests/wpt/mozilla/tests/css/translate_clip_ref.html b/tests/wpt/mozilla/tests/css/translate_clip_ref.html new file mode 100644 index 00000000000..812e822b003 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/translate_clip_ref.html @@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<style> + body { + margin: 0; + } + .red { + height: 100px; + width: 100px; + overflow: hidden; + background-color: red; + } + .green { + width: 100px; + height: 100px; + position: absolute; + left: 0; + background-color: green; + } +</style> + +<div class="red"><div class="green"></div></div> + |