Update WR (reference frames for fixed position elements).

This commit is contained in:
Glenn Watson 2017-03-03 09:46:24 +10:00
parent fa32d50c7a
commit 750794eb77
7 changed files with 73 additions and 56 deletions

View file

@ -182,17 +182,25 @@ impl DisplayList {
*client_point
} else {
let point = *translated_point - stacking_context.bounds.origin;
let inv_transform = match stacking_context.transform.inverse() {
Some(transform) => transform,
None => {
// If a transform function causes the current transformation matrix of an object
// to be non-invertible, the object and its content do not get displayed.
return;
match stacking_context.transform {
Some(transform) => {
let inv_transform = match transform.inverse() {
Some(transform) => transform,
None => {
// If a transform function causes the current transformation matrix of an object
// to be non-invertible, the object and its content do not get displayed.
return;
}
};
let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
point.y.to_f32_px()));
Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
}
};
let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
point.y.to_f32_px()));
Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
None => {
point
}
}
};
}
@ -360,10 +368,10 @@ pub struct StackingContext {
pub blend_mode: mix_blend_mode::T,
/// A transform to be applied to this stacking context.
pub transform: Matrix4D<f32>,
pub transform: Option<Matrix4D<f32>>,
/// The perspective matrix to be applied to children.
pub perspective: Matrix4D<f32>,
pub perspective: Option<Matrix4D<f32>>,
/// Whether this stacking context creates a new 3d rendering context.
pub establishes_3d_context: bool,
@ -385,8 +393,8 @@ impl StackingContext {
z_index: i32,
filters: filter::T,
blend_mode: mix_blend_mode::T,
transform: Matrix4D<f32>,
perspective: Matrix4D<f32>,
transform: Option<Matrix4D<f32>>,
perspective: Option<Matrix4D<f32>>,
establishes_3d_context: bool,
scroll_policy: ScrollPolicy,
parent_scroll_id: ScrollRootId)
@ -416,8 +424,8 @@ impl StackingContext {
0,
filter::T::new(Vec::new()),
mix_blend_mode::T::normal,
Matrix4D::identity(),
Matrix4D::identity(),
None,
None,
true,
ScrollPolicy::Scrollable,
ScrollRootId::root())

View file

@ -31,7 +31,7 @@ use app_units::{Au, MAX_AU};
use context::LayoutContext;
use display_list_builder::{BorderPaintingMode, DisplayListBuildState, FragmentDisplayListBuilding};
use display_list_builder::BlockFlowDisplayListBuilding;
use euclid::{Point2D, Rect, Size2D};
use euclid::{Matrix4D, Point2D, Rect, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
@ -1811,6 +1811,7 @@ impl BlockFlow {
}
let transform = match self.fragment
.transform_matrix(&stacking_relative_border_box)
.unwrap_or(Matrix4D::identity())
.inverse() {
Some(transform) => transform,
None => {

View file

@ -29,7 +29,7 @@ use app_units::Au;
use block::{BlockFlow, FormattingContextType};
use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
use euclid::{Point2D, Size2D};
use euclid::{Matrix4D, Point2D, Size2D};
use flex::FlexFlow;
use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, MutFlowListIterator};
@ -272,7 +272,11 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
// TODO: Take into account 3d transforms, even though it's a fairly
// uncommon case.
let transform_2d = self.as_block().fragment.transform_matrix(&position).to_2d();
let transform_2d = self.as_block()
.fragment
.transform_matrix(&position)
.unwrap_or(Matrix4D::identity())
.to_2d();
let transformed_overflow = Overflow {
paint: f32_rect_to_au_rect(transform_2d.transform_rect(
&au_rect_to_f32_rect(overflow.paint))),

View file

@ -2873,13 +2873,13 @@ impl Fragment {
}
/// Returns the 4D matrix representing this fragment's transform.
pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Matrix4D<f32> {
let mut transform = Matrix4D::identity();
pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Matrix4D<f32>> {
let operations = match self.style.get_box().transform.0 {
None => return transform,
None => return None,
Some(ref operations) => operations,
};
let mut transform = Matrix4D::identity();
let transform_origin = &self.style.get_box().transform_origin;
let transform_origin_x = model::specified(transform_origin.horizontal,
stacking_relative_border_box.size
@ -2928,11 +2928,11 @@ impl Fragment {
transform = transform.pre_mul(&matrix);
}
pre_transform.pre_mul(&transform).pre_mul(&post_transform)
Some(pre_transform.pre_mul(&transform).pre_mul(&post_transform))
}
/// Returns the 4D matrix representing this fragment's perspective.
pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Matrix4D<f32> {
pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Matrix4D<f32>> {
match self.style().get_box().perspective {
Either::First(length) => {
let perspective_origin = self.style().get_box().perspective_origin;
@ -2951,10 +2951,10 @@ impl Fragment {
let perspective_matrix = create_perspective_matrix(length);
pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform)
Some(pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform))
}
Either::Second(values::None_) => {
Matrix4D::identity()
None
}
}
}

View file

@ -381,12 +381,19 @@ impl WebRenderDisplayItemConverter for DisplayItem {
vec![],
None);
let transform = stacking_context.transform.map(|transform| {
LayoutTransform::from_untyped(&transform).into()
});
let perspective = stacking_context.perspective.map(|perspective| {
LayoutTransform::from_untyped(&perspective)
});
builder.push_stacking_context(stacking_context.scroll_policy,
stacking_context.bounds.to_rectf(),
clip,
stacking_context.z_index,
LayoutTransform::from_untyped(&stacking_context.transform).into(),
LayoutTransform::from_untyped(&stacking_context.perspective),
transform,
perspective,
stacking_context.blend_mode.to_blend_mode(),
stacking_context.filters.to_filter_ops());
}