aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <infra@servo.org>2023-05-11 21:04:45 +0200
committerGitHub <noreply@github.com>2023-05-11 21:04:45 +0200
commit9bec0d0f8e92e90b5d8c99ba691a9d9a6bb41bcc (patch)
treefbfaa73aa4702fdb2a32fe6838388189ab1d41db
parentfeaa66b5972c3e31d77c2acce7d626c455320535 (diff)
parentab2ba273e342c6f1a0c1f29cca3f551fd8926e94 (diff)
downloadservo-9bec0d0f8e92e90b5d8c99ba691a9d9a6bb41bcc.tar.gz
servo-9bec0d0f8e92e90b5d8c99ba691a9d9a6bb41bcc.zip
Auto merge of #29728 - Loirooriol:sync-fontprovider-D157589, r=mrobinson
Simplify our setup for font metric queries from style This is a backport of https://phabricator.services.mozilla.com/D157589, by Emilio Cobos Álvarez, plus some additions so that Servo compiles, and some parts from https://phabricator.services.mozilla.com/D144455. Should have no change in behavior. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because there should be no change in behavior <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
-rw-r--r--components/layout/query.rs4
-rw-r--r--components/layout/traversal.rs1
-rw-r--r--components/layout_2020/query.rs2
-rw-r--r--components/layout_2020/traversal.rs1
-rw-r--r--components/script/layout_dom/element.rs3
-rw-r--r--components/script_layout_interface/wrapper_traits.rs3
-rw-r--r--components/style/context.rs28
-rw-r--r--components/style/dom.rs7
-rw-r--r--components/style/driver.rs2
-rw-r--r--components/style/font_metrics.rs63
-rw-r--r--components/style/gecko/media_queries.rs72
-rw-r--r--components/style/gecko/wrapper.rs128
-rw-r--r--components/style/parallel.rs11
-rw-r--r--components/style/properties/cascade.rs8
-rw-r--r--components/style/servo/media_queries.rs17
-rw-r--r--components/style/style_resolver.rs1
-rw-r--r--components/style/stylesheets/viewport_rule.rs4
-rw-r--r--components/style/stylist.rs30
-rw-r--r--components/style/values/computed/mod.rs53
-rw-r--r--components/style/values/specified/font.rs34
-rw-r--r--components/style/values/specified/length.rs22
21 files changed, 172 insertions, 322 deletions
diff --git a/components/layout/query.rs b/components/layout/query.rs
index 1d4e810c23a..98a3ec662fb 100644
--- a/components/layout/query.rs
+++ b/components/layout/query.rs
@@ -856,7 +856,7 @@ where
if element.has_data() {
node.to_threadsafe().as_element().unwrap().resolved_style()
} else {
- let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
+ let mut tlc = ThreadLocalStyleContext::new();
let mut context = StyleContext {
shared: &context.style_context,
thread_local: &mut tlc,
@@ -911,7 +911,7 @@ pub fn process_resolved_style_request<'dom>(
return String::new();
}
- let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
+ let mut tlc = ThreadLocalStyleContext::new();
let mut context = StyleContext {
shared: &context.style_context,
thread_local: &mut tlc,
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index d07f76105e8..840aba5ef05 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -46,7 +46,6 @@ impl<'a, 'dom, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
where
E: TElement,
E::ConcreteNode: LayoutNode<'dom>,
- E::FontMetricsProvider: Send,
{
fn process_preorder<F>(
&self,
diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs
index 74420ae2bb5..3fd02a1597c 100644
--- a/components/layout_2020/query.rs
+++ b/components/layout_2020/query.rs
@@ -356,7 +356,7 @@ pub fn process_resolved_style_request_for_unstyled_node<'dom>(
return String::new();
}
- let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
+ let mut tlc = ThreadLocalStyleContext::new();
let mut context = StyleContext {
shared: &context.style_context,
thread_local: &mut tlc,
diff --git a/components/layout_2020/traversal.rs b/components/layout_2020/traversal.rs
index 1f73a7816f1..7ddb0e85ed4 100644
--- a/components/layout_2020/traversal.rs
+++ b/components/layout_2020/traversal.rs
@@ -34,7 +34,6 @@ impl<'a, 'dom, E> DomTraversal<E> for RecalcStyle<'a>
where
E: TElement,
E::ConcreteNode: LayoutNode<'dom>,
- E::FontMetricsProvider: Send,
{
fn process_preorder<F>(
&self,
diff --git a/components/script/layout_dom/element.rs b/components/script/layout_dom/element.rs
index 9b9f8c4790b..adbeba7e39d 100644
--- a/components/script/layout_dom/element.rs
+++ b/components/script/layout_dom/element.rs
@@ -33,7 +33,6 @@ use style::context::SharedStyleContext;
use style::data::ElementData;
use style::dom::{DomChildren, LayoutIterator, TDocument, TElement, TNode, TShadowRoot};
use style::element_state::*;
-use style::font_metrics::ServoMetricsProvider;
use style::properties::PropertyDeclarationBlock;
use style::selector_parser::{
extended_filtering, AttrValue as SelectorAttrValue, Lang, NonTSPseudoClass, PseudoElement,
@@ -169,8 +168,6 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
- type FontMetricsProvider = ServoMetricsProvider;
-
fn as_node(&self) -> ServoLayoutNode<'dom, LayoutDataType> {
ServoLayoutNode::from_layout_js(self.element.upcast())
}
diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs
index 9091a394161..8ba009a7a47 100644
--- a/components/script_layout_interface/wrapper_traits.rs
+++ b/components/script_layout_interface/wrapper_traits.rs
@@ -25,7 +25,6 @@ use style::context::SharedStyleContext;
use style::data::ElementData;
use style::dom::OpaqueNode;
use style::dom::{LayoutIterator, NodeInfo, TElement, TNode};
-use style::font_metrics::ServoMetricsProvider;
use style::properties::ComputedValues;
use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorImpl};
use style::stylist::RuleInclusion;
@@ -439,7 +438,6 @@ pub trait ThreadSafeLayoutElement<'dom>:
&context.guards,
&style_pseudo,
Some(data.styles.primary()),
- &ServoMetricsProvider,
),
PseudoElementCascadeType::Lazy => {
context
@@ -451,7 +449,6 @@ pub trait ThreadSafeLayoutElement<'dom>:
RuleInclusion::All,
data.styles.primary(),
/* is_probe = */ false,
- &ServoMetricsProvider,
/* matching_func = */ None,
)
.unwrap()
diff --git a/components/style/context.rs b/components/style/context.rs
index 21b3633f670..08fdb4d1eef 100644
--- a/components/style/context.rs
+++ b/components/style/context.rs
@@ -9,7 +9,6 @@ use crate::animation::DocumentAnimationSet;
use crate::bloom::StyleBloom;
use crate::data::{EagerPseudoStyles, ElementData};
use crate::dom::{SendElement, TElement};
-use crate::font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::structs;
use crate::parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB};
@@ -720,9 +719,6 @@ pub struct ThreadLocalStyleContext<E: TElement> {
pub selector_flags: SelectorFlagsMap<E>,
/// Statistics about the traversal.
pub statistics: PerThreadTraversalStatistics,
- /// 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,
/// A checker used to ensure that parallel.rs does not recurse indefinitely
/// even on arbitrarily deep trees. See Gecko bug 1376883.
pub stack_limit_checker: StackLimitChecker,
@@ -731,27 +727,8 @@ pub struct ThreadLocalStyleContext<E: TElement> {
}
impl<E: TElement> ThreadLocalStyleContext<E> {
- /// Creates a new `ThreadLocalStyleContext` from a shared one.
- #[cfg(feature = "servo")]
- pub fn new(shared: &SharedStyleContext) -> Self {
- ThreadLocalStyleContext {
- sharing_cache: StyleSharingCache::new(),
- rule_cache: RuleCache::new(),
- bloom_filter: StyleBloom::new(),
- tasks: SequentialTaskList(Vec::new()),
- selector_flags: SelectorFlagsMap::new(),
- statistics: PerThreadTraversalStatistics::default(),
- font_metrics_provider: E::FontMetricsProvider::create_from(shared),
- stack_limit_checker: StackLimitChecker::new(
- (STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024,
- ),
- nth_index_cache: NthIndexCache::default(),
- }
- }
-
- #[cfg(feature = "gecko")]
- /// Creates a new `ThreadLocalStyleContext` from a shared one.
- pub fn new(shared: &SharedStyleContext) -> Self {
+ /// Creates a new `ThreadLocalStyleContext`
+ pub fn new() -> Self {
ThreadLocalStyleContext {
sharing_cache: StyleSharingCache::new(),
rule_cache: RuleCache::new(),
@@ -759,7 +736,6 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
tasks: SequentialTaskList(Vec::new()),
selector_flags: SelectorFlagsMap::new(),
statistics: PerThreadTraversalStatistics::default(),
- font_metrics_provider: E::FontMetricsProvider::create_from(shared),
stack_limit_checker: StackLimitChecker::new(
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024,
),
diff --git a/components/style/dom.rs b/components/style/dom.rs
index 86c5a382891..c23b985a628 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -13,7 +13,6 @@ use crate::context::SharedStyleContext;
use crate::context::{PostAnimationTasks, UpdateAnimationsTasks};
use crate::data::ElementData;
use crate::element_state::ElementState;
-use crate::font_metrics::FontMetricsProvider;
use crate::media_queries::Device;
use crate::properties::{AnimationDeclarations, ComputedValues, PropertyDeclarationBlock};
use crate::selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl};
@@ -363,12 +362,6 @@ pub trait TElement:
/// syntax.
type TraversalChildrenIterator: Iterator<Item = Self::ConcreteNode>;
- /// Type of the font metrics provider
- ///
- /// XXXManishearth It would be better to make this a type parameter on
- /// ThreadLocalStyleContext and StyleContext
- type FontMetricsProvider: FontMetricsProvider + Send;
-
/// Get this element as a node.
fn as_node(&self) -> Self::ConcreteNode;
diff --git a/components/style/driver.rs b/components/style/driver.rs
index eab7c3a6a31..475d04269c5 100644
--- a/components/style/driver.rs
+++ b/components/style/driver.rs
@@ -91,7 +91,7 @@ where
// ThreadLocalStyleContext has not released its TLS borrow by that point,
// we'll panic on double-borrow.
let mut tls_slots = None;
- let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context());
+ let mut tlc = ThreadLocalStyleContext::new();
let mut context = StyleContext {
shared: traversal.shared_context(),
thread_local: &mut tlc,
diff --git a/components/style/font_metrics.rs b/components/style/font_metrics.rs
index db435539735..13a4e9e182b 100644
--- a/components/style/font_metrics.rs
+++ b/components/style/font_metrics.rs
@@ -6,9 +6,7 @@
#![deny(missing_docs)]
-use crate::context::SharedStyleContext;
use crate::values::computed::Length;
-use crate::Atom;
/// Represents the font metrics that style needs from a font to compute the
/// value of certain CSS units like `ex`.
@@ -47,64 +45,3 @@ pub enum FontMetricsOrientation {
/// Force getting horizontal metrics.
Horizontal,
}
-
-/// A trait used to represent something capable of providing us font metrics.
-pub trait FontMetricsProvider {
- /// Obtain the metrics for given font family.
- fn query(
- &self,
- _context: &crate::values::computed::Context,
- _base_size: crate::values::specified::length::FontBaseSize,
- _orientation: FontMetricsOrientation,
- ) -> FontMetrics {
- Default::default()
- }
-
- /// Get default size of a given language and generic family.
- fn get_size(
- &self,
- font_name: &Atom,
- font_family: crate::values::computed::font::GenericFontFamily,
- ) -> Length;
-
- /// Construct from a shared style context
- fn create_from(context: &SharedStyleContext) -> Self
- where
- Self: Sized;
-}
-
-// 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
- }
-
- fn get_size(&self, _: &Atom, _: crate::values::computed::font::GenericFontFamily) -> Length {
- unreachable!("Dummy provider should never be used to compute font size")
- }
-}
-
-// 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
-
-#[cfg(feature = "gecko")]
-/// Construct a font metrics provider for the current product
-pub fn get_metrics_provider_for_product() -> crate::gecko::wrapper::GeckoFontMetricsProvider {
- crate::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
-}
diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs
index a116121a258..08ef628f1ff 100644
--- a/components/style/gecko/media_queries.rs
+++ b/components/style/gecko/media_queries.rs
@@ -6,12 +6,14 @@
use crate::context::QuirksMode;
use crate::custom_properties::CssEnvironment;
+use crate::font_metrics::FontMetrics;
use crate::gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
use crate::gecko_bindings::bindings;
use crate::gecko_bindings::structs;
use crate::media_queries::MediaType;
use crate::properties::ComputedValues;
use crate::string_cache::Atom;
+use crate::values::computed::font::GenericFontFamily;
use crate::values::computed::Length;
use crate::values::specified::font::FONT_MEDIUM_PX;
use crate::values::{CustomIdent, KeyframesName};
@@ -50,6 +52,8 @@ pub struct Device {
/// Whether any styles computed in the document relied on the root font-size
/// by using rem units.
used_root_font_size: AtomicBool,
+ /// Whether any styles computed in the document relied on font metrics.
+ used_font_metrics: AtomicBool,
/// Whether any styles computed in the document relied on the viewport size
/// by using vw/vh/vmin/vmax units.
used_viewport_size: AtomicBool,
@@ -91,6 +95,7 @@ impl Device {
root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
body_text_color: AtomicUsize::new(prefs.mDefaultColor as usize),
used_root_font_size: AtomicBool::new(false),
+ used_font_metrics: AtomicBool::new(false),
used_viewport_size: AtomicBool::new(false),
environment: CssEnvironment,
}
@@ -157,6 +162,67 @@ impl Device {
.store(convert_rgba_to_nscolor(&color) as usize, Ordering::Relaxed)
}
+ /// Gets the base size given a generic font family and a language.
+ pub fn base_size_for_generic(&self, language: &Atom, generic: GenericFontFamily) -> Length {
+ unsafe { bindings::Gecko_GetBaseSize(self.document(), language.as_ptr(), generic) }
+ }
+
+ /// Queries font metrics
+ pub fn query_font_metrics(
+ &self,
+ vertical: bool,
+ font: &crate::properties::style_structs::Font,
+ base_size: Length,
+ in_media_query: bool,
+ retrieve_math_scales: bool,
+ ) -> FontMetrics {
+ self.used_font_metrics.store(true, Ordering::Relaxed);
+ let pc = match self.pres_context() {
+ Some(pc) => pc,
+ None => return Default::default(),
+ };
+ let gecko_metrics = unsafe {
+ bindings::Gecko_GetFontMetrics(
+ pc,
+ vertical,
+ font.gecko(),
+ base_size,
+ // we don't use the user font set in a media query
+ !in_media_query,
+ retrieve_math_scales,
+ )
+ };
+ FontMetrics {
+ x_height: Some(gecko_metrics.mXSize),
+ zero_advance_measure: if gecko_metrics.mChSize.px() >= 0. {
+ Some(gecko_metrics.mChSize)
+ } else {
+ None
+ },
+ cap_height: if gecko_metrics.mCapHeight.px() >= 0. {
+ Some(gecko_metrics.mCapHeight)
+ } else {
+ None
+ },
+ ic_width: if gecko_metrics.mIcWidth.px() >= 0. {
+ Some(gecko_metrics.mIcWidth)
+ } else {
+ None
+ },
+ ascent: gecko_metrics.mAscent,
+ script_percent_scale_down: if gecko_metrics.mScriptPercentScaleDown > 0. {
+ Some(gecko_metrics.mScriptPercentScaleDown)
+ } else {
+ None
+ },
+ script_script_percent_scale_down: if gecko_metrics.mScriptScriptPercentScaleDown > 0. {
+ Some(gecko_metrics.mScriptScriptPercentScaleDown)
+ } else {
+ None
+ },
+ }
+ }
+
/// Returns the body text color.
pub fn body_text_color(&self) -> RGBA {
convert_nscolor_to_rgba(self.body_text_color.load(Ordering::Relaxed) as u32)
@@ -196,6 +262,7 @@ impl Device {
pub fn rebuild_cached_data(&mut self) {
self.reset_computed_values();
self.used_root_font_size.store(false, Ordering::Relaxed);
+ self.used_font_metrics.store(false, Ordering::Relaxed);
self.used_viewport_size.store(false, Ordering::Relaxed);
}
@@ -287,6 +354,11 @@ impl Device {
self.used_viewport_size.load(Ordering::Relaxed)
}
+ /// Returns whether font metrics have been queried.
+ pub fn used_font_metrics(&self) -> bool {
+ self.used_font_metrics.load(Ordering::Relaxed)
+ }
+
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
let pc = match self.pres_context() {
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 78e41cf767f..7d4b4e03f73 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -20,7 +20,6 @@ use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateA
use crate::data::ElementData;
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
use crate::element_state::{DocumentState, ElementState};
-use crate::font_metrics::{FontMetrics, FontMetricsOrientation, FontMetricsProvider};
use crate::gecko::data::GeckoStyleSheet;
use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
use crate::gecko::snapshot_helpers;
@@ -67,9 +66,6 @@ use crate::selector_parser::{AttrValue, HorizontalDirection, Lang};
use crate::shared_lock::{Locked, SharedRwLock};
use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use crate::stylist::CascadeData;
-use crate::values::computed::font::GenericFontFamily;
-use crate::values::computed::Length;
-use crate::values::specified::length::FontBaseSize;
use crate::values::{AtomIdent, AtomString};
use crate::CaseSensitivityExt;
use crate::LocalName;
@@ -81,7 +77,6 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext};
use selectors::sink::Push;
use selectors::{Element, OpaqueElement};
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
-use std::cell::RefCell;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
@@ -920,131 +915,8 @@ fn get_animation_rule(
}
}
-#[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, DefaultFontSizes)>>,
-}
-
-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: GenericFontFamily) -> Length {
- 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 { bindings::Gecko_GetBaseSize(font_name.as_ptr()) };
- let size = sizes.size_for_generic(font_family);
- cache.push((font_name.clone(), sizes));
- size
- }
-
- fn query(
- &self,
- context: &crate::values::computed::Context,
- base_size: FontBaseSize,
- orientation: FontMetricsOrientation,
- ) -> FontMetrics {
- let pc = match context.device().pres_context() {
- Some(pc) => pc,
- None => return Default::default(),
- };
-
- let size = base_size.resolve(context);
- let style = context.style();
-
- let (wm, font) = match base_size {
- FontBaseSize::CurrentStyle => (style.writing_mode, style.get_font()),
- // This is only used for font-size computation.
- FontBaseSize::InheritedStyle => {
- (*style.inherited_writing_mode(), style.get_parent_font())
- },
- };
-
- let vertical_metrics = match orientation {
- FontMetricsOrientation::MatchContextPreferHorizontal => {
- wm.is_vertical() && wm.is_upright()
- },
- FontMetricsOrientation::MatchContextPreferVertical => {
- wm.is_vertical() && !wm.is_sideways()
- },
- FontMetricsOrientation::Horizontal => false,
- };
- let gecko_metrics = unsafe {
- bindings::Gecko_GetFontMetrics(
- pc,
- vertical_metrics,
- font.gecko(),
- size,
- // we don't use the user font set in a media query
- !context.in_media_query,
- )
- };
- FontMetrics {
- x_height: Some(gecko_metrics.mXSize),
- zero_advance_measure: if gecko_metrics.mChSize.px() >= 0. {
- Some(gecko_metrics.mChSize)
- } else {
- None
- },
- cap_height: if gecko_metrics.mCapHeight.px() >= 0. {
- Some(gecko_metrics.mCapHeight)
- } else {
- None
- },
- ascent: gecko_metrics.mAscent,
- }
- }
-}
-
-/// The default font sizes for generic families for a given language group.
-#[derive(Debug)]
-#[repr(C)]
-pub struct DefaultFontSizes {
- variable: Length,
- serif: Length,
- sans_serif: Length,
- monospace: Length,
- cursive: Length,
- fantasy: Length,
-}
-
-impl DefaultFontSizes {
- fn size_for_generic(&self, font_family: GenericFontFamily) -> Length {
- match font_family {
- GenericFontFamily::None => self.variable,
- GenericFontFamily::Serif => self.serif,
- GenericFontFamily::SansSerif => self.sans_serif,
- GenericFontFamily::Monospace => self.monospace,
- GenericFontFamily::Cursive => self.cursive,
- GenericFontFamily::Fantasy => self.fantasy,
- GenericFontFamily::MozEmoji => unreachable!(
- "Should never get here, since this doesn't (yet) appear on font family"
- ),
- }
- }
-}
-
impl<'le> TElement for GeckoElement<'le> {
type ConcreteNode = GeckoNode<'le>;
- type FontMetricsProvider = GeckoFontMetricsProvider;
type TraversalChildrenIterator = GeckoChildrenIterator<'le>;
fn inheritance_parent(&self) -> Option<Self> {
diff --git a/components/style/parallel.rs b/components/style/parallel.rs
index 44618ef2fc1..f03bf64fe61 100644
--- a/components/style/parallel.rs
+++ b/components/style/parallel.rs
@@ -75,14 +75,11 @@ type WorkUnit<N> = ArrayVec<SendNode<N>, WORK_UNIT_MAX>;
/// out of line so we don't allocate stack space for the entire struct
/// in the caller.
#[inline(never)]
-fn create_thread_local_context<'scope, E, D>(
- traversal: &'scope D,
- slot: &mut Option<ThreadLocalStyleContext<E>>,
-) where
+fn create_thread_local_context<'scope, E>(slot: &mut Option<ThreadLocalStyleContext<E>>)
+where
E: TElement + 'scope,
- D: DomTraversal<E>,
{
- *slot = Some(ThreadLocalStyleContext::new(traversal.shared_context()));
+ *slot = Some(ThreadLocalStyleContext::new());
}
/// A parallel top-down DOM traversal.
@@ -127,7 +124,7 @@ fn top_down_dom<'a, 'scope, E, D>(
// Scope the borrow of the TLS so that the borrow is dropped before
// a potential recursive call when we pass TailCall.
let mut tlc = tls.ensure(|slot: &mut Option<ThreadLocalStyleContext<E>>| {
- create_thread_local_context(traversal, slot)
+ create_thread_local_context(slot)
});
// Check that we're not in danger of running out of stack.
diff --git a/components/style/properties/cascade.rs b/components/style/properties/cascade.rs
index acfdfc51457..f7ab9f95fde 100644
--- a/components/style/properties/cascade.rs
+++ b/components/style/properties/cascade.rs
@@ -7,7 +7,6 @@
use crate::context::QuirksMode;
use crate::custom_properties::CustomPropertiesBuilder;
use crate::dom::TElement;
-use crate::font_metrics::FontMetricsProvider;
use crate::logical_geometry::WritingMode;
use crate::media_queries::Device;
use crate::properties::{
@@ -82,7 +81,6 @@ pub fn cascade<E>(
parent_style_ignoring_first_line: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
visited_rules: Option<&StrongRuleNode>,
- font_metrics_provider: &dyn FontMetricsProvider,
quirks_mode: QuirksMode,
rule_cache: Option<&RuleCache>,
rule_cache_conditions: &mut RuleCacheConditions,
@@ -99,7 +97,6 @@ where
parent_style,
parent_style_ignoring_first_line,
layout_parent_style,
- font_metrics_provider,
CascadeMode::Unvisited { visited_rules },
quirks_mode,
rule_cache,
@@ -197,7 +194,6 @@ fn cascade_rules<E>(
parent_style: Option<&ComputedValues>,
parent_style_ignoring_first_line: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
- font_metrics_provider: &dyn FontMetricsProvider,
cascade_mode: CascadeMode,
quirks_mode: QuirksMode,
rule_cache: Option<&RuleCache>,
@@ -220,7 +216,6 @@ where
parent_style,
parent_style_ignoring_first_line,
layout_parent_style,
- font_metrics_provider,
cascade_mode,
quirks_mode,
rule_cache,
@@ -256,7 +251,6 @@ pub fn apply_declarations<'a, E, I>(
parent_style: Option<&ComputedValues>,
parent_style_ignoring_first_line: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
- font_metrics_provider: &dyn FontMetricsProvider,
cascade_mode: CascadeMode,
quirks_mode: QuirksMode,
rule_cache: Option<&RuleCache>,
@@ -317,7 +311,6 @@ where
in_media_query: false,
for_smil_animation: false,
for_non_inherited_property: None,
- font_metrics_provider,
quirks_mode,
rule_cache_conditions: RefCell::new(rule_cache_conditions),
};
@@ -762,7 +755,6 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
visited_parent!(parent_style),
visited_parent!(parent_style_ignoring_first_line),
visited_parent!(layout_parent_style),
- self.context.font_metrics_provider,
CascadeMode::Visited { writing_mode },
self.context.quirks_mode,
// The rule cache doesn't care about caching :visited
diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs
index 17949c723d0..4b535a9b875 100644
--- a/components/style/servo/media_queries.rs
+++ b/components/style/servo/media_queries.rs
@@ -6,6 +6,7 @@
use crate::context::QuirksMode;
use crate::custom_properties::CssEnvironment;
+use crate::font_metrics::FontMetrics;
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
use crate::media_queries::media_feature_expression::RangeOrOperator;
@@ -156,6 +157,22 @@ impl Device {
self.device_pixel_ratio
}
+ /// Queries dummy font metrics for Servo. Knows nothing about fonts and does not provide
+ /// any metrics.
+ /// 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
+ pub fn query_font_metrics(
+ &self,
+ _vertical: bool,
+ _font: &crate::properties::style_structs::Font,
+ _base_size: CSSPixelLength,
+ _in_media_query: bool,
+ _retrieve_math_scales: bool,
+ ) -> FontMetrics {
+ Default::default()
+ }
+
/// Take into account a viewport rule taken from the stylesheets.
pub fn account_for_viewport_rule(&mut self, constraints: &ViewportConstraints) {
self.viewport_size = constraints.size;
diff --git a/components/style/style_resolver.rs b/components/style/style_resolver.rs
index 7c28e001403..81517f6cd64 100644
--- a/components/style/style_resolver.rs
+++ b/components/style/style_resolver.rs
@@ -351,7 +351,6 @@ where
parent_style,
parent_style,
layout_parent_style,
- &self.context.thread_local.font_metrics_provider,
Some(&self.context.thread_local.rule_cache),
&mut conditions,
);
diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs
index 9f751ece265..3353662cb4b 100644
--- a/components/style/stylesheets/viewport_rule.rs
+++ b/components/style/stylesheets/viewport_rule.rs
@@ -9,7 +9,6 @@
use crate::context::QuirksMode;
use crate::error_reporting::ContextualParseError;
-use crate::font_metrics::get_metrics_provider_for_product;
use crate::media_queries::Device;
use crate::parser::{Parse, ParserContext};
use crate::properties::StyleBuilder;
@@ -673,14 +672,11 @@ impl MaybeNew for ViewportConstraints {
// DEVICE-ADAPT § 6.2.3 Resolve non-auto lengths to pixel lengths
let initial_viewport = device.au_viewport_size();
- let provider = get_metrics_provider_for_product();
-
let mut conditions = RuleCacheConditions::default();
let context = Context {
// Note: DEVICE-ADAPT § 5. states that relative length values are
// resolved against initial values
builder: StyleBuilder::for_inheritance(device, None, None),
- font_metrics_provider: &provider,
cached_system_font: None,
in_media_query: false,
quirks_mode: quirks_mode,
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 9a2134450de..5cb40b968eb 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -8,7 +8,6 @@ use crate::applicable_declarations::{ApplicableDeclarationBlock, ApplicableDecla
use crate::context::{CascadeInputs, QuirksMode};
use crate::dom::{TElement, TShadowRoot};
use crate::element_state::{DocumentState, ElementState};
-use crate::font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
use crate::invalidation::element::invalidation_map::InvalidationMap;
@@ -662,7 +661,6 @@ impl Stylist {
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent: Option<&ComputedValues>,
- font_metrics: &dyn FontMetricsProvider,
) -> Arc<ComputedValues>
where
E: TElement,
@@ -671,13 +669,7 @@ impl Stylist {
let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
- self.precomputed_values_for_pseudo_with_rule_node::<E>(
- guards,
- pseudo,
- parent,
- font_metrics,
- rule_node,
- )
+ self.precomputed_values_for_pseudo_with_rule_node::<E>(guards, pseudo, parent, rule_node)
}
/// Computes the style for a given "precomputed" pseudo-element with
@@ -690,7 +682,6 @@ impl Stylist {
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent: Option<&ComputedValues>,
- font_metrics: &dyn FontMetricsProvider,
rules: StrongRuleNode,
) -> Arc<ComputedValues>
where
@@ -704,7 +695,6 @@ impl Stylist {
pseudo,
guards,
parent,
- font_metrics,
None,
)
}
@@ -759,13 +749,7 @@ impl Stylist {
where
E: TElement,
{
- use crate::font_metrics::ServoMetricsProvider;
- self.precomputed_values_for_pseudo::<E>(
- guards,
- &pseudo,
- Some(parent_style),
- &ServoMetricsProvider,
- )
+ self.precomputed_values_for_pseudo::<E>(guards, &pseudo, Some(parent_style))
}
/// Computes a pseudo-element style lazily during layout.
@@ -783,7 +767,6 @@ impl Stylist {
rule_inclusion: RuleInclusion,
parent_style: &ComputedValues,
is_probe: bool,
- font_metrics: &dyn FontMetricsProvider,
matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
) -> Option<Arc<ComputedValues>>
where
@@ -804,7 +787,6 @@ impl Stylist {
pseudo,
guards,
Some(parent_style),
- font_metrics,
Some(element),
))
}
@@ -819,7 +801,6 @@ impl Stylist {
pseudo: &PseudoElement,
guards: &StylesheetGuards,
parent_style: Option<&ComputedValues>,
- font_metrics: &dyn FontMetricsProvider,
element: Option<E>,
) -> Arc<ComputedValues>
where
@@ -845,7 +826,6 @@ impl Stylist {
parent_style,
parent_style,
parent_style,
- font_metrics,
/* rule_cache = */ None,
&mut RuleCacheConditions::default(),
)
@@ -872,7 +852,6 @@ impl Stylist {
parent_style: Option<&ComputedValues>,
parent_style_ignoring_first_line: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
- font_metrics: &dyn FontMetricsProvider,
rule_cache: Option<&RuleCache>,
rule_cache_conditions: &mut RuleCacheConditions,
) -> Arc<ComputedValues>
@@ -909,7 +888,6 @@ impl Stylist {
parent_style_ignoring_first_line,
layout_parent_style,
visited_rules,
- font_metrics,
self.quirks_mode,
rule_cache,
rule_cache_conditions,
@@ -1326,10 +1304,7 @@ impl Stylist {
where
E: TElement,
{
- use crate::font_metrics::get_metrics_provider_for_product;
-
let block = declarations.read_with(guards.author);
- let metrics = get_metrics_provider_for_product();
// We don't bother inserting these declarations in the rule tree, since
// it'd be quite useless and slow.
@@ -1348,7 +1323,6 @@ impl Stylist {
Some(parent_style),
Some(parent_style),
Some(parent_style),
- &metrics,
CascadeMode::Unvisited {
visited_rules: None,
},
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 1b242547307..9dbbf40b5f4 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -14,13 +14,15 @@ use super::generics::transform::IsParallelTo;
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
use super::specified;
use super::{CSSFloat, CSSInteger};
+use crate::computed_value_flags::ComputedValueFlags;
use crate::context::QuirksMode;
-use crate::font_metrics::{get_metrics_provider_for_product, FontMetricsProvider};
+use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
use crate::media_queries::Device;
#[cfg(feature = "gecko")]
use crate::properties;
use crate::properties::{ComputedValues, LonghandId, StyleBuilder};
use crate::rule_cache::RuleCacheConditions;
+use crate::values::specified::length::FontBaseSize;
use crate::{ArcSlice, Atom, One};
use euclid::{default, Point2D, Rect, Size2D};
use servo_arc::Arc;
@@ -155,10 +157,6 @@ pub struct Context<'a> {
#[cfg(feature = "servo")]
pub cached_system_font: Option<()>,
- /// A font metrics provider, used to access font metrics to implement
- /// font-relative units.
- pub font_metrics_provider: &'a dyn FontMetricsProvider,
-
/// Whether or not we are computing the media list in a media query
pub in_media_query: bool,
@@ -192,11 +190,9 @@ impl<'a> Context<'a> {
F: FnOnce(&Context) -> R,
{
let mut conditions = RuleCacheConditions::default();
- let provider = get_metrics_provider_for_product();
let context = Context {
builder: StyleBuilder::for_inheritance(device, None, None),
- font_metrics_provider: &provider,
cached_system_font: None,
in_media_query: true,
quirks_mode,
@@ -213,6 +209,49 @@ impl<'a> Context<'a> {
self.builder.device
}
+ /// Queries font metrics.
+ pub fn query_font_metrics(
+ &self,
+ base_size: FontBaseSize,
+ orientation: FontMetricsOrientation,
+ retrieve_math_scales: bool,
+ ) -> FontMetrics {
+ if self.for_non_inherited_property.is_some() {
+ self.rule_cache_conditions.borrow_mut().set_uncacheable();
+ }
+ self.builder.add_flags(match base_size {
+ FontBaseSize::CurrentStyle => ComputedValueFlags::DEPENDS_ON_SELF_FONT_METRICS,
+ FontBaseSize::InheritedStyle => ComputedValueFlags::DEPENDS_ON_INHERITED_FONT_METRICS,
+ });
+ let size = base_size.resolve(self);
+ let style = self.style();
+
+ let (wm, font) = match base_size {
+ FontBaseSize::CurrentStyle => (style.writing_mode, style.get_font()),
+ // This is only used for font-size computation.
+ FontBaseSize::InheritedStyle => {
+ (*style.inherited_writing_mode(), style.get_parent_font())
+ },
+ };
+
+ let vertical = match orientation {
+ FontMetricsOrientation::MatchContextPreferHorizontal => {
+ wm.is_vertical() && wm.is_upright()
+ },
+ FontMetricsOrientation::MatchContextPreferVertical => {
+ wm.is_vertical() && !wm.is_sideways()
+ },
+ FontMetricsOrientation::Horizontal => false,
+ };
+ self.device().query_font_metrics(
+ vertical,
+ font,
+ size,
+ self.in_media_query,
+ retrieve_math_scales,
+ )
+ }
+
/// The current viewport size, used to resolve viewport units.
pub fn viewport_size_for_viewport_unit_resolution(&self) -> default::Size2D<Au> {
self.builder
diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs
index bda757440bb..b83b6411fee 100644
--- a/components/style/values/specified/font.rs
+++ b/components/style/values/specified/font.rs
@@ -5,6 +5,8 @@
//! Specified values for font properties
#[cfg(feature = "gecko")]
+use crate::context::QuirksMode;
+#[cfg(feature = "gecko")]
use crate::gecko_bindings::bindings;
use crate::parser::{Parse, ParserContext};
use crate::properties::longhands::system_font::SystemFont;
@@ -811,8 +813,27 @@ impl FontSizeKeyword {
#[cfg(feature = "gecko")]
#[inline]
fn to_length(&self, cx: &Context) -> NonNegativeLength {
- use crate::context::QuirksMode;
+ let gecko_font = cx.style().get_font().gecko();
+ let family = &gecko_font.mFont.family.families;
+ let generic = family
+ .single_generic()
+ .unwrap_or(computed::GenericFontFamily::None);
+ let base_size = unsafe {
+ Atom::with(gecko_font.mLanguage.mRawPtr, |language| {
+ cx.device().base_size_for_generic(language, generic)
+ })
+ };
+ self.to_length_without_context(cx.quirks_mode, base_size)
+ }
+ /// Resolve a keyword length without any context, with explicit arguments.
+ #[cfg(feature = "gecko")]
+ #[inline]
+ pub fn to_length_without_context(
+ &self,
+ quirks_mode: QuirksMode,
+ base_size: Length,
+ ) -> NonNegativeLength {
// The tables in this function are originally from
// nsRuleNode::CalcFontPointSize in Gecko:
//
@@ -856,19 +877,10 @@ impl FontSizeKeyword {
];
static FONT_SIZE_FACTORS: [i32; 8] = [60, 75, 89, 100, 120, 150, 200, 300];
-
- let ref gecko_font = cx.style().get_font().gecko();
- let base_size = unsafe {
- Atom::with(gecko_font.mLanguage.mRawPtr, |atom| {
- cx.font_metrics_provider
- .get_size(atom, gecko_font.mGenericID)
- })
- };
-
let base_size_px = base_size.px().round() as i32;
let html_size = self.html_size() as usize;
NonNegative(if base_size_px >= 9 && base_size_px <= 16 {
- let mapping = if cx.quirks_mode == QuirksMode::Quirks {
+ let mapping = if quirks_mode == QuirksMode::Quirks {
QUIRKS_FONT_SIZE_MAPPING
} else {
FONT_SIZE_MAPPING
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index 62f070893a6..cf529408c98 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -7,7 +7,6 @@
//! [length]: https://drafts.csswg.org/css-values/#lengths
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
-use crate::computed_value_flags::ComputedValueFlags;
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
use crate::parser::{Parse, ParserContext};
use crate::values::computed::{self, CSSPixelLength, Context};
@@ -159,16 +158,11 @@ impl FontRelativeLength {
base_size: FontBaseSize,
orientation: FontMetricsOrientation,
) -> FontMetrics {
- context
- .font_metrics_provider
- .query(context, base_size, orientation)
+ let retrieve_math_scales = false;
+ context.query_font_metrics(base_size, orientation, retrieve_math_scales)
}
let reference_font_size = base_size.resolve(context);
- let font_metrics_flag = match base_size {
- FontBaseSize::CurrentStyle => ComputedValueFlags::DEPENDS_ON_SELF_FONT_METRICS,
- FontBaseSize::InheritedStyle => ComputedValueFlags::DEPENDS_ON_INHERITED_FONT_METRICS,
- };
match *self {
FontRelativeLength::Em(length) => {
if context.for_non_inherited_property.is_some() {
@@ -183,10 +177,6 @@ impl FontRelativeLength {
(reference_font_size, length)
},
FontRelativeLength::Ex(length) => {
- if context.for_non_inherited_property.is_some() {
- context.rule_cache_conditions.borrow_mut().set_uncacheable();
- }
- context.builder.add_flags(font_metrics_flag);
// The x-height is an intrinsically horizontal metric.
let metrics =
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
@@ -202,10 +192,6 @@ impl FontRelativeLength {
(reference_size, length)
},
FontRelativeLength::Ch(length) => {
- if context.for_non_inherited_property.is_some() {
- context.rule_cache_conditions.borrow_mut().set_uncacheable();
- }
- context.builder.add_flags(font_metrics_flag);
// https://drafts.csswg.org/css-values/#ch:
//
// Equal to the used advance measure of the “0” (ZERO,
@@ -239,10 +225,6 @@ impl FontRelativeLength {
(reference_size, length)
},
FontRelativeLength::Cap(length) => {
- if context.for_non_inherited_property.is_some() {
- context.rule_cache_conditions.borrow_mut().set_uncacheable();
- }
- context.builder.add_flags(font_metrics_flag);
let metrics =
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
let reference_size = metrics.cap_height.unwrap_or_else(|| {