aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Watson <gw@intuitionlibrary.com>2015-06-18 13:06:31 +1000
committerGlenn Watson <gw@intuitionlibrary.com>2015-06-23 14:10:44 +1000
commit39ddbbb0e1a20e7165740860b63cdf892951a5ec (patch)
tree26d78ca5b184929c5d3859f2e3f53e8e986e3101
parentd86c5879255ec9ced621412d4565a9a66ee4dc72 (diff)
downloadservo-39ddbbb0e1a20e7165740860b63cdf892951a5ec.tar.gz
servo-39ddbbb0e1a20e7165740860b63cdf892951a5ec.zip
Implement enough of 3d transforms spec to run the CSS FPS demo.
-rw-r--r--components/compositing/compositor.rs49
-rw-r--r--components/compositing/compositor_layer.rs5
-rw-r--r--components/gfx/display_list/mod.rs74
-rw-r--r--components/gfx/paint_context.rs3
-rw-r--r--components/gfx/paint_task.rs117
-rw-r--r--components/layout/block.rs51
-rw-r--r--components/layout/display_list_builder.rs75
-rw-r--r--components/layout/fragment.rs7
-rw-r--r--components/layout/layout_task.rs8
-rw-r--r--components/msg/compositor_msg.rs15
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl4
-rw-r--r--components/servo/Cargo.lock44
-rw-r--r--components/style/properties.mako.rs172
-rw-r--r--components/style/values.rs69
-rw-r--r--ports/cef/Cargo.lock42
-rw-r--r--ports/gonk/Cargo.lock40
-rw-r--r--tests/html/test_3d_transform_1.html131
-rw-r--r--tests/html/test_3d_transform_2.html81
-rw-r--r--tests/html/test_3d_transform_zsort.html52
19 files changed, 894 insertions, 145 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index 8a4d1191b7f..0613d337bad 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -11,6 +11,7 @@ use scrolling::ScrollingTimerProxy;
use windowing;
use windowing::{MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
+use euclid::Matrix4;
use euclid::point::{Point2D, TypedPoint2D};
use euclid::rect::{Rect, TypedRect};
use euclid::scale_factor::ScaleFactor;
@@ -26,7 +27,7 @@ use layers::rendergl::RenderContext;
use layers::rendergl;
use layers::scene::Scene;
use layout_traits::{LayoutControlChan, LayoutControlMsg};
-use msg::compositor_msg::{Epoch, FrameTreeId, LayerId};
+use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
use msg::constellation_msg::AnimationState;
use msg::constellation_msg::Msg as ConstellationMsg;
@@ -357,6 +358,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.create_or_update_descendant_layer(pipeline_id, *layer_properties);
}
}
+ self.send_buffer_requests_for_all_layers();
}
(Msg::GetGraphicsMetadata(chan), ShutdownState::NotShuttingDown) => {
@@ -560,9 +562,13 @@ impl<Window: WindowMethods> IOCompositor<Window> {
-> Rc<Layer<CompositorData>> {
let layer_properties = LayerProperties {
id: LayerId::null(),
+ parent_id: None,
rect: Rect::zero(),
background_color: color::transparent(),
scroll_policy: ScrollPolicy::Scrollable,
+ transform: Matrix4::identity(),
+ perspective: Matrix4::identity(),
+ establishes_3d_context: true,
};
let root_layer = CompositorData::new_layer(pipeline.id,
@@ -624,6 +630,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn create_or_update_base_layer(&mut self, pipeline_id: PipelineId, layer_properties: LayerProperties) {
+ debug_assert!(layer_properties.parent_id.is_none());
+
let root_layer = match self.find_pipeline_root_layer(pipeline_id) {
Some(root_layer) => root_layer,
None => {
@@ -653,29 +661,29 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.scroll_layer_to_fragment_point_if_necessary(pipeline_id,
layer_properties.id);
- self.send_buffer_requests_for_all_layers();
}
fn create_or_update_descendant_layer(&mut self, pipeline_id: PipelineId, layer_properties: LayerProperties) {
+ debug_assert!(layer_properties.parent_id.is_some());
+
if !self.update_layer_if_exists(pipeline_id, layer_properties) {
self.create_descendant_layer(pipeline_id, layer_properties);
}
self.scroll_layer_to_fragment_point_if_necessary(pipeline_id,
layer_properties.id);
- self.send_buffer_requests_for_all_layers();
}
fn create_descendant_layer(&self, pipeline_id: PipelineId, layer_properties: LayerProperties) {
- let root_layer = match self.find_pipeline_root_layer(pipeline_id) {
- Some(root_layer) => root_layer,
- None => return, // This pipeline is in the process of shutting down.
- };
+ let parent_id = layer_properties.parent_id.unwrap();
- let new_layer = CompositorData::new_layer(pipeline_id,
- layer_properties,
- WantsScrollEventsFlag::DoesntWantScrollEvents,
- root_layer.tile_size);
- root_layer.add_child(new_layer);
+ if let Some(parent_layer) = self.find_layer_with_pipeline_and_layer_id(pipeline_id,
+ parent_id) {
+ let new_layer = CompositorData::new_layer(pipeline_id,
+ layer_properties,
+ WantsScrollEventsFlag::DoesntWantScrollEvents,
+ parent_layer.tile_size);
+ parent_layer.add_child(new_layer);
+ }
}
fn send_window_size(&self) {
@@ -1143,11 +1151,18 @@ impl<Window: WindowMethods> IOCompositor<Window> {
request.page_rect = request.page_rect / scale.get();
}
+ let layer_kind = if layer.transform_state.borrow().is_3d {
+ LayerKind::Layer3D
+ } else {
+ LayerKind::Layer2D
+ };
+
vec.push(PaintRequest {
buffer_requests: layer_requests,
scale: scale.get(),
layer_id: layer.extra_data.borrow().id,
epoch: layer.extra_data.borrow().requested_epoch,
+ layer_kind: layer_kind,
});
}
@@ -1188,6 +1203,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
/// Returns true if any buffer requests were sent or false otherwise.
fn send_buffer_requests_for_all_layers(&mut self) -> bool {
+ if let Some(ref root_layer) = self.scene.root {
+ root_layer.update_transform_state(&Matrix4::identity(),
+ &Matrix4::identity(),
+ &Point2D::zero());
+ }
+
let mut layers_and_requests = Vec::new();
let mut unused_buffers = Vec::new();
self.scene.get_buffer_requests(&mut layers_and_requests, &mut unused_buffers);
@@ -1417,7 +1438,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn initialize_compositing(&mut self) {
let context = CompositorTask::create_graphics_context(&self.window.native_metadata());
let show_debug_borders = opts::get().show_debug_borders;
- self.context = Some(rendergl::RenderContext::new(context, show_debug_borders))
+ self.context = Some(rendergl::RenderContext::new(context,
+ show_debug_borders,
+ opts::get().output_file.is_some()))
}
fn find_topmost_layer_at_point_for_layer(&self,
diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs
index 6a34fc785ce..1be9df64ca9 100644
--- a/components/compositing/compositor_layer.rs
+++ b/components/compositing/compositor_layer.rs
@@ -7,7 +7,6 @@ use windowing::{MouseWindowEvent, WindowMethods};
use azure::azure_hl;
use euclid::length::Length;
-use euclid::matrix::Matrix4;
use euclid::point::{Point2D, TypedPoint2D};
use euclid::size::TypedSize2D;
use euclid::rect::Rect;
@@ -66,6 +65,7 @@ impl CompositorData {
tile_size,
to_layers_color(&layer_properties.background_color),
1.0,
+ layer_properties.establishes_3d_context,
new_compositor_data))
}
}
@@ -190,6 +190,8 @@ pub enum ScrollEventResult {
impl CompositorLayer for Layer<CompositorData> {
fn update_layer_except_bounds(&self, layer_properties: LayerProperties) {
self.extra_data.borrow_mut().scroll_policy = layer_properties.scroll_policy;
+ *self.transform.borrow_mut() = layer_properties.transform;
+ *self.perspective.borrow_mut() = layer_properties.perspective;
*self.background_color.borrow_mut() = to_layers_color(&layer_properties.background_color);
@@ -392,7 +394,6 @@ impl CompositorLayer for Layer<CompositorData> {
// Only scroll this layer if it's not fixed-positioned.
if self.extra_data.borrow().scroll_policy != ScrollPolicy::FixedPosition {
let new_offset = new_offset.to_untyped();
- *self.transform.borrow_mut() = Matrix4::identity().translate(new_offset.x, new_offset.y, 0.0);
*self.content_offset.borrow_mut() = Point2D::from_untyped(&new_offset);
result = true
}
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 22ca879b417..93a11d6b605 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -32,7 +32,7 @@ use euclid::approxeq::ApproxEq;
use euclid::num::Zero;
use libc::uintptr_t;
use paint_task::PaintLayer;
-use msg::compositor_msg::LayerId;
+use msg::compositor_msg::{LayerId, LayerKind};
use net_traits::image::base::Image;
use util::opts;
use util::cursor::Cursor;
@@ -246,6 +246,12 @@ pub struct StackingContext {
/// A transform to be applied to this stacking context.
pub transform: Matrix4,
+
+ /// The perspective matrix to be applied to children.
+ pub perspective: Matrix4,
+
+ /// Whether this stacking context creates a new 3d rendering context.
+ pub establishes_3d_context: bool,
}
impl StackingContext {
@@ -255,30 +261,40 @@ impl StackingContext {
bounds: &Rect<Au>,
overflow: &Rect<Au>,
z_index: i32,
- transform: &Matrix4,
filters: filter::T,
blend_mode: mix_blend_mode::T,
- layer: Option<Arc<PaintLayer>>)
+ layer: Option<Arc<PaintLayer>>,
+ transform: Matrix4,
+ perspective: Matrix4,
+ establishes_3d_context: bool)
-> StackingContext {
StackingContext {
display_list: display_list,
- layer: layer,
bounds: *bounds,
overflow: *overflow,
z_index: z_index,
- transform: *transform,
filters: filters,
blend_mode: blend_mode,
+ layer: layer,
+ transform: transform,
+ perspective: perspective,
+ establishes_3d_context: establishes_3d_context,
}
}
/// Draws the stacking context in the proper order according to the steps in CSS 2.1 § E.2.
- pub fn optimize_and_draw_into_context(&self,
- paint_context: &mut PaintContext,
- tile_bounds: &Rect<AzFloat>,
- transform: &Matrix4,
- clip_rect: Option<&Rect<Au>>) {
- let transform = transform.mul(&self.transform);
+ pub fn draw_into_context(&self,
+ display_list: &DisplayList,
+ paint_context: &mut PaintContext,
+ tile_bounds: &Rect<AzFloat>,
+ transform: &Matrix4,
+ clip_rect: Option<&Rect<Au>>) {
+ // If a layer is being used, the transform for this layer
+ // will be handled by the compositor.
+ let transform = match self.layer {
+ Some(..) => *transform,
+ None => transform.mul(&self.transform),
+ };
let temporary_draw_target =
paint_context.get_or_create_temporary_draw_target(&self.filters, self.blend_mode);
{
@@ -289,12 +305,9 @@ impl StackingContext {
screen_rect: paint_context.screen_rect,
clip_rect: clip_rect.map(|clip_rect| *clip_rect),
transient_clip: None,
+ layer_kind: paint_context.layer_kind,
};
- // Optimize the display list to throw out out-of-bounds display items and so forth.
- let display_list =
- DisplayListOptimizer::new(tile_bounds).optimize(&*self.display_list);
-
if opts::get().dump_display_list_optimized {
println!("**** optimized display list. Tile bounds: {:?}", tile_bounds);
display_list.print_items("*".to_owned());
@@ -409,6 +422,35 @@ impl StackingContext {
paint_context.draw_temporary_draw_target_if_necessary(&temporary_draw_target,
&self.filters,
self.blend_mode)
+
+ }
+
+ /// Optionally optimize and then draws the stacking context.
+ pub fn optimize_and_draw_into_context(&self,
+ paint_context: &mut PaintContext,
+ tile_bounds: &Rect<AzFloat>,
+ transform: &Matrix4,
+ clip_rect: Option<&Rect<Au>>) {
+ // TODO(gw): This is a hack to avoid running the DL optimizer
+ // on 3d transformed tiles. We should have a better solution
+ // than just disabling the opts here.
+ if paint_context.layer_kind == LayerKind::Layer3D {
+ self.draw_into_context(&self.display_list,
+ paint_context,
+ tile_bounds,
+ transform,
+ clip_rect);
+
+ } else {
+ // Optimize the display list to throw out out-of-bounds display items and so forth.
+ let display_list = DisplayListOptimizer::new(tile_bounds).optimize(&*self.display_list);
+
+ self.draw_into_context(&display_list,
+ paint_context,
+ tile_bounds,
+ transform,
+ clip_rect);
+ }
}
/// Translate the given tile rect into the coordinate system of a child stacking context.
@@ -1005,7 +1047,7 @@ impl<'a> Iterator for DisplayItemIterator<'a> {
impl DisplayItem {
/// Paints this display item into the given painting context.
fn draw_into_context(&self, paint_context: &mut PaintContext) {
- {
+ if paint_context.layer_kind == LayerKind::Layer2D {
let this_clip = &self.base().clip;
match paint_context.transient_clip {
Some(ref transient_clip) if transient_clip == this_clip => {}
diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs
index 2098b5c9c19..57b6b1feba2 100644
--- a/components/gfx/paint_context.rs
+++ b/components/gfx/paint_context.rs
@@ -29,6 +29,7 @@ use euclid::rect::Rect;
use euclid::side_offsets::SideOffsets2D;
use euclid::size::Size2D;
use libc::types::common::c99::uint32_t;
+use msg::compositor_msg::LayerKind;
use net_traits::image::base::Image;
use png::PixelsByColorType;
use std::default::Default;
@@ -54,6 +55,8 @@ pub struct PaintContext<'a> {
/// clipping region used by the last display item. We cache the last value so that we avoid
/// pushing and popping clipping regions unnecessarily.
pub transient_clip: Option<ClippingRegion>,
+ /// A temporary hack to disable clipping optimizations on 3d layers.
+ pub layer_kind: LayerKind,
}
#[derive(Copy, Clone)]
diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs
index b711b14e98e..1d02c153f78 100644
--- a/components/gfx/paint_task.rs
+++ b/components/gfx/paint_task.rs
@@ -21,7 +21,7 @@ use layers::platform::surface::NativeSurface;
use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
use layers;
use canvas_traits::CanvasMsg;
-use msg::compositor_msg::{Epoch, FrameTreeId, LayerId};
+use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, PaintListener, ScrollPolicy};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
@@ -69,6 +69,7 @@ pub struct PaintRequest {
pub scale: f32,
pub layer_id: LayerId,
pub epoch: Epoch,
+ pub layer_kind: LayerKind,
}
pub enum Msg {
@@ -272,10 +273,10 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
}
let mut replies = Vec::new();
- for PaintRequest { buffer_requests, scale, layer_id, epoch }
+ for PaintRequest { buffer_requests, scale, layer_id, epoch, layer_kind }
in requests.into_iter() {
if self.current_epoch == Some(epoch) {
- self.paint(&mut replies, buffer_requests, scale, layer_id);
+ self.paint(&mut replies, buffer_requests, scale, layer_id, layer_kind);
} else {
debug!("painter epoch mismatch: {:?} != {:?}", self.current_epoch, epoch);
}
@@ -405,7 +406,8 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
replies: &mut Vec<(LayerId, Box<LayerBufferSet>)>,
mut tiles: Vec<BufferRequest>,
scale: f32,
- layer_id: LayerId) {
+ layer_id: LayerId,
+ layer_kind: LayerKind) {
time::profile(time::ProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || {
// Bail out if there is no appropriate stacking context.
let stacking_context = if let Some(ref stacking_context) = self.root_stacking_context {
@@ -429,7 +431,8 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
tile,
layer_buffer,
stacking_context.clone(),
- scale);
+ scale,
+ layer_kind);
}
let new_buffers = (0..tile_count).map(|i| {
let thread_id = i % self.worker_threads.len();
@@ -450,32 +453,72 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
};
let mut properties = Vec::new();
- build(&mut properties, &**root_stacking_context, &ZERO_POINT);
+ build(&mut properties,
+ &**root_stacking_context,
+ &ZERO_POINT,
+ &Matrix4::identity(),
+ &Matrix4::identity(),
+ None);
self.compositor.initialize_layers_for_pipeline(self.id, properties, self.current_epoch.unwrap());
fn build(properties: &mut Vec<LayerProperties>,
stacking_context: &StackingContext,
- page_position: &Point2D<Au>) {
- let page_position = stacking_context.bounds.origin + *page_position;
- if let Some(ref paint_layer) = stacking_context.layer {
- // Layers start at the top left of their overflow rect, as far as the info we give to
- // the compositor is concerned.
- let overflow_relative_page_position = page_position + stacking_context.overflow.origin;
- let layer_position =
- Rect::new(Point2D::new(overflow_relative_page_position.x.to_nearest_px() as f32,
- overflow_relative_page_position.y.to_nearest_px() as f32),
- Size2D::new(stacking_context.overflow.size.width.to_nearest_px() as f32,
- stacking_context.overflow.size.height.to_nearest_px() as f32));
- properties.push(LayerProperties {
- id: paint_layer.id,
- rect: layer_position,
- background_color: paint_layer.background_color,
- scroll_policy: paint_layer.scroll_policy,
- })
- }
+ page_position: &Point2D<Au>,
+ transform: &Matrix4,
+ perspective: &Matrix4,
+ parent_id: Option<LayerId>) {
+
+ let transform = transform.mul(&stacking_context.transform);
+ let perspective = perspective.mul(&stacking_context.perspective);
+
+ let (next_parent_id, page_position, transform, perspective) = match stacking_context.layer {
+ Some(ref paint_layer) => {
+ // Layers start at the top left of their overflow rect, as far as the info we give to
+ // the compositor is concerned.
+ let overflow_relative_page_position = *page_position +
+ stacking_context.bounds.origin +
+ stacking_context.overflow.origin;
+ let layer_position =
+ Rect::new(Point2D::new(overflow_relative_page_position.x.to_nearest_px() as f32,
+ overflow_relative_page_position.y.to_nearest_px() as f32),
+ Size2D::new(stacking_context.overflow.size.width.to_nearest_px() as f32,
+ stacking_context.overflow.size.height.to_nearest_px() as f32));
+
+ let establishes_3d_context = stacking_context.establishes_3d_context;
+
+ properties.push(LayerProperties {
+ id: paint_layer.id,
+ parent_id: parent_id,
+ rect: layer_position,
+ background_color: paint_layer.background_color,
+ scroll_policy: paint_layer.scroll_policy,
+ transform: transform,
+ perspective: perspective,
+ establishes_3d_context: establishes_3d_context,
+ });
+
+ // When there is a new layer, the transforms and origin
+ // are handled by the compositor.
+ (Some(paint_layer.id),
+ Point2D::zero(),
+ Matrix4::identity(),
+ Matrix4::identity())
+ }
+ None => {
+ (parent_id,
+ stacking_context.bounds.origin + *page_position,
+ transform,
+ perspective)
+ }
+ };
for kid in stacking_context.display_list.children.iter() {
- build(properties, &**kid, &page_position)
+ build(properties,
+ &**kid,
+ &page_position,
+ &transform,
+ &perspective,
+ next_parent_id);
}
}
}
@@ -522,8 +565,14 @@ impl WorkerThreadProxy {
tile: BufferRequest,
layer_buffer: Option<Box<LayerBuffer>>,
stacking_context: Arc<StackingContext>,
- scale: f32) {
- let msg = MsgToWorkerThread::PaintTile(thread_id, tile, layer_buffer, stacking_context, scale);
+ scale: f32,
+ layer_kind: LayerKind) {
+ let msg = MsgToWorkerThread::PaintTile(thread_id,
+ tile,
+ layer_buffer,
+ stacking_context,
+ scale,
+ layer_kind);
self.sender.send(msg).unwrap()
}
@@ -568,8 +617,12 @@ impl WorkerThread {
loop {
match self.receiver.recv().unwrap() {
MsgToWorkerThread::Exit => break,
- MsgToWorkerThread::PaintTile(thread_id, tile, layer_buffer, stacking_context, scale) => {
- let draw_target = self.optimize_and_paint_tile(thread_id, &tile, stacking_context, scale);
+ MsgToWorkerThread::PaintTile(thread_id, tile, layer_buffer, stacking_context, scale, layer_kind) => {
+ let draw_target = self.optimize_and_paint_tile(thread_id,
+ &tile,
+ stacking_context,
+ scale,
+ layer_kind);
let buffer = self.create_layer_buffer_for_painted_tile(&tile,
layer_buffer,
draw_target,
@@ -584,7 +637,8 @@ impl WorkerThread {
thread_id: usize,
tile: &BufferRequest,
stacking_context: Arc<StackingContext>,
- scale: f32)
+ scale: f32,
+ layer_kind: LayerKind)
-> DrawTarget {
let size = Size2D::new(tile.screen_rect.size.width as i32, tile.screen_rect.size.height as i32);
let draw_target = if !opts::get().gpu_painting {
@@ -612,6 +666,7 @@ impl WorkerThread {
screen_rect: tile.screen_rect,
clip_rect: None,
transient_clip: None,
+ layer_kind: layer_kind,
};
// Apply a translation to start at the boundaries of the stacking context, since the
@@ -708,7 +763,7 @@ impl WorkerThread {
enum MsgToWorkerThread {
Exit,
- PaintTile(usize, BufferRequest, Option<Box<LayerBuffer>>, Arc<StackingContext>, f32),
+ PaintTile(usize, BufferRequest, Option<Box<LayerBuffer>>, Arc<StackingContext>, f32, LayerKind),
}
enum MsgFromWorkerThread {
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 0ce4d5a9539..0e8990702c3 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -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);
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 0ab4fe91fe1..e97dca0c17b 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -21,7 +21,7 @@ use list_item::ListItemFlow;
use model::{self, MaybeAuto, ToGfxMatrix, ToAu};
use table_cell::CollapsedBordersForCell;
-use euclid::{Point2D, Rect, Size2D, SideOffsets2D};
+use euclid::{Point2D, Point3D, Rect, Size2D, SideOffsets2D};
use euclid::Matrix4;
use gfx_traits::color;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
@@ -46,11 +46,12 @@ use style::computed_values::filter::Filter;
use style::computed_values::{background_attachment, background_clip, background_origin,
background_repeat, background_size};
use style::computed_values::{border_style, image_rendering, overflow_x, position,
- visibility, transform};
+ visibility, transform, transform_style};
use style::properties::ComputedValues;
use style::properties::style_structs::Border;
use style::values::RGBA;
-use style::values::computed::{Image, LinearGradient, LengthOrPercentage, LengthOrPercentageOrAuto};
+use style::values::computed::{Image, LinearGradient};
+use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
use url::Url;
use util::cursor::Cursor;
@@ -1146,17 +1147,18 @@ impl FragmentDisplayListBuilding for Fragment {
if let Some(ref operations) = self.style().get_effects().transform {
let transform_origin = self.style().get_effects().transform_origin;
let transform_origin =
- Point2D::new(model::specified(transform_origin.horizontal,
+ Point3D::new(model::specified(transform_origin.horizontal,
border_box.size.width).to_f32_px(),
model::specified(transform_origin.vertical,
- border_box.size.height).to_f32_px());
+ border_box.size.height).to_f32_px(),
+ transform_origin.depth.to_f32_px());
let pre_transform = Matrix4::create_translation(transform_origin.x,
transform_origin.y,
- 0.0);
+ transform_origin.z);
let post_transform = Matrix4::create_translation(-transform_origin.x,
-transform_origin.y,
- 0.0);
+ -transform_origin.z);
for operation in operations {
let matrix = match operation {
@@ -1190,6 +1192,31 @@ impl FragmentDisplayListBuilding for Fragment {
transform = pre_transform.mul(&transform).mul(&post_transform);
}
+ let perspective = match self.style().get_effects().perspective {
+ LengthOrNone::Length(d) => {
+ let perspective_origin = self.style().get_effects().perspective_origin;
+ let perspective_origin =
+ Point2D::new(model::specified(perspective_origin.horizontal,
+ border_box.size.width).to_f32_px(),
+ model::specified(perspective_origin.vertical,
+ border_box.size.height).to_f32_px());
+
+ let pre_transform = Matrix4::create_translation(perspective_origin.x,
+ perspective_origin.y,
+ 0.0);
+ let post_transform = Matrix4::create_translation(-perspective_origin.x,
+ -perspective_origin.y,
+ 0.0);
+
+ let perspective_matrix = Matrix4::create_perspective(d.to_f32_px());
+
+ pre_transform.mul(&perspective_matrix).mul(&post_transform)
+ }
+ LengthOrNone::None => {
+ Matrix4::identity()
+ }
+ };
+
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
let margin = self.margin.to_physical(base_flow.writing_mode);
let overflow = base_flow.overflow.translate(&-Point2D::new(margin.left, Au(0)));
@@ -1221,16 +1248,19 @@ impl FragmentDisplayListBuilding for Fragment {
.send((layer_id, fragment_info.renderer.clone())).unwrap();
}
+ let transform_style = self.style().get_used_transform_style();
let layer = layer.map(|l| Arc::new(l));
Arc::new(StackingContext::new(display_list,
&border_box,
&overflow,
self.style().get_box().z_index.number_or_zero(),
- &transform,
filters,
self.style().get_effects().mix_blend_mode,
- layer))
+ layer,
+ transform,
+ perspective,
+ transform_style == transform_style::T::flat))
}
#[inline(never)]
@@ -1489,11 +1519,28 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
background_border_level);
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
- DisplayListBuildingResult::StackingContext(
- self.fragment.create_stacking_context(&self.base,
- display_list,
- layout_context,
- StackingContextLayer::IfCanvas(self.layer_id(0))))
+ if self.will_get_layer() {
+ // If we got here, then we need a new layer.
+ let scroll_policy = if self.is_fixed() {
+ ScrollPolicy::FixedPosition
+ } else {
+ ScrollPolicy::Scrollable
+ };
+
+ let paint_layer = PaintLayer::new(self.layer_id(0), color::transparent(), scroll_policy);
+ let layer = StackingContextLayer::Existing(paint_layer);
+ let stacking_context = self.fragment.create_stacking_context(&self.base,
+ display_list,
+ layout_context,
+ layer);
+ DisplayListBuildingResult::StackingContext(stacking_context)
+ } else {
+ DisplayListBuildingResult::StackingContext(
+ self.fragment.create_stacking_context(&self.base,
+ display_list,
+ layout_context,
+ StackingContextLayer::IfCanvas(self.layer_id(0))))
+ }
} else {
match self.fragment.style.get_box().position {
position::T::static_ => {}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 36225040c4e..4a5fe56393c 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -40,6 +40,7 @@ use string_cache::Atom;
use style::computed_values::content::ContentItem;
use style::computed_values::{border_collapse, clear, mix_blend_mode, overflow_wrap, position};
use style::computed_values::{text_align, text_decoration, white_space, word_break};
+use style::computed_values::transform_style;
use style::node::TNode;
use style::properties::{self, ComputedValues, cascade_anonymous};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
@@ -1990,6 +1991,12 @@ impl Fragment {
if self.style().get_effects().transform.is_some() {
return true
}
+ match self.style().get_used_transform_style() {
+ transform_style::T::flat | transform_style::T::preserve_3d => {
+ return true
+ }
+ transform_style::T::auto => {}
+ }
// Canvas always layerizes, as an special case
// FIXME(pcwalton): Don't unconditionally form stacking contexts for each canvas.
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 1cad8855750..b4d74ced074 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -35,7 +35,7 @@ use euclid::scale_factor::ScaleFactor;
use euclid::size::Size2D;
use gfx_traits::color;
use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, OpaqueNode};
-use gfx::display_list::{StackingContext};
+use gfx::display_list::StackingContext;
use gfx::font_cache_task::FontCacheTask;
use gfx::paint_task::Msg as PaintMsg;
use gfx::paint_task::{PaintChan, PaintLayer};
@@ -872,10 +872,12 @@ impl LayoutTask {
&origin,
&origin,
0,
- &Matrix4::identity(),
filter::T::new(Vec::new()),
mix_blend_mode::T::normal,
- Some(paint_layer)));
+ Some(paint_layer),
+ Matrix4::identity(),
+ Matrix4::identity(),
+ true));
if opts::get().dump_display_list {
println!("#### start printing display list.");
diff --git a/components/msg/compositor_msg.rs b/components/msg/compositor_msg.rs
index f6af5e02f22..b3f07a04e1d 100644
--- a/components/msg/compositor_msg.rs
+++ b/components/msg/compositor_msg.rs
@@ -6,6 +6,7 @@ use azure::azure_hl::Color;
use constellation_msg::{Key, KeyState, KeyModifiers};
use euclid::point::Point2D;
use euclid::rect::Rect;
+use euclid::Matrix4;
use layers::platform::surface::NativeGraphicsMetadata;
use layers::layers::LayerBufferSet;
use std::fmt::{Formatter, Debug};
@@ -51,6 +52,12 @@ impl LayerId {
}
}
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum LayerKind {
+ Layer2D,
+ Layer3D,
+}
+
/// The scrolling policy of a layer.
#[derive(Clone, PartialEq, Eq, Copy)]
pub enum ScrollPolicy {
@@ -66,12 +73,20 @@ pub enum ScrollPolicy {
pub struct LayerProperties {
/// An opaque ID. This is usually the address of the flow and index of the box within it.
pub id: LayerId,
+ /// The id of the parent layer.
+ pub parent_id: Option<LayerId>,
/// The position and size of the layer in pixels.
pub rect: Rect<f32>,
/// The background color of the layer.
pub background_color: Color,
/// The scrolling policy of this layer.
pub scroll_policy: ScrollPolicy,
+ /// The transform for this layer
+ pub transform: Matrix4,
+ /// The perspective transform for this layer
+ pub perspective: Matrix4,
+ /// Whether this layer establishes a new 3d rendering context.
+ pub establishes_3d_context: bool,
}
/// The interface used by the painter to acquire draw targets for each paint frame and
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl
index d85dfc8f8ca..63220ad1ecd 100644
--- a/components/script/dom/webidls/CSSStyleDeclaration.webidl
+++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl
@@ -93,6 +93,10 @@ partial interface CSSStyleDeclaration {
[TreatNullAs=EmptyString] attribute DOMString transform;
[TreatNullAs=EmptyString] attribute DOMString transformOrigin;
+ [TreatNullAs=EmptyString] attribute DOMString perspective;
+ [TreatNullAs=EmptyString] attribute DOMString perspectiveOrigin;
+ [TreatNullAs=EmptyString] attribute DOMString transformStyle;
+ [TreatNullAs=EmptyString] attribute DOMString backfaceVisibility;
[TreatNullAs=EmptyString] attribute DOMString direction;
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 2760747c721..379d9e0fa06 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -48,7 +48,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -78,7 +78,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -94,7 +94,7 @@ version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
@@ -145,7 +145,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -321,7 +321,7 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -403,7 +403,7 @@ dependencies = [
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
@@ -504,7 +504,7 @@ dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.0.26 (git+https://github.com/servo/glutin?branch=servo)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -592,7 +592,7 @@ source = "git+https://github.com/servo/io-surface-rs#401cf1d0a90290aa832b6220612
dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -625,13 +625,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#65001b9e18631172a457c31c04be990639c02c35"
+source = "git+https://github.com/servo/rust-layers#d7defb1fbc84e90322d7b1c6f3fde6cf9ffb736d"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
@@ -653,7 +653,7 @@ dependencies = [
"clock_ticks 0.0.6 (git+https://github.com/tomaka/clock_ticks)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
@@ -681,7 +681,7 @@ dependencies = [
name = "layout_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -764,7 +764,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -781,7 +781,7 @@ version = "0.0.1"
dependencies = [
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -813,7 +813,7 @@ dependencies = [
name = "net_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -857,7 +857,7 @@ dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -1034,7 +1034,7 @@ dependencies = [
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"html5ever 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1077,7 +1077,7 @@ name = "script_traits"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1166,7 +1166,7 @@ dependencies = [
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1187,7 +1187,7 @@ name = "style_tests"
version = "0.0.1"
dependencies = [
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.1.0 (git+https://github.com/servo/rust-selectors)",
"string_cache 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_plugin 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1266,7 +1266,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1288,7 +1288,7 @@ dependencies = [
name = "util_tests"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"util 0.0.1",
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index 78ff721e8a6..ac0de8cbb4b 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -34,7 +34,6 @@ use computed_values;
use self::property_bit_field::PropertyBitField;
-
<%!
import re
@@ -3498,8 +3497,151 @@ pub mod longhands {
}
</%self:longhand>
+ ${single_keyword("backface-visibility", "visible hidden")}
+
+ ${single_keyword("transform-style", "auto flat preserve-3d")}
+
<%self:longhand name="transform-origin">
use values::computed::{ToComputedValue, Context};
+ use values::specified::{Length, LengthOrPercentage};
+
+ use cssparser::ToCss;
+ use std::fmt;
+ use util::geometry::Au;
+
+ pub mod computed_value {
+ use values::computed::{Length, LengthOrPercentage};
+
+ #[derive(Clone, Copy, Debug, PartialEq)]
+ pub struct T {
+ pub horizontal: LengthOrPercentage,
+ pub vertical: LengthOrPercentage,
+ pub depth: Length,
+ }
+ }
+
+ #[derive(Clone, Copy, Debug, PartialEq)]
+ pub struct SpecifiedValue {
+ horizontal: LengthOrPercentage,
+ vertical: LengthOrPercentage,
+ depth: Length,
+ }
+
+ impl ToCss for SpecifiedValue {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(self.horizontal.to_css(dest));
+ try!(dest.write_str(" "));
+ try!(self.vertical.to_css(dest));
+ try!(dest.write_str(" "));
+ self.depth.to_css(dest)
+ }
+ }
+
+ #[inline]
+ pub fn get_initial_value() -> computed_value::T {
+ computed_value::T {
+ horizontal: computed::LengthOrPercentage::Percentage(0.5),
+ vertical: computed::LengthOrPercentage::Percentage(0.5),
+ depth: Au(0),
+ }
+ }
+
+ pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
+ let (mut horizontal, mut vertical, mut depth) = (None, None, None);
+ loop {
+ if let Err(_) = input.try(|input| {
+ let token = try!(input.expect_ident());
+ match_ignore_ascii_case! {
+ token,
+ "left" => {
+ if horizontal.is_none() {
+ horizontal = Some(LengthOrPercentage::Percentage(0.0))
+ } else {
+ return Err(())
+ }
+ },
+ "center" => {
+ if horizontal.is_none() {
+ horizontal = Some(LengthOrPercentage::Percentage(0.5))
+ } else if vertical.is_none() {
+ vertical = Some(LengthOrPercentage::Percentage(0.5))
+ } else {
+ return Err(())
+ }
+ },
+ "right" => {
+ if horizontal.is_none() {
+ horizontal = Some(LengthOrPercentage::Percentage(1.0))
+ } else {
+ return Err(())
+ }
+ },
+ "top" => {
+ if vertical.is_none() {
+ vertical = Some(LengthOrPercentage::Percentage(0.0))
+ } else {
+ return Err(())
+ }
+ },
+ "bottom" => {
+ if vertical.is_none() {
+ vertical = Some(LengthOrPercentage::Percentage(1.0))
+ } else {
+ return Err(())
+ }
+ }
+ _ => return Err(())
+ }
+ Ok(())
+ }) {
+ match LengthOrPercentage::parse(input) {
+ Ok(value) => {
+ if horizontal.is_none() {
+ horizontal = Some(value);
+ } else if vertical.is_none() {
+ vertical = Some(value);
+ } else if let LengthOrPercentage::Length(length) = value {
+ depth = Some(length);
+ } else {
+ return Err(());
+ }
+ }
+ _ => break,
+ }
+ }
+ }
+
+ if horizontal.is_some() || vertical.is_some() {
+ Ok(SpecifiedValue {
+ horizontal: horizontal.unwrap_or(LengthOrPercentage::Percentage(0.5)),
+ vertical: vertical.unwrap_or(LengthOrPercentage::Percentage(0.5)),
+ depth: depth.unwrap_or(Length::Absolute(Au(0))),
+ })
+ } else {
+ Err(())
+ }
+ }
+
+ impl ToComputedValue for SpecifiedValue {
+ type ComputedValue = computed_value::T;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ computed_value::T {
+ horizontal: self.horizontal.to_computed_value(context),
+ vertical: self.vertical.to_computed_value(context),
+ depth: self.depth.to_computed_value(context),
+ }
+ }
+ }
+ </%self:longhand>
+
+ ${predefined_type("perspective",
+ "LengthOrNone",
+ "computed::LengthOrNone::None")}
+
+ <%self:longhand name="perspective-origin">
+ use values::computed::{ToComputedValue, Context};
use values::specified::LengthOrPercentage;
use cssparser::ToCss;
@@ -5323,6 +5465,34 @@ impl ComputedValues {
self.font.clone()
}
+ // http://dev.w3.org/csswg/css-transforms/#grouping-property-values
+ pub fn get_used_transform_style(&self) -> computed_values::transform_style::T {
+ use computed_values::mix_blend_mode;
+ use computed_values::transform_style;
+
+ let effects = self.get_effects();
+
+ // TODO(gw): Add clip-path, isolation, mask-image, mask-border-source when supported.
+ if effects.opacity < 1.0 ||
+ !effects.filter.is_empty() ||
+ effects.clip.is_some() {
+ effects.mix_blend_mode != mix_blend_mode::T::normal ||
+ return transform_style::T::flat;
+ }
+
+ if effects.transform_style == transform_style::T::auto {
+ if effects.transform.is_some() {
+ return transform_style::T::flat;
+ }
+ if effects.perspective != computed::LengthOrNone::None {
+ return transform_style::T::flat;
+ }
+ }
+
+ // Return the computed value if not overridden by the above exceptions
+ effects.transform_style
+ }
+
% for style_struct in STYLE_STRUCTS:
#[inline]
pub fn get_${style_struct.name.lower()}
diff --git a/components/style/values.rs b/components/style/values.rs
index d6ccb0480be..3fad8588a18 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -480,6 +480,45 @@ pub mod specified {
}
}
+ #[derive(Clone, PartialEq, Copy, Debug)]
+ pub enum LengthOrNone {
+ Length(Length),
+ None,
+ }
+
+ impl ToCss for LengthOrNone {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match self {
+ &LengthOrNone::Length(length) => length.to_css(dest),
+ &LengthOrNone::None => dest.write_str("none"),
+ }
+ }
+ }
+ impl LengthOrNone {
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
+ -> Result<LengthOrNone, ()>
+ {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrNone::Length),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrNone::Length(Length::Absolute(Au(0)))),
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
+ Ok(LengthOrNone::None),
+ _ => Err(())
+ }
+ }
+ #[allow(dead_code)]
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<LengthOrNone, ()> {
+ LengthOrNone::parse_internal(input, &AllowedNumericType::All)
+ }
+ #[inline]
+ pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrNone, ()> {
+ LengthOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+ }
+
/// The sum of a series of lengths and a percentage. This is used in `calc()` and other things
/// that effectively work like it (e.g. transforms).
#[derive(Clone, Debug, PartialEq)]
@@ -1069,6 +1108,36 @@ pub mod computed {
}
}
+ #[derive(PartialEq, Clone, Copy)]
+ pub enum LengthOrNone {
+ Length(Au),
+ None,
+ }
+ impl fmt::Debug for LengthOrNone {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ &LengthOrNone::Length(length) => write!(f, "{:?}", length),
+ &LengthOrNone::None => write!(f, "none"),
+ }
+ }
+ }
+
+ impl ToComputedValue for specified::LengthOrNone {
+ type ComputedValue = LengthOrNone;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LengthOrNone {
+ match *self {
+ specified::LengthOrNone::Length(value) => {
+ LengthOrNone::Length(value.to_computed_value(context))
+ }
+ specified::LengthOrNone::None => {
+ LengthOrNone::None
+ }
+ }
+ }
+ }
+
/// The sum of a series of lengths and a percentage. This is used in `calc()` and other things
/// that effectively work like it (e.g. transforms).
#[derive(Clone, Copy, Debug, PartialEq)]
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 8a383015502..1e05f384c37 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -10,7 +10,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"devtools 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
@@ -47,7 +47,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -77,7 +77,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -93,7 +93,7 @@ version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
@@ -144,7 +144,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -320,7 +320,7 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -402,7 +402,7 @@ dependencies = [
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
@@ -496,7 +496,7 @@ dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.0.26 (git+https://github.com/servo/glutin?branch=servo)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -584,7 +584,7 @@ source = "git+https://github.com/servo/io-surface-rs#401cf1d0a90290aa832b6220612
dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -617,13 +617,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#65001b9e18631172a457c31c04be990639c02c35"
+source = "git+https://github.com/servo/rust-layers#d7defb1fbc84e90322d7b1c6f3fde6cf9ffb736d"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
@@ -645,7 +645,7 @@ dependencies = [
"clock_ticks 0.0.6 (git+https://github.com/tomaka/clock_ticks)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
@@ -673,7 +673,7 @@ dependencies = [
name = "layout_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -756,7 +756,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -773,7 +773,7 @@ version = "0.0.1"
dependencies = [
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -793,7 +793,7 @@ dependencies = [
name = "net_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -837,7 +837,7 @@ dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -1014,7 +1014,7 @@ dependencies = [
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"html5ever 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1049,7 +1049,7 @@ name = "script_traits"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1164,7 +1164,7 @@ dependencies = [
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1250,7 +1250,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index 205364aa667..6d248ea394a 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -7,7 +7,7 @@ dependencies = [
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"errno 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -34,7 +34,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -64,7 +64,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -80,7 +80,7 @@ version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
@@ -121,7 +121,7 @@ dependencies = [
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -307,7 +307,7 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -381,7 +381,7 @@ dependencies = [
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
@@ -518,7 +518,7 @@ source = "git+https://github.com/servo/io-surface-rs#401cf1d0a90290aa832b6220612
dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -551,13 +551,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#65001b9e18631172a457c31c04be990639c02c35"
+source = "git+https://github.com/servo/rust-layers#d7defb1fbc84e90322d7b1c6f3fde6cf9ffb736d"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
@@ -579,7 +579,7 @@ dependencies = [
"clock_ticks 0.0.6 (git+https://github.com/tomaka/clock_ticks)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
@@ -607,7 +607,7 @@ dependencies = [
name = "layout_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -682,7 +682,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -699,7 +699,7 @@ version = "0.0.1"
dependencies = [
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -719,7 +719,7 @@ dependencies = [
name = "net_traits"
version = "0.0.1"
dependencies = [
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -754,7 +754,7 @@ dependencies = [
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -922,7 +922,7 @@ dependencies = [
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"html5ever 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -957,7 +957,7 @@ name = "script_traits"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1062,7 +1062,7 @@ dependencies = [
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1139,7 +1139,7 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/tests/html/test_3d_transform_1.html b/tests/html/test_3d_transform_1.html
new file mode 100644
index 00000000000..e35a7777018
--- /dev/null
+++ b/tests/html/test_3d_transform_1.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style type="text/css">
+ /* Shorthand classes for different perspective values */
+ .pers250 {
+ perspective: 250px;
+ }
+ .pers350 {
+ perspective: 350px;
+ }
+ .pers500 {
+ perspective: 500px;
+ }
+
+ /* Define the container div, the cube div, and a generic face */
+ .container {
+ width: 200px;
+ height: 200px;
+ margin: 75px 0 0 75px;
+ border: none;
+ }
+ .cube {
+ width: 100%;
+ height: 100%;
+ backface-visibility: visible;
+ perspective-origin: 150% 150%;
+ transform-style: preserve-3d;
+ }
+ .face {
+ display: block;
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ border: none;
+ line-height: 100px;
+ font-family: sans-serif;
+ font-size: 60px;
+ color: white;
+ text-align: center;
+ }
+
+ /* Define each face based on direction */
+ .front {
+ background: rgba(0, 0, 0, 0.3);
+ transform: translateZ(50px);
+ }
+ .back {
+ background: rgba(0, 255, 0, 1);
+ color: black;
+ transform: rotateY(180deg) translateZ(50px);
+ }
+ .right {
+ background: rgba(196, 0, 0, 0.7);
+ transform: rotateY(90deg) translateZ(50px);
+ }
+ .left {
+ background: rgba(0, 0, 196, 0.7);
+ transform: rotateY(-90deg) translateZ(50px);
+ }
+ .top {
+ background: rgba(196, 196, 0, 0.7);
+ transform: rotateX(90deg) translateZ(50px);
+ }
+ .bottom {
+ background: rgba(196, 0, 196, 0.7);
+ transform: rotateX(-90deg) translateZ(50px);
+ }
+
+ /* Make the table a little nicer */
+ th, p, td {
+ background-color: #EEEEEE;
+ padding: 10px;
+ font-family: sans-serif;
+ text-align: left;
+ }
+ </style>
+ </head>
+ <body>
+ <table>
+ <tbody>
+ <tr>
+ <th><code>perspective: 250px;</code>
+ </th>
+ <th><code>perspective: 350px;</code>
+ </th>
+ <th><code>perspective: 500px;</code>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <div class="container">
+ <div class="cube pers250">
+ <div class="face front"></div>
+ <div class="face back"></div>
+ <div class="face right"></div>
+ <div class="face left"></div>
+ <div class="face top"></div>
+ <div class="face bottom"></div>
+ </div>
+ </div>
+ </td>
+ <td>
+ <div class="container">
+ <div class="cube pers350">
+ <div class="face front"></div>
+ <div class="face back"></div>
+ <div class="face right"></div>
+ <div class="face left"></div>
+ <div class="face top"></div>
+ <div class="face bottom"></div>
+ </div>
+ </div>
+ </td>
+ <td>
+ <div class="container">
+ <div class="cube pers500">
+ <div class="face front"></div>
+ <div class="face back"></div>
+ <div class="face right"></div>
+ <div class="face left"></div>
+ <div class="face top"></div>
+ <div class="face bottom"></div>
+ </div>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </body>
+</html>
diff --git a/tests/html/test_3d_transform_2.html b/tests/html/test_3d_transform_2.html
new file mode 100644
index 00000000000..b585831a52c
--- /dev/null
+++ b/tests/html/test_3d_transform_2.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style type="text/css">
+ .pers200 {
+ perspective: 200px;
+ }
+
+ .pers500 {
+ perspective: 500px;
+ }
+
+ .container {
+ //background-color: red;
+ width: 200px;
+ height: 200px;
+ margin: 75px 0 0 75px;
+ //border: 1px solid red;
+ }
+ .cube {
+ //background-color: green;
+ width: 100%;
+ height: 100%;
+ backface-visibility: visible;
+ perspective-origin: 150% 150%;
+ transform-style: preserve-3d;
+ }
+ .face {
+ display: block;
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ border: none;
+ line-height: 100px;
+ font-family: sans-serif;
+ font-size: 60px;
+ color: white;
+ text-align: center;
+ }
+
+ /* Define each face based on direction */
+ .front {
+ background: rgba(1, 1, 1, 0.5);
+ transform: translateZ(50px);
+ }
+ .back {
+ background: rgba(0, 255, 0, 0.5);
+ color: black;
+ transform: rotateY(180deg) translateZ(50px);
+ }
+ .right {
+ background: rgba(196, 0, 0, 0.7);
+ transform: rotateY(90deg) translateZ(50px);
+ }
+ .left {
+ background: rgba(0, 0, 196, 0.7);
+ transform: rotateY(-90deg) translateZ(50px);
+ }
+ .top {
+ background: rgba(196, 196, 0, 0.7);
+ transform: rotateX(90deg) translateZ(50px);
+ }
+ .bottom {
+ background: rgba(196, 0, 196, 0.7);
+ transform: rotateX(-90deg) translateZ(50px);
+ }
+ </style>
+ </head>
+ <body>
+ <div class="container">
+ <div class="cube pers500">
+ <div class="face front"></div>
+ <div class="face back"></div>
+ <div class="face right"></div>
+ <div class="face left"></div>
+ <div class="face top"></div>
+ <div class="face bottom"></div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/tests/html/test_3d_transform_zsort.html b/tests/html/test_3d_transform_zsort.html
new file mode 100644
index 00000000000..688d717d659
--- /dev/null
+++ b/tests/html/test_3d_transform_zsort.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style type="text/css">
+ * {
+ margin: 0;
+ padding: 0;
+ }
+ .container {
+ perspective: 100px;
+ background-color: rgba(0, 0, 0, 0.5);
+ width: 600px;
+ height: 600px;
+ transform-style: preserve-3d;
+ }
+ .f1 {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: red;
+ transform: translate3d(0, 0, -5px);
+ }
+ .f2 {
+ position: absolute;
+ top: 100px;
+ left: 100px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ transform: translate3d(0, 0, 0);
+ }
+ .f3 {
+ position: absolute;
+ top: 200px;
+ left: 200px;
+ width: 200px;
+ height: 200px;
+ background-color: blue;
+ transform: translate3d(0, 0, 0);
+ }
+ </style>
+ </head>
+ <body>
+ <div class="container">AAA
+ <div class="f1"></div>
+ <div class="f2"></div>
+ <div class="f3"></div>
+ </div>
+ </body>
+</html>