diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 896ee0be81..d94d9cb51d 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -1742,7 +1742,6 @@ pub mod tests { } } - #[cfg(target_os = "macos")] #[gpui::test(retries = 5)] async fn test_soft_wraps(cx: &mut gpui::TestAppContext) { cx.background_executor @@ -1760,7 +1759,7 @@ pub mod tests { editor.update(cx, |editor, _cx| editor.text_layout_details(window)); let font_size = px(12.0); - let wrap_width = Some(px(64.)); + let wrap_width = Some(px(96.)); let text = "one two three four five\nsix seven eight"; let buffer = MultiBuffer::build_simple(text, cx); @@ -2411,8 +2410,6 @@ pub mod tests { } } - // todo(linux) fails due to pixel differences in text rendering - #[cfg(target_os = "macos")] #[gpui::test] async fn test_chunks_with_soft_wrapping(cx: &mut gpui::TestAppContext) { cx.background_executor diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 3e8aaaaefb..f57ae8b96b 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -2277,7 +2277,6 @@ mod tests { } } - #[cfg(target_os = "macos")] #[gpui::test] fn test_blocks_on_wrapped_lines(cx: &mut gpui::TestAppContext) { cx.update(init_test); @@ -2292,7 +2291,7 @@ mod tests { let (_, fold_snapshot) = FoldMap::new(inlay_snapshot); let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap()); let (_, wraps_snapshot) = cx.update(|cx| { - WrapMap::new(tab_snapshot, font("Helvetica"), px(14.0), Some(px(60.)), cx) + WrapMap::new(tab_snapshot, font("Helvetica"), px(14.0), Some(px(90.)), cx) }); let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index b7354bdb9e..78f9e67df6 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -1316,8 +1316,6 @@ fn test_move_cursor(cx: &mut TestAppContext) { }); } -// TODO: Re-enable this test -#[cfg(target_os = "macos")] #[gpui::test] fn test_move_cursor_multibyte(cx: &mut TestAppContext) { init_test(cx, |_| {}); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index dffa4da3e1..a05e39e2f0 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -6638,7 +6638,7 @@ impl Element for EditorElement { } }; - if editor.set_wrap_width(wrap_width, cx) { + if editor.set_wrap_width(wrap_width.map(|w| w.ceil()), cx) { editor.snapshot(window, cx) } else { snapshot diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 526d992f26..969e51e44d 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -37,9 +37,10 @@ use crate::{ DEFAULT_WINDOW_SIZE, DevicePixels, DispatchEventResult, Font, FontId, FontMetrics, FontRun, ForegroundExecutor, GlyphId, GpuSpecs, ImageSource, Keymap, LineLayout, Pixels, PlatformInput, Point, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, ScaledPixels, Scene, - SharedString, Size, SvgRenderer, SvgSize, Task, TaskLabel, Window, point, + ShapedGlyph, ShapedRun, SharedString, Size, SvgRenderer, SvgSize, Task, TaskLabel, Window, + point, px, size, }; -use anyhow::{Result, anyhow}; +use anyhow::Result; use async_task::Runnable; use futures::channel::oneshot; use image::codecs::gif::GifDecoder; @@ -532,40 +533,105 @@ impl PlatformTextSystem for NoopTextSystem { Vec::new() } - fn font_id(&self, descriptor: &Font) -> Result { - Err(anyhow!("No font found for {:?}", descriptor)) + fn font_id(&self, _descriptor: &Font) -> Result { + return Ok(FontId(1)); } fn font_metrics(&self, _font_id: FontId) -> FontMetrics { - unimplemented!() + FontMetrics { + units_per_em: 1000, + ascent: 1025.0, + descent: -275.0, + line_gap: 0.0, + underline_position: -95.0, + underline_thickness: 60.0, + cap_height: 698.0, + x_height: 516.0, + bounding_box: Bounds { + origin: Point { + x: -260.0, + y: -245.0, + }, + size: Size { + width: 1501.0, + height: 1364.0, + }, + }, + } } - fn typographic_bounds(&self, font_id: FontId, _glyph_id: GlyphId) -> Result> { - Err(anyhow!("No font found for {:?}", font_id)) + fn typographic_bounds(&self, _font_id: FontId, _glyph_id: GlyphId) -> Result> { + Ok(Bounds { + origin: Point { x: 54.0, y: 0.0 }, + size: size(392.0, 528.0), + }) } - fn advance(&self, font_id: FontId, _glyph_id: GlyphId) -> Result> { - Err(anyhow!("No font found for {:?}", font_id)) + fn advance(&self, _font_id: FontId, glyph_id: GlyphId) -> Result> { + Ok(size(600.0 * glyph_id.0 as f32, 0.0)) } - fn glyph_for_char(&self, _font_id: FontId, _ch: char) -> Option { - None + fn glyph_for_char(&self, _font_id: FontId, ch: char) -> Option { + Some(GlyphId(ch.len_utf16() as u32)) } - fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result> { - Err(anyhow!("No font found for {:?}", params)) + fn glyph_raster_bounds(&self, _params: &RenderGlyphParams) -> Result> { + Ok(Default::default()) } fn rasterize_glyph( &self, - params: &RenderGlyphParams, - _raster_bounds: Bounds, + _params: &RenderGlyphParams, + raster_bounds: Bounds, ) -> Result<(Size, Vec)> { - Err(anyhow!("No font found for {:?}", params)) + Ok((raster_bounds.size, Vec::new())) } - fn layout_line(&self, _text: &str, _font_size: Pixels, _runs: &[FontRun]) -> LineLayout { - unimplemented!() + fn layout_line(&self, text: &str, font_size: Pixels, _runs: &[FontRun]) -> LineLayout { + let mut position = px(0.); + let metrics = self.font_metrics(FontId(0)); + let em_width = font_size + * self + .advance(FontId(0), self.glyph_for_char(FontId(0), 'm').unwrap()) + .unwrap() + .width + / metrics.units_per_em as f32; + let mut glyphs = SmallVec::default(); + for (ix, c) in text.char_indices() { + if let Some(glyph) = self.glyph_for_char(FontId(0), c) { + glyphs.push(ShapedGlyph { + id: glyph, + position: point(position, px(0.)), + index: ix, + is_emoji: glyph.0 == 2, + }); + if glyph.0 == 2 { + position += em_width * 2.0; + } else { + position += em_width; + } + } else { + position += em_width + } + } + let mut runs = Vec::default(); + if glyphs.len() > 0 { + runs.push(ShapedRun { + font_id: FontId(0), + glyphs, + }); + } else { + position = px(0.); + } + + LineLayout { + font_size, + width: position, + ascent: font_size * (metrics.ascent / metrics.units_per_em as f32), + descent: font_size * (metrics.descent / metrics.units_per_em as f32), + runs, + len: text.len(), + } } } diff --git a/crates/gpui/src/platform/test/platform.rs b/crates/gpui/src/platform/test/platform.rs index 90e3cf2fa6..3902a98a65 100644 --- a/crates/gpui/src/platform/test/platform.rs +++ b/crates/gpui/src/platform/test/platform.rs @@ -1,8 +1,8 @@ use crate::{ AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DevicePixels, - ForegroundExecutor, Keymap, Platform, PlatformDisplay, PlatformTextSystem, ScreenCaptureFrame, - ScreenCaptureSource, ScreenCaptureStream, Size, Task, TestDisplay, TestWindow, - WindowAppearance, WindowParams, size, + ForegroundExecutor, Keymap, NoopTextSystem, Platform, PlatformDisplay, PlatformTextSystem, + ScreenCaptureFrame, ScreenCaptureSource, ScreenCaptureStream, Size, Task, TestDisplay, + TestWindow, WindowAppearance, WindowParams, size, }; use anyhow::Result; use collections::VecDeque; @@ -91,17 +91,7 @@ impl TestPlatform { ) }; - #[cfg(target_os = "macos")] - let text_system = Arc::new(crate::platform::mac::MacTextSystem::new()); - - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - let text_system = Arc::new(crate::platform::linux::CosmicTextSystem::new()); - - #[cfg(target_os = "windows")] - let text_system = Arc::new( - crate::platform::windows::DirectWriteTextSystem::new(&bitmap_factory) - .expect("Unable to initialize direct write."), - ); + let text_system = Arc::new(NoopTextSystem); Rc::new_cyclic(|weak| TestPlatform { background_executor: executor, diff --git a/crates/gpui/src/text_system/line_wrapper.rs b/crates/gpui/src/text_system/line_wrapper.rs index f0dfc927e5..d7bc4c1f24 100644 --- a/crates/gpui/src/text_system/line_wrapper.rs +++ b/crates/gpui/src/text_system/line_wrapper.rs @@ -330,13 +330,6 @@ mod tests { fn build_wrapper() -> LineWrapper { let dispatcher = TestDispatcher::new(StdRng::seed_from_u64(0)); let cx = TestAppContext::new(dispatcher, None); - cx.text_system() - .add_fonts(vec![ - std::fs::read("../../assets/fonts/plex-mono/ZedPlexMono-Regular.ttf") - .unwrap() - .into(), - ]) - .unwrap(); let id = cx.text_system().font_id(&font("Zed Plex Mono")).unwrap(); LineWrapper::new(id, px(16.), cx.text_system().platform_text_system.clone()) } @@ -734,16 +727,16 @@ mod tests { lines[0].layout.wrap_boundaries(), &[ WrapBoundary { - run_ix: 1, - glyph_ix: 3 + run_ix: 0, + glyph_ix: 7 }, WrapBoundary { - run_ix: 2, - glyph_ix: 3 + run_ix: 0, + glyph_ix: 12 }, WrapBoundary { - run_ix: 4, - glyph_ix: 2 + run_ix: 0, + glyph_ix: 18 } ], );