Skip to content

Commit

Permalink
Use euclid data types for physical structs in layout_2020
Browse files Browse the repository at this point in the history
This removes a bit of duplication and allows layout_2020 to benefit from
a much richer set of utilities.
  • Loading branch information
mrobinson committed Jan 23, 2020
1 parent ee3fb92 commit 02deb99
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 271 deletions.
52 changes: 30 additions & 22 deletions components/layout_2020/display_list.rs
Expand Up @@ -4,7 +4,7 @@

use crate::context::LayoutContext;
use crate::fragments::{BoxFragment, Fragment};
use crate::geom::physical::{Rect, Vec2};
use crate::geom::{PhysicalPoint, PhysicalRect, ToWebRender};
use crate::replaced::IntrinsicSizes;
use embedder_traits::Cursor;
use euclid::{Point2D, SideOffsets2D, Size2D, Vector2D};
Expand Down Expand Up @@ -74,15 +74,15 @@ impl Fragment {
pub(crate) fn build_display_list(
&self,
builder: &mut DisplayListBuilder,
containing_block: &Rect<Length>,
containing_block: &PhysicalRect<Length>,
) {
match self {
Fragment::Box(b) => BuilderForBoxFragment::new(b, containing_block).build(builder),
Fragment::Anonymous(a) => {
let rect = a
.rect
.to_physical(a.mode, containing_block)
.translate(&containing_block.top_left);
.translate(containing_block.origin.to_vector());
for child in &a.children {
child.build_display_list(builder, &rect)
}
Expand All @@ -92,30 +92,35 @@ impl Fragment {
let rect = t
.rect
.to_physical(t.parent_style.writing_mode, containing_block)
.translate(&containing_block.top_left);
let mut baseline_origin = rect.top_left.clone();
.translate(containing_block.origin.to_vector());
let mut baseline_origin = rect.origin.clone();
baseline_origin.y += t.ascent;
let glyphs = glyphs(&t.glyphs, baseline_origin);
if glyphs.is_empty() {
return;
}
let mut common = builder.common_properties(rect.clone().into());
let mut common = builder.common_properties(rect.clone().to_webrender());
common.hit_info = hit_info(&t.parent_style, t.tag, Cursor::Text);
let color = t.parent_style.clone_color();
builder
.wr
.push_text(&common, rect.into(), &glyphs, t.font_key, rgba(color), None);
builder.wr.push_text(
&common,
rect.to_webrender(),
&glyphs,
t.font_key,
rgba(color),
None,
);
},
Fragment::Image(i) => {
builder.is_contentful = true;
let rect = i
.rect
.to_physical(i.style.writing_mode, containing_block)
.translate(&containing_block.top_left);
let common = builder.common_properties(rect.clone().into());
.translate(containing_block.origin.to_vector());
let common = builder.common_properties(rect.clone().to_webrender());
builder.wr.push_image(
&common,
rect.into(),
rect.to_webrender(),
image_rendering(i.style.get_inherited_box().image_rendering),
wr::AlphaType::PremultipliedAlpha,
i.image_key,
Expand All @@ -128,7 +133,7 @@ impl Fragment {

struct BuilderForBoxFragment<'a> {
fragment: &'a BoxFragment,
containing_block: &'a Rect<Length>,
containing_block: &'a PhysicalRect<Length>,
border_rect: units::LayoutRect,
padding_rect: OnceCell<units::LayoutRect>,
content_rect: OnceCell<units::LayoutRect>,
Expand All @@ -137,12 +142,12 @@ struct BuilderForBoxFragment<'a> {
}

impl<'a> BuilderForBoxFragment<'a> {
fn new(fragment: &'a BoxFragment, containing_block: &'a Rect<Length>) -> Self {
fn new(fragment: &'a BoxFragment, containing_block: &'a PhysicalRect<Length>) -> Self {
let border_rect: units::LayoutRect = fragment
.border_rect()
.to_physical(fragment.style.writing_mode, containing_block)
.translate(&containing_block.top_left)
.into();
.translate(containing_block.origin.to_vector())
.to_webrender();

let border_radius = {
let resolve = |radius: &LengthPercentage, box_size: f32| {
Expand Down Expand Up @@ -179,8 +184,8 @@ impl<'a> BuilderForBoxFragment<'a> {
self.fragment
.content_rect
.to_physical(self.fragment.style.writing_mode, self.containing_block)
.translate(&self.containing_block.top_left)
.into()
.translate(self.containing_block.origin.to_vector())
.to_webrender()
})
}

Expand All @@ -189,8 +194,8 @@ impl<'a> BuilderForBoxFragment<'a> {
self.fragment
.padding_rect()
.to_physical(self.fragment.style.writing_mode, self.containing_block)
.translate(&self.containing_block.top_left)
.into()
.translate(self.containing_block.origin.to_vector())
.to_webrender()
})
}

Expand Down Expand Up @@ -235,7 +240,7 @@ impl<'a> BuilderForBoxFragment<'a> {
.fragment
.content_rect
.to_physical(self.fragment.style.writing_mode, self.containing_block)
.translate(&self.containing_block.top_left);
.translate(self.containing_block.origin.to_vector());
for child in &self.fragment.children {
child.build_display_list(builder, &content_rect)
}
Expand Down Expand Up @@ -580,7 +585,10 @@ fn rgba(rgba: cssparser::RGBA) -> wr::ColorF {
)
}

fn glyphs(glyph_runs: &[Arc<GlyphStore>], mut origin: Vec2<Length>) -> Vec<wr::GlyphInstance> {
fn glyphs(
glyph_runs: &[Arc<GlyphStore>],
mut origin: PhysicalPoint<Length>,
) -> Vec<wr::GlyphInstance> {
use gfx_traits::ByteIndex;
use range::Range;

Expand Down
12 changes: 4 additions & 8 deletions components/layout_2020/dom_traversal.rs
Expand Up @@ -4,7 +4,7 @@

use crate::context::LayoutContext;
use crate::element_data::{LayoutBox, LayoutDataForElement};
use crate::geom::physical::Vec2;
use crate::geom::PhysicalSize;
use crate::replaced::ReplacedContent;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside};
use crate::wrapper::GetRawData;
Expand Down Expand Up @@ -307,7 +307,7 @@ pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync {

/// Returns the image if it’s loaded, and its size in image pixels
/// adjusted for `image_density`.
fn as_image(self) -> Option<(Option<Arc<NetImage>>, Vec2<f64>)>;
fn as_image(self) -> Option<(Option<Arc<NetImage>>, PhysicalSize<f64>)>;
fn first_child(self) -> Option<Self>;
fn next_sibling(self) -> Option<Self>;
fn parent_node(self) -> Option<Self>;
Expand Down Expand Up @@ -337,7 +337,7 @@ where
}
}

fn as_image(self) -> Option<(Option<Arc<NetImage>>, Vec2<f64>)> {
fn as_image(self) -> Option<(Option<Arc<NetImage>>, PhysicalSize<f64>)> {
let node = self.to_threadsafe();
let (resource, metadata) = node.image_data()?;
let (width, height) = resource
Expand All @@ -350,11 +350,7 @@ where
width = width / density;
height = height / density;
}
let size = Vec2 {
x: width,
y: height,
};
Some((resource, size))
Some((resource, PhysicalSize::new(width, height)))
}

fn first_child(self) -> Option<Self> {
Expand Down
63 changes: 29 additions & 34 deletions components/layout_2020/flow/root.rs
Expand Up @@ -9,9 +9,8 @@ use crate::flow::float::FloatBox;
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Fragment;
use crate::geom;
use crate::geom::flow_relative::Vec2;
use crate::geom::physical;
use crate::geom::PhysicalRect;
use crate::positioned::AbsolutelyPositionedBox;
use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContent;
Expand All @@ -25,7 +24,6 @@ use script_layout_interface::wrapper_traits::LayoutNode;
use servo_arc::Arc;
use style::properties::ComputedValues;
use style::values::computed::Length;
use style::Zero;
use style_traits::CSSPixel;

pub struct BoxTreeRoot(BlockFormattingContext);
Expand All @@ -35,10 +33,10 @@ pub struct FragmentTreeRoot {
children: Vec<Fragment>,

/// The scrollable overflow of the root of the fragment tree.
scrollable_overflow: physical::Rect<Length>,
scrollable_overflow: PhysicalRect<Length>,

/// The axis-aligned bounding box of the border box of all child fragments
bounding_box_of_border_boxes: physical::Rect<Length>,
bounding_box_of_border_boxes: PhysicalRect<Length>,
}

impl BoxTreeRoot {
Expand Down Expand Up @@ -116,7 +114,7 @@ impl BoxTreeRoot {
pub fn layout(
&self,
layout_context: &LayoutContext,
viewport: geom::Size<CSSPixel>,
viewport: euclid::Size2D<f32, CSSPixel>,
) -> FragmentTreeRoot {
let style = ComputedValues::initial_values();
let initial_containing_block = DefiniteContainingBlock {
Expand Down Expand Up @@ -150,7 +148,7 @@ impl BoxTreeRoot {
independent_layout
.fragments
.iter()
.fold(physical::Rect::zero(), |acc, child| {
.fold(PhysicalRect::zero(), |acc, child| {
let child_overflow = child.scrollable_overflow();

// https://drafts.csswg.org/css-overflow/#scrolling-direction
Expand All @@ -159,23 +157,23 @@ impl BoxTreeRoot {
//
// FIXME(mrobinson, bug 25564): This should take into account writing
// mode.
let child_overflow = physical::Rect {
top_left: physical::Vec2::zero(),
size: physical::Vec2 {
x: child_overflow.size.x + child_overflow.top_left.x,
y: child_overflow.size.y + child_overflow.top_left.y,
},
};
acc.axis_aligned_bounding_box(&child_overflow)
let child_overflow = PhysicalRect::new(
euclid::Point2D::zero(),
euclid::Size2D::new(
child_overflow.size.width + child_overflow.origin.x,
child_overflow.size.height + child_overflow.origin.y,
),
);
acc.union(&child_overflow)
});

let containing_block = physical::Rect::zero();
let containing_block = PhysicalRect::zero();
let bounding_box_of_border_boxes =
independent_layout
.fragments
.iter()
.fold(physical::Rect::zero(), |acc, child| {
acc.axis_aligned_bounding_box(&match child {
.fold(PhysicalRect::zero(), |acc, child| {
acc.union(&match child {
Fragment::Box(fragment) => fragment
.border_rect()
.to_physical(fragment.style.writing_mode, &containing_block),
Expand Down Expand Up @@ -205,16 +203,13 @@ impl FragmentTreeRoot {
builder: &mut crate::display_list::DisplayListBuilder,
viewport_size: webrender_api::units::LayoutSize,
) {
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 containing_block = PhysicalRect::new(
euclid::Point2D::zero(),
euclid::Size2D::new(
Length::new(viewport_size.width),
Length::new(viewport_size.height),
),
);
for fragment in &self.children {
fragment.build_display_list(builder, &containing_block)
}
Expand All @@ -229,19 +224,19 @@ impl FragmentTreeRoot {

pub fn scrollable_overflow(&self) -> webrender_api::units::LayoutSize {
webrender_api::units::LayoutSize::from_untyped(Size2D::new(
self.scrollable_overflow.size.x.px(),
self.scrollable_overflow.size.y.px(),
self.scrollable_overflow.size.width.px(),
self.scrollable_overflow.size.height.px(),
))
}

pub fn bounding_box_of_border_boxes(&self) -> Rect<Au> {
let origin = Point2D::new(
Au::from_f32_px(self.bounding_box_of_border_boxes.top_left.x.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.top_left.y.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.origin.x.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.origin.y.px()),
);
let size = Size2D::new(
Au::from_f32_px(self.bounding_box_of_border_boxes.size.x.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.size.y.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.size.width.px()),
Au::from_f32_px(self.bounding_box_of_border_boxes.size.height.px()),
);
Rect::new(origin, size)
}
Expand Down
22 changes: 11 additions & 11 deletions components/layout_2020/fragments.rs
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::geom::physical;
use crate::geom::PhysicalRect;
use gfx::text::glyph::GlyphStore;
use gfx_traits::print_tree::PrintTree;
use servo_arc::Arc as ServoArc;
Expand Down Expand Up @@ -39,7 +39,7 @@ pub(crate) struct BoxFragment {
pub block_margins_collapsed_with_children: CollapsedBlockMargins,

/// The scrollable overflow of this box fragment.
pub scrollable_overflow: physical::Rect<Length>,
pub scrollable_overflow: PhysicalRect<Length>,
}

pub(crate) struct CollapsedBlockMargins {
Expand All @@ -61,7 +61,7 @@ pub(crate) struct AnonymousFragment {
pub mode: WritingMode,

/// The scrollable overflow of this anonymous fragment's children.
pub scrollable_overflow: physical::Rect<Length>,
pub scrollable_overflow: PhysicalRect<Length>,
}

pub(crate) struct TextFragment {
Expand Down Expand Up @@ -98,18 +98,18 @@ impl Fragment {
}
}

pub fn scrollable_overflow(&self) -> physical::Rect<Length> {
pub fn scrollable_overflow(&self) -> PhysicalRect<Length> {
// FIXME(mrobinson, bug 25564): We should be using the containing block
// here to properly convert scrollable overflow to physical geometry.
match self {
Fragment::Box(fragment) => fragment.scrollable_overflow.clone(),
Fragment::Anonymous(fragment) => fragment.scrollable_overflow.clone(),
Fragment::Text(fragment) => fragment
.rect
.to_physical(fragment.parent_style.writing_mode, &physical::Rect::zero()),
.to_physical(fragment.parent_style.writing_mode, &PhysicalRect::zero()),
Fragment::Image(fragment) => fragment
.rect
.to_physical(fragment.style.writing_mode, &physical::Rect::zero()),
.to_physical(fragment.style.writing_mode, &PhysicalRect::zero()),
}
}
}
Expand All @@ -120,15 +120,15 @@ impl AnonymousFragment {
children: vec![],
rect: Rect::zero(),
mode,
scrollable_overflow: physical::Rect::zero(),
scrollable_overflow: PhysicalRect::zero(),
}
}

pub fn new(rect: Rect<Length>, children: Vec<Fragment>, mode: WritingMode) -> Self {
// FIXME(mrobinson, bug 25564): We should be using the containing block
// here to properly convert scrollable overflow to physical geometry.
let scrollable_overflow = children.iter().fold(physical::Rect::zero(), |acc, child| {
acc.axis_aligned_bounding_box(&child.scrollable_overflow())
let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
acc.union(&child.scrollable_overflow())
});
AnonymousFragment {
rect,
Expand Down Expand Up @@ -168,8 +168,8 @@ impl BoxFragment {
let scrollable_overflow = children.iter().fold(
content_rect
.inflate(&border)
.to_physical(style.writing_mode, &physical::Rect::zero()),
|acc, child| acc.axis_aligned_bounding_box(&child.scrollable_overflow()),
.to_physical(style.writing_mode, &PhysicalRect::zero()),
|acc, child| acc.union(&child.scrollable_overflow()),
);
BoxFragment {
tag,
Expand Down

0 comments on commit 02deb99

Please sign in to comment.