mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Rearrange FontLanguageOverride
Creating one from a u32 should be unsafe because we rely on the fact that the value is a valid &str.
This commit is contained in:
parent
e7cb736796
commit
94ee8b34ca
2 changed files with 46 additions and 47 deletions
|
@ -21,7 +21,6 @@ use crate::values::specified::font::{
|
||||||
use crate::values::specified::length::{FontBaseSize, NoCalcLength};
|
use crate::values::specified::length::{FontBaseSize, NoCalcLength};
|
||||||
use crate::values::CSSFloat;
|
use crate::values::CSSFloat;
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
|
||||||
use cssparser::{serialize_identifier, CssStringWriter, Parser};
|
use cssparser::{serialize_identifier, CssStringWriter, Parser};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
@ -676,7 +675,7 @@ pub type FontVariationSettings = FontSettings<VariationValue<Number>>;
|
||||||
/// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
/// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
||||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToResolvedValue)]
|
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToResolvedValue)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FontLanguageOverride(pub u32);
|
pub struct FontLanguageOverride(u32);
|
||||||
|
|
||||||
impl FontLanguageOverride {
|
impl FontLanguageOverride {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -684,6 +683,46 @@ impl FontLanguageOverride {
|
||||||
pub fn zero() -> FontLanguageOverride {
|
pub fn zero() -> FontLanguageOverride {
|
||||||
FontLanguageOverride(0)
|
FontLanguageOverride(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns this value as a `&str`, backed by `storage`.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_str(self, storage: &mut [u8; 4]) -> &str {
|
||||||
|
if self.0 == 0 {
|
||||||
|
return "normal";
|
||||||
|
}
|
||||||
|
*storage = u32::to_be_bytes(self.0);
|
||||||
|
// Safe because we ensure it's ASCII during computing
|
||||||
|
let slice = if cfg!(debug_assertions) {
|
||||||
|
std::str::from_utf8(&storage[..]).unwrap()
|
||||||
|
} else {
|
||||||
|
unsafe { std::str::from_utf8_unchecked(&storage[..]) }
|
||||||
|
};
|
||||||
|
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]
|
||||||
|
pub unsafe fn from_u32(value: u32) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for FontLanguageOverride {
|
impl ToCss for FontLanguageOverride {
|
||||||
|
@ -691,27 +730,7 @@ impl ToCss for FontLanguageOverride {
|
||||||
where
|
where
|
||||||
W: fmt::Write,
|
W: fmt::Write,
|
||||||
{
|
{
|
||||||
use std::str;
|
self.to_str(&mut [0; 4]).to_css(dest)
|
||||||
|
|
||||||
if self.0 == 0 {
|
|
||||||
return dest.write_str("normal");
|
|
||||||
}
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
BigEndian::write_u32(&mut buf, self.0);
|
|
||||||
// Safe because we ensure it's ASCII during computing
|
|
||||||
let slice = if cfg!(debug_assertions) {
|
|
||||||
str::from_utf8(&buf).unwrap()
|
|
||||||
} else {
|
|
||||||
unsafe { str::from_utf8_unchecked(&buf) }
|
|
||||||
};
|
|
||||||
slice.trim_end().to_css(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
impl From<u32> for FontLanguageOverride {
|
|
||||||
fn from(bits: u32) -> FontLanguageOverride {
|
|
||||||
FontLanguageOverride(bits)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
|
||||||
use crate::values::specified::{NoCalcLength, NonNegativeNumber, Number, Percentage};
|
use crate::values::specified::{NoCalcLength, NonNegativeNumber, Number, Percentage};
|
||||||
use crate::values::CustomIdent;
|
use crate::values::CustomIdent;
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
@ -2057,19 +2056,9 @@ impl FontLanguageOverride {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn compute_non_system(&self) -> computed::FontLanguageOverride {
|
pub fn compute_non_system(&self) -> computed::FontLanguageOverride {
|
||||||
match *self {
|
match *self {
|
||||||
FontLanguageOverride::Normal => computed::FontLanguageOverride(0),
|
FontLanguageOverride::Normal => computed::FontLanguageOverride::zero(),
|
||||||
FontLanguageOverride::Override(ref lang) => {
|
FontLanguageOverride::Override(ref lang) => {
|
||||||
if lang.is_empty() || lang.len() > 4 {
|
computed::FontLanguageOverride::from_str(lang)
|
||||||
return computed::FontLanguageOverride(0);
|
|
||||||
}
|
|
||||||
let mut bytes = [b' '; 4];
|
|
||||||
for (byte, lang_byte) in bytes.iter_mut().zip(lang.as_bytes()) {
|
|
||||||
if !lang_byte.is_ascii() {
|
|
||||||
return computed::FontLanguageOverride(0);
|
|
||||||
}
|
|
||||||
*byte = *lang_byte;
|
|
||||||
}
|
|
||||||
computed::FontLanguageOverride(BigEndian::read_u32(&bytes))
|
|
||||||
},
|
},
|
||||||
FontLanguageOverride::System(..) => unreachable!(),
|
FontLanguageOverride::System(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -2090,19 +2079,10 @@ impl ToComputedValue for FontLanguageOverride {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self {
|
fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self {
|
||||||
if computed.0 == 0 {
|
if *computed == computed::FontLanguageOverride::zero() {
|
||||||
return FontLanguageOverride::Normal;
|
return FontLanguageOverride::Normal;
|
||||||
}
|
}
|
||||||
let mut buf = [0; 4];
|
FontLanguageOverride::Override(computed.to_str(&mut [0; 4]).into())
|
||||||
BigEndian::write_u32(&mut buf, computed.0);
|
|
||||||
FontLanguageOverride::Override(
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
String::from_utf8(buf.to_vec()).unwrap()
|
|
||||||
} else {
|
|
||||||
unsafe { String::from_utf8_unchecked(buf.to_vec()) }
|
|
||||||
}
|
|
||||||
.into_boxed_str(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue