aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/construct.rs11
-rw-r--r--components/layout/flow.rs2
-rw-r--r--components/layout/fragment.rs223
-rw-r--r--components/layout/inline.rs435
-rw-r--r--components/layout/list_item.rs22
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-default.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row-reverse.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap-reverse.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/c5501-imrgn-t-000.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/c5503-imrgn-b-000.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/inline-block-valign-002.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/line-height-129.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-applies-to-012.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-007.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-008.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-019.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-020.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-031.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-032.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-043.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-044.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-055.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-056.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-067.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-068.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-079.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-080.htm.ini3
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json48
-rw-r--r--tests/wpt/mozilla/tests/css/inline_block_centering_a.html33
-rw-r--r--tests/wpt/mozilla/tests/css/inline_block_centering_ref.html26
-rw-r--r--tests/wpt/mozilla/tests/css/vertical_align_middle_a.html14
-rw-r--r--tests/wpt/mozilla/tests/css/vertical_align_middle_ref.html27
-rw-r--r--tests/wpt/mozilla/tests/css/vertical_align_super_a.html2
35 files changed, 524 insertions, 391 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 9722cc852d7..5cc982fcc3f 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -476,14 +476,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
{
// FIXME(#6503): Use Arc::get_mut().unwrap() here.
let inline_flow = flow_ref::deref_mut(&mut inline_flow_ref).as_mut_inline();
-
-
- let (ascent, descent) =
- inline_flow.compute_minimum_ascent_and_descent(&mut self.layout_context
- .font_context(),
- &node.style(self.style_context()));
- inline_flow.minimum_block_size_above_baseline = ascent;
- inline_flow.minimum_depth_below_baseline = descent;
+ inline_flow.minimum_line_metrics =
+ inline_flow.minimum_line_metrics(&mut self.layout_context.font_context(),
+ &node.style(self.style_context()))
}
inline_flow_ref.finish();
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 5fdff19d8eb..28694686ef0 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -1576,7 +1576,7 @@ impl ContainingBlockLink {
if flow.is_block_like() {
flow.as_block().explicit_block_containing_size(shared_context)
} else if flow.is_inline_flow() {
- Some(flow.as_inline().minimum_block_size_above_baseline)
+ Some(flow.as_inline().minimum_line_metrics.space_above_baseline)
} else {
None
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 910497daca2..0faf0df22af 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -19,7 +19,7 @@ use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::{FragmentType, LayerId, LayerType, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
-use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT};
+use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics};
use ipc_channel::ipc::IpcSender;
#[cfg(debug_assertions)]
use layout_debug;
@@ -54,6 +54,10 @@ use text;
use text::TextRunScanner;
use url::Url;
+// From gfxFontConstants.h in Firefox.
+static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
+static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34;
+
/// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position
/// themselves. In general, fragments do not have a simple correspondence with CSS fragments in the
/// specification:
@@ -643,6 +647,7 @@ impl ReplacedImageFragmentInfo {
inline_size + noncontent_inline_size
}
+ /// Here, `noncontent_block_size` represents the sum of border and padding, but not margin.
pub fn calculate_replaced_block_size(&mut self,
style: &ServoComputedValues,
noncontent_block_size: Au,
@@ -650,7 +655,6 @@ impl ReplacedImageFragmentInfo {
fragment_inline_size: Au,
fragment_block_size: Au)
-> Au {
- // TODO(ksh8281): compute border,margin,padding
let style_block_size = style.content_block_size();
let style_min_block_size = style.min_block_size();
let style_max_block_size = style.max_block_size();
@@ -1178,13 +1182,6 @@ impl Fragment {
}
}
- pub fn calculate_line_height(&self, layout_context: &LayoutContext) -> Au {
- let font_style = self.style.get_font_arc();
- let font_metrics = text::font_metrics_for_style(&mut layout_context.font_context(),
- font_style);
- text::line_height_from_style(&*self.style, &font_metrics)
- }
-
/// Returns the sum of the inline-sizes of all the borders of this fragment. Note that this
/// can be expensive to compute, so if possible use the `border_padding` field instead.
#[inline]
@@ -2132,38 +2129,52 @@ impl Fragment {
}
}
+ /// Returns true if this fragment is replaced content or an inline-block or false otherwise.
+ pub fn is_replaced_or_inline_block(&self) -> bool {
+ match self.specific {
+ SpecificFragmentInfo::Canvas(_) |
+ SpecificFragmentInfo::Iframe(_) |
+ SpecificFragmentInfo::Image(_) |
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
+ SpecificFragmentInfo::InlineBlock(_) |
+ SpecificFragmentInfo::Svg(_) => true,
+ SpecificFragmentInfo::Generic |
+ SpecificFragmentInfo::GeneratedContent(_) |
+ SpecificFragmentInfo::InlineAbsolute(_) |
+ SpecificFragmentInfo::Table |
+ SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::TableColumn(_) |
+ SpecificFragmentInfo::TableRow |
+ SpecificFragmentInfo::TableWrapper |
+ SpecificFragmentInfo::Multicol |
+ SpecificFragmentInfo::MulticolColumn |
+ SpecificFragmentInfo::ScannedText(_) |
+ SpecificFragmentInfo::UnscannedText(_) => false,
+ }
+ }
+
/// Calculates block-size above baseline, depth below baseline, and ascent for this fragment
/// when used in an inline formatting context. See CSS 2.1 § 10.8.1.
- pub fn inline_metrics(&self, layout_context: &LayoutContext) -> InlineMetrics {
- return match self.specific {
- SpecificFragmentInfo::Image(ref image_fragment_info) => {
- let computed_block_size = image_fragment_info.replaced_image_fragment_info
- .computed_block_size();
- InlineMetrics {
- block_size_above_baseline: computed_block_size +
- self.border_padding.block_start,
- depth_below_baseline: self.border_padding.block_end,
- ascent: computed_block_size + self.border_padding.block_start,
- }
- }
- SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
- let computed_block_size = canvas_fragment_info.replaced_image_fragment_info
- .computed_block_size();
- InlineMetrics {
- block_size_above_baseline: computed_block_size +
- self.border_padding.block_start,
- depth_below_baseline: self.border_padding.block_end,
- ascent: computed_block_size + self.border_padding.block_start,
- }
- }
- SpecificFragmentInfo::Svg(ref svg_fragment_info) => {
- let computed_block_size = svg_fragment_info.replaced_image_fragment_info
- .computed_block_size();
+ ///
+ /// This does not take `vertical-align` into account. For that, use `aligned_inline_metrics()`.
+ fn content_inline_metrics(&self, layout_context: &LayoutContext) -> InlineMetrics {
+ // CSS 2.1 § 10.8: "The height of each inline-level box in the line box is
+ // calculated. For replaced elements, inline-block elements, and inline-table
+ // elements, this is the height of their margin box."
+ //
+ // FIXME(pcwalton): We have to handle `Generic` and `GeneratedContent` here to avoid
+ // crashing in a couple of `css21_dev/html4/content-` WPTs, but I don't see how those two
+ // fragment types should end up inside inlines. (In the case of `GeneratedContent`, those
+ // fragment types should have been resolved by now…)
+ let inline_metrics = match self.specific {
+ SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) |
+ SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Svg(_) |
+ SpecificFragmentInfo::Generic | SpecificFragmentInfo::GeneratedContent(_) => {
+ let ascent = self.border_box.size.block + self.margin.block_start;
InlineMetrics {
- block_size_above_baseline: computed_block_size +
- self.border_padding.block_start,
- depth_below_baseline: self.border_padding.block_end,
- ascent: computed_block_size + self.border_padding.block_start,
+ space_above_baseline: ascent,
+ space_below_baseline: self.margin.block_end,
+ ascent: ascent,
}
}
SpecificFragmentInfo::ScannedText(ref info) => {
@@ -2173,14 +2184,10 @@ impl Fragment {
return InlineMetrics::new(Au(0), Au(0), Au(0));
}
// See CSS 2.1 § 10.8.1.
- let line_height = self.calculate_line_height(layout_context);
- let font_derived_metrics =
- InlineMetrics::from_font_metrics(&info.run.font_metrics, line_height);
- InlineMetrics {
- block_size_above_baseline: font_derived_metrics.block_size_above_baseline,
- depth_below_baseline: font_derived_metrics.depth_below_baseline,
- ascent: font_derived_metrics.ascent + self.border_padding.block_start,
- }
+ let font_metrics = text::font_metrics_for_style(&mut layout_context.font_context(),
+ self.style.get_font_arc());
+ let line_height = text::line_height_from_style(&*self.style, &font_metrics);
+ InlineMetrics::from_font_metrics(&info.run.font_metrics, line_height)
}
SpecificFragmentInfo::InlineBlock(ref info) => {
inline_metrics_of_block(&info.flow_ref, &*self.style)
@@ -2191,21 +2198,26 @@ impl Fragment {
SpecificFragmentInfo::InlineAbsolute(_) => {
InlineMetrics::new(Au(0), Au(0), Au(0))
}
- _ => {
- InlineMetrics {
- block_size_above_baseline: self.border_box.size.block,
- depth_below_baseline: Au(0),
- ascent: self.border_box.size.block,
- }
+ SpecificFragmentInfo::Table |
+ SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::TableColumn(_) |
+ SpecificFragmentInfo::TableRow |
+ SpecificFragmentInfo::TableWrapper |
+ SpecificFragmentInfo::Multicol |
+ SpecificFragmentInfo::MulticolColumn |
+ SpecificFragmentInfo::UnscannedText(_) => {
+ unreachable!("Shouldn't see fragments of this type here!")
}
};
+ return inline_metrics;
fn inline_metrics_of_block(flow: &FlowRef, style: &ServoComputedValues) -> InlineMetrics {
- // See CSS 2.1 § 10.8.1.
+ // CSS 2.1 § 10.8: "The height of each inline-level box in the line box is calculated.
+ // For replaced elements, inline-block elements, and inline-table elements, this is the
+ // height of their margin box."
let block_flow = flow.as_block();
let is_auto = style.get_position().height == LengthOrPercentageOrAuto::Auto;
- let baseline_offset = flow.baseline_offset_of_last_line_box_in_flow();
- let baseline_offset = match baseline_offset {
+ let baseline_offset = match flow.baseline_offset_of_last_line_box_in_flow() {
Some(baseline_offset) if is_auto => baseline_offset,
_ => block_flow.fragment.border_box.size.block,
};
@@ -2218,6 +2230,107 @@ impl Fragment {
}
}
+ /// Calculates the offset from the baseline that applies to this fragment due to
+ /// `vertical-align`. Positive values represent downward displacement.
+ ///
+ /// If `actual_line_metrics` is supplied, then these metrics are used to determine the
+ /// displacement of the fragment when `top` or `bottom` `vertical-align` values are
+ /// encountered. If this is not supplied, then `top` and `bottom` values are ignored.
+ fn vertical_alignment_offset(&self,
+ layout_context: &LayoutContext,
+ content_inline_metrics: &InlineMetrics,
+ minimum_line_metrics: &LineMetrics,
+ actual_line_metrics: Option<&LineMetrics>)
+ -> Au {
+ let mut offset = Au(0);
+ for style in self.inline_styles() {
+ // If any of the inline styles say `top` or `bottom`, adjust the vertical align
+ // appropriately.
+ //
+ // FIXME(#5624, pcwalton): This passes our current reftests but isn't the right thing
+ // to do.
+ match style.get_box().vertical_align {
+ vertical_align::T::baseline => {}
+ vertical_align::T::middle => {
+ let font_metrics =
+ text::font_metrics_for_style(&mut layout_context.font_context(),
+ style.get_font_arc());
+ offset += (content_inline_metrics.ascent -
+ content_inline_metrics.space_below_baseline -
+ font_metrics.x_height).scale_by(0.5)
+ }
+ vertical_align::T::sub => {
+ offset += minimum_line_metrics.space_needed()
+ .scale_by(FONT_SUBSCRIPT_OFFSET_RATIO)
+ }
+ vertical_align::T::super_ => {
+ offset -= minimum_line_metrics.space_needed()
+ .scale_by(FONT_SUPERSCRIPT_OFFSET_RATIO)
+ }
+ vertical_align::T::text_top => {
+ offset = self.content_inline_metrics(layout_context).ascent -
+ minimum_line_metrics.space_above_baseline
+ }
+ vertical_align::T::text_bottom => {
+ offset = minimum_line_metrics.space_below_baseline -
+ self.content_inline_metrics(layout_context).space_below_baseline
+ }
+ vertical_align::T::top => {
+ if let Some(actual_line_metrics) = actual_line_metrics {
+ offset = content_inline_metrics.ascent -
+ actual_line_metrics.space_above_baseline
+ }
+ }
+ vertical_align::T::bottom => {
+ if let Some(actual_line_metrics) = actual_line_metrics {
+ offset = actual_line_metrics.space_below_baseline -
+ content_inline_metrics.space_below_baseline
+ }
+ }
+ vertical_align::T::LengthOrPercentage(LengthOrPercentage::Length(length)) => {
+ offset -= length
+ }
+ vertical_align::T::LengthOrPercentage(LengthOrPercentage::Percentage(
+ percentage)) => {
+ offset -= minimum_line_metrics.space_needed().scale_by(percentage)
+ }
+ vertical_align::T::LengthOrPercentage(LengthOrPercentage::Calc(formula)) => {
+ offset -= minimum_line_metrics.space_needed().scale_by(formula.percentage()) +
+ formula.length()
+ }
+ }
+ }
+ offset
+ }
+
+ /// Calculates block-size above baseline, depth below baseline, and ascent for this fragment
+ /// when used in an inline formatting context, taking `vertical-align` (other than `top` or
+ /// `bottom`) into account. See CSS 2.1 § 10.8.1.
+ ///
+ /// If `actual_line_metrics` is supplied, then these metrics are used to determine the
+ /// displacement of the fragment when `top` or `bottom` `vertical-align` values are
+ /// encountered. If this is not supplied, then `top` and `bottom` values are ignored.
+ pub fn aligned_inline_metrics(&self,
+ layout_context: &LayoutContext,
+ minimum_line_metrics: &LineMetrics,
+ actual_line_metrics: Option<&LineMetrics>)
+ -> InlineMetrics {
+ let content_inline_metrics = self.content_inline_metrics(layout_context);
+ let vertical_alignment_offset = self.vertical_alignment_offset(layout_context,
+ &content_inline_metrics,
+ minimum_line_metrics,
+ actual_line_metrics);
+ let mut space_above_baseline = match actual_line_metrics {
+ None => content_inline_metrics.space_above_baseline,
+ Some(actual_line_metrics) => actual_line_metrics.space_above_baseline,
+ };
+ space_above_baseline = space_above_baseline - vertical_alignment_offset;
+ let space_below_baseline = content_inline_metrics.space_below_baseline +
+ vertical_alignment_offset;
+ let ascent = content_inline_metrics.ascent - vertical_alignment_offset;
+ InlineMetrics::new(space_above_baseline, space_below_baseline, ascent)
+ }
+
/// Returns true if this fragment is a hypothetical box. See CSS 2.1 § 10.3.7.
pub fn is_hypothetical(&self) -> bool {
match self.specific {
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index f0622f1bbcb..c06e3631719 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -37,14 +37,9 @@ use style::computed_values::{text_overflow, vertical_align, white_space};
use style::context::{SharedStyleContext, StyleContext};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ServoComputedValues;
-use style::values::computed::LengthOrPercentage;
use text;
use unicode_bidi;
-// From gfxFontConstants.h in Firefox
-static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
-static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34;
-
/// `Line`s are represented as offsets into the child list, rather than
/// as an object that "owns" fragments. Choosing a different set of line
/// breaks requires a new list of offsets, and possibly some splitting and
@@ -158,31 +153,22 @@ pub struct Line {
/// ~~~
pub green_zone: LogicalSize<Au>,
- /// The minimum block size above the baseline for this line, as specified by the style.
- pub minimum_block_size_above_baseline: Au,
-
- /// The minimum depth below the baseline for this line, as specified by the style.
- pub minimum_depth_below_baseline: Au,
+ /// The minimum metrics for this line, as specified by the style.
+ pub minimum_metrics: LineMetrics,
- /// The inline metrics for this line.
- pub inline_metrics: InlineMetrics,
+ /// The actual metrics for this line.
+ pub metrics: LineMetrics,
}
impl Line {
- fn new(writing_mode: WritingMode,
- minimum_block_size_above_baseline: Au,
- minimum_depth_below_baseline: Au)
- -> Line {
+ fn new(writing_mode: WritingMode, minimum_metrics: &LineMetrics) -> Line {
Line {
range: Range::empty(),
visual_runs: None,
bounds: LogicalRect::zero(writing_mode),
green_zone: LogicalSize::zero(writing_mode),
- minimum_block_size_above_baseline: minimum_block_size_above_baseline,
- minimum_depth_below_baseline: minimum_depth_below_baseline,
- inline_metrics: InlineMetrics::new(minimum_block_size_above_baseline,
- minimum_depth_below_baseline,
- minimum_block_size_above_baseline),
+ minimum_metrics: *minimum_metrics,
+ metrics: *minimum_metrics,
}
}
@@ -190,29 +176,31 @@ impl Line {
///
/// FIXME(pcwalton): this assumes that the tallest fragment in the line determines the line
/// block-size. This might not be the case with some weird text fonts.
- fn new_inline_metrics(&self, new_fragment: &Fragment, layout_context: &LayoutContext)
- -> InlineMetrics {
+ fn new_metrics_for_fragment(&self, new_fragment: &Fragment, layout_context: &LayoutContext)
+ -> LineMetrics {
if !new_fragment.is_vertically_aligned_to_top_or_bottom() {
- let fragment_inline_metrics = new_fragment.inline_metrics(layout_context);
- self.inline_metrics.max(&fragment_inline_metrics)
+ let fragment_inline_metrics =
+ new_fragment.aligned_inline_metrics(layout_context, &self.minimum_metrics, None);
+ self.metrics.new_metrics_for_fragment(&fragment_inline_metrics)
} else {
- self.inline_metrics
+ self.metrics
}
}
/// Returns the new block size that this line would have if `new_fragment` were added to it.
/// `new_inline_metrics` represents the new inline metrics that this line would have; it can
/// be computed with `new_inline_metrics()`.
- fn new_block_size(&self,
- new_fragment: &Fragment,
- new_inline_metrics: &InlineMetrics,
- layout_context: &LayoutContext)
- -> Au {
+ fn new_block_size_for_fragment(&self,
+ new_fragment: &Fragment,
+ new_line_metrics: &LineMetrics,
+ layout_context: &LayoutContext)
+ -> Au {
let new_block_size = if new_fragment.is_vertically_aligned_to_top_or_bottom() {
- max(new_fragment.inline_metrics(layout_context).block_size(),
- self.minimum_block_size_above_baseline + self.minimum_depth_below_baseline)
+ max(new_fragment.aligned_inline_metrics(layout_context, &self.minimum_metrics, None)
+ .space_needed(),
+ self.minimum_metrics.space_needed())
} else {
- new_inline_metrics.block_size()
+ new_line_metrics.space_needed()
};
max(self.bounds.size.block, new_block_size)
}
@@ -243,34 +231,24 @@ struct LineBreaker {
cur_b: Au,
/// The computed value of the indentation for the first line (`text-indent`, CSS 2.1 § 16.1).
first_line_indentation: Au,
- /// The minimum block-size above the baseline for each line, as specified by the line height
- /// and font style.
- minimum_block_size_above_baseline: Au,
- /// The minimum depth below the baseline for each line, as specified by the line height and
- /// font style.
- minimum_depth_below_baseline: Au,
+ /// The minimum metrics for each line, as specified by the line height and font style.
+ minimum_metrics: LineMetrics,
}
impl LineBreaker {
/// Creates a new `LineBreaker` with a set of floats and the indentation of the first line.
- fn new(float_context: Floats,
- first_line_indentation: Au,
- minimum_block_size_above_baseline: Au,
- minimum_depth_below_baseline: Au)
+ fn new(float_context: Floats, first_line_indentation: Au, minimum_line_metrics: &LineMetrics)
-> LineBreaker {
LineBreaker {
new_fragments: Vec::new(),
work_list: VecDeque::new(),
- pending_line: Line::new(float_context.writing_mode,
- minimum_block_size_above_baseline,
- minimum_depth_below_baseline),
+ pending_line: Line::new(float_context.writing_mode, minimum_line_metrics),
floats: float_context,
lines: Vec::new(),
cur_b: Au(0),
last_known_line_breaking_opportunity: None,
first_line_indentation: first_line_indentation,
- minimum_block_size_above_baseline: minimum_block_size_above_baseline,
- minimum_depth_below_baseline: minimum_depth_below_baseline,
+ minimum_metrics: *minimum_line_metrics,
}
}
@@ -285,9 +263,8 @@ impl LineBreaker {
/// Reinitializes the pending line to blank data.
fn reset_line(&mut self) -> Line {
self.last_known_line_breaking_opportunity = None;
- mem::replace(&mut self.pending_line, Line::new(self.floats.writing_mode,
- self.minimum_block_size_above_baseline,
- self.minimum_depth_below_baseline))
+ mem::replace(&mut self.pending_line,
+ Line::new(self.floats.writing_mode, &self.minimum_metrics))
}
/// Reflows fragments for the given inline flow.
@@ -574,10 +551,11 @@ impl LineBreaker {
// `green_zone.block < self.pending_line.bounds.size.block`, then we committed a line that
// overlaps with floats.
let green_zone = self.pending_line.green_zone;
- let new_inline_metrics = self.pending_line.new_inline_metrics(&fragment, layout_context);
- let new_block_size = self.pending_line.new_block_size(&fragment,
- &new_inline_metrics,
- layout_context);
+ let new_line_metrics = self.pending_line.new_metrics_for_fragment(&fragment,
+ layout_context);
+ let new_block_size = self.pending_line.new_block_size_for_fragment(&fragment,
+ &new_line_metrics,
+ layout_context);
if new_block_size > green_zone.block {
// Uh-oh. Float collision imminent. Enter the float collision avoider!
if !self.avoid_floats(flow, fragment, new_block_size) {
@@ -747,14 +725,13 @@ impl LineBreaker {
if !fragment.is_inline_absolute() && !fragment.is_hypothetical() {
self.pending_line.bounds.size.inline = self.pending_line.bounds.size.inline +
- fragment.margin_box_inline_size() +
- indentation;
- self.pending_line.inline_metrics =
- self.pending_line.new_inline_metrics(&fragment, layout_context);
+ fragment.margin_box_inline_size() + indentation;
+ self.pending_line.metrics = self.pending_line.new_metrics_for_fragment(&fragment,
+ layout_context);
self.pending_line.bounds.size.block =
- self.pending_line.new_block_size(&fragment,
- &self.pending_line.inline_metrics,
- layout_context);
+ self.pending_line.new_block_size_for_fragment(&fragment,
+ &self.pending_line.metrics,
+ layout_context);
}
self.new_fragments.push(fragment);
@@ -864,13 +841,8 @@ pub struct InlineFlow {
/// lines.
pub lines: Vec<Line>,
- /// The minimum block-size above the baseline for each line, as specified by the line height
- /// and font style.
- pub minimum_block_size_above_baseline: Au,
-
- /// The minimum depth below the baseline for each line, as specified by the line height and
- /// font style.
- pub minimum_depth_below_baseline: Au,
+ /// The minimum metrics for each line, as specified by the line height and font style.
+ pub minimum_line_metrics: LineMetrics,
/// The amount of indentation to use on the first line. This is determined by our block parent
/// (because percentages are relative to the containing block, and we aren't in a position to
@@ -884,8 +856,7 @@ impl InlineFlow {
base: BaseFlow::new(None, writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragments: fragments,
lines: Vec::new(),
- minimum_block_size_above_baseline: Au(0),
- minimum_depth_below_baseline: Au(0),
+ minimum_line_metrics: LineMetrics::new(Au(0), Au(0)),
first_line_indentation: Au(0),
};
@@ -1050,90 +1021,62 @@ impl InlineFlow {
/// Sets final fragment positions in the block direction for one line.
fn set_block_fragment_positions(fragments: &mut InlineFragments,
line: &Line,
- minimum_block_size_above_baseline: Au,
- minimum_depth_below_baseline: Au,
+ minimum_line_metrics: &LineMetrics,
layout_context: &LayoutContext) {
for fragment_index in line.range.each_index() {
- // If any of the inline styles say `top` or `bottom`, adjust the vertical align
- // appropriately.
- //
- // FIXME(#5624, pcwalton): This passes our current reftests but isn't the right thing
- // to do.
let fragment = fragments.get_mut(fragment_index.to_usize());
- let fragment_inline_metrics = fragment.inline_metrics(layout_context);
- let line_block_metrics = LineBlockMetrics::new(line, fragment, layout_context);
- let mut block_start = line_block_metrics.start +
- line_block_metrics.size_above_baseline -
- fragment_inline_metrics.ascent;
-
- for style in fragment.inline_styles() {
- match style.get_box().vertical_align {
- vertical_align::T::baseline => {}
- vertical_align::T::middle => {}
- vertical_align::T::sub => {
- let sub_offset =
- (minimum_block_size_above_baseline +
- minimum_depth_below_baseline).scale_by(FONT_SUBSCRIPT_OFFSET_RATIO);
- block_start = block_start + sub_offset
- }
- vertical_align::T::super_ => {
- let super_offset =
- (minimum_block_size_above_baseline +
- minimum_depth_below_baseline).scale_by(FONT_SUPERSCRIPT_OFFSET_RATIO);
- block_start = block_start - super_offset
- }
- vertical_align::T::text_top => {
- block_start = line_block_metrics.start +
- line_block_metrics.size_above_baseline -
- minimum_block_size_above_baseline
- }
- vertical_align::T::text_bottom => {
- block_start = line_block_metrics.start +
- line_block_metrics.size_above_baseline +
- minimum_depth_below_baseline -
- fragment.border_box.size.block
- }
- vertical_align::T::top => {
- block_start = line_block_metrics.start
- }
- vertical_align::T::bottom => {
- block_start = line_block_metrics.start + line_block_metrics.size -
- fragment.border_box.size.block
- }
- vertical_align::T::LengthOrPercentage(LengthOrPercentage::Length(length)) => {
- block_start = block_start - length
- }
- vertical_align::T::LengthOrPercentage(LengthOrPercentage::Percentage(
- percentage)) => {
- let line_height = fragment.calculate_line_height(layout_context);
- let length = line_height.scale_by(percentage);
- block_start = block_start - length
- }
- vertical_align::T::LengthOrPercentage(LengthOrPercentage::Calc(calc)) => {
- let line_height = fragment.calculate_line_height(layout_context);
- let percentage_length = line_height.scale_by(calc.percentage());
- block_start = block_start - percentage_length - calc.length()
- }
- }
+ let line_metrics = LineMetrics::for_line_and_fragment(line, fragment, layout_context);
+ let inline_metrics = fragment.aligned_inline_metrics(layout_context,
+ minimum_line_metrics,
+ Some(&line_metrics));
+
+ // Align the top of the fragment's border box with its ascent above the baseline.
+ fragment.border_box.start.b = line.bounds.start.b + line_metrics.space_above_baseline -
+ inline_metrics.ascent;
+
+ // CSS 2.1 § 10.8: "The height of each inline-level box in the line box is
+ // calculated. For replaced elements, inline-block elements, and inline-table
+ // elements, this is the height of their margin box; for inline boxes, this is their
+ // 'line-height'."
+ //
+ // CSS 2.1 § 10.8.1: "Although margins, borders, and padding of non-replaced elements
+ // do not enter into the line box calculation, they are still rendered around inline
+ // boxes."
+ //
+ // Effectively, if the fragment is a non-replaced element (excluding inline-block), we
+ // need to align its ascent above the baseline with the top of the *content box*, not
+ // the border box. Since the code above has already aligned it to the border box, we
+ // simply need to adjust it in this case.
+ if !fragment.is_replaced_or_inline_block() {
+ fragment.border_box.start.b -= fragment.border_padding.block_start
}
- fragment.border_box.start.b = block_start;
fragment.update_late_computed_block_position_if_necessary();
}
}
- /// Computes the minimum ascent and descent for each line. This is done during flow
- /// construction.
+ /// Computes the minimum metrics for each line. This is done during flow construction.
///
/// `style` is the style of the block.
- pub fn compute_minimum_ascent_and_descent(&self,
+ pub fn minimum_line_metrics(&self, font_context: &mut FontContext, style: &ServoComputedValues)
+ -> LineMetrics {
+ InlineFlow::minimum_line_metrics_for_fragments(&self.fragments.fragments,
+ font_context,
+ style)
+ }
+
+ /// Computes the minimum line metrics for the given fragments. This is typically done during
+ /// flow construction.
+ ///
+ /// `style` is the style of the block that these fragments belong to.
+ pub fn minimum_line_metrics_for_fragments(fragments: &[Fragment],
font_context: &mut FontContext,
style: &ServoComputedValues)
- -> (Au, Au) {
+ -> LineMetrics {
// As a special case, if this flow contains only hypothetical fragments, then the entire
// flow is hypothetical and takes up no space. See CSS 2.1 § 10.3.7.
- if self.fragments.fragments.iter().all(|fragment| fragment.is_hypothetical()) {
- return (Au(0), Au(0))
+ if fragments.iter().all(Fragment::is_hypothetical) {
+ return LineMetrics::new(Au(0), Au(0))
}
let font_style = style.get_font_arc();
@@ -1141,86 +1084,73 @@ impl InlineFlow {
let line_height = text::line_height_from_style(style, &font_metrics);
let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height);
- let mut block_size_above_baseline = Au(0);
- let mut depth_below_baseline = Au(i32::MIN);
+ let mut line_metrics = LineMetrics::new(Au(0), Au(i32::MIN));
let mut largest_block_size_for_top_fragments = Au(0);
let mut largest_block_size_for_bottom_fragments = Au(0);
// We use `vertical_align::T::baseline` here because `vertical-align` must not apply to
// the inside of inline blocks.
- update_inline_metrics(&inline_metrics,
- style.get_box().display,
- vertical_align::T::baseline,
- &mut block_size_above_baseline,
- &mut depth_below_baseline,
- &mut largest_block_size_for_top_fragments,
- &mut largest_block_size_for_bottom_fragments);
+ update_line_metrics_for_fragment(&mut line_metrics,
+ &inline_metrics,
+ style.get_box().display,
+ vertical_align::T::baseline,
+ &mut largest_block_size_for_top_fragments,
+ &mut largest_block_size_for_bottom_fragments);
// According to CSS 2.1 § 10.8, `line-height` of any inline element specifies the minimal
// height of line boxes within the element.
- for frag in &self.fragments.fragments {
- if let Some(ref inline_context) = frag.inline_context {
- for node in &inline_context.nodes {
- let font_style = node.style.get_font_arc();
- let font_metrics = text::font_metrics_for_style(font_context, font_style);
- let line_height = text::line_height_from_style(&*node.style, &font_metrics);
- let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics,
- line_height);
-
- update_inline_metrics(&inline_metrics,
- node.style.get_box().display,
- node.style.get_box().vertical_align,
- &mut block_size_above_baseline,
- &mut depth_below_baseline,
- &mut largest_block_size_for_top_fragments,
- &mut largest_block_size_for_bottom_fragments);
+ for inline_context in fragments.iter()
+ .filter_map(|fragment| fragment.inline_context.as_ref()) {
+ for node in &inline_context.nodes {
+ let font_style = node.style.get_font_arc();
+ let font_metrics = text::font_metrics_for_style(font_context, font_style);
+ let line_height = text::line_height_from_style(&*node.style, &font_metrics);
+ let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height);
+
+ update_line_metrics_for_fragment(&mut line_metrics,
+ &inline_metrics,
+ node.style.get_box().display,
+ node.style.get_box().vertical_align,
+ &mut largest_block_size_for_top_fragments,
+ &mut largest_block_size_for_bottom_fragments);
- }
}
}
- block_size_above_baseline =
- max(block_size_above_baseline,
- largest_block_size_for_bottom_fragments - max(depth_below_baseline, Au(0)));
- depth_below_baseline =
- max(depth_below_baseline,
- largest_block_size_for_top_fragments - block_size_above_baseline);
+ line_metrics.space_above_baseline =
+ max(line_metrics.space_above_baseline,
+ largest_block_size_for_bottom_fragments - max(line_metrics.space_below_baseline,
+ Au(0)));
+ line_metrics.space_below_baseline =
+ max(line_metrics.space_below_baseline,
+ largest_block_size_for_top_fragments - line_metrics.space_above_baseline);
- return (block_size_above_baseline, depth_below_baseline);
+ return line_metrics;
- fn update_inline_metrics(inline_metrics: &InlineMetrics,
- display_value: display::T,
- vertical_align_value: vertical_align::T,
- block_size_above_baseline: &mut Au,
- depth_below_baseline: &mut Au,
- largest_block_size_for_top_fragments: &mut Au,
- largest_block_size_for_bottom_fragments: &mut Au) {
+ fn update_line_metrics_for_fragment(line_metrics: &mut LineMetrics,
+ inline_metrics: &InlineMetrics,
+ display_value: display::T,
+ vertical_align_value: vertical_align::T,
+ largest_block_size_for_top_fragments: &mut Au,
+ largest_block_size_for_bottom_fragments: &mut Au) {
match (display_value, vertical_align_value) {
(display::T::inline, vertical_align::T::top) |
(display::T::block, vertical_align::T::top) |
(display::T::inline_block, vertical_align::T::top) if
- inline_metrics.block_size_above_baseline >= Au(0) => {
- *largest_block_size_for_top_fragments =
- max(*largest_block_size_for_top_fragments,
- inline_metrics.block_size_above_baseline +
- inline_metrics.depth_below_baseline)
+ inline_metrics.space_above_baseline >= Au(0) => {
+ *largest_block_size_for_top_fragments = max(
+ *largest_block_size_for_top_fragments,
+ inline_metrics.space_above_baseline + inline_metrics.space_below_baseline)
}
(display::T::inline, vertical_align::T::bottom) |
(display::T::block, vertical_align::T::bottom) |
(display::T::inline_block, vertical_align::T::bottom) if
- inline_metrics.depth_below_baseline >= Au(0) => {
- *largest_block_size_for_bottom_fragments =
- max(*largest_block_size_for_bottom_fragments,
- inline_metrics.block_size_above_baseline +
- inline_metrics.depth_below_baseline)
- }
- _ => {
- *block_size_above_baseline =
- max(*block_size_above_baseline,
- inline_metrics.block_size_above_baseline);
- *depth_below_baseline = max(*depth_below_baseline,
- inline_metrics.depth_below_baseline);
+ inline_metrics.space_below_baseline >= Au(0) => {
+ *largest_block_size_for_bottom_fragments = max(
+ *largest_block_size_for_bottom_fragments,
+ inline_metrics.space_above_baseline + inline_metrics.space_below_baseline)
}
+ _ => *line_metrics = line_metrics.new_metrics_for_fragment(inline_metrics),
}
}
}
@@ -1284,7 +1214,7 @@ impl InlineFlow {
pub fn baseline_offset_of_last_line(&self) -> Option<Au> {
self.last_line_containing_real_fragments().map(|line| {
- line.bounds.start.b + line.bounds.size.block - line.inline_metrics.depth_below_baseline
+ line.bounds.start.b + line.bounds.size.block - line.metrics.space_below_baseline
})
}
@@ -1476,8 +1406,7 @@ impl Flow for InlineFlow {
// Perform line breaking.
let mut scanner = LineBreaker::new(self.base.floats.clone(),
indentation,
- self.minimum_block_size_above_baseline,
- self.minimum_depth_below_baseline);
+ &self.minimum_line_metrics);
scanner.scan_for_lines(self, layout_context);
// Now, go through each line and lay out the fragments inside.
@@ -1493,8 +1422,7 @@ impl Flow for InlineFlow {
// Compute the final positions in the block direction of each fragment.
InlineFlow::set_block_fragment_positions(&mut self.fragments,
line,
- self.minimum_block_size_above_baseline,
- self.minimum_depth_below_baseline,
+ &self.minimum_line_metrics,
layout_context);
// This is used to set the block-start position of the next line in the next iteration
@@ -1849,22 +1777,28 @@ fn inline_contexts_are_equal(inline_context_a: &Option<InlineFragmentContext>,
}
}
-/// Block-size above the baseline, depth below the baseline, and ascent for a fragment. See CSS 2.1
-/// § 10.8.1.
+/// Ascent and space needed above and below the baseline for a fragment. See CSS 2.1 § 10.8.1.
+///
+/// Descent is not included in this structure because it can be computed from the fragment's
+/// border/content box and the ascent.
#[derive(Clone, Copy, Debug, RustcEncodable)]
pub struct InlineMetrics {
- pub block_size_above_baseline: Au,
- pub depth_below_baseline: Au,
+ /// The amount of space above the baseline needed for this fragment.
+ pub space_above_baseline: Au,
+ /// The amount of space below the baseline needed for this fragment.
+ pub space_below_baseline: Au,
+ /// The distance from the baseline to the top of this fragment. This can differ from
+ /// `block_size_above_baseline` if the fragment needs some empty space above it due to
+ /// line-height, etc.
pub ascent: Au,
}
impl InlineMetrics {
/// Creates a new set of inline metrics.
- pub fn new(block_size_above_baseline: Au, depth_below_baseline: Au, ascent: Au)
- -> InlineMetrics {
+ pub fn new(space_above_baseline: Au, space_below_baseline: Au, ascent: Au) -> InlineMetrics {
InlineMetrics {
- block_size_above_baseline: block_size_above_baseline,
- depth_below_baseline: depth_below_baseline,
+ space_above_baseline: space_above_baseline,
+ space_below_baseline: space_below_baseline,
ascent: ascent,
}
}
@@ -1873,29 +1807,22 @@ impl InlineMetrics {
#[inline]
pub fn from_font_metrics(font_metrics: &FontMetrics, line_height: Au) -> InlineMetrics {
let leading = line_height - (font_metrics.ascent + font_metrics.descent);
+
// Calculating the half leading here and then using leading - half_leading
// below ensure that we don't introduce any rounding accuracy issues here.
// The invariant is that the resulting total line height must exactly
// equal the requested line_height.
let half_leading = leading.scale_by(0.5);
InlineMetrics {
- block_size_above_baseline: font_metrics.ascent + half_leading,
- depth_below_baseline: font_metrics.descent + leading - half_leading,
+ space_above_baseline: font_metrics.ascent + half_leading,
+ space_below_baseline: font_metrics.descent + leading - half_leading,
ascent: font_metrics.ascent,
}
}
- pub fn block_size(&self) -> Au {
- self.block_size_above_baseline + self.depth_below_baseline
- }
-
- pub fn max(&self, other: &InlineMetrics) -> InlineMetrics {
- InlineMetrics {
- block_size_above_baseline: max(self.block_size_above_baseline,
- other.block_size_above_baseline),
- depth_below_baseline: max(self.depth_below_baseline, other.depth_below_baseline),
- ascent: max(self.ascent, other.ascent),
- }
+ /// Returns the sum of the space needed above and below the baseline.
+ fn space_needed(&self) -> Au {
+ self.space_above_baseline + self.space_below_baseline
}
}
@@ -1905,31 +1832,55 @@ enum LineFlushMode {
Flush,
}
-struct LineBlockMetrics {
- start: Au,
- size: Au,
- size_above_baseline: Au,
+#[derive(Copy, Clone, Debug, RustcEncodable)]
+pub struct LineMetrics {
+ pub space_above_baseline: Au,
+ pub space_below_baseline: Au,
}
-impl LineBlockMetrics {
- fn new(line: &Line, fragment: &Fragment, layout_context: &LayoutContext) -> LineBlockMetrics {
+impl LineMetrics {
+ pub fn new(space_above_baseline: Au, space_below_baseline: Au) -> LineMetrics {
+ LineMetrics {
+ space_above_baseline: space_above_baseline,
+ space_below_baseline: space_below_baseline,
+ }
+ }
+
+ /// Returns the line metrics that result from combining the line that these metrics represent
+ /// with a fragment with the given metrics.
+ fn new_metrics_for_fragment(&self, fragment_inline_metrics: &InlineMetrics) -> LineMetrics {
+ LineMetrics {
+ space_above_baseline: max(self.space_above_baseline,
+ fragment_inline_metrics.space_above_baseline),
+ space_below_baseline: max(self.space_below_baseline,
+ fragment_inline_metrics.space_below_baseline),
+ }
+ }
+
+ fn for_line_and_fragment(line: &Line, fragment: &Fragment, layout_context: &LayoutContext)
+ -> LineMetrics {
if !fragment.is_hypothetical() {
- return LineBlockMetrics {
- start: line.bounds.start.b,
- size: line.bounds.size.block,
- size_above_baseline: line.inline_metrics.block_size_above_baseline,
+ let space_above_baseline = line.metrics.space_above_baseline;
+ return LineMetrics {
+ space_above_baseline: space_above_baseline,
+ space_below_baseline: line.bounds.size.block - space_above_baseline,
}
}
- let hypothetical_inline_metrics = line.new_inline_metrics(fragment, layout_context);
- let hypothetical_block_size = line.new_block_size(fragment,
- &hypothetical_inline_metrics,
- layout_context);
- LineBlockMetrics {
- start: line.bounds.start.b,
- size: hypothetical_block_size,
- size_above_baseline: hypothetical_inline_metrics.block_size_above_baseline,
+ let hypothetical_line_metrics = line.new_metrics_for_fragment(fragment, layout_context);
+ let hypothetical_block_size = line.new_block_size_for_fragment(fragment,
+ &hypothetical_line_metrics,
+ layout_context);
+ let hypothetical_space_above_baseline = hypothetical_line_metrics.space_above_baseline;
+ LineMetrics {
+ space_above_baseline: hypothetical_space_above_baseline,
+ space_below_baseline: hypothetical_block_size - hypothetical_space_above_baseline,
}
}
+
+ /// Returns the sum of the space needed above and below the baseline.
+ pub fn space_needed(&self) -> Au {
+ self.space_above_baseline + self.space_below_baseline
+ }
}
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 9bcb38cd5ad..75f42016076 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -18,14 +18,13 @@ use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedC
use fragment::Overflow;
use generated_content;
use gfx::display_list::StackingContext;
-use inline::InlineMetrics;
+use inline::InlineFlow;
use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT;
use std::sync::Arc;
use style::computed_values::{list_style_type, position};
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::ServoComputedValues;
-use text;
/// A block with the CSS `display` property equal to `list-item`.
#[derive(Debug)]
@@ -105,21 +104,20 @@ impl Flow for ListItemFlow {
fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
self.block_flow.assign_block_size(layout_context);
+ // FIXME(pcwalton): Do this during flow construction, like `InlineFlow` does?
+ let marker_line_metrics =
+ InlineFlow::minimum_line_metrics_for_fragments(&self.marker_fragments,
+ &mut layout_context.font_context(),
+ &*self.block_flow.fragment.style);
for marker in &mut self.marker_fragments {
let containing_block_block_size =
self.block_flow.base.block_container_explicit_block_size;
marker.assign_replaced_block_size_if_necessary(containing_block_block_size);
-
- let font_metrics =
- text::font_metrics_for_style(&mut layout_context.font_context(),
- marker.style.get_font_arc());
- let line_height = text::line_height_from_style(&*marker.style, &font_metrics);
- let item_inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height);
- let marker_inline_metrics = marker.inline_metrics(layout_context);
- marker.border_box.start.b = item_inline_metrics.block_size_above_baseline -
+ let marker_inline_metrics = marker.aligned_inline_metrics(layout_context,
+ &marker_line_metrics,
+ Some(&marker_line_metrics));
+ marker.border_box.start.b = marker_line_metrics.space_above_baseline -
marker_inline_metrics.ascent;
- marker.border_box.size.block = marker_inline_metrics.ascent +
- marker_inline_metrics.depth_below_baseline;
}
}
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-default.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-default.htm.ini
deleted file mode 100644
index 0a79af0a0af..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-default.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox-flex-direction-default.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row-reverse.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row-reverse.htm.ini
deleted file mode 100644
index c698835ab08..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row-reverse.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox-flex-direction-row-reverse.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row.htm.ini
deleted file mode 100644
index e6e5d318408..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-direction-row.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox-flex-direction-row.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap-reverse.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap-reverse.htm.ini
deleted file mode 100644
index baf24ce9d49..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap-reverse.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox-flex-wrap-wrap-reverse.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap.htm.ini
deleted file mode 100644
index 4cd53e2f17d..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox-flex-wrap-wrap.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox-flex-wrap-wrap.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/c5501-imrgn-t-000.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c5501-imrgn-t-000.htm.ini
deleted file mode 100644
index 7368fcb16f1..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/c5501-imrgn-t-000.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[c5501-imrgn-t-000.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/c5503-imrgn-b-000.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c5503-imrgn-b-000.htm.ini
deleted file mode 100644
index 4c5da0951ee..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/c5503-imrgn-b-000.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[c5503-imrgn-b-000.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-block-valign-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-block-valign-002.htm.ini
deleted file mode 100644
index 341c23ad5a3..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/inline-block-valign-002.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[inline-block-valign-002.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/line-height-129.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/line-height-129.htm.ini
deleted file mode 100644
index 9203572a2c9..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/line-height-129.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[line-height-129.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-applies-to-012.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-applies-to-012.htm.ini
deleted file mode 100644
index 9cb328147fd..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-applies-to-012.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[margin-applies-to-012.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-007.htm.ini
deleted file mode 100644
index 13f69ec2c31..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-007.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-007.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-008.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-008.htm.ini
deleted file mode 100644
index 01a7e4b816e..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-008.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-008.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-019.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-019.htm.ini
deleted file mode 100644
index b6ca8e83680..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-019.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-019.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-020.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-020.htm.ini
deleted file mode 100644
index 1c523497bbe..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-020.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-020.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-031.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-031.htm.ini
deleted file mode 100644
index e1b95516cea..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-031.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-031.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-032.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-032.htm.ini
deleted file mode 100644
index e65ced98fb9..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-032.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-032.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-043.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-043.htm.ini
deleted file mode 100644
index 997ee2da824..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-043.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-043.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-044.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-044.htm.ini
deleted file mode 100644
index 7157d26bf2c..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-044.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-044.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-055.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-055.htm.ini
deleted file mode 100644
index 2a51eb06e38..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-055.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-055.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-056.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-056.htm.ini
deleted file mode 100644
index f1c757ff723..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-056.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-056.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-067.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-067.htm.ini
deleted file mode 100644
index dae338ab0a6..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-067.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-067.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-068.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-068.htm.ini
deleted file mode 100644
index 784c8c9c1e1..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-068.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-068.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-079.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-079.htm.ini
deleted file mode 100644
index 62632801d5d..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-079.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-079.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-080.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-080.htm.ini
deleted file mode 100644
index 6f5ed8637b8..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/vertical-align-080.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[vertical-align-080.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 2045a615f5d..2d2a03fa7c5 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -2528,6 +2528,18 @@
"url": "/_mozilla/css/inline_block_border_intrinsic_size_a.html"
}
],
+ "css/inline_block_centering_a.html": [
+ {
+ "path": "css/inline_block_centering_a.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_block_centering_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_block_centering_a.html"
+ }
+ ],
"css/inline_block_height_with_out_of_flow_child_a.html": [
{
"path": "css/inline_block_height_with_out_of_flow_child_a.html",
@@ -5688,6 +5700,18 @@
"url": "/_mozilla/css/vertical_align_inside_table_a.html"
}
],
+ "css/vertical_align_middle_a.html": [
+ {
+ "path": "css/vertical_align_middle_a.html",
+ "references": [
+ [
+ "/_mozilla/css/vertical_align_middle_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/vertical_align_middle_a.html"
+ }
+ ],
"css/vertical_align_sub_a.html": [
{
"path": "css/vertical_align_sub_a.html",
@@ -16286,6 +16310,18 @@
"url": "/_mozilla/css/inline_block_border_intrinsic_size_a.html"
}
],
+ "css/inline_block_centering_a.html": [
+ {
+ "path": "css/inline_block_centering_a.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_block_centering_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_block_centering_a.html"
+ }
+ ],
"css/inline_block_height_with_out_of_flow_child_a.html": [
{
"path": "css/inline_block_height_with_out_of_flow_child_a.html",
@@ -19446,6 +19482,18 @@
"url": "/_mozilla/css/vertical_align_inside_table_a.html"
}
],
+ "css/vertical_align_middle_a.html": [
+ {
+ "path": "css/vertical_align_middle_a.html",
+ "references": [
+ [
+ "/_mozilla/css/vertical_align_middle_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/vertical_align_middle_a.html"
+ }
+ ],
"css/vertical_align_sub_a.html": [
{
"path": "css/vertical_align_sub_a.html",
diff --git a/tests/wpt/mozilla/tests/css/inline_block_centering_a.html b/tests/wpt/mozilla/tests/css/inline_block_centering_a.html
new file mode 100644
index 00000000000..dce2edebc09
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_block_centering_a.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="match" href="inline_block_centering_ref.html">
+<!--
+ Tests that the popular inline-block centering technique works.
+
+ See: https://s.codepen.io/shshaw/fullpage/gEiDt?#Inline-Block
+-->
+<style>
+div {
+ width: 100px;
+}
+#a {
+ background: blue;
+ position: absolute;
+ height: 100px;
+ top: 0;
+ left: 0;
+}
+#a:after, #b {
+ display: inline-block;
+ vertical-align: middle;
+}
+#a:after {
+ content: '';
+ height: 100%;
+}
+#b {
+ background: green;
+ height: 50px;
+}
+</style>
+<div id=a><div id=b>
diff --git a/tests/wpt/mozilla/tests/css/inline_block_centering_ref.html b/tests/wpt/mozilla/tests/css/inline_block_centering_ref.html
new file mode 100644
index 00000000000..b1d95ec9b42
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_block_centering_ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<!--
+ Tests that the popular inline-block centering technique works.
+
+ See: https://s.codepen.io/shshaw/fullpage/gEiDt?#Inline-Block
+-->
+<style>
+div {
+ position: absolute;
+ width: 100px;
+ left: 0;
+}
+#a {
+ background: blue;
+ height: 100px;
+ top: 0;
+}
+#b {
+ background: green;
+ height: 50px;
+ top: 25px;
+}
+</style>
+<div id=a><div id=b>
+
diff --git a/tests/wpt/mozilla/tests/css/vertical_align_middle_a.html b/tests/wpt/mozilla/tests/css/vertical_align_middle_a.html
new file mode 100644
index 00000000000..01b3cc0ab9c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/vertical_align_middle_a.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="match" href="vertical_align_middle_ref.html">
+<style>
+html, body {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+</style>
+<img width=50 height=50 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYPj/HwADAgH/xCAAOgAAAABJRU5ErkJggg=="><!--
+--><img width=100 height=100 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgaGD4DwAChAGA2FJdiQAAAABJRU5ErkJggg==">
+
diff --git a/tests/wpt/mozilla/tests/css/vertical_align_middle_ref.html b/tests/wpt/mozilla/tests/css/vertical_align_middle_ref.html
new file mode 100644
index 00000000000..e6e2b3428ea
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/vertical_align_middle_ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+html, body {
+ margin: 0;
+}
+div {
+ position: absolute;
+}
+#a {
+ left: 0;
+ top: 25px;
+ width: 50px;
+ height: 50px;
+ background: blue;
+}
+#b {
+ left: 50px;
+ top: 0;
+ width: 100px;
+ height: 100px;
+ background: green;
+}
+</style>
+<div id=a></div>
+<div id=b></div>
+
diff --git a/tests/wpt/mozilla/tests/css/vertical_align_super_a.html b/tests/wpt/mozilla/tests/css/vertical_align_super_a.html
index c1780235b83..d62a1acb8d1 100644
--- a/tests/wpt/mozilla/tests/css/vertical_align_super_a.html
+++ b/tests/wpt/mozilla/tests/css/vertical_align_super_a.html
@@ -11,7 +11,7 @@
}
div {
color: blue;
- margin-top: 100px;
+ margin-top: 82px;
}
.align {
color: red;