mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Make for_maybe_position_relative
take care of relative adjustment.
This commit is contained in:
parent
b218957461
commit
58b7005a9b
6 changed files with 49 additions and 56 deletions
|
@ -9,10 +9,10 @@ use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragments::CollapsedBlockMargins;
|
use crate::fragments::CollapsedBlockMargins;
|
||||||
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
|
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
|
||||||
use crate::{relative_adjustement, ContainingBlock};
|
use crate::ContainingBlock;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use gfx::text::text_run::GlyphRun;
|
use gfx::text::text_run::GlyphRun;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
|
@ -367,11 +367,9 @@ impl InlineBox {
|
||||||
block: padding.block_start + border.block_start + margin.block_start,
|
block: padding.block_start + border.block_start + margin.block_start,
|
||||||
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
|
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
|
||||||
};
|
};
|
||||||
start_corner += &relative_adjustement(
|
if style.clone_position().is_relative() {
|
||||||
&style,
|
start_corner += &relative_adjustement(&style, ifc.containing_block)
|
||||||
ifc.containing_block.inline_size,
|
}
|
||||||
ifc.containing_block.block_size,
|
|
||||||
);
|
|
||||||
PartialInlineBoxFragment {
|
PartialInlineBoxFragment {
|
||||||
style,
|
style,
|
||||||
start_corner,
|
start_corner,
|
||||||
|
@ -457,11 +455,9 @@ fn layout_atomic<'box_tree>(
|
||||||
block: pbm.block_start,
|
block: pbm.block_start,
|
||||||
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
|
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
|
||||||
};
|
};
|
||||||
start_corner += &relative_adjustement(
|
if atomic.style.clone_position().is_relative() {
|
||||||
&atomic.style,
|
start_corner += &relative_adjustement(&atomic.style, ifc.containing_block)
|
||||||
ifc.containing_block.inline_size,
|
}
|
||||||
ifc.containing_block.block_size,
|
|
||||||
);
|
|
||||||
|
|
||||||
let fragment = match atomic.as_replaced() {
|
let fragment = match atomic.as_replaced() {
|
||||||
Ok(replaced) => {
|
Ok(replaced) => {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::replaced::ReplacedContent;
|
use crate::replaced::ReplacedContent;
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::ComputedValuesExt;
|
||||||
use crate::{relative_adjustement, ContainingBlock};
|
use crate::ContainingBlock;
|
||||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||||
use rayon_croissant::ParallelIteratorExt;
|
use rayon_croissant::ParallelIteratorExt;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
|
@ -271,6 +271,7 @@ impl BlockLevelBox {
|
||||||
BlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
BlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
||||||
Fragment::Box(positioning_context.for_maybe_position_relative(
|
Fragment::Box(positioning_context.for_maybe_position_relative(
|
||||||
layout_context,
|
layout_context,
|
||||||
|
containing_block,
|
||||||
style,
|
style,
|
||||||
|positioning_context| {
|
|positioning_context| {
|
||||||
layout_in_flow_non_replaced_block_level(
|
layout_in_flow_non_replaced_block_level(
|
||||||
|
@ -288,6 +289,7 @@ impl BlockLevelBox {
|
||||||
BlockLevelBox::Independent(contents) => {
|
BlockLevelBox::Independent(contents) => {
|
||||||
Fragment::Box(positioning_context.for_maybe_position_relative(
|
Fragment::Box(positioning_context.for_maybe_position_relative(
|
||||||
layout_context,
|
layout_context,
|
||||||
|
containing_block,
|
||||||
&contents.style,
|
&contents.style,
|
||||||
|positioning_context| match contents.as_replaced() {
|
|positioning_context| match contents.as_replaced() {
|
||||||
Ok(replaced) => layout_in_flow_replaced_block_level(
|
Ok(replaced) => layout_in_flow_replaced_block_level(
|
||||||
|
@ -470,14 +472,13 @@ fn layout_in_flow_non_replaced_block_level<'a>(
|
||||||
content_block_size = independent_layout.content_block_size;
|
content_block_size = independent_layout.content_block_size;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let relative_adjustement = relative_adjustement(style, inline_size, block_size);
|
|
||||||
let block_size = block_size.auto_is(|| {
|
let block_size = block_size.auto_is(|| {
|
||||||
content_block_size.clamp_between_extremums(min_box_size.block, max_box_size.block)
|
content_block_size.clamp_between_extremums(min_box_size.block, max_box_size.block)
|
||||||
});
|
});
|
||||||
let content_rect = Rect {
|
let content_rect = Rect {
|
||||||
start_corner: Vec2 {
|
start_corner: Vec2 {
|
||||||
block: pb.block_start + relative_adjustement.block,
|
block: pb.block_start,
|
||||||
inline: pb.inline_start + relative_adjustement.inline + margin.inline_start,
|
inline: pb.inline_start,
|
||||||
},
|
},
|
||||||
size: Vec2 {
|
size: Vec2 {
|
||||||
block: block_size,
|
block: block_size,
|
||||||
|
@ -525,15 +526,10 @@ fn layout_in_flow_replaced_block_level<'a>(
|
||||||
block_end: computed_margin.block_end.auto_is(Length::zero),
|
block_end: computed_margin.block_end.auto_is(Length::zero),
|
||||||
};
|
};
|
||||||
let fragments = replaced.make_fragments(style, size.clone());
|
let fragments = replaced.make_fragments(style, size.clone());
|
||||||
let relative_adjustement = relative_adjustement(
|
|
||||||
style,
|
|
||||||
size.inline,
|
|
||||||
LengthOrAuto::LengthPercentage(size.block),
|
|
||||||
);
|
|
||||||
let content_rect = Rect {
|
let content_rect = Rect {
|
||||||
start_corner: Vec2 {
|
start_corner: Vec2 {
|
||||||
block: pb.block_start + relative_adjustement.block,
|
block: pb.block_start,
|
||||||
inline: pb.inline_start + relative_adjustement.inline + margin.inline_start,
|
inline: pb.inline_start + margin.inline_start,
|
||||||
},
|
},
|
||||||
size,
|
size,
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,11 +27,8 @@ pub mod wrapper;
|
||||||
pub use flow::{BoxTreeRoot, FragmentTreeRoot};
|
pub use flow::{BoxTreeRoot, FragmentTreeRoot};
|
||||||
|
|
||||||
use crate::geom::flow_relative::Vec2;
|
use crate::geom::flow_relative::Vec2;
|
||||||
use crate::style_ext::ComputedValuesExt;
|
|
||||||
use style::computed_values::position::T as Position;
|
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{Length, LengthOrAuto};
|
use style::values::computed::{Length, LengthOrAuto};
|
||||||
use style::Zero;
|
|
||||||
|
|
||||||
struct ContainingBlock<'a> {
|
struct ContainingBlock<'a> {
|
||||||
inline_size: Length,
|
inline_size: Length,
|
||||||
|
@ -53,30 +50,3 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css2/visuren.html#relative-positioning
|
|
||||||
fn relative_adjustement(
|
|
||||||
style: &ComputedValues,
|
|
||||||
inline_size: Length,
|
|
||||||
block_size: LengthOrAuto,
|
|
||||||
) -> Vec2<Length> {
|
|
||||||
if style.get_box().position != Position::Relative {
|
|
||||||
return Vec2::zero();
|
|
||||||
}
|
|
||||||
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
|
|
||||||
match (start, end) {
|
|
||||||
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
|
|
||||||
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end,
|
|
||||||
(LengthOrAuto::LengthPercentage(start), _) => start,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let block_size = block_size.auto_is(Length::zero);
|
|
||||||
let box_offsets = style.box_offsets().map_inline_and_block_axes(
|
|
||||||
|v| v.percentage_relative_to(inline_size),
|
|
||||||
|v| v.percentage_relative_to(block_size),
|
|
||||||
);
|
|
||||||
Vec2 {
|
|
||||||
inline: adjust(box_offsets.inline_start, box_offsets.inline_end),
|
|
||||||
block: adjust(box_offsets.block_start, box_offsets.block_end),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -150,11 +150,17 @@ impl<'box_tree> PositioningContext<'box_tree> {
|
||||||
pub(crate) fn for_maybe_position_relative(
|
pub(crate) fn for_maybe_position_relative(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
f: impl FnOnce(&mut Self) -> BoxFragment,
|
f: impl FnOnce(&mut Self) -> BoxFragment,
|
||||||
) -> BoxFragment {
|
) -> BoxFragment {
|
||||||
if style.clone_position() == Position::Relative {
|
if style.clone_position() == Position::Relative {
|
||||||
Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f)
|
let mut fragment =
|
||||||
|
// Establing a containing block for absolutely positioned descendants
|
||||||
|
Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f);
|
||||||
|
|
||||||
|
fragment.content_rect.start_corner += &relative_adjustement(style, containing_block);
|
||||||
|
fragment
|
||||||
} else {
|
} else {
|
||||||
f(self)
|
f(self)
|
||||||
}
|
}
|
||||||
|
@ -610,3 +616,27 @@ fn vec_append_owned<T>(a: &mut Vec<T>, mut b: Vec<T>) {
|
||||||
a.append(&mut b)
|
a.append(&mut b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css2/visuren.html#relative-positioning
|
||||||
|
pub(crate) fn relative_adjustement(
|
||||||
|
style: &ComputedValues,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
) -> 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),
|
||||||
|
);
|
||||||
|
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
|
||||||
|
match (start, end) {
|
||||||
|
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
|
||||||
|
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end,
|
||||||
|
(LengthOrAuto::LengthPercentage(start), _) => start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vec2 {
|
||||||
|
inline: adjust(box_offsets.inline_start, box_offsets.inline_end),
|
||||||
|
block: adjust(box_offsets.block_start, box_offsets.block_end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,6 +55,9 @@ impl computed_value::T {
|
||||||
pub fn is_absolutely_positioned(self) -> bool {
|
pub fn is_absolutely_positioned(self) -> bool {
|
||||||
matches!(self, Self::Absolute | Self::Fixed)
|
matches!(self, Self::Absolute | Self::Fixed)
|
||||||
}
|
}
|
||||||
|
pub fn is_relative(self) -> bool {
|
||||||
|
self == Self::Relative
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</%helpers:single_keyword>
|
</%helpers:single_keyword>
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[block-in-inline-relpos-001.xht]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue