servo: Merge #16959 - Font serialization for canvas (from hiikezoe:font-serialization-for-canvas); r=Manishearth,emilio

<!-- Please describe your changes on the following line: -->
This is a PR for https://bugzilla.mozilla.org/show_bug.cgi?id=1362914
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes do not require tests because it's for stylo

Source-Repo: https://github.com/servo/servo
Source-Revision: 8cd4330b2afdaf6f5a1724539a25a27850d41e29

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 6da2098f9c326659f9bae725f89714ce908edf12
This commit is contained in:
Hiroyuki Ikezoe 2017-05-21 23:22:35 -05:00
Родитель f50286022e
Коммит 34fd4e6344
6 изменённых файлов: 128 добавлений и 48 удалений

Просмотреть файл

@ -2471,6 +2471,11 @@ extern "C" {
CSSPseudoElementType)
-> ServoComputedValuesStrong;
}
extern "C" {
pub fn Servo_SerializeFontValueForCanvas(declarations:
RawServoDeclarationBlockBorrowed,
buffer: *mut nsAString);
}
extern "C" {
pub fn Servo_GetStyleFont(computed_values:
ServoComputedValuesBorrowedOrNull)

Просмотреть файл

@ -34192,7 +34192,7 @@ pub mod root {
root::nsCharTraits ) ));
}
#[test]
fn __bindgen_test_layout__bindgen_ty_id_210589_instantiation_99() {
fn __bindgen_test_layout__bindgen_ty_id_210592_instantiation_99() {
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
"Size of template specialization: " , stringify ! ( u8 )
));
@ -34201,7 +34201,7 @@ pub mod root {
) ));
}
#[test]
fn __bindgen_test_layout__bindgen_ty_id_210625_instantiation_100() {
fn __bindgen_test_layout__bindgen_ty_id_210628_instantiation_100() {
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
"Size of template specialization: " , stringify ! ( u8 )
));

Просмотреть файл

@ -33682,7 +33682,7 @@ pub mod root {
root::nsCharTraits ) ));
}
#[test]
fn __bindgen_test_layout__bindgen_ty_id_206916_instantiation_97() {
fn __bindgen_test_layout__bindgen_ty_id_206919_instantiation_97() {
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
"Size of template specialization: " , stringify ! ( u8 )
));
@ -33691,7 +33691,7 @@ pub mod root {
) ));
}
#[test]
fn __bindgen_test_layout__bindgen_ty_id_206952_instantiation_98() {
fn __bindgen_test_layout__bindgen_ty_id_206955_instantiation_98() {
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
"Size of template specialization: " , stringify ! ( u8 )
));

Просмотреть файл

