mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #25888 - ferjm:text.decoration.2020, r=nox
Partial text decoration support for layout 2020 - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #25166 - [X] There are tests for these changes
This commit is contained in:
commit
acd14672e1
84 changed files with 743 additions and 53 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
use crate::geom::{PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize};
|
||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||
use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
|
||||
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
||||
use style::values::computed::Filter as ComputedFilter;
|
||||
use style::values::computed::Length;
|
||||
|
@ -100,3 +101,16 @@ impl ToWebRender for PhysicalSides<Length> {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWebRender for ComputedTextDecorationStyle {
|
||||
type Type = webrender_api::LineStyle;
|
||||
fn to_webrender(&self) -> Self::Type {
|
||||
match *self {
|
||||
ComputedTextDecorationStyle::Solid => wr::LineStyle::Solid,
|
||||
ComputedTextDecorationStyle::Dotted => wr::LineStyle::Dotted,
|
||||
ComputedTextDecorationStyle::Dashed => wr::LineStyle::Dashed,
|
||||
ComputedTextDecorationStyle::Wavy => wr::LineStyle::Wavy,
|
||||
_ => wr::LineStyle::Solid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use crate::context::LayoutContext;
|
||||
use crate::display_list::conversions::ToWebRender;
|
||||
use crate::fragments::{BoxFragment, Fragment};
|
||||
use crate::fragments::{BoxFragment, Fragment, TextFragment};
|
||||
use crate::geom::{PhysicalPoint, PhysicalRect};
|
||||
use crate::replaced::IntrinsicSizes;
|
||||
use embedder_traits::Cursor;
|
||||
|
@ -13,10 +13,11 @@ use gfx::text::glyph::GlyphStore;
|
|||
use mitochondria::OnceCell;
|
||||
use net_traits::image_cache::UsePlaceholder;
|
||||
use std::sync::Arc;
|
||||
use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
|
||||
use style::dom::OpaqueNode;
|
||||
use style::properties::ComputedValues;
|
||||
|
||||
use style::values::computed::{BorderStyle, Length, LengthPercentage};
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::values::specified::ui::CursorKind;
|
||||
use webrender_api::{self as wr, units};
|
||||
|
||||
|
@ -80,30 +81,6 @@ impl Fragment {
|
|||
Fragment::Box(b) => BuilderForBoxFragment::new(b, containing_block).build(builder),
|
||||
Fragment::AbsoluteOrFixedPositioned(_) => {},
|
||||
Fragment::Anonymous(_) => {},
|
||||
Fragment::Text(t) => {
|
||||
builder.is_contentful = true;
|
||||
let rect = t
|
||||
.rect
|
||||
.to_physical(t.parent_style.writing_mode, containing_block)
|
||||
.translate(containing_block.origin.to_vector());
|
||||
let mut baseline_origin = rect.origin.clone();
|
||||
baseline_origin.y += t.ascent;
|
||||
let glyphs = glyphs(&t.glyphs, baseline_origin);
|
||||
if glyphs.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut common = builder.common_properties(rect.clone().to_webrender());
|
||||
common.hit_info = hit_info(&t.parent_style, t.tag, Cursor::Text);
|
||||
let color = t.parent_style.clone_color();
|
||||
builder.wr.push_text(
|
||||
&common,
|
||||
rect.to_webrender(),
|
||||
&glyphs,
|
||||
t.font_key,
|
||||
rgba(color),
|
||||
None,
|
||||
);
|
||||
},
|
||||
Fragment::Image(i) => {
|
||||
builder.is_contentful = true;
|
||||
let rect = i
|
||||
|
@ -120,8 +97,111 @@ impl Fragment {
|
|||
wr::ColorF::WHITE,
|
||||
);
|
||||
},
|
||||
Fragment::Text(t) => {
|
||||
self.build_display_list_for_text_fragment(t, builder, containing_block)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn build_display_list_for_text_fragment(
|
||||
&self,
|
||||
fragment: &TextFragment,
|
||||
builder: &mut DisplayListBuilder,
|
||||
containing_block: &PhysicalRect<Length>,
|
||||
) {
|
||||
// NB: The order of painting text components (CSS Text Decoration Module Level 3) is:
|
||||
// shadows, underline, overline, text, text-emphasis, and then line-through.
|
||||
|
||||
builder.is_contentful = true;
|
||||
|
||||
let rect = fragment
|
||||
.rect
|
||||
.to_physical(fragment.parent_style.writing_mode, containing_block)
|
||||
.translate(containing_block.origin.to_vector());
|
||||
let mut baseline_origin = rect.origin.clone();
|
||||
baseline_origin.y += fragment.font_metrics.ascent;
|
||||
let glyphs = glyphs(&fragment.glyphs, baseline_origin);
|
||||
if glyphs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut common = builder.common_properties(rect.to_webrender());
|
||||
common.hit_info = hit_info(&fragment.parent_style, fragment.tag, Cursor::Text);
|
||||
|
||||
let color = fragment.parent_style.clone_color();
|
||||
let font_metrics = &fragment.font_metrics;
|
||||
|
||||
// Underline.
|
||||
if fragment
|
||||
.text_decoration_line
|
||||
.contains(TextDecorationLine::UNDERLINE)
|
||||
{
|
||||
let mut rect = rect;
|
||||
rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.underline_offset;
|
||||
rect.size.height = font_metrics.underline_size;
|
||||
self.build_display_list_for_text_decoration(fragment, builder, &rect, color);
|
||||
}
|
||||
|
||||
// Overline.
|
||||
if fragment
|
||||
.text_decoration_line
|
||||
.contains(TextDecorationLine::OVERLINE)
|
||||
{
|
||||
let mut rect = rect;
|
||||
rect.size.height = font_metrics.underline_size;
|
||||
self.build_display_list_for_text_decoration(fragment, builder, &rect, color);
|
||||
}
|
||||
|
||||
// Text.
|
||||
builder.wr.push_text(
|
||||
&common,
|
||||
rect.to_webrender(),
|
||||
&glyphs,
|
||||
fragment.font_key,
|
||||
rgba(color),
|
||||
None,
|
||||
);
|
||||
|
||||
// Line-through.
|
||||
if fragment
|
||||
.text_decoration_line
|
||||
.contains(TextDecorationLine::LINE_THROUGH)
|
||||
{
|
||||
let mut rect = rect;
|
||||
rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.strikeout_offset;
|
||||
// XXX(ferjm) This does not work on MacOS #942
|
||||
rect.size.height = font_metrics.strikeout_size;
|
||||
self.build_display_list_for_text_decoration(fragment, builder, &rect, color);
|
||||
}
|
||||
}
|
||||
|
||||
fn build_display_list_for_text_decoration(
|
||||
&self,
|
||||
fragment: &TextFragment,
|
||||
builder: &mut DisplayListBuilder,
|
||||
rect: &PhysicalRect<Length>,
|
||||
color: cssparser::RGBA,
|
||||
) {
|
||||
let rect = rect.to_webrender();
|
||||
let wavy_line_thickness = (0.33 * rect.size.height).ceil();
|
||||
let text_decoration_color = fragment
|
||||
.parent_style
|
||||
.clone_text_decoration_color()
|
||||
.to_rgba(color);
|
||||
let text_decoration_style = fragment.parent_style.clone_text_decoration_style();
|
||||
if text_decoration_style == ComputedTextDecorationStyle::MozNone {
|
||||
return;
|
||||
}
|
||||
builder.wr.push_line(
|
||||
&builder.common_properties(rect),
|
||||
&rect,
|
||||
wavy_line_thickness,
|
||||
wr::LineOrientation::Horizontal,
|
||||
&rgba(text_decoration_color),
|
||||
text_decoration_style.to_webrender(),
|
||||
);
|
||||
// XXX(ferjm) support text-decoration-style: double
|
||||
}
|
||||
}
|
||||
|
||||
struct BuilderForBoxFragment<'a> {
|
||||
|
|
|
@ -19,6 +19,7 @@ use servo_arc::Arc;
|
|||
use std::convert::{TryFrom, TryInto};
|
||||
use style::properties::ComputedValues;
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
impl BlockFormattingContext {
|
||||
pub fn construct<'dom>(
|
||||
|
@ -27,9 +28,16 @@ impl BlockFormattingContext {
|
|||
style: &Arc<ComputedValues>,
|
||||
contents: NonReplacedContents,
|
||||
content_sizes: ContentSizesRequest,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
) -> (Self, BoxContentSizes) {
|
||||
let (contents, contains_floats, inline_content_sizes) =
|
||||
BlockContainer::construct(context, node, style, contents, content_sizes);
|
||||
let (contents, contains_floats, inline_content_sizes) = BlockContainer::construct(
|
||||
context,
|
||||
node,
|
||||
style,
|
||||
contents,
|
||||
content_sizes,
|
||||
propagated_text_decoration_line,
|
||||
);
|
||||
// FIXME: add contribution to `inline_content_sizes` of floats in this formatting context
|
||||
// https://dbaron.org/css/intrinsic/#intrinsic
|
||||
let bfc = Self {
|
||||
|
@ -52,6 +60,7 @@ enum BlockLevelCreator {
|
|||
Independent {
|
||||
display_inside: DisplayInside,
|
||||
contents: Contents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
},
|
||||
OutOfFlowAbsolutelyPositionedBox {
|
||||
display_inside: DisplayInside,
|
||||
|
@ -72,7 +81,7 @@ enum BlockLevelCreator {
|
|||
/// Deferring allows using rayon’s `into_par_iter`.
|
||||
enum IntermediateBlockContainer {
|
||||
InlineFormattingContext(InlineFormattingContext),
|
||||
Deferred(NonReplacedContents),
|
||||
Deferred(NonReplacedContents, TextDecorationLine),
|
||||
}
|
||||
|
||||
/// A builder for a block container.
|
||||
|
@ -140,13 +149,16 @@ impl BlockContainer {
|
|||
block_container_style: &Arc<ComputedValues>,
|
||||
contents: NonReplacedContents,
|
||||
content_sizes: ContentSizesRequest,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | block_container_style.clone_text_decoration_line();
|
||||
let mut builder = BlockContainerBuilder {
|
||||
context,
|
||||
root,
|
||||
block_container_style,
|
||||
block_level_boxes: Vec::new(),
|
||||
ongoing_inline_formatting_context: InlineFormattingContext::default(),
|
||||
ongoing_inline_formatting_context: InlineFormattingContext::new(text_decoration_line),
|
||||
ongoing_inline_boxes_stack: Vec::new(),
|
||||
anonymous_style: None,
|
||||
contains_floats: ContainsFloats::No,
|
||||
|
@ -439,6 +451,8 @@ where
|
|||
display_inside,
|
||||
contents,
|
||||
ContentSizesRequest::inline_if(!style.inline_size_is_length()),
|
||||
// Text decorations are not propagated to atomic inline-level descendants.
|
||||
TextDecorationLine::NONE,
|
||||
),
|
||||
))
|
||||
};
|
||||
|
@ -494,6 +508,9 @@ where
|
|||
.push(ArcRefCell::new(fragmented_inline));
|
||||
}
|
||||
|
||||
let propagated_text_decoration_line =
|
||||
self.ongoing_inline_formatting_context.text_decoration_line;
|
||||
|
||||
// We found a block level element, so the ongoing inline formatting
|
||||
// context needs to be ended.
|
||||
self.end_ongoing_inline_formatting_context();
|
||||
|
@ -501,11 +518,12 @@ where
|
|||
let kind = match contents.try_into() {
|
||||
Ok(contents) => match display_inside {
|
||||
DisplayInside::Flow => BlockLevelCreator::SameFormattingContextBlock(
|
||||
IntermediateBlockContainer::Deferred(contents),
|
||||
IntermediateBlockContainer::Deferred(contents, propagated_text_decoration_line),
|
||||
),
|
||||
_ => BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents: contents.into(),
|
||||
propagated_text_decoration_line,
|
||||
},
|
||||
},
|
||||
Err(contents) => {
|
||||
|
@ -513,6 +531,7 @@ where
|
|||
BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -680,6 +699,7 @@ where
|
|||
BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
} => {
|
||||
let content_sizes = ContentSizesRequest::inline_if(
|
||||
max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
||||
|
@ -692,6 +712,7 @@ where
|
|||
display_inside,
|
||||
contents,
|
||||
content_sizes,
|
||||
propagated_text_decoration_line,
|
||||
);
|
||||
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
|
||||
to.max_assign(&contents.content_sizes.outer_inline(&contents.style))
|
||||
|
@ -742,8 +763,15 @@ impl IntermediateBlockContainer {
|
|||
content_sizes: ContentSizesRequest,
|
||||
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
||||
match self {
|
||||
IntermediateBlockContainer::Deferred(contents) => {
|
||||
BlockContainer::construct(context, node, style, contents, content_sizes)
|
||||
IntermediateBlockContainer::Deferred(contents, propagated_text_decoration_line) => {
|
||||
BlockContainer::construct(
|
||||
context,
|
||||
node,
|
||||
style,
|
||||
contents,
|
||||
content_sizes,
|
||||
propagated_text_decoration_line,
|
||||
)
|
||||
},
|
||||
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
||||
let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context));
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::sizing::ContentSizesRequest;
|
|||
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
||||
use servo_arc::Arc;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub(crate) struct FloatBox {
|
||||
|
@ -43,6 +44,8 @@ impl FloatBox {
|
|||
display_inside,
|
||||
contents,
|
||||
content_sizes,
|
||||
// Text decorations are not propagated to any out-of-flow descendants
|
||||
TextDecorationLine::NONE,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::flow::FlowLayout;
|
|||
use crate::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::fragments::{
|
||||
AbsoluteOrFixedPositionedFragment, AnonymousFragment, BoxFragment, CollapsedBlockMargins,
|
||||
DebugId, Fragment, TextFragment,
|
||||
DebugId, FontMetrics, Fragment, TextFragment,
|
||||
};
|
||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||
use crate::positioned::{
|
||||
|
@ -26,12 +26,14 @@ use style::dom::OpaqueNode;
|
|||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{Length, LengthPercentage, Percentage};
|
||||
use style::values::specified::text::TextAlignKeyword;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::Zero;
|
||||
use webrender_api::FontInstanceKey;
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
pub(crate) struct InlineFormattingContext {
|
||||
pub(super) inline_level_boxes: Vec<ArcRefCell<InlineLevelBox>>,
|
||||
pub(super) text_decoration_line: TextDecorationLine,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -68,6 +70,11 @@ struct InlineNestingLevelState<'box_tree> {
|
|||
inline_start: Length,
|
||||
max_block_size_of_fragments_so_far: Length,
|
||||
positioning_context: Option<PositioningContext>,
|
||||
/// Indicates whether this nesting level have text decorations in effect.
|
||||
/// From https://drafts.csswg.org/css-text-decor/#line-decoration
|
||||
// "When specified on or propagated to a block container that establishes
|
||||
// an IFC..."
|
||||
text_decoration_line: TextDecorationLine,
|
||||
}
|
||||
|
||||
struct PartialInlineBoxFragment<'box_tree> {
|
||||
|
@ -122,6 +129,13 @@ struct Lines {
|
|||
}
|
||||
|
||||
impl InlineFormattingContext {
|
||||
pub(super) fn new(text_decoration_line: TextDecorationLine) -> InlineFormattingContext {
|
||||
InlineFormattingContext {
|
||||
inline_level_boxes: Default::default(),
|
||||
text_decoration_line,
|
||||
}
|
||||
}
|
||||
|
||||
// This works on an already-constructed `InlineFormattingContext`,
|
||||
// Which would have to change if/when
|
||||
// `BlockContainer::construct` parallelize their construction.
|
||||
|
@ -256,8 +270,10 @@ impl InlineFormattingContext {
|
|||
inline_start: Length::zero(),
|
||||
max_block_size_of_fragments_so_far: Length::zero(),
|
||||
positioning_context: None,
|
||||
text_decoration_line: self.text_decoration_line,
|
||||
},
|
||||
};
|
||||
|
||||
loop {
|
||||
if let Some(child) = ifc.current_nesting_level.remaining_boxes.next() {
|
||||
match &*child.borrow() {
|
||||
|
@ -385,6 +401,7 @@ impl Lines {
|
|||
block: line_block_size,
|
||||
};
|
||||
self.next_line_block_position += size.block;
|
||||
|
||||
self.fragments
|
||||
.push(Fragment::Anonymous(AnonymousFragment::new(
|
||||
Rect { start_corner, size },
|
||||
|
@ -423,6 +440,8 @@ impl InlineBox {
|
|||
start_corner += &relative_adjustement(&style, ifc.containing_block)
|
||||
}
|
||||
let positioning_context = PositioningContext::new_for_style(&style);
|
||||
let text_decoration_line =
|
||||
ifc.current_nesting_level.text_decoration_line | style.clone_text_decoration_line();
|
||||
PartialInlineBoxFragment {
|
||||
tag: self.tag,
|
||||
style,
|
||||
|
@ -441,6 +460,7 @@ impl InlineBox {
|
|||
inline_start: ifc.inline_position,
|
||||
max_block_size_of_fragments_so_far: Length::zero(),
|
||||
positioning_context,
|
||||
text_decoration_line: text_decoration_line,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -631,8 +651,7 @@ fn layout_atomic(
|
|||
}
|
||||
|
||||
struct BreakAndShapeResult {
|
||||
font_ascent: Au,
|
||||
font_line_gap: Au,
|
||||
font_metrics: FontMetrics,
|
||||
font_key: FontInstanceKey,
|
||||
runs: Vec<GlyphRun>,
|
||||
break_at_start: bool,
|
||||
|
@ -699,8 +718,7 @@ impl TextRun {
|
|||
);
|
||||
|
||||
BreakAndShapeResult {
|
||||
font_ascent: font.metrics.ascent,
|
||||
font_line_gap: font.metrics.line_gap,
|
||||
font_metrics: (&font.metrics).into(),
|
||||
font_key: font.font_key,
|
||||
runs,
|
||||
break_at_start,
|
||||
|
@ -712,8 +730,7 @@ impl TextRun {
|
|||
use style::values::generics::text::LineHeight;
|
||||
|
||||
let BreakAndShapeResult {
|
||||
font_ascent,
|
||||
font_line_gap,
|
||||
font_metrics,
|
||||
font_key,
|
||||
runs,
|
||||
break_at_start: _,
|
||||
|
@ -750,7 +767,7 @@ impl TextRun {
|
|||
}
|
||||
}
|
||||
let line_height = match self.parent_style.get_inherited_text().line_height {
|
||||
LineHeight::Normal => font_line_gap.into(),
|
||||
LineHeight::Normal => font_metrics.line_gap,
|
||||
LineHeight::Number(n) => font_size * n.0,
|
||||
LineHeight::Length(l) => l.0,
|
||||
};
|
||||
|
@ -775,9 +792,10 @@ impl TextRun {
|
|||
debug_id: DebugId::new(),
|
||||
parent_style: self.parent_style.clone(),
|
||||
rect,
|
||||
ascent: font_ascent.into(),
|
||||
font_metrics,
|
||||
font_key,
|
||||
glyphs,
|
||||
text_decoration_line: ifc.current_nesting_level.text_decoration_line,
|
||||
}));
|
||||
if runs.is_empty() {
|
||||
break;
|
||||
|
|
|
@ -104,6 +104,7 @@ fn construct_for_root_element<'dom>(
|
|||
))],
|
||||
)
|
||||
} else {
|
||||
let propagated_text_decoration_line = style.clone_text_decoration_line();
|
||||
(
|
||||
ContainsFloats::No,
|
||||
vec![ArcRefCell::new(BlockLevelBox::Independent(
|
||||
|
@ -114,6 +115,7 @@ fn construct_for_root_element<'dom>(
|
|||
display_inside,
|
||||
contents,
|
||||
ContentSizesRequest::None,
|
||||
propagated_text_decoration_line,
|
||||
),
|
||||
))],
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ use std::convert::TryInto;
|
|||
use style::dom::OpaqueNode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::Length;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
/// https://drafts.csswg.org/css-display/#independent-formatting-context
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -62,6 +63,7 @@ impl IndependentFormattingContext {
|
|||
display_inside: DisplayInside,
|
||||
contents: Contents,
|
||||
content_sizes: ContentSizesRequest,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
) -> Self {
|
||||
match contents.try_into() {
|
||||
Ok(non_replaced) => match display_inside {
|
||||
|
@ -72,6 +74,7 @@ impl IndependentFormattingContext {
|
|||
&style,
|
||||
non_replaced,
|
||||
content_sizes,
|
||||
propagated_text_decoration_line,
|
||||
);
|
||||
Self {
|
||||
tag: node.as_opaque(),
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::geom::{PhysicalPoint, PhysicalRect};
|
|||
#[cfg(debug_assertions)]
|
||||
use crate::layout_debug;
|
||||
use crate::positioned::HoistedFragmentId;
|
||||
use gfx::font::FontMetrics as GfxFontMetrics;
|
||||
use gfx::text::glyph::GlyphStore;
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
#[cfg(not(debug_assertions))]
|
||||
|
@ -18,6 +19,7 @@ use style::dom::OpaqueNode;
|
|||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::Length;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::Zero;
|
||||
use webrender_api::{FontInstanceKey, ImageKey};
|
||||
|
||||
|
@ -86,6 +88,29 @@ pub(crate) struct AnonymousFragment {
|
|||
pub scrollable_overflow: PhysicalRect<Length>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
pub(crate) struct FontMetrics {
|
||||
pub ascent: Length,
|
||||
pub line_gap: Length,
|
||||
pub underline_offset: Length,
|
||||
pub underline_size: Length,
|
||||
pub strikeout_offset: Length,
|
||||
pub strikeout_size: Length,
|
||||
}
|
||||
|
||||
impl From<&GfxFontMetrics> for FontMetrics {
|
||||
fn from(metrics: &GfxFontMetrics) -> FontMetrics {
|
||||
FontMetrics {
|
||||
ascent: metrics.ascent.into(),
|
||||
line_gap: metrics.line_gap.into(),
|
||||
underline_offset: metrics.underline_offset.into(),
|
||||
underline_size: metrics.underline_size.into(),
|
||||
strikeout_offset: metrics.strikeout_offset.into(),
|
||||
strikeout_size: metrics.strikeout_size.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct TextFragment {
|
||||
pub debug_id: DebugId,
|
||||
|
@ -93,10 +118,12 @@ pub(crate) struct TextFragment {
|
|||
#[serde(skip_serializing)]
|
||||
pub parent_style: ServoArc<ComputedValues>,
|
||||
pub rect: Rect<Length>,
|
||||
pub ascent: Length,
|
||||
pub font_metrics: FontMetrics,
|
||||
#[serde(skip_serializing)]
|
||||
pub font_key: FontInstanceKey,
|
||||
pub glyphs: Vec<Arc<GlyphStore>>,
|
||||
/// A flag that represents the _used_ value of the text-decoration property.
|
||||
pub text_decoration_line: TextDecorationLine,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||
use style::computed_values::position::T as Position;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::Zero;
|
||||
|
||||
static HOISTED_FRAGMENT_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
|
@ -104,6 +105,8 @@ impl AbsolutelyPositionedBox {
|
|||
display_inside,
|
||||
contents,
|
||||
content_sizes,
|
||||
// Text decorations are not propagated to any out-of-flow descendants.
|
||||
TextDecorationLine::NONE,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ ${helpers.predefined_type(
|
|||
"TextDecorationLine",
|
||||
"specified::TextDecorationLine::none()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
initial_specified_value="specified::TextDecorationLine::none()",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line",
|
||||
|
@ -42,7 +41,7 @@ ${helpers.predefined_type(
|
|||
${helpers.single_keyword(
|
||||
"text-decoration-style",
|
||||
"solid double dotted dashed wavy -moz-none",
|
||||
engines="gecko",
|
||||
engines="gecko servo-2020",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-style",
|
||||
)}
|
||||
|
@ -51,7 +50,7 @@ ${helpers.predefined_type(
|
|||
"text-decoration-color",
|
||||
"Color",
|
||||
"computed_value::T::currentcolor()",
|
||||
engines="gecko",
|
||||
engines="gecko servo-2020",
|
||||
initial_specified_value="specified::Color::currentcolor()",
|
||||
animation_value_type="AnimatedColor",
|
||||
ignored_when_colors_disabled=True,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="text-decoration"
|
||||
engines="gecko servo-2013"
|
||||
engines="gecko servo-2013 servo-2020"
|
||||
flags="SHORTHAND_IN_GETCS"
|
||||
sub_properties="text-decoration-line
|
||||
${' text-decoration-style text-decoration-color text-decoration-thickness' if engine == 'gecko' else ''}"
|
||||
|
|
|
@ -217,7 +217,7 @@ impl ToComputedValue for TextOverflow {
|
|||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
#[derive(MallocSizeOf, Serialize, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
#[value_info(other_values = "none,underline,overline,line-through,blink")]
|
||||
#[repr(C)]
|
||||
/// Specified keyword values for the text-decoration-line property.
|
||||
|
@ -244,6 +244,12 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for TextDecorationLine {
|
||||
fn default() -> Self {
|
||||
TextDecorationLine::NONE
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TextDecorationLine {
|
||||
/// none | [ underline || overline || line-through || blink ]
|
||||
fn parse<'i, 't>(
|
||||
|
|
|
@ -15,6 +15,8 @@ skip: true
|
|||
skip: false
|
||||
[css-color]
|
||||
skip: false
|
||||
[css-text-decor]
|
||||
skip: false
|
||||
[css-transforms]
|
||||
skip: false
|
||||
[filter-effects]
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[content-070.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[content-082.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,55 @@
|
|||
[inheritance.html]
|
||||
[Property text-emphasis-style inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-emphasis-style has initial value none]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style has initial value solid]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position has initial value auto]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line has initial value none]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-emphasis-color has initial value rgba(2, 3, 4, 0.5)]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow has initial value none]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-color has initial value rgba(2, 3, 4, 0.5)]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-skip-ink inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-skip-ink has initial value auto]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line does not inherit]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-emphasis-position inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-color does not inherit]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-emphasis-position has initial value over right]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style does not inherit]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-emphasis-color inherits]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
[text-decoration-color-computed.html]
|
||||
[Property text-decoration-color value 'inherit']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-color value 'rgb(0, 0, 255)']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-color value 'currentcolor']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
[text-decoration-computed.html]
|
||||
[Property text-decoration value 'auto']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'currentcolor']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'double overline underline']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'line-through']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'underline dashed rgb(0, 255, 0)']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'underline overline line-through red']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'rgba(10, 20, 30, 0.4) dotted']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'none']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value '10px']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'underline red from-font']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'solid']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration value 'from-font']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
[text-decoration-line-computed.html]
|
||||
[Property text-decoration-line value 'underline overline']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'overline blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline line-through blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline overline blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'line-through blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline line-through']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'overline line-through blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'line-through']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'overline line-through']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'spelling-error']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline overline line-through']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'none']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'grammar-error']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'underline overline line-through blink']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-line value 'overline']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[text-decoration-line-valid.html]
|
||||
[e.style['text-decoration-line'\] = "spelling-error" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-line'\] = "grammar-error" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[text-decoration-shorthand.html]
|
||||
[e.style['text-decoration'\] = "overline dotted green" should set text-decoration-line]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "overline dotted green" should set text-decoration-style]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "overline dotted green" should set text-decoration-color]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "overline dotted green" should not set unrelated longhands]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[text-decoration-skip-ink-computed.html]
|
||||
[Property text-decoration-skip-ink value 'none']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-skip-ink value 'auto']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[text-decoration-skip-ink-valid.html]
|
||||
[e.style['text-decoration-skip-ink'\] = "none" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-skip-ink'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[text-decoration-style-computed.html]
|
||||
[Property text-decoration-style value 'wavy']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style value 'dashed']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style value 'dotted']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style value 'double']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-style value 'solid']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
[text-decoration-valid.html]
|
||||
[e.style['text-decoration'\] = "underline auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "underline dashed green" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "10px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "double overline underline" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "rgba(10, 20, 30, 0.4) dotted" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "solid" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "line-through 20px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "underline overline line-through red" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "overline 3em" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "currentcolor" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "from-font" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration'\] = "overline green from-font" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
[text-shadow-computed.html]
|
||||
[Property text-shadow value 'calc(0.5em + 10px) calc(0.5em + 10px) calc(0.5em + 10px)']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value '10px 20px, 30px 40px']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value 'lime 10px 20px 30px, red 40px 50px']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value 'calc(-0.5em + 10px) calc(-0.5em + 10px) calc(-0.5em + 10px)']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value 'red 10px 20px 30px']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value 'none']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-shadow value '10px 20px']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
[text-shadow-valid.html]
|
||||
[e.style['text-shadow'\] = "rgb(255, 0, 0) 10px 20px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "lime 10px 20px 30px, blue 40px 50px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "10px 20px 30px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "10px -20px 30px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "-10px 20px 30px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "10px 20px 30px lime" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "10px 20px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "none" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "10px 20px, 30px 40px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-shadow'\] = "calc(1em + 2px) calc(3em + 4px) calc(5em + 6px)" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[text-underline-position-computed.html]
|
||||
[Property text-underline-position value 'under left']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position value 'left']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position value 'under']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position value 'right']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-position value 'auto']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
[text-underline-position-valid.html]
|
||||
[e.style['text-underline-position'\] = "right under" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-position'\] = "under left" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-position'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-position'\] = "left" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-position'\] = "right" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-position'\] = "under" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-color.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,4 @@
|
|||
[text-decoration-serialization.tentative.html]
|
||||
[text-decoration shorthand serialization]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-003.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-004.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-005.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-sidewayslr-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-sidewaysrl-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-upright-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-upright-002.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-vertical-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-skip-ink-vertical-002.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,7 @@
|
|||
[text-decoration-skip-ink.html]
|
||||
[Body must have text-decoration-skip-ink auto by default.]
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-skip-ink must support values auto, none and all.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-subelements-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-subelements-002.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,10 @@
|
|||
[text-decoration-thickness-computed.html]
|
||||
[Property text-decoration-thickness value 'auto']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-thickness value 'from-font']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-decoration-thickness value 'calc(10px - 8px)']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[text-decoration-thickness-initial.html]
|
||||
[Initial value of text-decoration-thickness should be auto]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-linethrough-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-overline-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-scroll-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-underline-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,25 @@
|
|||
[text-decoration-thickness-valid.html]
|
||||
[e.style['text-decoration-thickness'\] = "from-font" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "2001em" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "-49em" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "calc(-50em + 13px)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "53px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "calc(40em - 10px)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-decoration-thickness'\] = "-10px" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-vertical-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-thickness-vertical-002.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-underline-position-vertical-ja.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-decoration-underline-position-vertical.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-color-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-above-left-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-above-left-002.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-above-right-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-above-right-002.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-below-left-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-below-left-002.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-below-right-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-position-below-right-002.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-002.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-006.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-007.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-008.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-010.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-012.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-021.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-filled-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-open-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-shape-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-emphasis-style-string-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[text-underline-offset-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,7 @@
|
|||
[text-underline-offset-computed.html]
|
||||
[Property text-underline-offset value 'auto']
|
||||
expected: FAIL
|
||||
|
||||
[Property text-underline-offset value 'calc(10px - 8px)']
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[text-underline-offset-initial.html]
|
||||
[Initial value of text-underline-offset]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[text-underline-offset-scroll-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,22 @@
|
|||
[text-underline-offset-valid.html]
|
||||
[e.style['text-underline-offset'\] = "53px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "calc(-13em + 50px)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "2001em" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "-10px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "calc(40em - 10px)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['text-underline-offset'\] = "-49em" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[text_decoration_smoke_a.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[text_decoration_underline_subpx_a.html]
|
||||
expected: FAIL
|
|
@ -2,4 +2,3 @@
|
|||
bug: https://github.com/servo/servo/issues/25802
|
||||
[localeCompare should return the same as other browsers, even though it's implementation-dependent]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue