mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Move DL items from gfx to layout
Implement corner clipping. Remove PixelFormat from WebrenderImageInfo. Use WebRender text shadow. Remove MallocSizeOf and Deserialize for DL items. Closes #19649, #19680, #19802
This commit is contained in:
parent
782d4d4af6
commit
c0be925bed
26 changed files with 417 additions and 287 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1022,8 +1022,6 @@ dependencies = [
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"malloc_size_of 0.0.1",
|
"malloc_size_of 0.0.1",
|
||||||
"malloc_size_of_derive 0.0.1",
|
|
||||||
"msg 0.0.1",
|
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
|
@ -1032,7 +1030,6 @@ dependencies = [
|
||||||
"servo_allocator 0.0.1",
|
"servo_allocator 0.0.1",
|
||||||
"servo_arc 0.1.1",
|
"servo_arc 0.1.1",
|
||||||
"servo_atoms 0.0.1",
|
"servo_atoms 0.0.1",
|
||||||
"servo_geometry 0.0.1",
|
|
||||||
"servo_url 0.0.1",
|
"servo_url 0.0.1",
|
||||||
"simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1723,12 +1720,11 @@ dependencies = [
|
||||||
name = "metrics_tests"
|
name = "metrics_tests"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gfx 0.0.1",
|
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"layout 0.0.1",
|
||||||
"metrics 0.0.1",
|
"metrics 0.0.1",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"servo_url 0.0.1",
|
"servo_url 0.0.1",
|
||||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -28,15 +28,12 @@ lazy_static = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.3.5"
|
log = "0.3.5"
|
||||||
malloc_size_of = { path = "../malloc_size_of" }
|
malloc_size_of = { path = "../malloc_size_of" }
|
||||||
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
|
|
||||||
msg = {path = "../msg"}
|
|
||||||
net_traits = {path = "../net_traits"}
|
net_traits = {path = "../net_traits"}
|
||||||
ordered-float = "0.4"
|
ordered-float = "0.4"
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
servo_arc = {path = "../servo_arc"}
|
servo_arc = {path = "../servo_arc"}
|
||||||
servo_atoms = {path = "../atoms"}
|
servo_atoms = {path = "../atoms"}
|
||||||
servo_geometry = {path = "../geometry"}
|
|
||||||
servo_url = {path = "../url"}
|
servo_url = {path = "../url"}
|
||||||
smallvec = "0.6"
|
smallvec = "0.6"
|
||||||
style = {path = "../style"}
|
style = {path = "../style"}
|
||||||
|
|
|
@ -43,14 +43,11 @@ extern crate libc;
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[cfg_attr(target_os = "windows", macro_use)]
|
#[cfg_attr(target_os = "windows", macro_use)]
|
||||||
extern crate malloc_size_of;
|
extern crate malloc_size_of;
|
||||||
#[macro_use] extern crate malloc_size_of_derive;
|
|
||||||
extern crate msg;
|
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate range;
|
extern crate range;
|
||||||
#[macro_use] extern crate serde;
|
#[macro_use] extern crate serde;
|
||||||
extern crate servo_arc;
|
extern crate servo_arc;
|
||||||
extern crate servo_geometry;
|
|
||||||
extern crate servo_url;
|
extern crate servo_url;
|
||||||
#[macro_use] extern crate servo_atoms;
|
#[macro_use] extern crate servo_atoms;
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
|
@ -66,9 +63,6 @@ extern crate xi_unicode;
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
extern crate xml5ever;
|
extern crate xml5ever;
|
||||||
|
|
||||||
#[deny(unsafe_code)]
|
|
||||||
pub mod display_list;
|
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
#[macro_use] pub mod font;
|
#[macro_use] pub mod font;
|
||||||
pub mod font_cache_thread;
|
pub mod font_cache_thread;
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf)]
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct FontContextHandle {
|
pub struct FontContextHandle {
|
||||||
ctx: ()
|
ctx: ()
|
||||||
}
|
}
|
||||||
|
@ -13,3 +15,9 @@ impl FontContextHandle {
|
||||||
FontContextHandle { ctx: () }
|
FontContextHandle { ctx: () }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MallocSizeOf for FontContextHandle {
|
||||||
|
fn size_of(&self, _: &mut MallocSizeOfOps) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
//! CSS transitions and animations.
|
//! CSS transitions and animations.
|
||||||
|
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
|
use display_list::items::OpaqueNode;
|
||||||
use flow::{Flow, GetBaseFlow};
|
use flow::{Flow, GetBaseFlow};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use gfx::display_list::OpaqueNode;
|
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use opaque_node::OpaqueNodeMethods;
|
use opaque_node::OpaqueNodeMethods;
|
||||||
|
|
|
@ -32,13 +32,13 @@ use context::LayoutContext;
|
||||||
use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode};
|
use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode};
|
||||||
use display_list::{DisplayListBuildState, StackingContextCollectionFlags};
|
use display_list::{DisplayListBuildState, StackingContextCollectionFlags};
|
||||||
use display_list::StackingContextCollectionState;
|
use display_list::StackingContextCollectionState;
|
||||||
|
use display_list::items::DisplayListSection;
|
||||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||||
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
||||||
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag, GetBaseFlow};
|
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag, GetBaseFlow};
|
||||||
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags};
|
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags};
|
||||||
use flow_list::FlowList;
|
use flow_list::FlowList;
|
||||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
|
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
|
||||||
use gfx::display_list::DisplayListSection;
|
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use incremental::RelayoutMode;
|
use incremental::RelayoutMode;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
|
|
|
@ -17,6 +17,7 @@ use ServoArc;
|
||||||
use block::BlockFlow;
|
use block::BlockFlow;
|
||||||
use context::{LayoutContext, with_thread_local_font_context};
|
use context::{LayoutContext, with_thread_local_font_context};
|
||||||
use data::{LayoutDataFlags, LayoutData};
|
use data::{LayoutDataFlags, LayoutData};
|
||||||
|
use display_list::items::OpaqueNode;
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use floats::FloatKind;
|
use floats::FloatKind;
|
||||||
use flow::{AbsoluteDescendants, Flow, FlowClass, GetBaseFlow, ImmutableFlowUtils};
|
use flow::{AbsoluteDescendants, Flow, FlowClass, GetBaseFlow, ImmutableFlowUtils};
|
||||||
|
@ -27,7 +28,6 @@ use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo, FragmentFlags
|
||||||
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
|
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
|
||||||
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||||
use fragment::WhitespaceStrippingResult;
|
use fragment::WhitespaceStrippingResult;
|
||||||
use gfx::display_list::OpaqueNode;
|
|
||||||
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags};
|
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags};
|
||||||
use linked_list::prepend_from;
|
use linked_list::prepend_from;
|
||||||
use list_item::{ListItemFlow, ListStyleTypeContent};
|
use list_item::{ListItemFlow, ListStyleTypeContent};
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
//! Data needed by the layout thread.
|
//! Data needed by the layout thread.
|
||||||
|
|
||||||
|
use display_list::items::{WebRenderImageInfo, OpaqueNode};
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
|
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
use gfx::font_context::FontContext;
|
use gfx::font_context::FontContext;
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use display_list::ToLayout;
|
use display_list::ToLayout;
|
||||||
|
use display_list::items::{BorderDetails, Gradient, RadialGradient, WebRenderImageInfo};
|
||||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
|
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
|
||||||
use gfx::display_list::{self, BorderDetails, WebRenderImageInfo};
|
|
||||||
use model::{self, MaybeAuto};
|
use model::{self, MaybeAuto};
|
||||||
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
|
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
|
||||||
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
||||||
|
@ -56,7 +56,9 @@ pub struct BackgroundPlacement {
|
||||||
pub tile_spacing: Size2D<Au>,
|
pub tile_spacing: Size2D<Au>,
|
||||||
/// A clip area. While the background is rendered according to all the
|
/// A clip area. While the background is rendered according to all the
|
||||||
/// measures above it is only shown within these bounds.
|
/// measures above it is only shown within these bounds.
|
||||||
pub css_clip: Rect<Au>,
|
pub clip_rect: Rect<Au>,
|
||||||
|
/// Rounded corners for the clip_rect.
|
||||||
|
pub clip_radii: BorderRadius,
|
||||||
/// Whether or not the background is fixed to the viewport.
|
/// Whether or not the background is fixed to the viewport.
|
||||||
pub fixed: bool,
|
pub fixed: bool,
|
||||||
}
|
}
|
||||||
|
@ -149,6 +151,26 @@ fn compute_background_image_size(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compute_background_clip(
|
||||||
|
bg_clip: BackgroundClip,
|
||||||
|
absolute_bounds: Rect<Au>,
|
||||||
|
border: SideOffsets2D<Au>,
|
||||||
|
border_padding: SideOffsets2D<Au>,
|
||||||
|
border_radii: BorderRadius,
|
||||||
|
) -> (Rect<Au>, BorderRadius) {
|
||||||
|
match bg_clip {
|
||||||
|
BackgroundClip::BorderBox => (absolute_bounds, border_radii),
|
||||||
|
BackgroundClip::PaddingBox => (
|
||||||
|
absolute_bounds.inner_rect(border),
|
||||||
|
calculate_inner_border_radii(border_radii, border),
|
||||||
|
),
|
||||||
|
BackgroundClip::ContentBox => (
|
||||||
|
absolute_bounds.inner_rect(border_padding),
|
||||||
|
calculate_inner_border_radii(border_radii, border_padding),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Determines where to place an element background image or gradient.
|
/// Determines where to place an element background image or gradient.
|
||||||
///
|
///
|
||||||
/// Photos have their resolution as intrinsic size while gradients have
|
/// Photos have their resolution as intrinsic size while gradients have
|
||||||
|
@ -160,6 +182,7 @@ pub fn compute_background_placement(
|
||||||
intrinsic_size: Option<Size2D<Au>>,
|
intrinsic_size: Option<Size2D<Au>>,
|
||||||
border: SideOffsets2D<Au>,
|
border: SideOffsets2D<Au>,
|
||||||
border_padding: SideOffsets2D<Au>,
|
border_padding: SideOffsets2D<Au>,
|
||||||
|
border_radii: BorderRadius,
|
||||||
index: usize,
|
index: usize,
|
||||||
) -> BackgroundPlacement {
|
) -> BackgroundPlacement {
|
||||||
let bg_attachment = *get_cyclic(&bg.background_attachment.0, index);
|
let bg_attachment = *get_cyclic(&bg.background_attachment.0, index);
|
||||||
|
@ -170,11 +193,13 @@ pub fn compute_background_placement(
|
||||||
let bg_repeat = get_cyclic(&bg.background_repeat.0, index);
|
let bg_repeat = get_cyclic(&bg.background_repeat.0, index);
|
||||||
let bg_size = *get_cyclic(&bg.background_size.0, index);
|
let bg_size = *get_cyclic(&bg.background_size.0, index);
|
||||||
|
|
||||||
let css_clip = match bg_clip {
|
let (clip_rect, clip_radii) = compute_background_clip(
|
||||||
BackgroundClip::BorderBox => absolute_bounds,
|
bg_clip,
|
||||||
BackgroundClip::PaddingBox => absolute_bounds.inner_rect(border),
|
absolute_bounds,
|
||||||
BackgroundClip::ContentBox => absolute_bounds.inner_rect(border_padding),
|
border,
|
||||||
};
|
border_padding,
|
||||||
|
border_radii,
|
||||||
|
);
|
||||||
|
|
||||||
let mut fixed = false;
|
let mut fixed = false;
|
||||||
let mut bounds = match bg_attachment {
|
let mut bounds = match bg_attachment {
|
||||||
|
@ -202,8 +227,8 @@ pub fn compute_background_placement(
|
||||||
&mut tile_size.width,
|
&mut tile_size.width,
|
||||||
&mut tile_spacing.width,
|
&mut tile_spacing.width,
|
||||||
pos_x,
|
pos_x,
|
||||||
css_clip.origin.x,
|
clip_rect.origin.x,
|
||||||
css_clip.size.width,
|
clip_rect.size.width,
|
||||||
);
|
);
|
||||||
tile_image_axis(
|
tile_image_axis(
|
||||||
bg_repeat.1,
|
bg_repeat.1,
|
||||||
|
@ -212,15 +237,16 @@ pub fn compute_background_placement(
|
||||||
&mut tile_size.height,
|
&mut tile_size.height,
|
||||||
&mut tile_spacing.height,
|
&mut tile_spacing.height,
|
||||||
pos_y,
|
pos_y,
|
||||||
css_clip.origin.y,
|
clip_rect.origin.y,
|
||||||
css_clip.size.height,
|
clip_rect.size.height,
|
||||||
);
|
);
|
||||||
|
|
||||||
BackgroundPlacement {
|
BackgroundPlacement {
|
||||||
bounds,
|
bounds,
|
||||||
tile_size,
|
tile_size,
|
||||||
tile_spacing,
|
tile_spacing,
|
||||||
css_clip,
|
clip_rect,
|
||||||
|
clip_radii,
|
||||||
fixed,
|
fixed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,7 +534,7 @@ pub fn convert_linear_gradient(
|
||||||
stops: &[GradientItem],
|
stops: &[GradientItem],
|
||||||
direction: LineDirection,
|
direction: LineDirection,
|
||||||
repeating: bool,
|
repeating: bool,
|
||||||
) -> display_list::Gradient {
|
) -> Gradient {
|
||||||
let angle = match direction {
|
let angle = match direction {
|
||||||
LineDirection::Angle(angle) => angle.radians(),
|
LineDirection::Angle(angle) => angle.radians(),
|
||||||
LineDirection::Horizontal(x) => match x {
|
LineDirection::Horizontal(x) => match x {
|
||||||
|
@ -556,7 +582,7 @@ pub fn convert_linear_gradient(
|
||||||
|
|
||||||
let center = Point2D::new(size.width / 2, size.height / 2);
|
let center = Point2D::new(size.width / 2, size.height / 2);
|
||||||
|
|
||||||
display_list::Gradient {
|
Gradient {
|
||||||
start_point: (center - delta).to_layout(),
|
start_point: (center - delta).to_layout(),
|
||||||
end_point: (center + delta).to_layout(),
|
end_point: (center + delta).to_layout(),
|
||||||
stops: stops,
|
stops: stops,
|
||||||
|
@ -570,7 +596,7 @@ pub fn convert_radial_gradient(
|
||||||
shape: EndingShape,
|
shape: EndingShape,
|
||||||
center: Position,
|
center: Position,
|
||||||
repeating: bool,
|
repeating: bool,
|
||||||
) -> display_list::RadialGradient {
|
) -> RadialGradient {
|
||||||
let center = Point2D::new(
|
let center = Point2D::new(
|
||||||
center.horizontal.to_used_value(size.width),
|
center.horizontal.to_used_value(size.width),
|
||||||
center.vertical.to_used_value(size.height),
|
center.vertical.to_used_value(size.height),
|
||||||
|
@ -593,7 +619,7 @@ pub fn convert_radial_gradient(
|
||||||
|
|
||||||
let stops = convert_gradient_stops(stops, radius.width);
|
let stops = convert_gradient_stops(stops, radius.width);
|
||||||
|
|
||||||
display_list::RadialGradient {
|
RadialGradient {
|
||||||
center: center.to_layout(),
|
center: center.to_layout(),
|
||||||
radius: radius.to_layout(),
|
radius: radius.to_layout(),
|
||||||
stops: stops,
|
stops: stops,
|
||||||
|
|
|
@ -17,8 +17,18 @@ use context::LayoutContext;
|
||||||
use display_list::ToLayout;
|
use display_list::ToLayout;
|
||||||
use display_list::background::{build_border_radius, build_image_border_details};
|
use display_list::background::{build_border_radius, build_image_border_details};
|
||||||
use display_list::background::{calculate_inner_border_radii, compute_background_placement};
|
use display_list::background::{calculate_inner_border_radii, compute_background_placement};
|
||||||
use display_list::background::{convert_linear_gradient, convert_radial_gradient};
|
use display_list::background::{convert_radial_gradient, convert_linear_gradient};
|
||||||
use display_list::background::{get_cyclic, simple_normal_border};
|
use display_list::background::{get_cyclic, simple_normal_border};
|
||||||
|
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
|
||||||
|
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
|
||||||
|
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
|
||||||
|
use display_list::items::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
|
||||||
|
use display_list::items::{DisplayListSection, GradientBorder, GradientDisplayItem};
|
||||||
|
use display_list::items::{IframeDisplayItem, ImageDisplayItem, LineDisplayItem, OpaqueNode};
|
||||||
|
use display_list::items::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
|
||||||
|
use display_list::items::{RadialGradientBorder, RadialGradientDisplayItem, SolidColorDisplayItem};
|
||||||
|
use display_list::items::{StackingContext, StackingContextType, StickyFrameData, TextDisplayItem};
|
||||||
|
use display_list::items::{TextOrientation, WebRenderImageInfo};
|
||||||
use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D};
|
use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D};
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use flow::{BaseFlow, Flow, FlowFlags};
|
use flow::{BaseFlow, Flow, FlowFlags};
|
||||||
|
@ -26,17 +36,6 @@ use flow_ref::FlowRef;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo};
|
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo};
|
||||||
use fragment::SpecificFragmentInfo;
|
use fragment::SpecificFragmentInfo;
|
||||||
use gfx::display_list;
|
|
||||||
use gfx::display_list::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
|
|
||||||
use gfx::display_list::{BoxShadowDisplayItem, ClipScrollNode};
|
|
||||||
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
|
|
||||||
use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
|
|
||||||
use gfx::display_list::{DisplayListSection, GradientDisplayItem, IframeDisplayItem};
|
|
||||||
use gfx::display_list::{ImageDisplayItem, LineDisplayItem, OpaqueNode};
|
|
||||||
use gfx::display_list::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
|
|
||||||
use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext};
|
|
||||||
use gfx::display_list::{StackingContextType, StickyFrameData, TextDisplayItem, TextOrientation};
|
|
||||||
use gfx::display_list::WebRenderImageInfo;
|
|
||||||
use gfx::text::TextRun;
|
use gfx::text::TextRun;
|
||||||
use gfx::text::glyph::ByteIndex;
|
use gfx::text::glyph::ByteIndex;
|
||||||
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
|
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
|
||||||
|
@ -45,7 +44,6 @@ use ipc_channel::ipc;
|
||||||
use list_item::ListItemFlow;
|
use list_item::ListItemFlow;
|
||||||
use model::MaybeAuto;
|
use model::MaybeAuto;
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||||
use net_traits::image::base::PixelFormat;
|
|
||||||
use net_traits::image_cache::UsePlaceholder;
|
use net_traits::image_cache::UsePlaceholder;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
|
@ -61,7 +59,7 @@ use style::computed_values::pointer_events::T as PointerEvents;
|
||||||
use style::computed_values::position::T as StylePosition;
|
use style::computed_values::position::T as StylePosition;
|
||||||
use style::computed_values::visibility::T as Visibility;
|
use style::computed_values::visibility::T as Visibility;
|
||||||
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect};
|
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect};
|
||||||
use style::properties::{ComputedValues, style_structs};
|
use style::properties::{style_structs, ComputedValues};
|
||||||
use style::servo::restyle_damage::ServoRestyleDamage;
|
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||||
use style::values::{Either, RGBA};
|
use style::values::{Either, RGBA};
|
||||||
use style::values::computed::Gradient;
|
use style::values::computed::Gradient;
|
||||||
|
@ -240,7 +238,7 @@ impl StackingContextCollectionState {
|
||||||
let mut stacking_context_info = FnvHashMap::default();
|
let mut stacking_context_info = FnvHashMap::default();
|
||||||
stacking_context_info.insert(
|
stacking_context_info.insert(
|
||||||
StackingContextId::root(),
|
StackingContextId::root(),
|
||||||
StackingContextInfo::new(StackingContextId::root())
|
StackingContextInfo::new(StackingContextId::root()),
|
||||||
);
|
);
|
||||||
|
|
||||||
StackingContextCollectionState {
|
StackingContextCollectionState {
|
||||||
|
@ -261,7 +259,7 @@ impl StackingContextCollectionState {
|
||||||
|
|
||||||
fn allocate_stacking_context_info(
|
fn allocate_stacking_context_info(
|
||||||
&mut self,
|
&mut self,
|
||||||
stacking_context_type: StackingContextType
|
stacking_context_type: StackingContextType,
|
||||||
) -> StackingContextId {
|
) -> StackingContextId {
|
||||||
let next_stacking_context_id = self.next_stacking_context_id.next();
|
let next_stacking_context_id = self.next_stacking_context_id.next();
|
||||||
let allocated_id =
|
let allocated_id =
|
||||||
|
@ -274,7 +272,7 @@ impl StackingContextCollectionState {
|
||||||
|
|
||||||
self.stacking_context_info.insert(
|
self.stacking_context_info.insert(
|
||||||
allocated_id,
|
allocated_id,
|
||||||
StackingContextInfo::new(real_stacking_context_id)
|
StackingContextInfo::new(real_stacking_context_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
allocated_id
|
allocated_id
|
||||||
|
@ -285,7 +283,11 @@ impl StackingContextCollectionState {
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
stacking_context: StackingContext,
|
stacking_context: StackingContext,
|
||||||
) {
|
) {
|
||||||
self.stacking_context_info.get_mut(&parent_id).unwrap().children.push(stacking_context);
|
self.stacking_context_info
|
||||||
|
.get_mut(&parent_id)
|
||||||
|
.unwrap()
|
||||||
|
.children
|
||||||
|
.push(stacking_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex {
|
fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex {
|
||||||
|
@ -462,7 +464,9 @@ impl<'a> DisplayListBuildState<'a> {
|
||||||
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
|
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
|
||||||
child_items.reverse();
|
child_items.reverse();
|
||||||
|
|
||||||
let mut info = self.stacking_context_info.remove(&stacking_context.id).unwrap();
|
let mut info = self.stacking_context_info
|
||||||
|
.remove(&stacking_context.id)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
info.children.sort();
|
info.children.sort();
|
||||||
|
|
||||||
|
@ -806,7 +810,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// XXXManishearth the below method should ideally use an iterator over
|
// XXXManishearth the below method should ideally use an iterator over
|
||||||
// backgrounds
|
// backgrounds
|
||||||
self.build_display_list_for_background_if_applicable_with_background(
|
self.build_display_list_for_background_if_applicable_with_background(
|
||||||
state, style, background, background_color, display_list_section, absolute_bounds)
|
state,
|
||||||
|
style,
|
||||||
|
background,
|
||||||
|
background_color,
|
||||||
|
display_list_section,
|
||||||
|
absolute_bounds,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_for_background_if_applicable_with_background(
|
fn build_display_list_for_background_if_applicable_with_background(
|
||||||
|
@ -955,6 +965,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
index: usize,
|
index: usize,
|
||||||
) {
|
) {
|
||||||
debug!("(building display list) building background image");
|
debug!("(building display list) building background image");
|
||||||
|
if webrender_image.key.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let image = Size2D::new(
|
let image = Size2D::new(
|
||||||
Au::from_px(webrender_image.width as i32),
|
Au::from_px(webrender_image.width as i32),
|
||||||
|
@ -967,13 +980,21 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
Some(image),
|
Some(image),
|
||||||
style.logical_border_width().to_physical(style.writing_mode),
|
style.logical_border_width().to_physical(style.writing_mode),
|
||||||
self.border_padding.to_physical(style.writing_mode),
|
self.border_padding.to_physical(style.writing_mode),
|
||||||
|
build_border_radius(&absolute_bounds, style.get_border()),
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||||
|
if !placement.clip_radii.is_zero() {
|
||||||
|
let clip_id =
|
||||||
|
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
|
||||||
|
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the image display item.
|
// Create the image display item.
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&placement.bounds,
|
&placement.bounds,
|
||||||
&placement.css_clip,
|
&placement.clip_rect,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
|
@ -982,11 +1003,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
debug!("(building display list) adding background image.");
|
debug!("(building display list) adding background image.");
|
||||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||||
base: base,
|
base: base,
|
||||||
webrender_image: webrender_image,
|
id: webrender_image.key.unwrap(),
|
||||||
stretch_size: placement.tile_size.to_layout(),
|
stretch_size: placement.tile_size.to_layout(),
|
||||||
tile_spacing: placement.tile_spacing.to_layout(),
|
tile_spacing: placement.tile_spacing.to_layout(),
|
||||||
image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
|
image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_webrender_image_for_paint_worklet(
|
fn get_webrender_image_for_paint_worklet(
|
||||||
|
@ -1032,7 +1055,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let webrender_image = WebRenderImageInfo {
|
let webrender_image = WebRenderImageInfo {
|
||||||
width: draw_result.width,
|
width: draw_result.width,
|
||||||
height: draw_result.height,
|
height: draw_result.height,
|
||||||
format: draw_result.format,
|
|
||||||
key: draw_result.image_key,
|
key: draw_result.image_key,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1066,12 +1088,20 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
None,
|
None,
|
||||||
style.logical_border_width().to_physical(style.writing_mode),
|
style.logical_border_width().to_physical(style.writing_mode),
|
||||||
self.border_padding.to_physical(style.writing_mode),
|
self.border_padding.to_physical(style.writing_mode),
|
||||||
|
build_border_radius(&absolute_bounds, style.get_border()),
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||||
|
if !placement.clip_radii.is_zero() {
|
||||||
|
let clip_id =
|
||||||
|
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
|
||||||
|
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||||
|
}
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&placement.bounds,
|
&placement.bounds,
|
||||||
&placement.css_clip,
|
&placement.clip_rect,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
|
@ -1109,6 +1139,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
state.add_display_item(display_item);
|
state.add_display_item(display_item);
|
||||||
|
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_for_box_shadow_if_applicable(
|
fn build_display_list_for_box_shadow_if_applicable(
|
||||||
|
@ -1252,7 +1283,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
Either::Second(Image::Gradient(ref gradient)) => {
|
Either::Second(Image::Gradient(ref gradient)) => {
|
||||||
Some(match gradient.kind {
|
Some(match gradient.kind {
|
||||||
GradientKind::Linear(angle_or_corner) => {
|
GradientKind::Linear(angle_or_corner) => {
|
||||||
BorderDetails::Gradient(display_list::GradientBorder {
|
BorderDetails::Gradient(GradientBorder {
|
||||||
gradient: convert_linear_gradient(
|
gradient: convert_linear_gradient(
|
||||||
bounds.size,
|
bounds.size,
|
||||||
&gradient.items[..],
|
&gradient.items[..],
|
||||||
|
@ -1264,7 +1295,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
GradientKind::Radial(shape, center, _angle) => {
|
GradientKind::Radial(shape, center, _angle) => {
|
||||||
BorderDetails::RadialGradient(display_list::RadialGradientBorder {
|
BorderDetails::RadialGradient(RadialGradientBorder {
|
||||||
gradient: convert_radial_gradient(
|
gradient: convert_radial_gradient(
|
||||||
bounds.size,
|
bounds.size,
|
||||||
&gradient.items[..],
|
&gradient.items[..],
|
||||||
|
@ -1519,8 +1550,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
clip: &Rect<Au>,
|
clip: &Rect<Au>,
|
||||||
) {
|
) {
|
||||||
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
||||||
self.build_display_list_no_damage(state, stacking_relative_border_box,
|
self.build_display_list_no_damage(
|
||||||
border_painting_mode, display_list_section, clip)
|
state,
|
||||||
|
stacking_relative_border_box,
|
||||||
|
border_painting_mode,
|
||||||
|
display_list_section,
|
||||||
|
clip,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_no_damage(
|
fn build_display_list_no_damage(
|
||||||
|
@ -1662,16 +1698,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
let create_base_display_item = |state: &mut DisplayListBuildState| {
|
let create_base_display_item = |state: &mut DisplayListBuildState| {
|
||||||
// Adjust the clipping region as necessary to account for `border-radius`.
|
// Adjust the clipping region as necessary to account for `border-radius`.
|
||||||
let radii = build_border_radius_for_inner_rect(
|
let radii =
|
||||||
&stacking_relative_border_box,
|
build_border_radius_for_inner_rect(&stacking_relative_border_box, &self.style);
|
||||||
&self.style
|
|
||||||
);
|
|
||||||
|
|
||||||
if !radii.is_zero() {
|
if !radii.is_zero() {
|
||||||
let clip_id = state.add_late_clip_node(
|
let clip_id =
|
||||||
stacking_relative_border_box.to_layout(),
|
state.add_late_clip_node(stacking_relative_border_box.to_layout(), radii);
|
||||||
radii
|
|
||||||
);
|
|
||||||
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1779,22 +1811,24 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
SpecificFragmentInfo::Image(ref image_fragment) => {
|
SpecificFragmentInfo::Image(ref image_fragment) => {
|
||||||
// Place the image into the display list.
|
// Place the image into the display list.
|
||||||
if let Some(ref image) = image_fragment.image {
|
if let Some(ref image) = image_fragment.image {
|
||||||
let base = create_base_display_item(state);
|
if let Some(id) = image.id {
|
||||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
let base = create_base_display_item(state);
|
||||||
base,
|
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||||
webrender_image: WebRenderImageInfo::from_image(image),
|
base,
|
||||||
stretch_size: stacking_relative_content_box.size.to_layout(),
|
id,
|
||||||
tile_spacing: LayoutSize::zero(),
|
stretch_size: stacking_relative_content_box.size.to_layout(),
|
||||||
image_rendering: self.style.get_inheritedbox().image_rendering.to_layout(),
|
tile_spacing: LayoutSize::zero(),
|
||||||
})));
|
image_rendering: self.style
|
||||||
|
.get_inheritedbox()
|
||||||
|
.image_rendering
|
||||||
|
.to_layout(),
|
||||||
|
})));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
||||||
let computed_width = canvas_fragment_info.dom_width.to_px();
|
let image_key = match canvas_fragment_info.source {
|
||||||
let computed_height = canvas_fragment_info.dom_height.to_px();
|
CanvasFragmentSource::WebGL(image_key) => image_key,
|
||||||
|
|
||||||
let (image_key, format) = match canvas_fragment_info.source {
|
|
||||||
CanvasFragmentSource::WebGL(image_key) => (image_key, PixelFormat::BGRA8),
|
|
||||||
CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer {
|
CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer {
|
||||||
Some(ref ipc_renderer) => {
|
Some(ref ipc_renderer) => {
|
||||||
let ipc_renderer = ipc_renderer.lock().unwrap();
|
let ipc_renderer = ipc_renderer.lock().unwrap();
|
||||||
|
@ -1802,7 +1836,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
ipc_renderer
|
ipc_renderer
|
||||||
.send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender)))
|
.send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(receiver.recv().unwrap().image_key, PixelFormat::BGRA8)
|
receiver.recv().unwrap().image_key
|
||||||
},
|
},
|
||||||
None => return,
|
None => return,
|
||||||
},
|
},
|
||||||
|
@ -1811,12 +1845,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let base = create_base_display_item(state);
|
let base = create_base_display_item(state);
|
||||||
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem {
|
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||||
base,
|
base,
|
||||||
webrender_image: WebRenderImageInfo {
|
id: image_key,
|
||||||
width: computed_width as u32,
|
|
||||||
height: computed_height as u32,
|
|
||||||
format: format,
|
|
||||||
key: Some(image_key),
|
|
||||||
},
|
|
||||||
stretch_size: stacking_relative_content_box.size.to_layout(),
|
stretch_size: stacking_relative_content_box.size.to_layout(),
|
||||||
tile_spacing: LayoutSize::zero(),
|
tile_spacing: LayoutSize::zero(),
|
||||||
image_rendering: ImageRendering::Auto,
|
image_rendering: ImageRendering::Auto,
|
||||||
|
@ -1942,12 +1971,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state.add_display_item(DisplayItem::PushTextShadow(Box::new(
|
state.add_display_item(DisplayItem::PushTextShadow(Box::new(
|
||||||
PushTextShadowDisplayItem {
|
PushTextShadowDisplayItem {
|
||||||
base: base.clone(),
|
base: base.clone(),
|
||||||
blur_radius: shadow.blur.px(),
|
shadow: webrender_api::Shadow {
|
||||||
offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
|
offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
|
||||||
color: shadow
|
color: shadow
|
||||||
.color
|
.color
|
||||||
.unwrap_or(self.style().get_color().color)
|
.unwrap_or(self.style().get_color().color)
|
||||||
.to_layout(),
|
.to_layout(),
|
||||||
|
blur_radius: shadow.blur.px(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -2146,7 +2177,8 @@ pub trait BlockFlowDisplayListBuilding {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
background: &style_structs::Background,
|
background: &style_structs::Background,
|
||||||
background_color: RGBA);
|
background_color: RGBA,
|
||||||
|
);
|
||||||
|
|
||||||
fn stacking_context_type(
|
fn stacking_context_type(
|
||||||
&self,
|
&self,
|
||||||
|
@ -2679,8 +2711,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
let background_border_section = self.background_border_section();
|
let background_border_section = self.background_border_section();
|
||||||
|
|
||||||
state.processing_scrolling_overflow_element = self.has_scrolling_overflow();
|
state.processing_scrolling_overflow_element = self.has_scrolling_overflow();
|
||||||
let stacking_relative_border_box =
|
let stacking_relative_border_box = self.base
|
||||||
self.base.stacking_relative_border_box_for_display_list(&self.fragment);
|
.stacking_relative_border_box_for_display_list(&self.fragment);
|
||||||
// Add the box that starts the block context.
|
// Add the box that starts the block context.
|
||||||
self.fragment.build_display_list_no_damage(
|
self.fragment.build_display_list_no_damage(
|
||||||
state,
|
state,
|
||||||
|
@ -2701,7 +2733,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
) {
|
) {
|
||||||
self.fragment.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
self.fragment
|
||||||
|
.restyle_damage
|
||||||
|
.remove(ServoRestyleDamage::REPAINT);
|
||||||
self.build_display_list_for_block_no_damage(state, border_painting_mode);
|
self.build_display_list_for_block_no_damage(state, border_painting_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2709,23 +2743,28 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
background: &style_structs::Background,
|
background: &style_structs::Background,
|
||||||
background_color: RGBA) {
|
background_color: RGBA,
|
||||||
let stacking_relative_border_box =
|
) {
|
||||||
self.base.stacking_relative_border_box_for_display_list(&self.fragment);
|
let stacking_relative_border_box = self.base
|
||||||
|
.stacking_relative_border_box_for_display_list(&self.fragment);
|
||||||
let background_border_section = self.background_border_section();
|
let background_border_section = self.background_border_section();
|
||||||
|
|
||||||
self.fragment.build_display_list_for_background_if_applicable_with_background(
|
self.fragment
|
||||||
state, self.fragment.style(), background, background_color,
|
.build_display_list_for_background_if_applicable_with_background(
|
||||||
background_border_section, &stacking_relative_border_box
|
state,
|
||||||
)
|
self.fragment.style(),
|
||||||
|
background,
|
||||||
|
background_color,
|
||||||
|
background_border_section,
|
||||||
|
&stacking_relative_border_box,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn stacking_context_type(
|
fn stacking_context_type(
|
||||||
&self,
|
&self,
|
||||||
flags: StackingContextCollectionFlags,
|
flags: StackingContextCollectionFlags,
|
||||||
) -> Option<StackingContextType>{
|
) -> Option<StackingContextType> {
|
||||||
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
|
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -2734,7 +2773,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
return Some(StackingContextType::Real);
|
return Some(StackingContextType::Real);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
|
if self.base
|
||||||
|
.flags
|
||||||
|
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
|
||||||
|
{
|
||||||
return Some(StackingContextType::PseudoPositioned);
|
return Some(StackingContextType::PseudoPositioned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2810,8 +2852,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
index: usize,
|
index: usize,
|
||||||
) {
|
) {
|
||||||
let fragment = self.fragments.fragments.get_mut(index).unwrap();
|
let fragment = self.fragments.fragments.get_mut(index).unwrap();
|
||||||
let stacking_relative_border_box =
|
let stacking_relative_border_box = self.base
|
||||||
self.base.stacking_relative_border_box_for_display_list(fragment);
|
.stacking_relative_border_box_for_display_list(fragment);
|
||||||
fragment.build_display_list(
|
fragment.build_display_list(
|
||||||
state,
|
state,
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
|
@ -2866,8 +2908,9 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
|
||||||
fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) {
|
fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) {
|
||||||
// Draw the marker, if applicable.
|
// Draw the marker, if applicable.
|
||||||
for marker in &mut self.marker_fragments {
|
for marker in &mut self.marker_fragments {
|
||||||
let stacking_relative_border_box =
|
let stacking_relative_border_box = self.block_flow
|
||||||
self.block_flow.base.stacking_relative_border_box_for_display_list(marker);
|
.base
|
||||||
|
.stacking_relative_border_box_for_display_list(marker);
|
||||||
marker.build_display_list(
|
marker.build_display_list(
|
||||||
state,
|
state,
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
|
@ -3057,6 +3100,10 @@ impl IndexableText {
|
||||||
// TODO(#20020): access all elements
|
// TODO(#20020): access all elements
|
||||||
let point = point_in_item + item[0].origin.to_vector();
|
let point = point_in_item + item[0].origin.to_vector();
|
||||||
let offset = point - item[0].baseline_origin;
|
let offset = point - item[0].baseline_origin;
|
||||||
Some(item[0].text_run.range_index_of_advance(&item[0].range, offset.x))
|
Some(
|
||||||
|
item[0]
|
||||||
|
.text_run
|
||||||
|
.range_index_of_advance(&item[0].range, offset.x),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,17 @@
|
||||||
//! perform. Using a list instead of painting elements in immediate mode allows transforms, hit
|
//! perform. Using a list instead of painting elements in immediate mode allows transforms, hit
|
||||||
//! testing, and invalidation to be performed using the same primitives as painting. It also allows
|
//! testing, and invalidation to be performed using the same primitives as painting. It also allows
|
||||||
//! Servo to aggressively cull invisible and out-of-bounds painting elements, to reduce overdraw.
|
//! Servo to aggressively cull invisible and out-of-bounds painting elements, to reduce overdraw.
|
||||||
//! Finally, display lists allow tiles to be farmed out onto multiple CPUs and painted in parallel
|
|
||||||
//! (although this benefit does not apply to GPU-based painting).
|
|
||||||
//!
|
//!
|
||||||
//! Display items describe relatively high-level drawing operations (for example, entire borders
|
//! Display items describe relatively high-level drawing operations (for example, entire borders
|
||||||
//! and shadows instead of lines and blur operations), to reduce the amount of allocation required.
|
//! and shadows instead of lines and blur operations), to reduce the amount of allocation required.
|
||||||
//! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
|
//! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
|
||||||
//! low-level drawing primitives.
|
//! low-level drawing primitives.
|
||||||
|
|
||||||
use euclid::{Vector2D, TypedRect, SideOffsets2D};
|
use euclid::{SideOffsets2D, TypedRect, Vector2D};
|
||||||
use euclid::num::{One, Zero};
|
|
||||||
use gfx_traits::{self, StackingContextId};
|
use gfx_traits::{self, StackingContextId};
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::image::base::{Image, PixelFormat};
|
use net_traits::image::base::Image;
|
||||||
use servo_geometry::MaxRect;
|
use servo_geometry::MaxRect;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -29,7 +26,7 @@ use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, Col
|
||||||
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
|
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
|
||||||
use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
|
use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
|
||||||
use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
|
use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
|
||||||
use webrender_api::{LineStyle, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity};
|
use webrender_api::{LineStyle, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity, Shadow};
|
||||||
use webrender_api::{StickyOffsetBounds, TransformStyle};
|
use webrender_api::{StickyOffsetBounds, TransformStyle};
|
||||||
|
|
||||||
pub use style::dom::OpaqueNode;
|
pub use style::dom::OpaqueNode;
|
||||||
|
@ -40,7 +37,7 @@ pub static BLUR_INFLATION_FACTOR: i32 = 3;
|
||||||
|
|
||||||
/// An index into the vector of ClipScrollNodes. During WebRender conversion these nodes
|
/// An index into the vector of ClipScrollNodes. During WebRender conversion these nodes
|
||||||
/// are given ClipIds.
|
/// are given ClipIds.
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize)]
|
||||||
pub struct ClipScrollNodeIndex(pub usize);
|
pub struct ClipScrollNodeIndex(pub usize);
|
||||||
|
|
||||||
impl ClipScrollNodeIndex {
|
impl ClipScrollNodeIndex {
|
||||||
|
@ -60,7 +57,7 @@ impl ClipScrollNodeIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of indices into the clip scroll node vector for a given item.
|
/// A set of indices into the clip scroll node vector for a given item.
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize)]
|
||||||
pub struct ClippingAndScrolling {
|
pub struct ClippingAndScrolling {
|
||||||
pub scrolling: ClipScrollNodeIndex,
|
pub scrolling: ClipScrollNodeIndex,
|
||||||
pub clipping: Option<ClipScrollNodeIndex>,
|
pub clipping: Option<ClipScrollNodeIndex>,
|
||||||
|
@ -74,7 +71,10 @@ impl ClippingAndScrolling {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(scrolling: ClipScrollNodeIndex, clipping: ClipScrollNodeIndex) -> ClippingAndScrolling {
|
pub fn new(
|
||||||
|
scrolling: ClipScrollNodeIndex,
|
||||||
|
clipping: ClipScrollNodeIndex,
|
||||||
|
) -> ClippingAndScrolling {
|
||||||
ClippingAndScrolling {
|
ClippingAndScrolling {
|
||||||
scrolling,
|
scrolling,
|
||||||
clipping: Some(clipping),
|
clipping: Some(clipping),
|
||||||
|
@ -82,7 +82,7 @@ impl ClippingAndScrolling {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct DisplayList {
|
pub struct DisplayList {
|
||||||
pub list: Vec<DisplayItem>,
|
pub list: Vec<DisplayItem>,
|
||||||
pub clip_scroll_nodes: Vec<ClipScrollNode>,
|
pub clip_scroll_nodes: Vec<ClipScrollNode>,
|
||||||
|
@ -113,11 +113,12 @@ impl DisplayList {
|
||||||
|
|
||||||
print_tree.new_level("Items".to_owned());
|
print_tree.new_level("Items".to_owned());
|
||||||
for item in &self.list {
|
for item in &self.list {
|
||||||
print_tree.add_item(format!("{:?} StackingContext: {:?} {:?}",
|
print_tree.add_item(format!(
|
||||||
|
"{:?} StackingContext: {:?} {:?}",
|
||||||
item,
|
item,
|
||||||
item.base().stacking_context_id,
|
item.base().stacking_context_id,
|
||||||
item.clipping_and_scrolling())
|
item.clipping_and_scrolling()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
print_tree.end_level();
|
print_tree.end_level();
|
||||||
}
|
}
|
||||||
|
@ -130,10 +131,7 @@ impl gfx_traits::DisplayList for DisplayList {
|
||||||
fn is_contentful(&self) -> bool {
|
fn is_contentful(&self) -> bool {
|
||||||
for item in &self.list {
|
for item in &self.list {
|
||||||
match item {
|
match item {
|
||||||
&DisplayItem::Text(_) |
|
&DisplayItem::Text(_) | &DisplayItem::Image(_) => return true,
|
||||||
&DisplayItem::Image(_) => {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +143,7 @@ impl gfx_traits::DisplayList for DisplayList {
|
||||||
/// Display list sections that make up a stacking context. Each section here refers
|
/// Display list sections that make up a stacking context. Each section here refers
|
||||||
/// to the steps in CSS 2.1 Appendix E.
|
/// to the steps in CSS 2.1 Appendix E.
|
||||||
///
|
///
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub enum DisplayListSection {
|
pub enum DisplayListSection {
|
||||||
BackgroundAndBorders,
|
BackgroundAndBorders,
|
||||||
BlockBackgroundsAndBorders,
|
BlockBackgroundsAndBorders,
|
||||||
|
@ -153,14 +151,14 @@ pub enum DisplayListSection {
|
||||||
Outlines,
|
Outlines,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub enum StackingContextType {
|
pub enum StackingContextType {
|
||||||
Real,
|
Real,
|
||||||
PseudoPositioned,
|
PseudoPositioned,
|
||||||
PseudoFloat,
|
PseudoFloat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
/// Represents one CSS stacking context, which may or may not have a hardware layer.
|
/// Represents one CSS stacking context, which may or may not have a hardware layer.
|
||||||
pub struct StackingContext {
|
pub struct StackingContext {
|
||||||
/// The ID of this StackingContext for uniquely identifying it.
|
/// The ID of this StackingContext for uniquely identifying it.
|
||||||
|
@ -203,19 +201,20 @@ pub struct StackingContext {
|
||||||
impl StackingContext {
|
impl StackingContext {
|
||||||
/// Creates a new stacking context.
|
/// Creates a new stacking context.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(id: StackingContextId,
|
pub fn new(
|
||||||
context_type: StackingContextType,
|
id: StackingContextId,
|
||||||
bounds: LayoutRect,
|
context_type: StackingContextType,
|
||||||
overflow: LayoutRect,
|
bounds: LayoutRect,
|
||||||
z_index: i32,
|
overflow: LayoutRect,
|
||||||
filters: Vec<FilterOp>,
|
z_index: i32,
|
||||||
mix_blend_mode: MixBlendMode,
|
filters: Vec<FilterOp>,
|
||||||
transform: Option<LayoutTransform>,
|
mix_blend_mode: MixBlendMode,
|
||||||
transform_style: TransformStyle,
|
transform: Option<LayoutTransform>,
|
||||||
perspective: Option<LayoutTransform>,
|
transform_style: TransformStyle,
|
||||||
scroll_policy: ScrollPolicy,
|
perspective: Option<LayoutTransform>,
|
||||||
parent_clipping_and_scrolling: ClippingAndScrolling)
|
scroll_policy: ScrollPolicy,
|
||||||
-> StackingContext {
|
parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||||
|
) -> StackingContext {
|
||||||
StackingContext {
|
StackingContext {
|
||||||
id,
|
id,
|
||||||
context_type,
|
context_type,
|
||||||
|
@ -246,7 +245,7 @@ impl StackingContext {
|
||||||
TransformStyle::Flat,
|
TransformStyle::Flat,
|
||||||
None,
|
None,
|
||||||
ScrollPolicy::Scrollable,
|
ScrollPolicy::Scrollable,
|
||||||
ClippingAndScrolling::simple(ClipScrollNodeIndex(0))
|
ClippingAndScrolling::simple(ClipScrollNodeIndex(0)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,19 +254,15 @@ impl StackingContext {
|
||||||
base_item.stacking_context_id = self.id;
|
base_item.stacking_context_id = self.id;
|
||||||
base_item.clipping_and_scrolling = self.parent_clipping_and_scrolling;
|
base_item.clipping_and_scrolling = self.parent_clipping_and_scrolling;
|
||||||
|
|
||||||
let pop_item = DisplayItem::PopStackingContext(Box::new(
|
let pop_item = DisplayItem::PopStackingContext(Box::new(PopStackingContextItem {
|
||||||
PopStackingContextItem {
|
base: base_item.clone(),
|
||||||
base: base_item.clone(),
|
stacking_context_id: self.id,
|
||||||
stacking_context_id: self.id,
|
}));
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
let push_item = DisplayItem::PushStackingContext(Box::new(
|
let push_item = DisplayItem::PushStackingContext(Box::new(PushStackingContextItem {
|
||||||
PushStackingContextItem {
|
base: base_item,
|
||||||
base: base_item,
|
stacking_context: self,
|
||||||
stacking_context: self,
|
}));
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
(push_item, pop_item)
|
(push_item, pop_item)
|
||||||
}
|
}
|
||||||
|
@ -303,28 +298,28 @@ impl PartialEq for StackingContext {
|
||||||
|
|
||||||
impl fmt::Debug for StackingContext {
|
impl fmt::Debug for StackingContext {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let type_string = if self.context_type == StackingContextType::Real {
|
let type_string = if self.context_type == StackingContextType::Real {
|
||||||
"StackingContext"
|
"StackingContext"
|
||||||
} else {
|
} else {
|
||||||
"Pseudo-StackingContext"
|
"Pseudo-StackingContext"
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(f, "{} at {:?} with overflow {:?}: {:?}",
|
write!(
|
||||||
type_string,
|
f,
|
||||||
self.bounds,
|
"{} at {:?} with overflow {:?}: {:?}",
|
||||||
self.overflow,
|
type_string, self.bounds, self.overflow, self.id
|
||||||
self.id)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct StickyFrameData {
|
pub struct StickyFrameData {
|
||||||
pub margins: SideOffsets2D<Option<f32>>,
|
pub margins: SideOffsets2D<Option<f32>>,
|
||||||
pub vertical_offset_bounds: StickyOffsetBounds,
|
pub vertical_offset_bounds: StickyOffsetBounds,
|
||||||
pub horizontal_offset_bounds: StickyOffsetBounds,
|
pub horizontal_offset_bounds: StickyOffsetBounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub enum ClipScrollNodeType {
|
pub enum ClipScrollNodeType {
|
||||||
ScrollFrame(ScrollSensitivity, ExternalScrollId),
|
ScrollFrame(ScrollSensitivity, ExternalScrollId),
|
||||||
StickyFrame(StickyFrameData),
|
StickyFrame(StickyFrameData),
|
||||||
|
@ -332,7 +327,7 @@ pub enum ClipScrollNodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a clip scroll node.
|
/// Defines a clip scroll node.
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct ClipScrollNode {
|
pub struct ClipScrollNode {
|
||||||
/// The index of the parent of this ClipScrollNode.
|
/// The index of the parent of this ClipScrollNode.
|
||||||
pub parent_index: ClipScrollNodeIndex,
|
pub parent_index: ClipScrollNodeIndex,
|
||||||
|
@ -348,7 +343,7 @@ pub struct ClipScrollNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One drawing command in the list.
|
/// One drawing command in the list.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub enum DisplayItem {
|
pub enum DisplayItem {
|
||||||
SolidColor(Box<SolidColorDisplayItem>),
|
SolidColor(Box<SolidColorDisplayItem>),
|
||||||
Text(Box<TextDisplayItem>),
|
Text(Box<TextDisplayItem>),
|
||||||
|
@ -367,7 +362,7 @@ pub enum DisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information common to all display items.
|
/// Information common to all display items.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct BaseDisplayItem {
|
pub struct BaseDisplayItem {
|
||||||
/// The boundaries of the display item, in layer coordinates.
|
/// The boundaries of the display item, in layer coordinates.
|
||||||
pub bounds: LayoutRect,
|
pub bounds: LayoutRect,
|
||||||
|
@ -390,13 +385,14 @@ pub struct BaseDisplayItem {
|
||||||
|
|
||||||
impl BaseDisplayItem {
|
impl BaseDisplayItem {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(bounds: LayoutRect,
|
pub fn new(
|
||||||
metadata: DisplayItemMetadata,
|
bounds: LayoutRect,
|
||||||
clip_rect: LayoutRect,
|
metadata: DisplayItemMetadata,
|
||||||
section: DisplayListSection,
|
clip_rect: LayoutRect,
|
||||||
stacking_context_id: StackingContextId,
|
section: DisplayListSection,
|
||||||
clipping_and_scrolling: ClippingAndScrolling)
|
stacking_context_id: StackingContextId,
|
||||||
-> BaseDisplayItem {
|
clipping_and_scrolling: ClippingAndScrolling,
|
||||||
|
) -> BaseDisplayItem {
|
||||||
BaseDisplayItem {
|
BaseDisplayItem {
|
||||||
bounds,
|
bounds,
|
||||||
metadata,
|
metadata,
|
||||||
|
@ -427,7 +423,7 @@ impl BaseDisplayItem {
|
||||||
/// A clipping region for a display item. Currently, this can describe rectangles, rounded
|
/// A clipping region for a display item. Currently, this can describe rectangles, rounded
|
||||||
/// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms
|
/// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms
|
||||||
/// are not supported because those are handled by the higher-level `StackingContext` abstraction.
|
/// are not supported because those are handled by the higher-level `StackingContext` abstraction.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
#[derive(Clone, PartialEq, Serialize)]
|
||||||
pub struct ClippingRegion {
|
pub struct ClippingRegion {
|
||||||
/// The main rectangular region. This does not include any corners.
|
/// The main rectangular region. This does not include any corners.
|
||||||
pub main: LayoutRect,
|
pub main: LayoutRect,
|
||||||
|
@ -487,7 +483,9 @@ impl ClippingRegion {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn might_intersect_point(&self, point: &LayoutPoint) -> bool {
|
pub fn might_intersect_point(&self, point: &LayoutPoint) -> bool {
|
||||||
self.main.contains(point) &&
|
self.main.contains(point) &&
|
||||||
self.complex.iter().all(|complex| complex.rect.contains(point))
|
self.complex
|
||||||
|
.iter()
|
||||||
|
.all(|complex| complex.rect.contains(point))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this clipping region might intersect the given rectangle and false
|
/// Returns true if this clipping region might intersect the given rectangle and false
|
||||||
|
@ -495,7 +493,9 @@ impl ClippingRegion {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn might_intersect_rect(&self, rect: &LayoutRect) -> bool {
|
pub fn might_intersect_rect(&self, rect: &LayoutRect) -> bool {
|
||||||
self.main.intersects(rect) &&
|
self.main.intersects(rect) &&
|
||||||
self.complex.iter().all(|complex| complex.rect.intersects(rect))
|
self.complex
|
||||||
|
.iter()
|
||||||
|
.all(|complex| complex.rect.intersects(rect))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this clipping region completely surrounds the given rect.
|
/// Returns true if this clipping region completely surrounds the given rect.
|
||||||
|
@ -535,10 +535,10 @@ impl ClippingRegion {
|
||||||
for existing_complex_region in &mut self.complex {
|
for existing_complex_region in &mut self.complex {
|
||||||
if existing_complex_region.completely_encloses(&new_complex_region) {
|
if existing_complex_region.completely_encloses(&new_complex_region) {
|
||||||
*existing_complex_region = new_complex_region;
|
*existing_complex_region = new_complex_region;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if new_complex_region.completely_encloses(existing_complex_region) {
|
if new_complex_region.completely_encloses(existing_complex_region) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,13 +550,14 @@ impl ClippingRegion {
|
||||||
pub fn translate(&self, delta: &LayoutVector2D) -> ClippingRegion {
|
pub fn translate(&self, delta: &LayoutVector2D) -> ClippingRegion {
|
||||||
ClippingRegion {
|
ClippingRegion {
|
||||||
main: self.main.translate(delta),
|
main: self.main.translate(delta),
|
||||||
complex: self.complex.iter().map(|complex| {
|
complex: self.complex
|
||||||
ComplexClipRegion {
|
.iter()
|
||||||
|
.map(|complex| ComplexClipRegion {
|
||||||
rect: complex.rect.translate(delta),
|
rect: complex.rect.translate(delta),
|
||||||
radii: complex.radii,
|
radii: complex.radii,
|
||||||
mode: complex.mode,
|
mode: complex.mode,
|
||||||
}
|
})
|
||||||
}).collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +576,11 @@ impl fmt::Debug for ClippingRegion {
|
||||||
} else if self.main == LayoutRect::max_rect() {
|
} else if self.main == LayoutRect::max_rect() {
|
||||||
write!(f, "ClippingRegion(Complex={:?})", self.complex)
|
write!(f, "ClippingRegion(Complex={:?})", self.complex)
|
||||||
} else {
|
} else {
|
||||||
write!(f, "ClippingRegion(Rect={:?}, Complex={:?})", self.main, self.complex)
|
write!(
|
||||||
|
f,
|
||||||
|
"ClippingRegion(Rect={:?}, Complex={:?})",
|
||||||
|
self.main, self.complex
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -590,11 +595,21 @@ impl CompletelyEncloses for ComplexClipRegion {
|
||||||
fn completely_encloses(&self, other: &Self) -> bool {
|
fn completely_encloses(&self, other: &Self) -> bool {
|
||||||
let left = self.radii.top_left.width.max(self.radii.bottom_left.width);
|
let left = self.radii.top_left.width.max(self.radii.bottom_left.width);
|
||||||
let top = self.radii.top_left.height.max(self.radii.top_right.height);
|
let top = self.radii.top_left.height.max(self.radii.top_right.height);
|
||||||
let right = self.radii.top_right.width.max(self.radii.bottom_right.width);
|
let right = self.radii
|
||||||
let bottom = self.radii.bottom_left.height.max(self.radii.bottom_right.height);
|
.top_right
|
||||||
let interior = LayoutRect::new(LayoutPoint::new(self.rect.origin.x + left, self.rect.origin.y + top),
|
.width
|
||||||
LayoutSize::new(self.rect.size.width - left - right,
|
.max(self.radii.bottom_right.width);
|
||||||
self.rect.size.height - top - bottom));
|
let bottom = self.radii
|
||||||
|
.bottom_left
|
||||||
|
.height
|
||||||
|
.max(self.radii.bottom_right.height);
|
||||||
|
let interior = LayoutRect::new(
|
||||||
|
LayoutPoint::new(self.rect.origin.x + left, self.rect.origin.y + top),
|
||||||
|
LayoutSize::new(
|
||||||
|
self.rect.size.width - left - right,
|
||||||
|
self.rect.size.height - top - bottom,
|
||||||
|
),
|
||||||
|
);
|
||||||
interior.origin.x <= other.rect.origin.x && interior.origin.y <= other.rect.origin.y &&
|
interior.origin.x <= other.rect.origin.x && interior.origin.y <= other.rect.origin.y &&
|
||||||
interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y()
|
interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y()
|
||||||
}
|
}
|
||||||
|
@ -603,7 +618,7 @@ impl CompletelyEncloses for ComplexClipRegion {
|
||||||
/// Metadata attached to each display item. This is useful for performing auxiliary threads with
|
/// Metadata attached to each display item. This is useful for performing auxiliary threads with
|
||||||
/// the display list involving hit testing: finding the originating DOM node and determining the
|
/// the display list involving hit testing: finding the originating DOM node and determining the
|
||||||
/// cursor to use when the element is hovered over.
|
/// cursor to use when the element is hovered over.
|
||||||
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Copy, Serialize)]
|
||||||
pub struct DisplayItemMetadata {
|
pub struct DisplayItemMetadata {
|
||||||
/// The DOM node from which this display item originated.
|
/// The DOM node from which this display item originated.
|
||||||
pub node: OpaqueNode,
|
pub node: OpaqueNode,
|
||||||
|
@ -613,7 +628,7 @@ pub struct DisplayItemMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a solid color.
|
/// Paints a solid color.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct SolidColorDisplayItem {
|
pub struct SolidColorDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -623,7 +638,7 @@ pub struct SolidColorDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints text.
|
/// Paints text.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct TextDisplayItem {
|
pub struct TextDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -635,7 +650,7 @@ pub struct TextDisplayItem {
|
||||||
pub text_color: ColorF,
|
pub text_color: ColorF,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
|
#[derive(Clone, Eq, PartialEq, Serialize)]
|
||||||
pub enum TextOrientation {
|
pub enum TextOrientation {
|
||||||
Upright,
|
Upright,
|
||||||
SidewaysLeft,
|
SidewaysLeft,
|
||||||
|
@ -643,11 +658,11 @@ pub enum TextOrientation {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints an image.
|
/// Paints an image.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct ImageDisplayItem {
|
pub struct ImageDisplayItem {
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
|
||||||
pub webrender_image: WebRenderImageInfo,
|
pub id: ImageKey,
|
||||||
|
|
||||||
/// The dimensions to which the image display item should be stretched. If this is smaller than
|
/// The dimensions to which the image display item should be stretched. If this is smaller than
|
||||||
/// the bounds of this display item, then the image will be repeated in the appropriate
|
/// the bounds of this display item, then the image will be repeated in the appropriate
|
||||||
|
@ -663,14 +678,14 @@ pub struct ImageDisplayItem {
|
||||||
pub image_rendering: ImageRendering,
|
pub image_rendering: ImageRendering,
|
||||||
}
|
}
|
||||||
/// Paints an iframe.
|
/// Paints an iframe.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct IframeDisplayItem {
|
pub struct IframeDisplayItem {
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
pub iframe: PipelineId,
|
pub iframe: PipelineId,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a gradient.
|
/// Paints a gradient.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct Gradient {
|
pub struct Gradient {
|
||||||
/// The start point of the gradient (computed during display list construction).
|
/// The start point of the gradient (computed during display list construction).
|
||||||
pub start_point: LayoutPoint,
|
pub start_point: LayoutPoint,
|
||||||
|
@ -685,7 +700,7 @@ pub struct Gradient {
|
||||||
pub extend_mode: ExtendMode,
|
pub extend_mode: ExtendMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct GradientDisplayItem {
|
pub struct GradientDisplayItem {
|
||||||
/// Fields common to all display item.
|
/// Fields common to all display item.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -705,7 +720,7 @@ pub struct GradientDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a radial gradient.
|
/// Paints a radial gradient.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct RadialGradient {
|
pub struct RadialGradient {
|
||||||
/// The center point of the gradient.
|
/// The center point of the gradient.
|
||||||
pub center: LayoutPoint,
|
pub center: LayoutPoint,
|
||||||
|
@ -720,7 +735,7 @@ pub struct RadialGradient {
|
||||||
pub extend_mode: ExtendMode,
|
pub extend_mode: ExtendMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct RadialGradientDisplayItem {
|
pub struct RadialGradientDisplayItem {
|
||||||
/// Fields common to all display item.
|
/// Fields common to all display item.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -740,7 +755,7 @@ pub struct RadialGradientDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A border that is made of linear gradient
|
/// A border that is made of linear gradient
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct GradientBorder {
|
pub struct GradientBorder {
|
||||||
/// The gradient info that this border uses, border-image-source.
|
/// The gradient info that this border uses, border-image-source.
|
||||||
pub gradient: Gradient,
|
pub gradient: Gradient,
|
||||||
|
@ -750,7 +765,7 @@ pub struct GradientBorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A border that is made of radial gradient
|
/// A border that is made of radial gradient
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct RadialGradientBorder {
|
pub struct RadialGradientBorder {
|
||||||
/// The gradient info that this border uses, border-image-source.
|
/// The gradient info that this border uses, border-image-source.
|
||||||
pub gradient: RadialGradient,
|
pub gradient: RadialGradient,
|
||||||
|
@ -760,7 +775,7 @@ pub struct RadialGradientBorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies the type of border
|
/// Specifies the type of border
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub enum BorderDetails {
|
pub enum BorderDetails {
|
||||||
Normal(NormalBorder),
|
Normal(NormalBorder),
|
||||||
Image(ImageBorder),
|
Image(ImageBorder),
|
||||||
|
@ -769,7 +784,7 @@ pub enum BorderDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a border.
|
/// Paints a border.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct BorderDisplayItem {
|
pub struct BorderDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -782,7 +797,7 @@ pub struct BorderDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a line segment.
|
/// Paints a line segment.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct LineDisplayItem {
|
pub struct LineDisplayItem {
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
|
||||||
|
@ -794,7 +809,7 @@ pub struct LineDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paints a box shadow per CSS-BACKGROUNDS.
|
/// Paints a box shadow per CSS-BACKGROUNDS.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct BoxShadowDisplayItem {
|
pub struct BoxShadowDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -822,30 +837,23 @@ pub struct BoxShadowDisplayItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a text shadow that affects all items until the paired PopTextShadow.
|
/// Defines a text shadow that affects all items until the paired PopTextShadow.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct PushTextShadowDisplayItem {
|
pub struct PushTextShadowDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
|
||||||
/// The offset of this shadow from the text.
|
pub shadow: Shadow,
|
||||||
pub offset: LayoutVector2D,
|
|
||||||
|
|
||||||
/// The color of this shadow.
|
|
||||||
pub color: ColorF,
|
|
||||||
|
|
||||||
/// The blur radius for this shadow.
|
|
||||||
pub blur_radius: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a text shadow that affects all items until the next PopTextShadow.
|
/// Defines a text shadow that affects all items until the next PopTextShadow.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct PopAllTextShadowsDisplayItem {
|
pub struct PopAllTextShadowsDisplayItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a stacking context.
|
/// Defines a stacking context.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct PushStackingContextItem {
|
pub struct PushStackingContextItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -854,7 +862,7 @@ pub struct PushStackingContextItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a stacking context.
|
/// Defines a stacking context.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct PopStackingContextItem {
|
pub struct PopStackingContextItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -863,7 +871,7 @@ pub struct PopStackingContextItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a group of items inside a particular scroll root.
|
/// Starts a group of items inside a particular scroll root.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub struct DefineClipScrollNodeItem {
|
pub struct DefineClipScrollNodeItem {
|
||||||
/// Fields common to all display items.
|
/// Fields common to all display items.
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
@ -935,14 +943,17 @@ impl fmt::Debug for DisplayItem {
|
||||||
return write!(f, "DefineClipScrollNode({:?}", item.node_index);
|
return write!(f, "DefineClipScrollNode({:?}", item.node_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{} @ {:?} {:?}",
|
write!(
|
||||||
|
f,
|
||||||
|
"{} @ {:?} {:?}",
|
||||||
match *self {
|
match *self {
|
||||||
DisplayItem::SolidColor(ref solid_color) =>
|
DisplayItem::SolidColor(ref solid_color) => format!(
|
||||||
format!("SolidColor rgba({}, {}, {}, {})",
|
"SolidColor rgba({}, {}, {}, {})",
|
||||||
solid_color.color.r,
|
solid_color.color.r,
|
||||||
solid_color.color.g,
|
solid_color.color.g,
|
||||||
solid_color.color.b,
|
solid_color.color.b,
|
||||||
solid_color.color.a),
|
solid_color.color.a
|
||||||
|
),
|
||||||
DisplayItem::Text(_) => "Text".to_owned(),
|
DisplayItem::Text(_) => "Text".to_owned(),
|
||||||
DisplayItem::Image(_) => "Image".to_owned(),
|
DisplayItem::Image(_) => "Image".to_owned(),
|
||||||
DisplayItem::Border(_) => "Border".to_owned(),
|
DisplayItem::Border(_) => "Border".to_owned(),
|
||||||
|
@ -963,11 +974,10 @@ impl fmt::Debug for DisplayItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Copy, Serialize)]
|
||||||
pub struct WebRenderImageInfo {
|
pub struct WebRenderImageInfo {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
pub format: PixelFormat,
|
|
||||||
pub key: Option<ImageKey>,
|
pub key: Option<ImageKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,7 +987,6 @@ impl WebRenderImageInfo {
|
||||||
WebRenderImageInfo {
|
WebRenderImageInfo {
|
||||||
width: image.width,
|
width: image.width,
|
||||||
height: image.height,
|
height: image.height,
|
||||||
format: image.format,
|
|
||||||
key: image.id,
|
key: image.id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -986,7 +995,6 @@ impl WebRenderImageInfo {
|
||||||
/// The type of the scroll offset list. This is only populated if WebRender is in use.
|
/// The type of the scroll offset list. This is only populated if WebRender is in use.
|
||||||
pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32>>;
|
pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32>>;
|
||||||
|
|
||||||
|
|
||||||
pub trait SimpleMatrixDetection {
|
pub trait SimpleMatrixDetection {
|
||||||
fn is_identity_or_simple_translation(&self) -> bool;
|
fn is_identity_or_simple_translation(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
@ -994,11 +1002,9 @@ pub trait SimpleMatrixDetection {
|
||||||
impl SimpleMatrixDetection for LayoutTransform {
|
impl SimpleMatrixDetection for LayoutTransform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_identity_or_simple_translation(&self) -> bool {
|
fn is_identity_or_simple_translation(&self) -> bool {
|
||||||
let (_0, _1) = (Zero::zero(), One::one());
|
let (_0, _1) = (0.0, 1.0);
|
||||||
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 &&
|
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 && self.m21 == _0 &&
|
||||||
self.m21 == _0 && self.m22 == _1 && self.m23 == _0 && self.m24 == _0 &&
|
self.m22 == _1 && self.m23 == _0 && self.m24 == _0 && self.m31 == _0 &&
|
||||||
self.m31 == _0 && self.m32 == _0 && self.m33 == _1 && self.m34 == _0 &&
|
self.m32 == _0 && self.m33 == _1 && self.m34 == _0 && self.m44 == _1
|
||||||
self.m44 == _1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,5 @@ pub use self::webrender_helpers::WebRenderDisplayListConverter;
|
||||||
mod background;
|
mod background;
|
||||||
mod builder;
|
mod builder;
|
||||||
mod conversions;
|
mod conversions;
|
||||||
|
pub mod items;
|
||||||
mod webrender_helpers;
|
mod webrender_helpers;
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
// This might be achieved by sharing types between WR and Servo display lists, or
|
// This might be achieved by sharing types between WR and Servo display lists, or
|
||||||
// completely converting layout to directly generate WebRender display lists, for example.
|
// completely converting layout to directly generate WebRender display lists, for example.
|
||||||
|
|
||||||
use gfx::display_list::{BorderDetails, ClipScrollNode};
|
use display_list::items::{BorderDetails, ClipScrollNode};
|
||||||
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
||||||
use gfx::display_list::{DisplayList, StackingContextType};
|
use display_list::items::{DisplayList, StackingContextType};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder};
|
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder};
|
||||||
|
|
||||||
|
@ -111,17 +111,15 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
DisplayItem::Image(ref item) => {
|
DisplayItem::Image(ref item) => {
|
||||||
if let Some(id) = item.webrender_image.key {
|
if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
|
||||||
if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
|
builder.push_image(
|
||||||
builder.push_image(
|
&self.prim_info(),
|
||||||
&self.prim_info(),
|
item.stretch_size,
|
||||||
item.stretch_size,
|
item.tile_spacing,
|
||||||
item.tile_spacing,
|
item.image_rendering,
|
||||||
item.image_rendering,
|
webrender_api::AlphaType::PremultipliedAlpha,
|
||||||
webrender_api::AlphaType::PremultipliedAlpha,
|
item.id,
|
||||||
id,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DisplayItem::Border(ref item) => {
|
DisplayItem::Border(ref item) => {
|
||||||
|
@ -204,14 +202,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
DisplayItem::PushTextShadow(ref item) => {
|
DisplayItem::PushTextShadow(ref item) => {
|
||||||
builder.push_shadow(
|
builder.push_shadow(&self.prim_info(), item.shadow);
|
||||||
&self.prim_info(),
|
|
||||||
webrender_api::Shadow {
|
|
||||||
blur_radius: item.blur_radius,
|
|
||||||
offset: item.offset,
|
|
||||||
color: item.color,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
DisplayItem::PopAllTextShadows(_) => {
|
DisplayItem::PopAllTextShadows(_) => {
|
||||||
builder.pop_all_shadows();
|
builder.pop_all_shadows();
|
||||||
|
|
|
@ -29,13 +29,13 @@ use app_units::Au;
|
||||||
use block::{BlockFlow, FormattingContextType};
|
use block::{BlockFlow, FormattingContextType};
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use display_list::{DisplayListBuildState, StackingContextCollectionState};
|
use display_list::{DisplayListBuildState, StackingContextCollectionState};
|
||||||
|
use display_list::items::ClippingAndScrolling;
|
||||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use floats::{Floats, SpeculatedFloatPlacement};
|
use floats::{Floats, SpeculatedFloatPlacement};
|
||||||
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
||||||
use flow_ref::{FlowRef, WeakFlowRef};
|
use flow_ref::{FlowRef, WeakFlowRef};
|
||||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||||
use gfx::display_list::ClippingAndScrolling;
|
|
||||||
use gfx_traits::StackingContextId;
|
use gfx_traits::StackingContextId;
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use inline::InlineFlow;
|
use inline::InlineFlow;
|
||||||
|
|
|
@ -11,12 +11,12 @@ use app_units::Au;
|
||||||
use canvas_traits::canvas::CanvasMsg;
|
use canvas_traits::canvas::CanvasMsg;
|
||||||
use context::{LayoutContext, with_thread_local_font_context};
|
use context::{LayoutContext, with_thread_local_font_context};
|
||||||
use display_list::ToLayout;
|
use display_list::ToLayout;
|
||||||
|
use display_list::items::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||||
use floats::ClearType;
|
use floats::ClearType;
|
||||||
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
||||||
use flow_ref::FlowRef;
|
use flow_ref::FlowRef;
|
||||||
use gfx;
|
use gfx;
|
||||||
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
|
||||||
use gfx::text::glyph::ByteIndex;
|
use gfx::text::glyph::ByteIndex;
|
||||||
use gfx::text::text_run::{TextRun, TextRunSlice};
|
use gfx::text::text_run::{TextRun, TextRunSlice};
|
||||||
use gfx_traits::StackingContextId;
|
use gfx_traits::StackingContextId;
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
//! as possible.
|
//! as possible.
|
||||||
|
|
||||||
use context::{LayoutContext, with_thread_local_font_context};
|
use context::{LayoutContext, with_thread_local_font_context};
|
||||||
|
use display_list::items::OpaqueNode;
|
||||||
use flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils};
|
use flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils};
|
||||||
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||||
use gfx::display_list::OpaqueNode;
|
|
||||||
use script_layout_interface::wrapper_traits::PseudoElementType;
|
use script_layout_interface::wrapper_traits::PseudoElementType;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::{HashMap, LinkedList};
|
use std::collections::{HashMap, LinkedList};
|
||||||
|
|
|
@ -10,6 +10,7 @@ use block::AbsoluteAssignBSizesTraversal;
|
||||||
use context::{LayoutContext, LayoutFontContext};
|
use context::{LayoutContext, LayoutFontContext};
|
||||||
use display_list::{DisplayListBuildState, InlineFlowDisplayListBuilding};
|
use display_list::{DisplayListBuildState, InlineFlowDisplayListBuilding};
|
||||||
use display_list::StackingContextCollectionState;
|
use display_list::StackingContextCollectionState;
|
||||||
|
use display_list::items::OpaqueNode;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
use floats::{FloatKind, Floats, PlacementInfo};
|
use floats::{FloatKind, Floats, PlacementInfo};
|
||||||
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
|
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
|
||||||
|
@ -18,7 +19,6 @@ use flow_ref::FlowRef;
|
||||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||||
use fragment::FragmentFlags;
|
use fragment::FragmentFlags;
|
||||||
use fragment::SpecificFragmentInfo;
|
use fragment::SpecificFragmentInfo;
|
||||||
use gfx::display_list::OpaqueNode;
|
|
||||||
use gfx::font::FontMetrics;
|
use gfx::font::FontMetrics;
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use gfx::display_list::OpaqueNode;
|
use display_list::items::OpaqueNode;
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ use app_units::Au;
|
||||||
use construct::ConstructionResult;
|
use construct::ConstructionResult;
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use display_list::IndexableText;
|
use display_list::IndexableText;
|
||||||
|
use display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
||||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||||
use flow::{Flow, GetBaseFlow};
|
use flow::{Flow, GetBaseFlow};
|
||||||
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||||
use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
|
||||||
use inline::InlineFragmentNodeFlags;
|
use inline::InlineFragmentNodeFlags;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
|
|
|
@ -55,7 +55,6 @@ use dom_wrapper::{ServoLayoutElement, ServoLayoutDocument, ServoLayoutNode};
|
||||||
use dom_wrapper::drop_style_and_layout_data;
|
use dom_wrapper::drop_style_and_layout_data;
|
||||||
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
|
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use gfx::display_list::{OpaqueNode, WebRenderImageInfo};
|
|
||||||
use gfx::font;
|
use gfx::font;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
use gfx::font_context;
|
use gfx::font_context;
|
||||||
|
@ -68,8 +67,8 @@ use layout::context::LayoutContext;
|
||||||
use layout::context::RegisteredPainter;
|
use layout::context::RegisteredPainter;
|
||||||
use layout::context::RegisteredPainters;
|
use layout::context::RegisteredPainters;
|
||||||
use layout::context::malloc_size_of_persistent_local_context;
|
use layout::context::malloc_size_of_persistent_local_context;
|
||||||
use layout::display_list::{IndexableText, ToLayout};
|
use layout::display_list::{IndexableText, ToLayout, WebRenderDisplayListConverter};
|
||||||
use layout::display_list::WebRenderDisplayListConverter;
|
use layout::display_list::items::{OpaqueNode, WebRenderImageInfo};
|
||||||
use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||||
use layout::flow_ref::FlowRef;
|
use layout::flow_ref::FlowRef;
|
||||||
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage};
|
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage};
|
||||||
|
|
|
@ -10,12 +10,11 @@ path = "lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gfx = {path = "../../../components/gfx"}
|
|
||||||
gfx_traits = {path = "../../../components/gfx_traits"}
|
gfx_traits = {path = "../../../components/gfx_traits"}
|
||||||
ipc-channel = "0.10"
|
ipc-channel = "0.10"
|
||||||
|
layout = {path = "../../../components/layout"}
|
||||||
metrics = {path = "../../../components/metrics"}
|
metrics = {path = "../../../components/metrics"}
|
||||||
msg = {path = "../../../components/msg"}
|
msg = {path = "../../../components/msg"}
|
||||||
net_traits = {path = "../../../components/net_traits"}
|
|
||||||
profile_traits = {path = "../../../components/profile_traits"}
|
profile_traits = {path = "../../../components/profile_traits"}
|
||||||
servo_url = {path = "../../../components/url"}
|
servo_url = {path = "../../../components/url"}
|
||||||
time = "0.1.12"
|
time = "0.1.12"
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
|
|
||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
|
|
||||||
extern crate gfx;
|
|
||||||
extern crate gfx_traits;
|
extern crate gfx_traits;
|
||||||
extern crate ipc_channel;
|
extern crate ipc_channel;
|
||||||
|
extern crate layout;
|
||||||
extern crate metrics;
|
extern crate metrics;
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
extern crate net_traits;
|
|
||||||
extern crate profile_traits;
|
extern crate profile_traits;
|
||||||
extern crate servo_url;
|
extern crate servo_url;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
|
@ -2,17 +2,15 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use gfx::display_list::{BaseDisplayItem, WebRenderImageInfo};
|
|
||||||
use gfx::display_list::{DisplayItem, DisplayList, ImageDisplayItem};
|
|
||||||
use gfx_traits::Epoch;
|
use gfx_traits::Epoch;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
|
use layout::display_list::items::{BaseDisplayItem, DisplayItem, DisplayList, ImageDisplayItem};
|
||||||
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
|
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
|
||||||
use msg::constellation_msg::TEST_PIPELINE_ID;
|
use msg::constellation_msg::TEST_PIPELINE_ID;
|
||||||
use net_traits::image::base::PixelFormat;
|
|
||||||
use profile_traits::time::{ProfilerChan, TimerMetadata};
|
use profile_traits::time::{ProfilerChan, TimerMetadata};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use time;
|
use time;
|
||||||
use webrender_api::{ImageRendering, LayoutSize};
|
use webrender_api::{ImageKey, ImageRendering, LayoutSize};
|
||||||
|
|
||||||
struct DummyProfilerMetadataFactory {}
|
struct DummyProfilerMetadataFactory {}
|
||||||
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
|
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
|
||||||
|
@ -120,12 +118,7 @@ fn test_first_paint_setter() {
|
||||||
fn test_first_contentful_paint_setter() {
|
fn test_first_contentful_paint_setter() {
|
||||||
let image = DisplayItem::Image(Box::new(ImageDisplayItem {
|
let image = DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||||
base: BaseDisplayItem::empty(),
|
base: BaseDisplayItem::empty(),
|
||||||
webrender_image: WebRenderImageInfo {
|
id: ImageKey::DUMMY,
|
||||||
width: 1,
|
|
||||||
height: 1,
|
|
||||||
format: PixelFormat::RGB8,
|
|
||||||
key: None,
|
|
||||||
},
|
|
||||||
stretch_size: LayoutSize::zero(),
|
stretch_size: LayoutSize::zero(),
|
||||||
tile_spacing: LayoutSize::zero(),
|
tile_spacing: LayoutSize::zero(),
|
||||||
image_rendering: ImageRendering::Auto,
|
image_rendering: ImageRendering::Auto,
|
||||||
|
|
|
@ -100521,6 +100521,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/background-rounded-image-clip.html": [
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/background-rounded-image-clip.html",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/reference/background-rounded-image-clip.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/background-size-002.html": [
|
"css/css-backgrounds/background-size-002.html": [
|
||||||
[
|
[
|
||||||
"/css/css-backgrounds/background-size-002.html",
|
"/css/css-backgrounds/background-size-002.html",
|
||||||
|
@ -236779,6 +236791,11 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
|
||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -483700,6 +483717,10 @@
|
||||||
"36050bffda9382cfd978dc82a2f0244a535a6a46",
|
"36050bffda9382cfd978dc82a2f0244a535a6a46",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/background-rounded-image-clip.html": [
|
||||||
|
"c22edf865829fea1d69a54e34396b4462250585f",
|
||||||
|
"reftest"
|
||||||
|
],
|
||||||
"css/css-backgrounds/background-size-001.html": [
|
"css/css-backgrounds/background-size-001.html": [
|
||||||
"7cf677bf25a1fcac569bd0accd28dd66e6060a1b",
|
"7cf677bf25a1fcac569bd0accd28dd66e6060a1b",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
@ -485904,6 +485925,10 @@
|
||||||
"1141a4c270ace715755b9b8352dab9baffca27c4",
|
"1141a4c270ace715755b9b8352dab9baffca27c4",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
|
||||||
|
"f5c1af4d9e5b415e762c921c6d93355b2861946c",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
||||||
"33d8850f315bedabb7024031b091a14177034c1d",
|
"33d8850f315bedabb7024031b091a14177034c1d",
|
||||||
"support"
|
"support"
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Background Clip Follows Rounded Corner</title>
|
||||||
|
<link rel="match" href="reference/background-rounded-image-clip.html">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping">
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
#a {
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#b {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
background-image: linear-gradient(green, green);
|
||||||
|
background-clip: content-box;
|
||||||
|
border-top-left-radius: 90px;
|
||||||
|
border-width: 10px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="a"></div>
|
||||||
|
<div id="b"></div>
|
||||||
|
</body>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
#a {
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="a"></div>
|
Loading…
Add table
Add a link
Reference in a new issue