mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
style: Make all font-metrics-affecting properties cascade early.
And make font-size computation work on the whole font of the parent, not just accounting for the parent's font-size. Differential Revision: https://phabricator.services.mozilla.com/D20656
This commit is contained in:
parent
aa5ea337da
commit
d3f254d2e4
4 changed files with 36 additions and 38 deletions
|
@ -7,9 +7,6 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use crate::context::SharedStyleContext;
|
use crate::context::SharedStyleContext;
|
||||||
use crate::logical_geometry::WritingMode;
|
|
||||||
use crate::media_queries::Device;
|
|
||||||
use crate::properties::style_structs::Font;
|
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
|
||||||
|
@ -36,22 +33,15 @@ pub enum FontMetricsQueryResult {
|
||||||
/// A trait used to represent something capable of providing us font metrics.
|
/// A trait used to represent something capable of providing us font metrics.
|
||||||
pub trait FontMetricsProvider {
|
pub trait FontMetricsProvider {
|
||||||
/// Obtain the metrics for given font family.
|
/// Obtain the metrics for given font family.
|
||||||
///
|
|
||||||
/// TODO: We could make this take the full list, I guess, and save a few
|
|
||||||
/// virtual calls in the case we are repeatedly unable to find font metrics?
|
|
||||||
/// That is not too common in practice though.
|
|
||||||
fn query(
|
fn query(
|
||||||
&self,
|
&self,
|
||||||
_font: &Font,
|
_context: &crate::values::computed::Context,
|
||||||
_font_size: Au,
|
_base_size: crate::values::specified::length::FontBaseSize,
|
||||||
_wm: WritingMode,
|
|
||||||
_in_media_query: bool,
|
|
||||||
_device: &Device,
|
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetricsQueryResult {
|
||||||
FontMetricsQueryResult::NotAvailable
|
FontMetricsQueryResult::NotAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get default size of a given language and generic family
|
/// Get default size of a given language and generic family.
|
||||||
fn get_size(&self, font_name: &Atom, font_family: u8) -> Au;
|
fn get_size(&self, font_name: &Atom, font_family: u8) -> Au;
|
||||||
|
|
||||||
/// Construct from a shared style context
|
/// Construct from a shared style context
|
||||||
|
|
|
@ -58,10 +58,8 @@ use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
|
||||||
use crate::global_style_data::GLOBAL_STYLE_DATA;
|
use crate::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
use crate::hash::FxHashMap;
|
use crate::hash::FxHashMap;
|
||||||
use crate::invalidation::element::restyle_hints::RestyleHint;
|
use crate::invalidation::element::restyle_hints::RestyleHint;
|
||||||
use crate::logical_geometry::WritingMode;
|
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
use crate::properties::animated_properties::{AnimationValue, AnimationValueMap};
|
use crate::properties::animated_properties::{AnimationValue, AnimationValueMap};
|
||||||
use crate::properties::style_structs::Font;
|
|
||||||
use crate::properties::{ComputedValues, LonghandId};
|
use crate::properties::{ComputedValues, LonghandId};
|
||||||
use crate::properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
|
use crate::properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
use crate::rule_tree::CascadeLevel as ServoCascadeLevel;
|
use crate::rule_tree::CascadeLevel as ServoCascadeLevel;
|
||||||
|
@ -69,6 +67,7 @@ use crate::selector_parser::{AttrValue, HorizontalDirection, Lang};
|
||||||
use crate::shared_lock::Locked;
|
use crate::shared_lock::Locked;
|
||||||
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::specified::length::FontBaseSize;
|
||||||
use crate::CaseSensitivityExt;
|
use crate::CaseSensitivityExt;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
||||||
|
@ -1023,37 +1022,48 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self, font_name: &Atom, font_family: u8) -> Au {
|
fn get_size(&self, font_name: &Atom, font_family: u8) -> Au {
|
||||||
use crate::gecko_bindings::bindings::Gecko_GetBaseSize;
|
|
||||||
let mut cache = self.font_size_cache.borrow_mut();
|
let mut cache = self.font_size_cache.borrow_mut();
|
||||||
if let Some(sizes) = cache.iter().find(|el| el.0 == *font_name) {
|
if let Some(sizes) = cache.iter().find(|el| el.0 == *font_name) {
|
||||||
return sizes.1.size_for_generic(font_family);
|
return sizes.1.size_for_generic(font_family);
|
||||||
}
|
}
|
||||||
let sizes = unsafe { Gecko_GetBaseSize(font_name.as_ptr()) };
|
let sizes = unsafe { bindings::Gecko_GetBaseSize(font_name.as_ptr()) };
|
||||||
cache.push((font_name.clone(), sizes));
|
cache.push((font_name.clone(), sizes));
|
||||||
sizes.size_for_generic(font_family)
|
sizes.size_for_generic(font_family)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query(
|
fn query(
|
||||||
&self,
|
&self,
|
||||||
font: &Font,
|
context: &crate::values::computed::Context,
|
||||||
font_size: Au,
|
base_size: FontBaseSize,
|
||||||
wm: WritingMode,
|
|
||||||
in_media_query: bool,
|
|
||||||
device: &Device,
|
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetricsQueryResult {
|
||||||
use crate::gecko_bindings::bindings::Gecko_GetFontMetrics;
|
let pc = match context.device().pres_context() {
|
||||||
let pc = match device.pres_context() {
|
|
||||||
Some(pc) => pc,
|
Some(pc) => pc,
|
||||||
None => return FontMetricsQueryResult::NotAvailable,
|
None => return FontMetricsQueryResult::NotAvailable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let size = base_size.resolve(context);
|
||||||
|
let style = context.style();
|
||||||
|
|
||||||
|
let (wm, font) = match base_size {
|
||||||
|
FontBaseSize::CurrentStyle => {
|
||||||
|
(style.writing_mode, style.get_font())
|
||||||
|
},
|
||||||
|
// These are only used for font-size computation, and the first is
|
||||||
|
// really dubious...
|
||||||
|
FontBaseSize::InheritedStyleButStripEmUnits |
|
||||||
|
FontBaseSize::InheritedStyle => {
|
||||||
|
(*style.inherited_writing_mode(), style.get_parent_font())
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let gecko_metrics = unsafe {
|
let gecko_metrics = unsafe {
|
||||||
Gecko_GetFontMetrics(
|
bindings::Gecko_GetFontMetrics(
|
||||||
pc,
|
pc,
|
||||||
wm.is_vertical() && !wm.is_sideways(),
|
wm.is_vertical() && !wm.is_sideways(),
|
||||||
font.gecko(),
|
font.gecko(),
|
||||||
font_size.0,
|
size.0,
|
||||||
// we don't use the user font set in a media query
|
// we don't use the user font set in a media query
|
||||||
!in_media_query,
|
!context.in_media_query,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let metrics = FontMetrics {
|
let metrics = FontMetrics {
|
||||||
|
|
|
@ -1257,8 +1257,12 @@ impl LonghandId {
|
||||||
LonghandId::MozScriptLevel |
|
LonghandId::MozScriptLevel |
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
// Needed to compute font-relative lengths correctly.
|
// Needed to compute the first available font, in order to
|
||||||
|
// compute font-relative units correctly.
|
||||||
LonghandId::FontSize |
|
LonghandId::FontSize |
|
||||||
|
LonghandId::FontWeight |
|
||||||
|
LonghandId::FontStretch |
|
||||||
|
LonghandId::FontStyle |
|
||||||
LonghandId::FontFamily |
|
LonghandId::FontFamily |
|
||||||
|
|
||||||
// Needed to resolve currentcolor at computed value time properly.
|
// Needed to resolve currentcolor at computed value time properly.
|
||||||
|
|
|
@ -131,15 +131,9 @@ impl FontRelativeLength {
|
||||||
) -> (Au, CSSFloat) {
|
) -> (Au, CSSFloat) {
|
||||||
fn query_font_metrics(
|
fn query_font_metrics(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
reference_font_size: Au,
|
base_size: FontBaseSize,
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetricsQueryResult {
|
||||||
context.font_metrics_provider.query(
|
context.font_metrics_provider.query(context, base_size)
|
||||||
context.style().get_font(),
|
|
||||||
reference_font_size,
|
|
||||||
context.style().writing_mode,
|
|
||||||
context.in_media_query,
|
|
||||||
context.device(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let reference_font_size = base_size.resolve(context);
|
let reference_font_size = base_size.resolve(context);
|
||||||
|
@ -164,7 +158,7 @@ impl FontRelativeLength {
|
||||||
if context.for_non_inherited_property.is_some() {
|
if context.for_non_inherited_property.is_some() {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
let reference_size = match query_font_metrics(context, reference_font_size) {
|
let reference_size = match query_font_metrics(context, base_size) {
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
||||||
// https://drafts.csswg.org/css-values/#ex
|
// https://drafts.csswg.org/css-values/#ex
|
||||||
//
|
//
|
||||||
|
@ -180,7 +174,7 @@ impl FontRelativeLength {
|
||||||
if context.for_non_inherited_property.is_some() {
|
if context.for_non_inherited_property.is_some() {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
let reference_size = match query_font_metrics(context, reference_font_size) {
|
let reference_size = match query_font_metrics(context, base_size) {
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
||||||
// https://drafts.csswg.org/css-values/#ch
|
// https://drafts.csswg.org/css-values/#ch
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue