aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow/inline.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2023-12-21 15:45:34 +0100
committerGitHub <noreply@github.com>2023-12-21 14:45:34 +0000
commit74798c4b7bf173fc99b96e219c6c2cab136d5c4c (patch)
tree7d3ec58e3b05e37fad3a4e2d4c6b9d7004832bd2 /components/layout_2020/flow/inline.rs
parentd007d265bd5449d6c8e5abd18f946b79ca9f31f7 (diff)
downloadservo-74798c4b7bf173fc99b96e219c6c2cab136d5c4c.tar.gz
servo-74798c4b7bf173fc99b96e219c6c2cab136d5c4c.zip
layout: Add support for `text-align-last` (#30905)
This change adds support for `text-align-last` as well as ensuring that it also applies to lines before forced line breaks. Two tests start to fail because they rely on right-to-left text to pass: - /css/css-text/text-align/text-align-last-010.html.ini - /css/css-text/text-align/text-align-last-011.html.ini
Diffstat (limited to 'components/layout_2020/flow/inline.rs')
-rw-r--r--components/layout_2020/flow/inline.rs51
1 files changed, 32 insertions, 19 deletions
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs
index ca5360469ac..f67e95400f4 100644
--- a/components/layout_2020/flow/inline.rs
+++ b/components/layout_2020/flow/inline.rs
@@ -20,7 +20,7 @@ use style::properties::ComputedValues;
use style::values::computed::Length;
use style::values::generics::text::LineHeight;
use style::values::specified::text::{TextAlignKeyword, TextDecorationLine};
-use style::values::specified::TextJustify;
+use style::values::specified::{TextAlignLast, TextJustify};
use style::Zero;
use webrender_api::FontInstanceKey;
use xi_unicode::{linebreak_property, LineBreakLeafIter};
@@ -537,20 +537,19 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
// Finally we finish the line itself and convert all of the LineItems into
// fragments.
- self.finish_current_line_and_reset(true /* last_line */);
+ self.finish_current_line_and_reset(true /* last_line_or_forced_line_break */);
}
/// Finish layout of all inline boxes for the current line. This will gather all
/// [`LineItem`]s and turn them into [`Fragment`]s, then reset the
/// [`InlineFormattingContextState`] preparing it for laying out a new line.
- fn finish_current_line_and_reset(&mut self, last_line: bool) {
+ fn finish_current_line_and_reset(&mut self, last_line_or_forced_line_break: bool) {
let whitespace_trimmed = self.current_line.trim_trailing_whitespace();
- let (inline_start_position, mut justification_adjustment) = self
- .calculate_current_line_inline_start_and_justification_adjustment(whitespace_trimmed);
-
- if last_line {
- justification_adjustment = Length::zero();
- }
+ let (inline_start_position, justification_adjustment) = self
+ .calculate_current_line_inline_start_and_justification_adjustment(
+ whitespace_trimmed,
+ last_line_or_forced_line_break,
+ );
let block_start_position = self
.current_line
@@ -642,18 +641,32 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
fn calculate_current_line_inline_start_and_justification_adjustment(
&self,
whitespace_trimmed: Length,
+ last_line_or_forced_line_break: bool,
) -> (Length, Length) {
enum TextAlign {
Start,
Center,
End,
}
- let line_left_is_inline_start = self
- .containing_block
- .style
- .writing_mode
- .line_left_is_inline_start();
- let text_align_keyword = self.containing_block.style.clone_text_align();
+ let style = self.containing_block.style;
+ let line_left_is_inline_start = style.writing_mode.line_left_is_inline_start();
+ let mut text_align_keyword = style.clone_text_align();
+
+ if last_line_or_forced_line_break {
+ text_align_keyword = match style.clone_text_align_last() {
+ TextAlignLast::Auto if text_align_keyword == TextAlignKeyword::Justify => {
+ TextAlignKeyword::Start
+ },
+ TextAlignLast::Auto => text_align_keyword,
+ TextAlignLast::Start => TextAlignKeyword::Start,
+ TextAlignLast::End => TextAlignKeyword::End,
+ TextAlignLast::Left => TextAlignKeyword::Left,
+ TextAlignLast::Right => TextAlignKeyword::Right,
+ TextAlignLast::Center => TextAlignKeyword::Center,
+ TextAlignLast::Justify => TextAlignKeyword::Justify,
+ };
+ }
+
let text_align = match text_align_keyword {
TextAlignKeyword::Start => TextAlign::Start,
TextAlignKeyword::Center => TextAlign::Center,
@@ -936,7 +949,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
}
self.commit_current_segment_to_line();
- self.process_line_break();
+ self.process_line_break(true /* forced_line_break */);
self.linebreak_before_new_content = false;
}
@@ -1023,13 +1036,13 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
self.propagate_current_nesting_level_white_space_style();
}
- fn process_line_break(&mut self) {
+ fn process_line_break(&mut self, forced_line_break: bool) {
self.current_line_segment
.prepare_for_placement_on_empty_line(
&self.current_line,
self.inline_box_state_stack.len(),
);
- self.finish_current_line_and_reset(false /* last_line */);
+ self.finish_current_line_and_reset(forced_line_break);
}
/// Process a soft wrap opportunity. This will either commit the current unbreakble
@@ -1052,7 +1065,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
};
if self.new_potential_line_size_causes_line_break(&potential_line_size) {
- self.process_line_break();
+ self.process_line_break(false /* forced_line_break */);
}
self.commit_current_segment_to_line();
}