style: Use cbindgen for text-decoration-line.

Differential Revision: https://phabricator.services.mozilla.com/D23412
This commit is contained in:
Emilio Cobos Álvarez 2019-03-18 17:58:16 +00:00
parent 4b07af2240
commit b0af565656
6 changed files with 110 additions and 158 deletions

View file

@ -105,6 +105,7 @@ include = [
"WordBreak",
"Contain",
"RestyleHint",
"TextDecorationLine",
]
item_types = ["enums", "structs", "typedefs"]

View file

@ -3996,9 +3996,7 @@ fn static_assert() {
</%self:impl_trait>
<%self:impl_trait style_struct_name="Text"
skip_longhands="text-decoration-line text-overflow initial-letter">
${impl_simple_type_with_conversion("text_decoration_line")}
skip_longhands="text-overflow initial-letter">
fn clear_overflow_sides_if_string(&mut self) {
use crate::gecko_bindings::structs::nsStyleTextOverflowSide;
@ -4112,21 +4110,6 @@ fn static_assert() {
InitialLetter::Specified(self.gecko.mInitialLetterSize, Some(self.gecko.mInitialLetterSink))
}
}
#[inline]
pub fn has_underline(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
}
#[inline]
pub fn has_overline(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
}
#[inline]
pub fn has_line_through(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
}
</%self:impl_trait>
// Set SVGPathData to StyleShapeSource.

View file

@ -5,16 +5,7 @@
<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method %>
<% data.new_style_struct(
"Text",
inherited=False,
gecko_name="TextReset",
additional_methods=[
Method("has_underline", "bool"),
Method("has_overline", "bool"),
Method("has_line_through", "bool"),
]
) %>
<% data.new_style_struct("Text", inherited=False, gecko_name="TextReset") %>
${helpers.predefined_type(
"text-overflow",

View file

@ -2638,24 +2638,6 @@ pub mod style_structs {
use crate::Zero;
!self.outline_width.is_zero()
}
% elif style_struct.name == "Text":
/// Whether the text decoration has an underline.
#[inline]
pub fn has_underline(&self) -> bool {
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::UNDERLINE)
}
/// Whether the text decoration has an overline.
#[inline]
pub fn has_overline(&self) -> bool {
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::OVERLINE)
}
/// Whether the text decoration has a line through.
#[inline]
pub fn has_line_through(&self) -> bool {
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::LINE_THROUGH)
}
% elif style_struct.name == "Box":
/// Sets the display property, but without touching original_display,
/// except when the adjustment comes from root or item display fixups.

View file

@ -19,7 +19,7 @@ use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
pub use crate::values::specified::TextAlignKeyword as TextAlign;
pub use crate::values::specified::TextEmphasisPosition;
pub use crate::values::specified::{TextEmphasisPosition, TextDecorationLine};
pub use crate::values::specified::{OverflowWrap, WordBreak};
/// A computed value for the `initial-letter` property.
@ -182,11 +182,11 @@ impl TextDecorationsInEffect {
.clone(),
};
let text_style = style.get_text();
let line = style.get_text().clone_text_decoration_line();
result.underline |= text_style.has_underline();
result.overline |= text_style.has_overline();
result.line_through |= text_style.has_line_through();
result.underline |= line.contains(TextDecorationLine::UNDERLINE);
result.overline |= line.contains(TextDecorationLine::OVERLINE);
result.line_through |= line.contains(TextDecorationLine::LINE_THROUGH);
result
}

View file

@ -22,8 +22,7 @@ use cssparser::{Parser, Token};
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
use style_traits::values::SequenceWriter;
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use unicode_segmentation::UnicodeSegmentation;
/// A specified type for the `initial-letter` property.
@ -255,24 +254,22 @@ impl ToComputedValue for TextOverflow {
}
}
macro_rules! impl_text_decoration_line {
{
$(
$(#[$($meta:tt)+])*
$ident:ident / $css:expr => $value:expr,
)+
} => {
bitflags! {
#[derive(MallocSizeOf, ToComputedValue)]
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue)]
#[value_info(other_values = "none,underline,overline,line-through,blink")]
#[repr(C)]
/// Specified keyword values for the text-decoration-line property.
pub struct TextDecorationLine: u8 {
/// No text decoration line is specified
/// No text decoration line is specified.
const NONE = 0;
$(
$(#[$($meta)+])*
const $ident = $value;
)+
#[cfg(feature = "gecko")]
/// underline
const UNDERLINE = 1 << 0;
/// overline
const OVERLINE = 1 << 1;
/// line-through
const LINE_THROUGH = 1 << 2;
/// blink
const BLINK = 1 << 3;
/// Only set by presentation attributes
///
/// Setting this will mean that text-decorations use the color
@ -280,44 +277,51 @@ macro_rules! impl_text_decoration_line {
///
/// For example, this gives <a href=foo><font color="red">text</font></a>
/// a red text decoration
#[cfg(feature = "gecko")]
const COLOR_OVERRIDE = 0x10;
}
}
impl Parse for TextDecorationLine {
/// none | [ underline || overline || line-through || blink ]
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<TextDecorationLine, ParseError<'i>> {
let mut result = TextDecorationLine::NONE;
if input
.try(|input| input.expect_ident_matching("none"))
.is_ok()
{
return Ok(result);
) -> Result<Self, ParseError<'i>> {
let mut result = TextDecorationLine::empty();
// NOTE(emilio): this loop has this weird structure because we run this
// code to parse the text-decoration shorthand as well, so we need to
// ensure we don't return an error if we don't consume the whole thing
// because we find an invalid identifier or other kind of token.
loop {
let flag: Result<_, ParseError<'i>> = input.try(|input| {
let flag = try_match_ident_ignore_ascii_case! { input,
"none" if result.is_empty() => TextDecorationLine::NONE,
"underline" => TextDecorationLine::UNDERLINE,
"overline" => TextDecorationLine::OVERLINE,
"line-through" => TextDecorationLine::LINE_THROUGH,
"blink" => TextDecorationLine::BLINK,
};
Ok(flag)
});
let flag = match flag {
Ok(flag) => flag,
Err(..) => break,
};
if flag.is_empty() {
return Ok(TextDecorationLine::NONE);
}
loop {
let result = input.try(|input| {
let ident = input.expect_ident().map_err(|_| ())?;
match_ignore_ascii_case! { ident,
$(
$css => {
if result.contains(TextDecorationLine::$ident) {
Err(())
} else {
result.insert(TextDecorationLine::$ident);
Ok(())
}
}
)+
_ => Err(()),
}
});
if result.is_err() {
break;
if result.contains(flag) {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
result.insert(flag)
}
if !result.is_empty() {
@ -338,37 +342,28 @@ macro_rules! impl_text_decoration_line {
}
let mut writer = SequenceWriter::new(dest, " ");
$(
let mut any = false;
macro_rules! maybe_write {
($ident:ident => $str:expr) => {
if self.contains(TextDecorationLine::$ident) {
writer.raw_item($css)?;
any = true;
writer.raw_item($str)?;
}
)+
};
}
maybe_write!(UNDERLINE => "underline");
maybe_write!(OVERLINE => "overline");
maybe_write!(LINE_THROUGH => "line-through");
maybe_write!(BLINK => "blink");
debug_assert!(any || *self == TextDecorationLine::COLOR_OVERRIDE);
Ok(())
}
}
impl SpecifiedValueInfo for TextDecorationLine {
fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&["none", $($css,)+]);
}
}
}
}
impl_text_decoration_line! {
/// Underline
UNDERLINE / "underline" => 1 << 0,
/// Overline
OVERLINE / "overline" => 1 << 1,
/// Line through
LINE_THROUGH / "line-through" => 1 << 2,
/// Blink
BLINK / "blink" => 1 << 3,
}
#[cfg(feature = "gecko")]
impl_bitflags_conversions!(TextDecorationLine);
impl TextDecorationLine {
#[inline]
/// Returns the initial value of text-decoration-line