layout: Use the fragment's writing mode when computing sizes relevant to that fragment.

Otherwise we might mix writing modes. Not totally sure this change is correct in
the case we're mixing them, we might need to just not checking that operation.
This commit is contained in:
Emilio Cobos Álvarez 2016-09-26 12:10:48 +02:00
parent 3dddb70038
commit bdf1d179ba
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
3 changed files with 29 additions and 13 deletions

View file

@ -1155,8 +1155,14 @@ impl Fragment {
match self.inline_context { match self.inline_context {
None => style_border_width, None => style_border_width,
Some(ref inline_fragment_context) => { Some(ref inline_fragment_context) => {
// NOTE: We can have nodes with different writing mode inside
// the inline fragment context, so we need to overwrite the
// writing mode to compute the child logical sizes.
let writing_mode = self.style.writing_mode;
inline_fragment_context.nodes.iter().fold(style_border_width, |accumulator, node| { inline_fragment_context.nodes.iter().fold(style_border_width, |accumulator, node| {
let mut this_border_width = node.style.logical_border_width(); let mut this_border_width =
node.style.border_width_for_writing_mode(writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
this_border_width.inline_start = Au(0) this_border_width.inline_start = Au(0)
} }
@ -1289,7 +1295,7 @@ impl Fragment {
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::TableWrapper |
SpecificFragmentInfo::InlineBlock(_) => LogicalMargin::zero(self.style.writing_mode), SpecificFragmentInfo::InlineBlock(_) => LogicalMargin::zero(self.style.writing_mode),
_ => model::padding_from_style(self.style(), containing_block_inline_size), _ => model::padding_from_style(self.style(), containing_block_inline_size, self.style().writing_mode),
}; };
// Compute padding from the inline fragment context. // Compute padding from the inline fragment context.
@ -1301,9 +1307,10 @@ impl Fragment {
LogicalMargin::zero(self.style.writing_mode) LogicalMargin::zero(self.style.writing_mode)
} }
(_, &Some(ref inline_fragment_context)) => { (_, &Some(ref inline_fragment_context)) => {
let zero_padding = LogicalMargin::zero(self.style.writing_mode); let writing_mode = self.style.writing_mode;
let zero_padding = LogicalMargin::zero(writing_mode);
inline_fragment_context.nodes.iter().fold(zero_padding, |accumulator, node| { inline_fragment_context.nodes.iter().fold(zero_padding, |accumulator, node| {
let mut padding = model::padding_from_style(&*node.style, Au(0)); let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
padding.inline_start = Au(0) padding.inline_start = Au(0)
} }
@ -1529,11 +1536,12 @@ impl Fragment {
// Take borders and padding for parent inline fragments into account, if necessary. // Take borders and padding for parent inline fragments into account, if necessary.
if self.is_primary_fragment() { if self.is_primary_fragment() {
let writing_mode = self.style.writing_mode;
if let Some(ref context) = self.inline_context { if let Some(ref context) = self.inline_context {
for node in &context.nodes { for node in &context.nodes {
let mut border_width = node.style.logical_border_width(); let mut border_width = node.style.logical_border_width();
let mut padding = model::padding_from_style(&*node.style, Au(0)); let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
let mut margin = model::specified_margin_from_style(&*node.style); let mut margin = model::specified_margin_from_style(&*node.style, writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
border_width.inline_start = Au(0); border_width.inline_start = Au(0);
padding.inline_start = Au(0); padding.inline_start = Au(0);

View file

@ -12,7 +12,7 @@ use fragment::Fragment;
use std::cmp::{max, min}; use std::cmp::{max, min};
use std::fmt; use std::fmt;
use style::computed_values::transform::ComputedMatrix; use style::computed_values::transform::ComputedMatrix;
use style::logical_geometry::LogicalMargin; use style::logical_geometry::{LogicalMargin, WritingMode};
use style::properties::ServoComputedValues; use style::properties::ServoComputedValues;
use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto}; use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone};
@ -463,10 +463,12 @@ pub fn specified_border_radius(radius: BorderRadiusSize, containing_length: Au)
} }
#[inline] #[inline]
pub fn padding_from_style(style: &ServoComputedValues, containing_block_inline_size: Au) pub fn padding_from_style(style: &ServoComputedValues,
containing_block_inline_size: Au,
writing_mode: WritingMode)
-> LogicalMargin<Au> { -> LogicalMargin<Au> {
let padding_style = style.get_padding(); let padding_style = style.get_padding();
LogicalMargin::from_physical(style.writing_mode, SideOffsets2D::new( LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
specified(padding_style.padding_top, containing_block_inline_size), specified(padding_style.padding_top, containing_block_inline_size),
specified(padding_style.padding_right, containing_block_inline_size), specified(padding_style.padding_right, containing_block_inline_size),
specified(padding_style.padding_bottom, containing_block_inline_size), specified(padding_style.padding_bottom, containing_block_inline_size),
@ -478,9 +480,10 @@ pub fn padding_from_style(style: &ServoComputedValues, containing_block_inline_s
/// ///
/// This is used when calculating intrinsic inline sizes. /// This is used when calculating intrinsic inline sizes.
#[inline] #[inline]
pub fn specified_margin_from_style(style: &ServoComputedValues) -> LogicalMargin<Au> { pub fn specified_margin_from_style(style: &ServoComputedValues,
writing_mode: WritingMode) -> LogicalMargin<Au> {
let margin_style = style.get_margin(); let margin_style = style.get_margin();
LogicalMargin::from_physical(style.writing_mode, SideOffsets2D::new( LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
MaybeAuto::from_style(margin_style.margin_top, Au(0)).specified_or_zero(), MaybeAuto::from_style(margin_style.margin_top, Au(0)).specified_or_zero(),
MaybeAuto::from_style(margin_style.margin_right, Au(0)).specified_or_zero(), MaybeAuto::from_style(margin_style.margin_right, Au(0)).specified_or_zero(),
MaybeAuto::from_style(margin_style.margin_bottom, Au(0)).specified_or_zero(), MaybeAuto::from_style(margin_style.margin_bottom, Au(0)).specified_or_zero(),

View file

@ -1526,9 +1526,9 @@ impl ComputedValues {
} }
#[inline] #[inline]
pub fn logical_border_width(&self) -> LogicalMargin<Au> { pub fn border_width_for_writing_mode(&self, writing_mode: WritingMode) -> LogicalMargin<Au> {
let border_style = self.get_border(); let border_style = self.get_border();
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new( LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
border_style.border_top_width, border_style.border_top_width,
border_style.border_right_width, border_style.border_right_width,
border_style.border_bottom_width, border_style.border_bottom_width,
@ -1536,6 +1536,11 @@ impl ComputedValues {
)) ))
} }
#[inline]
pub fn logical_border_width(&self) -> LogicalMargin<Au> {
self.border_width_for_writing_mode(self.writing_mode)
}
#[inline] #[inline]
pub fn logical_margin(&self) -> LogicalMargin<computed::LengthOrPercentageOrAuto> { pub fn logical_margin(&self) -> LogicalMargin<computed::LengthOrPercentageOrAuto> {
let margin_style = self.get_margin(); let margin_style = self.get_margin();