diff --git a/adamina.ttf b/adamina.ttf new file mode 100644 index 0000000..2c76861 Binary files /dev/null and b/adamina.ttf differ diff --git a/adamina.woff b/adamina.woff new file mode 100644 index 0000000..352c99c Binary files /dev/null and b/adamina.woff differ diff --git a/MononokiNerdFont-Regular.ttf b/mononoki.ttf similarity index 100% rename from MononokiNerdFont-Regular.ttf rename to mononoki.ttf diff --git a/src/app/bin.rs b/src/app/bin.rs index 71df79c..d061c50 100644 --- a/src/app/bin.rs +++ b/src/app/bin.rs @@ -4,22 +4,17 @@ use std::{ rc::Rc, }; -use clay_layout::{ - Declaration, - bindings::Clay_ResetMeasureTextCache, - fit, grow, - id::Id, - layout::{LayoutDirection, Padding}, - math::Dimensions, - render_commands::RenderCommandConfig, - text::{TextConfig, TextElementConfig}, -}; +mod gui; + +use clay_layout::render_commands::RenderCommandConfig; +use gui::GUI; use raylib::{ RaylibHandle, RaylibThread, color::Color, - ffi::Vector2, - prelude::{Font, RaylibDraw, RaylibDrawHandle, RaylibScissorModeExt}, + ffi::{MouseButton, TextLength, Vector2}, + prelude::{Font, RaylibDraw, RaylibDrawHandle}, text::RaylibFont, + texture::Texture2D, }; struct FontStore { @@ -29,9 +24,9 @@ struct FontStore { } impl FontStore { - const SIZE_PARAGRAPH: f32 = 20.; - const SIZE_HEADER: f32 = 30.; - const MOD_SUBTEXT: f32 = 0.5; + // const SIZE_PARAGRAPH: f32 = 20.; + // const SIZE_HEADER: f32 = 30.; + // const MOD_SUBTEXT: f32 = 0.5; pub fn new(name: impl Into) -> Self { Self { @@ -51,27 +46,30 @@ impl FontStore { } } - pub fn get_no_load(&self, size: i32) -> Option> { - if let Some(font) = self.fonts.get(&size) { - Some(font.clone()) - } else { - None - } - } + // pub fn get_no_load(&self, size: i32) -> Option> { + // if let Some(font) = self.fonts.get(&size) { + // Some(font.clone()) + // } else { + // None + // } + // } pub fn load_fonts( &mut self, handle: &mut RaylibHandle, thread: &RaylibThread, - ) -> Result<(), String> { - for size in self.fonts_to_be_loaded.clone() { - assert!(size != 0, "HOW IS THIS ZERO?"); - println!("Loading {} in {size}px", self.font); - let font = Rc::new(handle.load_font_ex(&thread, &self.font, size, None)?); - self.fonts.insert(size, font.clone()); + ) -> Result { + let invalidate = self.fonts_to_be_loaded.len() > 0; + if invalidate { + for size in self.fonts_to_be_loaded.clone() { + assert!(size != 0, "HOW IS THIS ZERO?"); + println!("Loading {} in {size}px", self.font); + let font = Rc::new(handle.load_font_ex(&thread, &self.font, size, None)?); + self.fonts.insert(size, font.clone()); + } + self.fonts_to_be_loaded.clear(); } - self.fonts_to_be_loaded.clear(); - Ok(()) + Ok(invalidate) } pub fn text( @@ -102,10 +100,10 @@ impl FontStore { #[inline] fn clay2ray(c: clay_layout::color::Color) -> Color { Color { - r: (c.r as f32 * 256.0) as u8, - g: (c.g as f32 * 256.0) as u8, - b: (c.b as f32 * 256.0) as u8, - a: (c.a as f32 * 256.0) as u8, + r: c.r as u8, + g: c.g as u8, + b: c.b as u8, + a: c.a as u8, } } @@ -119,24 +117,24 @@ fn main() -> Result<(), String> { .resizable() .build(); let mut clay = clay_layout::Clay::new((640., 480.).into()); - // let font = match rl.load_font_ex(&thread, "MononokiNerdFont-Regular.ttf", 20, None) { - // Ok(font) => font, - // Err(err) => panic!("Failed to load font {}", err), - // }; - let font_store = Rc::new(RefCell::new(FontStore::new("MononokiNerdFont-Regular.ttf"))); + let font_store = Rc::new(RefCell::new(FontStore::new("adamina.ttf"))); let font_store_math = Rc::new(RefCell::new(FontStore::new("xits-italic.ttf"))); - { - font_store.borrow_mut().get(16); - } + let mut gui = GUI::new(); + + let mut previous_left_button = false; + let mut previous_right_button = false; // stupid fucking 'static closures let font_store_clone = font_store.clone(); - let font_store_math_clone = font_store.clone(); + let font_store_math_clone = font_store_math.clone(); clay.set_measure_text_function(move |text, config| { let mut text_size = clay_layout::math::Dimensions::new(0., 0.); + let mut max_text_width: f32 = 0.; + let mut line_text_width: f32 = 0.; + let font_store = match config.font_id { 0 => font_store_clone.clone(), 1 => font_store_math_clone.clone(), @@ -146,154 +144,110 @@ fn main() -> Result<(), String> { let font = if let Some(font) = font_store.borrow_mut().get(config.font_size.into()) { font } else { - println!("Font not cached. Returning: {:?}", text_size); + // println!("Font not cached. Returning: {:?}", text_size); return text_size; }; - let size = font.measure_text(text, config.font_size.into(), config.letter_spacing.into()); + let scale_factor = config.font_size as f32 / font.baseSize as f32; - text_size.width = size.x; - text_size.height = size.y; + let text_height = config.font_size as f32; - println!("Measurements: {:?}", text_size); + for char in text.chars() { + if char == '\n' { + max_text_width = max_text_width.max(line_text_width); + line_text_width = 0.; + continue; + } + + let idx = char as u32 - 32; + line_text_width += if let Some(glyph) = font.chars().get(idx as usize) { + if glyph.advanceX > 0 { + glyph.advanceX as f32 + } else { + font.get_glyph_atlas_rec(char).width + glyph.offsetX as f32 + } + } else { + 0 as f32 + } + config.letter_spacing as f32; + } + + max_text_width = max_text_width.max(line_text_width); + + text_size.width = max_text_width * scale_factor; + text_size.height = text_height; text_size + + // unsafe { + // std::mem::transmute(font.measure_text(text, config.font_size as f32, config.letter_spacing as f32 + 1.)) + // } }); - rl.set_target_fps(30); + rl.set_target_fps(60); + rl.set_exit_key(None); let mut debug = false; while !rl.window_should_close() { if rl.is_window_resized() { - let size = (rl.get_screen_width() as f32 - 200., rl.get_screen_height() as f32); + let size = (rl.get_screen_width() as f32, rl.get_screen_height() as f32); clay.layout_dimensions(size.into()); println!("Resized window to {:?}", size); } + let left_button = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT); + let right_button = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT); + { - font_store.borrow_mut().load_fonts(&mut rl, &thread)?; - font_store_math.borrow_mut().load_fonts(&mut rl, &thread)?; + if font_store.borrow_mut().load_fonts(&mut rl, &thread)? + || font_store_math.borrow_mut().load_fonts(&mut rl, &thread)? + { + clay.reset_measure_text_cache(); + } } - if rl.is_key_pressed(raylib::ffi::KeyboardKey::KEY_D) { - debug = !debug; + if rl.is_key_down(raylib::ffi::KeyboardKey::KEY_RIGHT_ALT) + && rl.is_key_pressed(raylib::ffi::KeyboardKey::KEY_D) + { + debug = !clay.debug_mode_enabled(); clay.reset_measure_text_cache(); clay.enable_debug_mode(debug); println!("Toggled debug mode to {debug}"); } - clay.set_debug_highlight((0xff, 0x0, 0x0).into()); + clay.set_debug_highlight((180, 142, 173, 150).into()); - clay.begin(); - - clay.with( - Declaration::new() - .id(clay.id("body")) - .layout() - .width(grow!(0.)) - .height(grow!(0.)) - .direction(LayoutDirection::TopToBottom) - .padding(Padding::all(8)) - .child_gap(0) - .end() - .scroll(false, true), - |clay| { - for i in 0..0 { - clay.with( - Declaration::new() - .id(clay.id(i.to_string().as_str())) - .layout() - .width(grow!(0.)) - .height(fit!(0.)) - .padding(Padding::all(4)) - .end(), - |clay| { - clay.text( - "test", - TextConfig::new() - .color((0x0, 0x0, 0x0).into()) - .font_size(16) - .end(), - ) - }, - ); - } - }, + clay.update_scroll_containers( + false, + unsafe { std::mem::transmute(rl.get_mouse_wheel_move_v()) }, + rl.get_frame_time(), ); - let render_commands = clay.end(); + clay.pointer_state( + unsafe { std::mem::transmute(rl.get_mouse_position()) }, + left_button, + ); + + let render_commands = gui.render( + &clay, + (left_button, left_button && !previous_left_button), + (right_button, right_button && !previous_right_button), + (rl.get_char_pressed(), rl.get_key_pressed_number()), + rl.get_time() + ); let mut d = rl.begin_drawing(&thread); d.clear_background(Color::WHITE); - /* - for (int j = 0; j < renderCommands.length; j++) - { - Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, j); - Clay_BoundingBox boundingBox = renderCommand->boundingBox; - switch (renderCommand->commandType) - { - case CLAY_RENDER_COMMAND_TYPE_TEXT: { - // Raylib uses standard C strings so isn't compatible with cheap slices, we need to clone the string to append null terminator - Clay_TextRenderData *textData = &renderCommand->renderData.text; - char *cloned = (char *)malloc(textData->stringContents.length + 1); - memcpy(cloned, textData->stringContents.chars, textData->stringContents.length); - cloned[textData->stringContents.length] = '\0'; - Font fontToUse = fonts[textData->fontId]; - DrawTextEx(fontToUse, cloned, (Vector2){boundingBox.x, boundingBox.y}, (float)textData->fontSize, (float)textData->letterSpacing, CLAY_COLOR_TO_RAYLIB_COLOR(textData->textColor)); - free(cloned); - break; - } - case CLAY_RENDER_COMMAND_TYPE_IMAGE: { - Texture2D imageTexture = *(Texture2D *)renderCommand->renderData.image.imageData; - Clay_Color tintColor = renderCommand->renderData.image.backgroundColor; - if (tintColor.r == 0 && tintColor.g == 0 && tintColor.b == 0 && tintColor.a == 0) { - tintColor = (Clay_Color) { 255, 255, 255, 255 }; - } - DrawTextureEx( - imageTexture, - (Vector2){boundingBox.x, boundingBox.y}, - 0, - boundingBox.width / (float)imageTexture.width, - CLAY_COLOR_TO_RAYLIB_COLOR(tintColor)); - break; - } - case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: { - break; - } - case CLAY_RENDER_COMMAND_TYPE_CUSTOM: { - Clay_CustomRenderData *config = &renderCommand->renderData.custom; - CustomLayoutElement *customElement = (CustomLayoutElement *)config->customData; - if (!customElement) continue; - switch (customElement->type) { - case CUSTOM_LAYOUT_ELEMENT_TYPE_3D_MODEL: { - Clay_BoundingBox rootBox = renderCommands.internalArray[0].boundingBox; - float scaleValue = CLAY__MIN(CLAY__MIN(1, 768 / rootBox.height) * CLAY__MAX(1, rootBox.width / 1024), 1.5f); - Ray positionRay = GetScreenToWorldPointWithZDistance((Vector2) { renderCommand->boundingBox.x + renderCommand->boundingBox.width / 2, renderCommand->boundingBox.y + (renderCommand->boundingBox.height / 2) + 20 }, Raylib_camera, (int)roundf(rootBox.width), (int)roundf(rootBox.height), 140); - BeginMode3D(Raylib_camera); - DrawModel(customElement->customData.model.model, positionRay.position, customElement->customData.model.scale * scaleValue, WHITE); // Draw 3d model with texture - EndMode3D(); - break; - } - default: break; - } - break; - } - default: { - printf("Error: unhandled render command."); - exit(1); - } - } - } - */ - for command in render_commands { match command.config { RenderCommandConfig::Rectangle(rectangle) => { - println!("RECT!!! {}: {:?}\n{:?}\n\n", command.id, command.bounding_box, rectangle); - + // println!( + // "RECT!!! {}: {:?}\n{:?}\n\n", + // command.id, command.bounding_box, rectangle + // ); + // d.draw_rectangle_rounded( raylib::ffi::Rectangle { x: command.bounding_box.x, @@ -307,8 +261,13 @@ fn main() -> Result<(), String> { ); } RenderCommandConfig::Text(text) => { - // println!("{:?}", text); - font_store.borrow_mut().text( + let font = match text.font_id { + 0 => font_store.clone(), + 1 => font_store_math.clone(), + _ => panic!("Unknown font {}", text.font_id), + }; + + font.borrow_mut().text( &mut d, text.text, command.bounding_box.x, @@ -318,7 +277,6 @@ fn main() -> Result<(), String> { Some(clay2ray(text.color)), ); } - RenderCommandConfig::ScissorStart() => unsafe { raylib::ffi::BeginScissorMode( command.bounding_box.x as i32, @@ -330,22 +288,7 @@ fn main() -> Result<(), String> { RenderCommandConfig::ScissorEnd() => unsafe { raylib::ffi::EndScissorMode(); }, - RenderCommandConfig::Border(border) => { - // if (config->cornerRadius.topLeft > 0) { - // DrawRing((Vector2) { roundf(boundingBox.x + config->cornerRadius.topLeft), roundf(boundingBox.y + config->cornerRadius.topLeft) }, roundf(config->cornerRadius.topLeft - config->width.top), config->cornerRadius.topLeft, 180, 270, 10, CLAY_COLOR_TO_RAYLIB_COLOR(config->color)); - // } - // if (config->cornerRadius.topRight > 0) { - // DrawRing((Vector2) { roundf(boundingBox.x + boundingBox.width - config->cornerRadius.topRight), roundf(boundingBox.y + config->cornerRadius.topRight) }, roundf(config->cornerRadius.topRight - config->width.top), config->cornerRadius.topRight, 270, 360, 10, CLAY_COLOR_TO_RAYLIB_COLOR(config->color)); - // } - // if (config->cornerRadius.bottomLeft > 0) { - // DrawRing((Vector2) { roundf(boundingBox.x + config->cornerRadius.bottomLeft), roundf(boundingBox.y + boundingBox.height - config->cornerRadius.bottomLeft) }, roundf(config->cornerRadius.bottomLeft - config->width.top), config->cornerRadius.bottomLeft, 90, 180, 10, CLAY_COLOR_TO_RAYLIB_COLOR(config->color)); - // } - // if (config->cornerRadius.bottomRight > 0) { - // DrawRing((Vector2) { roundf(boundingBox.x + boundingBox.width - config->cornerRadius.bottomRight), roundf(boundingBox.y + boundingBox.height - config->cornerRadius.bottomRight) }, roundf(config->cornerRadius.bottomRight - config->width.bottom), config->cornerRadius.bottomRight, 0.1, 90, 10, CLAY_COLOR_TO_RAYLIB_COLOR(config->color)); - // } - // break; - // } // Left border if border.width.left > 0 { d.draw_rectangle( @@ -399,12 +342,95 @@ fn main() -> Result<(), String> { clay2ray(border.color), ); } + // Top left corner + if border.corner_radii.top_left > 0. { + d.draw_ring( + Vector2 { + x: command.bounding_box.x + border.corner_radii.top_left, + y: command.bounding_box.y + border.corner_radii.top_left, + }, + border.corner_radii.top_left - border.width.top as f32, + border.corner_radii.top_left, + 180., + 270., + 10, + clay2ray(border.color), + ); + } + // Top right corner + if border.corner_radii.top_right > 0. { + d.draw_ring( + Vector2 { + x: command.bounding_box.x + command.bounding_box.width + - border.corner_radii.top_right, + y: command.bounding_box.y + border.corner_radii.top_right, + }, + border.corner_radii.top_right - border.width.top as f32, + border.corner_radii.top_right, + 270., + 360., + 10, + clay2ray(border.color), + ); + } + // Bottom left + if border.corner_radii.bottom_left > 0. { + d.draw_ring( + Vector2 { + x: command.bounding_box.x + border.corner_radii.bottom_left, + y: command.bounding_box.y + command.bounding_box.height + - border.corner_radii.bottom_left, + }, + border.corner_radii.bottom_left - border.width.top as f32, + border.corner_radii.bottom_left, + 90., + 180., + 10, + clay2ray(border.color), + ); + } + // Bottom right + if border.corner_radii.bottom_right > 0. { + d.draw_ring( + Vector2 { + x: command.bounding_box.x + command.bounding_box.width + - border.corner_radii.bottom_right, + y: command.bounding_box.y + command.bounding_box.height + - border.corner_radii.bottom_right, + }, + border.corner_radii.bottom_right - border.width.bottom as f32, + border.corner_radii.bottom_right, + 0., + 90., + 10, + clay2ray(border.color), + ); + } } - RenderCommandConfig::None() => {} + RenderCommandConfig::Image(image) => { + let texture: &Texture2D = unsafe { + std::mem::transmute::<*const std::ffi::c_void, *const Texture2D>(image.data) + .as_ref() + .unwrap() + }; + d.draw_texture_ex( + texture, + Vector2 { + x: command.bounding_box.x, + y: command.bounding_box.y, + }, + 0., + command.bounding_box.width / image.dimensions.width, + clay2ray(image.background_color), + ); + } _ => panic!("Unimplemented {:#?}", command), } } + + previous_left_button = left_button; + previous_right_button = right_button; } Ok(()) diff --git a/src/app/gui/document.rs b/src/app/gui/document.rs new file mode 100644 index 0000000..2468ea6 --- /dev/null +++ b/src/app/gui/document.rs @@ -0,0 +1,224 @@ +use std::mem::ManuallyDrop; + +use clay_layout::{ + Clay, Declaration, fit, fixed, grow, + layout::{LayoutDirection, Padding}, + text::TextConfig, +}; +use raylib::ffi::KeyboardKey; + +pub type LineType = String; + +pub struct Document { + lines: Vec<(String, LineType)>, + total_lines: usize, + current_line: Option, + current_char: usize, + lines_to_delete: Vec, + lines_to_add: Vec<(usize, LineType)>, + last_type_time: f64, +} + +impl Document { + pub fn new() -> Self { + Self { + lines: vec![("0".to_owned(), "".to_string())], + total_lines: 1, + current_line: Some(0), + current_char: 0, + lines_to_delete: vec![], + lines_to_add: vec![], + last_type_time: -100., + } + } + + pub fn add_line(&mut self, content: impl Into) { + self.add_line_at(self.lines.len(), content); + } + + pub fn add_line_at(&mut self, idx: usize, content: impl Into) { + self.lines + .insert(idx, (self.total_lines.to_string(), content.into())); + self.total_lines += 1; + } + + pub fn render<'a>( + &'a mut self, + clay: &'a Clay, + (left_held, left_pressed): (bool, bool), + (righ_held, right_pressed): (bool, bool), + (latest_char, latest_key): (Option, Option), + time: f64, + ) { + if !self.lines_to_delete.is_empty() { + self.lines_to_delete.sort(); + + for line in self.lines_to_delete.iter().rev() { + self.lines.remove(*line); + } + + self.lines_to_delete.clear(); + + self.current_line = if let Some(i) = self.current_line { + if self.lines.len() == 0 { + self.add_line("".to_string()); + } + Some( + (TryInto::::try_into(i).unwrap() - 1) + .max(0) + .min(TryInto::::try_into(self.lines.len()).unwrap() - 1) + .try_into() + .unwrap(), + ) + } else { + None + }; + } + + if !self.lines_to_add.is_empty() { + // i am NOT cloning this shit + let lines_to_add: ManuallyDrop> = unsafe { + let len = self.lines_to_add.len(); + let cap = self.lines_to_add.capacity(); + let fuck = self.lines_to_add.as_mut_ptr(); + std::mem::ManuallyDrop::new(Vec::from_raw_parts(fuck, len, cap)) + }; + + for (idx, line) in lines_to_add.iter() { + self.add_line_at(*idx, line); + } + + self.lines_to_add.clear(); + self.current_line = if let Some(i) = self.current_line { + Some(i + 1) + } else { + None + }; + } + + if left_pressed && clay.pointer_over(clay.id("document")) { + self.current_line = None; + } + + let len = self.lines.len(); + let mut can_go_down = true; + + clay.with( + &Declaration::new() + .id(clay.id("document")) + .layout() + .width(grow!(0.)) + .height(grow!(0.)) + .direction(LayoutDirection::TopToBottom) + .padding(Padding::all(8)) + .child_gap(0) + .end() + .background_color((46, 52, 64).into()) + .scroll(false, true), + |clay| { + for (i, line) in self.lines.iter_mut().enumerate() { + let current_selected = + if left_pressed && clay.pointer_over(clay.id(line.0.as_str())) { + self.current_line = Some(i); + true + } else { + Some(i) == self.current_line + }; + + if current_selected { + if let Some(char) = latest_char { + line.1 += char.to_string().as_str(); + self.last_type_time = time; + } + + match latest_key { + Some(val) if val == KeyboardKey::KEY_BACKSPACE as u32 => { + if line.1.len() == 0 { + self.lines_to_delete.push(i); + } else { + let _ = line.1.pop(); + } + } + Some(val) if val == KeyboardKey::KEY_ENTER as u32 => { + self.lines_to_add.push((i + 1, "".to_string())); + } + Some(val) if val == KeyboardKey::KEY_UP as u32 => { + self.current_line = Some( + (TryInto::::try_into(self.current_line.unwrap()).unwrap() + - 1) + .max(0) + .try_into() + .unwrap(), + ); + } + Some(val) if val == KeyboardKey::KEY_DOWN as u32 && can_go_down => { + self.current_line = Some( + (TryInto::::try_into(self.current_line.unwrap()).unwrap() + + 1) + .min(TryInto::::try_into(len).unwrap() - 1) + .try_into() + .unwrap(), + ); + can_go_down = false; + } + _ => {} + } + } + + clay.with( + &Declaration::new() + .id(clay.id(line.0.as_str())) + .layout() + .width(grow!(0.)) + .height(fit!(21.)) + .direction(LayoutDirection::LeftToRight) + .padding(Padding::new(4, 4, 0, 1)) + .child_alignment(clay_layout::layout::Alignment { + x: clay_layout::layout::LayoutAlignmentX::Left, + y: clay_layout::layout::LayoutAlignmentY::Center, + }) + // .child_gap(2) + // .end() + // .border() + // .color((67, 76, 94).into()) + // .bottom(2) + // .end() + // .corner_radius() + // .all(4.) + .end(), + |clay| { + clay.text( + line.1.as_str(), + TextConfig::new() + .color((229, 233, 240).into()) + .font_size(20) + .font_id(0) + .letter_spacing(2) + .end(), + ); + if current_selected + && can_go_down + && ((time - self.last_type_time) < 0.5 || time % 1.2 < 0.6) + { + clay.with( + &Declaration::new() + .id(clay.id("text_cursor")) + .layout() + .height(grow!(0.)) + .width(fixed!(8.)) + .end() + .background_color((229, 233, 240, 100).into()) + // .corner_radius() + // .all(2.) + // .end(), + , + |_| {}, + ); + } + }, + ); + } + }, + ); + } +} diff --git a/src/app/gui/mod.rs b/src/app/gui/mod.rs index 026d0fe..380fd97 100644 --- a/src/app/gui/mod.rs +++ b/src/app/gui/mod.rs @@ -1,27 +1,36 @@ -use std::rc::Rc; - -use libopenbirch::node::{ - NodeEnum, add::Add, constant::Constant, divide::Divide, multiply::Multiply, symbol::Symbol, +use clay_layout::{ + Clay, Declaration, grow, + layout::{LayoutDirection, Padding}, + render_commands::RenderCommand, }; -use math_segments::MathSegment; +use document::Document; -mod math_segments; +mod document; pub struct GUI { - meth: Vec>, + pub document: Document, } impl GUI { pub fn new() -> Self { - let a = Constant::new(69.0).into(); - let b = Constant::new(420.0).into(); - let c: NodeEnum = Add::new(a, b).into(); - let d = Symbol::new_from_str("x").into(); - let e = Divide::new(c.clone(), d).into(); - let f = Multiply::new(e, c); - Self { - meth: vec![Rc::new(NodeEnum::Multiply(f))], + document: Document::new(), } } + + pub fn render<'a>( + &'a mut self, + clay: &'a Clay, + left_mouse: (bool, bool), + right_mouse: (bool, bool), + latest_char: (Option, Option), + time: f64, + ) -> impl Iterator { + clay.begin(); + + self.document + .render(clay, left_mouse, right_mouse, latest_char, time); + + clay.end() + } } diff --git a/src/lib/node/assign.rs b/src/lib/node/assign.rs index defabbd..c04d58f 100644 --- a/src/lib/node/assign.rs +++ b/src/lib/node/assign.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use super::{Environment, Node, NodeEnum, Precedence, empty::Empty, symbol::Symbol}; +use super::{Environment, Node, NodeEnum, Precedence, empty::Empty}; #[derive(Debug, Clone, PartialEq, PartialOrd)] pub struct Assign { diff --git a/xits-italic.otf b/xits-italic.otf deleted file mode 100644 index 0c9802a..0000000 Binary files a/xits-italic.otf and /dev/null differ