mirror of
https://github.com/servo/servo.git
synced 2025-09-29 16:19:14 +01:00
fonts: Add support for generic font families and font size configuration (#32673)
This adds support for generic font families in Servo and allows for configuration of them as well as their default font sizes. One interesting fix here is that now monospace default to 13px, like it does in other browsers. In addition to that, this exposes a new interface in Stylo which allows setting a default style. This is quite useful for fonts, but also for other kinds of default style settings -- like text zoom. Fixes #8371. Fixes #14773. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
parent
956b7f62e0
commit
77e9e3deba
32 changed files with 397 additions and 300 deletions
|
@ -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<String> {
|
||||
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()
|
||||
}
|
||||
|
|
|
@ -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<String> {
|
||||
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<FontStyle> {
|
||||
let mut slant: c_int = 0;
|
||||
unsafe {
|
||||
|
|
|
@ -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<String> {
|
||||
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()
|
||||
}
|
||||
|
|
|
@ -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<String> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the list of fallback fonts given an optional codepoint. This is
|
||||
/// based on `gfxPlatformMac::GetCommonFallbackFonts()` in Gecko from
|
||||
/// <https://searchfox.org/mozilla-central/source/gfx/thebes/gfxPlatformMac.cpp>.
|
||||
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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<String> {
|
||||
Some("Verdana".to_owned())
|
||||
}
|
||||
|
||||
pub fn for_each_available_family<F>(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()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue