Auto merge of #16187 - upsuper:bug1345696, r=Manishearth,heycam

Implement access to CSSFontFaceRule for stylo

This is the Servo part of [bug 1345696](https://bugzilla.mozilla.org/show_bug.cgi?id=1345696) which has been reviewed on Bugzilla.
This commit is contained in:
bors-servo 2017-03-29 20:50:47 -05:00 committed by GitHub
commit 2084ee29c4
19 changed files with 4693 additions and 3374 deletions

View file

@ -98,6 +98,7 @@ use servo_url::ServoUrl;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::marker::PhantomData;
use std::mem as std_mem; use std::mem as std_mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::process; use std::process;
@ -116,7 +117,7 @@ use style::parser::ParserContextExtraData;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW}; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards}; use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets}; use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets};
use style::stylist::Stylist; use style::stylist::{ExtraStyleData, Stylist};
use style::thread_state; use style::thread_state;
use style::timer::Timer; use style::timer::Timer;
use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags}; use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags};
@ -1078,11 +1079,15 @@ impl LayoutThread {
author: &author_guard, author: &author_guard,
ua_or_user: &ua_or_user_guard, ua_or_user: &ua_or_user_guard,
}; };
let mut extra_data = ExtraStyleData {
marker: PhantomData,
};
let needs_dirtying = Arc::get_mut(&mut rw_data.stylist).unwrap().update( let needs_dirtying = Arc::get_mut(&mut rw_data.stylist).unwrap().update(
&data.document_stylesheets, &data.document_stylesheets,
&guards, &guards,
Some(ua_stylesheets), Some(ua_stylesheets),
data.stylesheets_changed); data.stylesheets_changed,
&mut extra_data);
let needs_reflow = viewport_size_changed && !needs_dirtying; let needs_reflow = viewport_size_changed && !needs_dirtying;
if needs_dirtying { if needs_dirtying {
if let Some(mut d) = element.mutate_data() { if let Some(mut d) = element.mutate_data() {

View file

@ -94,14 +94,13 @@ use std::time::{SystemTime, Instant};
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
use style::context::QuirksMode; use style::context::QuirksMode;
use style::element_state::*; use style::element_state::*;
use style::font_face::FontFaceRule;
use style::keyframes::Keyframe; use style::keyframes::Keyframe;
use style::media_queries::MediaList; use style::media_queries::MediaList;
use style::properties::PropertyDeclarationBlock; use style::properties::PropertyDeclarationBlock;
use style::selector_parser::{PseudoElement, Snapshot}; use style::selector_parser::{PseudoElement, Snapshot};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked}; use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule}; use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule};
use style::stylesheets::SupportsRule; use style::stylesheets::{NamespaceRule, StyleRule, ImportRule, SupportsRule};
use style::values::specified::Length; use style::values::specified::Length;
use style::viewport::ViewportRule; use style::viewport::ViewportRule;
use time::Duration; use time::Duration;

View file

@ -11,8 +11,8 @@ use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window; use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::sync::Arc; use std::sync::Arc;
use style::font_face::FontFaceRule;
use style::shared_lock::{Locked, ToCssWithGuard}; use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::FontFaceRule;
#[dom_struct] #[dom_struct]
pub struct CSSFontFaceRule { pub struct CSSFontFaceRule {

View file

@ -258,6 +258,7 @@ mod bindings {
vars: true, vars: true,
..CodegenConfig::nothing() ..CodegenConfig::nothing()
}) })
.include(add_include("nsCSSPseudoClasses.h")) // servo/rust-bindgen#599
.header(add_include("nsStyleStruct.h")) .header(add_include("nsStyleStruct.h"))
.include(add_include("mozilla/ServoPropPrefList.h")) .include(add_include("mozilla/ServoPropPrefList.h"))
.header(add_include("mozilla/StyleAnimationValue.h")) .header(add_include("mozilla/StyleAnimationValue.h"))
@ -270,6 +271,7 @@ mod bindings {
.include(add_include("mozilla/dom/NameSpaceConstants.h")) .include(add_include("mozilla/dom/NameSpaceConstants.h"))
.include(add_include("mozilla/LookAndFeel.h")) .include(add_include("mozilla/LookAndFeel.h"))
.include(add_include("mozilla/ServoBindings.h")) .include(add_include("mozilla/ServoBindings.h"))
.include(add_include("nsCSSFontFaceRule.h"))
.include(add_include("nsMediaFeatures.h")) .include(add_include("nsMediaFeatures.h"))
.include(add_include("nsMediaList.h")) .include(add_include("nsMediaList.h"))
// FIXME(emilio): Incrementally remove these "pub use"s. Probably // FIXME(emilio): Incrementally remove these "pub use"s. Probably
@ -336,6 +338,7 @@ mod bindings {
"nsBorderColors", "nsBorderColors",
"nscolor", "nscolor",
"nsChangeHint", "nsChangeHint",
"nsCSSFontFaceRule",
"nsCSSKeyword", "nsCSSKeyword",
"nsCSSPropertyID", "nsCSSPropertyID",
"nsCSSProps", "nsCSSProps",
@ -585,6 +588,7 @@ mod bindings {
"RawGeckoElement", "RawGeckoElement",
"RawGeckoKeyframeList", "RawGeckoKeyframeList",
"RawGeckoComputedKeyframeValuesList", "RawGeckoComputedKeyframeValuesList",
"RawGeckoFontFaceRuleList",
"RawGeckoNode", "RawGeckoNode",
"RawGeckoAnimationValueList", "RawGeckoAnimationValueList",
"RawServoAnimationValue", "RawServoAnimationValue",
@ -608,9 +612,11 @@ mod bindings {
"StyleBasicShape", "StyleBasicShape",
"StyleBasicShapeType", "StyleBasicShapeType",
"StyleShapeSource", "StyleShapeSource",
"nsCSSFontFaceRule",
"nsCSSKeyword", "nsCSSKeyword",
"nsCSSPropertyID", "nsCSSPropertyID",
"nsCSSShadowArray", "nsCSSShadowArray",
"nsCSSUnit",
"nsCSSValue", "nsCSSValue",
"nsCSSValueSharedList", "nsCSSValueSharedList",
"nsChangeHint", "nsChangeHint",
@ -701,6 +707,7 @@ mod bindings {
"RawGeckoAnimationValueList", "RawGeckoAnimationValueList",
"RawGeckoKeyframeList", "RawGeckoKeyframeList",
"RawGeckoComputedKeyframeValuesList", "RawGeckoComputedKeyframeValuesList",
"RawGeckoFontFaceRuleList",
]; ];
for &ty in structs_types.iter() { for &ty in structs_types.iter() {
builder = builder.hide_type(ty) builder = builder.hide_type(ty)

View file

@ -75,8 +75,8 @@ impl ToCss for UrlSource {
/// ///
/// Note that the prelude parsing code lives in the `stylesheets` module. /// Note that the prelude parsing code lives in the `stylesheets` module.
pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
-> Result<FontFaceRule, ()> { -> Result<FontFaceData, ()> {
let mut rule = FontFaceRule::initial(); let mut rule = FontFaceData::initial();
{ {
let parser = FontFaceRuleParser { let parser = FontFaceRuleParser {
context: context, context: context,
@ -104,7 +104,7 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub struct EffectiveSources(Vec<Source>); pub struct EffectiveSources(Vec<Source>);
impl FontFaceRule { impl FontFaceData {
/// Returns the list of effective sources for that font-face, that is the /// Returns the list of effective sources for that font-face, that is the
/// sources which don't list any format hint, or the ones which list at /// sources which don't list any format hint, or the ones which list at
/// least "truetype" or "opentype". /// least "truetype" or "opentype".
@ -134,7 +134,7 @@ impl iter::Iterator for EffectiveSources {
struct FontFaceRuleParser<'a, 'b: 'a> { struct FontFaceRuleParser<'a, 'b: 'a> {
context: &'a ParserContext<'b>, context: &'a ParserContext<'b>,
rule: &'a mut FontFaceRule, rule: &'a mut FontFaceData,
missing: MissingDescriptors, missing: MissingDescriptors,
} }
@ -181,11 +181,11 @@ macro_rules! font_face_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_ty: ty = $o_initial: expr, )*
] ]
) => { ) => {
/// A `@font-face` rule. /// Data inside a `@font-face` rule.
/// ///
/// https://drafts.csswg.org/css-fonts/#font-face-rule /// https://drafts.csswg.org/css-fonts/#font-face-rule
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct FontFaceRule { pub struct FontFaceData {
$( $(
#[$m_doc] #[$m_doc]
pub $m_ident: $m_ty, pub $m_ident: $m_ty,
@ -218,9 +218,9 @@ macro_rules! font_face_descriptors {
} }
} }
impl FontFaceRule { impl FontFaceData {
fn initial() -> Self { fn initial() -> Self {
FontFaceRule { FontFaceData {
$( $(
$m_ident: $m_initial, $m_ident: $m_initial,
)* )*
@ -231,7 +231,7 @@ macro_rules! font_face_descriptors {
} }
} }
impl ToCssWithGuard for FontFaceRule { impl ToCssWithGuard for FontFaceData {
// Serialization of FontFaceRule is not specced. // Serialization of FontFaceRule is not specced.
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write { where W: fmt::Write {

View file

@ -13,9 +13,9 @@ use gecko::values::{convert_rgba_to_nscolor, GeckoStyleCoordConvertible};
use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue}; use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue};
use gecko_bindings::bindings::Gecko_InitializeImageCropRect; use gecko_bindings::bindings::Gecko_InitializeImageCropRect;
use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage}; use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
use gecko_bindings::structs::nsresult; use gecko_bindings::structs::{nsresult, SheetType};
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut}; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
use stylesheets::RulesMutateError; use stylesheets::{Origin, RulesMutateError};
use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto}; use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto};
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue { impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
@ -503,3 +503,13 @@ impl From<RulesMutateError> for nsresult {
} }
} }
} }
impl From<Origin> for SheetType {
fn from(other: Origin) -> Self {
match other {
Origin::UserAgent => SheetType::Agent,
Origin::Author => SheetType::Doc,
Origin::User => SheetType::User,
}
}
}

View file

@ -13,12 +13,12 @@ use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
use media_queries::Device; use media_queries::Device;
use parking_lot::RwLock; use parking_lot::RwLock;
use properties::ComputedValues; use properties::ComputedValues;
use shared_lock::{StylesheetGuards, SharedRwLockReadGuard}; use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
use stylesheets::Stylesheet; use stylesheets::{FontFaceRule, Origin, Stylesheet};
use stylist::Stylist; use stylist::{ExtraStyleData, Stylist};
/// The container for data that a Servo-backed Gecko document needs to style /// The container for data that a Servo-backed Gecko document needs to style
/// itself. /// itself.
@ -45,6 +45,9 @@ pub struct PerDocumentStyleDataImpl {
/// Unused. Will go away when we actually implement transitions and /// Unused. Will go away when we actually implement transitions and
/// animations properly. /// animations properly.
pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>, pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>,
/// List of effective font face rules.
pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
} }
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics /// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
@ -66,6 +69,7 @@ impl PerDocumentStyleData {
new_animations_receiver: new_anims_receiver, new_animations_receiver: new_anims_receiver,
running_animations: Arc::new(RwLock::new(HashMap::new())), running_animations: Arc::new(RwLock::new(HashMap::new())),
expired_animations: Arc::new(RwLock::new(HashMap::new())), expired_animations: Arc::new(RwLock::new(HashMap::new())),
font_faces: vec![],
})) }))
} }
@ -97,7 +101,11 @@ impl PerDocumentStyleDataImpl {
pub fn flush_stylesheets(&mut self, guard: &SharedRwLockReadGuard) { pub fn flush_stylesheets(&mut self, guard: &SharedRwLockReadGuard) {
if self.stylesheets_changed { if self.stylesheets_changed {
let mut stylist = Arc::get_mut(&mut self.stylist).unwrap(); let mut stylist = Arc::get_mut(&mut self.stylist).unwrap();
stylist.update(&self.stylesheets, &StylesheetGuards::same(guard), None, true); let mut extra_data = ExtraStyleData {
font_faces: &mut self.font_faces,
};
stylist.update(&self.stylesheets, &StylesheetGuards::same(guard),
None, true, &mut extra_data);
self.stylesheets_changed = false; self.stylesheets_changed = false;
} }
} }

View file

@ -13,6 +13,7 @@ pub mod data;
pub mod global_style_data; pub mod global_style_data;
pub mod media_queries; pub mod media_queries;
pub mod restyle_damage; pub mod restyle_damage;
pub mod rules;
pub mod selector_parser; pub mod selector_parser;
pub mod snapshot; pub mod snapshot;
pub mod snapshot_helpers; pub mod snapshot_helpers;

View file

@ -0,0 +1,121 @@
/* 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/. */
//! Bindings for CSS Rule objects
use font_face::{FontFaceData, Source};
use gecko_bindings::bindings;
use gecko_bindings::structs::{self, CSSFontFaceDescriptors, nsCSSFontFaceRule};
use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr};
use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard};
use std::fmt;
/// A @font-face rule
pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>;
fn set_font_face_descriptors(descriptors: &mut CSSFontFaceDescriptors,
data: FontFaceData) {
// font-family
descriptors.mFamily.set_string_from_atom(&data.family.0);
macro_rules! map_enum {
($target:ident = ($data:ident: $prop:ident) {
$($servo:ident => $gecko:ident,)+
}) => {{
use computed_values::$prop::T;
descriptors.$target.set_enum(match data.$data {
$( T::$servo => structs::$gecko as i32, )+
})
}}
}
// font-style
map_enum!(mStyle = (style: font_style) {
normal => NS_FONT_STYLE_NORMAL,
italic => NS_FONT_STYLE_ITALIC,
oblique => NS_FONT_STYLE_OBLIQUE,
});
// font-weight
descriptors.mWeight.set_integer(data.weight as i32);
// font-stretch
map_enum!(mStretch = (stretch: font_stretch) {
normal => NS_FONT_STRETCH_NORMAL,
ultra_condensed => NS_FONT_STRETCH_ULTRA_CONDENSED,
extra_condensed => NS_FONT_STRETCH_EXTRA_CONDENSED,
condensed => NS_FONT_STRETCH_CONDENSED,
semi_condensed => NS_FONT_STRETCH_SEMI_CONDENSED,
semi_expanded => NS_FONT_STRETCH_SEMI_EXPANDED,
expanded => NS_FONT_STRETCH_EXPANDED,
extra_expanded => NS_FONT_STRETCH_EXTRA_EXPANDED,
ultra_expanded => NS_FONT_STRETCH_ULTRA_EXPANDED,
});
// src
let src_len = data.sources.iter().fold(0, |acc, src| {
acc + match *src {
// Each format hint takes one position in the array of mSrc.
Source::Url(ref url) => url.format_hints.len() + 1,
Source::Local(_) => 1,
}
});
let mut target_srcs =
descriptors.mSrc.set_array(src_len as i32).as_mut_slice().iter_mut();
macro_rules! next { () => {
target_srcs.next().expect("Length of target_srcs should be enough")
} }
for src in data.sources.iter() {
match *src {
Source::Url(ref url) => {
next!().set_url(&url.url);
for hint in url.format_hints.iter() {
next!().set_font_format(&hint);
}
}
Source::Local(ref name) => {
next!().set_local_font(&name.0);
}
}
}
debug_assert!(target_srcs.next().is_none(), "Should have filled all slots");
// unicode-range
let target_ranges = descriptors.mUnicodeRange
.set_array((data.unicode_range.len() * 2) as i32)
.as_mut_slice().chunks_mut(2);
for (range, target) in data.unicode_range.iter().zip(target_ranges) {
target[0].set_integer(range.start as i32);
target[1].set_integer(range.end as i32);
}
// The following three descriptors are not implemented yet.
// font-feature-settings
descriptors.mFontFeatureSettings.set_normal();
// font-language-override
descriptors.mFontLanguageOverride.set_normal();
// font-display
descriptors.mDisplay.set_enum(structs::NS_FONT_DISPLAY_AUTO as i32);
}
impl From<FontFaceData> for FontFaceRule {
fn from(data: FontFaceData) -> FontFaceRule {
let mut result = unsafe {
UniqueRefPtr::from_addrefed(bindings::Gecko_CSSFontFaceRule_Create())
};
set_font_face_descriptors(&mut result.mDecl.mDescriptors, data);
result.get()
}
}
impl ToCssWithGuard for FontFaceRule {
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
ns_auto_string!(css_text);
unsafe {
bindings::Gecko_CSSFontFaceRule_GetCssText(self.get(), &mut *css_text);
}
write!(dest, "{}", css_text)
}
}

