Skip to main content

layout_api/
layout_damage.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
5use bitflags::bitflags;
6use style::selector_parser::RestyleDamage;
7
8bitflags! {
9    /// Individual layout actions that may be necessary after restyling. This is an extension
10    /// of `RestyleDamage` from stylo, which only uses the 4 lower bits.
11    #[derive(Clone, Copy, Default, Eq, PartialEq)]
12    pub struct LayoutDamage: u16 {
13        // Layout Modes
14        //
15        // These should be kept in sync with the layout modes defined in Stylo's `RestyleDamage`.
16        // The entire damage machinery depends on `LayoutDamage` being a superset of `RestyleDamage`.
17        /// Repaint the node itself.
18        const Repaint = 0b0001;
19        /// Rebuilds the stacking contexts.
20        const RebuildStackingContextTree = 0b0011;
21        /// Recalculates the scrollable overflow.
22        const RecalculateOverflow = 0b0111;
23        /// Any other type of damage, which requires running layout again.
24        const Relayout = 0b1111;
25
26        // Layout-specific damage
27        /// Clear the cached inline content sizes and recompute them during the next layout.
28        const RecomputeInlineContentSizes = 0b1000_0000_0000_0000;
29        /// There is a change in a descendant of this box that can affect its layout.
30        /// This flag is not propagated upwards when encountering an absolutely positioned
31        /// box, since it's out-of-flow.
32        const LayoutAffectedByInflowDescendant = 0b0100_0000_0000_0000;
33        /// Rebuild this box and all of its ancestors. Do not rebuild any children. This
34        /// is used when a box's content (such as text content) changes or a descendant
35        /// has box damage ([`Self::BOX_DAMAGE`]).
36        const DescendantHasBoxDamage = 0b0011_1111_1111_0000;
37        /// Rebuild this box, all of its ancestors and all of its descendants. This is the
38        /// most a box can be damaged.
39        const BoxDamage = 0b1111_1111_1111_0000;
40    }
41}
42
43impl LayoutDamage {
44    pub fn only_layout_modes(&self) -> LayoutDamage {
45        self.intersection(LayoutDamage::Relayout)
46    }
47}
48
49impl From<RestyleDamage> for LayoutDamage {
50    fn from(restyle_damage: RestyleDamage) -> Self {
51        LayoutDamage::from_bits_retain(restyle_damage.bits())
52    }
53}
54
55impl From<LayoutDamage> for RestyleDamage {
56    fn from(layout_damage: LayoutDamage) -> Self {
57        RestyleDamage::from_bits_retain(layout_damage.bits())
58    }
59}
60
61impl std::fmt::Debug for LayoutDamage {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        if self.contains(Self::BoxDamage) {
64            f.write_str("REBUILD_BOX")
65        } else if self.contains(Self::DescendantHasBoxDamage) {
66            f.write_str("RECOLLECT_BOX_TREE_CHILDREN")
67        } else {
68            f.write_str("EMPTY")
69        }
70    }
71}