servo: Merge #10486 - Take transform:translate into account when computing clipping regions (from notriddle:overflow_premature_clip); r=pcwalton

Note that this only works for translation; a more general fix would
require major changes to how display lists work.

Closes #10431?

Source-Repo: https://github.com/servo/servo
Source-Revision: 7e63c1be63716e6f190416b512caa12afb4cda52
This commit is contained in:
Michael Howell 2016-04-13 06:43:38 +05:01
Родитель 6a601b508f
Коммит 0bb050408c
2 изменённых файлов: 43 добавлений и 11 удалений

Просмотреть файл

@ -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
)
}
}

Просмотреть файл

@ -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);