View file

@ -8,6 +8,7 @@ use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoKeyframeList; use gecko_bindings::structs::RawGeckoKeyframeList;
use gecko_bindings::structs::RawGeckoComputedKeyframeValuesList; use gecko_bindings::structs::RawGeckoComputedKeyframeValuesList;
use gecko_bindings::structs::RawGeckoFontFaceRuleList;
use gecko_bindings::structs::RawGeckoNode; use gecko_bindings::structs::RawGeckoNode;
use gecko_bindings::structs::RawGeckoAnimationValueList; use gecko_bindings::structs::RawGeckoAnimationValueList;
use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoAnimationValue;
@ -31,9 +32,11 @@ use gecko_bindings::structs::SheetParsingMode;
use gecko_bindings::structs::StyleBasicShape; use gecko_bindings::structs::StyleBasicShape;
use gecko_bindings::structs::StyleBasicShapeType; use gecko_bindings::structs::StyleBasicShapeType;
use gecko_bindings::structs::StyleShapeSource; use gecko_bindings::structs::StyleShapeSource;
use gecko_bindings::structs::nsCSSFontFaceRule;
use gecko_bindings::structs::nsCSSKeyword; use gecko_bindings::structs::nsCSSKeyword;
use gecko_bindings::structs::nsCSSPropertyID; use gecko_bindings::structs::nsCSSPropertyID;
use gecko_bindings::structs::nsCSSShadowArray; use gecko_bindings::structs::nsCSSShadowArray;
use gecko_bindings::structs::nsCSSUnit;
use gecko_bindings::structs::nsCSSValue; use gecko_bindings::structs::nsCSSValue;
use gecko_bindings::structs::nsCSSValueSharedList; use gecko_bindings::structs::nsCSSValueSharedList;
use gecko_bindings::structs::nsChangeHint; use gecko_bindings::structs::nsChangeHint;
@ -281,6 +284,10 @@ pub type RawGeckoComputedKeyframeValuesListBorrowed<'a> = &'a RawGeckoComputedKe
pub type RawGeckoComputedKeyframeValuesListBorrowedOrNull<'a> = Option<&'a RawGeckoComputedKeyframeValuesList>; pub type RawGeckoComputedKeyframeValuesListBorrowedOrNull<'a> = Option<&'a RawGeckoComputedKeyframeValuesList>;
pub type RawGeckoComputedKeyframeValuesListBorrowedMut<'a> = &'a mut RawGeckoComputedKeyframeValuesList; pub type RawGeckoComputedKeyframeValuesListBorrowedMut<'a> = &'a mut RawGeckoComputedKeyframeValuesList;
pub type RawGeckoComputedKeyframeValuesListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoComputedKeyframeValuesList>; pub type RawGeckoComputedKeyframeValuesListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoComputedKeyframeValuesList>;
pub type RawGeckoFontFaceRuleListBorrowed<'a> = &'a RawGeckoFontFaceRuleList;
pub type RawGeckoFontFaceRuleListBorrowedOrNull<'a> = Option<&'a RawGeckoFontFaceRuleList>;
pub type RawGeckoFontFaceRuleListBorrowedMut<'a> = &'a mut RawGeckoFontFaceRuleList;
pub type RawGeckoFontFaceRuleListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoFontFaceRuleList>;
extern "C" { extern "C" {
pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void, pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
@ -951,6 +958,9 @@ extern "C" {
pub fn Gecko_CSSValue_SetAbsoluteLength(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetAbsoluteLength(css_value: nsCSSValueBorrowedMut,
len: nscoord); len: nscoord);
} }
extern "C" {
pub fn Gecko_CSSValue_SetNormal(css_value: nsCSSValueBorrowedMut);
}
extern "C" { extern "C" {
pub fn Gecko_CSSValue_SetNumber(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetNumber(css_value: nsCSSValueBorrowedMut,
number: f32); number: f32);
@ -977,11 +987,13 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Gecko_CSSValue_SetString(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetString(css_value: nsCSSValueBorrowedMut,
string: *const u8, len: u32); string: *const u8, len: u32,
unit: nsCSSUnit);
} }
extern "C" { extern "C" {
pub fn Gecko_CSSValue_SetIdent(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetStringFromAtom(css_value: nsCSSValueBorrowedMut,
string: *const u8, len: u32); atom: *mut nsIAtom,
unit: nsCSSUnit);
} }
extern "C" { extern "C" {
pub fn Gecko_CSSValue_SetArray(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetArray(css_value: nsCSSValueBorrowedMut,
@ -992,12 +1004,8 @@ extern "C" {
uri: ServoBundledURI); uri: ServoBundledURI);
} }
extern "C" { extern "C" {
pub fn Gecko_CSSValue_SetLocal(css_value: nsCSSValueBorrowedMut, pub fn Gecko_CSSValue_SetInt(css_value: nsCSSValueBorrowedMut,
family: nsString); integer: i32, unit: nsCSSUnit);
}
extern "C" {
pub fn Gecko_CSSValue_SetInteger(css_value: nsCSSValueBorrowedMut,
integer: i32);
} }
extern "C" { extern "C" {
pub fn Gecko_CSSValue_Drop(css_value: nsCSSValueBorrowedMut); pub fn Gecko_CSSValue_Drop(css_value: nsCSSValueBorrowedMut);
@ -1030,6 +1038,19 @@ extern "C" {
extern "C" { extern "C" {
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature; pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
} }
extern "C" {
pub fn Gecko_CSSFontFaceRule_Create() -> *mut nsCSSFontFaceRule;
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_GetCssText(rule: *const nsCSSFontFaceRule,
result: *mut nsAString);
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_AddRef(aPtr: *mut nsCSSFontFaceRule);
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_Release(aPtr: *mut nsCSSFontFaceRule);
}
extern "C" { extern "C" {
pub fn Gecko_GetLookAndFeelSystemColor(color_id: i32, pub fn Gecko_GetLookAndFeelSystemColor(color_id: i32,
pres_context: pres_context:
@ -1440,6 +1461,11 @@ extern "C" {
RawGeckoKeyframeListBorrowedMut) RawGeckoKeyframeListBorrowedMut)
-> bool; -> bool;
} }
extern "C" {
pub fn Servo_StyleSet_GetFontFaceRules(set: RawServoStyleSetBorrowed,
list:
RawGeckoFontFaceRuleListBorrowedMut);
}
extern "C" { extern "C" {
pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
result: nsTArrayBorrowed_uintptr_t); result: nsTArrayBorrowed_uintptr_t);
@ -1494,6 +1520,11 @@ extern "C" {
pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed, pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed,
result: *mut nsAString); result: *mut nsAString);
} }
extern "C" {
pub fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed,
index: u32)
-> *mut nsCSSFontFaceRule;
}
extern "C" { extern "C" {
pub fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) pub fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed)
-> RawServoDeclarationBlockStrong; -> RawServoDeclarationBlockStrong;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,7 @@ use app_units::Au;
use gecko_bindings::bindings; use gecko_bindings::bindings;
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit}; use gecko_bindings::structs::{nsCSSValue, nsCSSUnit};
use gecko_bindings::structs::{nsCSSValue_Array, nscolor}; use gecko_bindings::structs::{nsCSSValue_Array, nscolor};
use gecko_string_cache::Atom;
use std::mem; use std::mem;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::slice; use std::slice;
@ -100,14 +101,56 @@ impl nsCSSValue {
} }
} }
/// Set to a normal value
pub fn set_normal(&mut self) {
unsafe { bindings::Gecko_CSSValue_SetNormal(self) }
}
fn set_string_internal(&mut self, s: &str, unit: nsCSSUnit) {
unsafe { bindings::Gecko_CSSValue_SetString(self, s.as_ptr(), s.len() as u32, unit) }
}
fn set_string_from_atom_internal(&mut self, s: &Atom, unit: nsCSSUnit) {
unsafe { bindings::Gecko_CSSValue_SetStringFromAtom(self, s.as_ptr(), unit) }
}
/// Set to a string value /// Set to a string value
pub fn set_string(&mut self, s: &str) { pub fn set_string(&mut self, s: &str) {
unsafe { bindings::Gecko_CSSValue_SetString(self, s.as_ptr(), s.len() as u32) } self.set_string_internal(s, nsCSSUnit::eCSSUnit_String)
}
/// Set to a string value from the given atom
pub fn set_string_from_atom(&mut self, s: &Atom) {
self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_String)
} }
/// Set to an identifier value /// Set to an identifier value
pub fn set_ident(&mut self, s: &str) { pub fn set_ident(&mut self, s: &str) {
unsafe { bindings::Gecko_CSSValue_SetIdent(self, s.as_ptr(), s.len() as u32) } self.set_string_internal(s, nsCSSUnit::eCSSUnit_Ident)
}
/// Set to a font format
pub fn set_font_format(&mut self, s: &str) {
self.set_string_internal(s, nsCSSUnit::eCSSUnit_Font_Format);
}
/// Set to a local font value
pub fn set_local_font(&mut self, s: &Atom) {
self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_Local_Font);
}
fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) {
unsafe { bindings::Gecko_CSSValue_SetInt(self, value, unit) }
}
/// Set to an integer value
pub fn set_integer(&mut self, value: i32) {
self.set_int_internal(value, nsCSSUnit::eCSSUnit_Integer)
}
/// Set to an enumerated value
pub fn set_enum<T: Into<i32>>(&mut self, value: T) {
self.set_int_internal(value.into(), nsCSSUnit::eCSSUnit_Enumerated);
} }
/// Set to a url value /// Set to a url value
@ -116,8 +159,9 @@ impl nsCSSValue {
} }
/// Set to an array of given length /// Set to an array of given length
pub fn set_array(&mut self, len: i32) { pub fn set_array(&mut self, len: i32) -> &mut nsCSSValue_Array {
unsafe { bindings::Gecko_CSSValue_SetArray(self, len) } unsafe { bindings::Gecko_CSSValue_SetArray(self, len) }
unsafe { self.mValue.mArray.as_mut().as_mut() }.unwrap()
} }
} }

