From d5669ead290ed8657ea1ae05166d4a4e01f2e383 Mon Sep 17 00:00:00 2001 From: Felipe Date: Sat, 24 Sep 2016 17:41:11 +0200 Subject: [PATCH 1/4] Implement `word-break: keep_all` --- components/gfx/text/text_run.rs | 77 +++++++++++++++++-- components/layout/fragment.rs | 17 +++- .../longhand/inherited_text.mako.rs | 3 +- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index a431a124239..9455c862aeb 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -135,6 +135,53 @@ impl<'a> Iterator for NaturalWordSliceIterator<'a> { } } +pub struct SoftWrapSliceIterator<'a> { + text: &'a str, + glyph_run: Option<&'a GlyphRun>, + glyph_run_iter: Iter<'a, GlyphRun>, + range: Range, +} + +// This is like NaturalWordSliceIterator, except that soft-wrap opportunities +// are allowed. That is, word boundaries are defined solely by UAX#29, +// regardless of whether the sequence being broken into different slices is +// a sequence of alphanumeric characters. This shouldn't make a difference in +// the case of Latin text, but it does in ideographic characters, as well as +// scripts such as Thai. +impl<'a> Iterator for SoftWrapSliceIterator<'a> { + type Item = TextRunSlice<'a>; + + #[inline(always)] + fn next(&mut self) -> Option> { + let glyph_run = match self.glyph_run { + None => return None, + Some(glyph_run) => glyph_run, + }; + + let text_start = self.range.begin(); + let text = &self.text[text_start.to_usize()..glyph_run.range.end().to_usize()]; + let slice_text = match LineBreakIterator::new(text).next() { + Some((idx, _)) => &text[0..idx], + None => unreachable!() + }; + + let slice_len = ByteIndex(slice_text.len() as isize); + self.range.adjust_by(slice_len, -slice_len); + if self.range.is_empty() { + self.glyph_run = None + } else if self.range.intersect(&glyph_run.range).is_empty() { + self.glyph_run = self.glyph_run_iter.next(); + } + + let index_within_glyph_run = text_start - glyph_run.range.begin(); + Some(TextRunSlice { + glyphs: &*glyph_run.glyph_store, + offset: glyph_run.range.begin(), + range: Range::new(index_within_glyph_run, slice_len), + }) + } +} + pub struct CharacterSliceIterator<'a> { text: &'a str, glyph_run: Option<&'a GlyphRun>, @@ -206,11 +253,13 @@ impl<'a> TextRun { // Split off any trailing whitespace into a separate glyph run. let mut whitespace = slice.end..slice.end; if let Some((i, _)) = word.char_indices().rev() - .take_while(|&(_, c)| char_is_whitespace(c)).last() { - whitespace.start = slice.start + i; - slice.end = whitespace.start; - } - + .take_while(|&(_, c)| char_is_whitespace(c)).last() { + whitespace.start = slice.start + i; + slice.end = whitespace.start; + } else if idx != text.len() { + // If there's no whitespace, try increasing the slice. + continue; + } if slice.len() > 0 { glyphs.push(GlyphRun { glyph_store: font.shape_text(&text[slice.clone()], options), @@ -343,6 +392,24 @@ impl<'a> TextRun { } } + /// Returns an iterator that will iterate over all slices of glyphs that represent natural + /// words in the given range, where soft wrap opportunities are taken into account. + pub fn soft_wrap_slices_in_range(&'a self, range: &Range) + -> SoftWrapSliceIterator<'a> { + let index = match self.index_of_first_glyph_run_containing(range.begin()) { + None => self.glyphs.len(), + Some(index) => index, + }; + let mut glyph_run_iter = self.glyphs[index..].iter(); + let first_glyph_run = glyph_run_iter.next(); + SoftWrapSliceIterator { + text: &self.text, + glyph_run: first_glyph_run, + glyph_run_iter: glyph_run_iter, + range: *range, + } + } + /// Returns an iterator that will iterate over all slices of glyphs that represent individual /// characters in the given range. pub fn character_slices_in_range(&'a self, range: &Range) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 5245e821711..93a19f14af1 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -1638,11 +1638,11 @@ impl Fragment { match self.style().get_inheritedtext().word_break { word_break::T::normal => { - // Break at normal word boundaries. - let natural_word_breaking_strategy = - text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range); + // Break at normal word boundaries, allowing for soft wrap opportunities. + let soft_wrap_breaking_strategy = + text_fragment_info.run.soft_wrap_slices_in_range(&text_fragment_info.range); self.calculate_split_position_using_breaking_strategy( - natural_word_breaking_strategy, + soft_wrap_breaking_strategy, max_inline_size, flags) } @@ -1655,6 +1655,15 @@ impl Fragment { character_breaking_strategy, max_inline_size, flags) + }, + word_break::T::keep_all => { + // Break at word boundaries, and forbid soft wrap opportunities. + let natural_word_breaking_strategy = + text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range); + self.calculate_split_position_using_breaking_strategy( + natural_word_breaking_strategy, + max_inline_size, + flags) } } } diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index b2f856059bb..5251f4a8a74 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -385,8 +385,7 @@ ${helpers.single_keyword("overflow-wrap", // TODO(pcwalton): Support `word-break: keep-all` once we have better CJK support. ${helpers.single_keyword("word-break", - "normal break-all", - extra_gecko_values="keep-all", + "normal break-all keep-all", gecko_constant_prefix="NS_STYLE_WORDBREAK", animatable=False)} From e0a48fe596a64bcf62671be2c34b867a937737ea Mon Sep 17 00:00:00 2001 From: Felipe Date: Tue, 27 Sep 2016 10:02:33 +0200 Subject: [PATCH 2/4] Use word-break to decide how glyph runs should be created --- components/gfx/font.rs | 2 + components/gfx/text/text_run.rs | 74 +++------------------------------ components/layout/fragment.rs | 2 +- components/layout/text.rs | 9 +++- 4 files changed, 15 insertions(+), 72 deletions(-) diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 7e1cf5236d5..c955c042eff 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -148,6 +148,8 @@ bitflags! { const DISABLE_KERNING_SHAPING_FLAG = 0x04, #[doc = "Text direction is right-to-left."] const RTL_FLAG = 0x08, + #[doc = "Set if word-break is set to keep-all."] + const KEEP_ALL_FLAG = 0x10, } } diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index 9455c862aeb..7ab8f4a870f 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; -use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, RunMetrics}; -use font::ShapingOptions; +use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, KEEP_ALL_FLAG}; +use font::{RunMetrics, ShapingOptions}; use platform::font_template::FontTemplateData; use range::Range; use std::cell::Cell; @@ -135,53 +135,6 @@ impl<'a> Iterator for NaturalWordSliceIterator<'a> { } } -pub struct SoftWrapSliceIterator<'a> { - text: &'a str, - glyph_run: Option<&'a GlyphRun>, - glyph_run_iter: Iter<'a, GlyphRun>, - range: Range, -} - -// This is like NaturalWordSliceIterator, except that soft-wrap opportunities -// are allowed. That is, word boundaries are defined solely by UAX#29, -// regardless of whether the sequence being broken into different slices is -// a sequence of alphanumeric characters. This shouldn't make a difference in -// the case of Latin text, but it does in ideographic characters, as well as -// scripts such as Thai. -impl<'a> Iterator for SoftWrapSliceIterator<'a> { - type Item = TextRunSlice<'a>; - - #[inline(always)] - fn next(&mut self) -> Option> { - let glyph_run = match self.glyph_run { - None => return None, - Some(glyph_run) => glyph_run, - }; - - let text_start = self.range.begin(); - let text = &self.text[text_start.to_usize()..glyph_run.range.end().to_usize()]; - let slice_text = match LineBreakIterator::new(text).next() { - Some((idx, _)) => &text[0..idx], - None => unreachable!() - }; - - let slice_len = ByteIndex(slice_text.len() as isize); - self.range.adjust_by(slice_len, -slice_len); - if self.range.is_empty() { - self.glyph_run = None - } else if self.range.intersect(&glyph_run.range).is_empty() { - self.glyph_run = self.glyph_run_iter.next(); - } - - let index_within_glyph_run = text_start - glyph_run.range.begin(); - Some(TextRunSlice { - glyphs: &*glyph_run.glyph_store, - offset: glyph_run.range.begin(), - range: Range::new(index_within_glyph_run, slice_len), - }) - } -} - pub struct CharacterSliceIterator<'a> { text: &'a str, glyph_run: Option<&'a GlyphRun>, @@ -256,8 +209,9 @@ impl<'a> TextRun { .take_while(|&(_, c)| char_is_whitespace(c)).last() { whitespace.start = slice.start + i; slice.end = whitespace.start; - } else if idx != text.len() { - // If there's no whitespace, try increasing the slice. + } else if idx != text.len() && options.flags.contains(KEEP_ALL_FLAG) { + // If there's no whitespace and word-break is set to + // keep-all, try increasing the slice. continue; } if slice.len() > 0 { @@ -392,24 +346,6 @@ impl<'a> TextRun { } } - /// Returns an iterator that will iterate over all slices of glyphs that represent natural - /// words in the given range, where soft wrap opportunities are taken into account. - pub fn soft_wrap_slices_in_range(&'a self, range: &Range) - -> SoftWrapSliceIterator<'a> { - let index = match self.index_of_first_glyph_run_containing(range.begin()) { - None => self.glyphs.len(), - Some(index) => index, - }; - let mut glyph_run_iter = self.glyphs[index..].iter(); - let first_glyph_run = glyph_run_iter.next(); - SoftWrapSliceIterator { - text: &self.text, - glyph_run: first_glyph_run, - glyph_run_iter: glyph_run_iter, - range: *range, - } - } - /// Returns an iterator that will iterate over all slices of glyphs that represent individual /// characters in the given range. pub fn character_slices_in_range(&'a self, range: &Range) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 93a19f14af1..2dc8db47f60 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -1640,7 +1640,7 @@ impl Fragment { word_break::T::normal => { // Break at normal word boundaries, allowing for soft wrap opportunities. let soft_wrap_breaking_strategy = - text_fragment_info.run.soft_wrap_slices_in_range(&text_fragment_info.range); + text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range); self.calculate_split_position_using_breaking_strategy( soft_wrap_breaking_strategy, max_inline_size, diff --git a/components/layout/text.rs b/components/layout/text.rs index 18d2cbf3c08..237f339ea71 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -10,7 +10,7 @@ use app_units::Au; use fragment::{Fragment, REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES, ScannedTextFlags}; use fragment::{SELECTED, ScannedTextFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG}; -use gfx::font::{RTL_FLAG, RunMetrics, ShapingFlags, ShapingOptions}; +use gfx::font::{KEEP_ALL_FLAG, RTL_FLAG, RunMetrics, ShapingFlags, ShapingOptions}; use gfx::font_context::FontContext; use gfx::text::glyph::ByteIndex; use gfx::text::text_run::TextRun; @@ -24,7 +24,7 @@ use std::collections::LinkedList; use std::mem; use std::sync::Arc; use style::computed_values::{line_height, text_orientation, text_rendering, text_transform}; -use style::computed_values::white_space; +use style::computed_values::{word_break, white_space}; use style::logical_geometry::{LogicalSize, WritingMode}; use style::properties::ServoComputedValues; use style::properties::style_structs; @@ -151,6 +151,7 @@ impl TextRunScanner { let letter_spacing; let word_spacing; let text_rendering; + let word_break; { let in_fragment = self.clump.front().unwrap(); let font_style = in_fragment.style().get_font_arc(); @@ -169,6 +170,7 @@ impl TextRunScanner { .map(|lop| lop.to_hash_key()) .unwrap_or((Au(0), NotNaN::new(0.0).unwrap())); text_rendering = inherited_text_style.text_rendering; + word_break = inherited_text_style.word_break; } // First, transform/compress text of all the nodes. @@ -289,6 +291,9 @@ impl TextRunScanner { flags.insert(IGNORE_LIGATURES_SHAPING_FLAG); flags.insert(DISABLE_KERNING_SHAPING_FLAG) } + if word_break == word_break::T::keep_all { + flags.insert(KEEP_ALL_FLAG); + } let options = ShapingOptions { letter_spacing: letter_spacing, word_spacing: word_spacing, From 44c26e014aceec8ab45d419619b5f321779618f2 Mon Sep 17 00:00:00 2001 From: Felipe Date: Tue, 27 Sep 2016 10:58:58 +0200 Subject: [PATCH 3/4] add tests --- .../htmloptionscollection.html.ini | 1 + tests/wpt/mozilla/meta/MANIFEST.json | 96 +++++++++++++++++++ .../meta/css/word-break-keep-all-008.htm.ini | 3 + .../tests/css/word-break-keep-all-005.htm | 24 +++++ .../tests/css/word-break-keep-all-006.htm | 23 +++++ .../tests/css/word-break-keep-all-007.htm | 23 +++++ .../tests/css/word-break-keep-all-008.htm | 23 +++++ .../tests/css/word-break-keep-all-ref-005.htm | 17 ++++ .../tests/css/word-break-keep-all-ref-006.htm | 17 ++++ .../tests/css/word-break-keep-all-ref-007.htm | 17 ++++ .../tests/css/word-break-keep-all-ref-008.htm | 17 ++++ 11 files changed, 261 insertions(+) create mode 100644 tests/wpt/mozilla/meta/css/word-break-keep-all-008.htm.ini create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-005.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-006.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-007.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-008.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-ref-005.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-ref-006.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-ref-007.htm create mode 100644 tests/wpt/mozilla/tests/css/word-break-keep-all-ref-008.htm diff --git a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html.ini b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html.ini index eb045799edd..4ea1f777183 100644 --- a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html.ini +++ b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html.ini @@ -17,3 +17,4 @@ [HTMLOptionsCollection.add method insert HTMLOptionElement Option element] expected: FAIL + diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index fc7ee02cb96..61103659ba0 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5946,6 +5946,54 @@ "url": "/_mozilla/css/width_nonreplaced_block_simple_a.html" } ], + "css/word-break-keep-all-005.htm": [ + { + "path": "css/word-break-keep-all-005.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-005.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-005.htm" + } + ], + "css/word-break-keep-all-006.htm": [ + { + "path": "css/word-break-keep-all-006.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-006.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-006.htm" + } + ], + "css/word-break-keep-all-007.htm": [ + { + "path": "css/word-break-keep-all-007.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-007.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-007.htm" + } + ], + "css/word-break-keep-all-008.htm": [ + { + "path": "css/word-break-keep-all-008.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-008.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-008.htm" + } + ], "css/word-spacing.html": [ { "path": "css/word-spacing.html", @@ -19584,6 +19632,54 @@ "url": "/_mozilla/css/width_nonreplaced_block_simple_a.html" } ], + "css/word-break-keep-all-005.htm": [ + { + "path": "css/word-break-keep-all-005.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-005.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-005.htm" + } + ], + "css/word-break-keep-all-006.htm": [ + { + "path": "css/word-break-keep-all-006.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-006.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-006.htm" + } + ], + "css/word-break-keep-all-007.htm": [ + { + "path": "css/word-break-keep-all-007.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-007.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-007.htm" + } + ], + "css/word-break-keep-all-008.htm": [ + { + "path": "css/word-break-keep-all-008.htm", + "references": [ + [ + "/_mozilla/css/word-break-keep-all-ref-008.htm", + "==" + ] + ], + "url": "/_mozilla/css/word-break-keep-all-008.htm" + } + ], "css/word-spacing.html": [ { "path": "css/word-spacing.html", diff --git a/tests/wpt/mozilla/meta/css/word-break-keep-all-008.htm.ini b/tests/wpt/mozilla/meta/css/word-break-keep-all-008.htm.ini new file mode 100644 index 00000000000..3c59220918d --- /dev/null +++ b/tests/wpt/mozilla/meta/css/word-break-keep-all-008.htm.ini @@ -0,0 +1,3 @@ +[word-break-keep-all-008.htm] + type: reftest + expected: FAIL diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-005.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-005.htm new file mode 100644 index 00000000000..5bf0022a007 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-005.htm @@ -0,0 +1,24 @@ + + + +word-break: keep-all, latin + + + + + + + +
Test passes if the two orange boxes are the same.
+
Latin latin latin latin
+
Latin latin latin
latin
+ + + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-006.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-006.htm new file mode 100644 index 00000000000..17eb109a001 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-006.htm @@ -0,0 +1,23 @@ + + + +word-break: keep-all, japanese + + + + + + +
Test passes if the two orange boxes are the same.
+
日本語 日本語 日本語
+
日本語 日本語
日本語
+ + + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-007.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-007.htm new file mode 100644 index 00000000000..ac1385ff8c9 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-007.htm @@ -0,0 +1,23 @@ + + + +word-break: keep-all, korean + + + + + + +
Test passes if the two orange boxes are the same.
+
한글이 한글이 한글이
+
한글이 한글이
한글이
+ + + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-008.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-008.htm new file mode 100644 index 00000000000..2b935f80f11 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-008.htm @@ -0,0 +1,23 @@ + + + +word-break: keep-all, thai + + + + + + +
Test passes if the two orange boxes are the same.
+
แและ แและแและ
+
แและ แและ
แและ
+ + + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-005.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-005.htm new file mode 100644 index 00000000000..156b202ba8d --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-005.htm @@ -0,0 +1,17 @@ + + + +word-break: keep-all, latin + + + + +
Test passes if the two orange boxes are the same.
+
Latin latin latin
latin
+
Latin latin latin
latin
+ + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-006.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-006.htm new file mode 100644 index 00000000000..118e9630e38 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-006.htm @@ -0,0 +1,17 @@ + + + +word-break: keep-all, japanese + + + + +
Test passes if the two orange boxes are the same.
+
日本語 日本語
日本語
+
日本語 日本語
日本語
+ + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-007.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-007.htm new file mode 100644 index 00000000000..11161b43696 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-007.htm @@ -0,0 +1,17 @@ + + + +word-break: keep-all, korean + + + + +
Test passes if the two orange boxes are the same.
+
한글이 한글이
한글이
+
한글이 한글이
한글이
+ + diff --git a/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-008.htm b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-008.htm new file mode 100644 index 00000000000..bf2e5f58edb --- /dev/null +++ b/tests/wpt/mozilla/tests/css/word-break-keep-all-ref-008.htm @@ -0,0 +1,17 @@ + + + +word-break: keep-all, thai + + + + +
Test passes if the two orange boxes are the same.
+
แและ แและ
แและ
+
แและ แและ
แและ
+ + From fb66abba74df33d05eaf7a2a5e8ad8f2c88aff41 Mon Sep 17 00:00:00 2001 From: Felipe Lacerda Date: Tue, 27 Sep 2016 20:07:32 +0200 Subject: [PATCH 4/4] combine normal and keep-all into a single strategy --- components/layout/fragment.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 2dc8db47f60..f7f46d2fdcc 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -1637,12 +1637,12 @@ impl Fragment { } match self.style().get_inheritedtext().word_break { - word_break::T::normal => { - // Break at normal word boundaries, allowing for soft wrap opportunities. - let soft_wrap_breaking_strategy = + word_break::T::normal | word_break::T::keep_all => { + // Break at normal word boundaries. keep-all forbids soft wrap opportunities. + let natural_word_breaking_strategy = text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range); self.calculate_split_position_using_breaking_strategy( - soft_wrap_breaking_strategy, + natural_word_breaking_strategy, max_inline_size, flags) } @@ -1655,15 +1655,6 @@ impl Fragment { character_breaking_strategy, max_inline_size, flags) - }, - word_break::T::keep_all => { - // Break at word boundaries, and forbid soft wrap opportunities. - let natural_word_breaking_strategy = - text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range); - self.calculate_split_position_using_breaking_strategy( - natural_word_breaking_strategy, - max_inline_size, - flags) } } }