/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! The restyle damage is a hint that tells layout which kind of operations may //! be needed in presence of incremental style changes.
use bitflags::Flags;
usecrate::computed_values::isolation::T as Isolation; usecrate::computed_values::mix_blend_mode::T as MixBlendMode; usecrate::computed_values::transform_style::T as TransformStyle; usecrate::dom::TElement; usecrate::matching::{StyleChange, StyleDifference}; usecrate::properties::{
restyle_damage_rebuild_box, restyle_damage_rebuild_stacking_context,
restyle_damage_recalculate_overflow, restyle_damage_repaint, style_structs, ComputedValues,
}; usecrate::values::computed::basic_shape::ClipPath; usecrate::values::computed::Perspective; usecrate::values::generics::transform::{GenericRotate, GenericScale, GenericTranslate}; use std::fmt;
bitflags! { /// Major phases of layout that need to be run due to the damage to a node during restyling. In /// addition to the 4 bytes used for that, the rest of the `u16` is exposed as an extension point /// for users of the crate to add their own custom types of damage that correspond to the /// layout system they are implementing. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pubstruct ServoRestyleDamage: u16 { /// Repaint the node itself. /// /// Propagates both up and down the flow tree. const REPAINT = 0b0001;
/// Rebuilds the stacking contexts. /// /// Propagates both up and down the flow tree. const REBUILD_STACKING_CONTEXT = 0b0011;
/// Recalculates the scrollable overflow. /// /// Propagates both up and down the flow tree. const RECALCULATE_OVERFLOW = 0b0111;
/// Any other type of damage, which requires running layout again. /// /// Propagates both up and down the flow tree. const RELAYOUT = 0b1111;
}
}
letmut any_style_changed = !damage.is_empty(); // FIXME(emilio): Differentiate between reset and inherited // properties here, and set `reset_only` appropriately so the // optimization to skip the cascade in those cases applies. letmut reset_only = !any_style_changed;
let old_custom_props = old.custom_properties(); let new_custom_props = new.custom_properties(); letmut custom_properties_changed = false; if old_custom_props.inherited != new_custom_props.inherited {
any_style_changed = true;
custom_properties_changed = true;
reset_only = false;
} elseif old_custom_props.non_inherited != new_custom_props.non_inherited {
any_style_changed = true;
custom_properties_changed = true;
}; if custom_properties_changed { // Paint worklets may depend on custom properties, so if they have changed we should repaint.
damage.insert(ServoRestyleDamage::REPAINT);
}
let change = if any_style_changed {
StyleChange::Changed {
reset_only,
custom_properties_changed,
}
} else {
StyleChange::Unchanged
};
StyleDifference { damage, change }
}
/// Returns a bitmask indicating that the frame needs to be reconstructed. pubfn reconstruct() -> ServoRestyleDamage { // There's no way of knowing what kind of damage system the embedder will use, but part of // this interface is that a fully saturated restyle damage means to rebuild everything.
ServoRestyleDamage::from_bits_retain(<ServoRestyleDamage as Flags>::Bits::MAX)
}
}
fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> ServoRestyleDamage { // Damage flags higher up the if-else chain imply damage flags lower down the if-else chain, // so we can skip the diffing process for later flags if an earlier flag is true if augmented_restyle_damage_rebuild_box(old, new) {
ServoRestyleDamage::RELAYOUT
} elseif restyle_damage_recalculate_overflow(old, new) {
ServoRestyleDamage::RECALCULATE_OVERFLOW
} elseif augmented_restyle_damage_rebuild_stacking_context(old, new) {
ServoRestyleDamage::REBUILD_STACKING_CONTEXT
} elseif restyle_damage_repaint(old, new) {
ServoRestyleDamage::REPAINT
} else {
ServoRestyleDamage::empty()
}
}
impl ComputedValues { /// Some properties establish a stacking context when they are set to a non-initial value. /// In that case, the damage is only set to `ServoRestyleDamage::REPAINT` because we don't /// need to rebuild stacking contexts when the style changes between different non-initial /// values. This function checks whether any of these properties is set to a value that /// guarantees a stacking context, so that we only do the work when this changes. /// Note that it's still possible to establish a stacking context when this returns false. pubfn guarantees_stacking_context(&self) -> bool { self.get_effects().opacity != 1.0
|| self.get_effects().mix_blend_mode != MixBlendMode::Normal
|| self.get_svg().clip_path != ClipPath::None
|| self.get_box().isolation == Isolation::Isolate
}
}
impl style_structs::Box { /// Whether there is a non-default transform or perspective style set pubfn has_transform_or_perspective(&self) -> bool {
!self.transform.0.is_empty()
|| self.scale != GenericScale::None
|| self.rotate != GenericRotate::None
|| self.translate != GenericTranslate::None
|| self.perspective != Perspective::None
|| self.transform_style == TransformStyle::Preserve3d
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.