mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use typed transforms in stacking contexts
This commit is contained in:
parent
615e38f186
commit
279cda65ed
6 changed files with 51 additions and 53 deletions
|
@ -14,7 +14,7 @@
|
||||||
//! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
|
//! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
|
||||||
//! low-level drawing primitives.
|
//! low-level drawing primitives.
|
||||||
|
|
||||||
use euclid::{Transform3D, Vector2D, TypedRect, SideOffsets2D};
|
use euclid::{Vector2D, TypedRect, SideOffsets2D};
|
||||||
use euclid::num::{One, Zero};
|
use euclid::num::{One, Zero};
|
||||||
use gfx_traits::{self, StackingContextId};
|
use gfx_traits::{self, StackingContextId};
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
|
@ -33,8 +33,8 @@ use text::glyph::ByteIndex;
|
||||||
use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, ColorF};
|
use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, ColorF};
|
||||||
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
|
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
|
||||||
use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
|
use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
|
||||||
use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutVector2D, LineStyle, LocalClip};
|
use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineStyle};
|
||||||
use webrender_api::{MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity};
|
use webrender_api::{LocalClip, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity};
|
||||||
use webrender_api::{StickyOffsetBounds, TransformStyle};
|
use webrender_api::{StickyOffsetBounds, TransformStyle};
|
||||||
|
|
||||||
pub use style::dom::OpaqueNode;
|
pub use style::dom::OpaqueNode;
|
||||||
|
@ -209,13 +209,13 @@ pub struct StackingContext {
|
||||||
pub mix_blend_mode: MixBlendMode,
|
pub mix_blend_mode: MixBlendMode,
|
||||||
|
|
||||||
/// A transform to be applied to this stacking context.
|
/// A transform to be applied to this stacking context.
|
||||||
pub transform: Option<Transform3D<f32>>,
|
pub transform: Option<LayoutTransform>,
|
||||||
|
|
||||||
/// The transform style of this stacking context.
|
/// The transform style of this stacking context.
|
||||||
pub transform_style: TransformStyle,
|
pub transform_style: TransformStyle,
|
||||||
|
|
||||||
/// The perspective matrix to be applied to children.
|
/// The perspective matrix to be applied to children.
|
||||||
pub perspective: Option<Transform3D<f32>>,
|
pub perspective: Option<LayoutTransform>,
|
||||||
|
|
||||||
/// The scroll policy of this layer.
|
/// The scroll policy of this layer.
|
||||||
pub scroll_policy: ScrollPolicy,
|
pub scroll_policy: ScrollPolicy,
|
||||||
|
@ -234,9 +234,9 @@ impl StackingContext {
|
||||||
z_index: i32,
|
z_index: i32,
|
||||||
filters: Vec<FilterOp>,
|
filters: Vec<FilterOp>,
|
||||||
mix_blend_mode: MixBlendMode,
|
mix_blend_mode: MixBlendMode,
|
||||||
transform: Option<Transform3D<f32>>,
|
transform: Option<LayoutTransform>,
|
||||||
transform_style: TransformStyle,
|
transform_style: TransformStyle,
|
||||||
perspective: Option<Transform3D<f32>>,
|
perspective: Option<LayoutTransform>,
|
||||||
scroll_policy: ScrollPolicy,
|
scroll_policy: ScrollPolicy,
|
||||||
parent_clipping_and_scrolling: ClippingAndScrolling)
|
parent_clipping_and_scrolling: ClippingAndScrolling)
|
||||||
-> StackingContext {
|
-> StackingContext {
|
||||||
|
@ -1028,7 +1028,7 @@ pub trait SimpleMatrixDetection {
|
||||||
fn is_identity_or_simple_translation(&self) -> bool;
|
fn is_identity_or_simple_translation(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleMatrixDetection for Transform3D<f32> {
|
impl SimpleMatrixDetection for LayoutTransform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_identity_or_simple_translation(&self) -> bool {
|
fn is_identity_or_simple_translation(&self) -> bool {
|
||||||
let (_0, _1) = (Zero::zero(), One::one());
|
let (_0, _1) = (Zero::zero(), One::one());
|
||||||
|
|
|
@ -17,7 +17,7 @@ use context::LayoutContext;
|
||||||
use display_list::ToLayout;
|
use display_list::ToLayout;
|
||||||
use display_list::background::{compute_background_image_size, tile_image_axis};
|
use display_list::background::{compute_background_image_size, tile_image_axis};
|
||||||
use display_list::background::{convert_linear_gradient, convert_radial_gradient};
|
use display_list::background::{convert_linear_gradient, convert_radial_gradient};
|
||||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D, Vector2D, rect};
|
use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D};
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use flow::{BaseFlow, Flow, FlowFlags};
|
use flow::{BaseFlow, Flow, FlowFlags};
|
||||||
use flow_ref::FlowRef;
|
use flow_ref::FlowRef;
|
||||||
|
@ -76,9 +76,9 @@ use style_traits::cursor::CursorKind;
|
||||||
use table_cell::CollapsedBordersForCell;
|
use table_cell::CollapsedBordersForCell;
|
||||||
use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ClipMode, ColorF};
|
use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ClipMode, ColorF};
|
||||||
use webrender_api::{ComplexClipRegion, ExternalScrollId, FilterOp, GlyphInstance, ImageBorder};
|
use webrender_api::{ComplexClipRegion, ExternalScrollId, FilterOp, GlyphInstance, ImageBorder};
|
||||||
use webrender_api::{ImageRendering, LayoutRect, LayoutSize, LayoutVector2D, LineStyle, LocalClip};
|
use webrender_api::{ImageRendering, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
|
||||||
use webrender_api::{NinePatchDescriptor, NormalBorder, ScrollPolicy, ScrollSensitivity};
|
use webrender_api::{LineStyle, LocalClip, NinePatchDescriptor, NormalBorder, ScrollPolicy};
|
||||||
use webrender_api::StickyOffsetBounds;
|
use webrender_api::{ScrollSensitivity, StickyOffsetBounds};
|
||||||
|
|
||||||
trait ResolvePercentage {
|
trait ResolvePercentage {
|
||||||
fn resolve(&self, length: u32) -> u32;
|
fn resolve(&self, length: u32) -> u32;
|
||||||
|
@ -2464,7 +2464,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
|
|
||||||
let perspective = self.fragment
|
let perspective = self.fragment
|
||||||
.perspective_matrix(&border_box)
|
.perspective_matrix(&border_box)
|
||||||
.unwrap_or_else(Transform3D::identity);
|
.unwrap_or(LayoutTransform::identity());
|
||||||
let transform = transform.pre_mul(&perspective).inverse();
|
let transform = transform.pre_mul(&perspective).inverse();
|
||||||
|
|
||||||
let origin = &border_box.origin;
|
let origin = &border_box.origin;
|
||||||
|
@ -2766,10 +2766,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size;
|
let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size;
|
||||||
let content_size = Size2D::new(content_size.x, content_size.y);
|
let content_size = Size2D::new(content_size.x, content_size.y);
|
||||||
|
|
||||||
let external_id = ExternalScrollId(
|
let external_id =
|
||||||
self.fragment.unique_id(),
|
ExternalScrollId(self.fragment.unique_id(), state.pipeline_id.to_webrender());
|
||||||
state.pipeline_id.to_webrender()
|
|
||||||
);
|
|
||||||
let new_clip_scroll_index = state.add_clip_scroll_node(ClipScrollNode {
|
let new_clip_scroll_index = state.add_clip_scroll_node(ClipScrollNode {
|
||||||
parent_index: self.clipping_and_scrolling().scrolling,
|
parent_index: self.clipping_and_scrolling().scrolling,
|
||||||
clip: clip,
|
clip: clip,
|
||||||
|
|
|
@ -11,8 +11,7 @@ use gfx::display_list::{BorderDetails, ClipScrollNode};
|
||||||
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
||||||
use gfx::display_list::{DisplayList, StackingContextType};
|
use gfx::display_list::{DisplayList, StackingContextType};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use webrender_api::{self, ClipAndScrollInfo, ClipId};
|
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder};
|
||||||
use webrender_api::{DisplayListBuilder, LayoutTransform};
|
|
||||||
|
|
||||||
pub trait WebRenderDisplayListConverter {
|
pub trait WebRenderDisplayListConverter {
|
||||||
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
|
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
|
||||||
|
@ -224,19 +223,12 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
||||||
let stacking_context = &item.stacking_context;
|
let stacking_context = &item.stacking_context;
|
||||||
debug_assert_eq!(stacking_context.context_type, StackingContextType::Real);
|
debug_assert_eq!(stacking_context.context_type, StackingContextType::Real);
|
||||||
|
|
||||||
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(
|
builder.push_stacking_context(
|
||||||
&webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds),
|
&webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds),
|
||||||
stacking_context.scroll_policy,
|
stacking_context.scroll_policy,
|
||||||
transform,
|
stacking_context.transform.map(Into::into),
|
||||||
stacking_context.transform_style,
|
stacking_context.transform_style,
|
||||||
perspective,
|
stacking_context.perspective,
|
||||||
stacking_context.mix_blend_mode,
|
stacking_context.mix_blend_mode,
|
||||||
stacking_context.filters.clone(),
|
stacking_context.filters.clone(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,7 +29,7 @@ use app_units::Au;
|
||||||
use block::{BlockFlow, FormattingContextType};
|
use block::{BlockFlow, FormattingContextType};
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use display_list::{DisplayListBuildState, StackingContextCollectionState};
|
use display_list::{DisplayListBuildState, StackingContextCollectionState};
|
||||||
use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D};
|
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use floats::{Floats, SpeculatedFloatPlacement};
|
use floats::{Floats, SpeculatedFloatPlacement};
|
||||||
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
||||||
|
@ -67,6 +67,7 @@ use table_colgroup::TableColGroupFlow;
|
||||||
use table_row::TableRowFlow;
|
use table_row::TableRowFlow;
|
||||||
use table_rowgroup::TableRowGroupFlow;
|
use table_rowgroup::TableRowGroupFlow;
|
||||||
use table_wrapper::TableWrapperFlow;
|
use table_wrapper::TableWrapperFlow;
|
||||||
|
use webrender_api::LayoutTransform;
|
||||||
|
|
||||||
/// This marker trait indicates that a type is a struct with `#[repr(C)]` whose first field
|
/// This marker trait indicates that a type is a struct with `#[repr(C)]` whose first field
|
||||||
/// is of type `BaseFlow` or some type that also implements this trait.
|
/// is of type `BaseFlow` or some type that also implements this trait.
|
||||||
|
@ -335,8 +336,8 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static {
|
||||||
let transform_2d = self.as_block()
|
let transform_2d = self.as_block()
|
||||||
.fragment
|
.fragment
|
||||||
.transform_matrix(&position)
|
.transform_matrix(&position)
|
||||||
.unwrap_or(Transform3D::identity())
|
.unwrap_or(LayoutTransform::identity())
|
||||||
.to_2d();
|
.to_2d().to_untyped();
|
||||||
let transformed_overflow = Overflow {
|
let transformed_overflow = Overflow {
|
||||||
paint: f32_rect_to_au_rect(transform_2d.transform_rect(
|
paint: f32_rect_to_au_rect(transform_2d.transform_rect(
|
||||||
&au_rect_to_f32_rect(overflow.paint))),
|
&au_rect_to_f32_rect(overflow.paint))),
|
||||||
|
|
|
@ -10,7 +10,8 @@ use ServoArc;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use canvas_traits::canvas::CanvasMsg;
|
use canvas_traits::canvas::CanvasMsg;
|
||||||
use context::{LayoutContext, with_thread_local_font_context};
|
use context::{LayoutContext, with_thread_local_font_context};
|
||||||
use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D};
|
use display_list::ToLayout;
|
||||||
|
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||||
use floats::ClearType;
|
use floats::ClearType;
|
||||||
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
||||||
use flow_ref::FlowRef;
|
use flow_ref::FlowRef;
|
||||||
|
@ -65,7 +66,7 @@ use style::values::generics::box_::VerticalAlign;
|
||||||
use style::values::generics::transform;
|
use style::values::generics::transform;
|
||||||
use text;
|
use text;
|
||||||
use text::TextRunScanner;
|
use text::TextRunScanner;
|
||||||
use webrender_api;
|
use webrender_api::{self, LayoutTransform};
|
||||||
use wrapper::ThreadSafeLayoutNodeHelpers;
|
use wrapper::ThreadSafeLayoutNodeHelpers;
|
||||||
|
|
||||||
// From gfxFontConstants.h in Firefox.
|
// From gfxFontConstants.h in Firefox.
|
||||||
|
@ -2867,9 +2868,10 @@ impl Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the 4D matrix representing this fragment's transform.
|
/// Returns the 4D matrix representing this fragment's transform.
|
||||||
pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Transform3D<f32>> {
|
pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<LayoutTransform> {
|
||||||
let list = &self.style.get_box().transform;
|
let list = &self.style.get_box().transform;
|
||||||
let transform = list.to_transform_3d_matrix(Some(stacking_relative_border_box)).ok()?.0;
|
let transform = LayoutTransform::from_untyped(
|
||||||
|
&list.to_transform_3d_matrix(Some(stacking_relative_border_box)).ok()?.0);
|
||||||
|
|
||||||
let transform_origin = &self.style.get_box().transform_origin;
|
let transform_origin = &self.style.get_box().transform_origin;
|
||||||
let transform_origin_x =
|
let transform_origin_x =
|
||||||
|
@ -2882,10 +2884,12 @@ impl Fragment {
|
||||||
.to_f32_px();
|
.to_f32_px();
|
||||||
let transform_origin_z = transform_origin.depth.px();
|
let transform_origin_z = transform_origin.depth.px();
|
||||||
|
|
||||||
let pre_transform = Transform3D::create_translation(transform_origin_x,
|
let pre_transform = LayoutTransform::create_translation(
|
||||||
|
transform_origin_x,
|
||||||
transform_origin_y,
|
transform_origin_y,
|
||||||
transform_origin_z);
|
transform_origin_z);
|
||||||
let post_transform = Transform3D::create_translation(-transform_origin_x,
|
let post_transform = LayoutTransform::create_translation(
|
||||||
|
-transform_origin_x,
|
||||||
-transform_origin_y,
|
-transform_origin_y,
|
||||||
-transform_origin_z);
|
-transform_origin_z);
|
||||||
|
|
||||||
|
@ -2893,27 +2897,29 @@ impl Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the 4D matrix representing this fragment's perspective.
|
/// Returns the 4D matrix representing this fragment's perspective.
|
||||||
pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Transform3D<f32>> {
|
pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<LayoutTransform> {
|
||||||
match self.style().get_box().perspective {
|
match self.style().get_box().perspective {
|
||||||
Either::First(length) => {
|
Either::First(length) => {
|
||||||
let perspective_origin = self.style().get_box().perspective_origin;
|
let perspective_origin = self.style().get_box().perspective_origin;
|
||||||
let perspective_origin =
|
let perspective_origin =
|
||||||
Point2D::new(
|
Point2D::new(
|
||||||
perspective_origin.horizontal
|
perspective_origin.horizontal
|
||||||
.to_used_value(stacking_relative_border_box.size.width)
|
.to_used_value(stacking_relative_border_box.size.width),
|
||||||
.to_f32_px(),
|
|
||||||
perspective_origin.vertical
|
perspective_origin.vertical
|
||||||
.to_used_value(stacking_relative_border_box.size.height)
|
.to_used_value(stacking_relative_border_box.size.height)
|
||||||
.to_f32_px());
|
).to_layout();
|
||||||
|
|
||||||
let pre_transform = Transform3D::create_translation(perspective_origin.x,
|
let pre_transform = LayoutTransform::create_translation(
|
||||||
|
perspective_origin.x,
|
||||||
perspective_origin.y,
|
perspective_origin.y,
|
||||||
0.0);
|
0.0);
|
||||||
let post_transform = Transform3D::create_translation(-perspective_origin.x,
|
let post_transform = LayoutTransform::create_translation(
|
||||||
|
-perspective_origin.x,
|
||||||
-perspective_origin.y,
|
-perspective_origin.y,
|
||||||
0.0);
|
0.0);
|
||||||
|
|
||||||
let perspective_matrix = transform::create_perspective_matrix(length.px());
|
let perspective_matrix = LayoutTransform::from_untyped(
|
||||||
|
&transform::create_perspective_matrix(length.px()));
|
||||||
|
|
||||||
Some(pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform))
|
Some(pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use servo_config::opts;
|
||||||
use style::servo::restyle_damage::ServoRestyleDamage;
|
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
|
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
|
||||||
use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
|
use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
|
||||||
|
use webrender_api::LayoutPoint;
|
||||||
|
|
||||||
pub fn resolve_generated_content(root: &mut Flow, layout_context: &LayoutContext) {
|
pub fn resolve_generated_content(root: &mut Flow, layout_context: &LayoutContext) {
|
||||||
ResolveGeneratedContent::new(&layout_context).traverse(root, 0);
|
ResolveGeneratedContent::new(&layout_context).traverse(root, 0);
|
||||||
|
@ -98,7 +99,7 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator
|
||||||
if let Some(matrix) = kid.as_block()
|
if let Some(matrix) = kid.as_block()
|
||||||
.fragment
|
.fragment
|
||||||
.transform_matrix(&relative_position) {
|
.transform_matrix(&relative_position) {
|
||||||
let transform_matrix = matrix.transform_point2d(&Point2D::zero());
|
let transform_matrix = matrix.transform_point2d(&LayoutPoint::zero());
|
||||||
stacking_context_position = stacking_context_position +
|
stacking_context_position = stacking_context_position +
|
||||||
Vector2D::new(Au::from_f32_px(transform_matrix.x),
|
Vector2D::new(Au::from_f32_px(transform_matrix.x),
|
||||||
Au::from_f32_px(transform_matrix.y))
|
Au::from_f32_px(transform_matrix.y))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue