From 38cb95f42797d3c3cacfee93804c2da5d9c42202 Mon Sep 17 00:00:00 2001 From: apricotbucket28 <71973804+apricotbucket28@users.noreply.github.com> Date: Sat, 15 Jun 2024 19:23:00 -0300 Subject: [PATCH] linux: Update cosmic_text (#13095) Bumps cosmic_text, removes some stale `todo`s and stores a ShapeBuffer to prevent reallocations Improvements: - Performance should be a lot better (haven't actually tested it) - Fixed display of `\t` in the terminal ![image](https://github.com/zed-industries/zed/assets/71973804/ca994912-851d-48ef-8dc7-b244c9eb484d) ![image](https://github.com/zed-industries/zed/assets/71973804/42fa9acf-ec10-4247-a5e3-2d4fe664ded6) Release Notes: - N/A --- Cargo.lock | 53 ++++++++++++------- crates/gpui/Cargo.toml | 2 +- .../src/platform/cosmic_text/text_system.rs | 31 +++++++---- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97b4dcebb4..8da51b2dad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2726,14 +2726,13 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c578f2b9abb4d5f3fbb12aba4008084d435dc6a8425c195cfe0b3594bfea0c25" +source = "git+https://github.com/pop-os/cosmic-text?rev=542b20c#542b20ca4376a3b5de5fa629db1a4ace44e18e0c" dependencies = [ "bitflags 2.4.2", "fontdb", - "libm", "log", "rangemap", + "rayon", "rustc-hash", "rustybuzz", "self_cell", @@ -4102,9 +4101,12 @@ dependencies = [ [[package]] name = "font-types" -version = "0.4.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd7f3ea17572640b606b35df42cfb6ecdf003704b062580e59918692190b73d" +checksum = "34fd7136aca682873d859ef34494ab1a7d3f57ecd485ed40eb6437ee8c85aa29" +dependencies = [ + "bytemuck", +] [[package]] name = "fontconfig-parser" @@ -4117,9 +4119,9 @@ dependencies = [ [[package]] name = "fontdb" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770" dependencies = [ "fontconfig-parser", "log", @@ -8214,10 +8216,11 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.15.3" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1362980db95801b70031dd592dc052a44b1810ca9da8fbcf7b25983f3174ed0" +checksum = "e8b8af39d1f23869711ad4cea5e7835a20daa987f80232f7f2a2374d648ca64d" dependencies = [ + "bytemuck", "font-types", ] @@ -8822,9 +8825,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rustybuzz" -version = "0.12.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ae5692c5beaad6a9e22830deeed7874eae8a4e3ba4076fb48e12c56856222c" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" dependencies = [ "bitflags 2.4.2", "bytemuck", @@ -9485,6 +9488,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "skrifa" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab45fb68b53576a43d4fc0e9ec8ea64e29a4d2cc7f44506964cb75f288222e9" +dependencies = [ + "bytemuck", + "read-fonts", +] + [[package]] name = "slab" version = "0.4.9" @@ -10193,11 +10206,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.1.12" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06ff4664af8923625604261c645f5c4cc610cc83c84bec74b50d76237089de7" +checksum = "4d7773d67fe3373048cf840bfcc54ec3207cfc1e95c526b287ef2eb5eff9faf6" dependencies = [ - "read-fonts", + "skrifa", "yazi", "zeno", ] @@ -11289,9 +11302,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "ttf-parser" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "tungstenite" @@ -11399,15 +11412,15 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-bidi-mirroring" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" [[package]] name = "unicode-ccc" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" [[package]] name = "unicode-ident" diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index ebaace06c0..5561ba94bc 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -103,7 +103,7 @@ blade-graphics.workspace = true blade-macros.workspace = true blade-util.workspace = true bytemuck = "1" -cosmic-text = "0.11.2" +cosmic-text = { git = "https://github.com/pop-os/cosmic-text", rev = "542b20c" } copypasta = "0.10.1" [target.'cfg(target_os = "linux")'.dependencies] diff --git a/crates/gpui/src/platform/cosmic_text/text_system.rs b/crates/gpui/src/platform/cosmic_text/text_system.rs index 039c6dd3d5..1931d93d8b 100644 --- a/crates/gpui/src/platform/cosmic_text/text_system.rs +++ b/crates/gpui/src/platform/cosmic_text/text_system.rs @@ -6,7 +6,8 @@ use crate::{ use anyhow::{anyhow, Context, Ok, Result}; use collections::HashMap; use cosmic_text::{ - Attrs, AttrsList, BufferLine, CacheKey, Family, Font as CosmicTextFont, FontSystem, SwashCache, + Attrs, AttrsList, CacheKey, Family, Font as CosmicTextFont, FontSystem, ShapeBuffer, ShapeLine, + SwashCache, }; use itertools::Itertools; @@ -23,6 +24,7 @@ pub(crate) struct CosmicTextSystem(RwLock); struct CosmicTextSystemState { swash_cache: SwashCache, font_system: FontSystem, + scratch: ShapeBuffer, /// Contains all already loaded fonts, including all faces. Indexed by `FontId`. loaded_fonts_store: Vec>, /// Caches the `FontId`s associated with a specific family to avoid iterating the font database @@ -42,6 +44,7 @@ impl CosmicTextSystem { Self(RwLock::new(CosmicTextSystemState { font_system, swash_cache: SwashCache::new(), + scratch: ShapeBuffer::default(), loaded_fonts_store: Vec::new(), font_ids_by_family_cache: HashMap::default(), postscript_names: HashMap::default(), @@ -60,8 +63,6 @@ impl PlatformTextSystem for CosmicTextSystem { self.0.write().add_fonts(fonts) } - // todo(linux) ensure that this integrates with platform font loading - // do we need to do more than call load_system_fonts()? fn all_font_names(&self) -> Vec { self.0 .read() @@ -367,13 +368,11 @@ impl CosmicTextSystemState { } } - // todo(linux) This is all a quick first pass, maybe we should be using cosmic_text::Buffer #[profiling::function] fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout { let mut attrs_list = AttrsList::new(Attrs::new()); let mut offs = 0; for run in font_runs { - // todo(linux) We need to check we are doing utf properly let font = &self.loaded_fonts_store[run.font_id.0]; let font = self.font_system.db().face(font.id()).unwrap(); attrs_list.add_span( @@ -386,17 +385,27 @@ impl CosmicTextSystemState { ); offs += run.len; } - let mut line = BufferLine::new(text, attrs_list, cosmic_text::Shaping::Advanced); - - let layout = line.layout( + let mut line = ShapeLine::new_in_buffer( + &mut self.scratch, &mut self.font_system, + text, + &attrs_list, + cosmic_text::Shaping::Advanced, + 4, + ); + + let mut layout = Vec::with_capacity(1); + line.layout_to_buffer( + &mut self.scratch, font_size.0, - f32::MAX, // We do our own wrapping + None, // We do our own wrapping cosmic_text::Wrap::None, None, + &mut layout, + None, ); - let mut runs = Vec::new(); + let mut runs = Vec::new(); let layout = layout.first().unwrap(); for glyph in &layout.glyphs { let font_id = glyph.font_id; @@ -412,7 +421,7 @@ impl CosmicTextSystemState { // todo(linux) this is definitely wrong, each glyph in glyphs from cosmic-text is a cluster with one glyph, ShapedRun takes a run of glyphs with the same font and direction glyphs.push(ShapedGlyph { id: GlyphId(glyph.glyph_id as u32), - position: point((glyph.x).into(), glyph.y.into()), + position: point(glyph.x.into(), glyph.y.into()), index: glyph.start, is_emoji, });