From 14c524df4f38a8b8262b3ba458c100966377d072 Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Tue, 16 May 2017 11:38:42 -0500 Subject: [PATCH] [gfx] [layout] [style] Upgrade unicode-bidi to 0.3 --- Cargo.lock | 28 +++++++++++++++++++++------- components/gfx/Cargo.toml | 1 + components/gfx/lib.rs | 1 + components/gfx/text/text_run.rs | 7 ++++--- components/layout/Cargo.toml | 2 +- components/layout/inline.rs | 27 +++++++++++++++------------ components/layout/text.rs | 16 ++++++++-------- components/style/Cargo.toml | 1 + components/style/lib.rs | 1 + components/style/logical_geometry.rs | 11 ++++++++--- 10 files changed, 61 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 071481b7e487..3b172d243b3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1021,6 +1021,7 @@ dependencies = [ "style_traits 0.0.1", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.39.0 (git+https://github.com/servo/webrender)", "xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1231,11 +1232,11 @@ dependencies = [ [[package]] name = "idna" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1407,7 +1408,7 @@ dependencies = [ "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", - "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.39.0 (git+https://github.com/servo/webrender)", ] @@ -2517,6 +2518,14 @@ dependencies = [ "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_test" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo" version = "0.0.1" @@ -2871,6 +2880,7 @@ dependencies = [ "style_traits 0.0.1", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3145,10 +3155,13 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_test 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3194,7 +3207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3549,7 +3562,7 @@ dependencies = [ "checksum hyper 0.10.9 (registry+https://github.com/rust-lang/crates.io-index)" = "94da93321c171e26481afeebe8288757b0501901b7c5492648163d8ec4942ec5" "checksum hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "85a372eb692590b3fe014c196c30f9f52d4c42f58cd49dd94caeee1593c9cc37" "checksum hyper_serde 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a43d985c58afed6b59991932e1d9b5f2629472849f0062c0078d82fdc0b788bb" -"checksum idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac85ec3f80c8e4e99d9325521337e14ec7555c458a14e377d189659a427f375" +"checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37" "checksum image 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d95816db758249fe16f23a4e23f1a3a817fe11892dbfd1c5836f625324702158" "checksum immeta 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0b9260463a221bfe3f02100c56e2d14c050d5ffe7e44a43d0a1b2b1f2b523502" "checksum inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" @@ -3645,6 +3658,7 @@ dependencies = [ "checksum serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc888bd283bd2420b16ad0d860e35ad8acb21941180a83a189bb2046f9d00400" "checksum serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "978fd866f4d4872084a81ccc35e275158351d3b9fe620074e7d7504b816b74ba" "checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" +"checksum serde_test 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef7adefe71d2d715b39b93aeeee729e61dae3ac109a6e40e35e6e38317075a4" "checksum servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21069a884c33fe6ee596975e1f3849ed88c4ec857fbaf11d33672d8ebe051217" "checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262" "checksum servo-fontconfig-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6be80777ee6edecbbbf8774c76e19dddfe336256c57a4ded06d6ad3df7be358e" @@ -3690,7 +3704,7 @@ dependencies = [ "checksum truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec30350633d6dac9dc1a625786b6cbe9150664be941aac2c35ad7199eab877" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" -"checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032" +"checksum unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c44d4e7ce691e2538b886bf33669fd6da1653a12d741b9390f351955c0949c03" "checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" "checksum unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5430ae21ef212551680d0021fc7dbd936e8b268c5ea8fdae8814e0b2496d80f" "checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3" diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index 843f7f833c78..dfbe6ab582bd 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -37,6 +37,7 @@ smallvec = "0.3" style = {path = "../style"} style_traits = {path = "../style_traits"} time = "0.1.12" +unicode-bidi = {version = "0.3", features = ["with_serde"]} unicode-script = {version = "0.1", features = ["harfbuzz"]} webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]} xi-unicode = "0.1.0" diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 09c1c16951d8..b7e23df0d830 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -69,6 +69,7 @@ extern crate smallvec; extern crate style; extern crate style_traits; extern crate time; +extern crate unicode_bidi; extern crate unicode_script; extern crate webrender_traits; extern crate xi_unicode; diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index 0f487a4b70ea..b65700221f73 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -13,6 +13,7 @@ use std::slice::Iter; use std::sync::Arc; use style::str::char_is_whitespace; use text::glyph::{ByteIndex, GlyphStore}; +use unicode_bidi as bidi; use webrender_traits; use xi_unicode::LineBreakIterator; @@ -32,7 +33,7 @@ pub struct TextRun { pub font_key: webrender_traits::FontKey, /// The glyph runs that make up this text run. pub glyphs: Arc>, - pub bidi_level: u8, + pub bidi_level: bidi::Level, pub extra_word_spacing: Au, } @@ -179,7 +180,7 @@ impl<'a> Iterator for CharacterSliceIterator<'a> { } impl<'a> TextRun { - pub fn new(font: &mut Font, text: String, options: &ShapingOptions, bidi_level: u8) -> TextRun { + pub fn new(font: &mut Font, text: String, options: &ShapingOptions, bidi_level: bidi::Level) -> TextRun { let glyphs = TextRun::break_and_shape(font, &text, options); TextRun { text: Arc::new(text), @@ -340,7 +341,7 @@ impl<'a> TextRun { pub fn natural_word_slices_in_visual_order(&'a self, range: &Range) -> NaturalWordSliceIterator<'a> { // Iterate in reverse order if bidi level is RTL. - let reverse = self.bidi_level % 2 == 1; + let reverse = self.bidi_level.is_rtl(); let index = if reverse { match self.index_of_first_glyph_run_containing(range.end() - ByteIndex(1)) { diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index 483314d2e90a..aaced4168886 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -43,6 +43,6 @@ servo_url = {path = "../url"} smallvec = "0.3" style = {path = "../style"} style_traits = {path = "../style_traits"} -unicode-bidi = "0.2" +unicode-bidi = {version = "0.3", features = ["with_serde"]} unicode-script = {version = "0.1", features = ["harfbuzz"]} webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]} diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 3ffdd275c717..f3dc8fc5395b 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -36,7 +36,7 @@ use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::properties::{longhands, ServoComputedValues}; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION, RESOLVE_GENERATED_CONTENT}; use text; -use unicode_bidi; +use unicode_bidi as bidi; /// `Line`s are represented as offsets into the child list, rather than /// as an object that "owns" fragments. Choosing a different set of line @@ -95,7 +95,7 @@ pub struct Line { /// The bidirectional embedding level runs for this line, in visual order. /// /// Can be set to `None` if the line is 100% left-to-right. - pub visual_runs: Option, u8)>>, + pub visual_runs: Option, bidi::Level)>>, /// The bounds are the exact position and extents of the line with respect /// to the parent box. @@ -293,22 +293,25 @@ impl LineBreaker { // (because we split fragments on level run boundaries during flow // construction), so we can build a level array with just one entry per // fragment. - let levels: Vec = self.new_fragments.iter().map(|fragment| match fragment.specific { - SpecificFragmentInfo::ScannedText(ref info) => info.run.bidi_level, - _ => para_level - }).collect(); + let levels: Vec = self.new_fragments.iter().map( + |fragment| match fragment.specific { + SpecificFragmentInfo::ScannedText(ref info) => info.run.bidi_level, + _ => para_level + } + ).collect(); let mut lines = mem::replace(&mut self.lines, Vec::new()); // If everything is LTR, don't bother with reordering. - let has_rtl = levels.iter().cloned().any(unicode_bidi::is_rtl); - - if has_rtl { + if bidi::level::has_rtl(&levels) { // Compute and store the visual ordering of the fragments within the // line. for line in &mut lines { let range = line.range.begin().to_usize()..line.range.end().to_usize(); - let runs = unicode_bidi::visual_runs(range, &levels); + // FIXME: Update to use BidiInfo::visual_runs, as this algorithm needs access to + // the original text and original BidiClass of its characters. + #[allow(deprecated)] + let runs = bidi::deprecated::visual_runs(range, &levels); line.visual_runs = Some(runs.iter().map(|run| { let start = FragmentIndex(run.start as isize); let len = FragmentIndex(run.len() as isize); @@ -957,11 +960,11 @@ impl InlineFlow { let (range, level) = match line.visual_runs { Some(ref runs) if is_ltr => runs[run_idx], Some(ref runs) => runs[run_count - run_idx - 1], // reverse order for RTL runs - None => (line.range, 0) + None => (line.range, bidi::Level::ltr()) }; // If the bidi embedding direction is opposite the layout direction, lay out this // run in reverse order. - let reverse = unicode_bidi::is_ltr(level) != is_ltr; + let reverse = level.is_ltr() != is_ltr; let fragment_indices = if reverse { (range.end().get() - 1..range.begin().get() - 1).step_by(-1) } else { diff --git a/components/layout/text.rs b/components/layout/text.rs index 43b2fd086e72..8b0d3c707ead 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -28,7 +28,7 @@ use style::computed_values::{word_break, white_space}; use style::logical_geometry::{LogicalSize, WritingMode}; use style::properties::ServoComputedValues; use style::properties::style_structs; -use unicode_bidi::{is_rtl, process_text}; +use unicode_bidi as bidi; use unicode_script::{Script, get_script}; /// Returns the concatenated text of a list of unscanned text fragments. @@ -74,10 +74,10 @@ impl TextRunScanner { // Calculate bidi embedding levels, so we can split bidirectional fragments for reordering. let text = text(&fragments); let para_level = fragments.front().unwrap().style.writing_mode.to_bidi_level(); - let bidi_info = process_text(&text, Some(para_level)); + let bidi_info = bidi::BidiInfo::new(&text, Some(para_level)); // Optimization: If all the text is LTR, don't bother splitting on bidi levels. - let bidi_levels = if bidi_info.levels.iter().cloned().any(is_rtl) { + let bidi_levels = if bidi_info.has_rtl() { Some(&bidi_info.levels[..]) } else { None @@ -126,7 +126,7 @@ impl TextRunScanner { font_context: &mut FontContext, out_fragments: &mut Vec, paragraph_bytes_processed: &mut usize, - bidi_levels: Option<&[u8]>, + bidi_levels: Option<&[bidi::Level]>, mut last_whitespace: bool) -> bool { debug!("TextRunScanner: flushing {} fragments in range", self.clump.len()); @@ -211,7 +211,7 @@ impl TextRunScanner { let bidi_level = match bidi_levels { Some(levels) => levels[*paragraph_bytes_processed], - None => 0 + None => bidi::Level::ltr(), }; // Break the run if the new character has a different explicit script than the @@ -310,7 +310,7 @@ impl TextRunScanner { run_info_list.into_iter().map(|run_info| { let mut options = options; options.script = run_info.script; - if is_rtl(run_info.bidi_level) { + if run_info.bidi_level.is_rtl() { options.flags.insert(RTL_FLAG); } let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut(); @@ -522,7 +522,7 @@ struct RunInfo { /// The index of the applicable font in the font group. font_index: usize, /// The bidirection embedding level of this text run. - bidi_level: u8, + bidi_level: bidi::Level, /// The Unicode script property of this text run. script: Script, } @@ -533,7 +533,7 @@ impl RunInfo { text: String::new(), insertion_point: None, font_index: 0, - bidi_level: 0, + bidi_level: bidi::Level::ltr(), script: Script::Common, } } diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index e6018f2653bb..2bfa11dae9c8 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -67,6 +67,7 @@ style_derive = {path = "../style_derive"} style_traits = {path = "../style_traits"} servo_url = {path = "../url", optional = true} time = "0.1" +unicode-bidi = {version = "0.3", features = ["with_serde"]} unicode-segmentation = "1.0" [target.'cfg(windows)'.dependencies] diff --git a/components/style/lib.rs b/components/style/lib.rs index c294885aed6b..fd796bc2f2d2 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -83,6 +83,7 @@ extern crate style_derive; #[macro_use] extern crate style_traits; extern crate time; +extern crate unicode_bidi; #[allow(unused_extern_crates)] extern crate unicode_segmentation; diff --git a/components/style/logical_geometry.rs b/components/style/logical_geometry.rs index e9748128f551..bb7eb053b8e5 100644 --- a/components/style/logical_geometry.rs +++ b/components/style/logical_geometry.rs @@ -10,6 +10,7 @@ use euclid::side_offsets::SideOffsets2D; use std::cmp::{max, min}; use std::fmt::{self, Debug, Error, Formatter}; use std::ops::{Add, Sub}; +use unicode_bidi as bidi; pub enum BlockFlowDirection { TopToBottom, @@ -131,9 +132,13 @@ impl WritingMode { #[inline] /// The default bidirectional embedding level for this writing mode. /// - /// Returns 0 if the mode is LTR, or 1 otherwise. - pub fn to_bidi_level(&self) -> u8 { - !self.is_bidi_ltr() as u8 + /// Returns bidi level 0 if the mode is LTR, or 1 otherwise. + pub fn to_bidi_level(&self) -> bidi::Level { + if self.is_bidi_ltr() { + bidi::Level::ltr() + } else { + bidi::Level::rtl() + } } }