servo: Merge #6425 - Implement enough of 3d transforms spec to run the CSS FPS demo (from glennw:3d-transforms); r=pcwalton

Source-Repo: https://github.com/servo/servo
Source-Revision: dcb1237bb5deb84cdf921bf7b145b07eb2bd1430
This commit is contained in:
Glenn Watson 2015-06-23 12:13:25 -06:00
parent c6d1841eec
commit 5cd9134a2e
19 changed files with 894 additions and 145 deletions

View File

@ -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,

View File

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

View File

@ -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 => {}

View File

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

View File

@ -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 {

View File

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

View File

@ -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_ => {}

View File

@ -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.

View File

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

View File

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

View File

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

View File

@ -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",

View File

@ -34,7 +34,6 @@ use computed_values;
use self::property_bit_field::PropertyBitField;
<%!
import re
@ -3498,7 +3497,150 @@ 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;
@ -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()}

View File

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

View File

@ -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)",

View File

@ -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)",

View File

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

View File

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

View File

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