mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Macroize conversion of @font-face values to Gecko types
This commit is contained in:
parent
61812d4d9d
commit
b43e2fb0df
4 changed files with 89 additions and 54 deletions
|
@ -12,6 +12,7 @@
|
||||||
use computed_values::{font_style, font_weight, font_stretch};
|
use computed_values::{font_style, font_weight, font_stretch};
|
||||||
use computed_values::font_family::FamilyName;
|
use computed_values::font_family::FamilyName;
|
||||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
||||||
|
#[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
|
||||||
#[cfg(feature = "gecko")] use cssparser::UnicodeRange;
|
#[cfg(feature = "gecko")] use cssparser::UnicodeRange;
|
||||||
use parser::{ParserContext, log_css_error, Parse};
|
use parser::{ParserContext, log_css_error, Parse};
|
||||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
|
@ -174,7 +175,7 @@ impl Parse for Source {
|
||||||
|
|
||||||
macro_rules! font_face_descriptors_common {
|
macro_rules! font_face_descriptors_common {
|
||||||
(
|
(
|
||||||
$( #[$doc: meta] $name: tt $ident: ident: $ty: ty, )*
|
$( #[$doc: meta] $name: tt $ident: ident / $gecko_ident: ident: $ty: ty, )*
|
||||||
) => {
|
) => {
|
||||||
/// Data inside a `@font-face` rule.
|
/// Data inside a `@font-face` rule.
|
||||||
///
|
///
|
||||||
|
@ -195,6 +196,19 @@ macro_rules! font_face_descriptors_common {
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert to Gecko types
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn set_descriptors(&self, descriptors: &mut CSSFontFaceDescriptors) {
|
||||||
|
$(
|
||||||
|
if let Some(ref value) = self.$ident {
|
||||||
|
descriptors.$gecko_ident.set_from(value)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
// Leave unset descriptors to eCSSUnit_Null,
|
||||||
|
// FontFaceSet::FindOrCreateUserFontEntryFromFontFace does the defaulting
|
||||||
|
// to initial values.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCssWithGuard for FontFaceRuleData {
|
impl ToCssWithGuard for FontFaceRuleData {
|
||||||
|
@ -232,15 +246,16 @@ macro_rules! font_face_descriptors_common {
|
||||||
macro_rules! font_face_descriptors {
|
macro_rules! font_face_descriptors {
|
||||||
(
|
(
|
||||||
mandatory descriptors = [
|
mandatory descriptors = [
|
||||||
$( #[$m_doc: meta] $m_name: tt $m_ident: ident: $m_ty: ty, )*
|
$( #[$m_doc: meta] $m_name: tt $m_ident: ident / $m_gecko_ident: ident: $m_ty: ty, )*
|
||||||
]
|
]
|
||||||
optional descriptors = [
|
optional descriptors = [
|
||||||
$( #[$o_doc: meta] $o_name: tt $o_ident: ident: $o_ty: ty = $o_initial: expr, )*
|
$( #[$o_doc: meta] $o_name: tt $o_ident: ident / $o_gecko_ident: ident: $o_ty: ty =
|
||||||
|
$o_initial: expr, )*
|
||||||
]
|
]
|
||||||
) => {
|
) => {
|
||||||
font_face_descriptors_common! {
|
font_face_descriptors_common! {
|
||||||
$( #[$m_doc] $m_name $m_ident: $m_ty, )*
|
$( #[$m_doc] $m_name $m_ident / $m_gecko_ident: $m_ty, )*
|
||||||
$( #[$o_doc] $o_name $o_ident: $o_ty, )*
|
$( #[$o_doc] $o_name $o_ident / $o_gecko_ident: $o_ty, )*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontFaceRuleData {
|
impl FontFaceRuleData {
|
||||||
|
@ -286,23 +301,23 @@ macro_rules! font_face_descriptors {
|
||||||
font_face_descriptors! {
|
font_face_descriptors! {
|
||||||
mandatory descriptors = [
|
mandatory descriptors = [
|
||||||
/// The name of this font face
|
/// The name of this font face
|
||||||
"font-family" family: FamilyName,
|
"font-family" family / mFamily: FamilyName,
|
||||||
|
|
||||||
/// The alternative sources for this font face.
|
/// The alternative sources for this font face.
|
||||||
"src" sources: Vec<Source>,
|
"src" sources / mSrc: Vec<Source>,
|
||||||
]
|
]
|
||||||
optional descriptors = [
|
optional descriptors = [
|
||||||
/// The style of this font face
|
/// The style of this font face
|
||||||
"font-style" style: font_style::T = font_style::T::normal,
|
"font-style" style / mStyle: font_style::T = font_style::T::normal,
|
||||||
|
|
||||||
/// The weight of this font face
|
/// The weight of this font face
|
||||||
"font-weight" weight: font_weight::T = font_weight::T::Weight400 /* normal */,
|
"font-weight" weight / mWeight: font_weight::T = font_weight::T::Weight400 /* normal */,
|
||||||
|
|
||||||
/// The stretch of this font face
|
/// The stretch of this font face
|
||||||
"font-stretch" stretch: font_stretch::T = font_stretch::T::normal,
|
"font-stretch" stretch / mStretch: font_stretch::T = font_stretch::T::normal,
|
||||||
|
|
||||||
/// The ranges of code points outside of which this font face should not be used.
|
/// The ranges of code points outside of which this font face should not be used.
|
||||||
"unicode-range" unicode_range: Vec<UnicodeRange> = vec![
|
"unicode-range" unicode_range / mUnicodeRange: Vec<UnicodeRange> = vec![
|
||||||
UnicodeRange { start: 0, end: 0x10FFFF }
|
UnicodeRange { start: 0, end: 0x10FFFF }
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -314,10 +329,10 @@ font_face_descriptors! {
|
||||||
font_face_descriptors! {
|
font_face_descriptors! {
|
||||||
mandatory descriptors = [
|
mandatory descriptors = [
|
||||||
/// The name of this font face
|
/// The name of this font face
|
||||||
"font-family" family: FamilyName,
|
"font-family" family / mFamily: FamilyName,
|
||||||
|
|
||||||
/// The alternative sources for this font face.
|
/// The alternative sources for this font face.
|
||||||
"src" sources: Vec<Source>,
|
"src" sources / mSrc: Vec<Source>,
|
||||||
]
|
]
|
||||||
optional descriptors = [
|
optional descriptors = [
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,9 +4,13 @@
|
||||||
|
|
||||||
//! Bindings for CSS Rule objects
|
//! Bindings for CSS Rule objects
|
||||||
|
|
||||||
|
use computed_values::{font_style, font_weight, font_stretch};
|
||||||
|
use computed_values::font_family::FamilyName;
|
||||||
|
use cssparser::UnicodeRange;
|
||||||
use font_face::{FontFaceRuleData, Source};
|
use font_face::{FontFaceRuleData, Source};
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
use gecko_bindings::structs::{self, CSSFontFaceDescriptors, nsCSSFontFaceRule};
|
use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue};
|
||||||
|
use gecko_bindings::sugar::ns_css_value::ToNsCssValue;
|
||||||
use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr};
|
use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr};
|
||||||
use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard};
|
use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -14,40 +18,46 @@ use std::fmt;
|
||||||
/// A @font-face rule
|
/// A @font-face rule
|
||||||
pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>;
|
pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>;
|
||||||
|
|
||||||
fn set_font_face_descriptors(descriptors: &mut CSSFontFaceDescriptors,
|
impl ToNsCssValue for FamilyName {
|
||||||
data: FontFaceRuleData) {
|
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||||
// font-family
|
nscssvalue.set_string_from_atom(&self.name)
|
||||||
if let Some(ref family) = data.family {
|
|
||||||
descriptors.mFamily.set_string_from_atom(&family.name);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! map_enum {
|
impl ToNsCssValue for font_weight::T {
|
||||||
($target:ident = ($data:ident: $prop:ident) {
|
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||||
$($servo:ident => $gecko:ident,)+
|
nscssvalue.set_integer(*self as i32)
|
||||||
}) => {{
|
}
|
||||||
if let Some(ref value) = data.$data {
|
}
|
||||||
use computed_values::$prop::T;
|
|
||||||
descriptors.$target.set_enum(match *value {
|
macro_rules! map_enum {
|
||||||
$( T::$servo => structs::$gecko as i32, )+
|
(
|
||||||
})
|
$(
|
||||||
|
$prop:ident {
|
||||||
|
$($servo:ident => $gecko:ident,)+
|
||||||
}
|
}
|
||||||
}}
|
)+
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
impl ToNsCssValue for $prop::T {
|
||||||
|
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||||
|
nscssvalue.set_enum(match *self {
|
||||||
|
$( $prop::T::$servo => structs::$gecko as i32, )+
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// font-style
|
map_enum! {
|
||||||
map_enum!(mStyle = (style: font_style) {
|
font_style {
|
||||||
normal => NS_FONT_STYLE_NORMAL,
|
normal => NS_FONT_STYLE_NORMAL,
|
||||||
italic => NS_FONT_STYLE_ITALIC,
|
italic => NS_FONT_STYLE_ITALIC,
|
||||||
oblique => NS_FONT_STYLE_OBLIQUE,
|
oblique => NS_FONT_STYLE_OBLIQUE,
|
||||||
});
|
|
||||||
|
|
||||||
// font-weight
|
|
||||||
if let Some(weight) = data.weight {
|
|
||||||
descriptors.mWeight.set_integer(weight as i32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// font-stretch
|
font_stretch {
|
||||||
map_enum!(mStretch = (stretch: font_stretch) {
|
|
||||||
normal => NS_FONT_STRETCH_NORMAL,
|
normal => NS_FONT_STRETCH_NORMAL,
|
||||||
ultra_condensed => NS_FONT_STRETCH_ULTRA_CONDENSED,
|
ultra_condensed => NS_FONT_STRETCH_ULTRA_CONDENSED,
|
||||||
extra_condensed => NS_FONT_STRETCH_EXTRA_CONDENSED,
|
extra_condensed => NS_FONT_STRETCH_EXTRA_CONDENSED,
|
||||||
|
@ -57,11 +67,12 @@ fn set_font_face_descriptors(descriptors: &mut CSSFontFaceDescriptors,
|
||||||
expanded => NS_FONT_STRETCH_EXPANDED,
|
expanded => NS_FONT_STRETCH_EXPANDED,
|
||||||
extra_expanded => NS_FONT_STRETCH_EXTRA_EXPANDED,
|
extra_expanded => NS_FONT_STRETCH_EXTRA_EXPANDED,
|
||||||
ultra_expanded => NS_FONT_STRETCH_ULTRA_EXPANDED,
|
ultra_expanded => NS_FONT_STRETCH_ULTRA_EXPANDED,
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// src
|
impl ToNsCssValue for Vec<Source> {
|
||||||
if let Some(ref sources) = data.sources {
|
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||||
let src_len = sources.iter().fold(0, |acc, src| {
|
let src_len = self.iter().fold(0, |acc, src| {
|
||||||
acc + match *src {
|
acc + match *src {
|
||||||
// Each format hint takes one position in the array of mSrc.
|
// Each format hint takes one position in the array of mSrc.
|
||||||
Source::Url(ref url) => url.format_hints.len() + 1,
|
Source::Url(ref url) => url.format_hints.len() + 1,
|
||||||
|
@ -69,11 +80,11 @@ fn set_font_face_descriptors(descriptors: &mut CSSFontFaceDescriptors,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut target_srcs =
|
let mut target_srcs =
|
||||||
descriptors.mSrc.set_array(src_len as i32).as_mut_slice().iter_mut();
|
nscssvalue.set_array(src_len as i32).as_mut_slice().iter_mut();
|
||||||
macro_rules! next { () => {
|
macro_rules! next { () => {
|
||||||
target_srcs.next().expect("Length of target_srcs should be enough")
|
target_srcs.next().expect("Length of target_srcs should be enough")
|
||||||
} }
|
} }
|
||||||
for src in sources.iter() {
|
for src in self.iter() {
|
||||||
match *src {
|
match *src {
|
||||||
Source::Url(ref url) => {
|
Source::Url(ref url) => {
|
||||||
next!().set_url(&url.url);
|
next!().set_url(&url.url);
|
||||||
|
@ -88,20 +99,18 @@ fn set_font_face_descriptors(descriptors: &mut CSSFontFaceDescriptors,
|
||||||
}
|
}
|
||||||
debug_assert!(target_srcs.next().is_none(), "Should have filled all slots");
|
debug_assert!(target_srcs.next().is_none(), "Should have filled all slots");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// unicode-range
|
impl ToNsCssValue for Vec<UnicodeRange> {
|
||||||
if let Some(ref unicode_range) = data.unicode_range {
|
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||||
let target_ranges = descriptors.mUnicodeRange
|
let target_ranges = nscssvalue
|
||||||
.set_array((unicode_range.len() * 2) as i32)
|
.set_array((self.len() * 2) as i32)
|
||||||
.as_mut_slice().chunks_mut(2);
|
.as_mut_slice().chunks_mut(2);
|
||||||
for (range, target) in unicode_range.iter().zip(target_ranges) {
|
for (range, target) in self.iter().zip(target_ranges) {
|
||||||
target[0].set_integer(range.start as i32);
|
target[0].set_integer(range.start as i32);
|
||||||
target[1].set_integer(range.end as i32);
|
target[1].set_integer(range.end as i32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave unset descriptors to eCSSUnit_Null,
|
|
||||||
// FontFaceSet::FindOrCreateUserFontEntryFromFontFace does the defaulting to initial values.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FontFaceRuleData> for FontFaceRule {
|
impl From<FontFaceRuleData> for FontFaceRule {
|
||||||
|
@ -109,7 +118,7 @@ impl From<FontFaceRuleData> for FontFaceRule {
|
||||||
let mut result = unsafe {
|
let mut result = unsafe {
|
||||||
UniqueRefPtr::from_addrefed(bindings::Gecko_CSSFontFaceRule_Create())
|
UniqueRefPtr::from_addrefed(bindings::Gecko_CSSFontFaceRule_Create())
|
||||||
};
|
};
|
||||||
set_font_face_descriptors(&mut result.mDecl.mDescriptors, data);
|
data.set_descriptors(&mut result.mDecl.mDescriptors);
|
||||||
result.get()
|
result.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
mod ns_com_ptr;
|
mod ns_com_ptr;
|
||||||
mod ns_css_shadow_array;
|
mod ns_css_shadow_array;
|
||||||
mod ns_css_value;
|
pub mod ns_css_value;
|
||||||
mod ns_style_auto_array;
|
mod ns_style_auto_array;
|
||||||
pub mod ns_style_coord;
|
pub mod ns_style_coord;
|
||||||
mod ns_t_array;
|
mod ns_t_array;
|
||||||
|
|
|
@ -163,6 +163,11 @@ impl nsCSSValue {
|
||||||
unsafe { bindings::Gecko_CSSValue_SetArray(self, len) }
|
unsafe { bindings::Gecko_CSSValue_SetArray(self, len) }
|
||||||
unsafe { self.mValue.mArray.as_mut().as_mut() }.unwrap()
|
unsafe { self.mValue.mArray.as_mut().as_mut() }.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic set from any value that implements the ToNsCssValue trait.
|
||||||
|
pub fn set_from<T: ToNsCssValue>(&mut self, value: &T) {
|
||||||
|
value.convert(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for nsCSSValue {
|
impl Drop for nsCSSValue {
|
||||||
|
@ -210,3 +215,9 @@ impl IndexMut<usize> for nsCSSValue_Array {
|
||||||
&mut self.as_mut_slice()[i]
|
&mut self.as_mut_slice()[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic conversion to nsCSSValue
|
||||||
|
pub trait ToNsCssValue {
|
||||||
|
/// Convert
|
||||||
|
fn convert(&self, nscssvalue: &mut nsCSSValue);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue