diff --git a/Cargo.lock b/Cargo.lock index ff3094ecbd4..b02b5552592 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1288,7 +1288,7 @@ dependencies = [ [[package]] name = "derive_common" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "darling", "proc-macro2", @@ -1838,6 +1838,7 @@ dependencies = [ "servo_allocator", "servo_arc", "servo_atoms", + "servo_config", "servo_url", "smallvec", "style", @@ -3755,7 +3756,7 @@ dependencies = [ [[package]] name = "malloc_size_of" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "accountable-refcell", "app_units", @@ -5405,7 +5406,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.24.0" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "bitflags 2.6.0", "cssparser", @@ -5693,7 +5694,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "nodrop", "serde", @@ -5703,7 +5704,7 @@ dependencies = [ [[package]] name = "servo_atoms" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "string_cache", "string_cache_codegen", @@ -5890,7 +5891,7 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "size_of_test" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "static_assertions", ] @@ -6031,7 +6032,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "static_prefs" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" [[package]] name = "strict-num" @@ -6068,7 +6069,7 @@ dependencies = [ [[package]] name = "style" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "app_units", "arrayvec", @@ -6126,7 +6127,7 @@ dependencies = [ [[package]] name = "style_config" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "lazy_static", ] @@ -6134,7 +6135,7 @@ dependencies = [ [[package]] name = "style_derive" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "darling", "derive_common", @@ -6165,7 +6166,7 @@ dependencies = [ [[package]] name = "style_traits" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "app_units", "bitflags 2.6.0", @@ -6515,7 +6516,7 @@ dependencies = [ [[package]] name = "to_shmem" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "cssparser", "servo_arc", @@ -6528,7 +6529,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab" +source = "git+https://github.com/servo/stylo?branch=2024-05-31#36bbc6a977f6f16383ea22f2b1215b10f461a7a1" dependencies = [ "darling", "derive_common", diff --git a/components/config/prefs.rs b/components/config/prefs.rs index c758e0cfe8a..0780dcd9536 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -165,6 +165,14 @@ mod gen { std::cmp::max(num_cpus::get() * 3 / 4, 1) as i64 } + fn default_font_size() -> i64 { + 16 + } + + fn default_monospace_font_size() -> i64 { + 13 + } + fn black() -> i64 { 0x000000 } @@ -188,6 +196,23 @@ mod gen { foreground_color: i64, } }, + fonts: { + #[serde(default)] + default: String, + #[serde(default)] + serif: String, + #[serde(default)] + #[serde(rename = "fonts.sans-serif")] + sans_serif: String, + #[serde(default)] + monospace: String, + #[serde(default = "default_font_size")] + #[serde(rename = "fonts.default-size")] + default_size: i64, + #[serde(default = "default_monospace_font_size")] + #[serde(rename = "fonts.default-monospace-size")] + default_monospace_size: i64, + }, css: { animations: { testing: { diff --git a/components/fonts/Cargo.toml b/components/fonts/Cargo.toml index e8a165c0524..a0301ceaad8 100644 --- a/components/fonts/Cargo.toml +++ b/components/fonts/Cargo.toml @@ -36,6 +36,7 @@ range = { path = "../range" } serde = { workspace = true } servo_arc = { workspace = true } servo_atoms = { workspace = true } +servo_config = { path = "../config" } servo_url = { path = "../url" } smallvec = { workspace = true, features = ["union"] } surfman = { workspace = true } diff --git a/components/fonts/font.rs b/components/fonts/font.rs index 918186ecc0c..dd3cbe7d2cc 100644 --- a/components/fonts/font.rs +++ b/components/fonts/font.rs @@ -16,11 +16,12 @@ use log::debug; use malloc_size_of_derive::MallocSizeOf; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; -use servo_atoms::{atom, Atom}; use smallvec::SmallVec; use style::computed_values::font_variant_caps; use style::properties::style_structs::Font as FontStyleStruct; -use style::values::computed::font::{GenericFontFamily, SingleFontFamily}; +use style::values::computed::font::{ + FamilyName, FontFamilyNameSyntax, GenericFontFamily, SingleFontFamily, +}; use style::values::computed::{FontStretch, FontStyle, FontWeight}; use unicode_script::Script; use webrender_api::{FontInstanceFlags, FontInstanceKey}; @@ -629,10 +630,18 @@ impl FontGroup { TemplatePredicate: Fn(FontTemplateRef) -> bool, FontPredicate: Fn(&FontRef) -> bool, { - iter::once(FontFamilyDescriptor::serif()) - .chain(fallback_font_families(options).into_iter().map(|family| { - FontFamilyDescriptor::new(FontFamilyName::from(family), FontSearchScope::Local) - })) + iter::once(FontFamilyDescriptor::default()) + .chain( + fallback_font_families(options) + .into_iter() + .map(|family_name| { + let family = SingleFontFamily::FamilyName(FamilyName { + name: family_name.into(), + syntax: FontFamilyNameSyntax::Quoted, + }); + FontFamilyDescriptor::new(family, FontSearchScope::Local) + }), + ) .filter_map(|family_descriptor| { FontGroupFamily { family_descriptor, @@ -675,11 +684,8 @@ struct FontGroupFamily { impl FontGroupFamily { fn new(family: &SingleFontFamily) -> FontGroupFamily { - let family_descriptor = - FontFamilyDescriptor::new(FontFamilyName::from(family), FontSearchScope::Any); - FontGroupFamily { - family_descriptor, + family_descriptor: FontFamilyDescriptor::new(family.clone(), FontSearchScope::Any), members: None, } } @@ -781,73 +787,24 @@ pub enum FontSearchScope { Local, } -/// A font family name used in font selection. -#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] -pub enum FontFamilyName { - /// A specific name such as `"Arial"` - Specific(Atom), - - /// A generic name such as `sans-serif` - Generic(Atom), -} - -impl FontFamilyName { - pub fn name(&self) -> &str { - match *self { - FontFamilyName::Specific(ref name) => name, - FontFamilyName::Generic(ref name) => name, - } - } -} - -impl<'a> From<&'a SingleFontFamily> for FontFamilyName { - fn from(other: &'a SingleFontFamily) -> FontFamilyName { - match *other { - SingleFontFamily::FamilyName(ref family_name) => { - FontFamilyName::Specific(family_name.name.clone()) - }, - - SingleFontFamily::Generic(generic) => FontFamilyName::Generic(match generic { - GenericFontFamily::None => panic!("Shouldn't appear in style"), - GenericFontFamily::Serif => atom!("serif"), - GenericFontFamily::SansSerif => atom!("sans-serif"), - GenericFontFamily::Monospace => atom!("monospace"), - GenericFontFamily::Cursive => atom!("cursive"), - GenericFontFamily::Fantasy => atom!("fantasy"), - GenericFontFamily::SystemUi => atom!("system-ui"), - }), - } - } -} - -impl<'a> From<&'a str> for FontFamilyName { - fn from(other: &'a str) -> FontFamilyName { - FontFamilyName::Specific(Atom::from(other)) - } -} - /// The font family parameters for font selection. #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] pub struct FontFamilyDescriptor { - pub name: FontFamilyName, + pub family: SingleFontFamily, pub scope: FontSearchScope, } impl FontFamilyDescriptor { - pub fn new(name: FontFamilyName, scope: FontSearchScope) -> FontFamilyDescriptor { - FontFamilyDescriptor { name, scope } + pub fn new(family: SingleFontFamily, scope: FontSearchScope) -> FontFamilyDescriptor { + FontFamilyDescriptor { family, scope } } - fn serif() -> FontFamilyDescriptor { + fn default() -> FontFamilyDescriptor { FontFamilyDescriptor { - name: FontFamilyName::Generic(atom!("serif")), + family: SingleFontFamily::Generic(GenericFontFamily::None), scope: FontSearchScope::Local, } } - - pub fn name(&self) -> &str { - self.name.name() - } } /// Given a mapping array `mapping` and a value, map that value onto diff --git a/components/fonts/font_cache_thread.rs b/components/fonts/font_cache_thread.rs index bde22d4b515..0e45f0ab1a5 100644 --- a/components/fonts/font_cache_thread.rs +++ b/components/fonts/font_cache_thread.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::borrow::ToOwned; +use std::cell::OnceCell; use std::collections::HashMap; use std::ops::{Deref, RangeInclusive}; use std::sync::Arc; @@ -14,23 +15,25 @@ use ipc_channel::ipc::{self, IpcBytesReceiver, IpcBytesSender, IpcReceiver, IpcS use log::debug; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; -use servo_atoms::Atom; +use servo_config::pref; use servo_url::ServoUrl; use style::font_face::{FontFaceRuleData, FontStyle as FontFaceStyle}; -use style::values::computed::font::{FixedPoint, FontStyleFixedPoint}; +use style::values::computed::font::{ + FixedPoint, FontStyleFixedPoint, GenericFontFamily, SingleFontFamily, +}; use style::values::computed::{FontStretch, FontWeight}; use style::values::specified::FontStretch as SpecifiedFontStretch; use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey}; use webrender_traits::WebRenderFontApi; -use crate::font::{FontDescriptor, FontFamilyName}; +use crate::font::FontDescriptor; use crate::font_store::FontStore; use crate::font_template::{ FontTemplate, FontTemplateDescriptor, FontTemplateRef, FontTemplateRefMethods, }; use crate::platform::font_list::{ - for_each_available_family, for_each_variation, system_default_family, LocalFontIdentifier, - SANS_SERIF_FONT_FAMILY, + default_system_generic_font_family, for_each_available_family, for_each_variation, + LocalFontIdentifier, }; #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] @@ -60,7 +63,7 @@ pub struct SerializedFontTemplate { pub enum Command { GetFontTemplates( Option, - FontFamilyName, + SingleFontFamily, IpcSender>, ), GetFontInstance( @@ -75,43 +78,27 @@ pub enum Command { Ping, } +#[derive(Default)] +struct ResolvedGenericFontFamilies { + default: OnceCell, + serif: OnceCell, + sans_serif: OnceCell, + monospace: OnceCell, + fantasy: OnceCell, + cursive: OnceCell, + system_ui: OnceCell, +} + /// The font cache thread itself. It maintains a list of reference counted /// font templates that are currently in use. struct FontCache { port: IpcReceiver, - generic_fonts: HashMap, font_data: HashMap>>, local_families: FontStore, webrender_api: Box, webrender_fonts: HashMap, font_instances: HashMap<(FontKey, Au), FontInstanceKey>, -} - -fn populate_generic_fonts() -> HashMap { - let mut generic_fonts = HashMap::with_capacity(5); - - append_map(&mut generic_fonts, "serif", "Times New Roman"); - append_map(&mut generic_fonts, "sans-serif", SANS_SERIF_FONT_FAMILY); - append_map(&mut generic_fonts, "cursive", "Apple Chancery"); - append_map(&mut generic_fonts, "fantasy", "Papyrus"); - append_map(&mut generic_fonts, "monospace", "Menlo"); - - fn append_map( - generic_fonts: &mut HashMap, - generic_name: &str, - mapped_name: &str, - ) { - let family_name = match system_default_family(generic_name) { - Some(system_default) => LowercaseString::new(&system_default), - None => LowercaseString::new(mapped_name), - }; - - let generic_name = FontFamilyName::Generic(Atom::from(generic_name)); - - generic_fonts.insert(generic_name, family_name); - } - - generic_fonts + generic_fonts: ResolvedGenericFontFamilies, } impl FontCache { @@ -120,9 +107,9 @@ impl FontCache { let msg = self.port.recv().unwrap(); match msg { - Command::GetFontTemplates(descriptor_to_match, font_family_name, result) => { + Command::GetFontTemplates(descriptor_to_match, font_family, result) => { let templates = - self.find_font_templates(descriptor_to_match.as_ref(), &font_family_name); + self.find_font_templates(descriptor_to_match.as_ref(), &font_family); debug!("Found templates for descriptor {descriptor_to_match:?}: "); debug!(" {templates:?}"); @@ -192,28 +179,21 @@ impl FontCache { fn refresh_local_families(&mut self) { self.local_families.clear(); for_each_available_family(|family_name| { - let family_name = LowercaseString::new(&family_name); - self.local_families.families.entry(family_name).or_default(); + self.local_families + .families + .entry(family_name.as_str().into()) + .or_default(); }); } - fn transform_family(&self, family_name: &FontFamilyName) -> LowercaseString { - match self.generic_fonts.get(family_name) { - None => LowercaseString::from(family_name), - Some(mapped_family) => (*mapped_family).clone(), - } - } - fn find_font_templates( &mut self, descriptor_to_match: Option<&FontDescriptor>, - family_name: &FontFamilyName, + family: &SingleFontFamily, ) -> Vec { // TODO(Issue #188): look up localized font family names if canonical name not found // look up canonical name - // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. - // if such family exists, try to match style to a font - let family_name = self.transform_family(family_name); + let family_name = self.family_name_for_single_font_family(family); self.local_families .families .get_mut(&family_name) @@ -267,13 +247,53 @@ impl FontCache { webrender_font_api.add_font_instance(font_key, pt_size.to_f32_px(), flags) }) } + + pub(crate) fn family_name_for_single_font_family( + &mut self, + family: &SingleFontFamily, + ) -> LowercaseFontFamilyName { + let generic = match family { + SingleFontFamily::FamilyName(family_name) => return family_name.name.clone().into(), + SingleFontFamily::Generic(generic) => generic, + }; + + let resolved_font = match generic { + GenericFontFamily::None => &self.generic_fonts.default, + GenericFontFamily::Serif => &self.generic_fonts.serif, + GenericFontFamily::SansSerif => &self.generic_fonts.sans_serif, + GenericFontFamily::Monospace => &self.generic_fonts.monospace, + GenericFontFamily::Cursive => &self.generic_fonts.cursive, + GenericFontFamily::Fantasy => &self.generic_fonts.fantasy, + GenericFontFamily::SystemUi => &self.generic_fonts.system_ui, + }; + + resolved_font + .get_or_init(|| { + // First check whether the font is set in the preferences. + let family_name = match generic { + GenericFontFamily::None => pref!(fonts.default), + GenericFontFamily::Serif => pref!(fonts.serif), + GenericFontFamily::SansSerif => pref!(fonts.sans_serif), + GenericFontFamily::Monospace => pref!(fonts.monospace), + _ => String::new(), + }; + + if !family_name.is_empty() { + return family_name.into(); + } + + // Otherwise ask the platform for the default family for the generic font. + default_system_generic_font_family(*generic) + }) + .clone() + } } pub trait FontSource: Clone { fn find_matching_font_templates( &self, descriptor_to_match: Option<&FontDescriptor>, - font_family_name: &FontFamilyName, + font_family_name: &SingleFontFamily, ) -> Vec; fn get_system_font_instance( &self, @@ -313,7 +333,7 @@ pub enum ComputedFontStyleDescriptor { /// on the contents of the font itself. #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct CSSFontFaceDescriptors { - pub family_name: LowercaseString, + pub family_name: LowercaseFontFamilyName, pub weight: Option<(FontWeight, FontWeight)>, pub stretch: Option<(FontStretch, FontStretch)>, pub style: Option, @@ -323,7 +343,7 @@ pub struct CSSFontFaceDescriptors { impl CSSFontFaceDescriptors { pub fn new(family_name: &str) -> Self { CSSFontFaceDescriptors { - family_name: LowercaseString::new(family_name), + family_name: family_name.into(), ..Default::default() } } @@ -373,7 +393,7 @@ impl From<&FontFaceRuleData> for CSSFontFaceDescriptors { .map(|ranges| ranges.iter().map(|range| range.start..=range.end).collect()); CSSFontFaceDescriptors { - family_name: LowercaseString::new(&family_name), + family_name: family_name.into(), weight, stretch, style, @@ -389,18 +409,15 @@ impl FontCacheThread { thread::Builder::new() .name("FontCache".to_owned()) .spawn(move || { - // TODO: Allow users to specify these. - let generic_fonts = populate_generic_fonts(); - #[allow(clippy::default_constructed_unit_structs)] let mut cache = FontCache { port, - generic_fonts, font_data: HashMap::new(), local_families: Default::default(), webrender_api, webrender_fonts: HashMap::new(), font_instances: HashMap::new(), + generic_fonts: Default::default(), }; cache.refresh_local_families(); @@ -454,13 +471,13 @@ impl FontSource for FontCacheThread { fn find_matching_font_templates( &self, descriptor_to_match: Option<&FontDescriptor>, - font_family_name: &FontFamilyName, + font_family: &SingleFontFamily, ) -> Vec { let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel"); self.chan .send(Command::GetFontTemplates( descriptor_to_match.cloned(), - font_family_name.clone(), + font_family.clone(), response_chan, )) .expect("failed to send message to font cache thread"); @@ -521,25 +538,19 @@ impl FontSource for FontCacheThread { } #[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub struct LowercaseString { +pub struct LowercaseFontFamilyName { inner: String, } -impl LowercaseString { - pub fn new(s: &str) -> LowercaseString { - LowercaseString { - inner: s.to_lowercase(), +impl> From for LowercaseFontFamilyName { + fn from(value: T) -> Self { + LowercaseFontFamilyName { + inner: value.as_ref().to_lowercase(), } } } -impl<'a> From<&'a FontFamilyName> for LowercaseString { - fn from(family_name: &'a FontFamilyName) -> LowercaseString { - LowercaseString::new(family_name.name()) - } -} - -impl Deref for LowercaseString { +impl Deref for LowercaseFontFamilyName { type Target = str; #[inline] @@ -548,7 +559,7 @@ impl Deref for LowercaseString { } } -impl fmt::Display for LowercaseString { +impl fmt::Display for LowercaseFontFamilyName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.fmt(f) } diff --git a/components/fonts/font_context.rs b/components/fonts/font_context.rs index ef02f7d07d9..efadb035067 100644 --- a/components/fonts/font_context.rs +++ b/components/fonts/font_context.rs @@ -25,18 +25,18 @@ use style::media_queries::Device; use style::properties::style_structs::Font as FontStyleStruct; use style::shared_lock::SharedRwLockReadGuard; use style::stylesheets::{CssRule, DocumentStyleSheet, FontFaceRule, StylesheetInDocument}; +use style::values::computed::font::{FamilyName, FontFamilyNameSyntax, SingleFontFamily}; use style::Atom; use url::Url; use webrender_api::{FontInstanceKey, FontKey}; use crate::font::{ - Font, FontDescriptor, FontFamilyDescriptor, FontFamilyName, FontGroup, FontRef, FontSearchScope, -}; -use crate::font_cache_thread::{ - CSSFontFaceDescriptors, FontIdentifier, FontSource, LowercaseString, + Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope, }; +use crate::font_cache_thread::{CSSFontFaceDescriptors, FontIdentifier, FontSource}; use crate::font_store::{CrossThreadFontStore, CrossThreadWebRenderFontStore}; use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods}; +use crate::LowercaseFontFamilyName; static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h) @@ -170,28 +170,39 @@ impl FontContext { font } + fn matching_web_font_templates( + &self, + descriptor_to_match: &FontDescriptor, + family_descriptor: &FontFamilyDescriptor, + ) -> Option> { + if family_descriptor.scope != FontSearchScope::Any { + return None; + } + + // Do not look for generic fonts in our list of web fonts. + let SingleFontFamily::FamilyName(ref family_name) = family_descriptor.family else { + return None; + }; + + self.web_fonts + .read() + .families + .get(&family_name.name.clone().into()) + .map(|templates| templates.find_for_descriptor(Some(descriptor_to_match))) + } + + /// Try to find matching templates in this [`FontContext`], first looking in the list of web fonts and + /// falling back to asking the [`super::FontCacheThread`] for a matching system font. pub fn matching_templates( &self, descriptor_to_match: &FontDescriptor, family_descriptor: &FontFamilyDescriptor, ) -> Vec { - // First try to find an appropriate web font that matches this descriptor. - if family_descriptor.scope == FontSearchScope::Any { - let family_name = LowercaseString::from(&family_descriptor.name); - if let Some(templates) = self - .web_fonts - .read() - .families - .get(&family_name) - .map(|templates| templates.find_for_descriptor(Some(descriptor_to_match))) - { - return templates; - } - } - - // If not request a matching font from the system font cache. - self.cache - .matching_templates(descriptor_to_match, family_descriptor) + self.matching_web_font_templates(descriptor_to_match, family_descriptor) + .unwrap_or_else(|| { + self.cache + .matching_templates(descriptor_to_match, family_descriptor) + }) } /// Create a `Font` for use in layout calculations, from a `FontTemplateData` returned by the @@ -310,10 +321,13 @@ impl FontContextWebFontMethods for Arc FontContextWebFontMethods for Arc { font_context: Arc>, url: ServoArc, - web_font_family_name: LowercaseString, + web_font_family_name: LowercaseFontFamilyName, response_valid: Mutex, response_data: Mutex>, } @@ -468,7 +482,7 @@ impl RemoteWebFontDownloader { fn download( url_source: UrlSource, font_context: Arc>, - web_font_family_name: LowercaseString, + web_font_family_name: LowercaseFontFamilyName, state: WebFontDownloadState, ) { // https://drafts.csswg.org/css-fonts/#font-fetching-requirements @@ -652,7 +666,7 @@ impl CachingFontSource { let templates = self .font_cache_thread .lock() - .find_matching_font_templates(Some(descriptor_to_match), &family_descriptor.name); + .find_matching_font_templates(Some(descriptor_to_match), &family_descriptor.family); self.templates.write().insert(cache_key, templates.clone()); templates diff --git a/components/fonts/font_store.rs b/components/fonts/font_store.rs index ff6d56abac2..e5287b5bf88 100644 --- a/components/fonts/font_store.rs +++ b/components/fonts/font_store.rs @@ -14,13 +14,13 @@ use style::values::computed::{FontStyle, FontWeight}; use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey}; use crate::font::FontDescriptor; -use crate::font_cache_thread::{FontIdentifier, FontSource, LowercaseString}; +use crate::font_cache_thread::{FontIdentifier, FontSource, LowercaseFontFamilyName}; use crate::font_context::WebFontDownloadState; use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods, IsOblique}; #[derive(Default)] pub struct FontStore { - pub(crate) families: HashMap, + pub(crate) families: HashMap, web_fonts_loading: Vec<(DocumentStyleSheet, usize)>, } pub(crate) type CrossThreadFontStore = Arc>; diff --git a/components/fonts/platform/freetype/android/font_list.rs b/components/fonts/platform/freetype/android/font_list.rs index 0fd0c336487..b7152a8efc7 100644 --- a/components/fonts/platform/freetype/android/font_list.rs +++ b/components/fonts/platform/freetype/android/font_list.rs @@ -10,13 +10,16 @@ use base::text::{is_cjk, UnicodeBlock, UnicodeBlockMethod}; use log::warn; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; +use style::values::computed::font::GenericFontFamily; use style::values::computed::{ FontStretch as StyleFontStretch, FontStyle as StyleFontStyle, FontWeight as StyleFontWeight, }; use style::Atom; use super::xml::{Attribute, Node}; -use crate::{FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor}; +use crate::{ + FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor, LowercaseFontFamilyName, +}; lazy_static::lazy_static! { static ref FONT_LIST: FontList = FontList::new(); @@ -515,17 +518,6 @@ where } } -pub fn system_default_family(generic_name: &str) -> Option { - if let Some(family) = FONT_LIST.find_family(&generic_name) { - Some(family.name.clone()) - } else if let Some(alias) = FONT_LIST.find_alias(&generic_name) { - Some(alias.from.clone()) - } else { - // First font defined in the fonts.xml is the default on Android. - FONT_LIST.families.get(0).map(|family| family.name.clone()) - } -} - // Based on gfxAndroidPlatform::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'static str> { let mut families = vec![]; @@ -581,4 +573,14 @@ pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'st families } -pub static SANS_SERIF_FONT_FAMILY: &'static str = "sans-serif"; +pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName { + match generic { + GenericFontFamily::None | GenericFontFamily::Serif => "serif", + GenericFontFamily::SansSerif => "sans-serif", + GenericFontFamily::Monospace => "monospace", + GenericFontFamily::Cursive => "cursive", + GenericFontFamily::Fantasy => "serif", + GenericFontFamily::SystemUi => "Droid Sans", + } + .into() +} diff --git a/components/fonts/platform/freetype/font_list.rs b/components/fonts/platform/freetype/font_list.rs index 95e4b4043d2..0212344ba45 100644 --- a/components/fonts/platform/freetype/font_list.rs +++ b/components/fonts/platform/freetype/font_list.rs @@ -27,6 +27,7 @@ use libc::{c_char, c_int}; use log::debug; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; +use style::values::computed::font::GenericFontFamily; use style::values::computed::{FontStretch, FontStyle, FontWeight}; use style::Atom; use unicode_script::Script; @@ -35,7 +36,7 @@ use super::c_str_to_string; use crate::font::map_platform_values_to_style_values; use crate::font_template::{FontTemplate, FontTemplateDescriptor}; use crate::platform::add_noto_fallback_families; -use crate::{EmojiPresentationPreference, FallbackFontSelectionOptions}; +use crate::{EmojiPresentationPreference, FallbackFontSelectionOptions, LowercaseFontFamilyName}; /// An identifier for a local font on systems using Freetype. #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] @@ -166,41 +167,6 @@ where } } -pub fn system_default_family(generic_name: &str) -> Option { - let generic_name_c = CString::new(generic_name).unwrap(); - let generic_name_ptr = generic_name_c.as_ptr(); - - unsafe { - let pattern = FcNameParse(generic_name_ptr as *mut FcChar8); - - FcConfigSubstitute(ptr::null_mut(), pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - let mut result = 0; - let family_match = FcFontMatch(ptr::null_mut(), pattern, &mut result); - - let family_name = if result == FcResultMatch { - let mut match_string: *mut FcChar8 = ptr::null_mut(); - FcPatternGetString( - family_match, - FC_FAMILY.as_ptr() as *mut c_char, - 0, - &mut match_string, - ); - let result = c_str_to_string(match_string as *const c_char); - FcPatternDestroy(family_match); - Some(result) - } else { - None - }; - - FcPatternDestroy(pattern); - family_name - } -} - -pub static SANS_SERIF_FONT_FAMILY: &str = "DejaVu Sans"; - // Based on gfxPlatformGtk::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'static str> { let mut families = Vec::new(); @@ -241,6 +207,58 @@ pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'st families } +pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName { + let generic_string = match generic { + GenericFontFamily::None | GenericFontFamily::Serif => "serif", + GenericFontFamily::SansSerif => "sans-serif", + GenericFontFamily::Monospace => "monospace", + GenericFontFamily::Cursive => "cursive", + GenericFontFamily::Fantasy => "fantasy", + GenericFontFamily::SystemUi => "sans-serif", + }; + + let generic_name_c = CString::new(generic_string).unwrap(); + let generic_name_ptr = generic_name_c.as_ptr(); + + unsafe { + let pattern = FcNameParse(generic_name_ptr as *mut FcChar8); + FcConfigSubstitute(ptr::null_mut(), pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + let mut result = 0; + let family_match = FcFontMatch(ptr::null_mut(), pattern, &mut result); + + if result == FcResultMatch { + let mut match_string: *mut FcChar8 = ptr::null_mut(); + FcPatternGetString( + family_match, + FC_FAMILY.as_ptr() as *mut c_char, + 0, + &mut match_string, + ); + let family_name = c_str_to_string(match_string as *const c_char); + + FcPatternDestroy(family_match); + FcPatternDestroy(pattern); + + return family_name.into(); + } + + FcPatternDestroy(family_match); + FcPatternDestroy(pattern); + } + + match generic { + GenericFontFamily::None | GenericFontFamily::Serif => "Noto Serif", + GenericFontFamily::SansSerif => "Noto Sans", + GenericFontFamily::Monospace => "Deja Vu Sans Mono", + GenericFontFamily::Cursive => "Comic Sans MS", + GenericFontFamily::Fantasy => "Impact", + GenericFontFamily::SystemUi => "Noto Sans", + } + .into() +} + fn font_style_from_fontconfig_pattern(pattern: *mut FcPattern) -> Option { let mut slant: c_int = 0; unsafe { diff --git a/components/fonts/platform/freetype/ohos/font_list.rs b/components/fonts/platform/freetype/ohos/font_list.rs index 819535a618d..ee14200f0d1 100644 --- a/components/fonts/platform/freetype/ohos/font_list.rs +++ b/components/fonts/platform/freetype/ohos/font_list.rs @@ -10,12 +10,15 @@ use base::text::{is_cjk, UnicodeBlock, UnicodeBlockMethod}; use log::warn; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; +use style::values::computed::font::GenericFontFamily; use style::values::computed::{ FontStretch as StyleFontStretch, FontStyle as StyleFontStyle, FontWeight as StyleFontWeight, }; use style::Atom; -use crate::{FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor}; +use crate::{ + FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor, LowercaseFontFamilyName, +}; lazy_static::lazy_static! { static ref FONT_LIST: FontList = FontList::new(); @@ -185,16 +188,6 @@ where } } -pub fn system_default_family(generic_name: &str) -> Option { - if let Some(family) = FONT_LIST.find_family(&generic_name) { - Some(family.name.clone()) - } else if let Some(alias) = FONT_LIST.find_alias(&generic_name) { - Some(alias.from.clone()) - } else { - FONT_LIST.families.get(0).map(|family| family.name.clone()) - } -} - // Based on fonts present in OpenHarmony. pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'static str> { let mut families = vec![]; @@ -242,4 +235,6 @@ pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'st families } -pub static SANS_SERIF_FONT_FAMILY: &'static str = "HarmonyOS Sans"; +pub fn default_system_generic_font_family(_generic: GenericFontFamily) -> LowercaseFontFamilyName { + "HarmonyOS Sans".into() +} diff --git a/components/fonts/platform/macos/font_list.rs b/components/fonts/platform/macos/font_list.rs index b2176b31f42..a2d12c4247f 100644 --- a/components/fonts/platform/macos/font_list.rs +++ b/components/fonts/platform/macos/font_list.rs @@ -10,6 +10,7 @@ use base::text::{unicode_plane, UnicodeBlock, UnicodeBlockMethod}; use log::debug; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; +use style::values::computed::font::GenericFontFamily; use style::Atom; use unicode_script::Script; use webrender_api::NativeFontHandle; @@ -17,7 +18,8 @@ use webrender_api::NativeFontHandle; use crate::platform::add_noto_fallback_families; use crate::platform::font::CoreTextFontTraitsMapping; use crate::{ - EmojiPresentationPreference, FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor, + EmojiPresentationPreference, FallbackFontSelectionOptions, FontTemplate, + FontTemplateDescriptor, LowercaseFontFamilyName, }; /// An identifier for a local font on a MacOS system. These values comes from the CoreText @@ -89,10 +91,6 @@ where } } -pub fn system_default_family(_generic_name: &str) -> Option { - None -} - /// Get the list of fallback fonts given an optional codepoint. This is /// based on `gfxPlatformMac::GetCommonFallbackFonts()` in Gecko from /// . @@ -210,4 +208,14 @@ pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'st families } -pub static SANS_SERIF_FONT_FAMILY: &str = "Helvetica"; +pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName { + match generic { + GenericFontFamily::None | GenericFontFamily::Serif => "Times", + GenericFontFamily::SansSerif => "Helvetica", + GenericFontFamily::Monospace => "Menlo", + GenericFontFamily::Cursive => "Apple Chancery", + GenericFontFamily::Fantasy => "Papyrus", + GenericFontFamily::SystemUi => "Menlo", + } + .into() +} diff --git a/components/fonts/platform/windows/font_list.rs b/components/fonts/platform/windows/font_list.rs index 31c1d631160..3a2c32e66be 100644 --- a/components/fonts/platform/windows/font_list.rs +++ b/components/fonts/platform/windows/font_list.rs @@ -9,19 +9,15 @@ use base::text::{unicode_plane, UnicodeBlock, UnicodeBlockMethod}; use dwrote::{Font, FontCollection, FontDescriptor, FontStretch, FontStyle}; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; +use style::values::computed::font::GenericFontFamily; use style::values::computed::{FontStyle as StyleFontStyle, FontWeight as StyleFontWeight}; use style::values::specified::font::FontStretchKeyword; use crate::{ - EmojiPresentationPreference, FallbackFontSelectionOptions, FontTemplate, FontTemplateDescriptor, + EmojiPresentationPreference, FallbackFontSelectionOptions, FontTemplate, + FontTemplateDescriptor, LowercaseFontFamilyName, }; -pub static SANS_SERIF_FONT_FAMILY: &str = "Arial"; - -pub fn system_default_family(_: &str) -> Option { - Some("Verdana".to_owned()) -} - pub fn for_each_available_family(mut callback: F) where F: FnMut(String), @@ -377,3 +373,15 @@ impl From<&Font> for FontTemplateDescriptor { FontTemplateDescriptor::new(weight, stretch, style) } } + +pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName { + match generic { + GenericFontFamily::None | GenericFontFamily::Serif => "Times New Roman", + GenericFontFamily::SansSerif => "Arial", + GenericFontFamily::Monospace => "Courier New", + GenericFontFamily::Cursive => "Comic Sans MS", + GenericFontFamily::Fantasy => "Impact", + GenericFontFamily::SystemUi => "Segoe UI", + } + .into() +} diff --git a/components/fonts/tests/font_context.rs b/components/fonts/tests/font_context.rs index 652760d7f33..eb1154e6e8f 100644 --- a/components/fonts/tests/font_context.rs +++ b/components/fonts/tests/font_context.rs @@ -12,8 +12,8 @@ use std::rc::Rc; use app_units::Au; use fonts::{ fallback_font_families, CSSFontFaceDescriptors, FallbackFontSelectionOptions, FontContext, - FontDescriptor, FontFamilyDescriptor, FontFamilyName, FontIdentifier, FontSearchScope, - FontSource, FontTemplate, FontTemplateRef, FontTemplates, + FontDescriptor, FontFamilyDescriptor, FontIdentifier, FontSearchScope, FontSource, + FontTemplate, FontTemplateRef, FontTemplates, }; use ipc_channel::ipc; use net_traits::ResourceThreads; @@ -97,12 +97,16 @@ impl FontSource for MockFontCacheThread { fn find_matching_font_templates( &self, descriptor_to_match: Option<&FontDescriptor>, - font_family_name: &FontFamilyName, + font_family: &SingleFontFamily, ) -> Vec { self.find_font_count.set(self.find_font_count.get() + 1); + let SingleFontFamily::FamilyName(family_name) = font_family else { + return Vec::new(); + }; + self.families .borrow_mut() - .get_mut(font_family_name.name()) + .get_mut(&*family_name.name) .map(|family| family.find_for_descriptor(descriptor_to_match)) .unwrap_or_default() } @@ -295,8 +299,11 @@ fn test_font_template_is_cached() { pt_size: Au(10), }; - let family_descriptor = - FontFamilyDescriptor::new(FontFamilyName::from("CSSTest Basic"), FontSearchScope::Any); + let family = SingleFontFamily::FamilyName(FamilyName { + name: "CSSTest Basic".into(), + syntax: FontFamilyNameSyntax::Quoted, + }); + let family_descriptor = FontFamilyDescriptor::new(family, FontSearchScope::Any); let font_template = context.matching_templates(&font_descriptor, &family_descriptor)[0].clone(); diff --git a/components/layout/table.rs b/components/layout/table.rs index b91e77966ee..cc257c854f5 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -1350,14 +1350,9 @@ impl<'table> TableCellStyleInfo<'table> { }; { let cell_flow = &self.cell.block_flow; - let initial = ComputedValues::initial_values(); let build_dl = |sty: &ComputedValues, state: &mut &mut DisplayListBuildState| { let background = sty.get_background(); - // Don't redraw backgrounds that we've already drawn - if std::ptr::eq(background, initial.get_background()) { - return; - } let background_color = sty.resolve_color(background.background_color.clone()); cell_flow.build_display_list_for_background_if_applicable_with_background( state, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 16d242d728b..0530de0b8f7 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -301,7 +301,11 @@ impl BoxTree { layout_context: &LayoutContext, viewport: euclid::Size2D, ) -> FragmentTree { - let style = ComputedValues::initial_values(); + let style = layout_context + .style_context + .stylist + .device() + .default_computed_values(); // FIXME: use the document’s mode: // https://drafts.csswg.org/css-writing-modes/#principal-flow diff --git a/components/layout_2020/table/construct.rs b/components/layout_2020/table/construct.rs index 8e90cab0e4a..db7d515aa3e 100644 --- a/components/layout_2020/table/construct.rs +++ b/components/layout_2020/table/construct.rs @@ -9,6 +9,7 @@ use std::iter::repeat; use log::warn; use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode; use servo_arc::Arc; +use style::properties::style_structs::Font; use style::properties::ComputedValues; use style::selector_parser::PseudoElement; use style::str::char_is_whitespace; @@ -248,9 +249,11 @@ impl TableBuilder { } pub fn new_for_tests() -> Self { + let testing_style = + ComputedValues::initial_values_with_font_override(Font::initial_values()); Self::new( - ComputedValues::initial_values().to_arc(), - ComputedValues::initial_values().to_arc(), + testing_style.clone(), + testing_style.clone(), BaseFragmentInfo::anonymous(), ) } diff --git a/components/layout_2020/table/mod.rs b/components/layout_2020/table/mod.rs index 2296c72a5dd..1e29e605605 100644 --- a/components/layout_2020/table/mod.rs +++ b/components/layout_2020/table/mod.rs @@ -75,6 +75,7 @@ pub use construct::TableBuilder; use euclid::{Point2D, Size2D, UnknownUnit, Vector2D}; use serde::Serialize; use servo_arc::Arc; +use style::properties::style_structs::Font; use style::properties::ComputedValues; use style_traits::dom::OpaqueNode; @@ -215,7 +216,8 @@ impl TableSlotCell { }, colspan, rowspan, - style: ComputedValues::initial_values().to_arc(), + style: ComputedValues::initial_values_with_font_override(Font::initial_values()) + .to_arc(), base_fragment_info: BaseFragmentInfo::new_for_node(OpaqueNode(id)), } } diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 2973c4fd0c1..b9a52ee4986 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -73,6 +73,7 @@ use script_traits::{ use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::opts::{self, DebugOptions}; +use servo_config::pref; use servo_url::{ImmutableOrigin, ServoUrl}; use style::animation::{AnimationSetKey, DocumentAnimationSet, ElementAnimationSet}; use style::context::{ @@ -86,7 +87,7 @@ use style::invalidation::element::restyle_hints::RestyleHint; use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaList, MediaType}; use style::properties::style_structs::Font; -use style::properties::PropertyId; +use style::properties::{ComputedValues, PropertyId}; use style::selector_parser::{PseudoElement, SnapshotMap}; use style::servo::media_queries::FontMetricsProvider; use style::servo::restyle_damage::ServoRestyleDamage; @@ -98,6 +99,9 @@ use style::stylesheets::{ use style::stylist::Stylist; use style::traversal::DomTraversal; use style::traversal_flags::TraversalFlags; +use style::values::computed::font::GenericFontFamily; +use style::values::computed::{FontSize, Length, NonNegativeLength}; +use style::values::specified::font::KeywordInfo; use style_traits::{CSSPixel, DevicePixel, SpeculativePainter}; use url::Url; use webrender_api::{units, ColorF, HitTestFlags}; @@ -579,6 +583,14 @@ impl LayoutThread { // Let webrender know about this pipeline by sending an empty display list. webrender_api.send_initial_transaction(id.into()); + let mut font = Font::initial_values(); + let default_font_size = pref!(fonts.default_size); + font.font_size = FontSize { + computed_size: NonNegativeLength::new(default_font_size as f32), + used_size: NonNegativeLength::new(default_font_size as f32), + keyword_info: KeywordInfo::medium(), + }; + let font_context = Arc::new(FontContext::new(font_cache_thread, resource_threads)); let device = Device::new( MediaType::screen(), @@ -586,6 +598,7 @@ impl LayoutThread { window_size.initial_viewport, window_size.device_pixel_ratio, Box::new(LayoutFontMetricsProvider), + ComputedValues::initial_values_with_font_override(font), ); LayoutThread { @@ -1409,6 +1422,7 @@ impl LayoutThread { window_size_data.initial_viewport, window_size_data.device_pixel_ratio, Box::new(LayoutFontMetricsProvider), + self.stylist.device().default_computed_values().to_arc(), ); // Preserve any previously computed root font size. @@ -1631,4 +1645,12 @@ impl FontMetricsProvider for LayoutFontMetricsProvider { ) -> style::font_metrics::FontMetrics { Default::default() } + + fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length { + Length::new(match generic { + GenericFontFamily::Monospace => pref!(fonts.default_monospace_size), + _ => pref!(fonts.default_size), + } as f32) + .max(Length::new(0.0)) + } } diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 41a15df6cc7..84ff7d2fbed 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -59,6 +59,7 @@ use script_traits::{ use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::opts::{self, DebugOptions}; +use servo_config::pref; use servo_url::{ImmutableOrigin, ServoUrl}; use style::animation::DocumentAnimationSet; use style::context::{ @@ -71,7 +72,7 @@ use style::global_style_data::{GLOBAL_STYLE_DATA, STYLE_THREAD_POOL}; use style::invalidation::element::restyle_hints::RestyleHint; use style::media_queries::{Device, MediaList, MediaType}; use style::properties::style_structs::Font; -use style::properties::PropertyId; +use style::properties::{ComputedValues, PropertyId}; use style::selector_parser::{PseudoElement, SnapshotMap}; use style::servo::media_queries::FontMetricsProvider; use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards}; @@ -82,7 +83,9 @@ use style::stylesheets::{ use style::stylist::Stylist; use style::traversal::DomTraversal; use style::traversal_flags::TraversalFlags; -use style::values::computed::CSSPixelLength; +use style::values::computed::font::GenericFontFamily; +use style::values::computed::{CSSPixelLength, FontSize, Length, NonNegativeLength}; +use style::values::specified::font::KeywordInfo; use style::{driver, Zero}; use style_traits::{CSSPixel, DevicePixel, SpeculativePainter}; use url::Url; @@ -494,6 +497,14 @@ impl LayoutThread { // Let webrender know about this pipeline by sending an empty display list. webrender_api_sender.send_initial_transaction(id.into()); + let mut font = Font::initial_values(); + let default_font_size = pref!(fonts.default_size); + font.font_size = FontSize { + computed_size: NonNegativeLength::new(default_font_size as f32), + used_size: NonNegativeLength::new(default_font_size as f32), + keyword_info: KeywordInfo::medium(), + }; + // The device pixel ratio is incorrect (it does not have the hidpi value), // but it will be set correctly when the initial reflow takes place. let font_context = Arc::new(FontContext::new(font_cache_thread, resource_threads)); @@ -503,6 +514,7 @@ impl LayoutThread { window_size.initial_viewport, window_size.device_pixel_ratio, Box::new(LayoutFontMetricsProvider(font_context.clone())), + ComputedValues::initial_values_with_font_override(font), ); LayoutThread { @@ -1043,6 +1055,7 @@ impl LayoutThread { window_size_data.initial_viewport, window_size_data.device_pixel_ratio, Box::new(LayoutFontMetricsProvider(self.font_context.clone())), + self.stylist.device().default_computed_values().to_arc(), ); // Preserve any previously computed root font size. @@ -1262,6 +1275,14 @@ impl FontMetricsProvider for LayoutFontMetricsProvider { script_script_percent_scale_down: None, } } + + fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length { + Length::new(match generic { + GenericFontFamily::Monospace => pref!(fonts.default_monospace_size), + _ => pref!(fonts.default_size), + } as f32) + .max(Length::new(0.0)) + } } impl Debug for LayoutFontMetricsProvider { diff --git a/tests/unit/style/custom_properties.rs b/tests/unit/style/custom_properties.rs index 6c61805aab6..93eafe16fe7 100644 --- a/tests/unit/style/custom_properties.rs +++ b/tests/unit/style/custom_properties.rs @@ -14,7 +14,7 @@ use style::custom_properties::{ use style::font_metrics::FontMetrics; use style::media_queries::{Device, MediaType}; use style::properties::style_structs::Font; -use style::properties::{CustomDeclaration, CustomDeclarationValue, StyleBuilder}; +use style::properties::{ComputedValues, CustomDeclaration, CustomDeclarationValue, StyleBuilder}; use style::rule_cache::RuleCacheConditions; use style::rule_tree::CascadeLevel; use style::servo::media_queries::FontMetricsProvider; @@ -22,6 +22,7 @@ use style::stylesheets::container_rule::ContainerSizeQuery; use style::stylesheets::layer_rule::LayerOrder; use style::stylesheets::UrlExtraData; use style::stylist::Stylist; +use style::values::computed::font::GenericFontFamily; use style::values::computed::{Context, Length}; use test::{self, Bencher}; use url::Url; @@ -40,6 +41,9 @@ impl FontMetricsProvider for DummyMetricsProvider { ) -> FontMetrics { Default::default() } + fn base_size_for_generic(&self, _: GenericFontFamily) -> Length { + Length::new(16.) + } } fn cascade( @@ -60,12 +64,14 @@ fn cascade( }) .collect::>(); + let initial_style = ComputedValues::initial_values_with_font_override(Font::initial_values()); let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, Size2D::new(800., 600.), Scale::new(1.0), Box::new(DummyMetricsProvider), + initial_style, ); let stylist = Stylist::new(device, QuirksMode::NoQuirks); let mut builder = StyleBuilder::new(stylist.device(), Some(&stylist), None, None, None, false); diff --git a/tests/unit/style/stylist.rs b/tests/unit/style/stylist.rs index 2b6f1a9437c..eab122d4b23 100644 --- a/tests/unit/style/stylist.rs +++ b/tests/unit/style/stylist.rs @@ -11,7 +11,9 @@ use style::context::QuirksMode; use style::font_metrics::FontMetrics; use style::media_queries::{Device, MediaType}; use style::properties::style_structs::Font; -use style::properties::{longhands, Importance, PropertyDeclaration, PropertyDeclarationBlock}; +use style::properties::{ + longhands, ComputedValues, Importance, PropertyDeclaration, PropertyDeclarationBlock, +}; use style::selector_map::SelectorMap; use style::selector_parser::{SelectorImpl, SelectorParser}; use style::servo::media_queries::FontMetricsProvider; @@ -21,6 +23,7 @@ use style::stylist::{ needs_revalidation_for_testing, ContainerConditionId, LayerId, Rule, ScopeConditionId, Stylist, }; use style::thread_state::{self, ThreadState}; +use style::values::computed::font::GenericFontFamily; use style::values::computed::Length; use url::Url; @@ -38,6 +41,9 @@ impl FontMetricsProvider for DummyMetricsProvider { ) -> FontMetrics { Default::default() } + fn base_size_for_generic(&self, _: GenericFontFamily) -> Length { + Length::new(16.) + } } /// Helper method to get some Rules from selector strings. @@ -241,12 +247,14 @@ fn test_insert() { } fn mock_stylist() -> Stylist { + let initial_style = ComputedValues::initial_values_with_font_override(Font::initial_values()); let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, Size2D::new(0f32, 0f32), Scale::new(1.0), Box::new(DummyMetricsProvider), + initial_style, ); Stylist::new(device, QuirksMode::NoQuirks) } diff --git a/tests/wpt/meta/css/css-fonts/parsing/font-family-valid.html.ini b/tests/wpt/meta/css/css-fonts/parsing/font-family-valid.html.ini deleted file mode 100644 index b17ac3de579..00000000000 --- a/tests/wpt/meta/css/css-fonts/parsing/font-family-valid.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[font-family-valid.html] - [e.style['font-family'\] = "System-UI" should set the property value] - expected: FAIL diff --git a/tests/wpt/meta/css/css-fonts/system-ui-ar.html.ini b/tests/wpt/meta/css/css-fonts/system-ui-ar.html.ini deleted file mode 100644 index d334315178a..00000000000 --- a/tests/wpt/meta/css/css-fonts/system-ui-ar.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[system-ui-ar.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-fonts/system-ui-mixed.html.ini b/tests/wpt/meta/css/css-fonts/system-ui-mixed.html.ini deleted file mode 100644 index 9965271ed89..00000000000 --- a/tests/wpt/meta/css/css-fonts/system-ui-mixed.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[system-ui-mixed.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-fonts/system-ui-ur.html.ini b/tests/wpt/meta/css/css-fonts/system-ui-ur.html.ini deleted file mode 100644 index d9e58e116a2..00000000000 --- a/tests/wpt/meta/css/css-fonts/system-ui-ur.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[system-ui-ur.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-fonts/system-ui.html.ini b/tests/wpt/meta/css/css-fonts/system-ui.html.ini deleted file mode 100644 index fc1193a36c4..00000000000 --- a/tests/wpt/meta/css/css-fonts/system-ui.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[system-ui.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-transforms/transform-input-017.html.ini b/tests/wpt/meta/css/css-transforms/transform-input-017.html.ini deleted file mode 100644 index 0f1ebae4a3e..00000000000 --- a/tests/wpt/meta/css/css-transforms/transform-input-017.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[transform-input-017.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html.ini b/tests/wpt/meta/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html.ini deleted file mode 100644 index 89d10ae3c9a..00000000000 --- a/tests/wpt/meta/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[input-checkbox-switch-rtl.tentative.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 5ffc6a8ba75..fbb91fa1a9c 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -2236,7 +2236,7 @@ ] ], "font_size.html": [ - "4ffd55261f2f9e5b4dd2beaf8de8fb528c1de718", + "4f0fafc984a312881c0182325c1dc8876ea67f09", [ null, [ @@ -8724,7 +8724,7 @@ [] ], "font_face_attribute_ref.html": [ - "f018747d2ab41119af5e06d6a018101169592cab", + "14378f20cead025327c4cf296ac766b39ebea13a", [] ], "font_fallback_failed_ref.html": [ @@ -8732,7 +8732,7 @@ [] ], "font_size_ref.html": [ - "6bcf54338856d79af998eefad7bc7bb9f94d0236", + "923a3c45c8a5c333b575bedfff8500291547f265", [] ], "font_style_ref.html": [ diff --git a/tests/wpt/mozilla/tests/css/font_face_attribute_ref.html b/tests/wpt/mozilla/tests/css/font_face_attribute_ref.html index f018747d2ab..14378f20cea 100644 --- a/tests/wpt/mozilla/tests/css/font_face_attribute_ref.html +++ b/tests/wpt/mozilla/tests/css/font_face_attribute_ref.html @@ -2,8 +2,8 @@ - -

Servo

-

Servo

+ +

Servo

+

Servo

diff --git a/tests/wpt/mozilla/tests/css/font_size.html b/tests/wpt/mozilla/tests/css/font_size.html index 4ffd55261f2..4f0fafc984a 100644 --- a/tests/wpt/mozilla/tests/css/font_size.html +++ b/tests/wpt/mozilla/tests/css/font_size.html @@ -10,10 +10,14 @@

200% is 40px.

smaller is 16.66666…px.

larger is 24px. -

xx-small is 9.6px. -

x-small is 12px. -

small is 14.2222…px. + +

xx-small is 9px. +

x-small is 10px. +

small is 13px.

medium is 16px. -

large is 19.2px. +

large is 18px.

x-large is 24px.

xx-large is 32px. diff --git a/tests/wpt/mozilla/tests/css/font_size_ref.html b/tests/wpt/mozilla/tests/css/font_size_ref.html index 6bcf5433885..923a3c45c8a 100644 --- a/tests/wpt/mozilla/tests/css/font_size_ref.html +++ b/tests/wpt/mozilla/tests/css/font_size_ref.html @@ -8,10 +8,10 @@

200% is 40px.

smaller is 16.66666…px.

larger is 24px. -

xx-small is 9.6px. -

x-small is 12px. -

small is 14.2222…px. +

xx-small is 9px. +

x-small is 10px. +

small is 13px.

medium is 16px. -

large is 19.2px. +

large is 18px.

x-large is 24px.

xx-large is 32px.