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        /// Clear the cached inline content sizes and recompute them during the next layout.
14        const RECOMPUTE_INLINE_CONTENT_SIZES = 0b1000_0000_0000 << 4;
15        /// There is a change in a descendant of this box that can affect its layout.
16        /// This flag is not propagated upwards when encountering an absolutely positioned
17        /// box, since it's out-of-flow.
18        const LAYOUT_AFFECTED_BY_INFLOW_DESCENDANT = 0b0100_0000_0000 << 4;
19        /// Rebuild this box and all of its ancestors. Do not rebuild any children. This
20        /// is used when a box's content (such as text content) changes or a descendant
21        /// has box damage ([`Self::BOX_DAMAGE`]).
22        const DESCENDANT_HAS_BOX_DAMAGE = 0b0011_1111_1111 << 4;
23        /// Rebuild this box, all of its ancestors and all of its descendants. This is the
24        /// most a box can be damaged.
25        const BOX_DAMAGE = 0b1111_1111_1111 << 4;
26    }
27}
28
29impl LayoutDamage {
30    pub fn descendant_has_box_damage() -> RestyleDamage {
31        RestyleDamage::from_bits_retain(LayoutDamage::DESCENDANT_HAS_BOX_DAMAGE.bits())
32    }
33
34    pub fn box_damage() -> RestyleDamage {
35        RestyleDamage::from_bits_retain(LayoutDamage::BOX_DAMAGE.bits())
36    }
37
38    pub fn needs_new_box(&self) -> bool {
39        self.contains(Self::DESCENDANT_HAS_BOX_DAMAGE)
40    }
41
42    pub fn recompute_inline_content_sizes() -> RestyleDamage {
43        RestyleDamage::from_bits_retain(LayoutDamage::RECOMPUTE_INLINE_CONTENT_SIZES.bits())
44    }
45
46    pub fn layout_affected_by_inflow_descendant() -> RestyleDamage {
47        RestyleDamage::from_bits_retain(LayoutDamage::LAYOUT_AFFECTED_BY_INFLOW_DESCENDANT.bits())
48    }
49}
50
51impl From<RestyleDamage> for LayoutDamage {
52    fn from(restyle_damage: RestyleDamage) -> Self {
53        LayoutDamage::from_bits_retain(restyle_damage.bits())
54    }
55}
56
57impl From<LayoutDamage> for RestyleDamage {
58    fn from(layout_damage: LayoutDamage) -> Self {
59        RestyleDamage::from_bits_retain(layout_damage.bits())
60    }
61}
62
63impl std::fmt::Debug for LayoutDamage {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        if self.contains(Self::BOX_DAMAGE) {
66            f.write_str("REBUILD_BOX")
67        } else if self.contains(Self::DESCENDANT_HAS_BOX_DAMAGE) {
68            f.write_str("RECOLLECT_BOX_TREE_CHILDREN")
69        } else {
70            f.write_str("EMPTY")
71        }
72    }
73}