mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Implement enough of 3d transforms spec to run the CSS FPS demo.
This commit is contained in:
parent
d86c587925
commit
39ddbbb0e1
19 changed files with 894 additions and 145 deletions
|
@ -56,10 +56,10 @@ use std::cmp::{max, min};
|
|||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y};
|
||||
use style::computed_values::{position, text_align};
|
||||
use style::computed_values::{transform, transform_style, position, text_align};
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
use style::values::computed::{LengthOrPercentageOrNone};
|
||||
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
|
||||
use util::geometry::{Au, MAX_AU, MAX_RECT};
|
||||
use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||
use util::opts;
|
||||
|
@ -617,6 +617,33 @@ impl BlockFlow {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_requires_layer(&self) -> bool {
|
||||
// Check if the transform matrix is 2D or 3D
|
||||
if let Some(ref transform_list) = self.fragment.style().get_effects().transform {
|
||||
for transform in transform_list {
|
||||
match transform {
|
||||
&transform::ComputedOperation::Perspective(..) => {
|
||||
return true;
|
||||
}
|
||||
&transform::ComputedOperation::Matrix(m) => {
|
||||
// See http://dev.w3.org/csswg/css-transforms/#2d-matrix
|
||||
if m.m31 != 0.0 || m.m32 != 0.0 ||
|
||||
m.m13 != 0.0 || m.m23 != 0.0 ||
|
||||
m.m43 != 0.0 || m.m14 != 0.0 ||
|
||||
m.m24 != 0.0 || m.m34 != 0.0 ||
|
||||
m.m33 != 1.0 || m.m44 != 1.0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Neither perspective nor transform present
|
||||
false
|
||||
}
|
||||
|
||||
/// Compute the actual inline size and position for this block.
|
||||
pub fn compute_used_inline_size(&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
|
@ -1676,6 +1703,16 @@ impl Flow for BlockFlow {
|
|||
self.base.stacking_relative_position_of_display_port = MAX_RECT;
|
||||
}
|
||||
|
||||
// This flow needs a layer if it has a 3d transform, or provides perspective
|
||||
// to child layers. See http://dev.w3.org/csswg/css-transforms/#3d-rendering-contexts.
|
||||
let transform_style = self.fragment.style().get_used_transform_style();
|
||||
let has_3d_transform = self.transform_requires_layer();
|
||||
let has_perspective = self.fragment.style().get_effects().perspective != LengthOrNone::None;
|
||||
|
||||
if has_3d_transform || has_perspective {
|
||||
self.base.flags.insert(NEEDS_LAYER);
|
||||
}
|
||||
|
||||
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
let position_start = self.base.position.start.to_physical(self.base.writing_mode,
|
||||
container_size);
|
||||
|
@ -1818,6 +1855,16 @@ impl Flow for BlockFlow {
|
|||
|
||||
// Process children.
|
||||
for kid in self.base.child_iter() {
|
||||
// If this layer preserves the 3d context of children,
|
||||
// then children will need a render layer.
|
||||
// TODO(gw): This isn't always correct. In some cases
|
||||
// this may create extra layers than needed. I think
|
||||
// there are also some edge cases where children don't
|
||||
// get a layer when they should.
|
||||
if transform_style == transform_style::T::preserve_3d {
|
||||
flow::mut_base(kid).flags.insert(NEEDS_LAYER);
|
||||
}
|
||||
|
||||
if flow::base(kid).flags.contains(INLINE_POSITION_IS_STATIC) ||
|
||||
flow::base(kid).flags.contains(BLOCK_POSITION_IS_STATIC) {
|
||||
let kid_base = flow::mut_base(kid);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue