mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Auto merge of #16316 - Manishearth:stylo-threadsafe, r=emilio
stylo: Make font base size computation threadsafe r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1351200 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16316) <!-- Reviewable:end -->
This commit is contained in:
commit
d77d752990
25 changed files with 339 additions and 46 deletions
|
@ -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 {
|
||||
|
|
|
@ -14,13 +14,15 @@
|
|||
//! style system it's kind of pointless in the Stylo case, and only Servo forces
|
||||
//! the separation between the style system implementation and everything else.
|
||||
|
||||
use app_units::Au;
|
||||
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};
|
||||
use element_state::ElementState;
|
||||
use error_reporting::StdoutErrorReporter;
|
||||
use font_metrics::FontMetricsProvider;
|
||||
use gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
|
||||
use gecko::snapshot_helpers;
|
||||
|
@ -60,6 +62,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 +429,65 @@ fn get_animation_rule(element: &GeckoElement,
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Gecko font metrics provider
|
||||
pub struct GeckoFontMetricsProvider {
|
||||
/// Cache of base font sizes for each language
|
||||
///
|
||||
/// Usually will have 1 element.
|
||||
///
|
||||
// This may be slow on pages using more languages, might be worth optimizing
|
||||
// by caching lang->group mapping separately and/or using a hashmap on larger
|
||||
// loads.
|
||||
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 FontMetricsProvider for GeckoFontMetricsProvider {
|
||||
fn create_from(_: &SharedStyleContext) -> GeckoFontMetricsProvider {
|
||||
GeckoFontMetricsProvider::new()
|
||||
}
|
||||
|
||||
fn get_size(&self, font_name: &Atom, font_family: u8) -> Au {
|
||||
use gecko_bindings::bindings::Gecko_GetBaseSize;
|
||||
let mut cache = self.font_size_cache.borrow_mut();
|
||||
if let Some(sizes) = cache.iter().find(|el| el.0 == *font_name) {
|
||||
return sizes.1.size_for_generic(font_family);
|
||||
}
|
||||
let sizes = unsafe {
|
||||
Gecko_GetBaseSize(font_name.as_ptr())
|
||||
};
|
||||
cache.push((font_name.clone(), sizes));
|
||||
sizes.size_for_generic(font_family)
|
||||
}
|
||||
}
|
||||
|
||||
impl structs::FontSizePrefs {
|
||||
fn size_for_generic(&self, font_family: u8) -> Au {
|
||||
Au(match font_family {
|
||||
structs::kPresContext_DefaultVariableFont_ID => self.mDefaultVariableSize,
|
||||
structs::kPresContext_DefaultFixedFont_ID => self.mDefaultFixedSize,
|
||||
structs::kGenericFont_serif => self.mDefaultSerifSize,
|
||||
structs::kGenericFont_sans_serif => self.mDefaultSansSerifSize,
|
||||
structs::kGenericFont_monospace => self.mDefaultMonospaceSize,
|
||||
structs::kGenericFont_cursive => self.mDefaultCursiveSize,
|
||||
structs::kGenericFont_fantasy => self.mDefaultFantasySize,
|
||||
x => unreachable!("Unknown generic ID {}", x),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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)) }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue