mirror of
https://github.com/servo/servo.git
synced 2025-07-25 08:10:21 +01:00
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. -->
This commit is contained in:
commit
9bec0d0f8e
21 changed files with 172 additions and 322 deletions
|
@ -856,7 +856,7 @@ where
|
||||||
if element.has_data() {
|
if element.has_data() {
|
||||||
node.to_threadsafe().as_element().unwrap().resolved_style()
|
node.to_threadsafe().as_element().unwrap().resolved_style()
|
||||||
} else {
|
} else {
|
||||||
let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
|
let mut tlc = ThreadLocalStyleContext::new();
|
||||||
let mut context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: &context.style_context,
|
shared: &context.style_context,
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
|
@ -911,7 +911,7 @@ pub fn process_resolved_style_request<'dom>(
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
|
let mut tlc = ThreadLocalStyleContext::new();
|
||||||
let mut context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: &context.style_context,
|
shared: &context.style_context,
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
|
|
|
@ -46,7 +46,6 @@ impl<'a, 'dom, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
E::ConcreteNode: LayoutNode<'dom>,
|
E::ConcreteNode: LayoutNode<'dom>,
|
||||||
E::FontMetricsProvider: Send,
|
|
||||||
{
|
{
|
||||||
fn process_preorder<F>(
|
fn process_preorder<F>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -356,7 +356,7 @@ pub fn process_resolved_style_request_for_unstyled_node<'dom>(
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tlc = ThreadLocalStyleContext::new(&context.style_context);
|
let mut tlc = ThreadLocalStyleContext::new();
|
||||||
let mut context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: &context.style_context,
|
shared: &context.style_context,
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
|
|
|
@ -34,7 +34,6 @@ impl<'a, 'dom, E> DomTraversal<E> for RecalcStyle<'a>
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
E::ConcreteNode: LayoutNode<'dom>,
|
E::ConcreteNode: LayoutNode<'dom>,
|
||||||
E::FontMetricsProvider: Send,
|
|
||||||
{
|
{
|
||||||
fn process_preorder<F>(
|
fn process_preorder<F>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -33,7 +33,6 @@ use style::context::SharedStyleContext;
|
||||||
use style::data::ElementData;
|
use style::data::ElementData;
|
||||||
use style::dom::{DomChildren, LayoutIterator, TDocument, TElement, TNode, TShadowRoot};
|
use style::dom::{DomChildren, LayoutIterator, TDocument, TElement, TNode, TShadowRoot};
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::font_metrics::ServoMetricsProvider;
|
|
||||||
use style::properties::PropertyDeclarationBlock;
|
use style::properties::PropertyDeclarationBlock;
|
||||||
use style::selector_parser::{
|
use style::selector_parser::{
|
||||||
extended_filtering, AttrValue as SelectorAttrValue, Lang, NonTSPseudoClass, PseudoElement,
|
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 ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
|
||||||
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
|
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
|
||||||
|
|
||||||
type FontMetricsProvider = ServoMetricsProvider;
|
|
||||||
|
|
||||||
fn as_node(&self) -> ServoLayoutNode<'dom, LayoutDataType> {
|
fn as_node(&self) -> ServoLayoutNode<'dom, LayoutDataType> {
|
||||||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ use style::context::SharedStyleContext;
|
||||||
use style::data::ElementData;
|
use style::data::ElementData;
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::dom::{LayoutIterator, NodeInfo, TElement, TNode};
|
use style::dom::{LayoutIterator, NodeInfo, TElement, TNode};
|
||||||
use style::font_metrics::ServoMetricsProvider;
|
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorImpl};
|
use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorImpl};
|
||||||
use style::stylist::RuleInclusion;
|
use style::stylist::RuleInclusion;
|
||||||
|
@ -439,7 +438,6 @@ pub trait ThreadSafeLayoutElement<'dom>:
|
||||||
&context.guards,
|
&context.guards,
|
||||||
&style_pseudo,
|
&style_pseudo,
|
||||||
Some(data.styles.primary()),
|
Some(data.styles.primary()),
|
||||||
&ServoMetricsProvider,
|
|
||||||
),
|
),
|
||||||
PseudoElementCascadeType::Lazy => {
|
PseudoElementCascadeType::Lazy => {
|
||||||
context
|
context
|
||||||
|
@ -451,7 +449,6 @@ pub trait ThreadSafeLayoutElement<'dom>:
|
||||||
RuleInclusion::All,
|
RuleInclusion::All,
|
||||||
data.styles.primary(),
|
data.styles.primary(),
|
||||||
/* is_probe = */ false,
|
/* is_probe = */ false,
|
||||||
&ServoMetricsProvider,
|
|
||||||
/* matching_func = */ None,
|
/* matching_func = */ None,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::animation::DocumentAnimationSet;
|
||||||
use crate::bloom::StyleBloom;
|
use crate::bloom::StyleBloom;
|
||||||
use crate::data::{EagerPseudoStyles, ElementData};
|
use crate::data::{EagerPseudoStyles, ElementData};
|
||||||
use crate::dom::{SendElement, TElement};
|
use crate::dom::{SendElement, TElement};
|
||||||
use crate::font_metrics::FontMetricsProvider;
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::gecko_bindings::structs;
|
use crate::gecko_bindings::structs;
|
||||||
use crate::parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB};
|
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>,
|
pub selector_flags: SelectorFlagsMap<E>,
|
||||||
/// Statistics about the traversal.
|
/// Statistics about the traversal.
|
||||||
pub statistics: PerThreadTraversalStatistics,
|
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
|
/// A checker used to ensure that parallel.rs does not recurse indefinitely
|
||||||
/// even on arbitrarily deep trees. See Gecko bug 1376883.
|
/// even on arbitrarily deep trees. See Gecko bug 1376883.
|
||||||
pub stack_limit_checker: StackLimitChecker,
|
pub stack_limit_checker: StackLimitChecker,
|
||||||
|
@ -731,9 +727,8 @@ pub struct ThreadLocalStyleContext<E: TElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: TElement> ThreadLocalStyleContext<E> {
|
impl<E: TElement> ThreadLocalStyleContext<E> {
|
||||||
/// Creates a new `ThreadLocalStyleContext` from a shared one.
|
/// Creates a new `ThreadLocalStyleContext`
|
||||||
#[cfg(feature = "servo")]
|
pub fn new() -> Self {
|
||||||
pub fn new(shared: &SharedStyleContext) -> Self {
|
|
||||||
ThreadLocalStyleContext {
|
ThreadLocalStyleContext {
|
||||||
sharing_cache: StyleSharingCache::new(),
|
sharing_cache: StyleSharingCache::new(),
|
||||||
rule_cache: RuleCache::new(),
|
rule_cache: RuleCache::new(),
|
||||||
|
@ -741,25 +736,6 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
|
||||||
tasks: SequentialTaskList(Vec::new()),
|
tasks: SequentialTaskList(Vec::new()),
|
||||||
selector_flags: SelectorFlagsMap::new(),
|
selector_flags: SelectorFlagsMap::new(),
|
||||||
statistics: PerThreadTraversalStatistics::default(),
|
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 {
|
|
||||||
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(
|
stack_limit_checker: StackLimitChecker::new(
|
||||||
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024,
|
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024,
|
||||||
),
|
),
|
||||||
|
|
|
@ -13,7 +13,6 @@ use crate::context::SharedStyleContext;
|
||||||
use crate::context::{PostAnimationTasks, UpdateAnimationsTasks};
|
use crate::context::{PostAnimationTasks, UpdateAnimationsTasks};
|
||||||
use crate::data::ElementData;
|
use crate::data::ElementData;
|
||||||
use crate::element_state::ElementState;
|
use crate::element_state::ElementState;
|
||||||
use crate::font_metrics::FontMetricsProvider;
|
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
use crate::properties::{AnimationDeclarations, ComputedValues, PropertyDeclarationBlock};
|
use crate::properties::{AnimationDeclarations, ComputedValues, PropertyDeclarationBlock};
|
||||||
use crate::selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl};
|
use crate::selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl};
|
||||||
|
@ -363,12 +362,6 @@ pub trait TElement:
|
||||||
/// syntax.
|
/// syntax.
|
||||||
type TraversalChildrenIterator: Iterator<Item = Self::ConcreteNode>;
|
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.
|
/// Get this element as a node.
|
||||||
fn as_node(&self) -> Self::ConcreteNode;
|
fn as_node(&self) -> Self::ConcreteNode;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ where
|
||||||
// ThreadLocalStyleContext has not released its TLS borrow by that point,
|
// ThreadLocalStyleContext has not released its TLS borrow by that point,
|
||||||
// we'll panic on double-borrow.
|
// we'll panic on double-borrow.
|
||||||
let mut tls_slots = None;
|
let mut tls_slots = None;
|
||||||
let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context());
|
let mut tlc = ThreadLocalStyleContext::new();
|
||||||
let mut context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: traversal.shared_context(),
|
shared: traversal.shared_context(),
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use crate::context::SharedStyleContext;
|
|
||||||
use crate::values::computed::Length;
|
use crate::values::computed::Length;
|
||||||
use crate::Atom;
|
|
||||||
|
|
||||||
/// Represents the font metrics that style needs from a font to compute the
|
/// Represents the font metrics that style needs from a font to compute the
|
||||||
/// value of certain CSS units like `ex`.
|
/// value of certain CSS units like `ex`.
|
||||||
|
@ -47,64 +45,3 @@ pub enum FontMetricsOrientation {
|
||||||
/// Force getting horizontal metrics.
|
/// Force getting horizontal metrics.
|
||||||
Horizontal,
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,12 +6,14 @@
|
||||||
|
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::custom_properties::CssEnvironment;
|
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::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
use crate::gecko_bindings::structs;
|
use crate::gecko_bindings::structs;
|
||||||
use crate::media_queries::MediaType;
|
use crate::media_queries::MediaType;
|
||||||
use crate::properties::ComputedValues;
|
use crate::properties::ComputedValues;
|
||||||
use crate::string_cache::Atom;
|
use crate::string_cache::Atom;
|
||||||
|
use crate::values::computed::font::GenericFontFamily;
|
||||||
use crate::values::computed::Length;
|
use crate::values::computed::Length;
|
||||||
use crate::values::specified::font::FONT_MEDIUM_PX;
|
use crate::values::specified::font::FONT_MEDIUM_PX;
|
||||||
use crate::values::{CustomIdent, KeyframesName};
|
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
|
/// Whether any styles computed in the document relied on the root font-size
|
||||||
/// by using rem units.
|
/// by using rem units.
|
||||||
used_root_font_size: AtomicBool,
|
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
|
/// Whether any styles computed in the document relied on the viewport size
|
||||||
/// by using vw/vh/vmin/vmax units.
|
/// by using vw/vh/vmin/vmax units.
|
||||||
used_viewport_size: AtomicBool,
|
used_viewport_size: AtomicBool,
|
||||||
|
@ -91,6 +95,7 @@ impl Device {
|
||||||
root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
|
root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
|
||||||
body_text_color: AtomicUsize::new(prefs.mDefaultColor as usize),
|
body_text_color: AtomicUsize::new(prefs.mDefaultColor as usize),
|
||||||
used_root_font_size: AtomicBool::new(false),
|
used_root_font_size: AtomicBool::new(false),
|
||||||
|
used_font_metrics: AtomicBool::new(false),
|
||||||
used_viewport_size: AtomicBool::new(false),
|
used_viewport_size: AtomicBool::new(false),
|
||||||
environment: CssEnvironment,
|
environment: CssEnvironment,
|
||||||
}
|
}
|
||||||
|
@ -157,6 +162,67 @@ impl Device {
|
||||||
.store(convert_rgba_to_nscolor(&color) as usize, Ordering::Relaxed)
|
.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.
|
/// Returns the body text color.
|
||||||
pub fn body_text_color(&self) -> RGBA {
|
pub fn body_text_color(&self) -> RGBA {
|
||||||
convert_nscolor_to_rgba(self.body_text_color.load(Ordering::Relaxed) as u32)
|
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) {
|
pub fn rebuild_cached_data(&mut self) {
|
||||||
self.reset_computed_values();
|
self.reset_computed_values();
|
||||||
self.used_root_font_size.store(false, Ordering::Relaxed);
|
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);
|
self.used_viewport_size.store(false, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +354,11 @@ impl Device {
|
||||||
self.used_viewport_size.load(Ordering::Relaxed)
|
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.
|
/// Returns the device pixel ratio.
|
||||||
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||||
let pc = match self.pres_context() {
|
let pc = match self.pres_context() {
|
||||||
|
|
|
@ -20,7 +20,6 @@ use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateA
|
||||||
use crate::data::ElementData;
|
use crate::data::ElementData;
|
||||||
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
|
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
|
||||||
use crate::element_state::{DocumentState, ElementState};
|
use crate::element_state::{DocumentState, ElementState};
|
||||||
use crate::font_metrics::{FontMetrics, FontMetricsOrientation, FontMetricsProvider};
|
|
||||||
use crate::gecko::data::GeckoStyleSheet;
|
use crate::gecko::data::GeckoStyleSheet;
|
||||||
use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
||||||
use crate::gecko::snapshot_helpers;
|
use crate::gecko::snapshot_helpers;
|
||||||
|
@ -67,9 +66,6 @@ use crate::selector_parser::{AttrValue, HorizontalDirection, Lang};
|
||||||
use crate::shared_lock::{Locked, SharedRwLock};
|
use crate::shared_lock::{Locked, SharedRwLock};
|
||||||
use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
||||||
use crate::stylist::CascadeData;
|
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::values::{AtomIdent, AtomString};
|
||||||
use crate::CaseSensitivityExt;
|
use crate::CaseSensitivityExt;
|
||||||
use crate::LocalName;
|
use crate::LocalName;
|
||||||
|
@ -81,7 +77,6 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext};
|
||||||
use selectors::sink::Push;
|
use selectors::sink::Push;
|
||||||
use selectors::{Element, OpaqueElement};
|
use selectors::{Element, OpaqueElement};
|
||||||
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
|
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::mem;
|
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> {
|
impl<'le> TElement for GeckoElement<'le> {
|
||||||
type ConcreteNode = GeckoNode<'le>;
|
type ConcreteNode = GeckoNode<'le>;
|
||||||
type FontMetricsProvider = GeckoFontMetricsProvider;
|
|
||||||
type TraversalChildrenIterator = GeckoChildrenIterator<'le>;
|
type TraversalChildrenIterator = GeckoChildrenIterator<'le>;
|
||||||
|
|
||||||
fn inheritance_parent(&self) -> Option<Self> {
|
fn inheritance_parent(&self) -> Option<Self> {
|
||||||
|
|
|
@ -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
|
/// out of line so we don't allocate stack space for the entire struct
|
||||||
/// in the caller.
|
/// in the caller.
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn create_thread_local_context<'scope, E, D>(
|
fn create_thread_local_context<'scope, E>(slot: &mut Option<ThreadLocalStyleContext<E>>)
|
||||||
traversal: &'scope D,
|
where
|
||||||
slot: &mut Option<ThreadLocalStyleContext<E>>,
|
|
||||||
) where
|
|
||||||
E: TElement + 'scope,
|
E: TElement + 'scope,
|
||||||
D: DomTraversal<E>,
|
|
||||||
{
|
{
|
||||||
*slot = Some(ThreadLocalStyleContext::new(traversal.shared_context()));
|
*slot = Some(ThreadLocalStyleContext::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A parallel top-down DOM traversal.
|
/// 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
|
// Scope the borrow of the TLS so that the borrow is dropped before
|
||||||
// a potential recursive call when we pass TailCall.
|
// a potential recursive call when we pass TailCall.
|
||||||
let mut tlc = tls.ensure(|slot: &mut Option<ThreadLocalStyleContext<E>>| {
|
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.
|
// Check that we're not in danger of running out of stack.
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::custom_properties::CustomPropertiesBuilder;
|
use crate::custom_properties::CustomPropertiesBuilder;
|
||||||
use crate::dom::TElement;
|
use crate::dom::TElement;
|
||||||
use crate::font_metrics::FontMetricsProvider;
|
|
||||||
use crate::logical_geometry::WritingMode;
|
use crate::logical_geometry::WritingMode;
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
use crate::properties::{
|
use crate::properties::{
|
||||||
|
@ -82,7 +81,6 @@ pub fn cascade<E>(
|
||||||
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
||||||
layout_parent_style: Option<&ComputedValues>,
|
layout_parent_style: Option<&ComputedValues>,
|
||||||
visited_rules: Option<&StrongRuleNode>,
|
visited_rules: Option<&StrongRuleNode>,
|
||||||
font_metrics_provider: &dyn FontMetricsProvider,
|
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
rule_cache: Option<&RuleCache>,
|
rule_cache: Option<&RuleCache>,
|
||||||
rule_cache_conditions: &mut RuleCacheConditions,
|
rule_cache_conditions: &mut RuleCacheConditions,
|
||||||
|
@ -99,7 +97,6 @@ where
|
||||||
parent_style,
|
parent_style,
|
||||||
parent_style_ignoring_first_line,
|
parent_style_ignoring_first_line,
|
||||||
layout_parent_style,
|
layout_parent_style,
|
||||||
font_metrics_provider,
|
|
||||||
CascadeMode::Unvisited { visited_rules },
|
CascadeMode::Unvisited { visited_rules },
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
rule_cache,
|
rule_cache,
|
||||||
|
@ -197,7 +194,6 @@ fn cascade_rules<E>(
|
||||||
parent_style: Option<&ComputedValues>,
|
parent_style: Option<&ComputedValues>,
|
||||||
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
||||||
layout_parent_style: Option<&ComputedValues>,
|
layout_parent_style: Option<&ComputedValues>,
|
||||||
font_metrics_provider: &dyn FontMetricsProvider,
|
|
||||||
cascade_mode: CascadeMode,
|
cascade_mode: CascadeMode,
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
rule_cache: Option<&RuleCache>,
|
rule_cache: Option<&RuleCache>,
|
||||||
|
@ -220,7 +216,6 @@ where
|
||||||
parent_style,
|
parent_style,
|
||||||
parent_style_ignoring_first_line,
|
parent_style_ignoring_first_line,
|
||||||
layout_parent_style,
|
layout_parent_style,
|
||||||
font_metrics_provider,
|
|
||||||
cascade_mode,
|
cascade_mode,
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
rule_cache,
|
rule_cache,
|
||||||
|
@ -256,7 +251,6 @@ pub fn apply_declarations<'a, E, I>(
|
||||||
parent_style: Option<&ComputedValues>,
|
parent_style: Option<&ComputedValues>,
|
||||||
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
||||||
layout_parent_style: Option<&ComputedValues>,
|
layout_parent_style: Option<&ComputedValues>,
|
||||||
font_metrics_provider: &dyn FontMetricsProvider,
|
|
||||||
cascade_mode: CascadeMode,
|
cascade_mode: CascadeMode,
|
||||||
quirks_mode: QuirksMode,
|
quirks_mode: QuirksMode,
|
||||||
rule_cache: Option<&RuleCache>,
|
rule_cache: Option<&RuleCache>,
|
||||||
|
@ -317,7 +311,6 @@ where
|
||||||
in_media_query: false,
|
in_media_query: false,
|
||||||
for_smil_animation: false,
|
for_smil_animation: false,
|
||||||
for_non_inherited_property: None,
|
for_non_inherited_property: None,
|
||||||
font_metrics_provider,
|
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
rule_cache_conditions: RefCell::new(rule_cache_conditions),
|
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),
|
||||||
visited_parent!(parent_style_ignoring_first_line),
|
visited_parent!(parent_style_ignoring_first_line),
|
||||||
visited_parent!(layout_parent_style),
|
visited_parent!(layout_parent_style),
|
||||||
self.context.font_metrics_provider,
|
|
||||||
CascadeMode::Visited { writing_mode },
|
CascadeMode::Visited { writing_mode },
|
||||||
self.context.quirks_mode,
|
self.context.quirks_mode,
|
||||||
// The rule cache doesn't care about caching :visited
|
// The rule cache doesn't care about caching :visited
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::custom_properties::CssEnvironment;
|
use crate::custom_properties::CssEnvironment;
|
||||||
|
use crate::font_metrics::FontMetrics;
|
||||||
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
|
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
|
||||||
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
|
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
|
||||||
use crate::media_queries::media_feature_expression::RangeOrOperator;
|
use crate::media_queries::media_feature_expression::RangeOrOperator;
|
||||||
|
@ -156,6 +157,22 @@ impl Device {
|
||||||
self.device_pixel_ratio
|
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.
|
/// Take into account a viewport rule taken from the stylesheets.
|
||||||
pub fn account_for_viewport_rule(&mut self, constraints: &ViewportConstraints) {
|
pub fn account_for_viewport_rule(&mut self, constraints: &ViewportConstraints) {
|
||||||
self.viewport_size = constraints.size;
|
self.viewport_size = constraints.size;
|
||||||
|
|
|
@ -351,7 +351,6 @@ where
|
||||||
parent_style,
|
parent_style,
|
||||||
parent_style,
|
parent_style,
|
||||||
layout_parent_style,
|
layout_parent_style,
|
||||||
&self.context.thread_local.font_metrics_provider,
|
|
||||||
Some(&self.context.thread_local.rule_cache),
|
Some(&self.context.thread_local.rule_cache),
|
||||||
&mut conditions,
|
&mut conditions,
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::error_reporting::ContextualParseError;
|
use crate::error_reporting::ContextualParseError;
|
||||||
use crate::font_metrics::get_metrics_provider_for_product;
|
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::properties::StyleBuilder;
|
use crate::properties::StyleBuilder;
|
||||||
|
@ -673,14 +672,11 @@ impl MaybeNew for ViewportConstraints {
|
||||||
// DEVICE-ADAPT § 6.2.3 Resolve non-auto lengths to pixel lengths
|
// DEVICE-ADAPT § 6.2.3 Resolve non-auto lengths to pixel lengths
|
||||||
let initial_viewport = device.au_viewport_size();
|
let initial_viewport = device.au_viewport_size();
|
||||||
|
|
||||||
let provider = get_metrics_provider_for_product();
|
|
||||||
|
|
||||||
let mut conditions = RuleCacheConditions::default();
|
let mut conditions = RuleCacheConditions::default();
|
||||||
let context = Context {
|
let context = Context {
|
||||||
// Note: DEVICE-ADAPT § 5. states that relative length values are
|
// Note: DEVICE-ADAPT § 5. states that relative length values are
|
||||||
// resolved against initial values
|
// resolved against initial values
|
||||||
builder: StyleBuilder::for_inheritance(device, None, None),
|
builder: StyleBuilder::for_inheritance(device, None, None),
|
||||||
font_metrics_provider: &provider,
|
|
||||||
cached_system_font: None,
|
cached_system_font: None,
|
||||||
in_media_query: false,
|
in_media_query: false,
|
||||||
quirks_mode: quirks_mode,
|
quirks_mode: quirks_mode,
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::applicable_declarations::{ApplicableDeclarationBlock, ApplicableDecla
|
||||||
use crate::context::{CascadeInputs, QuirksMode};
|
use crate::context::{CascadeInputs, QuirksMode};
|
||||||
use crate::dom::{TElement, TShadowRoot};
|
use crate::dom::{TElement, TShadowRoot};
|
||||||
use crate::element_state::{DocumentState, ElementState};
|
use crate::element_state::{DocumentState, ElementState};
|
||||||
use crate::font_metrics::FontMetricsProvider;
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
|
use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
|
||||||
use crate::invalidation::element::invalidation_map::InvalidationMap;
|
use crate::invalidation::element::invalidation_map::InvalidationMap;
|
||||||
|
@ -662,7 +661,6 @@ impl Stylist {
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
pseudo: &PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
parent: Option<&ComputedValues>,
|
parent: Option<&ComputedValues>,
|
||||||
font_metrics: &dyn FontMetricsProvider,
|
|
||||||
) -> Arc<ComputedValues>
|
) -> Arc<ComputedValues>
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
|
@ -671,13 +669,7 @@ impl Stylist {
|
||||||
|
|
||||||
let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
|
let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
|
||||||
|
|
||||||
self.precomputed_values_for_pseudo_with_rule_node::<E>(
|
self.precomputed_values_for_pseudo_with_rule_node::<E>(guards, pseudo, parent, rule_node)
|
||||||
guards,
|
|
||||||
pseudo,
|
|
||||||
parent,
|
|
||||||
font_metrics,
|
|
||||||
rule_node,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the style for a given "precomputed" pseudo-element with
|
/// Computes the style for a given "precomputed" pseudo-element with
|
||||||
|
@ -690,7 +682,6 @@ impl Stylist {
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
pseudo: &PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
parent: Option<&ComputedValues>,
|
parent: Option<&ComputedValues>,
|
||||||
font_metrics: &dyn FontMetricsProvider,
|
|
||||||
rules: StrongRuleNode,
|
rules: StrongRuleNode,
|
||||||
) -> Arc<ComputedValues>
|
) -> Arc<ComputedValues>
|
||||||
where
|
where
|
||||||
|
@ -704,7 +695,6 @@ impl Stylist {
|
||||||
pseudo,
|
pseudo,
|
||||||
guards,
|
guards,
|
||||||
parent,
|
parent,
|
||||||
font_metrics,
|
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -759,13 +749,7 @@ impl Stylist {
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
{
|
{
|
||||||
use crate::font_metrics::ServoMetricsProvider;
|
self.precomputed_values_for_pseudo::<E>(guards, &pseudo, Some(parent_style))
|
||||||
self.precomputed_values_for_pseudo::<E>(
|
|
||||||
guards,
|
|
||||||
&pseudo,
|
|
||||||
Some(parent_style),
|
|
||||||
&ServoMetricsProvider,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a pseudo-element style lazily during layout.
|
/// Computes a pseudo-element style lazily during layout.
|
||||||
|
@ -783,7 +767,6 @@ impl Stylist {
|
||||||
rule_inclusion: RuleInclusion,
|
rule_inclusion: RuleInclusion,
|
||||||
parent_style: &ComputedValues,
|
parent_style: &ComputedValues,
|
||||||
is_probe: bool,
|
is_probe: bool,
|
||||||
font_metrics: &dyn FontMetricsProvider,
|
|
||||||
matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
|
matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
|
||||||
) -> Option<Arc<ComputedValues>>
|
) -> Option<Arc<ComputedValues>>
|
||||||
where
|
where
|
||||||
|
@ -804,7 +787,6 @@ impl Stylist {
|
||||||
pseudo,
|
pseudo,
|
||||||
guards,
|
guards,
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
font_metrics,
|
|
||||||
Some(element),
|
Some(element),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -819,7 +801,6 @@ impl Stylist {
|
||||||
pseudo: &PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
parent_style: Option<&ComputedValues>,
|
parent_style: Option<&ComputedValues>,
|
||||||
font_metrics: &dyn FontMetricsProvider,
|
|
||||||
element: Option<E>,
|
element: Option<E>,
|
||||||
) -> Arc<ComputedValues>
|
) -> Arc<ComputedValues>
|
||||||
where
|
where
|
||||||
|
@ -845,7 +826,6 @@ impl Stylist {
|
||||||
parent_style,
|
parent_style,
|
||||||
parent_style,
|
parent_style,
|
||||||
parent_style,
|
parent_style,
|
||||||
font_metrics,
|
|
||||||
/* rule_cache = */ None,
|
/* rule_cache = */ None,
|
||||||
&mut RuleCacheConditions::default(),
|
&mut RuleCacheConditions::default(),
|
||||||
)
|
)
|
||||||
|
@ -872,7 +852,6 @@ impl Stylist {
|
||||||
parent_style: Option<&ComputedValues>,
|
parent_style: Option<&ComputedValues>,
|
||||||
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
parent_style_ignoring_first_line: Option<&ComputedValues>,
|
||||||
layout_parent_style: Option<&ComputedValues>,
|
layout_parent_style: Option<&ComputedValues>,
|
||||||
font_metrics: &dyn FontMetricsProvider,
|
|
||||||
rule_cache: Option<&RuleCache>,
|
rule_cache: Option<&RuleCache>,
|
||||||
rule_cache_conditions: &mut RuleCacheConditions,
|
rule_cache_conditions: &mut RuleCacheConditions,
|
||||||
) -> Arc<ComputedValues>
|
) -> Arc<ComputedValues>
|
||||||
|
@ -909,7 +888,6 @@ impl Stylist {
|
||||||
parent_style_ignoring_first_line,
|
parent_style_ignoring_first_line,
|
||||||
layout_parent_style,
|
layout_parent_style,
|
||||||
visited_rules,
|
visited_rules,
|
||||||
font_metrics,
|
|
||||||
self.quirks_mode,
|
self.quirks_mode,
|
||||||
rule_cache,
|
rule_cache,
|
||||||
rule_cache_conditions,
|
rule_cache_conditions,
|
||||||
|
@ -1326,10 +1304,7 @@ impl Stylist {
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
{
|
{
|
||||||
use crate::font_metrics::get_metrics_provider_for_product;
|
|
||||||
|
|
||||||
let block = declarations.read_with(guards.author);
|
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
|
// We don't bother inserting these declarations in the rule tree, since
|
||||||
// it'd be quite useless and slow.
|
// it'd be quite useless and slow.
|
||||||
|
@ -1348,7 +1323,6 @@ impl Stylist {
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
&metrics,
|
|
||||||
CascadeMode::Unvisited {
|
CascadeMode::Unvisited {
|
||||||
visited_rules: None,
|
visited_rules: None,
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,13 +14,15 @@ use super::generics::transform::IsParallelTo;
|
||||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
|
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
|
||||||
use super::specified;
|
use super::specified;
|
||||||
use super::{CSSFloat, CSSInteger};
|
use super::{CSSFloat, CSSInteger};
|
||||||
|
use crate::computed_value_flags::ComputedValueFlags;
|
||||||
use crate::context::QuirksMode;
|
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;
|
use crate::media_queries::Device;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::properties;
|
use crate::properties;
|
||||||
use crate::properties::{ComputedValues, LonghandId, StyleBuilder};
|
use crate::properties::{ComputedValues, LonghandId, StyleBuilder};
|
||||||
use crate::rule_cache::RuleCacheConditions;
|
use crate::rule_cache::RuleCacheConditions;
|
||||||
|
use crate::values::specified::length::FontBaseSize;
|
||||||
use crate::{ArcSlice, Atom, One};
|
use crate::{ArcSlice, Atom, One};
|
||||||
use euclid::{default, Point2D, Rect, Size2D};
|
use euclid::{default, Point2D, Rect, Size2D};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
|
@ -155,10 +157,6 @@ pub struct Context<'a> {
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
pub cached_system_font: Option<()>,
|
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
|
/// Whether or not we are computing the media list in a media query
|
||||||
pub in_media_query: bool,
|
pub in_media_query: bool,
|
||||||
|
|
||||||
|
@ -192,11 +190,9 @@ impl<'a> Context<'a> {
|
||||||
F: FnOnce(&Context) -> R,
|
F: FnOnce(&Context) -> R,
|
||||||
{
|
{
|
||||||
let mut conditions = RuleCacheConditions::default();
|
let mut conditions = RuleCacheConditions::default();
|
||||||
let provider = get_metrics_provider_for_product();
|
|
||||||
|
|
||||||
let context = Context {
|
let context = Context {
|
||||||
builder: StyleBuilder::for_inheritance(device, None, None),
|
builder: StyleBuilder::for_inheritance(device, None, None),
|
||||||
font_metrics_provider: &provider,
|
|
||||||
cached_system_font: None,
|
cached_system_font: None,
|
||||||
in_media_query: true,
|
in_media_query: true,
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
|
@ -213,6 +209,49 @@ impl<'a> Context<'a> {
|
||||||
self.builder.device
|
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.
|
/// The current viewport size, used to resolve viewport units.
|
||||||
pub fn viewport_size_for_viewport_unit_resolution(&self) -> default::Size2D<Au> {
|
pub fn viewport_size_for_viewport_unit_resolution(&self) -> default::Size2D<Au> {
|
||||||
self.builder
|
self.builder
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
//! Specified values for font properties
|
//! Specified values for font properties
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use crate::context::QuirksMode;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
|
@ -811,8 +813,27 @@ impl FontSizeKeyword {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_length(&self, cx: &Context) -> NonNegativeLength {
|
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
|
// The tables in this function are originally from
|
||||||
// nsRuleNode::CalcFontPointSize in Gecko:
|
// nsRuleNode::CalcFontPointSize in Gecko:
|
||||||
//
|
//
|
||||||
|
@ -856,19 +877,10 @@ impl FontSizeKeyword {
|
||||||
];
|
];
|
||||||
|
|
||||||
static FONT_SIZE_FACTORS: [i32; 8] = [60, 75, 89, 100, 120, 150, 200, 300];
|
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 base_size_px = base_size.px().round() as i32;
|
||||||
let html_size = self.html_size() as usize;
|
let html_size = self.html_size() as usize;
|
||||||
NonNegative(if base_size_px >= 9 && base_size_px <= 16 {
|
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
|
QUIRKS_FONT_SIZE_MAPPING
|
||||||
} else {
|
} else {
|
||||||
FONT_SIZE_MAPPING
|
FONT_SIZE_MAPPING
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
||||||
|
|
||||||
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
||||||
use crate::computed_value_flags::ComputedValueFlags;
|
|
||||||
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
|
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::values::computed::{self, CSSPixelLength, Context};
|
use crate::values::computed::{self, CSSPixelLength, Context};
|
||||||
|
@ -159,16 +158,11 @@ impl FontRelativeLength {
|
||||||
base_size: FontBaseSize,
|
base_size: FontBaseSize,
|
||||||
orientation: FontMetricsOrientation,
|
orientation: FontMetricsOrientation,
|
||||||
) -> FontMetrics {
|
) -> FontMetrics {
|
||||||
context
|
let retrieve_math_scales = false;
|
||||||
.font_metrics_provider
|
context.query_font_metrics(base_size, orientation, retrieve_math_scales)
|
||||||
.query(context, base_size, orientation)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let reference_font_size = base_size.resolve(context);
|
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 {
|
match *self {
|
||||||
FontRelativeLength::Em(length) => {
|
FontRelativeLength::Em(length) => {
|
||||||
if context.for_non_inherited_property.is_some() {
|
if context.for_non_inherited_property.is_some() {
|
||||||
|
@ -183,10 +177,6 @@ impl FontRelativeLength {
|
||||||
(reference_font_size, length)
|
(reference_font_size, length)
|
||||||
},
|
},
|
||||||
FontRelativeLength::Ex(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.
|
// The x-height is an intrinsically horizontal metric.
|
||||||
let metrics =
|
let metrics =
|
||||||
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
||||||
|
@ -202,10 +192,6 @@ impl FontRelativeLength {
|
||||||
(reference_size, length)
|
(reference_size, length)
|
||||||
},
|
},
|
||||||
FontRelativeLength::Ch(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:
|
// https://drafts.csswg.org/css-values/#ch:
|
||||||
//
|
//
|
||||||
// Equal to the used advance measure of the “0” (ZERO,
|
// Equal to the used advance measure of the “0” (ZERO,
|
||||||
|
@ -239,10 +225,6 @@ impl FontRelativeLength {
|
||||||
(reference_size, length)
|
(reference_size, length)
|
||||||
},
|
},
|
||||||
FontRelativeLength::Cap(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 =
|
let metrics =
|
||||||
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
||||||
let reference_size = metrics.cap_height.unwrap_or_else(|| {
|
let reference_size = metrics.cap_height.unwrap_or_else(|| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue