Auto merge of #13414 - flacerdk:master, r=mbrubeck

Implement `word-break: keep-all` (#9673)

<!-- Please describe your changes on the following line: -->
Implement the `keep-all` value for the `word-break` property, as specified in [CSS](https://drafts.csswg.org/css-text-3/#word-break-property).

The relevant CSSWG tests (in `tests/wpt/css-tests/css-text-3_dev/html/word-break-keep-all-*.htm`) do not currently pass. As far as I can tell, this is because the tests use some JavaScript code that is not working properly. (But then, it seems that most tests in this directory are failing at the moment. I'm not sure what can be done here for now.)

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #9673.

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13414)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-09-29 19:20:55 -05:00 committed by GitHub
commit c9442346d3
15 changed files with 282 additions and 13 deletions

View file

@ -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,
}
}

View file

@ -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;
@ -206,11 +206,14 @@ 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() && 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 {
glyphs.push(GlyphRun {
glyph_store: font.shape_text(&text[slice.clone()], options),

View file

@ -1637,8 +1637,8 @@ impl Fragment {
}
match self.style().get_inheritedtext().word_break {
word_break::T::normal => {
// Break at normal word boundaries.
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(

View file

@ -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,

View file

@ -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)}