1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/* 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/. */
//! The `Fragment` type, which represents the leaves of the layout tree.
use crate::context::LayoutContext;
use crate::display_list::items::OpaqueNode;
use crate::ServoArc;
use app_units::Au;
use euclid::default::Rect;
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutNode};
use serde::ser::{Serialize, SerializeStruct, Serializer};
use style::logical_geometry::{LogicalMargin, LogicalRect};
use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
#[derive(Clone)]
pub struct Fragment {
pub node: OpaqueNode,
pub style: ServoArc<ComputedValues>,
pub border_box: LogicalRect<Au>,
pub border_padding: LogicalMargin<Au>,
pub margin: LogicalMargin<Au>,
pub specific: SpecificFragmentInfo,
pub restyle_damage: RestyleDamage,
pub pseudo: PseudoElementType,
}
impl Serialize for Fragment {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut serializer = serializer.serialize_struct("fragment", 3)?;
serializer.serialize_field("border_box", &self.border_box)?;
serializer.serialize_field("margin", &self.margin)?;
serializer.end()
}
}
#[derive(Clone)]
pub enum SpecificFragmentInfo {
Generic,
}
impl SpecificFragmentInfo {
fn restyle_damage(&self) -> RestyleDamage {
RestyleDamage::empty()
}
}
impl Fragment {
/// Constructs a new `Fragment` instance.
pub fn new<N: ThreadSafeLayoutNode>(
node: &N,
specific: SpecificFragmentInfo,
ctx: &LayoutContext,
) -> Fragment {
let shared_context = ctx.shared_context();
let style = node.style(shared_context);
let writing_mode = style.writing_mode;
let mut restyle_damage = RestyleDamage::rebuild_and_reflow();
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
Fragment {
node: node.opaque(),
style: style,
restyle_damage: restyle_damage,
border_box: LogicalRect::zero(writing_mode),
border_padding: LogicalMargin::zero(writing_mode),
margin: LogicalMargin::zero(writing_mode),
specific: specific,
pseudo: node.get_pseudo_element_type(),
}
}
pub fn restyle_damage(&self) -> RestyleDamage {
self.restyle_damage | self.specific.restyle_damage()
}
pub fn contains_node(&self, node_address: OpaqueNode) -> bool {
node_address == self.node
}
/// Returns the sum of the inline-sizes of all the borders of this fragment. Note that this
/// can be expensive to compute, so if possible use the `border_padding` field instead.
#[inline]
pub fn border_width(&self) -> LogicalMargin<Au> {
self.style().logical_border_width()
}
#[inline(always)]
pub fn style(&self) -> &ComputedValues {
&*self.style
}
pub fn is_primary_fragment(&self) -> bool {
true
}
}
/// A top-down fragment border box iteration handler.
pub trait FragmentBorderBoxIterator {
/// The operation to perform.
fn process(&mut self, fragment: &Fragment, level: i32, overflow: &Rect<Au>);
/// Returns true if this fragment must be processed in-order. If this returns false,
/// we skip the operation for this fragment, but continue processing siblings.
fn should_process(&mut self, fragment: &Fragment) -> bool;
}
|