mirror of
https://github.com/servo/servo.git
synced 2025-10-09 21:10:19 +01:00
This was generated with: ./mach cargo fmt --package selectors && ./mach cargo fmt --package servo_arc && ./mach cargo fmt --package style Using rustfmt 0.4.1-nightly (a4462d1 2018-03-26)
233 lines
6.6 KiB
Rust
233 lines
6.6 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Generic types for font stuff.
|
|
|
|
use app_units::Au;
|
|
use byteorder::{BigEndian, ReadBytesExt};
|
|
use cssparser::Parser;
|
|
use num_traits::One;
|
|
use parser::{Parse, ParserContext};
|
|
use std::fmt::{self, Write};
|
|
use std::io::Cursor;
|
|
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
|
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
|
|
|
/// https://drafts.csswg.org/css-fonts-4/#feature-tag-value
|
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)]
|
|
pub struct FeatureTagValue<Integer> {
|
|
/// A four-character tag, packed into a u32 (one byte per character).
|
|
pub tag: FontTag,
|
|
/// The actual value.
|
|
pub value: Integer,
|
|
}
|
|
|
|
impl<Integer> ToCss for FeatureTagValue<Integer>
|
|
where
|
|
Integer: One + ToCss + PartialEq,
|
|
{
|
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
where
|
|
W: Write,
|
|
{
|
|
self.tag.to_css(dest)?;
|
|
// Don't serialize the default value.
|
|
if self.value != Integer::one() {
|
|
dest.write_char(' ')?;
|
|
self.value.to_css(dest)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Variation setting for a single feature, see:
|
|
///
|
|
/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def
|
|
#[derive(Animate, Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
|
pub struct VariationValue<Number> {
|
|
/// A four-character tag, packed into a u32 (one byte per character).
|
|
#[animation(constant)]
|
|
pub tag: FontTag,
|
|
/// The actual value.
|
|
pub value: Number,
|
|
}
|
|
|
|
impl<Number> ComputeSquaredDistance for VariationValue<Number>
|
|
where
|
|
Number: ComputeSquaredDistance,
|
|
{
|
|
#[inline]
|
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
|
if self.tag != other.tag {
|
|
return Err(());
|
|
}
|
|
self.value.compute_squared_distance(&other.value)
|
|
}
|
|
}
|
|
|
|
/// A value both for font-variation-settings and font-feature-settings.
|
|
#[css(comma)]
|
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
|
pub struct FontSettings<T>(#[css(if_empty = "normal", iterable)] pub Box<[T]>);
|
|
|
|
impl<T> FontSettings<T> {
|
|
/// Default value of font settings as `normal`.
|
|
#[inline]
|
|
pub fn normal() -> Self {
|
|
FontSettings(vec![].into_boxed_slice())
|
|
}
|
|
}
|
|
|
|
impl<T: Parse> Parse for FontSettings<T> {
|
|
/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings
|
|
/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def
|
|
fn parse<'i, 't>(
|
|
context: &ParserContext,
|
|
input: &mut Parser<'i, 't>,
|
|
) -> Result<Self, ParseError<'i>> {
|
|
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
|
return Ok(Self::normal());
|
|
}
|
|
|
|
Ok(FontSettings(
|
|
input
|
|
.parse_comma_separated(|i| T::parse(context, i))?
|
|
.into_boxed_slice(),
|
|
))
|
|
}
|
|
}
|
|
|
|
/// A font four-character tag, represented as a u32 for convenience.
|
|
///
|
|
/// See:
|
|
/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def
|
|
/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings
|
|
///
|
|
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)]
|
|
pub struct FontTag(pub u32);
|
|
|
|
impl ToCss for FontTag {
|
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
where
|
|
W: Write,
|
|
{
|
|
use byteorder::{BigEndian, ByteOrder};
|
|
use std::str;
|
|
|
|
let mut raw = [0u8; 4];
|
|
BigEndian::write_u32(&mut raw, self.0);
|
|
str::from_utf8(&raw).unwrap_or_default().to_css(dest)
|
|
}
|
|
}
|
|
|
|
impl Parse for FontTag {
|
|
fn parse<'i, 't>(
|
|
_context: &ParserContext,
|
|
input: &mut Parser<'i, 't>,
|
|
) -> Result<Self, ParseError<'i>> {
|
|
let location = input.current_source_location();
|
|
let tag = input.expect_string()?;
|
|
|
|
// allowed strings of length 4 containing chars: <U+20, U+7E>
|
|
if tag.len() != 4 || tag.as_bytes().iter().any(|c| *c < b' ' || *c > b'~') {
|
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
|
}
|
|
|
|
let mut raw = Cursor::new(tag.as_bytes());
|
|
Ok(FontTag(raw.read_u32::<BigEndian>().unwrap()))
|
|
}
|
|
}
|
|
|
|
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq,
|
|
ToAnimatedValue, ToAnimatedZero, ToCss)]
|
|
/// Additional information for keyword-derived font sizes.
|
|
pub struct KeywordInfo<Length> {
|
|
/// The keyword used
|
|
pub kw: KeywordSize,
|
|
/// A factor to be multiplied by the computed size of the keyword
|
|
#[css(skip)]
|
|
pub factor: f32,
|
|
/// An additional Au offset to add to the kw*factor in the case of calcs
|
|
#[css(skip)]
|
|
pub offset: Length,
|
|
}
|
|
|
|
impl<L> KeywordInfo<L>
|
|
where
|
|
Au: Into<L>,
|
|
{
|
|
/// KeywordInfo value for font-size: medium
|
|
pub fn medium() -> Self {
|
|
KeywordSize::Medium.into()
|
|
}
|
|
}
|
|
|
|
impl<L> From<KeywordSize> for KeywordInfo<L>
|
|
where
|
|
Au: Into<L>,
|
|
{
|
|
fn from(x: KeywordSize) -> Self {
|
|
KeywordInfo {
|
|
kw: x,
|
|
factor: 1.,
|
|
offset: Au(0).into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// CSS font keywords
|
|
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq,
|
|
ToAnimatedValue, ToAnimatedZero)]
|
|
#[allow(missing_docs)]
|
|
pub enum KeywordSize {
|
|
XXSmall,
|
|
XSmall,
|
|
Small,
|
|
Medium,
|
|
Large,
|
|
XLarge,
|
|
XXLarge,
|
|
// This is not a real font keyword and will not parse
|
|
// HTML font-size 7 corresponds to this value
|
|
XXXLarge,
|
|
}
|
|
|
|
impl KeywordSize {
|
|
/// Convert to an HTML <font size> value
|
|
#[inline]
|
|
pub fn html_size(self) -> u8 {
|
|
self as u8
|
|
}
|
|
}
|
|
|
|
impl Default for KeywordSize {
|
|
fn default() -> Self {
|
|
KeywordSize::Medium
|
|
}
|
|
}
|
|
|
|
impl ToCss for KeywordSize {
|
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
where
|
|
W: Write,
|
|
{
|
|
dest.write_str(match *self {
|
|
KeywordSize::XXSmall => "xx-small",
|
|
KeywordSize::XSmall => "x-small",
|
|
KeywordSize::Small => "small",
|
|
KeywordSize::Medium => "medium",
|
|
KeywordSize::Large => "large",
|
|
KeywordSize::XLarge => "x-large",
|
|
KeywordSize::XXLarge => "xx-large",
|
|
KeywordSize::XXXLarge => {
|
|
debug_assert!(
|
|
false,
|
|
"We should never serialize specified values set via HTML presentation attributes"
|
|
);
|
|
"-servo-xxx-large"
|
|
},
|
|
})
|
|
}
|
|
}
|