mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Allow pre-wrap whitespace to hang at the end of the line (#31681)
* Allow pre-wrap whitespace to hang at the end of the line * Use bitflags
This commit is contained in:
parent
ac24cd6139
commit
39f660f520
24 changed files with 54 additions and 64 deletions
|
@ -72,6 +72,7 @@ use std::cell::OnceCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use bitflags::bitflags;
|
||||||
use gfx::font::FontMetrics;
|
use gfx::font::FontMetrics;
|
||||||
use gfx::text::glyph::GlyphStore;
|
use gfx::text::glyph::GlyphStore;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -1215,7 +1216,11 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
.current_inline_container_state()
|
.current_inline_container_state()
|
||||||
.strut_block_sizes
|
.strut_block_sizes
|
||||||
.clone();
|
.clone();
|
||||||
self.update_unbreakable_segment_for_new_content(&strut_size, Length::zero(), false);
|
self.update_unbreakable_segment_for_new_content(
|
||||||
|
&strut_size,
|
||||||
|
Length::zero(),
|
||||||
|
SegmentContentFlags::empty(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.had_inflow_content = true;
|
self.had_inflow_content = true;
|
||||||
|
@ -1243,12 +1248,11 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
font_index: usize,
|
font_index: usize,
|
||||||
) {
|
) {
|
||||||
let inline_advance = Length::from(glyph_store.total_advance());
|
let inline_advance = Length::from(glyph_store.total_advance());
|
||||||
let preserve_spaces = text_run
|
let flags = if glyph_store.is_whitespace() {
|
||||||
.parent_style
|
SegmentContentFlags::from(text_run.parent_style.get_inherited_text().white_space)
|
||||||
.get_inherited_text()
|
} else {
|
||||||
.white_space
|
SegmentContentFlags::empty()
|
||||||
.preserve_spaces();
|
};
|
||||||
let is_collapsible_whitespace = glyph_store.is_whitespace() && !preserve_spaces;
|
|
||||||
|
|
||||||
// If the metrics of this font don't match the default font, we are likely using a fallback
|
// If the metrics of this font don't match the default font, we are likely using a fallback
|
||||||
// font and need to adjust the line size to account for a potentially different font.
|
// font and need to adjust the line size to account for a potentially different font.
|
||||||
|
@ -1270,7 +1274,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
container_state.get_block_size_contribution(vertical_align, &font_metrics);
|
container_state.get_block_size_contribution(vertical_align, &font_metrics);
|
||||||
block_size.adjust_for_baseline_offset(container_state.baseline_offset);
|
block_size.adjust_for_baseline_offset(container_state.baseline_offset);
|
||||||
block_size
|
block_size
|
||||||
} else if quirks_mode && !is_collapsible_whitespace {
|
} else if quirks_mode && !flags.is_collapsible_whitespace() {
|
||||||
// Normally, the strut is incorporated into the nested block size. In quirks mode though
|
// Normally, the strut is incorporated into the nested block size. In quirks mode though
|
||||||
// if we find any text that isn't collapsed whitespace, we need to incorporate the strut.
|
// if we find any text that isn't collapsed whitespace, we need to incorporate the strut.
|
||||||
// TODO(mrobinson): This isn't quite right for situations where collapsible white space
|
// TODO(mrobinson): This isn't quite right for situations where collapsible white space
|
||||||
|
@ -1281,11 +1285,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
} else {
|
} else {
|
||||||
LineBlockSizes::zero()
|
LineBlockSizes::zero()
|
||||||
};
|
};
|
||||||
self.update_unbreakable_segment_for_new_content(
|
self.update_unbreakable_segment_for_new_content(&strut_size, inline_advance, flags);
|
||||||
&strut_size,
|
|
||||||
inline_advance,
|
|
||||||
is_collapsible_whitespace,
|
|
||||||
);
|
|
||||||
|
|
||||||
match self.current_line_segment.line_items.last_mut() {
|
match self.current_line_segment.line_items.last_mut() {
|
||||||
Some(LineItem::TextRun(line_item)) if ifc_font_info.key == line_item.font_key => {
|
Some(LineItem::TextRun(line_item)) if ifc_font_info.key == line_item.font_key => {
|
||||||
|
@ -1309,14 +1309,16 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
&mut self,
|
&mut self,
|
||||||
block_sizes_of_content: &LineBlockSizes,
|
block_sizes_of_content: &LineBlockSizes,
|
||||||
inline_size: Length,
|
inline_size: Length,
|
||||||
is_collapsible_whitespace: bool,
|
flags: SegmentContentFlags,
|
||||||
) {
|
) {
|
||||||
if !is_collapsible_whitespace {
|
if flags.is_collapsible_whitespace() || flags.is_wrappable_whitespace() {
|
||||||
|
self.current_line_segment.trailing_whitespace_size = inline_size;
|
||||||
|
} else {
|
||||||
self.current_line_segment.trailing_whitespace_size = Length::zero();
|
self.current_line_segment.trailing_whitespace_size = Length::zero();
|
||||||
|
}
|
||||||
|
if !flags.is_collapsible_whitespace() {
|
||||||
self.current_line_segment.has_content = true;
|
self.current_line_segment.has_content = true;
|
||||||
self.had_inflow_content = true;
|
self.had_inflow_content = true;
|
||||||
} else {
|
|
||||||
self.current_line_segment.trailing_whitespace_size = inline_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may or may not include the size of the strut depending on the quirks mode setting.
|
// This may or may not include the size of the strut depending on the quirks mode setting.
|
||||||
|
@ -1442,6 +1444,36 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct SegmentContentFlags: u8 {
|
||||||
|
const COLLAPSIBLE_WHITESPACE = 0b00000001;
|
||||||
|
const WRAPPABLE_WHITESPACE = 0b00000010;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SegmentContentFlags {
|
||||||
|
fn is_collapsible_whitespace(&self) -> bool {
|
||||||
|
self.contains(Self::COLLAPSIBLE_WHITESPACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_wrappable_whitespace(&self) -> bool {
|
||||||
|
self.contains(Self::WRAPPABLE_WHITESPACE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WhiteSpace> for SegmentContentFlags {
|
||||||
|
fn from(white_space: WhiteSpace) -> Self {
|
||||||
|
let mut flags = Self::empty();
|
||||||
|
if !white_space.preserve_spaces() {
|
||||||
|
flags.insert(Self::COLLAPSIBLE_WHITESPACE);
|
||||||
|
}
|
||||||
|
if white_space.allow_wrap() {
|
||||||
|
flags.insert(Self::WRAPPABLE_WHITESPACE);
|
||||||
|
}
|
||||||
|
flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum InlineFormattingContextIterItem<'a> {
|
enum InlineFormattingContextIterItem<'a> {
|
||||||
Item(&'a mut InlineLevelBox),
|
Item(&'a mut InlineLevelBox),
|
||||||
EndInlineBox,
|
EndInlineBox,
|
||||||
|
@ -2088,7 +2120,11 @@ impl IndependentFormattingContext {
|
||||||
|
|
||||||
let (block_sizes, baseline_offset_in_parent) =
|
let (block_sizes, baseline_offset_in_parent) =
|
||||||
self.get_block_sizes_and_baseline_offset(ifc, size.block, baseline_offset);
|
self.get_block_sizes_and_baseline_offset(ifc, size.block, baseline_offset);
|
||||||
ifc.update_unbreakable_segment_for_new_content(&block_sizes, size.inline, false);
|
ifc.update_unbreakable_segment_for_new_content(
|
||||||
|
&block_sizes,
|
||||||
|
size.inline,
|
||||||
|
SegmentContentFlags::empty(),
|
||||||
|
);
|
||||||
ifc.push_line_item_to_unbreakable_segment(LineItem::Atomic(AtomicLineItem {
|
ifc.push_line_item_to_unbreakable_segment(LineItem::Atomic(AtomicLineItem {
|
||||||
fragment,
|
fragment,
|
||||||
size,
|
size,
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[hyphens-auto-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[control-chars-00D.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[eol-spaces-bidi-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-006.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-007.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-015.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-align-left-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-align-start-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-leading-spaces-012.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[pre-wrap-tab-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-006.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-pre-wrap-007.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[white-space-pre-wrap.htm]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue