Skip to content

Commit

Permalink
Auto merge of #16187 - upsuper:bug1345696, r=Manishearth,heycam
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors-servo committed Mar 30, 2017
2 parents 0f9dbcc + 5c9152e commit 2084ee2
Show file tree
Hide file tree
Showing 19 changed files with 9,828 additions and 8,509 deletions.
9 changes: 7 additions & 2 deletions components/layout_thread/lib.rs
Expand Up @@ -98,6 +98,7 @@ use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::marker::PhantomData;
use std::mem as std_mem;
use std::ops::{Deref, DerefMut};
use std::process;
Expand All @@ -116,7 +117,7 @@ use style::parser::ParserContextExtraData;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets};
use style::stylist::Stylist;
use style::stylist::{ExtraStyleData, Stylist};
use style::thread_state;
use style::timer::Timer;
use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags};
Expand Down Expand Up @@ -1078,11 +1079,15 @@ impl LayoutThread {
author: &author_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(
&data.document_stylesheets,
&guards,
Some(ua_stylesheets),
data.stylesheets_changed);
data.stylesheets_changed,
&mut extra_data);
let needs_reflow = viewport_size_changed && !needs_dirtying;
if needs_dirtying {
if let Some(mut d) = element.mutate_data() {
Expand Down
5 changes: 2 additions & 3 deletions components/script/dom/bindings/trace.rs
Expand Up @@ -94,14 +94,13 @@ use std::time::{SystemTime, Instant};
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
use style::context::QuirksMode;
use style::element_state::*;
use style::font_face::FontFaceRule;
use style::keyframes::Keyframe;
use style::media_queries::MediaList;
use style::properties::PropertyDeclarationBlock;
use style::selector_parser::{PseudoElement, Snapshot};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule};
use style::stylesheets::SupportsRule;
use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule};
use style::stylesheets::{NamespaceRule, StyleRule, ImportRule, SupportsRule};
use style::values::specified::Length;
use style::viewport::ViewportRule;
use time::Duration;
Expand Down
2 changes: 1 addition & 1 deletion components/script/dom/cssfontfacerule.rs
Expand Up @@ -11,8 +11,8 @@ use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use dom_struct::dom_struct;
use std::sync::Arc;
use style::font_face::FontFaceRule;
use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::FontFaceRule;

#[dom_struct]
pub struct CSSFontFaceRule {
Expand Down
7 changes: 7 additions & 0 deletions components/style/build_gecko.rs
Expand Up @@ -258,6 +258,7 @@ mod bindings {
vars: true,
..CodegenConfig::nothing()
})
.include(add_include("nsCSSPseudoClasses.h")) // servo/rust-bindgen#599
.header(add_include("nsStyleStruct.h"))
.include(add_include("mozilla/ServoPropPrefList.h"))
.header(add_include("mozilla/StyleAnimationValue.h"))
Expand All @@ -270,6 +271,7 @@ mod bindings {
.include(add_include("mozilla/dom/NameSpaceConstants.h"))
.include(add_include("mozilla/LookAndFeel.h"))
.include(add_include("mozilla/ServoBindings.h"))
.include(add_include("nsCSSFontFaceRule.h"))
.include(add_include("nsMediaFeatures.h"))
.include(add_include("nsMediaList.h"))
// FIXME(emilio): Incrementally remove these "pub use"s. Probably
Expand Down Expand Up @@ -336,6 +338,7 @@ mod bindings {
"nsBorderColors",
"nscolor",
"nsChangeHint",
"nsCSSFontFaceRule",
"nsCSSKeyword",
"nsCSSPropertyID",
"nsCSSProps",
Expand Down Expand Up @@ -585,6 +588,7 @@ mod bindings {
"RawGeckoElement",
"RawGeckoKeyframeList",
"RawGeckoComputedKeyframeValuesList",
"RawGeckoFontFaceRuleList",
"RawGeckoNode",
"RawGeckoAnimationValueList",
"RawServoAnimationValue",
Expand All @@ -608,9 +612,11 @@ mod bindings {
"StyleBasicShape",
"StyleBasicShapeType",
"StyleShapeSource",
"nsCSSFontFaceRule",
"nsCSSKeyword",
"nsCSSPropertyID",
"nsCSSShadowArray",
"nsCSSUnit",
"nsCSSValue",
"nsCSSValueSharedList",
"nsChangeHint",
Expand Down Expand Up @@ -701,6 +707,7 @@ mod bindings {
"RawGeckoAnimationValueList",
"RawGeckoKeyframeList",
"RawGeckoComputedKeyframeValuesList",
"RawGeckoFontFaceRuleList",
];
for &ty in structs_types.iter() {
builder = builder.hide_type(ty)
Expand Down
18 changes: 9 additions & 9 deletions components/style/font_face.rs
Expand Up @@ -75,8 +75,8 @@ impl ToCss for UrlSource {
///
/// Note that the prelude parsing code lives in the `stylesheets` module.
pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
-> Result<FontFaceRule, ()> {
let mut rule = FontFaceRule::initial();
-> Result<FontFaceData, ()> {
let mut rule = FontFaceData::initial();
{
let parser = FontFaceRuleParser {
context: context,
Expand Down Expand Up @@ -104,7 +104,7 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub struct EffectiveSources(Vec<Source>);

impl FontFaceRule {
impl FontFaceData {
/// 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
/// least "truetype" or "opentype".
Expand Down Expand Up @@ -134,7 +134,7 @@ impl iter::Iterator for EffectiveSources {

struct FontFaceRuleParser<'a, 'b: 'a> {
context: &'a ParserContext<'b>,
rule: &'a mut FontFaceRule,
rule: &'a mut FontFaceData,
missing: MissingDescriptors,
}

Expand Down Expand Up @@ -181,11 +181,11 @@ macro_rules! font_face_descriptors {
$( #[$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
#[derive(Debug, PartialEq, Eq)]
pub struct FontFaceRule {
pub struct FontFaceData {
$(
#[$m_doc]
pub $m_ident: $m_ty,
Expand Down Expand Up @@ -218,9 +218,9 @@ macro_rules! font_face_descriptors {
}
}

impl FontFaceRule {
impl FontFaceData {
fn initial() -> Self {
FontFaceRule {
FontFaceData {
$(
$m_ident: $m_initial,
)*
Expand All @@ -231,7 +231,7 @@ macro_rules! font_face_descriptors {
}
}

impl ToCssWithGuard for FontFaceRule {
impl ToCssWithGuard for FontFaceData {
// Serialization of FontFaceRule is not specced.
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
Expand Down
14 changes: 12 additions & 2 deletions components/style/gecko/conversions.rs
Expand Up @@ -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_InitializeImageCropRect;
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 stylesheets::RulesMutateError;
use stylesheets::{Origin, RulesMutateError};
use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto};

impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
Expand Down Expand Up @@ -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,
}
}
}
16 changes: 12 additions & 4 deletions components/style/gecko/data.rs
Expand Up @@ -13,12 +13,12 @@ use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
use media_queries::Device;
use parking_lot::RwLock;
use properties::ComputedValues;
use shared_lock::{StylesheetGuards, SharedRwLockReadGuard};
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, channel};
use stylesheets::Stylesheet;
use stylist::Stylist;
use stylesheets::{FontFaceRule, Origin, Stylesheet};
use stylist::{ExtraStyleData, Stylist};

/// The container for data that a Servo-backed Gecko document needs to style
/// itself.
Expand All @@ -45,6 +45,9 @@ pub struct PerDocumentStyleDataImpl {
/// Unused. Will go away when we actually implement transitions and
/// animations properly.
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
Expand All @@ -66,6 +69,7 @@ impl PerDocumentStyleData {
new_animations_receiver: new_anims_receiver,
running_animations: Arc::new(RwLock::new(HashMap::new())),
expired_animations: Arc::new(RwLock::new(HashMap::new())),
font_faces: vec![],
}))
}

Expand Down Expand Up @@ -97,7 +101,11 @@ impl PerDocumentStyleDataImpl {
pub fn flush_stylesheets(&mut self, guard: &SharedRwLockReadGuard) {
if self.stylesheets_changed {
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;
}
}
Expand Down
1 change: 1 addition & 0 deletions components/style/gecko/mod.rs
Expand Up @@ -13,6 +13,7 @@ pub mod data;
pub mod global_style_data;
pub mod media_queries;
pub mod restyle_damage;
pub mod rules;
pub mod selector_parser;
pub mod snapshot;
pub mod snapshot_helpers;
Expand Down
121 changes: 121 additions & 0 deletions components/style/gecko/rules.rs
@@ -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)
}
}

0 comments on commit 2084ee2

Please sign in to comment.