tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

restyle_damage.rs (3830B)


      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 //! Gecko's restyle damage computation (aka change hints, aka `nsChangeHint`).
      6 
      7 use crate::gecko_bindings::bindings;
      8 use crate::gecko_bindings::structs;
      9 use crate::gecko_bindings::structs::nsChangeHint;
     10 use crate::matching::{StyleChange, StyleDifference};
     11 use crate::properties::ComputedValues;
     12 use std::ops::{BitAnd, BitOr, BitOrAssign, Not};
     13 
     14 /// The representation of Gecko's restyle damage is just a wrapper over
     15 /// `nsChangeHint`.
     16 #[derive(Clone, Copy, Debug, PartialEq)]
     17 pub struct GeckoRestyleDamage(nsChangeHint);
     18 
     19 impl GeckoRestyleDamage {
     20    /// Trivially construct a new `GeckoRestyleDamage`.
     21    #[inline]
     22    pub fn new(raw: nsChangeHint) -> Self {
     23        GeckoRestyleDamage(raw)
     24    }
     25 
     26    /// Get the inner change hint for this damage.
     27    #[inline]
     28    pub fn as_change_hint(&self) -> nsChangeHint {
     29        self.0
     30    }
     31 
     32    /// Get an empty change hint, that is (`nsChangeHint(0)`).
     33    #[inline]
     34    pub fn empty() -> Self {
     35        GeckoRestyleDamage(nsChangeHint(0))
     36    }
     37 
     38    /// Returns whether this restyle damage represents the empty damage.
     39    #[inline]
     40    pub fn is_empty(&self) -> bool {
     41        self.0 == nsChangeHint(0)
     42    }
     43 
     44    /// Computes the `StyleDifference` (including the appropriate change hint)
     45    /// given an old and a new style.
     46    pub fn compute_style_difference(
     47        old_style: &ComputedValues,
     48        new_style: &ComputedValues,
     49    ) -> StyleDifference {
     50        let mut any_style_changed = false;
     51        let mut reset_only = false;
     52        let hint = unsafe {
     53            bindings::Gecko_CalcStyleDifference(
     54                old_style.as_gecko_computed_style(),
     55                new_style.as_gecko_computed_style(),
     56                &mut any_style_changed,
     57                &mut reset_only,
     58            )
     59        };
     60        if reset_only && !old_style.custom_properties_equal(new_style) {
     61            // The Gecko_CalcStyleDifference call only checks the non-custom
     62            // property structs, so we check the custom properties here. Since
     63            // they generate no damage themselves, we can skip this check if we
     64            // already know we had some inherited (regular) property
     65            // differences.
     66            any_style_changed = true;
     67            reset_only = false;
     68        }
     69        let change = if any_style_changed {
     70            StyleChange::Changed { reset_only }
     71        } else {
     72            StyleChange::Unchanged
     73        };
     74        let damage = GeckoRestyleDamage(nsChangeHint(hint));
     75        StyleDifference { damage, change }
     76    }
     77 
     78    /// Returns true if this restyle damage contains all the damage of |other|.
     79    pub fn contains(self, other: Self) -> bool {
     80        self & other == other
     81    }
     82 
     83    /// Gets restyle damage to reconstruct the entire frame, subsuming all
     84    /// other damage.
     85    pub fn reconstruct() -> Self {
     86        GeckoRestyleDamage(structs::nsChangeHint::nsChangeHint_ReconstructFrame)
     87    }
     88 }
     89 
     90 impl Default for GeckoRestyleDamage {
     91    fn default() -> Self {
     92        Self::empty()
     93    }
     94 }
     95 
     96 impl BitOr for GeckoRestyleDamage {
     97    type Output = Self;
     98    fn bitor(self, other: Self) -> Self {
     99        GeckoRestyleDamage(self.0 | other.0)
    100    }
    101 }
    102 
    103 impl BitOrAssign for GeckoRestyleDamage {
    104    fn bitor_assign(&mut self, other: Self) {
    105        *self = *self | other;
    106    }
    107 }
    108 
    109 impl BitAnd for GeckoRestyleDamage {
    110    type Output = Self;
    111    fn bitand(self, other: Self) -> Self {
    112        GeckoRestyleDamage(nsChangeHint((self.0).0 & (other.0).0))
    113    }
    114 }
    115 
    116 impl Not for GeckoRestyleDamage {
    117    type Output = Self;
    118    fn not(self) -> Self {
    119        GeckoRestyleDamage(nsChangeHint(!(self.0).0))
    120    }
    121 }