diff options
-rw-r--r-- | components/gfx/Cargo.toml | 1 | ||||
-rw-r--r-- | components/gfx/font.rs | 6 | ||||
-rw-r--r-- | components/gfx/lib.rs | 1 | ||||
-rw-r--r-- | components/gfx/platform/freetype/font.rs | 21 | ||||
-rw-r--r-- | components/gfx/platform/macos/font.rs | 135 | ||||
-rw-r--r-- | components/gfx/text/shaping/harfbuzz.rs | 52 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 9 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 9 | ||||
-rw-r--r-- | ports/gonk/Cargo.lock | 9 |
9 files changed, 218 insertions, 25 deletions
diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index cf758332296..cb5f72bde95 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -47,6 +47,7 @@ webrender_traits = {git = "https://github.com/servo/webrender_traits"} xi-unicode = "0.0.1" [target.'cfg(target_os = "macos")'.dependencies] +byteorder = "0.5" core-foundation = "0.2" core-graphics = "0.3" core-text = "1.1" diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 2a1c9ee82e4..7fdf217d18e 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -30,6 +30,8 @@ macro_rules! ot_tag { ); } +pub const GPOS: u32 = ot_tag!('G', 'P', 'O', 'S'); +pub const GSUB: u32 = ot_tag!('G', 'S', 'U', 'B'); pub const KERN: u32 = ot_tag!('k', 'e', 'r', 'n'); static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; @@ -51,7 +53,9 @@ pub trait FontHandleMethods: Sized { fn glyph_index(&self, codepoint: char) -> Option<GlyphId>; fn glyph_h_advance(&self, GlyphId) -> Option<FractionalPixel>; - fn glyph_h_kerning(&self, GlyphId, GlyphId) -> FractionalPixel; + fn glyph_h_kerning(&self, glyph0: GlyphId, glyph1: GlyphId) -> FractionalPixel; + /// Can this font do basic horizontal LTR shaping without Harfbuzz? + fn can_do_fast_shaping(&self) -> bool; fn metrics(&self) -> FontMetrics; fn table_for_tag(&self, FontTableTag) -> Option<FontTable>; } diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 736b77a8cb0..450928a6197 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -28,6 +28,7 @@ extern crate azure; extern crate bitflags; // Mac OS-specific library dependencies +#[cfg(target_os = "macos")] extern crate byteorder; #[cfg(target_os = "macos")] extern crate core_foundation; #[cfg(target_os = "macos")] extern crate core_graphics; #[cfg(target_os = "macos")] extern crate core_text; diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 27c554730a2..caf04e53699 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -6,7 +6,7 @@ extern crate freetype; use app_units::Au; use font::{FontHandleMethods, FontMetrics, FontTableMethods}; -use font::{FontTableTag, FractionalPixel}; +use font::{FontTableTag, FractionalPixel, GPOS, GSUB, KERN}; use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; use freetype::freetype::{FT_Done_Face, FT_New_Memory_Face}; use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name}; @@ -35,6 +35,7 @@ fn fixed_to_float_ft(f: i32) -> f64 { fixed_to_float(6, f) } +#[derive(Debug)] pub struct FontTable { buffer: Vec<u8>, } @@ -52,6 +53,7 @@ pub struct FontHandle { font_data: Arc<FontTemplateData>, face: FT_Face, handle: FontContextHandle, + can_do_fast_shaping: bool, } impl Drop for FontHandle { @@ -74,11 +76,16 @@ impl FontHandleMethods for FontHandle { if ft_ctx.is_null() { return Err(()); } return create_face_from_buffer(ft_ctx, &template.bytes, pt_size).map(|face| { - let handle = FontHandle { + let mut handle = FontHandle { face: face, font_data: template.clone(), handle: fctx.clone(), + can_do_fast_shaping: false, }; + // TODO (#11310): Implement basic support for GPOS and GSUB. + handle.can_do_fast_shaping = handle.has_table(KERN) && + !handle.has_table(GPOS) && + !handle.has_table(GSUB); handle }); @@ -172,6 +179,10 @@ impl FontHandleMethods for FontHandle { fixed_to_float_ft(delta.x as i32) } + fn can_do_fast_shaping(&self) -> bool { + self.can_do_fast_shaping + } + fn glyph_h_advance(&self, glyph: GlyphId) -> Option<FractionalPixel> { assert!(!self.face.is_null()); unsafe { @@ -276,6 +287,12 @@ impl<'a> FontHandle { } } + fn has_table(&self, tag: FontTableTag) -> bool { + unsafe { + FT_Load_Sfnt_Table(self.face, tag as FT_ULong, 0, ptr::null_mut(), &mut 0).succeeded() + } + } + fn face_rec_mut(&'a self) -> &'a mut FT_FaceRec { unsafe { &mut (*self.face) diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index d9b0d60e9d4..4a12b50163a 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -9,6 +9,7 @@ extern crate core_graphics; extern crate core_text; use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use core_foundation::base::CFIndex; use core_foundation::data::CFData; use core_foundation::string::UniChar; @@ -17,16 +18,18 @@ use core_graphics::geometry::CGRect; use core_text::font::CTFont; use core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors}; use core_text::font_descriptor::{kCTFontDefaultOrientation}; -use font::FontTableTag; -use font::FractionalPixel; -use font::{FontHandleMethods, FontMetrics, FontTableMethods}; +use font::{FontHandleMethods, FontMetrics, FontTableTag, FontTableMethods, FractionalPixel}; +use font::{GPOS, GSUB, KERN}; use platform::font_template::FontTemplateData; use platform::macos::font_context::FontContextHandle; -use std::ptr; +use std::ops::Range; use std::sync::Arc; +use std::{fmt, ptr}; use style::computed_values::{font_stretch, font_weight}; use text::glyph::GlyphId; +const KERN_PAIR_LEN: usize = 6; + pub struct FontTable { data: CFData, } @@ -61,8 +64,107 @@ impl FontTableMethods for FontTable { pub struct FontHandle { font_data: Arc<FontTemplateData>, ctfont: CTFont, + h_kern_subtable: Option<CachedKernTable>, + can_do_fast_shaping: bool, +} + +impl FontHandle { + /// Cache all the data needed for basic horizontal kerning. This is used only as a fallback or + /// fast path (when the GPOS table is missing or unnecessary) so it needn't handle every case. + fn find_h_kern_subtable(&self) -> Option<CachedKernTable> { + let font_table = match self.table_for_tag(KERN) { + Some(table) => table, + None => return None + }; + + let mut result = CachedKernTable { + font_table: font_table, + pair_data_range: 0..0, + px_per_font_unit: 0.0, + }; + + // Look for a subtable with horizontal kerning in format 0. + // https://www.microsoft.com/typography/otspec/kern.htm + const KERN_COVERAGE_HORIZONTAL_FORMAT_0: u16 = 1; + const SUBTABLE_HEADER_LEN: usize = 6; + const FORMAT_0_HEADER_LEN: usize = 8; + { + let table = result.font_table.buffer(); + let version = BigEndian::read_u16(table); + if version != 0 { + return None; + } + let num_subtables = BigEndian::read_u16(&table[2..]); + let mut start = 4; + for _ in 0..num_subtables { + // TODO: Check the subtable version number? + let len = BigEndian::read_u16(&table[start + 2..]) as usize; + let cov = BigEndian::read_u16(&table[start + 4..]); + let end = start + len; + if cov == KERN_COVERAGE_HORIZONTAL_FORMAT_0 { + // Found a matching subtable. + if result.pair_data_range.len() > 0 { + debug!("Found multiple horizontal kern tables. Disable fast path."); + return None; + } + // Read the subtable header. + let subtable_start = start + SUBTABLE_HEADER_LEN; + let n_pairs = BigEndian::read_u16(&table[subtable_start..]) as usize; + let pair_data_start = subtable_start + FORMAT_0_HEADER_LEN; + + result.pair_data_range = pair_data_start..end; + let pt_per_font_unit = self.ctfont.pt_size() as f64 / + self.ctfont.units_per_em() as f64; + result.px_per_font_unit = pt_to_px(pt_per_font_unit); + + debug_assert_eq!(n_pairs * KERN_PAIR_LEN, result.pair_data_range.len()); + } + start = end; + } + } + if result.pair_data_range.len() > 0 { + Some(result) + } else { + None + } + } } +struct CachedKernTable { + font_table: FontTable, + pair_data_range: Range<usize>, + px_per_font_unit: f64, +} + +impl CachedKernTable { + /// Search for a glyph pair in the kern table and return the corresponding value. + fn binary_search(&self, first_glyph: GlyphId, second_glyph: GlyphId) -> Option<i16> { + let pairs = &self.font_table.buffer()[self.pair_data_range.clone()]; + + let query = first_glyph << 16 | second_glyph; + let (mut start, mut end) = (0, pairs.len() / KERN_PAIR_LEN); + while start < end { + let i = (start + end) / 2; + let key = BigEndian::read_u32(&pairs[i * KERN_PAIR_LEN..]); + if key > query { + end = i; + } else if key < query { + start = i + 1; + } else { + return Some(BigEndian::read_i16(&pairs[i * KERN_PAIR_LEN + 4..])); + } + } + None + } +} + +impl fmt::Debug for CachedKernTable { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "CachedKernTable") + } +} + + impl FontHandleMethods for FontHandle { fn new_from_template(_fctx: &FontContextHandle, template: Arc<FontTemplateData>, @@ -74,10 +176,18 @@ impl FontHandleMethods for FontHandle { }; match template.ctfont(size) { Some(ref ctfont) => { - Ok(FontHandle { + let mut handle = FontHandle { font_data: template.clone(), ctfont: ctfont.clone_with_font_size(size), - }) + h_kern_subtable: None, + can_do_fast_shaping: false, + }; + handle.h_kern_subtable = handle.find_h_kern_subtable(); + // TODO (#11310): Implement basic support for GPOS and GSUB. + handle.can_do_fast_shaping = handle.h_kern_subtable.is_some() && + handle.table_for_tag(GPOS).is_none() && + handle.table_for_tag(GSUB).is_none(); + Ok(handle) } None => { Err(()) @@ -155,12 +265,19 @@ impl FontHandleMethods for FontHandle { return Some(glyphs[0] as GlyphId); } - fn glyph_h_kerning(&self, _first_glyph: GlyphId, _second_glyph: GlyphId) - -> FractionalPixel { - // TODO: Implement on mac + fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) -> FractionalPixel { + if let Some(ref table) = self.h_kern_subtable { + if let Some(font_units) = table.binary_search(first_glyph, second_glyph) { + return font_units as f64 * table.px_per_font_unit; + } + } 0.0 } + fn can_do_fast_shaping(&self) -> bool { + self.can_do_fast_shaping + } + fn glyph_h_advance(&self, glyph: GlyphId) -> Option<FractionalPixel> { let glyphs = [glyph as CGGlyph]; let advance = self.ctfont.get_advances_for_glyphs(kCTFontDefaultOrientation, diff --git a/components/gfx/text/shaping/harfbuzz.rs b/components/gfx/text/shaping/harfbuzz.rs index a1457e4ffd0..79d36f9b6e0 100644 --- a/components/gfx/text/shaping/harfbuzz.rs +++ b/components/gfx/text/shaping/harfbuzz.rs @@ -4,7 +4,7 @@ use app_units::Au; use euclid::Point2D; -use font::{DISABLE_KERNING_SHAPING_FLAG, Font, FontTableMethods, FontTableTag}; +use font::{DISABLE_KERNING_SHAPING_FLAG, Font, FontHandleMethods, FontTableMethods, FontTableTag}; use font::{IGNORE_LIGATURES_SHAPING_FLAG, KERN, RTL_FLAG, ShapingOptions}; use harfbuzz::{HB_DIRECTION_LTR, HB_DIRECTION_RTL, HB_MEMORY_MODE_READONLY}; use harfbuzz::{hb_blob_create, hb_face_create_for_tables}; @@ -34,10 +34,12 @@ use harfbuzz::{hb_glyph_position_t}; use harfbuzz::{hb_position_t, hb_tag_t}; use libc::{c_char, c_int, c_uint, c_void}; use platform::font::FontTable; +use std::ascii::AsciiExt; use std::{char, cmp, ptr}; use text::glyph::{ByteIndex, GlyphData, GlyphId, GlyphStore}; use text::shaping::ShaperMethods; use text::util::{fixed_to_float, float_to_fixed, is_bidi_control}; +use unicode_script::Script; const NO_GLYPH: i32 = -1; const LIGA: u32 = ot_tag!('l', 'i', 'g', 'a'); @@ -199,7 +201,14 @@ impl ShaperMethods for Shaper { /// Calculate the layout metrics associated with the given text when painted in a specific /// font. fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) { + if self.can_use_fast_path(text, options) { + debug!("shape_text: Using ASCII fast path."); + self.shape_text_fast(text, options, glyphs); + return; + } unsafe { + debug!("shape_text: Using Harfbuzz."); + let hb_buffer: *mut hb_buffer_t = hb_buffer_create(); hb_buffer_set_direction(hb_buffer, if options.flags.contains(RTL_FLAG) { HB_DIRECTION_RTL @@ -241,6 +250,47 @@ impl ShaperMethods for Shaper { } impl Shaper { + fn can_use_fast_path(&self, text: &str, options: &ShapingOptions) -> bool { + let font = self.font_and_shaping_options.font; + + options.script == Script::Latin && + !options.flags.contains(RTL_FLAG) && + unsafe { (*font).handle.can_do_fast_shaping() } && + text.is_ascii() + } + + /// Fast path for ASCII text that only needs simple horizontal LTR kerning. + fn shape_text_fast(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) { + let font = unsafe { &mut *self.font_and_shaping_options.font }; + + let mut prev_glyph_id = None; + for (i, byte) in text.bytes().enumerate() { + let character = byte as char; + let glyph_id = match font.glyph_index(character) { + Some(id) => id, + None => continue, + }; + + let mut advance = Au::from_f64_px(font.glyph_h_advance(glyph_id)); + if character == ' ' { + advance += options.word_spacing; + } + if let Some(letter_spacing) = options.letter_spacing { + advance += letter_spacing; + } + let offset = prev_glyph_id.map(|prev| { + let h_kerning = Au::from_f64_px(font.glyph_h_kerning(prev, glyph_id)); + advance += h_kerning; + Point2D::new(h_kerning, Au(0)) + }); + + let glyph = GlyphData::new(glyph_id, advance, offset, true, true); + glyphs.add_glyph_for_byte_index(ByteIndex(i as isize), character, &glyph); + prev_glyph_id = Some(glyph_id); + } + glyphs.finalize_changes(); + } + fn save_glyph_results(&self, text: &str, options: &ShapingOptions, diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index a2eb6d56e03..b83014dd031 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -101,7 +101,7 @@ source = "git+https://github.com/servo/rust-azure#a7177c8df81554352bc51de2f5b77c dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "core-text" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -742,9 +742,10 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "azure 0.4.5 (git+https://github.com/servo/rust-azure)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", @@ -2498,7 +2499,7 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 25d66a72b1d..0a8cccf9175 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -78,7 +78,7 @@ source = "git+https://github.com/servo/rust-azure#a7177c8df81554352bc51de2f5b77c dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "core-text" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -663,9 +663,10 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "azure 0.4.5 (git+https://github.com/servo/rust-azure)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", @@ -2359,7 +2360,7 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 0b482116f00..081c0ac0ee0 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -80,7 +80,7 @@ source = "git+https://github.com/servo/rust-azure#a7177c8df81554352bc51de2f5b77c dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -367,7 +367,7 @@ dependencies = [ [[package]] name = "core-text" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -675,9 +675,10 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "azure 0.4.5 (git+https://github.com/servo/rust-azure)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", @@ -2319,7 +2320,7 @@ dependencies = [ "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-text 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", |