mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #16959 - hiikezoe:font-serialization-for-canvas, r=Manishearth,emilio
Font serialization for canvas <!-- 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 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16959) <!-- Reviewable:end -->
This commit is contained in:
commit
8cd4330b2a
6 changed files with 128 additions and 48 deletions
|
@ -2471,6 +2471,11 @@ extern "C" {
|
||||||
CSSPseudoElementType)
|
CSSPseudoElementType)
|
||||||
-> ServoComputedValuesStrong;
|
-> ServoComputedValuesStrong;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_SerializeFontValueForCanvas(declarations:
|
||||||
|
RawServoDeclarationBlockBorrowed,
|
||||||
|
buffer: *mut nsAString);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_GetStyleFont(computed_values:
|
pub fn Servo_GetStyleFont(computed_values:
|
||||||
ServoComputedValuesBorrowedOrNull)
|
ServoComputedValuesBorrowedOrNull)
|
||||||
|
|
|
@ -34192,7 +34192,7 @@ pub mod root {
|
||||||
root::nsCharTraits ) ));
|
root::nsCharTraits ) ));
|
||||||
}
|
}
|
||||||
#[test]
|
#[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 ! (
|
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
|
||||||
"Size of template specialization: " , stringify ! ( u8 )
|
"Size of template specialization: " , stringify ! ( u8 )
|
||||||
));
|
));
|
||||||
|
@ -34201,7 +34201,7 @@ pub mod root {
|
||||||
) ));
|
) ));
|
||||||
}
|
}
|
||||||
#[test]
|
#[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 ! (
|
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
|
||||||
"Size of template specialization: " , stringify ! ( u8 )
|
"Size of template specialization: " , stringify ! ( u8 )
|
||||||
));
|
));
|
||||||
|
|
|
@ -33682,7 +33682,7 @@ pub mod root {
|
||||||
root::nsCharTraits ) ));
|
root::nsCharTraits ) ));
|
||||||
}
|
}
|
||||||
#[test]
|
#[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 ! (
|
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
|
||||||
"Size of template specialization: " , stringify ! ( u8 )
|
"Size of template specialization: " , stringify ! ( u8 )
|
||||||
));
|
));
|
||||||
|
@ -33691,7 +33691,7 @@ pub mod root {
|
||||||
) ));
|
) ));
|
||||||
}
|
}
|
||||||
#[test]
|
#[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 ! (
|
assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
|
||||||
"Size of template specialization: " , stringify ! ( u8 )
|
"Size of template specialization: " , stringify ! ( u8 )
|
||||||
));
|
));
|
||||||
|
|
|
@ -12,6 +12,7 @@ use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
|
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::slice::Iter;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -54,6 +55,25 @@ pub struct PropertyDeclarationBlock {
|
||||||
longhands: LonghandIdSet,
|
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 {
|
impl fmt::Debug for PropertyDeclarationBlock {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.declarations.fmt(f)
|
self.declarations.fmt(f)
|
||||||
|
@ -93,6 +113,13 @@ impl PropertyDeclarationBlock {
|
||||||
&self.declarations
|
&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`.
|
/// Returns whether this block contains any declaration with `!important`.
|
||||||
///
|
///
|
||||||
/// This is based on the `important_count` counter,
|
/// This is based on the `important_count` counter,
|
||||||
|
@ -369,15 +396,10 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(shorthand) => {
|
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)) {
|
if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
|
||||||
return Err(fmt::Error)
|
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) {
|
match shorthand.get_shorthand_appendable_value(iter) {
|
||||||
Some(AppendableValue::Css { css, .. }) => {
|
Some(AppendableValue::Css { css, .. }) => {
|
||||||
dest.write_str(css)
|
dest.write_str(css)
|
||||||
|
|
|
@ -122,8 +122,67 @@
|
||||||
SomeSystem,
|
SomeSystem,
|
||||||
None
|
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
|
/// Check if some or all members are system fonts
|
||||||
fn check_system(&self) -> CheckSystemResult {
|
fn check_system(&self) -> CheckSystemResult {
|
||||||
let mut sys = None;
|
let mut sys = None;
|
||||||
|
@ -148,47 +207,18 @@
|
||||||
CheckSystemResult::None
|
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
|
// This may be a bit off, unsure, possibly needs changes
|
||||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
% if product == "gecko":
|
self.to_css_for(SerializeFor::Normal, dest)
|
||||||
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(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%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]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
|
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
|
||||||
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue