mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #20420 - pyfisch:corner-clipping, r=emilio
Move DL items from gfx to layout and implement corner clipping Implement corner clipping. Remove PixelFormat from WebrenderImageInfo. Use WebRender text shadow. Remove MallocSizeOf and Deserialize for DL items. Closes #19649, closes #19680, closes #19802 <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20420) <!-- Reviewable:end -->
This commit is contained in:
commit
0ff6f32d7d
26 changed files with 495 additions and 361 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1036,8 +1036,6 @@ dependencies = [
|
|||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of 0.0.1",
|
||||
"malloc_size_of_derive 0.0.1",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"range 0.0.1",
|
||||
|
@ -1046,7 +1044,6 @@ dependencies = [
|
|||
"servo_allocator 0.0.1",
|
||||
"servo_arc 0.1.1",
|
||||
"servo_atoms 0.0.1",
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"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)",
|
||||
|
@ -1750,12 +1747,11 @@ dependencies = [
|
|||
name = "metrics_tests"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"gfx 0.0.1",
|
||||
"gfx_traits 0.0.1",
|
||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"layout 0.0.1",
|
||||
"metrics 0.0.1",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"profile_traits 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -28,15 +28,12 @@ lazy_static = "1"
|
|||
libc = "0.2"
|
||||
log = "0.4"
|
||||
malloc_size_of = { path = "../malloc_size_of" }
|
||||
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
ordered-float = "0.4"
|
||||
range = {path = "../range"}
|
||||
serde = "1.0"
|
||||
servo_arc = {path = "../servo_arc"}
|
||||
servo_atoms = {path = "../atoms"}
|
||||
servo_geometry = {path = "../geometry"}
|
||||
servo_url = {path = "../url"}
|
||||
smallvec = "0.6"
|
||||
style = {path = "../style"}
|
||||
|
|
|
@ -43,14 +43,11 @@ extern crate lazy_static;
|
|||
extern crate log;
|
||||
#[cfg_attr(target_os = "windows", macro_use)]
|
||||
extern crate malloc_size_of;
|
||||
#[macro_use] extern crate malloc_size_of_derive;
|
||||
extern crate msg;
|
||||
extern crate net_traits;
|
||||
extern crate ordered_float;
|
||||
extern crate range;
|
||||
#[macro_use] extern crate serde;
|
||||
extern crate servo_arc;
|
||||
extern crate servo_geometry;
|
||||
extern crate servo_url;
|
||||
#[macro_use] extern crate servo_atoms;
|
||||
#[cfg(feature = "unstable")]
|
||||
|
@ -66,9 +63,6 @@ extern crate xi_unicode;
|
|||
#[cfg(target_os = "android")]
|
||||
extern crate xml5ever;
|
||||
|
||||
#[deny(unsafe_code)]
|
||||
pub mod display_list;
|
||||
|
||||
// Fonts
|
||||
#[macro_use] pub mod font;
|
||||
pub mod font_cache_thread;
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* 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/. */
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FontContextHandle {
|
||||
ctx: ()
|
||||
}
|
||||
|
@ -13,3 +15,9 @@ impl FontContextHandle {
|
|||
FontContextHandle { ctx: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl MallocSizeOf for FontContextHandle {
|
||||
fn size_of(&self, _: &mut MallocSizeOfOps) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
//! CSS transitions and animations.
|
||||
|
||||
use context::LayoutContext;
|
||||
use display_list::items::OpaqueNode;
|
||||
use flow::{Flow, GetBaseFlow};
|
||||
use fnv::FnvHashMap;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use opaque_node::OpaqueNodeMethods;
|
||||
|
|
|
@ -32,13 +32,13 @@ use context::LayoutContext;
|
|||
use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode};
|
||||
use display_list::{DisplayListBuildState, StackingContextCollectionFlags};
|
||||
use display_list::StackingContextCollectionState;
|
||||
use display_list::items::DisplayListSection;
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
||||
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag, GetBaseFlow};
|
||||
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags};
|
||||
use flow_list::FlowList;
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
|
||||
use gfx::display_list::DisplayListSection;
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
use incremental::RelayoutMode;
|
||||
use layout_debug;
|
||||
|
|
|
@ -17,6 +17,7 @@ use ServoArc;
|
|||
use block::BlockFlow;
|
||||
use context::{LayoutContext, with_thread_local_font_context};
|
||||
use data::{LayoutDataFlags, LayoutData};
|
||||
use display_list::items::OpaqueNode;
|
||||
use flex::FlexFlow;
|
||||
use floats::FloatKind;
|
||||
use flow::{AbsoluteDescendants, Flow, FlowClass, GetBaseFlow, ImmutableFlowUtils};
|
||||
|
@ -27,7 +28,6 @@ use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo, FragmentFlags
|
|||
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
|
||||
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||
use fragment::WhitespaceStrippingResult;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags};
|
||||
use linked_list::prepend_from;
|
||||
use list_item::{ListItemFlow, ListStyleTypeContent};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
//! Data needed by the layout thread.
|
||||
|
||||
use display_list::items::{WebRenderImageInfo, OpaqueNode};
|
||||
use fnv::FnvHasher;
|
||||
use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
|
||||
use gfx::font_cache_thread::FontCacheThread;
|
||||
use gfx::font_context::FontContext;
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
use app_units::Au;
|
||||
use display_list::ToLayout;
|
||||
use display_list::items::{BorderDetails, Gradient, RadialGradient, WebRenderImageInfo};
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
|
||||
use gfx::display_list::{self, BorderDetails, WebRenderImageInfo};
|
||||
use model::{self, MaybeAuto};
|
||||
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
|
||||
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
||||
|
@ -56,7 +56,9 @@ pub struct BackgroundPlacement {
|
|||
pub tile_spacing: Size2D<Au>,
|
||||
/// A clip area. While the background is rendered according to all the
|
||||
/// 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.
|
||||
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.
|
||||
///
|
||||
/// Photos have their resolution as intrinsic size while gradients have
|
||||
|
@ -160,6 +182,7 @@ pub fn compute_background_placement(
|
|||
intrinsic_size: Option<Size2D<Au>>,
|
||||
border: SideOffsets2D<Au>,
|
||||
border_padding: SideOffsets2D<Au>,
|
||||
border_radii: BorderRadius,
|
||||
index: usize,
|
||||
) -> BackgroundPlacement {
|
||||
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_size = *get_cyclic(&bg.background_size.0, index);
|
||||
|
||||
let css_clip = match bg_clip {
|
||||
BackgroundClip::BorderBox => absolute_bounds,
|
||||
BackgroundClip::PaddingBox => absolute_bounds.inner_rect(border),
|
||||
BackgroundClip::ContentBox => absolute_bounds.inner_rect(border_padding),
|
||||
};
|
||||
let (clip_rect, clip_radii) = compute_background_clip(
|
||||
bg_clip,
|
||||
absolute_bounds,
|
||||
border,
|
||||
border_padding,
|
||||
border_radii,
|
||||
);
|
||||
|
||||
let mut fixed = false;
|
||||
let mut bounds = match bg_attachment {
|
||||
|
@ -202,8 +227,8 @@ pub fn compute_background_placement(
|
|||
&mut tile_size.width,
|
||||
&mut tile_spacing.width,
|
||||
pos_x,
|
||||
css_clip.origin.x,
|
||||
css_clip.size.width,
|
||||
clip_rect.origin.x,
|
||||
clip_rect.size.width,
|
||||
);
|
||||
tile_image_axis(
|
||||
bg_repeat.1,
|
||||
|
@ -212,15 +237,16 @@ pub fn compute_background_placement(
|
|||
&mut tile_size.height,
|
||||
&mut tile_spacing.height,
|
||||
pos_y,
|
||||
css_clip.origin.y,
|
||||
css_clip.size.height,
|
||||
clip_rect.origin.y,
|
||||
clip_rect.size.height,
|
||||
);
|
||||
|
||||
BackgroundPlacement {
|
||||
bounds,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
css_clip,
|
||||
clip_rect,
|
||||
clip_radii,
|
||||
fixed,
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +534,7 @@ pub fn convert_linear_gradient(
|
|||
stops: &[GradientItem],
|
||||
direction: LineDirection,
|
||||
repeating: bool,
|
||||
) -> display_list::Gradient {
|
||||
) -> Gradient {
|
||||
let angle = match direction {
|
||||
LineDirection::Angle(angle) => angle.radians(),
|
||||
LineDirection::Horizontal(x) => match x {
|
||||
|
@ -556,7 +582,7 @@ pub fn convert_linear_gradient(
|
|||
|
||||
let center = Point2D::new(size.width / 2, size.height / 2);
|
||||
|
||||
display_list::Gradient {
|
||||
Gradient {
|
||||
start_point: (center - delta).to_layout(),
|
||||
end_point: (center + delta).to_layout(),
|
||||
stops: stops,
|
||||
|
@ -570,7 +596,7 @@ pub fn convert_radial_gradient(
|
|||
shape: EndingShape,
|
||||
center: Position,
|
||||
repeating: bool,
|
||||
) -> display_list::RadialGradient {
|
||||
) -> RadialGradient {
|
||||
let center = Point2D::new(
|
||||
center.horizontal.to_used_value(size.width),
|
||||
center.vertical.to_used_value(size.height),
|
||||
|
@ -593,7 +619,7 @@ pub fn convert_radial_gradient(
|
|||
|
||||
let stops = convert_gradient_stops(stops, radius.width);
|
||||
|
||||
display_list::RadialGradient {
|
||||
RadialGradient {
|
||||
center: center.to_layout(),
|
||||
radius: radius.to_layout(),
|
||||
stops: stops,
|
||||
|
|
|
@ -19,6 +19,16 @@ 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::{convert_linear_gradient, convert_radial_gradient};
|
||||
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 flex::FlexFlow;
|
||||
use flow::{BaseFlow, Flow, FlowFlags};
|
||||
|
@ -26,17 +36,6 @@ use flow_ref::FlowRef;
|
|||
use fnv::FnvHashMap;
|
||||
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo};
|
||||
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::glyph::ByteIndex;
|
||||
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
|
||||
|
@ -45,7 +44,6 @@ use ipc_channel::ipc;
|
|||
use list_item::ListItemFlow;
|
||||
use model::MaybeAuto;
|
||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||
use net_traits::image::base::PixelFormat;
|
||||
use net_traits::image_cache::UsePlaceholder;
|
||||
use range::Range;
|
||||
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::visibility::T as Visibility;
|
||||
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::values::{Either, RGBA};
|
||||
use style::values::computed::Gradient;
|
||||
|
@ -240,7 +238,7 @@ impl StackingContextCollectionState {
|
|||
let mut stacking_context_info = FnvHashMap::default();
|
||||
stacking_context_info.insert(
|
||||
StackingContextId::root(),
|
||||
StackingContextInfo::new(StackingContextId::root())
|
||||
StackingContextInfo::new(StackingContextId::root()),
|
||||
);
|
||||
|
||||
StackingContextCollectionState {
|
||||
|
@ -261,7 +259,7 @@ impl StackingContextCollectionState {
|
|||
|
||||
fn allocate_stacking_context_info(
|
||||
&mut self,
|
||||
stacking_context_type: StackingContextType
|
||||
stacking_context_type: StackingContextType,
|
||||
) -> StackingContextId {
|
||||
let next_stacking_context_id = self.next_stacking_context_id.next();
|
||||
let allocated_id =
|
||||
|
@ -274,7 +272,7 @@ impl StackingContextCollectionState {
|
|||
|
||||
self.stacking_context_info.insert(
|
||||
allocated_id,
|
||||
StackingContextInfo::new(real_stacking_context_id)
|
||||
StackingContextInfo::new(real_stacking_context_id),
|
||||
);
|
||||
|
||||
allocated_id
|
||||
|
@ -285,7 +283,11 @@ impl StackingContextCollectionState {
|
|||
parent_id: StackingContextId,
|
||||
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 {
|
||||
|
@ -462,7 +464,9 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
|
||||
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();
|
||||
|
||||
|
@ -543,6 +547,13 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
list.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
fn clipping_and_scrolling_scope<R, F: FnOnce(&mut Self) -> R>(&mut self, function: F) -> R {
|
||||
let previous_clipping_and_scrolling = self.current_clipping_and_scrolling;
|
||||
let ret = function(self);
|
||||
self.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// The logical width of an insertion point: at the moment, a one-pixel-wide line.
|
||||
|
@ -806,7 +817,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
// XXXManishearth the below method should ideally use an iterator over
|
||||
// backgrounds
|
||||
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(
|
||||
|
@ -848,25 +865,24 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
},
|
||||
}
|
||||
|
||||
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||
if !border_radii.is_zero() {
|
||||
let clip_id = state.add_late_clip_node(bounds.to_layout(), border_radii);
|
||||
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||
}
|
||||
state.clipping_and_scrolling_scope(|state| {
|
||||
if !border_radii.is_zero() {
|
||||
let clip_id = state.add_late_clip_node(bounds.to_layout(), border_radii);
|
||||
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||
}
|
||||
|
||||
let base = state.create_base_display_item(
|
||||
&bounds,
|
||||
&bounds,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem {
|
||||
base: base,
|
||||
color: background_color.to_layout(),
|
||||
})));
|
||||
|
||||
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||
let base = state.create_base_display_item(
|
||||
&bounds,
|
||||
&bounds,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem {
|
||||
base: base,
|
||||
color: background_color.to_layout(),
|
||||
})));
|
||||
});
|
||||
|
||||
// The background image is painted on top of the background color.
|
||||
// Implements background image, per spec:
|
||||
|
@ -955,6 +971,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
index: usize,
|
||||
) {
|
||||
debug!("(building display list) building background image");
|
||||
if webrender_image.key.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let image = Size2D::new(
|
||||
Au::from_px(webrender_image.width as i32),
|
||||
|
@ -967,26 +986,35 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
Some(image),
|
||||
style.logical_border_width().to_physical(style.writing_mode),
|
||||
self.border_padding.to_physical(style.writing_mode),
|
||||
build_border_radius(&absolute_bounds, style.get_border()),
|
||||
index,
|
||||
);
|
||||
|
||||
// Create the image display item.
|
||||
let base = state.create_base_display_item(
|
||||
&placement.bounds,
|
||||
&placement.css_clip,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.clipping_and_scrolling_scope(|state| {
|
||||
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);
|
||||
}
|
||||
|
||||
debug!("(building display list) adding background image.");
|
||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base: base,
|
||||
webrender_image: webrender_image,
|
||||
stretch_size: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
|
||||
})));
|
||||
// Create the image display item.
|
||||
let base = state.create_base_display_item(
|
||||
&placement.bounds,
|
||||
&placement.clip_rect,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
|
||||
debug!("(building display list) adding background image.");
|
||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base: base,
|
||||
id: webrender_image.key.unwrap(),
|
||||
stretch_size: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
fn get_webrender_image_for_paint_worklet(
|
||||
|
@ -1032,7 +1060,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
let webrender_image = WebRenderImageInfo {
|
||||
width: draw_result.width,
|
||||
height: draw_result.height,
|
||||
format: draw_result.format,
|
||||
key: draw_result.image_key,
|
||||
};
|
||||
|
||||
|
@ -1066,49 +1093,58 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
None,
|
||||
style.logical_border_width().to_physical(style.writing_mode),
|
||||
self.border_padding.to_physical(style.writing_mode),
|
||||
build_border_radius(&absolute_bounds, style.get_border()),
|
||||
index,
|
||||
);
|
||||
|
||||
let base = state.create_base_display_item(
|
||||
&placement.bounds,
|
||||
&placement.css_clip,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.clipping_and_scrolling_scope(|state| {
|
||||
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 display_item = match gradient.kind {
|
||||
GradientKind::Linear(angle_or_corner) => {
|
||||
let gradient = convert_linear_gradient(
|
||||
placement.tile_size,
|
||||
&gradient.items[..],
|
||||
angle_or_corner,
|
||||
gradient.repeating,
|
||||
);
|
||||
DisplayItem::Gradient(Box::new(GradientDisplayItem {
|
||||
base: base,
|
||||
gradient: gradient,
|
||||
tile: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
}))
|
||||
},
|
||||
GradientKind::Radial(shape, center, _angle) => {
|
||||
let gradient = convert_radial_gradient(
|
||||
placement.tile_size,
|
||||
&gradient.items[..],
|
||||
shape,
|
||||
center,
|
||||
gradient.repeating,
|
||||
);
|
||||
DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem {
|
||||
base: base,
|
||||
gradient: gradient,
|
||||
tile: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
}))
|
||||
},
|
||||
};
|
||||
state.add_display_item(display_item);
|
||||
let base = state.create_base_display_item(
|
||||
&placement.bounds,
|
||||
&placement.clip_rect,
|
||||
self.node,
|
||||
style.get_cursor(CursorKind::Default),
|
||||
display_list_section,
|
||||
);
|
||||
|
||||
let display_item = match gradient.kind {
|
||||
GradientKind::Linear(angle_or_corner) => {
|
||||
let gradient = convert_linear_gradient(
|
||||
placement.tile_size,
|
||||
&gradient.items[..],
|
||||
angle_or_corner,
|
||||
gradient.repeating,
|
||||
);
|
||||
DisplayItem::Gradient(Box::new(GradientDisplayItem {
|
||||
base: base,
|
||||
gradient: gradient,
|
||||
tile: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
}))
|
||||
},
|
||||
GradientKind::Radial(shape, center, _angle) => {
|
||||
let gradient = convert_radial_gradient(
|
||||
placement.tile_size,
|
||||
&gradient.items[..],
|
||||
shape,
|
||||
center,
|
||||
gradient.repeating,
|
||||
);
|
||||
DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem {
|
||||
base: base,
|
||||
gradient: gradient,
|
||||
tile: placement.tile_size.to_layout(),
|
||||
tile_spacing: placement.tile_spacing.to_layout(),
|
||||
}))
|
||||
},
|
||||
};
|
||||
state.add_display_item(display_item);
|
||||
});
|
||||
}
|
||||
|
||||
fn build_display_list_for_box_shadow_if_applicable(
|
||||
|
@ -1252,7 +1288,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
Either::Second(Image::Gradient(ref gradient)) => {
|
||||
Some(match gradient.kind {
|
||||
GradientKind::Linear(angle_or_corner) => {
|
||||
BorderDetails::Gradient(display_list::GradientBorder {
|
||||
BorderDetails::Gradient(GradientBorder {
|
||||
gradient: convert_linear_gradient(
|
||||
bounds.size,
|
||||
&gradient.items[..],
|
||||
|
@ -1264,7 +1300,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
})
|
||||
},
|
||||
GradientKind::Radial(shape, center, _angle) => {
|
||||
BorderDetails::RadialGradient(display_list::RadialGradientBorder {
|
||||
BorderDetails::RadialGradient(RadialGradientBorder {
|
||||
gradient: convert_radial_gradient(
|
||||
bounds.size,
|
||||
&gradient.items[..],
|
||||
|
@ -1519,8 +1555,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
clip: &Rect<Au>,
|
||||
) {
|
||||
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
||||
self.build_display_list_no_damage(state, stacking_relative_border_box,
|
||||
border_painting_mode, display_list_section, clip)
|
||||
self.build_display_list_no_damage(
|
||||
state,
|
||||
stacking_relative_border_box,
|
||||
border_painting_mode,
|
||||
display_list_section,
|
||||
clip,
|
||||
)
|
||||
}
|
||||
|
||||
fn build_display_list_no_damage(
|
||||
|
@ -1641,7 +1682,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
debug!("Fragment::build_display_list: intersected. Adding display item...");
|
||||
|
||||
// Create special per-fragment-type display items.
|
||||
self.build_fragment_type_specific_display_items(state, &stacking_relative_border_box, clip);
|
||||
state.clipping_and_scrolling_scope(|state| {
|
||||
self.build_fragment_type_specific_display_items(
|
||||
state,
|
||||
&stacking_relative_border_box,
|
||||
clip,
|
||||
);
|
||||
});
|
||||
|
||||
if opts::get().show_debug_fragment_borders {
|
||||
self.build_debug_borders_around_fragment(state, &stacking_relative_border_box, clip)
|
||||
|
@ -1654,24 +1701,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
stacking_relative_border_box: &Rect<Au>,
|
||||
clip: &Rect<Au>,
|
||||
) {
|
||||
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||
|
||||
// Compute the context box position relative to the parent stacking context.
|
||||
let stacking_relative_content_box =
|
||||
self.stacking_relative_content_box(stacking_relative_border_box);
|
||||
|
||||
let create_base_display_item = |state: &mut DisplayListBuildState| {
|
||||
// Adjust the clipping region as necessary to account for `border-radius`.
|
||||
let radii = build_border_radius_for_inner_rect(
|
||||
&stacking_relative_border_box,
|
||||
&self.style
|
||||
);
|
||||
let radii =
|
||||
build_border_radius_for_inner_rect(&stacking_relative_border_box, &self.style);
|
||||
|
||||
if !radii.is_zero() {
|
||||
let clip_id = state.add_late_clip_node(
|
||||
stacking_relative_border_box.to_layout(),
|
||||
radii
|
||||
);
|
||||
let clip_id =
|
||||
state.add_late_clip_node(stacking_relative_border_box.to_layout(), radii);
|
||||
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
|
||||
}
|
||||
|
||||
|
@ -1779,22 +1820,24 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
SpecificFragmentInfo::Image(ref image_fragment) => {
|
||||
// Place the image into the display list.
|
||||
if let Some(ref image) = image_fragment.image {
|
||||
let base = create_base_display_item(state);
|
||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base,
|
||||
webrender_image: WebRenderImageInfo::from_image(image),
|
||||
stretch_size: stacking_relative_content_box.size.to_layout(),
|
||||
tile_spacing: LayoutSize::zero(),
|
||||
image_rendering: self.style.get_inheritedbox().image_rendering.to_layout(),
|
||||
})));
|
||||
if let Some(id) = image.id {
|
||||
let base = create_base_display_item(state);
|
||||
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base,
|
||||
id,
|
||||
stretch_size: stacking_relative_content_box.size.to_layout(),
|
||||
tile_spacing: LayoutSize::zero(),
|
||||
image_rendering: self.style
|
||||
.get_inheritedbox()
|
||||
.image_rendering
|
||||
.to_layout(),
|
||||
})));
|
||||
}
|
||||
}
|
||||
},
|
||||
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
||||
let computed_width = canvas_fragment_info.dom_width.to_px();
|
||||
let computed_height = canvas_fragment_info.dom_height.to_px();
|
||||
|
||||
let (image_key, format) = match canvas_fragment_info.source {
|
||||
CanvasFragmentSource::WebGL(image_key) => (image_key, PixelFormat::BGRA8),
|
||||
let image_key = match canvas_fragment_info.source {
|
||||
CanvasFragmentSource::WebGL(image_key) => image_key,
|
||||
CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer {
|
||||
Some(ref ipc_renderer) => {
|
||||
let ipc_renderer = ipc_renderer.lock().unwrap();
|
||||
|
@ -1803,7 +1846,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
.send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender),
|
||||
canvas_fragment_info.canvas_id.clone()))
|
||||
.unwrap();
|
||||
(receiver.recv().unwrap().image_key, PixelFormat::BGRA8)
|
||||
receiver.recv().unwrap().image_key
|
||||
},
|
||||
None => return,
|
||||
},
|
||||
|
@ -1812,12 +1855,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
let base = create_base_display_item(state);
|
||||
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base,
|
||||
webrender_image: WebRenderImageInfo {
|
||||
width: computed_width as u32,
|
||||
height: computed_height as u32,
|
||||
format: format,
|
||||
key: Some(image_key),
|
||||
},
|
||||
id: image_key,
|
||||
stretch_size: stacking_relative_content_box.size.to_layout(),
|
||||
tile_spacing: LayoutSize::zero(),
|
||||
image_rendering: ImageRendering::Auto,
|
||||
|
@ -1832,8 +1870,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
panic!("Shouldn't see table column fragments here.")
|
||||
},
|
||||
}
|
||||
|
||||
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||
}
|
||||
|
||||
fn create_stacking_context(
|
||||
|
@ -1943,12 +1979,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
state.add_display_item(DisplayItem::PushTextShadow(Box::new(
|
||||
PushTextShadowDisplayItem {
|
||||
base: base.clone(),
|
||||
blur_radius: shadow.blur.px(),
|
||||
offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
|
||||
color: shadow
|
||||
.color
|
||||
.unwrap_or(self.style().get_color().color)
|
||||
.to_layout(),
|
||||
shadow: webrender_api::Shadow {
|
||||
offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
|
||||
color: shadow
|
||||
.color
|
||||
.unwrap_or(self.style().get_color().color)
|
||||
.to_layout(),
|
||||
blur_radius: shadow.blur.px(),
|
||||
},
|
||||
},
|
||||
)));
|
||||
}
|
||||
|
@ -2147,7 +2185,8 @@ pub trait BlockFlowDisplayListBuilding {
|
|||
&self,
|
||||
state: &mut DisplayListBuildState,
|
||||
background: &style_structs::Background,
|
||||
background_color: RGBA);
|
||||
background_color: RGBA,
|
||||
);
|
||||
|
||||
fn stacking_context_type(
|
||||
&self,
|
||||
|
@ -2680,8 +2719,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
let background_border_section = self.background_border_section();
|
||||
|
||||
state.processing_scrolling_overflow_element = self.has_scrolling_overflow();
|
||||
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);
|
||||
// Add the box that starts the block context.
|
||||
self.fragment.build_display_list_no_damage(
|
||||
state,
|
||||
|
@ -2702,7 +2741,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
state: &mut DisplayListBuildState,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -2710,23 +2751,28 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
&self,
|
||||
state: &mut DisplayListBuildState,
|
||||
background: &style_structs::Background,
|
||||
background_color: RGBA) {
|
||||
let stacking_relative_border_box =
|
||||
self.base.stacking_relative_border_box_for_display_list(&self.fragment);
|
||||
background_color: RGBA,
|
||||
) {
|
||||
let stacking_relative_border_box = self.base
|
||||
.stacking_relative_border_box_for_display_list(&self.fragment);
|
||||
let background_border_section = self.background_border_section();
|
||||
|
||||
self.fragment.build_display_list_for_background_if_applicable_with_background(
|
||||
state, self.fragment.style(), background, background_color,
|
||||
background_border_section, &stacking_relative_border_box
|
||||
)
|
||||
|
||||
self.fragment
|
||||
.build_display_list_for_background_if_applicable_with_background(
|
||||
state,
|
||||
self.fragment.style(),
|
||||
background,
|
||||
background_color,
|
||||
background_border_section,
|
||||
&stacking_relative_border_box,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn stacking_context_type(
|
||||
&self,
|
||||
flags: StackingContextCollectionFlags,
|
||||
) -> Option<StackingContextType>{
|
||||
) -> Option<StackingContextType> {
|
||||
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
|
||||
return None;
|
||||
}
|
||||
|
@ -2735,7 +2781,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -2811,8 +2860,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
index: usize,
|
||||
) {
|
||||
let fragment = self.fragments.fragments.get_mut(index).unwrap();
|
||||
let stacking_relative_border_box =
|
||||
self.base.stacking_relative_border_box_for_display_list(fragment);
|
||||
let stacking_relative_border_box = self.base
|
||||
.stacking_relative_border_box_for_display_list(fragment);
|
||||
fragment.build_display_list(
|
||||
state,
|
||||
stacking_relative_border_box,
|
||||
|
@ -2867,8 +2916,9 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
|
|||
fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) {
|
||||
// Draw the marker, if applicable.
|
||||
for marker in &mut self.marker_fragments {
|
||||
let stacking_relative_border_box =
|
||||
self.block_flow.base.stacking_relative_border_box_for_display_list(marker);
|
||||
let stacking_relative_border_box = self.block_flow
|
||||
.base
|
||||
.stacking_relative_border_box_for_display_list(marker);
|
||||
marker.build_display_list(
|
||||
state,
|
||||
stacking_relative_border_box,
|
||||
|
@ -3058,6 +3108,10 @@ impl IndexableText {
|
|||
// TODO(#20020): access all elements
|
||||
let point = point_in_item + item[0].origin.to_vector();
|
||||
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
|
||||
//! 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.
|
||||
//! 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
|
||||
//! 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
|
||||
//! low-level drawing primitives.
|
||||
|
||||
use euclid::{Vector2D, TypedRect, SideOffsets2D};
|
||||
use euclid::num::{One, Zero};
|
||||
use euclid::{SideOffsets2D, TypedRect, Vector2D};
|
||||
use gfx_traits::{self, StackingContextId};
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::image::base::{Image, PixelFormat};
|
||||
use net_traits::image::base::Image;
|
||||
use servo_geometry::MaxRect;
|
||||
use std::cmp::Ordering;
|
||||
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::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
|
||||
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};
|
||||
|
||||
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
|
||||
/// are given ClipIds.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize)]
|
||||
pub struct ClipScrollNodeIndex(pub usize);
|
||||
|
||||
impl ClipScrollNodeIndex {
|
||||
|
@ -60,7 +57,7 @@ impl ClipScrollNodeIndex {
|
|||
}
|
||||
|
||||
/// 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 scrolling: ClipScrollNodeIndex,
|
||||
pub clipping: Option<ClipScrollNodeIndex>,
|
||||
|
@ -74,7 +71,7 @@ impl ClippingAndScrolling {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(scrolling: ClipScrollNodeIndex, clipping: ClipScrollNodeIndex) -> ClippingAndScrolling {
|
||||
pub fn new(scrolling: ClipScrollNodeIndex, clipping: ClipScrollNodeIndex) -> Self {
|
||||
ClippingAndScrolling {
|
||||
scrolling,
|
||||
clipping: Some(clipping),
|
||||
|
@ -82,7 +79,7 @@ impl ClippingAndScrolling {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Serialize)]
|
||||
pub struct DisplayList {
|
||||
pub list: Vec<DisplayItem>,
|
||||
pub clip_scroll_nodes: Vec<ClipScrollNode>,
|
||||
|
@ -113,11 +110,12 @@ impl DisplayList {
|
|||
|
||||
print_tree.new_level("Items".to_owned());
|
||||
for item in &self.list {
|
||||
print_tree.add_item(format!("{:?} StackingContext: {:?} {:?}",
|
||||
print_tree.add_item(format!(
|
||||
"{:?} StackingContext: {:?} {:?}",
|
||||
item,
|
||||
item.base().stacking_context_id,
|
||||
item.clipping_and_scrolling())
|
||||
);
|
||||
item.clipping_and_scrolling()
|
||||
));
|
||||
}
|
||||
print_tree.end_level();
|
||||
}
|
||||
|
@ -130,10 +128,7 @@ impl gfx_traits::DisplayList for DisplayList {
|
|||
fn is_contentful(&self) -> bool {
|
||||
for item in &self.list {
|
||||
match item {
|
||||
&DisplayItem::Text(_) |
|
||||
&DisplayItem::Image(_) => {
|
||||
return true
|
||||
}
|
||||
&DisplayItem::Text(_) | &DisplayItem::Image(_) => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +140,7 @@ impl gfx_traits::DisplayList for DisplayList {
|
|||
/// Display list sections that make up a stacking context. Each section here refers
|
||||
/// 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 {
|
||||
BackgroundAndBorders,
|
||||
BlockBackgroundsAndBorders,
|
||||
|
@ -153,14 +148,14 @@ pub enum DisplayListSection {
|
|||
Outlines,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub enum StackingContextType {
|
||||
Real,
|
||||
PseudoPositioned,
|
||||
PseudoFloat,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
/// Represents one CSS stacking context, which may or may not have a hardware layer.
|
||||
pub struct StackingContext {
|
||||
/// The ID of this StackingContext for uniquely identifying it.
|
||||
|
@ -203,19 +198,20 @@ pub struct StackingContext {
|
|||
impl StackingContext {
|
||||
/// Creates a new stacking context.
|
||||
#[inline]
|
||||
pub fn new(id: StackingContextId,
|
||||
context_type: StackingContextType,
|
||||
bounds: LayoutRect,
|
||||
overflow: LayoutRect,
|
||||
z_index: i32,
|
||||
filters: Vec<FilterOp>,
|
||||
mix_blend_mode: MixBlendMode,
|
||||
transform: Option<LayoutTransform>,
|
||||
transform_style: TransformStyle,
|
||||
perspective: Option<LayoutTransform>,
|
||||
scroll_policy: ScrollPolicy,
|
||||
parent_clipping_and_scrolling: ClippingAndScrolling)
|
||||
-> StackingContext {
|
||||
pub fn new(
|
||||
id: StackingContextId,
|
||||
context_type: StackingContextType,
|
||||
bounds: LayoutRect,
|
||||
overflow: LayoutRect,
|
||||
z_index: i32,
|
||||
filters: Vec<FilterOp>,
|
||||
mix_blend_mode: MixBlendMode,
|
||||
transform: Option<LayoutTransform>,
|
||||
transform_style: TransformStyle,
|
||||
perspective: Option<LayoutTransform>,
|
||||
scroll_policy: ScrollPolicy,
|
||||
parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||
) -> StackingContext {
|
||||
StackingContext {
|
||||
id,
|
||||
context_type,
|
||||
|
@ -246,7 +242,7 @@ impl StackingContext {
|
|||
TransformStyle::Flat,
|
||||
None,
|
||||
ScrollPolicy::Scrollable,
|
||||
ClippingAndScrolling::simple(ClipScrollNodeIndex(0))
|
||||
ClippingAndScrolling::simple(ClipScrollNodeIndex(0)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -255,19 +251,15 @@ impl StackingContext {
|
|||
base_item.stacking_context_id = self.id;
|
||||
base_item.clipping_and_scrolling = self.parent_clipping_and_scrolling;
|
||||
|
||||
let pop_item = DisplayItem::PopStackingContext(Box::new(
|
||||
PopStackingContextItem {
|
||||
base: base_item.clone(),
|
||||
stacking_context_id: self.id,
|
||||
}
|
||||
));
|
||||
let pop_item = DisplayItem::PopStackingContext(Box::new(PopStackingContextItem {
|
||||
base: base_item.clone(),
|
||||
stacking_context_id: self.id,
|
||||
}));
|
||||
|
||||
let push_item = DisplayItem::PushStackingContext(Box::new(
|
||||
PushStackingContextItem {
|
||||
base: base_item,
|
||||
stacking_context: self,
|
||||
}
|
||||
));
|
||||
let push_item = DisplayItem::PushStackingContext(Box::new(PushStackingContextItem {
|
||||
base: base_item,
|
||||
stacking_context: self,
|
||||
}));
|
||||
|
||||
(push_item, pop_item)
|
||||
}
|
||||
|
@ -303,28 +295,28 @@ impl PartialEq for StackingContext {
|
|||
|
||||
impl fmt::Debug for StackingContext {
|
||||
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"
|
||||
} else {
|
||||
"Pseudo-StackingContext"
|
||||
};
|
||||
|
||||
write!(f, "{} at {:?} with overflow {:?}: {:?}",
|
||||
type_string,
|
||||
self.bounds,
|
||||
self.overflow,
|
||||
self.id)
|
||||
write!(
|
||||
f,
|
||||
"{} at {:?} with overflow {:?}: {:?}",
|
||||
type_string, self.bounds, self.overflow, self.id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct StickyFrameData {
|
||||
pub margins: SideOffsets2D<Option<f32>>,
|
||||
pub vertical_offset_bounds: StickyOffsetBounds,
|
||||
pub horizontal_offset_bounds: StickyOffsetBounds,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub enum ClipScrollNodeType {
|
||||
ScrollFrame(ScrollSensitivity, ExternalScrollId),
|
||||
StickyFrame(StickyFrameData),
|
||||
|
@ -332,7 +324,7 @@ pub enum ClipScrollNodeType {
|
|||
}
|
||||
|
||||
/// Defines a clip scroll node.
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct ClipScrollNode {
|
||||
/// The index of the parent of this ClipScrollNode.
|
||||
pub parent_index: ClipScrollNodeIndex,
|
||||
|
@ -348,7 +340,7 @@ pub struct ClipScrollNode {
|
|||
}
|
||||
|
||||
/// One drawing command in the list.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub enum DisplayItem {
|
||||
SolidColor(Box<SolidColorDisplayItem>),
|
||||
Text(Box<TextDisplayItem>),
|
||||
|
@ -367,7 +359,7 @@ pub enum DisplayItem {
|
|||
}
|
||||
|
||||
/// Information common to all display items.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct BaseDisplayItem {
|
||||
/// The boundaries of the display item, in layer coordinates.
|
||||
pub bounds: LayoutRect,
|
||||
|
@ -390,13 +382,14 @@ pub struct BaseDisplayItem {
|
|||
|
||||
impl BaseDisplayItem {
|
||||
#[inline(always)]
|
||||
pub fn new(bounds: LayoutRect,
|
||||
metadata: DisplayItemMetadata,
|
||||
clip_rect: LayoutRect,
|
||||
section: DisplayListSection,
|
||||
stacking_context_id: StackingContextId,
|
||||
clipping_and_scrolling: ClippingAndScrolling)
|
||||
-> BaseDisplayItem {
|
||||
pub fn new(
|
||||
bounds: LayoutRect,
|
||||
metadata: DisplayItemMetadata,
|
||||
clip_rect: LayoutRect,
|
||||
section: DisplayListSection,
|
||||
stacking_context_id: StackingContextId,
|
||||
clipping_and_scrolling: ClippingAndScrolling,
|
||||
) -> BaseDisplayItem {
|
||||
BaseDisplayItem {
|
||||
bounds,
|
||||
metadata,
|
||||
|
@ -427,7 +420,7 @@ impl BaseDisplayItem {
|
|||
/// 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
|
||||
/// 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 {
|
||||
/// The main rectangular region. This does not include any corners.
|
||||
pub main: LayoutRect,
|
||||
|
@ -487,7 +480,9 @@ impl ClippingRegion {
|
|||
#[inline]
|
||||
pub fn might_intersect_point(&self, point: &LayoutPoint) -> bool {
|
||||
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
|
||||
|
@ -495,7 +490,9 @@ impl ClippingRegion {
|
|||
#[inline]
|
||||
pub fn might_intersect_rect(&self, rect: &LayoutRect) -> bool {
|
||||
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.
|
||||
|
@ -535,10 +532,10 @@ impl ClippingRegion {
|
|||
for existing_complex_region in &mut self.complex {
|
||||
if existing_complex_region.completely_encloses(&new_complex_region) {
|
||||
*existing_complex_region = new_complex_region;
|
||||
return
|
||||
return;
|
||||
}
|
||||
if new_complex_region.completely_encloses(existing_complex_region) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,13 +547,14 @@ impl ClippingRegion {
|
|||
pub fn translate(&self, delta: &LayoutVector2D) -> ClippingRegion {
|
||||
ClippingRegion {
|
||||
main: self.main.translate(delta),
|
||||
complex: self.complex.iter().map(|complex| {
|
||||
ComplexClipRegion {
|
||||
complex: self.complex
|
||||
.iter()
|
||||
.map(|complex| ComplexClipRegion {
|
||||
rect: complex.rect.translate(delta),
|
||||
radii: complex.radii,
|
||||
mode: complex.mode,
|
||||
}
|
||||
}).collect(),
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +573,11 @@ impl fmt::Debug for ClippingRegion {
|
|||
} else if self.main == LayoutRect::max_rect() {
|
||||
write!(f, "ClippingRegion(Complex={:?})", self.complex)
|
||||
} else {
|
||||
write!(f, "ClippingRegion(Rect={:?}, Complex={:?})", self.main, self.complex)
|
||||
write!(
|
||||
f,
|
||||
"ClippingRegion(Rect={:?}, Complex={:?})",
|
||||
self.main, self.complex
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,11 +592,21 @@ impl CompletelyEncloses for ComplexClipRegion {
|
|||
fn completely_encloses(&self, other: &Self) -> bool {
|
||||
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 right = self.radii.top_right.width.max(self.radii.bottom_right.width);
|
||||
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));
|
||||
let right = self.radii
|
||||
.top_right
|
||||
.width
|
||||
.max(self.radii.bottom_right.width);
|
||||
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.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y()
|
||||
}
|
||||
|
@ -603,7 +615,7 @@ impl CompletelyEncloses for ComplexClipRegion {
|
|||
/// 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
|
||||
/// cursor to use when the element is hovered over.
|
||||
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
pub struct DisplayItemMetadata {
|
||||
/// The DOM node from which this display item originated.
|
||||
pub node: OpaqueNode,
|
||||
|
@ -613,7 +625,7 @@ pub struct DisplayItemMetadata {
|
|||
}
|
||||
|
||||
/// Paints a solid color.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct SolidColorDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -623,7 +635,7 @@ pub struct SolidColorDisplayItem {
|
|||
}
|
||||
|
||||
/// Paints text.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct TextDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -635,7 +647,7 @@ pub struct TextDisplayItem {
|
|||
pub text_color: ColorF,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
|
||||
#[derive(Clone, Eq, PartialEq, Serialize)]
|
||||
pub enum TextOrientation {
|
||||
Upright,
|
||||
SidewaysLeft,
|
||||
|
@ -643,11 +655,11 @@ pub enum TextOrientation {
|
|||
}
|
||||
|
||||
/// Paints an image.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ImageDisplayItem {
|
||||
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 bounds of this display item, then the image will be repeated in the appropriate
|
||||
|
@ -663,14 +675,14 @@ pub struct ImageDisplayItem {
|
|||
pub image_rendering: ImageRendering,
|
||||
}
|
||||
/// Paints an iframe.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct IframeDisplayItem {
|
||||
pub base: BaseDisplayItem,
|
||||
pub iframe: PipelineId,
|
||||
}
|
||||
|
||||
/// Paints a gradient.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct Gradient {
|
||||
/// The start point of the gradient (computed during display list construction).
|
||||
pub start_point: LayoutPoint,
|
||||
|
@ -685,7 +697,7 @@ pub struct Gradient {
|
|||
pub extend_mode: ExtendMode,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct GradientDisplayItem {
|
||||
/// Fields common to all display item.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -705,7 +717,7 @@ pub struct GradientDisplayItem {
|
|||
}
|
||||
|
||||
/// Paints a radial gradient.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct RadialGradient {
|
||||
/// The center point of the gradient.
|
||||
pub center: LayoutPoint,
|
||||
|
@ -720,7 +732,7 @@ pub struct RadialGradient {
|
|||
pub extend_mode: ExtendMode,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct RadialGradientDisplayItem {
|
||||
/// Fields common to all display item.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -740,7 +752,7 @@ pub struct RadialGradientDisplayItem {
|
|||
}
|
||||
|
||||
/// A border that is made of linear gradient
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct GradientBorder {
|
||||
/// The gradient info that this border uses, border-image-source.
|
||||
pub gradient: Gradient,
|
||||
|
@ -750,7 +762,7 @@ pub struct GradientBorder {
|
|||
}
|
||||
|
||||
/// A border that is made of radial gradient
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct RadialGradientBorder {
|
||||
/// The gradient info that this border uses, border-image-source.
|
||||
pub gradient: RadialGradient,
|
||||
|
@ -760,7 +772,7 @@ pub struct RadialGradientBorder {
|
|||
}
|
||||
|
||||
/// Specifies the type of border
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub enum BorderDetails {
|
||||
Normal(NormalBorder),
|
||||
Image(ImageBorder),
|
||||
|
@ -769,7 +781,7 @@ pub enum BorderDetails {
|
|||
}
|
||||
|
||||
/// Paints a border.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct BorderDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -782,7 +794,7 @@ pub struct BorderDisplayItem {
|
|||
}
|
||||
|
||||
/// Paints a line segment.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct LineDisplayItem {
|
||||
pub base: BaseDisplayItem,
|
||||
|
||||
|
@ -794,7 +806,7 @@ pub struct LineDisplayItem {
|
|||
}
|
||||
|
||||
/// Paints a box shadow per CSS-BACKGROUNDS.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct BoxShadowDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -822,30 +834,23 @@ pub struct BoxShadowDisplayItem {
|
|||
}
|
||||
|
||||
/// Defines a text shadow that affects all items until the paired PopTextShadow.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PushTextShadowDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
||||
/// The offset of this shadow from the text.
|
||||
pub offset: LayoutVector2D,
|
||||
|
||||
/// The color of this shadow.
|
||||
pub color: ColorF,
|
||||
|
||||
/// The blur radius for this shadow.
|
||||
pub blur_radius: f32,
|
||||
pub shadow: Shadow,
|
||||
}
|
||||
|
||||
/// Defines a text shadow that affects all items until the next PopTextShadow.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PopAllTextShadowsDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
}
|
||||
|
||||
/// Defines a stacking context.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PushStackingContextItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -854,7 +859,7 @@ pub struct PushStackingContextItem {
|
|||
}
|
||||
|
||||
/// Defines a stacking context.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PopStackingContextItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -863,7 +868,7 @@ pub struct PopStackingContextItem {
|
|||
}
|
||||
|
||||
/// Starts a group of items inside a particular scroll root.
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct DefineClipScrollNodeItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
|
@ -935,14 +940,17 @@ impl fmt::Debug for DisplayItem {
|
|||
return write!(f, "DefineClipScrollNode({:?}", item.node_index);
|
||||
}
|
||||
|
||||
write!(f, "{} @ {:?} {:?}",
|
||||
write!(
|
||||
f,
|
||||
"{} @ {:?} {:?}",
|
||||
match *self {
|
||||
DisplayItem::SolidColor(ref solid_color) =>
|
||||
format!("SolidColor rgba({}, {}, {}, {})",
|
||||
solid_color.color.r,
|
||||
solid_color.color.g,
|
||||
solid_color.color.b,
|
||||
solid_color.color.a),
|
||||
DisplayItem::SolidColor(ref solid_color) => format!(
|
||||
"SolidColor rgba({}, {}, {}, {})",
|
||||
solid_color.color.r,
|
||||
solid_color.color.g,
|
||||
solid_color.color.b,
|
||||
solid_color.color.a
|
||||
),
|
||||
DisplayItem::Text(_) => "Text".to_owned(),
|
||||
DisplayItem::Image(_) => "Image".to_owned(),
|
||||
DisplayItem::Border(_) => "Border".to_owned(),
|
||||
|
@ -963,11 +971,10 @@ impl fmt::Debug for DisplayItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
pub struct WebRenderImageInfo {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub format: PixelFormat,
|
||||
pub key: Option<ImageKey>,
|
||||
}
|
||||
|
||||
|
@ -977,7 +984,6 @@ impl WebRenderImageInfo {
|
|||
WebRenderImageInfo {
|
||||
width: image.width,
|
||||
height: image.height,
|
||||
format: image.format,
|
||||
key: image.id,
|
||||
}
|
||||
}
|
||||
|
@ -986,7 +992,6 @@ impl WebRenderImageInfo {
|
|||
/// The type of the scroll offset list. This is only populated if WebRender is in use.
|
||||
pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32>>;
|
||||
|
||||
|
||||
pub trait SimpleMatrixDetection {
|
||||
fn is_identity_or_simple_translation(&self) -> bool;
|
||||
}
|
||||
|
@ -994,11 +999,9 @@ pub trait SimpleMatrixDetection {
|
|||
impl SimpleMatrixDetection for LayoutTransform {
|
||||
#[inline]
|
||||
fn is_identity_or_simple_translation(&self) -> bool {
|
||||
let (_0, _1) = (Zero::zero(), One::one());
|
||||
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 &&
|
||||
self.m21 == _0 && self.m22 == _1 && self.m23 == _0 && self.m24 == _0 &&
|
||||
self.m31 == _0 && self.m32 == _0 && self.m33 == _1 && self.m34 == _0 &&
|
||||
self.m44 == _1
|
||||
let (_0, _1) = (0.0, 1.0);
|
||||
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 && self.m21 == _0 &&
|
||||
self.m22 == _1 && self.m23 == _0 && self.m24 == _0 && self.m31 == _0 &&
|
||||
self.m32 == _0 && self.m33 == _1 && self.m34 == _0 && self.m44 == _1
|
||||
}
|
||||
}
|
||||
|
|
@ -17,4 +17,5 @@ pub use self::webrender_helpers::WebRenderDisplayListConverter;
|
|||
mod background;
|
||||
mod builder;
|
||||
mod conversions;
|
||||
pub mod items;
|
||||
mod webrender_helpers;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
// 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.
|
||||
|
||||
use gfx::display_list::{BorderDetails, ClipScrollNode};
|
||||
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
||||
use gfx::display_list::{DisplayList, StackingContextType};
|
||||
use display_list::items::{BorderDetails, ClipScrollNode};
|
||||
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
||||
use display_list::items::{DisplayList, StackingContextType};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder, GlyphRasterSpace};
|
||||
|
||||
|
@ -111,17 +111,15 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||
);
|
||||
},
|
||||
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 {
|
||||
builder.push_image(
|
||||
&self.prim_info(),
|
||||
item.stretch_size,
|
||||
item.tile_spacing,
|
||||
item.image_rendering,
|
||||
webrender_api::AlphaType::PremultipliedAlpha,
|
||||
id,
|
||||
);
|
||||
}
|
||||
if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
|
||||
builder.push_image(
|
||||
&self.prim_info(),
|
||||
item.stretch_size,
|
||||
item.tile_spacing,
|
||||
item.image_rendering,
|
||||
webrender_api::AlphaType::PremultipliedAlpha,
|
||||
item.id,
|
||||
);
|
||||
}
|
||||
},
|
||||
DisplayItem::Border(ref item) => {
|
||||
|
@ -204,14 +202,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||
);
|
||||
},
|
||||
DisplayItem::PushTextShadow(ref item) => {
|
||||
builder.push_shadow(
|
||||
&self.prim_info(),
|
||||
webrender_api::Shadow {
|
||||
blur_radius: item.blur_radius,
|
||||
offset: item.offset,
|
||||
color: item.color,
|
||||
},
|
||||
);
|
||||
builder.push_shadow(&self.prim_info(), item.shadow);
|
||||
},
|
||||
DisplayItem::PopAllTextShadows(_) => {
|
||||
builder.pop_all_shadows();
|
||||
|
|
|
@ -29,13 +29,13 @@ use app_units::Au;
|
|||
use block::{BlockFlow, FormattingContextType};
|
||||
use context::LayoutContext;
|
||||
use display_list::{DisplayListBuildState, StackingContextCollectionState};
|
||||
use display_list::items::ClippingAndScrolling;
|
||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||
use flex::FlexFlow;
|
||||
use floats::{Floats, SpeculatedFloatPlacement};
|
||||
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
||||
use flow_ref::{FlowRef, WeakFlowRef};
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||
use gfx::display_list::ClippingAndScrolling;
|
||||
use gfx_traits::StackingContextId;
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
use inline::InlineFlow;
|
||||
|
|
|
@ -11,12 +11,12 @@ use app_units::Au;
|
|||
use canvas_traits::canvas::{CanvasMsg, CanvasId};
|
||||
use context::{LayoutContext, with_thread_local_font_context};
|
||||
use display_list::ToLayout;
|
||||
use display_list::items::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||
use floats::ClearType;
|
||||
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
||||
use flow_ref::FlowRef;
|
||||
use gfx;
|
||||
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||
use gfx::text::glyph::ByteIndex;
|
||||
use gfx::text::text_run::{TextRun, TextRunSlice};
|
||||
use gfx_traits::StackingContextId;
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
//! as possible.
|
||||
|
||||
use context::{LayoutContext, with_thread_local_font_context};
|
||||
use display_list::items::OpaqueNode;
|
||||
use flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils};
|
||||
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use script_layout_interface::wrapper_traits::PseudoElementType;
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::{HashMap, LinkedList};
|
||||
|
|
|
@ -10,6 +10,7 @@ use block::AbsoluteAssignBSizesTraversal;
|
|||
use context::{LayoutContext, LayoutFontContext};
|
||||
use display_list::{DisplayListBuildState, InlineFlowDisplayListBuilding};
|
||||
use display_list::StackingContextCollectionState;
|
||||
use display_list::items::OpaqueNode;
|
||||
use euclid::{Point2D, Size2D};
|
||||
use floats::{FloatKind, Floats, PlacementInfo};
|
||||
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
|
||||
|
@ -18,7 +19,6 @@ use flow_ref::FlowRef;
|
|||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||
use fragment::FragmentFlags;
|
||||
use fragment::SpecificFragmentInfo;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use gfx::font::FontMetrics;
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
use layout_debug;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use display_list::items::OpaqueNode;
|
||||
use libc::c_void;
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ use app_units::Au;
|
|||
use construct::ConstructionResult;
|
||||
use context::LayoutContext;
|
||||
use display_list::IndexableText;
|
||||
use display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||
use flow::{Flow, GetBaseFlow};
|
||||
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||
use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
||||
use inline::InlineFragmentNodeFlags;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
|
|
|
@ -59,7 +59,6 @@ use dom_wrapper::drop_style_and_layout_data;
|
|||
use embedder_traits::resources::{self, Resource};
|
||||
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
|
||||
use fnv::FnvHashMap;
|
||||
use gfx::display_list::{OpaqueNode, WebRenderImageInfo};
|
||||
use gfx::font;
|
||||
use gfx::font_cache_thread::FontCacheThread;
|
||||
use gfx::font_context;
|
||||
|
@ -73,8 +72,8 @@ use layout::context::LayoutContext;
|
|||
use layout::context::RegisteredPainter;
|
||||
use layout::context::RegisteredPainters;
|
||||
use layout::context::malloc_size_of_persistent_local_context;
|
||||
use layout::display_list::{IndexableText, ToLayout};
|
||||
use layout::display_list::WebRenderDisplayListConverter;
|
||||
use layout::display_list::{IndexableText, ToLayout, WebRenderDisplayListConverter};
|
||||
use layout::display_list::items::{OpaqueNode, WebRenderImageInfo};
|
||||
use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||
use layout::flow_ref::FlowRef;
|
||||
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage};
|
||||
|
|
|
@ -10,12 +10,11 @@ path = "lib.rs"
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
gfx = {path = "../../../components/gfx"}
|
||||
gfx_traits = {path = "../../../components/gfx_traits"}
|
||||
ipc-channel = "0.10"
|
||||
layout = {path = "../../../components/layout"}
|
||||
metrics = {path = "../../../components/metrics"}
|
||||
msg = {path = "../../../components/msg"}
|
||||
net_traits = {path = "../../../components/net_traits"}
|
||||
profile_traits = {path = "../../../components/profile_traits"}
|
||||
servo_url = {path = "../../../components/url"}
|
||||
time = "0.1.12"
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
#![cfg(test)]
|
||||
|
||||
extern crate gfx;
|
||||
extern crate gfx_traits;
|
||||
extern crate ipc_channel;
|
||||
extern crate layout;
|
||||
extern crate metrics;
|
||||
extern crate msg;
|
||||
extern crate net_traits;
|
||||
extern crate profile_traits;
|
||||
extern crate servo_url;
|
||||
extern crate time;
|
||||
|
|
|
@ -2,17 +2,15 @@
|
|||
* 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/. */
|
||||
|
||||
use gfx::display_list::{BaseDisplayItem, WebRenderImageInfo};
|
||||
use gfx::display_list::{DisplayItem, DisplayList, ImageDisplayItem};
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc;
|
||||
use layout::display_list::items::{BaseDisplayItem, DisplayItem, DisplayList, ImageDisplayItem};
|
||||
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
|
||||
use msg::constellation_msg::TEST_PIPELINE_ID;
|
||||
use net_traits::image::base::PixelFormat;
|
||||
use profile_traits::time::{ProfilerChan, TimerMetadata};
|
||||
use servo_url::ServoUrl;
|
||||
use time;
|
||||
use webrender_api::{ImageRendering, LayoutSize};
|
||||
use webrender_api::{ImageKey, ImageRendering, LayoutSize};
|
||||
|
||||
struct DummyProfilerMetadataFactory {}
|
||||
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
|
||||
|
@ -120,12 +118,7 @@ fn test_first_paint_setter() {
|
|||
fn test_first_contentful_paint_setter() {
|
||||
let image = DisplayItem::Image(Box::new(ImageDisplayItem {
|
||||
base: BaseDisplayItem::empty(),
|
||||
webrender_image: WebRenderImageInfo {
|
||||
width: 1,
|
||||
height: 1,
|
||||
format: PixelFormat::RGB8,
|
||||
key: None,
|
||||
},
|
||||
id: ImageKey::DUMMY,
|
||||
stretch_size: LayoutSize::zero(),
|
||||
tile_spacing: LayoutSize::zero(),
|
||||
image_rendering: ImageRendering::Auto,
|
||||
|
|
|
@ -100555,6 +100555,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",
|
||||
|
@ -238595,6 +238607,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
||||
[
|
||||
{}
|
||||
|
@ -488866,6 +488883,10 @@
|
|||
"36050bffda9382cfd978dc82a2f0244a535a6a46",
|
||||
"support"
|
||||
],
|
||||
"css/css-backgrounds/background-rounded-image-clip.html": [
|
||||
"1f3a33ee141f0bf0186875d376bc95414db8dd18",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-backgrounds/background-size-001.html": [
|
||||
"7cf677bf25a1fcac569bd0accd28dd66e6060a1b",
|
||||
"testharness"
|
||||
|
@ -491242,6 +491263,10 @@
|
|||
"1141a4c270ace715755b9b8352dab9baffca27c4",
|
||||
"support"
|
||||
],
|
||||
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
|
||||
"0f98f9c82627977b11cde5f7c8ba536104cccdd2",
|
||||
"support"
|
||||
],
|
||||
"css/css-backgrounds/reference/background-size-002-ref.html": [
|
||||
"33d8850f315bedabb7024031b091a14177034c1d",
|
||||
"support"
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!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>
|
||||
<div id="a"></div>
|
||||
<div id="b"></div>
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Corner Clipped Background Color</title>
|
||||
<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