Auto merge of #7825 - eefriedman:div-align, r=mbrubeck

Fully implement the "align descendants" rule for div.

This adds -servo-left and -servo-right to complement -servo-center.

~~This intentionally doesn't try to address issue #7301.~~  Commit added to address #7301.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7825)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-08 12:20:55 -06:00
commit ab42ca4296
9 changed files with 194 additions and 40 deletions

View file

@ -1466,8 +1466,9 @@ impl BlockFlow {
// Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow.
//
// TODO(#2018, pcwalton): Do this in the cascade instead.
flow::mut_base(kid).flags.propagate_text_alignment_from_parent(flags.clone());
// TODO(#2265, pcwalton): Do this in the cascade instead.
let containing_block_text_align = self.fragment.style().get_inheritedtext().text_align;
flow::mut_base(kid).flags.set_text_align(containing_block_text_align);
// Handle `text-indent` on behalf of any inline children that we have. This is
// necessary because any percentages are relative to the containing block, which only
@ -2272,9 +2273,6 @@ pub trait ISizeAndMarginsComputer {
(_, box_sizing::T::content_box) => {}
}
// The text alignment of a block flow is the text alignment of its box's style.
block.base.flags.set_text_align(style.get_inheritedtext().text_align);
let margin = style.logical_margin();
let position = style.logical_position();
@ -2438,6 +2436,7 @@ pub trait ISizeAndMarginsComputer {
// Check for direction of parent flow (NOT Containing Block)
let block_mode = block.base.writing_mode;
let container_mode = block.base.block_container_writing_mode;
let block_align = block.base.flags.text_align();
// FIXME (mbrubeck): Handle vertical writing modes.
let parent_has_same_direction = container_mode.is_bidi_ltr() == block_mode.is_bidi_ltr();
@ -2466,20 +2465,23 @@ pub trait ISizeAndMarginsComputer {
(MaybeAuto::Specified(margin_start),
MaybeAuto::Specified(inline_size),
MaybeAuto::Specified(margin_end)) => {
match (input.text_align, parent_has_same_direction) {
(text_align::T::servo_center, _) => {
// This is used for `<center>` and friends per HTML5 § 14.3.3. Make the
// inline-start and inline-end margins equal per HTML5 § 14.2.
let margin = (available_inline_size - inline_size).scale_by(0.5);
(margin, inline_size, margin)
}
(_, true) => {
// Ignore the end margin.
// servo_left, servo_right, and servo_center are used to implement
// the "align descendants" rule in HTML5 § 14.2.
if block_align == text_align::T::servo_center {
// Ignore any existing margins, and make the inline-start and
// inline-end margins equal.
let margin = (available_inline_size - inline_size).scale_by(0.5);
(margin, inline_size, margin)
} else {
let ignore_end_margin = match block_align {
text_align::T::servo_left => block_mode.is_bidi_ltr(),
text_align::T::servo_right => !block_mode.is_bidi_ltr(),
_ => parent_has_same_direction,
};
if ignore_end_margin {
(margin_start, inline_size, available_inline_size -
(margin_start + inline_size))
}
(_, false) => {
// Ignore the start margin.
} else {
(available_inline_size - (margin_end + inline_size),
inline_size,
margin_end)

View file

@ -656,14 +656,6 @@ static HAS_FLOATED_DESCENDANTS_BITMASK: FlowFlags = FlowFlags { bits: 0b0000_001
static TEXT_ALIGN_SHIFT: usize = 11;
impl FlowFlags {
/// Propagates text alignment flags from an appropriate parent flow per CSS 2.1.
///
/// FIXME(#2265, pcwalton): It would be cleaner and faster to make this a derived CSS property
/// `-servo-text-align-in-effect`.
pub fn propagate_text_alignment_from_parent(&mut self, parent_flags: FlowFlags) {
self.set_text_align_override(parent_flags);
}
#[inline]
pub fn text_align(self) -> text_align::T {
text_align::T::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
@ -675,11 +667,6 @@ impl FlowFlags {
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
}
#[inline]
pub fn set_text_align_override(&mut self, parent: FlowFlags) {
self.insert(parent & TEXT_ALIGN);
}
#[inline]
pub fn union_floated_descendants_flags(&mut self, other: FlowFlags) {
self.insert(other & HAS_FLOATED_DESCENDANTS_BITMASK);

View file

@ -1019,8 +1019,14 @@ impl InlineFlow {
// Translate `left` and `right` to logical directions.
let is_ltr = fragments.fragments[0].style().writing_mode.is_bidi_ltr();
let line_align = match (line_align, is_ltr) {
(text_align::T::left, true) | (text_align::T::right, false) => text_align::T::start,
(text_align::T::left, false) | (text_align::T::right, true) => text_align::T::end,
(text_align::T::left, true) |
(text_align::T::servo_left, true) |
(text_align::T::right, false) |
(text_align::T::servo_right, false) => text_align::T::start,
(text_align::T::left, false) |
(text_align::T::servo_left, false) |
(text_align::T::right, true) |
(text_align::T::servo_right, true) => text_align::T::end,
_ => line_align
};
@ -1040,7 +1046,10 @@ impl InlineFlow {
inline_start_position_for_fragment = inline_start_position_for_fragment +
slack_inline_size
}
text_align::T::left | text_align::T::right => unreachable!()
text_align::T::left |
text_align::T::servo_left |
text_align::T::right |
text_align::T::servo_right => unreachable!()
}
// Lay out the fragments in visual order.