stylo: Store font metrics provider in thread local style context

This commit is contained in:
Manish Goregaokar 2017-04-04 11:11:27 -07:00 committed by Manish Goregaokar
parent 2ea8d61fbf
commit e402c72d0e
19 changed files with 158 additions and 35 deletions

View file

@ -13,6 +13,7 @@ use script_traits::{AnimationState, ConstellationControlMsg, LayoutMsg as Conste
use std::collections::HashMap;
use std::sync::mpsc::Receiver;
use style::animation::{Animation, update_style_for_animation};
use style::font_metrics::ServoMetricsProvider;
use style::selector_parser::RestyleDamage;
use style::timer::Timer;
@ -143,7 +144,8 @@ pub fn recalc_style_for_animations(context: &LayoutContext,
let old_style = fragment.style.clone();
update_style_for_animation(&context.style_context,
animation,
&mut fragment.style);
&mut fragment.style,
&ServoMetricsProvider);
damage |= RestyleDamage::compute(&old_style, &fragment.style);
}
}

View file

@ -53,6 +53,7 @@ impl<'a> RecalcStyleAndConstructFlows<'a> {
impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
where E: TElement,
E::ConcreteNode: LayoutNode,
E::FontMetricsProvider: Send,
{
type ThreadLocalContext = ScopedThreadLocalLayoutContext<E>;

View file

@ -67,6 +67,7 @@ use style::data::ElementData;
use style::dom::{DescendantsBit, DirtyDescendants, LayoutIterator, NodeInfo, OpaqueNode};
use style::dom::{PresentationalHintsSynthetizer, TElement, TNode, UnsafeNode};
use style::element_state::*;
use style::font_metrics::ServoMetricsProvider;
use style::properties::{ComputedValues, PropertyDeclarationBlock};
use style::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
@ -373,6 +374,8 @@ impl<'le> PresentationalHintsSynthetizer for ServoLayoutElement<'le> {
impl<'le> TElement for ServoLayoutElement<'le> {
type ConcreteNode = ServoLayoutNode<'le>;
type FontMetricsProvider = ServoMetricsProvider;
fn as_node(&self) -> ServoLayoutNode<'le> {
ServoLayoutNode::from_layout_js(self.element.upcast())
}

View file

@ -21,6 +21,7 @@ use style::context::SharedStyleContext;
use style::data::ElementData;
use style::dom::{LayoutIterator, NodeInfo, PresentationalHintsSynthetizer, TNode};
use style::dom::OpaqueNode;
use style::font_metrics::ServoMetricsProvider;
use style::properties::{CascadeFlags, ServoComputedValues};
use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorImpl};
@ -411,7 +412,8 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
&context.guards,
&style_pseudo,
Some(data.styles().primary.values()),
CascadeFlags::empty());
CascadeFlags::empty(),
&ServoMetricsProvider);
data.styles_mut().cached_pseudos
.insert(style_pseudo.clone(), new_style);
}
@ -426,7 +428,8 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
&context.guards,
unsafe { &self.unsafe_get() },
&style_pseudo,
data.styles().primary.values());
data.styles().primary.values(),
&ServoMetricsProvider);
data.styles_mut().cached_pseudos
.insert(style_pseudo.clone(), new_style.unwrap());
}

View file

@ -10,6 +10,7 @@ use bezier::Bezier;
use context::SharedStyleContext;
use dom::{OpaqueNode, UnsafeNode};
use euclid::point::Point2D;
use font_metrics::FontMetricsProvider;
use keyframes::{KeyframesStep, KeyframesStepValue};
use properties::{self, CascadeFlags, ComputedValues, Importance};
use properties::animated_properties::{AnimatedProperty, TransitionProperty};
@ -410,7 +411,8 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>
fn compute_style_for_animation_step(context: &SharedStyleContext,
step: &KeyframesStep,
previous_style: &ComputedValues,
style_from_cascade: &ComputedValues)
style_from_cascade: &ComputedValues,
font_metrics_provider: &FontMetricsProvider)
-> ComputedValues {
match step.value {
KeyframesStepValue::ComputedValues => style_from_cascade.clone(),
@ -433,7 +435,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
previous_style,
/* cascade_info = */ None,
&*context.error_reporter,
/* Metrics provider */ None,
font_metrics_provider,
CascadeFlags::empty());
computed
}
@ -534,7 +536,8 @@ pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
/// If `damage` is provided, inserts the appropriate restyle damage.
pub fn update_style_for_animation(context: &SharedStyleContext,
animation: &Animation,
style: &mut Arc<ComputedValues>) {
style: &mut Arc<ComputedValues>,
font_metrics_provider: &FontMetricsProvider) {
debug!("update_style_for_animation: entering");
debug_assert!(!animation.is_expired());
@ -658,7 +661,8 @@ pub fn update_style_for_animation(context: &SharedStyleContext,
let from_style = compute_style_for_animation_step(context,
last_keyframe,
&**style,
&state.cascade_style);
&state.cascade_style,
font_metrics_provider);
// NB: The spec says that the timing function can be overwritten
// from the keyframe style.
@ -672,7 +676,8 @@ pub fn update_style_for_animation(context: &SharedStyleContext,
let target_style = compute_style_for_animation_step(context,
target_keyframe,
&from_style,
&state.cascade_style);
&state.cascade_style,
font_metrics_provider);
let mut new_style = (*style).clone();

View file

@ -12,6 +12,7 @@ use data::ElementData;
use dom::{OpaqueNode, TNode, TElement, SendElement};
use error_reporting::ParseErrorReporter;
use euclid::Size2D;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")] use gecko_bindings::structs;
use matching::StyleSharingCandidateCache;
use parking_lot::RwLock;
@ -291,6 +292,9 @@ pub struct ThreadLocalStyleContext<E: TElement> {
pub statistics: TraversalStatistics,
/// Information related to the current element, non-None during processing.
pub current_element_info: Option<CurrentElementInfo>,
/// The struct used to compute and cache font metrics from style
/// for evaluation of the font-relative em/ch units and font-size
pub font_metrics_provider: E::FontMetricsProvider,
}
impl<E: TElement> ThreadLocalStyleContext<E> {
@ -303,6 +307,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
tasks: Vec::new(),
statistics: TraversalStatistics::default(),
current_element_info: None,
font_metrics_provider: E::FontMetricsProvider::create_from(shared),
}
}

View file

@ -12,6 +12,7 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
#[cfg(feature = "gecko")] use context::UpdateAnimationsTasks;
use data::ElementData;
use element_state::ElementState;
use font_metrics::FontMetricsProvider;
use properties::{ComputedValues, PropertyDeclarationBlock};
use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
use selectors::matching::ElementSelectorFlags;
@ -278,6 +279,12 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
/// The concrete node type.
type ConcreteNode: TNode<ConcreteElement = Self>;
/// Type of the font metrics provider
///
/// XXXManishearth It would be better to make this a type parameter on
/// ThreadLocalStyleContext and StyleContext
type FontMetricsProvider: FontMetricsProvider;
/// Get this element as a node.
fn as_node(&self) -> Self::ConcreteNode;

View file

@ -8,6 +8,7 @@
use Atom;
use app_units::Au;
use context::SharedStyleContext;
use euclid::Size2D;
use std::fmt;
@ -31,8 +32,36 @@ pub enum FontMetricsQueryResult {
NotAvailable,
}
// TODO: Servo's font metrics provider will probably not live in this crate, so this will
// have to be replaced with something else (perhaps a trait method on TElement)
// when we get there
#[derive(Debug)]
#[cfg(feature = "servo")]
/// Dummy metrics provider for Servo. Knows nothing about fonts and does not provide
/// any metrics.
pub struct ServoMetricsProvider;
#[cfg(feature = "servo")]
impl FontMetricsProvider for ServoMetricsProvider {
fn create_from(_: &SharedStyleContext) -> Self {
ServoMetricsProvider
}
}
#[cfg(feature = "gecko")]
/// Construct a font metrics provider for the current product
pub fn get_metrics_provider_for_product() -> ::gecko::wrapper::GeckoFontMetricsProvider {
::gecko::wrapper::GeckoFontMetricsProvider::new()
}
#[cfg(feature = "servo")]
/// Construct a font metrics provider for the current product
pub fn get_metrics_provider_for_product() -> ServoMetricsProvider {
ServoMetricsProvider
}
/// A trait used to represent something capable of providing us font metrics.
pub trait FontMetricsProvider: Send + Sync + fmt::Debug {
pub trait FontMetricsProvider: Send + fmt::Debug {
/// Obtain the metrics for given font family.
///
/// TODO: We could make this take the full list, I guess, and save a few
@ -41,4 +70,13 @@ pub trait FontMetricsProvider: Send + Sync + fmt::Debug {
fn query(&self, _font_name: &Atom) -> FontMetricsQueryResult {
FontMetricsQueryResult::NotAvailable
}
/// Get default size of a given language and generic family
fn get_size(&self, _font_name: &Atom, _font_family: u8) -> Au {
unimplemented!()
}
/// Construct from a shared style context
fn create_from(context: &SharedStyleContext) -> Self where Self: Sized;
}

View file

@ -7,6 +7,7 @@
use app_units::Au;
use cssparser::{CssStringWriter, Parser, Token};
use euclid::Size2D;
use font_metrics::get_metrics_provider_for_product;
use gecko_bindings::bindings;
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsStringBuffer};
use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature};
@ -499,6 +500,8 @@ impl Expression {
let default_values = device.default_computed_values();
let provider = get_metrics_provider_for_product();
// http://dev.w3.org/csswg/mediaqueries3/#units
// em units are relative to the initial font-size.
let context = computed::Context {
@ -509,7 +512,7 @@ impl Expression {
// This cloning business is kind of dumb.... It's because Context
// insists on having an actual ComputedValues inside itself.
style: default_values.clone(),
font_metrics_provider: None,
font_metrics_provider: &provider,
};
let required_value = match self.value {

View file

@ -15,7 +15,7 @@
//! the separation between the style system implementation and everything else.
use atomic_refcell::AtomicRefCell;
use context::UpdateAnimationsTasks;
use context::{SharedStyleContext, UpdateAnimationsTasks};
use data::ElementData;
use dom::{self, AnimationRules, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
@ -60,6 +60,7 @@ use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::parser::{AttrSelector, NamespaceConstraint};
use shared_lock::Locked;
use sink::Push;
use std::cell::RefCell;
use std::fmt;
use std::ptr;
use std::sync::Arc;
@ -426,8 +427,34 @@ fn get_animation_rule(element: &GeckoElement,
}
}
#[derive(Debug)]
/// Gecko font metrics provider
pub struct GeckoFontMetricsProvider {
/// Cache of base font sizes for each language
///
/// Should have at most 31 elements (the number of language groups). Usually
/// will have 1.
pub font_size_cache: RefCell<Vec<(Atom, ::gecko_bindings::structs::FontSizePrefs)>>,
}
impl GeckoFontMetricsProvider {
/// Construct
pub fn new() -> Self {
GeckoFontMetricsProvider {
font_size_cache: RefCell::new(Vec::new()),
}
}
}
impl ::font_metrics::FontMetricsProvider for GeckoFontMetricsProvider {
fn create_from(_: &SharedStyleContext) -> Self {
GeckoFontMetricsProvider::new()
}
}
impl<'le> TElement for GeckoElement<'le> {
type ConcreteNode = GeckoNode<'le>;
type FontMetricsProvider = GeckoFontMetricsProvider;
fn as_node(&self) -> Self::ConcreteNode {
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }

View file

@ -15,6 +15,7 @@ use cascade_info::CascadeInfo;
use context::{SequentialTask, SharedStyleContext, StyleContext};
use data::{ComputedStyle, ElementData, ElementStyles, RestyleData};
use dom::{AnimationRules, SendElement, TElement, TNode};
use font_metrics::FontMetricsProvider;
use properties::{CascadeFlags, ComputedValues, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
use properties::longhands::display::computed_value as display;
use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_CSS_ANIMATIONS, RestyleHint};
@ -442,6 +443,7 @@ trait PrivateMatchMethods: TElement {
fn cascade_with_rules(&self,
shared_context: &SharedStyleContext,
font_metrics_provider: &FontMetricsProvider,
rule_node: &StrongRuleNode,
primary_style: &ComputedStyle,
cascade_flags: CascadeFlags,
@ -507,6 +509,7 @@ trait PrivateMatchMethods: TElement {
layout_parent_style,
Some(&mut cascade_info),
&*shared_context.error_reporter,
font_metrics_provider,
cascade_flags));
cascade_info.finish(&self.as_node());
@ -525,7 +528,8 @@ trait PrivateMatchMethods: TElement {
// Grab the rule node.
let rule_node = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1).rules;
self.cascade_with_rules(context.shared, rule_node, primary_style, cascade_flags, pseudo_style.is_some())
self.cascade_with_rules(context.shared, &context.thread_local.font_metrics_provider,
rule_node, primary_style, cascade_flags, pseudo_style.is_some())
}
/// Computes values and damage for the primary or pseudo style of an element,
@ -589,6 +593,7 @@ trait PrivateMatchMethods: TElement {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
self.cascade_with_rules(context.shared,
&context.thread_local.font_metrics_provider,
&without_transition_rules,
primary_style,
cascade_flags,
@ -650,7 +655,8 @@ trait PrivateMatchMethods: TElement {
let shared_context = context.shared;
if let Some(ref mut old) = *old_values {
self.update_animations_for_cascade(shared_context, old,
possibly_expired_animations);
possibly_expired_animations,
&context.thread_local.font_metrics_provider);
}
let new_animations_sender = &context.thread_local.new_animations_sender;
@ -725,7 +731,8 @@ trait PrivateMatchMethods: TElement {
fn update_animations_for_cascade(&self,
context: &SharedStyleContext,
style: &mut Arc<ComputedValues>,
possibly_expired_animations: &mut Vec<PropertyAnimation>) {
possibly_expired_animations: &mut Vec<PropertyAnimation>,
font_metrics: &FontMetricsProvider) {
// Finish any expired transitions.
let this_opaque = self.as_node().opaque();
animation::complete_expired_transitions(this_opaque, style, context);
@ -752,7 +759,8 @@ trait PrivateMatchMethods: TElement {
if !running_animation.is_expired() {
animation::update_style_for_animation(context,
running_animation,
style);
style,
font_metrics);
if let Animation::Transition(_, _, _, ref frame, _) = *running_animation {
possibly_expired_animations.push(frame.property_animation.clone())
}
@ -1265,6 +1273,7 @@ pub trait MatchMethods : TElement {
/// Returns computed values without animation and transition rules.
fn get_base_style(&self,
shared_context: &SharedStyleContext,
font_metrics_provider: &FontMetricsProvider,
primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &ComputedStyle)>)
-> Arc<ComputedValues> {
@ -1283,6 +1292,7 @@ pub trait MatchMethods : TElement {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
self.cascade_with_rules(shared_context,
font_metrics_provider,
&without_animation_rules,
primary_style,
cascade_flags,

View file

@ -1944,6 +1944,7 @@ pub fn cascade(device: &Device,
layout_parent_style: Option<<&ComputedValues>,
cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: &FontMetricsProvider,
flags: CascadeFlags)
-> ComputedValues {
debug_assert_eq!(parent_style.is_some(), layout_parent_style.is_some());
@ -1988,7 +1989,7 @@ pub fn cascade(device: &Device,
layout_parent_style,
cascade_info,
error_reporter,
None,
font_metrics_provider,
flags)
}
@ -2002,7 +2003,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
layout_parent_style: &ComputedValues,
mut cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: Option<<&FontMetricsProvider>,
font_metrics_provider: &FontMetricsProvider,
flags: CascadeFlags)
-> ComputedValues
where F: Fn() -> I,

View file

@ -7,6 +7,7 @@
use app_units::Au;
use cssparser::Parser;
use euclid::{Size2D, TypedSize2D};
use font_metrics::ServoMetricsProvider;
use media_queries::MediaType;
use properties::ComputedValues;
use std::fmt;
@ -185,7 +186,10 @@ impl Range<specified::Length> {
// This cloning business is kind of dumb.... It's because Context
// insists on having an actual ComputedValues inside itself.
style: default_values.clone(),
font_metrics_provider: None
// Servo doesn't support font metrics
// A real provider will be needed here once we do; since
// ch units can exist in media queries.
font_metrics_provider: &ServoMetricsProvider,
};
match *self {

View file

@ -10,6 +10,7 @@ use {Atom, LocalName};
use data::ComputedStyle;
use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement};
use error_reporting::StdoutErrorReporter;
use font_metrics::FontMetricsProvider;
use keyframes::KeyframesAnimation;
use media_queries::Device;
use pdqsort::sort_by;
@ -343,7 +344,8 @@ impl Stylist {
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent: Option<&Arc<ComputedValues>>,
cascade_flags: CascadeFlags)
cascade_flags: CascadeFlags,
font_metrics: &FontMetricsProvider)
-> ComputedStyle {
debug_assert!(pseudo.is_precomputed());
@ -379,6 +381,7 @@ impl Stylist {
parent.map(|p| &**p),
None,
&StdoutErrorReporter,
font_metrics,
cascade_flags);
ComputedStyle::new(rule_node, Arc::new(computed))
}
@ -390,6 +393,8 @@ impl Stylist {
pseudo: &PseudoElement,
parent_style: &Arc<ComputedValues>)
-> Arc<ComputedValues> {
use font_metrics::ServoMetricsProvider;
// For most (but not all) pseudo-elements, we inherit all values from the parent.
let inherit_all = match *pseudo {
PseudoElement::ServoText |
@ -414,7 +419,8 @@ impl Stylist {
if inherit_all {
cascade_flags.insert(INHERIT_ALL);
}
self.precomputed_values_for_pseudo(guards, &pseudo, Some(parent_style), cascade_flags)
self.precomputed_values_for_pseudo(guards, &pseudo, Some(parent_style), cascade_flags,
&ServoMetricsProvider)
.values.unwrap()
}
@ -429,7 +435,8 @@ impl Stylist {
guards: &StylesheetGuards,
element: &E,
pseudo: &PseudoElement,
parent: &Arc<ComputedValues>)
parent: &Arc<ComputedValues>,
font_metrics: &FontMetricsProvider)
-> Option<ComputedStyle>
where E: TElement +
fmt::Debug +
@ -492,6 +499,7 @@ impl Stylist {
Some(&**parent),
None,
&StdoutErrorReporter,
font_metrics,
CascadeFlags::empty());
Some(ComputedStyle::new(rule_node, Arc::new(computed)))

View file

@ -57,9 +57,7 @@ pub struct Context<'a> {
/// A font metrics provider, used to access font metrics to implement
/// font-relative units.
///
/// TODO(emilio): This should be required, see #14079.
pub font_metrics_provider: Option<&'a FontMetricsProvider>,
pub font_metrics_provider: &'a FontMetricsProvider,
}
impl<'a> Context<'a> {

View file

@ -73,11 +73,9 @@ impl FontRelativeLength {
/// font-family list.
pub fn find_first_available_font_metrics(context: &Context) -> Option<FontMetrics> {
use font_metrics::FontMetricsQueryResult::*;
if let Some(ref metrics_provider) = context.font_metrics_provider {
for family in context.style().get_font().font_family_iter() {
if let Available(metrics) = metrics_provider.query(family.atom()) {
return metrics;
}
for family in context.style().get_font().font_family_iter() {
if let Available(metrics) = context.font_metrics_provider.query(family.atom()) {
return metrics;
}
}

View file

@ -13,6 +13,7 @@ use app_units::Au;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
use cssparser::ToCss as ParserToCss;
use euclid::size::TypedSize2D;
use font_metrics::get_metrics_provider_for_product;
use media_queries::Device;
use parser::{Parse, ParserContext, log_css_error};
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
@ -672,6 +673,8 @@ impl MaybeNew for ViewportConstraints {
// resolved against initial values
let initial_viewport = device.au_viewport_size();
let provider = get_metrics_provider_for_product();
// TODO(emilio): Stop cloning `ComputedValues` around!
let context = Context {
is_root_element: false,
@ -679,7 +682,7 @@ impl MaybeNew for ViewportConstraints {
inherited_style: device.default_computed_values(),
layout_parent_style: device.default_computed_values(),
style: device.default_computed_values().clone(),
font_metrics_provider: None, // TODO: Should have!
font_metrics_provider: &provider,
};
// DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom'

View file

@ -20,6 +20,7 @@ use style::data::{ElementData, ElementStyles, RestyleData};
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
use style::dom::{ShowSubtreeData, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::font_metrics::get_metrics_provider_for_product;
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
use style::gecko::restyle_damage::GeckoRestyleDamage;
@ -418,7 +419,8 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe
let pseudos = &styles.pseudos;
let pseudo_style = pseudo.as_ref().map(|p| (p, pseudos.get(p).unwrap()));
element.get_base_style(shared_context, &styles.primary, &pseudo_style)
let provider = get_metrics_provider_for_product();
element.get_base_style(shared_context, &provider, &styles.primary, &pseudo_style)
.into_strong()
}
@ -812,8 +814,9 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
if skip_display_fixup {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
}
let metrics = get_metrics_provider_for_product();
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
cascade_flags)
cascade_flags, &metrics)
.values.unwrap()
.into_strong()
}
@ -859,10 +862,12 @@ fn get_pseudo_style(guard: &SharedRwLockReadGuard, element: GeckoElement, pseudo
let d = doc_data.borrow_mut();
let base = styles.primary.values();
let guards = StylesheetGuards::same(guard);
let metrics = get_metrics_provider_for_product();
d.stylist.lazily_compute_pseudo_element_style(&guards,
&element,
&pseudo,
base)
base,
&metrics)
.map(|s| s.values().clone())
},
}
@ -1672,6 +1677,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
let parent_style = parent_style.as_ref().map(|r| &**ComputedValues::as_arc(&r));
let default_values = data.default_computed_values();
let metrics = get_metrics_provider_for_product();
let context = Context {
is_root_element: false,
@ -1679,7 +1685,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
inherited_style: parent_style.unwrap_or(default_values),
layout_parent_style: parent_style.unwrap_or(default_values),
style: (**style).clone(),
font_metrics_provider: None,
font_metrics_provider: &metrics,
};
for (index, keyframe) in keyframes.iter().enumerate() {

View file

@ -6,6 +6,7 @@ use cssparser::Parser;
use euclid::size::TypedSize2D;
use media_queries::CSSErrorReporterTest;
use std::f32::consts::PI;
use style::font_metrics::ServoMetricsProvider;
use style::media_queries::{Device, MediaType};
use style::parser::ParserContext;
use style::properties::ComputedValues;
@ -51,7 +52,7 @@ fn test_linear_gradient() {
inherited_style: initial_style,
layout_parent_style: initial_style,
style: initial_style.clone(),
font_metrics_provider: None,
font_metrics_provider: &ServoMetricsProvider,
};
assert_eq!(specified::AngleOrCorner::None.to_computed_value(&specified_context),
computed::AngleOrCorner::Angle(Angle::from_radians(PI)));