Handle all white-space values when intrinsically sizing an IFC (#33343)

There were various cases like `text-wrap-mode: nowrap` and
`white-space-collapse: break-spaces` that weren't handled well.

Fixes #33335

flexbox_flex-formatting-interop.html fails now because we don't support
`table-layout: fixed`.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-09-12 01:50:45 +02:00 committed by GitHub
parent 777fb81260
commit d9be9d6bd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 351 additions and 45 deletions

View file

@ -291,15 +291,17 @@ bitflags! {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ShapingFlags: u8 {
/// Set if the text is entirely whitespace.
const IS_WHITESPACE_SHAPING_FLAG = 0x01;
const IS_WHITESPACE_SHAPING_FLAG = 1 << 0;
/// Set if the text ends with whitespace.
const ENDS_WITH_WHITESPACE_SHAPING_FLAG = 1 << 1;
/// Set if we are to ignore ligatures.
const IGNORE_LIGATURES_SHAPING_FLAG = 0x02;
const IGNORE_LIGATURES_SHAPING_FLAG = 1 << 2;
/// Set if we are to disable kerning.
const DISABLE_KERNING_SHAPING_FLAG = 0x04;
const DISABLE_KERNING_SHAPING_FLAG = 1 << 3;
/// Text direction is right-to-left.
const RTL_FLAG = 0x08;
const RTL_FLAG = 1 << 4;
/// Set if word-break is set to keep-all.
const KEEP_ALL_FLAG = 0x10;
const KEEP_ALL_FLAG = 1 << 5;
}
}
@ -344,6 +346,9 @@ impl Font {
options
.flags
.contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG),
options
.flags
.contains(ShapingFlags::ENDS_WITH_WHITESPACE_SHAPING_FLAG),
is_single_preserved_newline,
options.flags.contains(ShapingFlags::RTL_FLAG),
);
@ -946,10 +951,10 @@ mod test {
assert!(font.can_do_fast_shaping(text, &shaping_options));
let mut expected_glyphs = GlyphStore::new(text.len(), false, false, false);
let mut expected_glyphs = GlyphStore::new(text.len(), false, false, false, false);
font.shape_text_harfbuzz(text, &shaping_options, &mut expected_glyphs);
let mut glyphs = GlyphStore::new(text.len(), false, false, false);
let mut glyphs = GlyphStore::new(text.len(), false, false, false, false);
font.shape_text_fast(text, &shaping_options, &mut glyphs);
assert_eq!(glyphs.len(), expected_glyphs.len());

View file

@ -446,6 +446,11 @@ pub struct GlyphStore {
/// Whether or not this glyph store contains only glyphs for whitespace.
is_whitespace: bool,
/// Whether or not this glyph store ends with whitespace glyphs.
/// Typically whitespace glyphs are placed in a separate store,
/// but that may not be the case with `white-space: break-spaces`.
ends_with_whitespace: bool,
/// Whether or not this glyph store contains only a single glyph for a single
/// preserved newline.
is_single_preserved_newline: bool,
@ -460,6 +465,7 @@ impl<'a> GlyphStore {
pub fn new(
length: usize,
is_whitespace: bool,
ends_with_whitespace: bool,
is_single_preserved_newline: bool,
is_rtl: bool,
) -> GlyphStore {
@ -472,6 +478,7 @@ impl<'a> GlyphStore {
total_word_separators: 0,
has_detailed_glyphs: false,
is_whitespace,
ends_with_whitespace,
is_single_preserved_newline,
is_rtl,
}
@ -492,6 +499,11 @@ impl<'a> GlyphStore {
self.is_whitespace
}
#[inline]
pub fn ends_with_whitespace(&self) -> bool {
self.ends_with_whitespace
}
#[inline]
pub fn total_word_separators(&self) -> usize {
self.total_word_separators