Skip to content

Commit 36bbc6a

Browse files
mrobinsonmukilan
andauthored
servo: Add full support for generic font families (#50)
In order to do this, an interface is exposed so that the embedder can set a default style for a device. Signed-off-by: Martin Robinson <[email protected]> Co-authored-by: Mukilan Thiyagarajan <[email protected]>
1 parent 141446a commit 36bbc6a

File tree

5 files changed

+92
-108
lines changed

5 files changed

+92
-108
lines changed

style/properties/cascade.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -773,21 +773,18 @@ impl<'b> Cascade<'b> {
773773
self.recompute_font_size_for_zoom_change(&mut context.builder);
774774
}
775775

776+
// Compute font-family.
777+
let has_font_family = apply!(FontFamily);
778+
let has_lang = apply!(XLang);
779+
776780
#[cfg(feature = "gecko")] {
777-
// Compute font-family.
778-
let has_font_family = apply!(FontFamily);
779-
let has_lang = apply!(XLang);
780781
if has_lang {
781782
self.recompute_initial_font_family_if_needed(&mut context.builder);
782783
}
783784
if has_font_family {
784785
self.prioritize_user_fonts_if_needed(&mut context.builder);
785786
}
786787
}
787-
#[cfg(feature = "servo")] {
788-
apply!(FontFamily);
789-
apply!(XLang);
790-
}
791788

792789
// Compute font-size.
793790
#[cfg(feature = "gecko")] {
@@ -809,7 +806,12 @@ impl<'b> Cascade<'b> {
809806
}
810807
}
811808
#[cfg(feature = "servo")]
812-
apply!(FontSize);
809+
{
810+
apply!(FontSize);
811+
if has_lang || has_font_family {
812+
self.recompute_keyword_font_size_if_needed(context);
813+
}
814+
}
813815

814816
// Compute the rest of the first-available-font-affecting properties.
815817
apply!(FontWeight);
@@ -1193,7 +1195,6 @@ impl<'b> Cascade<'b> {
11931195
}
11941196

11951197
/// Some keyword sizes depend on the font family and language.
1196-
#[cfg(feature = "gecko")]
11971198
fn recompute_keyword_font_size_if_needed(&self, context: &mut computed::Context) {
11981199
use crate::values::computed::ToComputedValue;
11991200

@@ -1212,6 +1213,7 @@ impl<'b> Cascade<'b> {
12121213
},
12131214
};
12141215

1216+
#[cfg(feature = "gecko")]
12151217
if font.mScriptUnconstrainedSize == new_size.computed_size {
12161218
return;
12171219
}

style/properties/properties.mako.rs

Lines changed: 49 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,8 +1392,6 @@ pub mod style_structs {
13921392
use fxhash::FxHasher;
13931393
use super::longhands;
13941394
use std::hash::{Hash, Hasher};
1395-
use crate::media_queries::Device;
1396-
use crate::values::computed::NonNegativeLength;
13971395

13981396
% for style_struct in data.active_style_structs():
13991397
% if style_struct.name == "Font":
@@ -1522,34 +1520,24 @@ pub mod style_structs {
15221520
/// Computes a font hash in order to be able to cache fonts
15231521
/// effectively in GFX and layout.
15241522
pub fn compute_font_hash(&mut self) {
1525-
// Corresponds to the fields in
1526-
// `gfx::font_template::FontTemplateDescriptor`.
15271523
let mut hasher: FxHasher = Default::default();
15281524
self.font_weight.hash(&mut hasher);
15291525
self.font_stretch.hash(&mut hasher);
15301526
self.font_style.hash(&mut hasher);
15311527
self.font_family.hash(&mut hasher);
15321528
self.hash = hasher.finish()
15331529
}
1534-
1535-
/// (Servo does not handle MathML, so this just calls copy_font_size_from)
1536-
pub fn inherit_font_size_from(&mut self, parent: &Self,
1537-
_: Option<NonNegativeLength>,
1538-
_: &Device) {
1539-
self.copy_font_size_from(parent);
1540-
}
1541-
/// (Servo does not handle MathML, so this just calls set_font_size)
1542-
pub fn apply_font_size(&mut self,
1543-
v: longhands::font_size::computed_value::T,
1544-
_: &Self,
1545-
_: &Device) -> Option<NonNegativeLength> {
1546-
self.set_font_size(v);
1547-
None
1548-
}
1549-
/// (Servo does not handle MathML, so this does nothing)
1550-
pub fn apply_unconstrained_font_size(&mut self, _: NonNegativeLength) {
1530+
/// Create a new Font with the initial values of all members.
1531+
pub fn initial_values() -> Self {
1532+
Self {
1533+
% for longhand in style_struct.longhands:
1534+
% if not longhand.logical:
1535+
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
1536+
% endif
1537+
% endfor
1538+
hash: 0,
1539+
}
15511540
}
1552-
15531541
% elif style_struct.name == "Outline":
15541542
/// Whether the outline-width property is non-zero.
15551543
#[inline]
@@ -1952,7 +1940,45 @@ impl ComputedValues {
19521940
}
19531941

19541942
/// Get the initial computed values.
1955-
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
1943+
pub fn initial_values_with_font_override(default_font: super::style_structs::Font) -> Arc<Self> {
1944+
use crate::logical_geometry::WritingMode;
1945+
use crate::computed_value_flags::ComputedValueFlags;
1946+
use servo_arc::Arc;
1947+
use super::{ComputedValues, ComputedValuesInner, longhands, style_structs};
1948+
1949+
Arc::new(ComputedValues {
1950+
inner: ComputedValuesInner {
1951+
% for style_struct in data.active_style_structs():
1952+
% if style_struct.name == "Font":
1953+
font: Arc::new(default_font),
1954+
<% continue %>
1955+
% endif %
1956+
1957+
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
1958+
% for longhand in style_struct.longhands:
1959+
% if not longhand.logical:
1960+
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
1961+
% endif
1962+
% endfor
1963+
% if style_struct.name == "InheritedText":
1964+
text_decorations_in_effect:
1965+
crate::values::computed::text::TextDecorationsInEffect::default(),
1966+
% endif
1967+
% if style_struct.name == "Box":
1968+
original_display: longhands::display::get_initial_value(),
1969+
% endif
1970+
}),
1971+
% endfor
1972+
custom_properties: crate::custom_properties::ComputedCustomProperties::default(),
1973+
writing_mode: WritingMode::empty(),
1974+
rules: None,
1975+
visited_style: None,
1976+
effective_zoom: crate::values::computed::Zoom::ONE,
1977+
flags: ComputedValueFlags::empty(),
1978+
},
1979+
pseudo: None,
1980+
})
1981+
}
19561982

19571983
/// Converts the computed values to an Arc<> from a reference.
19581984
pub fn to_arc(&self) -> Arc<Self> {
@@ -2798,53 +2824,6 @@ impl<'a> StyleBuilder<'a> {
27982824
% endfor
27992825
}
28002826

2801-
#[cfg(feature = "servo")]
2802-
pub use self::lazy_static_module::INITIAL_SERVO_VALUES;
2803-
2804-
// Use a module to work around #[cfg] on lazy_static! not being applied to every generated item.
2805-
#[cfg(feature = "servo")]
2806-
#[allow(missing_docs)]
2807-
mod lazy_static_module {
2808-
use crate::logical_geometry::WritingMode;
2809-
use crate::computed_value_flags::ComputedValueFlags;
2810-
use servo_arc::Arc;
2811-
use super::{ComputedValues, ComputedValuesInner, longhands, style_structs};
2812-
2813-
lazy_static! {
2814-
/// The initial values for all style structs as defined by the specification.
2815-
pub static ref INITIAL_SERVO_VALUES : Arc<ComputedValues> = Arc::new(ComputedValues {
2816-
inner: ComputedValuesInner {
2817-
% for style_struct in data.active_style_structs():
2818-
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
2819-
% for longhand in style_struct.longhands:
2820-
% if not longhand.logical:
2821-
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
2822-
% endif
2823-
% endfor
2824-
% if style_struct.name == "InheritedText":
2825-
text_decorations_in_effect:
2826-
crate::values::computed::text::TextDecorationsInEffect::default(),
2827-
% endif
2828-
% if style_struct.name == "Font":
2829-
hash: 0,
2830-
% endif
2831-
% if style_struct.name == "Box":
2832-
original_display: longhands::display::get_initial_value(),
2833-
% endif
2834-
}),
2835-
% endfor
2836-
custom_properties: crate::custom_properties::ComputedCustomProperties::default(),
2837-
writing_mode: WritingMode::empty(),
2838-
rules: None,
2839-
visited_style: None,
2840-
effective_zoom: crate::values::computed::Zoom::ONE,
2841-
flags: ComputedValueFlags::empty(),
2842-
},
2843-
pseudo: None,
2844-
});
2845-
}
2846-
}
2847-
28482827
/// A per-longhand function that performs the CSS cascade for that longhand.
28492828
pub type CascadePropertyFn =
28502829
unsafe extern "Rust" fn(

style/servo/media_queries.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ use crate::media_queries::MediaType;
1414
use crate::parser::ParserContext;
1515
use crate::properties::style_structs::Font;
1616
use crate::properties::ComputedValues;
17-
use crate::values::computed::{CSSPixelLength, Context, LineHeight, NonNegativeLength, Resolution};
17+
use crate::values::computed::{CSSPixelLength, Context, Length, LineHeight, NonNegativeLength, Resolution};
18+
use crate::values::computed::font::GenericFontFamily;
1819
use crate::values::specified::font::{FONT_MEDIUM_LINE_HEIGHT_PX, FONT_MEDIUM_PX};
1920
use crate::values::specified::ViewportVariant;
2021
use crate::values::KeyframesName;
2122
use app_units::{Au, AU_PER_PX};
2223
use euclid::default::Size2D as UntypedSize2D;
2324
use euclid::{Scale, SideOffsets2D, Size2D};
2425
use mime::Mime;
26+
use servo_arc::Arc;
2527
use std::fmt::Debug;
2628
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
2729
use style_traits::{CSSPixel, DevicePixel};
@@ -38,6 +40,8 @@ pub trait FontMetricsProvider: Debug + Sync {
3840
in_media_query: bool,
3941
retrieve_math_scales: bool,
4042
) -> FontMetrics;
43+
/// Gets the base size given a generic font family.
44+
fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length;
4145
}
4246

4347
/// A device is a structure that represents the current media a given document
@@ -88,6 +92,9 @@ pub struct Device {
8892
/// An implementation of a trait which implements support for querying font metrics.
8993
#[ignore_malloc_size_of = "Owned by embedder"]
9094
font_metrics_provider: Box<dyn FontMetricsProvider>,
95+
/// The default computed values for this Device.
96+
#[ignore_malloc_size_of = "Arc is shared"]
97+
default_computed_values: Arc<ComputedValues>,
9198
}
9299

93100
impl Device {
@@ -98,13 +105,13 @@ impl Device {
98105
viewport_size: Size2D<f32, CSSPixel>,
99106
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
100107
font_metrics_provider: Box<dyn FontMetricsProvider>,
108+
default_computed_values: Arc<ComputedValues>,
101109
) -> Device {
102110
Device {
103111
media_type,
104112
viewport_size,
105113
device_pixel_ratio,
106114
quirks_mode,
107-
// FIXME(bz): Seems dubious?
108115
root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
109116
root_line_height: AtomicU32::new(FONT_MEDIUM_LINE_HEIGHT_PX.to_bits()),
110117
used_root_font_size: AtomicBool::new(false),
@@ -113,6 +120,7 @@ impl Device {
113120
used_viewport_units: AtomicBool::new(false),
114121
environment: CssEnvironment,
115122
font_metrics_provider,
123+
default_computed_values,
116124
}
117125
}
118126

@@ -124,10 +132,7 @@ impl Device {
124132

125133
/// Return the default computed values for this device.
126134
pub fn default_computed_values(&self) -> &ComputedValues {
127-
// FIXME(bz): This isn't really right, but it's no more wrong
128-
// than what we used to do. See
129-
// https://github.com/servo/servo/issues/14773 for fixing it properly.
130-
ComputedValues::initial_values()
135+
&self.default_computed_values
131136
}
132137

133138
/// Get the font size of the root element (for rem)
@@ -183,6 +188,11 @@ impl Device {
183188
// Servo doesn't implement this quirk (yet)
184189
}
185190

191+
/// Gets the base size given a generic font family.
192+
pub fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length {
193+
self.font_metrics_provider.base_size_for_generic(generic)
194+
}
195+
186196
/// Whether a given animation name may be referenced from style.
187197
pub fn animation_name_may_be_referenced(&self, _: &KeyframesName) -> bool {
188198
// Assume it is, since we don't have any good way to prove it's not.

style/values/specified/font.rs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
//! Specified values for font properties
66
7-
#[cfg(feature = "gecko")]
87
use crate::context::QuirksMode;
98
use crate::parser::{Parse, ParserContext};
109
use crate::values::computed::font::{FamilyName, FontFamilyList, SingleFontFamily};
@@ -775,50 +774,41 @@ pub const FONT_MEDIUM_PX: f32 = 16.0;
775774
pub const FONT_MEDIUM_LINE_HEIGHT_PX: f32 = FONT_MEDIUM_PX * 1.2;
776775

777776
impl FontSizeKeyword {
778-
#[inline]
779-
#[cfg(feature = "servo")]
780-
fn to_length(&self, _: &Context) -> NonNegativeLength {
781-
let medium = Length::new(FONT_MEDIUM_PX);
782-
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
783-
NonNegative(match *self {
784-
FontSizeKeyword::XXSmall => medium * 3.0 / 5.0,
785-
FontSizeKeyword::XSmall => medium * 3.0 / 4.0,
786-
FontSizeKeyword::Small => medium * 8.0 / 9.0,
787-
FontSizeKeyword::Medium => medium,
788-
FontSizeKeyword::Large => medium * 6.0 / 5.0,
789-
FontSizeKeyword::XLarge => medium * 3.0 / 2.0,
790-
FontSizeKeyword::XXLarge => medium * 2.0,
791-
FontSizeKeyword::XXXLarge => medium * 3.0,
792-
#[cfg(feature="gecko")]
793-
FontSizeKeyword::Math => unreachable!(),
794-
FontSizeKeyword::None => unreachable!(),
795-
})
796-
}
797-
798-
#[cfg(feature = "gecko")]
799777
#[inline]
800778
fn to_length(&self, cx: &Context) -> NonNegativeLength {
801779
let font = cx.style().get_font();
780+
781+
#[cfg(feature = "servo")]
782+
let family = &font.font_family.families;
783+
784+
#[cfg(feature = "gecko")]
802785
let family = &font.mFont.family.families;
786+
803787
let generic = family
804788
.single_generic()
805789
.unwrap_or(computed::GenericFontFamily::None);
790+
791+
#[cfg(feature = "gecko")]
806792
let base_size = unsafe {
807793
Atom::with(font.mLanguage.mRawPtr, |language| {
808794
cx.device().base_size_for_generic(language, generic)
809795
})
810796
};
797+
798+
#[cfg(feature = "servo")]
799+
let base_size = cx.device().base_size_for_generic(generic);
800+
811801
self.to_length_without_context(cx.quirks_mode, base_size)
812802
}
813803

814804
/// Resolve a keyword length without any context, with explicit arguments.
815-
#[cfg(feature = "gecko")]
816805
#[inline]
817806
pub fn to_length_without_context(
818807
&self,
819808
quirks_mode: QuirksMode,
820809
base_size: Length,
821810
) -> NonNegativeLength {
811+
#[cfg(feature = "gecko")]
822812
debug_assert_ne!(*self, FontSizeKeyword::Math);
823813
// The tables in this function are originally from
824814
// nsRuleNode::CalcFontPointSize in Gecko:

style_static_prefs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ macro_rules! pref {
1515
("layout.css.stylo-local-work-queue.in-worker") => {
1616
0
1717
};
18+
("layout.css.system-ui.enabled") => {
19+
true
20+
};
1821
($string:literal) => {
1922
false
2023
};

0 commit comments

Comments
 (0)