aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe <fegolac@gmail.com>2016-09-27 10:02:33 +0200
committerFelipe Lacerda <fegolac@gmail.com>2016-09-27 11:25:21 +0200
commite0a48fe596a64bcf62671be2c34b867a937737ea (patch)
tree7e6d43588896ddd45884e3d0236b6c94f7ef3dd4
parentd5669ead290ed8657ea1ae05166d4a4e01f2e383 (diff)
downloadservo-e0a48fe596a64bcf62671be2c34b867a937737ea.tar.gz
servo-e0a48fe596a64bcf62671be2c34b867a937737ea.zip
Use word-break to decide how glyph runs should be created
-rw-r--r--components/gfx/font.rs2
-rw-r--r--components/gfx/text/text_run.rs74
-rw-r--r--components/layout/fragment.rs2
-rw-r--r--components/layout/text.rs9
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,