geckolib: Return @font-face rules to Gecko in the expected cascade order. r?xidorn
draft
geckolib: Return @font-face rules to Gecko in the expected cascade order. r?xidorn
MozReview-Commit-ID: 18gfwcHhuf7
--- a/servo/components/style/stylesheets/origin.rs
+++ b/servo/components/style/stylesheets/origin.rs
@@ -59,16 +59,27 @@ impl<T> PerOrigin<T> {
}
/// Iterates over references to per-origin extra style data, from highest
/// level (author) to lowest (user agent).
pub fn iter_origins(&self) -> PerOriginIter<T> {
PerOriginIter {
data: &self,
cur: 0,
+ rev: false,
+ }
+ }
+
+ /// Iterates over references to per-origin extra style data, from lowest
+ /// level (user agent) to highest (author).
+ pub fn iter_origins_rev(&self) -> PerOriginIter<T> {
+ PerOriginIter {
+ data: &self,
+ cur: 2,
+ rev: true,
}
}
/// Iterates over mutable references to per-origin extra style data, from
/// highest level (author) to lowest (user agent).
pub fn iter_mut_origins(&mut self) -> PerOriginIterMut<T> {
PerOriginIterMut {
data: self,
@@ -94,30 +105,31 @@ impl<T> PerOriginClear for PerOrigin<T>
/// Iterator over `PerOrigin<T>`, from highest level (author) to lowest
/// (user agent).
///
/// We rely on this specific order for correctly looking up @font-face,
/// @counter-style and @keyframes rules.
pub struct PerOriginIter<'a, T: 'a> {
data: &'a PerOrigin<T>,
- cur: usize,
+ cur: isize,
+ rev: bool,
}
impl<'a, T> Iterator for PerOriginIter<'a, T> where T: 'a {
type Item = (&'a T, Origin);
fn next(&mut self) -> Option<Self::Item> {
let result = match self.cur {
0 => (&self.data.author, Origin::Author),
1 => (&self.data.user, Origin::User),
2 => (&self.data.user_agent, Origin::UserAgent),
_ => return None,
};
- self.cur += 1;
+ self.cur += if self.rev { -1 } else { 1 };
Some(result)
}
}
/// Like `PerOriginIter<T>`, but iterates over mutable references to the
/// per-origin data.
///
/// We must use unsafe code here since it's not possible for the borrow
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3408,18 +3408,20 @@ pub extern "C" fn Servo_StyleSet_GetFont
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let len: u32 = data.extra_style_data
.iter_origins()
.map(|(d, _)| d.font_faces.len() as u32)
.sum();
+ // Reversed iterator because Gecko expects rules to appear sorted
+ // UserAgent first, Author last.
let font_face_iter = data.extra_style_data
- .iter_origins()
+ .iter_origins_rev()
.flat_map(|(d, o)| d.font_faces.iter().zip(iter::repeat(o)));
unsafe { rules.set_len(len) };
for (src, dest) in font_face_iter.zip(rules.iter_mut()) {
dest.mRule = src.0.read_with(&guard).clone().forget();
dest.mSheetType = src.1.into();
}
}