mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
layout: Check flow descendants of inline block fragments to find their
baselines when aligning inline fragments per CSS 2.1 § 10.8.1.
This commit is contained in:
parent
8823f87276
commit
04f05349b1
6 changed files with 191 additions and 65 deletions
|
@ -512,6 +512,8 @@ pub trait ImmutableFlowUtils {
|
|||
/// Returns true if floats might flow through this flow, as determined by the float placement
|
||||
/// speculation pass.
|
||||
fn floats_might_flow_through(self) -> bool;
|
||||
|
||||
fn baseline_offset_of_last_line_box_in_flow(self) -> Option<Au>;
|
||||
}
|
||||
|
||||
pub trait MutableFlowUtils {
|
||||
|
@ -634,45 +636,48 @@ bitflags! {
|
|||
#[doc = "Whether this flow must have its own layer. Even if this flag is not set, it might"]
|
||||
#[doc = "get its own layer if it's deemed to be likely to overlap flows with their own"]
|
||||
#[doc = "layer."]
|
||||
const NEEDS_LAYER = 0b0000_0000_0000_0010_0000,
|
||||
const NEEDS_LAYER = 0b0000_0000_0000_0000_0010_0000,
|
||||
#[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"]
|
||||
#[doc = "virtual call is too expensive."]
|
||||
const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0100_0000,
|
||||
const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0000_0100_0000,
|
||||
#[doc = "Whether this flow clears to the left. This is checked all over layout, so a"]
|
||||
#[doc = "virtual call is too expensive."]
|
||||
const CLEARS_LEFT = 0b0000_0000_0000_1000_0000,
|
||||
const CLEARS_LEFT = 0b0000_0000_0000_0000_1000_0000,
|
||||
#[doc = "Whether this flow clears to the right. This is checked all over layout, so a"]
|
||||
#[doc = "virtual call is too expensive."]
|
||||
const CLEARS_RIGHT = 0b0000_0000_0001_0000_0000,
|
||||
const CLEARS_RIGHT = 0b0000_0000_0000_0001_0000_0000,
|
||||
#[doc = "Whether this flow is left-floated. This is checked all over layout, so a"]
|
||||
#[doc = "virtual call is too expensive."]
|
||||
const FLOATS_LEFT = 0b0000_0000_0010_0000_0000,
|
||||
const FLOATS_LEFT = 0b0000_0000_0000_0010_0000_0000,
|
||||
#[doc = "Whether this flow is right-floated. This is checked all over layout, so a"]
|
||||
#[doc = "virtual call is too expensive."]
|
||||
const FLOATS_RIGHT = 0b0000_0000_0100_0000_0000,
|
||||
const FLOATS_RIGHT = 0b0000_0000_0000_0100_0000_0000,
|
||||
#[doc = "Text alignment. \
|
||||
|
||||
NB: If you update this, update `TEXT_ALIGN_SHIFT` below."]
|
||||
const TEXT_ALIGN = 0b0000_0111_1000_0000_0000,
|
||||
const TEXT_ALIGN = 0b0000_0000_0111_1000_0000_0000,
|
||||
#[doc = "Whether this flow has a fragment with `counter-reset` or `counter-increment` \
|
||||
styles."]
|
||||
const AFFECTS_COUNTERS = 0b0000_1000_0000_0000_0000,
|
||||
const AFFECTS_COUNTERS = 0b0000_0000_1000_0000_0000_0000,
|
||||
#[doc = "Whether this flow's descendants have fragments that affect `counter-reset` or \
|
||||
`counter-increment` styles."]
|
||||
const HAS_COUNTER_AFFECTING_CHILDREN = 0b0001_0000_0000_0000_0000,
|
||||
const HAS_COUNTER_AFFECTING_CHILDREN = 0b0000_0001_0000_0000_0000_0000,
|
||||
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
|
||||
of positioning in the inline direction. This is set for flows with `position: \
|
||||
static` and `position: relative` as well as absolutely-positioned flows with \
|
||||
unconstrained positions in the inline direction."]
|
||||
const INLINE_POSITION_IS_STATIC = 0b0010_0000_0000_0000_0000,
|
||||
const INLINE_POSITION_IS_STATIC = 0b0000_0010_0000_0000_0000_0000,
|
||||
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
|
||||
of positioning in the block direction. This is set for flows with `position: \
|
||||
static` and `position: relative` as well as absolutely-positioned flows with \
|
||||
unconstrained positions in the block direction."]
|
||||
const BLOCK_POSITION_IS_STATIC = 0b0100_0000_0000_0000_0000,
|
||||
const BLOCK_POSITION_IS_STATIC = 0b0000_0100_0000_0000_0000_0000,
|
||||
|
||||
/// Whether any ancestor is a fragmentation container
|
||||
const CAN_BE_FRAGMENTED = 0b1000_0000_0000_0000_0000,
|
||||
const CAN_BE_FRAGMENTED = 0b0000_1000_0000_0000_0000_0000,
|
||||
|
||||
/// Whether this flow contains any text and/or replaced fragments.
|
||||
const CONTAINS_TEXT_OR_REPLACED_FRAGMENTS = 0b0001_0000_0000_0000_0000_0000,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1387,6 +1392,21 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
|
|||
}
|
||||
self.as_block().formatting_context_type() == FormattingContextType::None
|
||||
}
|
||||
|
||||
fn baseline_offset_of_last_line_box_in_flow(self) -> Option<Au> {
|
||||
for kid in base(self).children.iter().rev() {
|
||||
if kid.is_inline_flow() {
|
||||
return kid.as_inline().baseline_offset_of_last_line()
|
||||
}
|
||||
if kid.is_block_like() &&
|
||||
kid.as_block().formatting_context_type() == FormattingContextType::None {
|
||||
if let Some(baseline_offset) = kid.baseline_offset_of_last_line_box_in_flow() {
|
||||
return Some(base(kid).position.start.b + baseline_offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutableFlowUtils for &'a mut Flow {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue