linux: start the text system

Dzmitry Malyshau created

Change summary

crates/gpui/Cargo.toml                        |   1 
crates/gpui/src/platform/linux.rs             |   2 
crates/gpui/src/platform/linux/platform.rs    |  10 +
crates/gpui/src/platform/linux/text_system.rs | 103 +++++++++++++++++++++
4 files changed, 111 insertions(+), 5 deletions(-)

Detailed changes

crates/gpui/Cargo.toml 🔗

@@ -88,7 +88,6 @@ cocoa = "0.25"
 core-foundation = { version = "0.9.3", features = ["with-uuid"] }
 core-graphics = "0.22.3"
 core-text = "19.2"
-font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "d97147f" }
 foreign-types = "0.3"
 log.workspace = true
 media = { path = "../media" }

crates/gpui/src/platform/linux.rs 🔗

@@ -1,5 +1,7 @@
 mod dispatcher;
 mod platform;
+mod text_system;
 
 pub(crate) use dispatcher::*;
 pub(crate) use platform::*;
+pub(crate) use text_system::*;

crates/gpui/src/platform/linux/platform.rs 🔗

@@ -2,9 +2,9 @@
 
 use crate::{
     Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
-    ForegroundExecutor, Keymap, LinuxDispatcher, Menu, PathPromptOptions, Platform,
-    PlatformDisplay, PlatformInput, PlatformTextSystem, PlatformWindow, Result, SemanticVersion,
-    Task, WindowOptions,
+    ForegroundExecutor, Keymap, LinuxDispatcher, LinuxTextSystem, Menu, PathPromptOptions,
+    Platform, PlatformDisplay, PlatformInput, PlatformTextSystem, PlatformWindow, Result,
+    SemanticVersion, Task, WindowOptions,
 };
 
 use futures::channel::oneshot;
@@ -23,6 +23,7 @@ pub(crate) struct LinuxPlatform(Mutex<LinuxPlatformState>);
 pub(crate) struct LinuxPlatformState {
     background_executor: BackgroundExecutor,
     foreground_executor: ForegroundExecutor,
+    text_system: Arc<LinuxTextSystem>,
 }
 
 impl Default for LinuxPlatform {
@@ -37,6 +38,7 @@ impl LinuxPlatform {
         Self(Mutex::new(LinuxPlatformState {
             background_executor: BackgroundExecutor::new(dispatcher.clone()),
             foreground_executor: ForegroundExecutor::new(dispatcher),
+            text_system: Arc::new(LinuxTextSystem::new()),
         }))
     }
 }
@@ -51,7 +53,7 @@ impl Platform for LinuxPlatform {
     }
 
     fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
-        unimplemented!()
+        self.0.lock().text_system.clone()
     }
 
     fn run(&self, on_finish_launching: Box<dyn FnOnce()>) {

crates/gpui/src/platform/linux/text_system.rs 🔗

@@ -0,0 +1,103 @@
+use crate::{
+    Bounds, DevicePixels, Font, FontId, FontMetrics, FontRun, GlyphId, LineLayout, Pixels,
+    PlatformTextSystem, RenderGlyphParams, SharedString, Size,
+};
+use anyhow::Result;
+use collections::HashMap;
+use font_kit::{
+    font::Font as FontKitFont,
+    handle::Handle,
+    hinting::HintingOptions,
+    metrics::Metrics,
+    properties::{Style as FontkitStyle, Weight as FontkitWeight},
+    source::SystemSource,
+    sources::mem::MemSource,
+};
+use parking_lot::RwLock;
+use smallvec::SmallVec;
+use std::sync::Arc;
+
+pub(crate) struct LinuxTextSystem(RwLock<LinuxTextSystemState>);
+
+struct LinuxTextSystemState {
+    memory_source: MemSource,
+    system_source: SystemSource,
+    fonts: Vec<FontKitFont>,
+    font_selections: HashMap<Font, FontId>,
+    font_ids_by_postscript_name: HashMap<String, FontId>,
+    font_ids_by_family_name: HashMap<SharedString, SmallVec<[FontId; 4]>>,
+    postscript_names_by_font_id: HashMap<FontId, String>,
+}
+
+unsafe impl Send for LinuxTextSystemState {}
+unsafe impl Sync for LinuxTextSystemState {}
+
+impl LinuxTextSystem {
+    pub(crate) fn new() -> Self {
+        Self(RwLock::new(LinuxTextSystemState {
+            memory_source: MemSource::empty(),
+            system_source: SystemSource::new(),
+            fonts: Vec::new(),
+            font_selections: HashMap::default(),
+            font_ids_by_postscript_name: HashMap::default(),
+            font_ids_by_family_name: HashMap::default(),
+            postscript_names_by_font_id: HashMap::default(),
+        }))
+    }
+}
+
+impl Default for LinuxTextSystem {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[allow(unused)]
+impl PlatformTextSystem for LinuxTextSystem {
+    fn add_fonts(&self, fonts: &[Arc<Vec<u8>>]) -> Result<()> {
+        unimplemented!()
+    }
+    fn all_font_names(&self) -> Vec<String> {
+        unimplemented!()
+    }
+    fn all_font_families(&self) -> Vec<String> {
+        unimplemented!()
+    }
+    fn font_id(&self, descriptor: &Font) -> Result<FontId> {
+        unimplemented!()
+    }
+    fn font_metrics(&self, font_id: FontId) -> FontMetrics {
+        unimplemented!()
+    }
+    fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Bounds<f32>> {
+        unimplemented!()
+    }
+    fn advance(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Size<f32>> {
+        unimplemented!()
+    }
+    fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option<GlyphId> {
+        unimplemented!()
+    }
+    fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
+        unimplemented!()
+    }
+    fn rasterize_glyph(
+        &self,
+        params: &RenderGlyphParams,
+        raster_bounds: Bounds<DevicePixels>,
+    ) -> Result<(Size<DevicePixels>, Vec<u8>)> {
+        unimplemented!()
+    }
+    fn layout_line(&self, text: &str, font_size: Pixels, runs: &[FontRun]) -> LineLayout {
+        unimplemented!()
+    }
+    fn wrap_line(
+        &self,
+        text: &str,
+        font_id: FontId,
+        font_size: Pixels,
+        width: Pixels,
+    ) -> Vec<usize> {
+        unimplemented!()
+    }
+}