View file

@ -235,10 +235,7 @@ impl<T: RefCounted> PartialEq for RefPtr<T> {
unsafe impl<T: ThreadSafeRefCounted> Send for RefPtr<T> {} unsafe impl<T: ThreadSafeRefCounted> Send for RefPtr<T> {}
unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {} unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {}
// Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING. macro_rules! impl_refcount {
//
// Gets you a free RefCounted impl implemented via FFI.
macro_rules! impl_threadsafe_refcount {
($t:ty, $addref:ident, $release:ident) => ( ($t:ty, $addref:ident, $release:ident) => (
unsafe impl RefCounted for $t { unsafe impl RefCounted for $t {
fn addref(&self) { fn addref(&self) {
@ -248,6 +245,18 @@ macro_rules! impl_threadsafe_refcount {
::gecko_bindings::bindings::$release(self as *const _ as *mut _) ::gecko_bindings::bindings::$release(self as *const _ as *mut _)
} }
} }
);
}
impl_refcount!(::gecko_bindings::structs::nsCSSFontFaceRule,
Gecko_CSSFontFaceRule_AddRef, Gecko_CSSFontFaceRule_Release);
// Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING.
//
// Gets you a free RefCounted impl implemented via FFI.
macro_rules! impl_threadsafe_refcount {
($t:ty, $addref:ident, $release:ident) => (
impl_refcount!($t, $addref, $release);
unsafe impl ThreadSafeRefCounted for $t {} unsafe impl ThreadSafeRefCounted for $t {}
); );
} }

View file

@ -57,7 +57,9 @@ extern crate log;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
#[macro_use] #[macro_use]
extern crate matches; extern crate matches;
#[cfg(feature = "gecko")] extern crate nsstring_vendor as nsstring; #[cfg(feature = "gecko")]
#[macro_use]
extern crate nsstring_vendor as nsstring;
#[cfg(feature = "gecko")] extern crate num_cpus; #[cfg(feature = "gecko")] extern crate num_cpus;
extern crate num_integer; extern crate num_integer;
extern crate num_traits; extern crate num_traits;

View file

@ -11,7 +11,11 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser};
use cssparser::{AtRuleType, RuleListParser, SourcePosition, Token, parse_one_rule}; use cssparser::{AtRuleType, RuleListParser, SourcePosition, Token, parse_one_rule};
use cssparser::ToCss as ParserToCss; use cssparser::ToCss as ParserToCss;
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use font_face::{FontFaceRule, parse_font_face_block}; #[cfg(feature = "servo")]
use font_face::FontFaceData;
use font_face::parse_font_face_block;
#[cfg(feature = "gecko")]
pub use gecko::rules::FontFaceRule;
use keyframes::{Keyframe, parse_keyframe_list}; use keyframes::{Keyframe, parse_keyframe_list};
use media_queries::{Device, MediaList, parse_media_query_list}; use media_queries::{Device, MediaList, parse_media_query_list};
use parking_lot::RwLock; use parking_lot::RwLock;
@ -551,6 +555,10 @@ impl ToCssWithGuard for StyleRule {
} }
} }
/// A @font-face rule
#[cfg(feature = "servo")]
pub type FontFaceRule = FontFaceData;
impl Stylesheet { impl Stylesheet {
/// Updates an empty stylesheet from a given string of text. /// Updates an empty stylesheet from a given string of text.
pub fn update_from_str(existing: &Stylesheet, pub fn update_from_str(existing: &Stylesheet,
@ -1004,7 +1012,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
match prelude { match prelude {
AtRulePrelude::FontFace => { AtRulePrelude::FontFace => {
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap( Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
try!(parse_font_face_block(self.context, input)))))) parse_font_face_block(self.context, input)?.into()))))
} }
AtRulePrelude::Media(media_queries) => { AtRulePrelude::Media(media_queries) => {
Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule { Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {

View file

@ -34,9 +34,11 @@ use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
#[cfg(feature = "servo")]
use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use stylesheets::{CssRule, Origin, StyleRule, Stylesheet, UserAgentStylesheets}; use stylesheets::{CssRule, FontFaceRule, Origin, StyleRule, Stylesheet, UserAgentStylesheets};
use thread_state; use thread_state;
use viewport::{self, MaybeNew, ViewportRule}; use viewport::{self, MaybeNew, ViewportRule};
@ -118,6 +120,37 @@ pub struct Stylist {
non_common_style_affecting_attributes_selectors: Vec<Selector<SelectorImpl>>, non_common_style_affecting_attributes_selectors: Vec<Selector<SelectorImpl>>,
} }
/// This struct holds data which user of Stylist may want to extract
/// from stylesheets which can be done at the same time as updating.
pub struct ExtraStyleData<'a> {
/// A list of effective font-face rules and their origin.
#[cfg(feature = "gecko")]
pub font_faces: &'a mut Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
#[allow(missing_docs)]
#[cfg(feature = "servo")]
pub marker: PhantomData<&'a usize>,
}
#[cfg(feature = "gecko")]
impl<'a> ExtraStyleData<'a> {
/// Clear the internal @font-face rule list.
fn clear_font_faces(&mut self) {
self.font_faces.clear();
}
/// Add the given @font-face rule.
fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, origin: Origin) {
self.font_faces.push((rule.clone(), origin));
}
}
#[cfg(feature = "servo")]
impl<'a> ExtraStyleData<'a> {
fn clear_font_faces(&mut self) {}
fn add_font_face(&mut self, _: &Arc<Locked<FontFaceRule>>, _: Origin) {}
}
impl Stylist { impl Stylist {
/// Construct a new `Stylist`, using a given `Device`. /// Construct a new `Stylist`, using a given `Device`.
#[inline] #[inline]
@ -156,11 +189,12 @@ impl Stylist {
/// This method resets all the style data each time the stylesheets change /// This method resets all the style data each time the stylesheets change
/// (which is indicated by the `stylesheets_changed` parameter), or the /// (which is indicated by the `stylesheets_changed` parameter), or the
/// device is dirty, which means we need to re-evaluate media queries. /// device is dirty, which means we need to re-evaluate media queries.
pub fn update(&mut self, pub fn update<'a>(&mut self,
doc_stylesheets: &[Arc<Stylesheet>], doc_stylesheets: &[Arc<Stylesheet>],
guards: &StylesheetGuards, guards: &StylesheetGuards,
ua_stylesheets: Option<&UserAgentStylesheets>, ua_stylesheets: Option<&UserAgentStylesheets>,
stylesheets_changed: bool) -> bool { stylesheets_changed: bool,
extra_data: &mut ExtraStyleData<'a>) -> bool {
if !(self.is_device_dirty || stylesheets_changed) { if !(self.is_device_dirty || stylesheets_changed) {
return false; return false;
} }
@ -194,18 +228,21 @@ impl Stylist {
self.sibling_affecting_selectors.clear(); self.sibling_affecting_selectors.clear();
self.non_common_style_affecting_attributes_selectors.clear(); self.non_common_style_affecting_attributes_selectors.clear();
extra_data.clear_font_faces();
if let Some(ua_stylesheets) = ua_stylesheets { if let Some(ua_stylesheets) = ua_stylesheets {
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
self.add_stylesheet(&stylesheet, guards.ua_or_user); self.add_stylesheet(&stylesheet, guards.ua_or_user, extra_data);
} }
if self.quirks_mode { if self.quirks_mode {
self.add_stylesheet(&ua_stylesheets.quirks_mode_stylesheet, guards.ua_or_user); self.add_stylesheet(&ua_stylesheets.quirks_mode_stylesheet,
guards.ua_or_user, extra_data);
} }
} }
for ref stylesheet in doc_stylesheets.iter() { for ref stylesheet in doc_stylesheets.iter() {
self.add_stylesheet(stylesheet, guards.author); self.add_stylesheet(stylesheet, guards.author, extra_data);
} }
debug!("Stylist stats:"); debug!("Stylist stats:");
@ -230,7 +267,8 @@ impl Stylist {
true true
} }
fn add_stylesheet(&mut self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard) { fn add_stylesheet<'a>(&mut self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard,
extra_data: &mut ExtraStyleData<'a>) {
if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device, guard) { if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device, guard) {
return; return;
} }
@ -274,7 +312,7 @@ impl Stylist {
} }
CssRule::Import(ref import) => { CssRule::Import(ref import) => {
let import = import.read_with(guard); let import = import.read_with(guard);
self.add_stylesheet(&import.stylesheet, guard) self.add_stylesheet(&import.stylesheet, guard, extra_data)
} }
CssRule::Keyframes(ref keyframes_rule) => { CssRule::Keyframes(ref keyframes_rule) => {
let keyframes_rule = keyframes_rule.read_with(guard); let keyframes_rule = keyframes_rule.read_with(guard);
@ -284,6 +322,9 @@ impl Stylist {
debug!("Found valid keyframe animation: {:?}", animation); debug!("Found valid keyframe animation: {:?}", animation);
self.animations.insert(keyframes_rule.name.clone(), animation); self.animations.insert(keyframes_rule.name.clone(), animation);
} }
CssRule::FontFace(ref rule) => {
extra_data.add_font_face(&rule, stylesheet.origin);
}
// We don't care about any other rule. // We don't care about any other rule.
_ => {} _ => {}
} }

View file

@ -43,6 +43,7 @@ use style::gecko_bindings::bindings::{nsACString, nsAString};
use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe; use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut; use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoElementBorrowed; use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueStrong; use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
@ -54,7 +55,7 @@ use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
use style::gecko_bindings::structs; use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder}; use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint}; use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, nsCSSFontFaceRule};
use style::gecko_bindings::structs::Loader; use style::gecko_bindings::structs::Loader;
use style::gecko_bindings::structs::RawGeckoPresContextOwned; use style::gecko_bindings::structs::RawGeckoPresContextOwned;
use style::gecko_bindings::structs::ServoStyleSheet; use style::gecko_bindings::structs::ServoStyleSheet;
@ -602,6 +603,19 @@ impl_basic_rule_funcs! { (Namespace, NamespaceRule, RawServoNamespaceRule),
to_css: Servo_NamespaceRule_GetCssText, to_css: Servo_NamespaceRule_GetCssText,
} }
#[no_mangle]
pub extern "C" fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed, index: u32)
-> *mut nsCSSFontFaceRule
{
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
match rules.0[index as usize] {
CssRule::FontFace(ref rule) => rule.read_with(&guard).get(),
_ => unreachable!("Servo_CssRules_GetFontFaceRuleAt should only be called on a FontFace rule"),
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong { pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong {
read_locked_arc(rule, |rule: &StyleRule| { read_locked_arc(rule, |rule: &StyleRule| {
@ -1730,3 +1744,18 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
false false
} }
#[no_mangle]
pub extern "C" fn Servo_StyleSet_GetFontFaceRules(raw_data: RawServoStyleSetBorrowed,
rules: RawGeckoFontFaceRuleListBorrowedMut) {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
debug_assert!(rules.len() == 0);
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
unsafe { rules.set_len(data.font_faces.len() as u32) };
for (src, dest) in data.font_faces.iter().zip(rules.iter_mut()) {
dest.mRule = src.0.read_with(&guard).clone().forget();
dest.mSheetType = src.1.into();
}
}

View file

@ -5,7 +5,7 @@
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use ipc_channel::ipc; use ipc_channel::ipc;
use style::computed_values::font_family::FamilyName; use style::computed_values::font_family::FamilyName;
use style::font_face::{FontFaceRule, Source}; use style::font_face::{FontFaceData, Source};
#[test] #[test]
fn test_local_web_font() { fn test_local_web_font() {
@ -14,7 +14,7 @@ fn test_local_web_font() {
let font_cache_thread = FontCacheThread::new(inp_chan, None); let font_cache_thread = FontCacheThread::new(inp_chan, None);
let family_name = FamilyName(From::from("test family")); let family_name = FamilyName(From::from("test family"));
let variant_name = FamilyName(From::from("test font face")); let variant_name = FamilyName(From::from("test font face"));
let font_face_rule = FontFaceRule { let font_face_rule = FontFaceData {
family: family_name.clone(), family: family_name.clone(),
sources: vec![Source::Local(variant_name)], sources: vec![Source::Local(variant_name)],
}; };