mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Fixes for font-language-override parsing and tests
Differential Revision: https://phabricator.services.mozilla.com/D168555
This commit is contained in:
parent
2d441672be
commit
816a0f960b
4 changed files with 34 additions and 75 deletions
|
@ -442,6 +442,7 @@ class Longhand(Property):
|
|||
"Display",
|
||||
"FillRule",
|
||||
"Float",
|
||||
"FontLanguageOverride",
|
||||
"FontSizeAdjust",
|
||||
"FontStretch",
|
||||
"FontStyle",
|
||||
|
|
|
@ -223,7 +223,7 @@ ${helpers.predefined_type(
|
|||
"font-language-override",
|
||||
"FontLanguageOverride",
|
||||
engines="gecko",
|
||||
initial_value="computed::FontLanguageOverride::zero()",
|
||||
initial_value="computed::FontLanguageOverride::normal()",
|
||||
initial_specified_value="specified::FontLanguageOverride::normal()",
|
||||
animation_value_type="discrete",
|
||||
extra_prefixes="moz:layout.css.prefixes.font-features",
|
||||
|
|
|
@ -855,18 +855,30 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// font-language-override can only have a single three-letter
|
||||
/// font-language-override can only have a single 1-4 ASCII character
|
||||
/// OpenType "language system" tag, so we should be able to compute
|
||||
/// it and store it as a 32-bit integer
|
||||
/// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToResolvedValue)]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem
|
||||
)]
|
||||
#[repr(C)]
|
||||
#[value_info(other_values = "normal")]
|
||||
pub struct FontLanguageOverride(pub u32);
|
||||
|
||||
impl FontLanguageOverride {
|
||||
#[inline]
|
||||
/// Get computed default value of `font-language-override` with 0
|
||||
pub fn zero() -> FontLanguageOverride {
|
||||
pub fn normal() -> FontLanguageOverride {
|
||||
FontLanguageOverride(0)
|
||||
}
|
||||
|
||||
|
@ -874,7 +886,7 @@ impl FontLanguageOverride {
|
|||
#[inline]
|
||||
pub(crate) fn to_str(self, storage: &mut [u8; 4]) -> &str {
|
||||
*storage = u32::to_be_bytes(self.0);
|
||||
// Safe because we ensure it's ASCII during computing
|
||||
// Safe because we ensure it's ASCII during parsing
|
||||
let slice = if cfg!(debug_assertions) {
|
||||
std::str::from_utf8(&storage[..]).unwrap()
|
||||
} else {
|
||||
|
@ -883,23 +895,6 @@ impl FontLanguageOverride {
|
|||
slice.trim_end()
|
||||
}
|
||||
|
||||
/// Parses a str, return `Self::zero()` if the input isn't a valid OpenType
|
||||
/// "language system" tag.
|
||||
#[inline]
|
||||
pub fn from_str(lang: &str) -> Self {
|
||||
if lang.is_empty() || lang.len() > 4 {
|
||||
return Self::zero();
|
||||
}
|
||||
let mut bytes = [b' '; 4];
|
||||
for (byte, lang_byte) in bytes.iter_mut().zip(lang.as_bytes()) {
|
||||
if !lang_byte.is_ascii() {
|
||||
return Self::zero();
|
||||
}
|
||||
*byte = *lang_byte;
|
||||
}
|
||||
Self(u32::from_be_bytes(bytes))
|
||||
}
|
||||
|
||||
/// Unsafe because `Self::to_str` requires the value to represent a UTF-8
|
||||
/// string.
|
||||
#[inline]
|
||||
|
|
|
@ -1743,55 +1743,8 @@ impl Parse for FontVariantNumeric {
|
|||
/// This property provides low-level control over OpenType or TrueType font features.
|
||||
pub type FontFeatureSettings = FontSettings<FeatureTagValue<Integer>>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
/// Allows authors to explicitly specify the language system of the font,
|
||||
/// overriding the language system implied by the content language
|
||||
pub enum FontLanguageOverride {
|
||||
/// When rendering with OpenType fonts,
|
||||
/// the content language of the element is
|
||||
/// used to infer the OpenType language system
|
||||
Normal,
|
||||
/// Single three-letter case-sensitive OpenType language system tag,
|
||||
/// specifies the OpenType language system to be used instead of
|
||||
/// the language system implied by the language of the element
|
||||
Override(Box<str>),
|
||||
}
|
||||
|
||||
impl FontLanguageOverride {
|
||||
#[inline]
|
||||
/// Get default value with `normal`
|
||||
pub fn normal() -> FontLanguageOverride {
|
||||
FontLanguageOverride::Normal
|
||||
}
|
||||
|
||||
/// The ToComputedValue implementation for non-system-font
|
||||
/// FontLanguageOverride, used for @font-face descriptors.
|
||||
#[inline]
|
||||
pub fn compute_non_system(&self) -> computed::FontLanguageOverride {
|
||||
match *self {
|
||||
FontLanguageOverride::Normal => computed::FontLanguageOverride::zero(),
|
||||
FontLanguageOverride::Override(ref lang) => {
|
||||
computed::FontLanguageOverride::from_str(lang)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for FontLanguageOverride {
|
||||
type ComputedValue = computed::FontLanguageOverride;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> computed::FontLanguageOverride {
|
||||
self.compute_non_system()
|
||||
}
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self {
|
||||
if *computed == computed::FontLanguageOverride::zero() {
|
||||
return FontLanguageOverride::Normal;
|
||||
}
|
||||
FontLanguageOverride::Override(computed.to_str(&mut [0; 4]).into())
|
||||
}
|
||||
}
|
||||
/// For font-language-override, use the same representation as the computed value.
|
||||
pub use crate::values::computed::font::FontLanguageOverride;
|
||||
|
||||
impl Parse for FontLanguageOverride {
|
||||
/// normal | <string>
|
||||
|
@ -1803,13 +1756,23 @@ impl Parse for FontLanguageOverride {
|
|||
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(FontLanguageOverride::Normal);
|
||||
return Ok(FontLanguageOverride::normal());
|
||||
}
|
||||
|
||||
let string = input.expect_string()?;
|
||||
Ok(FontLanguageOverride::Override(
|
||||
string.as_ref().to_owned().into_boxed_str(),
|
||||
))
|
||||
|
||||
// The OpenType spec requires tags to be 1 to 4 ASCII characters:
|
||||
// https://learn.microsoft.com/en-gb/typography/opentype/spec/otff#data-types
|
||||
if string.is_empty() || string.len() > 4 || !string.is_ascii() {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
let mut bytes = [b' '; 4];
|
||||
for (byte, str_byte) in bytes.iter_mut().zip(string.as_bytes()) {
|
||||
*byte = *str_byte;
|
||||
}
|
||||
|
||||
Ok(FontLanguageOverride(u32::from_be_bytes(bytes)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue