Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the writing mode of the containing block when accessing CSS properties #26836

Merged
merged 1 commit into from Jun 10, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Use the writing mode of the containing block when accessing CSS prope…

…rties

… and converting them to flow-relative geometric values.

These values are almost always used to size and position a fragment within its containing block, so using the mode of the containing block seems more correct.

Note that the `writing-mode` and `direction` properties are disabled in Servo at the moment, so this PR by itself should have no effect: the writing mode of an element is always the same of that of its containing block since they’re both horizontal rtl.
  • Loading branch information
SimonSapin committed Jun 10, 2020
commit 08f008a0111020d5207bd0fd598213461f69fa42
@@ -21,6 +21,7 @@ use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
use std::borrow::Cow;
use std::convert::{TryFrom, TryInto};
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
use style::values::specified::text::TextDecorationLine;
@@ -67,7 +68,12 @@ impl BlockFormattingContext {
inline_level_boxes,
text_decoration_line,
};
let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context));
// FIXME: this is the wrong writing mode
// but we plan to remove eager content size computation.
let not_actually_containing_block_writing_mode = WritingMode::empty();
let content_sizes = content_sizes.compute(|| {
ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode)
});
let contents = BlockContainer::InlineFormattingContext(ifc);
let bfc = Self {
contents,
@@ -203,10 +209,13 @@ impl BlockContainer {
.is_empty()
{
if builder.block_level_boxes.is_empty() {
// FIXME: this is the wrong writing mode
// but we plan to remove eager content size computation.
let not_actually_containing_block_writing_mode = info.style.writing_mode;
let content_sizes = content_sizes.compute(|| {
builder
.ongoing_inline_formatting_context
.inline_content_sizes(context)
.inline_content_sizes(context, not_actually_containing_block_writing_mode)
});
let container = BlockContainer::InlineFormattingContext(
builder.ongoing_inline_formatting_context,
@@ -678,6 +687,9 @@ where
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
let info = &self.info;
// FIXME: this is the wrong writing mode
// but we plan to remove eager content size computation.
let not_actually_containing_block_writing_mode = info.style.writing_mode;
let (block_level_box, contains_floats) = match self.kind {
BlockLevelCreator::SameFormattingContextBlock(contents) => {
let (contents, contains_floats, box_content_sizes) = contents.finish(
@@ -689,7 +701,10 @@ where
),
);
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
to.max_assign(&box_content_sizes.outer_inline(&info.style))
to.max_assign(
&box_content_sizes
.outer_inline(&info.style, not_actually_containing_block_writing_mode),
)
}
let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
tag: Tag::from_node_and_style_info(info),
@@ -716,7 +731,12 @@ where
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))
to.max_assign(
&contents.content_sizes.outer_inline(
&contents.style,
not_actually_containing_block_writing_mode,
),
)
}
(
ArcRefCell::new(BlockLevelBox::Independent(contents)),
@@ -771,7 +791,12 @@ impl IntermediateBlockContainer {
)
},
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context));
// FIXME: this is the wrong writing mode
// but we plan to remove eager content size computation.
let not_actually_containing_block_writing_mode = info.style.writing_mode;
let content_sizes = content_sizes.compute(|| {
ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode)
});
// If that inline formatting context contained any float, those
// were already taken into account during the first phase of
// box construction.
@@ -23,6 +23,7 @@ use app_units::Au;
use atomic_refcell::AtomicRef;
use gfx::text::text_run::GlyphRun;
use servo_arc::Arc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage};
use style::values::specified::text::TextAlignKeyword;
@@ -139,24 +140,30 @@ impl InlineFormattingContext {
// This works on an already-constructed `InlineFormattingContext`,
// Which would have to change if/when
// `BlockContainer::construct` parallelize their construction.
pub(super) fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes {
struct Computation {
pub(super) fn inline_content_sizes(
&self,
layout_context: &LayoutContext,
containing_block_writing_mode: WritingMode,
) -> ContentSizes {
struct Computation<'a> {
layout_context: &'a LayoutContext<'a>,
containing_block_writing_mode: WritingMode,
paragraph: ContentSizes,
current_line: ContentSizes,
current_line_percentages: Percentage,
}
impl Computation {
fn traverse(
&mut self,
layout_context: &LayoutContext,
inline_level_boxes: &[ArcRefCell<InlineLevelBox>],
) {
impl Computation<'_> {
fn traverse(&mut self, inline_level_boxes: &[ArcRefCell<InlineLevelBox>]) {
for inline_level_box in inline_level_boxes {
match &*inline_level_box.borrow() {
InlineLevelBox::InlineBox(inline_box) => {
let padding = inline_box.style.padding();
let border = inline_box.style.border_width();
let margin = inline_box.style.margin();
let padding =
inline_box.style.padding(self.containing_block_writing_mode);
let border = inline_box
.style
.border_width(self.containing_block_writing_mode);
let margin =
inline_box.style.margin(self.containing_block_writing_mode);
macro_rules! add {
($condition: ident, $side: ident) => {
if inline_box.$condition {
@@ -170,15 +177,15 @@ impl InlineFormattingContext {
}

add!(first_fragment, inline_start);
self.traverse(layout_context, &inline_box.children);
self.traverse(&inline_box.children);
add!(last_fragment, inline_end);
},
InlineLevelBox::TextRun(text_run) => {
let BreakAndShapeResult {
runs,
break_at_start,
..
} = text_run.break_and_shape(layout_context);
} = text_run.break_and_shape(self.layout_context);
if break_at_start {
self.line_break_opportunity()
}
@@ -193,9 +200,10 @@ impl InlineFormattingContext {
}
},
InlineLevelBox::Atomic(atomic) => {
let (outer, pc) = atomic
.content_sizes
.outer_inline_and_percentages(&atomic.style);
let (outer, pc) = atomic.content_sizes.outer_inline_and_percentages(
&atomic.style,
self.containing_block_writing_mode,
);
self.current_line.min_content += outer.min_content;
self.current_line.max_content += outer.max_content;
self.current_line_percentages += pc;
@@ -239,11 +247,13 @@ impl InlineFormattingContext {
std::mem::replace(x, T::zero())
}
let mut computation = Computation {
layout_context,
containing_block_writing_mode,
paragraph: ContentSizes::zero(),
current_line: ContentSizes::zero(),
current_line_percentages: Percentage::zero(),
};
computation.traverse(layout_context, &self.inline_level_boxes);
computation.traverse(&self.inline_level_boxes);
computation.forced_line_break();
computation.paragraph
}
@@ -308,6 +318,7 @@ impl InlineFormattingContext {
box_.clone(),
initial_start_corner,
tree_rank,
ifc.containing_block,
);
let hoisted_fragment = hoisted_box.fragment.clone();
ifc.push_hoisted_box_to_positioning_context(hoisted_box);
@@ -316,8 +316,12 @@ impl BlockLevelBox {
))
},
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
let hoisted_box =
AbsolutelyPositionedBox::to_hoisted(box_.clone(), Vec2::zero(), tree_rank);
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
box_.clone(),
Vec2::zero(),
tree_rank,
containing_block,
);
let hoisted_fragment = hoisted_box.fragment.clone();
positioning_context.push(hoisted_box);
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment {
@@ -100,6 +100,7 @@ impl AbsolutelyPositionedBox {
self_: ArcRefCell<Self>,
initial_start_corner: Vec2<Length>,
tree_rank: usize,
containing_block: &ContainingBlock,
) -> HoistedAbsolutelyPositionedBox {
fn absolute_box_offsets(
initial_static_start: Length,
@@ -123,7 +124,7 @@ impl AbsolutelyPositionedBox {

let box_offsets = {
let box_ = self_.borrow();
let box_offsets = box_.contents.style.box_offsets();
let box_offsets = box_.contents.style.box_offsets(containing_block);
Vec2 {
inline: absolute_box_offsets(
initial_start_corner.inline,
@@ -708,10 +709,12 @@ pub(crate) fn relative_adjustement(
) -> Vec2<Length> {
let cbis = containing_block.inline_size;
let cbbs = containing_block.block_size.auto_is(Length::zero);
let box_offsets = style.box_offsets().map_inline_and_block_axes(
|v| v.percentage_relative_to(cbis),
|v| v.percentage_relative_to(cbbs),
);
let box_offsets = style
.box_offsets(containing_block)
.map_inline_and_block_axes(
|v| v.percentage_relative_to(cbis),
|v| v.percentage_relative_to(cbbs),
);
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
match (start, end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
@@ -5,6 +5,7 @@
//! https://drafts.csswg.org/css-sizing/

use crate::style_ext::ComputedValuesExt;
use style::logical_geometry::WritingMode;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage};
@@ -105,19 +106,25 @@ impl BoxContentSizes {
}

/// https://dbaron.org/css/intrinsic/#outer-intrinsic
pub fn outer_inline(&self, style: &ComputedValues) -> ContentSizes {
let (mut outer, percentages) = self.outer_inline_and_percentages(style);
pub fn outer_inline(
&self,
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
) -> ContentSizes {
let (mut outer, percentages) =
self.outer_inline_and_percentages(style, containing_block_writing_mode);
outer.adjust_for_pbm_percentages(percentages);
outer
}

pub(crate) fn outer_inline_and_percentages(
&self,
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
) -> (ContentSizes, Percentage) {
let padding = style.padding();
let border = style.border_width();
let margin = style.margin();
let padding = style.padding(containing_block_writing_mode);
let border = style.border_width(containing_block_writing_mode);
let margin = style.margin(containing_block_writing_mode);

let mut pbm_percentages = Percentage::zero();
let mut decompose = |x: &LengthPercentage| {
@@ -136,20 +143,20 @@ impl BoxContentSizes {

let box_sizing = style.get_position().box_sizing;
let inline_size = style
.box_size()
.box_size(containing_block_writing_mode)
.inline
.non_auto()
// Percentages for 'width' are treated as 'auto'
.and_then(|lp| lp.to_length());
let min_inline_size = style
.min_box_size()
.min_box_size(containing_block_writing_mode)
.inline
// Percentages for 'min-width' are treated as zero
.percentage_relative_to(Length::zero())
// FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero);
let max_inline_size = style
.max_box_size()
.max_box_size(containing_block_writing_mode)
.inline
// Percentages for 'max-width' are treated as 'none'
.and_then(|lp| lp.to_length());
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.