diff options
author | Felipe <fegolac@gmail.com> | 2016-09-27 10:02:33 +0200 |
---|---|---|
committer | Felipe Lacerda <fegolac@gmail.com> | 2016-09-27 11:25:21 +0200 |
commit | e0a48fe596a64bcf62671be2c34b867a937737ea (patch) | |
tree | 7e6d43588896ddd45884e3d0236b6c94f7ef3dd4 | |
parent | d5669ead290ed8657ea1ae05166d4a4e01f2e383 (diff) | |
download | servo-e0a48fe596a64bcf62671be2c34b867a937737ea.tar.gz servo-e0a48fe596a64bcf62671be2c34b867a937737ea.zip |
Use word-break to decide how glyph runs should be created
-rw-r--r-- | components/gfx/font.rs | 2 | ||||
-rw-r--r-- | components/gfx/text/text_run.rs | 74 | ||||
-rw-r--r-- | components/layout/fragment.rs | 2 | ||||
-rw-r--r-- | 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<ByteIndex>, -} - -// 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<TextRunSlice<'a>> { - 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<ByteIndex>) - -> 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<ByteIndex>) 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, |