@ -12,6 +12,7 @@ use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
use std::fmt;
use std::slice::Iter;
use style_traits::ToCss;
use stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*;
@ -54,6 +55,25 @@ pub struct PropertyDeclarationBlock {
longhands: LonghandIdSet,
}
/// Iterator for PropertyDeclaration to be generated from PropertyDeclarationBlock.
#[derive(Clone)]
pub struct PropertyDeclarationIterator<'a> {
iter: Iter<'a, (PropertyDeclaration, Importance)>,
}
impl<'a> Iterator for PropertyDeclarationIterator<'a> {
type Item = &'a PropertyDeclaration;
#[inline]
fn next(&mut self) -> Option<&'a PropertyDeclaration> {
// we use this function because a closure won't be `Clone`
fn get_declaration(dec: &(PropertyDeclaration, Importance))
-> &PropertyDeclaration {
&dec.0
}
self.iter.next().map(get_declaration as fn(_) -> _)
}
}
impl fmt::Debug for PropertyDeclarationBlock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.declarations.fmt(f)
@ -93,6 +113,13 @@ impl PropertyDeclarationBlock {
&self.declarations
}
/// Iterate over only PropertyDeclaration.
pub fn declarations_iter(&self) -> PropertyDeclarationIterator {
PropertyDeclarationIterator {
iter: self.declarations.iter(),
}
}
/// Returns whether this block contains any declaration with `!important`.
///
/// This is based on the `important_count` counter,
@ -369,15 +396,10 @@ impl PropertyDeclarationBlock {
}
}
Ok(shorthand) => {
// we use this function because a closure won't be `Clone`
fn get_declaration(dec: &(PropertyDeclaration, Importance))
-> &PropertyDeclaration {
&dec.0
}
if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
return Err(fmt::Error)
}
let iter = self.declarations.iter().map(get_declaration as fn(_) -> _);
let iter = self.declarations_iter();
match shorthand.get_shorthand_appendable_value(iter) {
Some(AppendableValue::Css { css, .. }) => {
dest.write_str(css)

Просмотреть файл

@ -122,8 +122,67 @@
SomeSystem,
None
}
% endif
enum SerializeFor {
Normal,
% if product == "gecko":
Canvas,
% endif
}
impl<'a> LonghandsToSerialize<'a> {
impl<'a> LonghandsToSerialize<'a> {
fn to_css_for<W>(&self,
serialize_for: SerializeFor,
dest: &mut W) -> fmt::Result where W: fmt::Write {
% if product == "gecko":
match self.check_system() {
CheckSystemResult::AllSystem(sys) => return sys.to_css(dest),
CheckSystemResult::SomeSystem => return Ok(()),
CheckSystemResult::None => ()
}
% endif
% if product == "gecko" or data.testing:
% for name in gecko_sub_properties:
if self.font_${name} != &font_${name}::get_initial_specified_value() {
return Ok(());
}
% endfor
% endif
// In case of serialization for canvas font, we need to drop
// initial values of properties other than size and family.
% for name in "style variant_caps weight stretch".split():
let needs_this_property = match serialize_for {
SerializeFor::Normal => true,
% if product == "gecko":
SerializeFor::Canvas =>
self.font_${name} != &font_${name}::get_initial_specified_value(),
% endif
};
if needs_this_property {
self.font_${name}.to_css(dest)?;
dest.write_str(" ")?;
}
% endfor
self.font_size.to_css(dest)?;
match *self.line_height {
line_height::SpecifiedValue::Normal => {},
_ => {
dest.write_str("/")?;
self.line_height.to_css(dest)?;
}
}
dest.write_str(" ")?;
self.font_family.to_css(dest)?;
Ok(())
}
% if product == "gecko":
/// Check if some or all members are system fonts
fn check_system(&self) -> CheckSystemResult {
let mut sys = None;
@ -148,47 +207,18 @@
CheckSystemResult::None
}
}
}
% endif
/// Serialize the shorthand value for canvas font attribute.
pub fn to_css_for_canvas<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.to_css_for(SerializeFor::Canvas, dest)
}
% endif
}
// This may be a bit off, unsure, possibly needs changes
impl<'a> ToCss for LonghandsToSerialize<'a> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
% if product == "gecko":
match self.check_system() {
CheckSystemResult::AllSystem(sys) => return sys.to_css(dest),
CheckSystemResult::SomeSystem => return Ok(()),
CheckSystemResult::None => ()
}
% endif
% if product == "gecko" or data.testing:
% for name in gecko_sub_properties:
if self.font_${name} != &font_${name}::get_initial_specified_value() {
return Ok(());
}
% endfor
% endif
% for name in "style variant_caps weight stretch".split():
self.font_${name}.to_css(dest)?;
dest.write_str(" ")?;
% endfor
self.font_size.to_css(dest)?;
match *self.line_height {
line_height::SpecifiedValue::Normal => {},
_ => {
dest.write_str("/")?;
self.line_height.to_css(dest)?;
}
}
dest.write_str(" ")?;
self.font_family.to_css(dest)?;
Ok(())
self.to_css_for(SerializeFor::Normal, dest)
}
}
</%helpers:shorthand>

Просмотреть файл

@ -1434,6 +1434,29 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
})
}
#[no_mangle]
pub extern "C" fn Servo_SerializeFontValueForCanvas(
declarations: RawServoDeclarationBlockBorrowed,
buffer: *mut nsAString) {
use style::properties::shorthands::font;
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
let longhands = match font::LonghandsToSerialize::from_iter(decls.declarations_iter()) {
Ok(l) => l,
Err(()) => {
warn!("Unexpected property!");
return;
}
};
let mut string = String::new();
let rv = longhands.to_css_for_canvas(&mut string);
debug_assert!(rv.is_ok());
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
})
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {