Use the WritingMode bitflags from Stylo

This commit is contained in:
Simon Sapin 2019-12-05 12:33:44 +01:00
parent b9adf8b7ac
commit 40ad9a722d
10 changed files with 62 additions and 81 deletions

View file

@ -4,7 +4,6 @@
use crate::fragments::{BoxFragment, Fragment};
use crate::geom::physical::{Rect, Vec2};
use crate::style_ext::ComputedValuesExt;
use euclid::{Point2D, SideOffsets2D};
use gfx::text::glyph::GlyphStore;
use std::sync::Arc;
@ -55,7 +54,7 @@ impl Fragment {
is_contentful.0 = true;
let rect = t
.content_rect
.to_physical(t.parent_style.writing_mode(), containing_block)
.to_physical(t.parent_style.writing_mode, containing_block)
.translate(&containing_block.top_left);
let mut baseline_origin = rect.top_left.clone();
baseline_origin.y += t.ascent;
@ -81,7 +80,7 @@ impl Fragment {
is_contentful.0 = true;
let rect = i
.content_rect
.to_physical(i.style.writing_mode(), containing_block)
.to_physical(i.style.writing_mode, containing_block)
.translate(&containing_block.top_left);
let common = CommonItemProperties {
clip_rect: rect.clone().into(),
@ -117,7 +116,7 @@ impl BoxFragment {
) {
let border_rect = self
.border_rect()
.to_physical(self.style.writing_mode(), containing_block)
.to_physical(self.style.writing_mode, containing_block)
.translate(&containing_block.top_left)
.into();
let common = CommonItemProperties {
@ -133,7 +132,7 @@ impl BoxFragment {
self.border_display_items(builder, &common, border_rect);
let content_rect = self
.content_rect
.to_physical(self.style.writing_mode(), containing_block)
.to_physical(self.style.writing_mode, containing_block)
.translate(&containing_block.top_left);
for child in &self.children {
child.build_display_list(builder, is_contentful, &content_rect)

View file

@ -446,7 +446,7 @@ fn layout_atomic<'box_tree>(
let containing_block_for_children = ContainingBlock {
inline_size,
block_size,
mode: atomic.style.writing_mode(),
mode: atomic.style.writing_mode,
};
assert_eq!(
ifc.containing_block.mode, containing_block_for_children.mode,

View file

@ -14,11 +14,12 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::adjust_static_positions;
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment};
use crate::replaced::ReplacedContent;
use crate::style_ext::{ComputedValuesExt, Position};
use crate::style_ext::ComputedValuesExt;
use crate::{relative_adjustement, ContainingBlock};
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
use style::computed_values::position::T as Position;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::values::generics::length::MaxSize;
@ -412,7 +413,7 @@ fn layout_in_flow_non_replaced_block_level<'a>(
let containing_block_for_children = ContainingBlock {
inline_size,
block_size,
mode: style.writing_mode(),
mode: style.writing_mode,
};
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
assert_eq!(
@ -520,7 +521,7 @@ fn layout_in_flow_replaced_block_level<'a>(
let border = style.border_width();
let computed_margin = style.margin().percentages_relative_to(cbis);
let pb = &padding + &border;
let mode = style.writing_mode();
let mode = style.writing_mode;
// FIXME(nox): We shouldn't pretend we always have a fully known intrinsic size.
let intrinsic_size = replaced.intrinsic_size.size_to_flow_relative(mode);
// FIXME(nox): This can divide by zero.

View file

@ -15,11 +15,12 @@ use crate::geom::flow_relative::Vec2;
use crate::positioned::AbsolutelyPositionedBox;
use crate::replaced::ReplacedContent;
use crate::sizing::ContentSizesRequest;
use crate::style_ext::{Direction, Display, DisplayGeneratingBox, DisplayInside, WritingMode};
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
use crate::{ContainingBlock, DefiniteContainingBlock};
use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator};
use script_layout_interface::wrapper_traits::LayoutNode;
use servo_arc::Arc;
use style::logical_geometry::WritingMode;
use style::values::computed::{Length, LengthOrAuto};
use style::Zero;
use style_traits::CSSPixel;
@ -107,7 +108,7 @@ impl BoxTreeRoot {
block_size: LengthOrAuto::LengthPercentage(initial_containing_block_size.block),
// FIXME: use the documents mode:
// https://drafts.csswg.org/css-writing-modes/#principal-flow
mode: (WritingMode::HorizontalTb, Direction::Ltr),
mode: WritingMode::empty(),
};
let dummy_tree_rank = 0;
let mut absolutely_positioned_fragments = vec![];

View file

@ -3,10 +3,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::geom::flow_relative::{Rect, Sides};
use crate::style_ext::{Direction, WritingMode};
use gfx::text::glyph::GlyphStore;
use servo_arc::Arc as ServoArc;
use std::sync::Arc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::Length;
use style::Zero;
@ -51,7 +51,7 @@ pub(crate) struct CollapsedMargin {
pub(crate) struct AnonymousFragment {
pub rect: Rect<Length>,
pub children: Vec<Fragment>,
pub mode: (WritingMode, Direction),
pub mode: WritingMode,
}
pub(crate) struct TextFragment {
@ -69,7 +69,7 @@ pub(crate) struct ImageFragment {
}
impl AnonymousFragment {
pub fn no_op(mode: (WritingMode, Direction)) -> Self {
pub fn no_op(mode: WritingMode) -> Self {
Self {
children: vec![],
rect: Rect::zero(),

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::style_ext::{Direction, WritingMode};
use std::fmt;
use std::ops::{Add, AddAssign, Sub};
use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, PhysicalCorner, WritingMode};
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::Zero;
use style_traits::CSSPixel;
@ -94,9 +94,9 @@ where
}
impl<T: Clone> physical::Vec2<T> {
pub fn size_to_flow_relative(&self, mode: (WritingMode, Direction)) -> flow_relative::Vec2<T> {
pub fn size_to_flow_relative(&self, mode: WritingMode) -> flow_relative::Vec2<T> {
// https://drafts.csswg.org/css-writing-modes/#logical-to-physical
let (i, b) = if let (WritingMode::HorizontalTb, _) = mode {
let (i, b) = if mode.is_horizontal() {
(&self.x, &self.y)
} else {
(&self.y, &self.x)
@ -160,9 +160,9 @@ impl flow_relative::Rect<Length> {
}
impl<T: Clone> flow_relative::Vec2<T> {
pub fn size_to_physical(&self, mode: (WritingMode, Direction)) -> physical::Vec2<T> {
pub fn size_to_physical(&self, mode: WritingMode) -> physical::Vec2<T> {
// https://drafts.csswg.org/css-writing-modes/#logical-to-physical
let (x, y) = if let (WritingMode::HorizontalTb, _) = mode {
let (x, y) = if mode.is_horizontal() {
(&self.inline, &self.block)
} else {
(&self.block, &self.inline)
@ -181,21 +181,20 @@ impl From<physical::Vec2<Length>> for Point<CSSPixel> {
}
impl<T: Clone> physical::Sides<T> {
pub fn to_flow_relative(&self, mode: (WritingMode, Direction)) -> flow_relative::Sides<T> {
use Direction::*;
use WritingMode::*;
pub fn to_flow_relative(&self, mode: WritingMode) -> flow_relative::Sides<T> {
// https://drafts.csswg.org/css-writing-modes/#logical-to-physical
let (bs, be) = match mode.0 {
HorizontalTb => (&self.top, &self.bottom),
VerticalRl => (&self.right, &self.left),
VerticalLr => (&self.left, &self.right),
let block_flow = mode.block_flow_direction();
let (bs, be) = match mode.block_flow_direction() {
BlockFlowDirection::TopToBottom => (&self.top, &self.bottom),
BlockFlowDirection::RightToLeft => (&self.right, &self.left),
BlockFlowDirection::LeftToRight => (&self.left, &self.right),
};
let (is, ie) = match mode {
(HorizontalTb, Ltr) => (&self.left, &self.right),
(HorizontalTb, Rtl) => (&self.right, &self.left),
(VerticalRl, Ltr) | (VerticalLr, Ltr) => (&self.top, &self.bottom),
(VerticalRl, Rtl) | (VerticalLr, Rtl) => (&self.bottom, &self.top),
use BlockFlowDirection::TopToBottom;
let (is, ie) = match (block_flow, mode.inline_base_direction()) {
(TopToBottom, InlineBaseDirection::LeftToRight) => (&self.left, &self.right),
(TopToBottom, InlineBaseDirection::RightToLeft) => (&self.right, &self.left),
(_, InlineBaseDirection::LeftToRight) => (&self.top, &self.bottom),
(_, InlineBaseDirection::RightToLeft) => (&self.bottom, &self.top),
};
flow_relative::Sides {
inline_start: is.clone(),
@ -298,7 +297,7 @@ impl<T> flow_relative::Rect<T> {
pub fn to_physical(
&self,
mode: (WritingMode, Direction),
mode: WritingMode,
// Will be needed for other writing modes
// FIXME: what if the containing block has a different mode?
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
@ -308,10 +307,9 @@ impl<T> flow_relative::Rect<T> {
T: Clone,
{
// Top-left corner
let (tl_x, tl_y) = if let (WritingMode::HorizontalTb, Direction::Ltr) = mode {
(&self.start_corner.inline, &self.start_corner.block)
} else {
unimplemented!()
let (tl_x, tl_y) = match mode.start_start_physical_corner() {
PhysicalCorner::TopLeft => (&self.start_corner.inline, &self.start_corner.block),
_ => unimplemented!(),
};
physical::Rect {
top_left: physical::Vec2 {

View file

@ -27,7 +27,9 @@ pub mod wrapper;
pub use flow::{BoxTreeRoot, FragmentTreeRoot};
use crate::geom::flow_relative::Vec2;
use crate::style_ext::{ComputedValuesExt, Direction, Position, WritingMode};
use crate::style_ext::ComputedValuesExt;
use style::computed_values::position::T as Position;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto};
use style::Zero;
@ -35,12 +37,12 @@ use style::Zero;
struct ContainingBlock {
inline_size: Length,
block_size: LengthOrAuto,
mode: (WritingMode, Direction),
mode: WritingMode,
}
struct DefiniteContainingBlock {
size: Vec2<Length>,
mode: (WritingMode, Direction),
mode: WritingMode,
}
/// https://drafts.csswg.org/css2/visuren.html#relative-positioning

View file

@ -8,10 +8,11 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::sizing::ContentSizesRequest;
use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode};
use crate::style_ext::{ComputedValuesExt, DisplayInside};
use crate::{ContainingBlock, DefiniteContainingBlock};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use servo_arc::Arc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::Zero;
@ -128,7 +129,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
fragments: &mut Vec<Fragment>,
content_rect_size: &Vec2<Length>,
padding: &Sides<Length>,
mode: (WritingMode, Direction),
mode: WritingMode,
) {
if absolute.is_empty() {
return;
@ -324,7 +325,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
let containing_block_for_children = ContainingBlock {
inline_size,
block_size,
mode: style.writing_mode(),
mode: style.writing_mode,
};
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
assert_eq!(
@ -369,7 +370,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
&mut independent_layout.fragments,
&content_rect.size,
&padding,
style.writing_mode(),
style.writing_mode,
);
Fragment::Box(BoxFragment {

View file

@ -9,10 +9,6 @@ use style::values::computed::{NonNegativeLengthPercentage, Size};
use style::values::generics::length::MaxSize;
use style::values::specified::box_ as stylo;
pub use style::computed_values::direction::T as Direction;
pub use style::computed_values::position::T as Position;
pub use style::computed_values::writing_mode::T as WritingMode;
#[derive(Clone, Copy, Eq, PartialEq)]
pub(crate) enum Display {
None,
@ -44,8 +40,6 @@ pub(crate) enum DisplayInside {
}
pub(crate) trait ComputedValuesExt {
fn writing_mode(&self) -> (WritingMode, Direction);
fn writing_mode_is_horizontal(&self) -> bool;
fn inline_size_is_auto(&self) -> bool;
fn inline_box_offsets_are_both_non_auto(&self) -> bool;
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
@ -58,44 +52,24 @@ pub(crate) trait ComputedValuesExt {
}
impl ComputedValuesExt for ComputedValues {
fn writing_mode(&self) -> (WritingMode, Direction) {
let inherited_box = self.get_inherited_box();
let writing_mode = inherited_box.writing_mode;
let direction = inherited_box.direction;
(writing_mode, direction)
}
fn writing_mode_is_horizontal(&self) -> bool {
match self.get_inherited_box().writing_mode {
WritingMode::HorizontalTb => true,
WritingMode::VerticalLr | WritingMode::VerticalRl => false,
}
}
fn inline_size_is_auto(&self) -> bool {
let position = self.get_position();
let size = if self.writing_mode_is_horizontal() {
let size = if self.writing_mode.is_horizontal() {
position.width
} else {
position.height
};
matches!(size, Size::Auto)
size == Size::Auto
}
fn inline_box_offsets_are_both_non_auto(&self) -> bool {
let position = self.get_position();
let offsets = if self.writing_mode_is_horizontal() {
let (a, b) = if self.writing_mode.is_horizontal() {
(position.left, position.right)
} else {
(position.top, position.bottom)
};
matches!(
offsets,
(
LengthPercentageOrAuto::LengthPercentage(_),
LengthPercentageOrAuto::LengthPercentage(_),
)
)
a != LengthPercentageOrAuto::Auto && b != LengthPercentageOrAuto::Auto
}
#[inline]
@ -107,7 +81,7 @@ impl ComputedValuesExt for ComputedValues {
bottom: position.bottom,
right: position.right,
}
.to_flow_relative(self.writing_mode())
.to_flow_relative(self.writing_mode)
}
#[inline]
@ -117,7 +91,7 @@ impl ComputedValuesExt for ComputedValues {
x: size_to_length(position.width),
y: size_to_length(position.height),
}
.size_to_flow_relative(self.writing_mode())
.size_to_flow_relative(self.writing_mode)
}
#[inline]
@ -127,7 +101,7 @@ impl ComputedValuesExt for ComputedValues {
x: size_to_length(position.min_width),
y: size_to_length(position.min_height),
}
.size_to_flow_relative(self.writing_mode())
.size_to_flow_relative(self.writing_mode)
}
#[inline]
@ -141,7 +115,7 @@ impl ComputedValuesExt for ComputedValues {
x: unwrap(position.max_width),
y: unwrap(position.max_height),
}
.size_to_flow_relative(self.writing_mode())
.size_to_flow_relative(self.writing_mode)
}
#[inline]
@ -153,7 +127,7 @@ impl ComputedValuesExt for ComputedValues {
bottom: padding.padding_bottom.0,
right: padding.padding_right.0,
}
.to_flow_relative(self.writing_mode())
.to_flow_relative(self.writing_mode)
}
fn border_width(&self) -> flow_relative::Sides<Length> {
@ -164,7 +138,7 @@ impl ComputedValuesExt for ComputedValues {
bottom: border.border_bottom_width.0,
right: border.border_right_width.0,
}
.to_flow_relative(self.writing_mode())
.to_flow_relative(self.writing_mode)
}
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto> {
@ -175,7 +149,7 @@ impl ComputedValuesExt for ComputedValues {
bottom: margin.margin_bottom,
right: margin.margin_right,
}
.to_flow_relative(self.writing_mode())
.to_flow_relative(self.writing_mode)
}
}

View file

@ -173,6 +173,11 @@ impl WritingMode {
self.intersects(WritingMode::VERTICAL)
}
#[inline]
pub fn is_horizontal(&self) -> bool {
!self.is_vertical()
}
/// Assuming .is_vertical(), does the block direction go left to right?
#[inline]
pub fn is_vertical_lr(&self) -> bool {