mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Use the writing mode of the containing block when accessing CSS properties
… 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.
This commit is contained in:
parent
554af02ab4
commit
08f008a011
6 changed files with 165 additions and 64 deletions
|
@ -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,7 +177,7 @@ 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) => {
|
||||
|
@ -178,7 +185,7 @@ impl InlineFormattingContext {
|
|||
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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue