diff --git a/Cargo.lock b/Cargo.lock index 4a5253a..d840dd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -836,11 +836,20 @@ dependencies = [ ] [[package]] -name = "cosmic-text" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75acbfb314aeb4f5210d379af45ed1ec2c98c7f1790bf57b8a4c562ac0c51b71" +name = "cosmic-jotdown" +version = "0.1.0" dependencies = [ + "cosmic-text", + "jotdown", +] + +[[package]] +name = "cosmic-text" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c578f2b9abb4d5f3fbb12aba4008084d435dc6a8425c195cfe0b3594bfea0c25" +dependencies = [ + "bitflags 2.4.2", "fontdb", "libm", "log", @@ -850,6 +859,7 @@ dependencies = [ "self_cell", "swash", "sys-locale", + "ttf-parser", "unicode-bidi", "unicode-linebreak", "unicode-script", @@ -907,6 +917,29 @@ dependencies = [ "winapi", ] +[[package]] +name = "databake" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82175d72e69414ceafbe2b49686794d3a8bed846e0d50267355f83ea8fdd953a" +dependencies = [ + "databake-derive", + "proc-macro2", + "quote", +] + +[[package]] +name = "databake-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377af281d8f23663862a7c84623bc5dcf7f8c44b13c7496a590bdc157f941a43" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", + "synstructure", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1020,6 +1053,7 @@ dependencies = [ name = "egui-glyphon" version = "0.1.0" dependencies = [ + "cosmic-jotdown", "eframe", "egui", "egui-wgpu", @@ -1298,16 +1332,16 @@ dependencies = [ [[package]] name = "fontdb" -version = "0.15.0" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020e203f177c0fb250fb19455a252e838d2bbbce1f80f25ecc42402aafa8cd38" +checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.8.0", + "memmap2", "slotmap", "tinyvec", - "ttf-parser 0.19.2", + "ttf-parser", ] [[package]] @@ -1536,8 +1570,6 @@ dependencies = [ [[package]] name = "glyphon" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a62d0338e4056db6a73221c2fb2e30619452f6ea9651bac4110f51b0f7a7581" dependencies = [ "cosmic-text", "etagere", @@ -1750,6 +1782,13 @@ dependencies = [ "libc", ] +[[package]] +name = "jotdown" +version = "0.3.2" +dependencies = [ + "databake", +] + [[package]] name = "js-sys" version = "0.3.69" @@ -1877,15 +1916,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "memmap2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.9.4" @@ -2155,7 +2185,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" dependencies = [ - "ttf-parser 0.20.0", + "ttf-parser", ] [[package]] @@ -2498,15 +2528,15 @@ dependencies = [ [[package]] name = "rustybuzz" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee8fe2a8461a0854a37101fe7a1b13998d0cfa987e43248e81d2a5f4570f6fa" +checksum = "f0ae5692c5beaad6a9e22830deeed7874eae8a4e3ba4076fb48e12c56856222c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "bytemuck", "libm", "smallvec", - "ttf-parser 0.20.0", + "ttf-parser", "unicode-bidi-mirroring", "unicode-ccc", "unicode-properties", @@ -2542,7 +2572,7 @@ checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.4", + "memmap2", "smithay-client-toolkit", "tiny-skia", ] @@ -2646,7 +2676,7 @@ dependencies = [ "cursor-icon", "libc", "log", - "memmap2 0.9.4", + "memmap2", "rustix 0.38.31", "thiserror", "wayland-backend", @@ -2749,6 +2779,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "sys-locale" version = "0.3.1" @@ -2898,12 +2939,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "ttf-parser" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" - [[package]] name = "ttf-parser" version = "0.20.0" @@ -3676,7 +3711,7 @@ dependencies = [ "js-sys", "libc", "log", - "memmap2 0.9.4", + "memmap2", "ndk", "ndk-sys", "objc2 0.4.1", diff --git a/Cargo.toml b/Cargo.toml index f39b3c4..ff34fb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ edition = "2021" [dependencies] egui = { version = "0.26.2", default-features = false } egui-wgpu = "0.26.2" -glyphon = "0.5.0" +glyphon = { git = "https://git.nations.lol/fnmain/glyphon.git" } [dev-dependencies] +cosmic-jotdown = { path = "../cosmic-jotdown" } eframe = { version = "0.26.2", features = ["wgpu"] } env_logger = "0.11.3" diff --git a/examples/hello-world.rs b/examples/hello-world.rs index e24055f..0e50905 100644 --- a/examples/hello-world.rs +++ b/examples/hello-world.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release -use std::sync::Arc; +use std::{ops::Deref, sync::Arc}; use eframe::{ egui::{self, Slider}, @@ -11,11 +11,12 @@ use eframe::{ }, CreationContext, }; +use egui::{Align2, Pos2}; use egui_glyphon::{ glyphon::{Attrs, Family, FontSystem, Metrics, Shaping}, BufferWithTextArea, GlyphonRenderer, GlyphonRendererCallback, }; -use glyphon::Buffer; +use glyphon::{cosmic_text::Align, Buffer}; fn main() -> Result<(), eframe::Error> { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). @@ -32,28 +33,26 @@ fn main() -> Result<(), eframe::Error> { struct MyApp { font_system: Arc>, - size: f32, - buffer: Arc>, + buffers: Vec>>, } impl Default for MyApp { fn default() -> Self { let mut font_system = FontSystem::new(); - let mut buffer = - egui_glyphon::glyphon::Buffer::new(&mut font_system, Metrics::new(30.0, 42.0)); + let buffers = cosmic_jotdown::jotdown_into_buffers( + r#"# Header + +Test _test_ *test* 'test' "`test`""#, + &mut font_system, + Metrics::new(30.0, 42.0), + f32::MAX, + ) + .map(|buffer| Arc::new(RwLock::new(buffer))) + .collect(); - buffer.set_size(&mut font_system, 16.0, 9.0); - buffer.set_text(&mut font_system, "<== Hello world! ==> 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z fi ffi 🐕‍🦺 fi ffi - fi تما 🐕‍🦺 ffi تما - ffi fi 🐕‍🦺 ffi fi - تما تما 🐕‍🦺 تما - تما ffi 🐕‍🦺 تما fi تما - تما تما 🐕‍🦺 تما", Attrs::new().family(Family::SansSerif), Shaping::Advanced); - buffer.shape_until_scroll(&mut font_system); Self { font_system: Arc::new(Mutex::new(font_system)), - buffer: Arc::new(RwLock::new(buffer)), - size: 35.0, + buffers, } } } @@ -70,28 +69,56 @@ impl MyApp { } } +pub fn measure_buffer(buffer: &Buffer, vb: Vec2) -> Rect { + let mut rtl = false; + let (width, total_lines) = + buffer + .layout_runs() + .fold((0.0, 0usize), |(width, total_lines), run| { + if run.rtl { + rtl = true; + } + (run.line_w.max(width), total_lines + 1) + }); + + let (max_width, max_height) = buffer.size(); + + let size = Vec2::new( + if rtl { vb.x } else { width.min(max_width) }, + (total_lines as f32 * buffer.metrics().line_height).min(max_height), + ); + match buffer.lines[0].align() { + Some(Align::Right) | Some(Align::End) => { + Align2::RIGHT_TOP.align_size_within_rect(size, Rect::from_min_size(Pos2::ZERO, vb)) + } + Some(Align::Center) | Some(Align::Justified) => { + Align2::CENTER_TOP.align_size_within_rect(size, Rect::from_min_size(Pos2::ZERO, vb)) + } + Some(Align::Left) | None => Rect::from_min_size(Pos2::ZERO, size), + } +} + impl eframe::App for MyApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - let size = Vec2::new(16.0 * self.size, 9.0 * self.size); - - { - let mut font_system = self.font_system.lock(); - let mut buffer = self.buffer.write(); - buffer.set_metrics(&mut font_system, Metrics::new(self.size, self.size)); - buffer.set_size(&mut font_system, size.x, size.y); - buffer.shape_until_scroll(&mut font_system); - } - egui::CentralPanel::default().show(ctx, |ui| { - ui.add(Slider::new(&mut self.size, 0.1..=67.5)); - let rect = Rect::from_min_size(ui.cursor().min, size); - let buffers: Vec = vec![BufferWithTextArea::new( - self.buffer.clone(), - rect, - 1.0, - egui_glyphon::glyphon::Color::rgb(255, 255, 255), - ui.ctx(), - )]; + let mut rect = Rect::from_min_size(ui.cursor().min, Vec2::INFINITY); + let buffers: Vec = self + .buffers + .iter() + .cloned() + .map(|buffer| { + let buffer_size = measure_buffer(buffer.read().deref(), ui.max_rect().size()); + let this_rect = rect; + rect.min.y += buffer_size.height() + 48.0; + BufferWithTextArea::new( + buffer, + this_rect, + 1.0, + egui_glyphon::glyphon::Color::rgb(255, 255, 255), + ui.ctx(), + ) + }) + .collect(); ui.painter().add(egui_wgpu::Callback::new_paint_callback( ui.max_rect(), GlyphonRendererCallback { buffers }, diff --git a/src/lib.rs b/src/lib.rs index 16ac693..8698f04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -162,6 +162,7 @@ impl egui_wgpu::CallbackTrait for GlyphonRendererCallback { bottom: b.rect.bottom() as i32, }, default_color: b.default_color, + opacity: b.opacity, }) .collect(); glyphon_renderer