mirror of
https://github.com/servo/servo.git
synced 2025-07-03 05:23:38 +01:00
2020: paint background-color
This commit is contained in:
parent
4e8eeda976
commit
cfc3ffcd54
8 changed files with 143 additions and 24 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2477,6 +2477,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
|
"cssparser",
|
||||||
"euclid",
|
"euclid",
|
||||||
"gfx",
|
"gfx",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
|
|
@ -15,6 +15,7 @@ doctest = false
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.7"
|
app_units = "0.7"
|
||||||
atomic_refcell = "0.1"
|
atomic_refcell = "0.1"
|
||||||
|
cssparser = "0.27"
|
||||||
euclid = "0.20"
|
euclid = "0.20"
|
||||||
gfx = {path = "../gfx"}
|
gfx = {path = "../gfx"}
|
||||||
ipc-channel = "0.12"
|
ipc-channel = "0.12"
|
||||||
|
|
106
components/layout_2020/display_list.rs
Normal file
106
components/layout_2020/display_list.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::fragments::{BoxFragment, Fragment};
|
||||||
|
use crate::geom::physical::{Rect, Vec2};
|
||||||
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
use app_units::Au;
|
||||||
|
use style::values::computed::Length;
|
||||||
|
use webrender_api::CommonItemProperties;
|
||||||
|
|
||||||
|
pub struct DisplayListBuilder {
|
||||||
|
pipeline_id: webrender_api::PipelineId,
|
||||||
|
pub wr: webrender_api::DisplayListBuilder,
|
||||||
|
pub is_contentful: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DisplayListBuilder {
|
||||||
|
pub fn new(
|
||||||
|
pipeline_id: webrender_api::PipelineId,
|
||||||
|
viewport_size: webrender_api::units::LayoutSize,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
pipeline_id,
|
||||||
|
is_contentful: false,
|
||||||
|
wr: webrender_api::DisplayListBuilder::new(pipeline_id, viewport_size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contentful paint, for the purpose of
|
||||||
|
/// https://w3c.github.io/paint-timing/#first-contentful-paint
|
||||||
|
/// (i.e. the display list contains items of type text,
|
||||||
|
/// image, non-white canvas or SVG). Used by metrics.
|
||||||
|
pub struct IsContentful(pub bool);
|
||||||
|
|
||||||
|
impl Fragment {
|
||||||
|
pub(crate) fn build_display_list(
|
||||||
|
&self,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
is_contentful: &mut IsContentful,
|
||||||
|
containing_block: &Rect<Length>,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
Fragment::Box(b) => b.build_display_list(builder, is_contentful, containing_block),
|
||||||
|
Fragment::Anonymous(a) => {
|
||||||
|
let rect = a
|
||||||
|
.rect
|
||||||
|
.to_physical(a.mode, containing_block)
|
||||||
|
.translate(&containing_block.top_left);
|
||||||
|
for child in &a.children {
|
||||||
|
child.build_display_list(builder, is_contentful, &rect)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Fragment::Text(_) => {
|
||||||
|
is_contentful.0 = true;
|
||||||
|
// FIXME
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxFragment {
|
||||||
|
fn build_display_list(
|
||||||
|
&self,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
is_contentful: &mut IsContentful,
|
||||||
|
containing_block: &Rect<Length>,
|
||||||
|
) {
|
||||||
|
let background_color = self
|
||||||
|
.style
|
||||||
|
.resolve_color(self.style.clone_background_color());
|
||||||
|
if background_color.alpha > 0 {
|
||||||
|
let clip_rect = self
|
||||||
|
.border_rect()
|
||||||
|
.to_physical(self.style.writing_mode(), containing_block)
|
||||||
|
.translate(&containing_block.top_left)
|
||||||
|
.into();
|
||||||
|
let common = CommonItemProperties {
|
||||||
|
clip_rect,
|
||||||
|
clip_id: webrender_api::ClipId::root(builder.pipeline_id),
|
||||||
|
spatial_id: webrender_api::SpatialId::root_scroll_node(builder.pipeline_id),
|
||||||
|
hit_info: None,
|
||||||
|
// TODO(gw): Make use of the WR backface visibility functionality.
|
||||||
|
is_backface_visible: true,
|
||||||
|
};
|
||||||
|
builder.wr.push_rect(&common, rgba(background_color))
|
||||||
|
}
|
||||||
|
let content_rect = self
|
||||||
|
.content_rect
|
||||||
|
.to_physical(self.style.writing_mode(), containing_block)
|
||||||
|
.translate(&containing_block.top_left);
|
||||||
|
for child in &self.children {
|
||||||
|
child.build_display_list(builder, is_contentful, &content_rect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rgba(rgba: cssparser::RGBA) -> webrender_api::ColorF {
|
||||||
|
webrender_api::ColorF::new(
|
||||||
|
rgba.red_f32(),
|
||||||
|
rgba.green_f32(),
|
||||||
|
rgba.blue_f32(),
|
||||||
|
rgba.alpha_f32(),
|
||||||
|
)
|
||||||
|
}
|
|
@ -2,11 +2,12 @@
|
||||||
* 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 https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::display_list::IsContentful;
|
||||||
use crate::dom_traversal::{Contents, NodeExt};
|
use crate::dom_traversal::{Contents, NodeExt};
|
||||||
use crate::flow::construct::ContainsFloats;
|
use crate::flow::construct::ContainsFloats;
|
||||||
use crate::flow::float::FloatBox;
|
use crate::flow::float::FloatBox;
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
||||||
use crate::fragments::{Fragment, IsContentful};
|
use crate::fragments::Fragment;
|
||||||
use crate::geom;
|
use crate::geom;
|
||||||
use crate::geom::flow_relative::Vec2;
|
use crate::geom::flow_relative::Vec2;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
|
@ -20,8 +21,8 @@ use servo_arc::Arc;
|
||||||
use style::context::SharedStyleContext;
|
use style::context::SharedStyleContext;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{Length, LengthOrAuto};
|
use style::values::computed::{Length, LengthOrAuto};
|
||||||
|
use style::Zero;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
use webrender_api::DisplayListBuilder;
|
|
||||||
|
|
||||||
pub struct BoxTreeRoot(BlockFormattingContext);
|
pub struct BoxTreeRoot(BlockFormattingContext);
|
||||||
pub struct FragmentTreeRoot(Vec<Fragment>);
|
pub struct FragmentTreeRoot(Vec<Fragment>);
|
||||||
|
@ -132,10 +133,25 @@ impl BoxTreeRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FragmentTreeRoot {
|
impl FragmentTreeRoot {
|
||||||
pub fn build_display_list(&self, builder: &mut DisplayListBuilder) -> IsContentful {
|
pub fn build_display_list(
|
||||||
|
&self,
|
||||||
|
builder: &mut crate::display_list::DisplayListBuilder,
|
||||||
|
pipeline_id: msg::constellation_msg::PipelineId,
|
||||||
|
viewport_size: webrender_api::units::LayoutSize,
|
||||||
|
) -> IsContentful {
|
||||||
|
let containing_block = geom::physical::Rect {
|
||||||
|
top_left: geom::physical::Vec2 {
|
||||||
|
x: Length::zero(),
|
||||||
|
y: Length::zero(),
|
||||||
|
},
|
||||||
|
size: geom::physical::Vec2 {
|
||||||
|
x: Length::new(viewport_size.width),
|
||||||
|
y: Length::new(viewport_size.height),
|
||||||
|
},
|
||||||
|
};
|
||||||
let mut is_contentful = IsContentful(false);
|
let mut is_contentful = IsContentful(false);
|
||||||
for fragment in &self.0 {
|
for fragment in &self.0 {
|
||||||
fragment.build_display_list(builder, &mut is_contentful)
|
fragment.build_display_list(builder, &mut is_contentful, &containing_block)
|
||||||
}
|
}
|
||||||
is_contentful
|
is_contentful
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::Length;
|
use style::values::computed::Length;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
use webrender_api::DisplayListBuilder;
|
|
||||||
|
|
||||||
pub(crate) enum Fragment {
|
pub(crate) enum Fragment {
|
||||||
Box(BoxFragment),
|
Box(BoxFragment),
|
||||||
|
@ -124,18 +123,3 @@ impl CollapsedMargin {
|
||||||
self.max_positive + self.min_negative
|
self.max_positive + self.min_negative
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contentful paint, for the purpose of
|
|
||||||
/// https://w3c.github.io/paint-timing/#first-contentful-paint
|
|
||||||
/// (i.e. the display list contains items of type text,
|
|
||||||
/// image, non-white canvas or SVG). Used by metrics.
|
|
||||||
pub struct IsContentful(pub bool);
|
|
||||||
|
|
||||||
impl Fragment {
|
|
||||||
pub(crate) fn build_display_list(
|
|
||||||
&self,
|
|
||||||
builder: &mut DisplayListBuilder,
|
|
||||||
is_contentful: &mut IsContentful,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -332,3 +332,12 @@ impl From<physical::Rect<Length>> for Rect<CSSPixel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<physical::Rect<Length>> for webrender_api::units::LayoutRect {
|
||||||
|
fn from(r: physical::Rect<Length>) -> Self {
|
||||||
|
Rect {
|
||||||
|
origin: Point::new(r.top_left.x.px(), r.top_left.y.px()),
|
||||||
|
size: Size::new(r.size.x.px(), r.size.y.px()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use style::Zero;
|
||||||
|
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
|
pub mod display_list;
|
||||||
mod dom_traversal;
|
mod dom_traversal;
|
||||||
mod element_data;
|
mod element_data;
|
||||||
mod flow;
|
mod flow;
|
||||||
|
|
|
@ -35,6 +35,7 @@ use gfx_traits::{node_id_from_scroll_id, Epoch};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
|
use layout::display_list::DisplayListBuilder;
|
||||||
use layout::query::{
|
use layout::query::{
|
||||||
process_content_box_request, process_content_boxes_request, LayoutRPCImpl, LayoutThreadData,
|
process_content_box_request, process_content_boxes_request, LayoutRPCImpl, LayoutThreadData,
|
||||||
};
|
};
|
||||||
|
@ -1271,9 +1272,9 @@ impl LayoutThread {
|
||||||
self.viewport_size.width.to_f32_px(),
|
self.viewport_size.width.to_f32_px(),
|
||||||
self.viewport_size.height.to_f32_px(),
|
self.viewport_size.height.to_f32_px(),
|
||||||
));
|
));
|
||||||
let mut display_list =
|
let mut display_list = DisplayListBuilder::new(self.id.to_webrender(), viewport_size);
|
||||||
webrender_api::DisplayListBuilder::new(self.id.to_webrender(), viewport_size);
|
let is_contentful =
|
||||||
let is_contentful = fragment_tree.build_display_list(&mut display_list);
|
fragment_tree.build_display_list(&mut display_list, self.id, viewport_size);
|
||||||
|
|
||||||
debug!("Layout done!");
|
debug!("Layout done!");
|
||||||
|
|
||||||
|
@ -1292,7 +1293,7 @@ impl LayoutThread {
|
||||||
webrender_api::Epoch(epoch.0),
|
webrender_api::Epoch(epoch.0),
|
||||||
None,
|
None,
|
||||||
viewport_size,
|
viewport_size,
|
||||||
display_list.finalize(),
|
display_list.wr.finalize(),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue