style/properties/computed_value_flags.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Misc information about a given computed style.
6
7/// Misc information about a given computed style.
8///
9/// All flags are currently inherited for text, pseudo elements, and
10/// anonymous boxes, see StyleBuilder::for_inheritance and its callsites.
11/// If we ever want to add some flags that shouldn't inherit for them,
12/// we might want to add a function to handle this.
13#[repr(C)]
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
16pub struct ComputedValueFlags(u32);
17
18bitflags! {
19 impl ComputedValueFlags: u32 {
20 /// Whether the style or any of the ancestors has a text-decoration-line
21 /// property that should get propagated to descendants.
22 ///
23 /// text-decoration-line is a reset property, but gets propagated in the
24 /// frame/box tree.
25 const HAS_TEXT_DECORATION_LINES = 1 << 0;
26
27 /// Whether line break inside should be suppressed.
28 ///
29 /// If this flag is set, the line should not be broken inside,
30 /// which means inlines act as if nowrap is set, <br> element is
31 /// suppressed, and blocks are inlinized.
32 ///
33 /// This bit is propagated to all children of line participants.
34 /// It is currently used by ruby to make its content unbreakable.
35 const SHOULD_SUPPRESS_LINEBREAK = 1 << 1;
36
37 /// A flag used to mark text that that has text-combine-upright.
38 ///
39 /// This is used from Gecko's layout engine.
40 const IS_TEXT_COMBINED = 1 << 2;
41
42 /// A flag used to mark styles under a relevant link that is also
43 /// visited.
44 const IS_RELEVANT_LINK_VISITED = 1 << 3;
45
46 /// A flag used to mark styles which are a ::first-line or under one.
47 const IS_IN_FIRST_LINE_SUBTREE = 1 << 4;
48
49 /// A flag used to mark styles which have contain:style or under one.
50 const SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE = 1 << 5;
51
52 /// Whether this style's `display` property depends on our parent style.
53 ///
54 /// This is important because it may affect our optimizations to avoid
55 /// computing the style of pseudo-elements, given whether the
56 /// pseudo-element is generated depends on the `display` value.
57 const DISPLAY_DEPENDS_ON_INHERITED_STYLE = 1 << 6;
58
59 /// Whether this style's `content` depends on our parent style.
60 ///
61 /// Important because of the same reason.
62 const CONTENT_DEPENDS_ON_INHERITED_STYLE = 1 << 7;
63
64 /// Whether the child explicitly inherits any reset property.
65 const INHERITS_RESET_STYLE = 1 << 8;
66
67 /// Whether any value on our style is font-metric-dependent on our
68 /// primary font.
69 const DEPENDS_ON_SELF_FONT_METRICS = 1 << 9;
70
71 /// Whether any value on our style is font-metric-dependent on the
72 /// primary font of our parent.
73 const DEPENDS_ON_INHERITED_FONT_METRICS = 1 << 10;
74
75 /// Whether the style or any of the ancestors has a multicol style.
76 ///
77 /// Only used in Servo.
78 const CAN_BE_FRAGMENTED = 1 << 11;
79
80 /// Whether this style is the style of the document element.
81 const IS_ROOT_ELEMENT_STYLE = 1 << 12;
82
83 /// Whether this element is inside an `opacity: 0` subtree.
84 const IS_IN_OPACITY_ZERO_SUBTREE = 1 << 13;
85
86 /// Whether there are author-specified rules for border-* properties
87 /// (except border-image-*), background-color, or background-image.
88 ///
89 /// TODO(emilio): Maybe do include border-image, see:
90 ///
91 /// https://github.com/w3c/csswg-drafts/issues/4777#issuecomment-604424845
92 const HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND = 1 << 14;
93
94 /// Whether we have author-specified font-size or margin, for <h1> purposes.
95 const HAS_AUTHOR_SPECIFIED_MARGIN_AND_FONT_SIZE = 1 << 15;
96
97 /// Whether there are author-specified rules for `font-family`.
98 const HAS_AUTHOR_SPECIFIED_FONT_FAMILY = 1 << 16;
99
100 /// Whether there are author-specified rules for `font-synthesis-weight`.
101 const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_WEIGHT = 1 << 17;
102
103 /// Whether there are author-specified rules for `font-synthesis-style`.
104 const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_STYLE = 1 << 18;
105
106 // (There's also font-synthesis-small-caps and font-synthesis-position,
107 // but we don't currently need to keep track of those.)
108
109 /// Whether there are author-specified rules for `letter-spacing`.
110 const HAS_AUTHOR_SPECIFIED_LETTER_SPACING = 1 << 19;
111
112 /// Whether there are author-specified rules for `word-spacing`.
113 const HAS_AUTHOR_SPECIFIED_WORD_SPACING = 1 << 20;
114
115 /// Whether the style depends on viewport units.
116 const USES_VIEWPORT_UNITS = 1 << 21;
117
118 /// Whether the style depends on viewport units on container queries.
119 ///
120 /// This needs to be a separate flag from `USES_VIEWPORT_UNITS` because
121 /// it causes us to re-match the style (rather than re-cascascading it,
122 /// which is enough for other uses of viewport units).
123 const USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES = 1 << 22;
124
125 /// A flag used to mark styles which have `container-type` of `size` or
126 /// `inline-size`, or under one.
127 const SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE = 1 << 23;
128 /// Whether the style uses container query units, in which case the style depends on the
129 /// container's size and we can't reuse it across cousins (without double-checking the
130 /// container at least).
131 const USES_CONTAINER_UNITS = 1 << 24;
132
133 /// Whether there are author-specific rules for text `color`.
134 const HAS_AUTHOR_SPECIFIED_TEXT_COLOR = 1 << 25;
135
136 /// Whether this style considered a scope style rule.
137 const CONSIDERED_NONTRIVIAL_SCOPED_STYLE = 1 << 26;
138 }
139}
140
141impl Default for ComputedValueFlags {
142 #[inline]
143 fn default() -> Self {
144 Self::empty()
145 }
146}
147
148impl ComputedValueFlags {
149 /// Flags that are unconditionally propagated to descendants.
150 #[inline]
151 fn inherited_flags() -> Self {
152 Self::IS_RELEVANT_LINK_VISITED |
153 Self::CAN_BE_FRAGMENTED |
154 Self::IS_IN_FIRST_LINE_SUBTREE |
155 Self::HAS_TEXT_DECORATION_LINES |
156 Self::IS_IN_OPACITY_ZERO_SUBTREE |
157 Self::SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE |
158 Self::SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE
159 }
160
161 /// Flags that may be propagated to descendants.
162 #[inline]
163 fn maybe_inherited_flags() -> Self {
164 Self::inherited_flags() | Self::SHOULD_SUPPRESS_LINEBREAK
165 }
166
167 /// Flags that are an input to the cascade.
168 #[inline]
169 fn cascade_input_flags() -> Self {
170 Self::USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES |
171 Self::CONSIDERED_NONTRIVIAL_SCOPED_STYLE
172 }
173
174 /// Returns the flags that are always propagated to descendants.
175 ///
176 /// See StyleAdjuster::set_bits and StyleBuilder.
177 #[inline]
178 pub fn inherited(self) -> Self {
179 self & Self::inherited_flags()
180 }
181
182 /// Flags that are conditionally propagated to descendants, just to handle
183 /// properly style invalidation.
184 #[inline]
185 pub fn maybe_inherited(self) -> Self {
186 self & Self::maybe_inherited_flags()
187 }
188
189 /// Flags that are an input to the cascade.
190 #[inline]
191 pub fn for_cascade_inputs(self) -> Self {
192 self & Self::cascade_input_flags()
193 }
194}