cache rendered chars
This commit is contained in:
		
							parent
							
								
									4eed089a06
								
							
						
					
					
						commit
						42042ec502
					
				
					 5 changed files with 46 additions and 28 deletions
				
			
		
							
								
								
									
										4
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1521,9 +1521,7 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "servicepoint" | ||||
| version = "0.15.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7d1e88713031e003dc3ee708dbb282e36714eee466a12d311d0e2e24c61c7118" | ||||
| version = "0.16.0" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "bzip2", | ||||
|  |  | |||
|  | @ -19,9 +19,6 @@ env_logger = "0.11" | |||
| clap = { version = "4.5", features = ["derive"] } | ||||
| thiserror = "2.0" | ||||
| 
 | ||||
| # package parsing | ||||
| servicepoint = { features = ["all_compressions"], version = "0.15.2" } | ||||
| 
 | ||||
| # font rendering | ||||
| font-kit = "0.14.2" | ||||
| # I should not need this as a direct dependency, but then I cannot spell the types needed to use font-kit... | ||||
|  | @ -32,6 +29,11 @@ winit = "0.30" | |||
| # for drawing pixels onto the surface of the window | ||||
| softbuffer = "0.4.6" | ||||
| 
 | ||||
| [dependencies.servicepoint] | ||||
| version = "0.16.0" | ||||
| features = ["all_compressions"] | ||||
| path = "../servicepoint-uniffi3" | ||||
| 
 | ||||
| [profile.release] | ||||
| lto = true          # Enable link-time optimization | ||||
| codegen-units = 1   # Reduce number of codegen units to increase optimizations | ||||
|  |  | |||
|  | @ -5,10 +5,11 @@ use crate::{ | |||
| }; | ||||
| use log::{debug, error, info, trace, warn}; | ||||
| use servicepoint::{ | ||||
|     BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, GlobalBrightnessCommand, | ||||
|     BrightnessGrid, BrightnessGridCommand, CharGridCommand, ClearCommand, | ||||
|     CompressionCode, Cp437GridCommand, FadeOutCommand, Grid, HardResetCommand, | ||||
|     Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, | ||||
|     BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, BrightnessGrid, | ||||
|     BrightnessGridCommand, CharGridCommand, ClearCommand, CompressionCode, | ||||
|     Cp437GridCommand, FadeOutCommand, GlobalBrightnessCommand, | ||||
|     HardResetCommand, Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, | ||||
|     TILE_SIZE, | ||||
| }; | ||||
| use std::{ | ||||
|     ops::{BitAnd, BitOr, BitXor}, | ||||
|  | @ -46,11 +47,11 @@ impl CommandExecute for BitmapCommand { | |||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let Self { | ||||
|             origin: | ||||
|             Origin { | ||||
|                 x: offset_x, | ||||
|                 y: offset_y, | ||||
|                 .. | ||||
|             }, | ||||
|                 Origin { | ||||
|                     x: offset_x, | ||||
|                     y: offset_y, | ||||
|                     .. | ||||
|                 }, | ||||
|             bitmap: pixels, | ||||
|             .. | ||||
|         } = self; | ||||
|  | @ -143,7 +144,7 @@ impl CommandExecute for Cp437GridCommand { | |||
|                     bitmap: context.cp437_font[char_code].clone(), | ||||
|                     compression: CompressionCode::default(), | ||||
|                 } | ||||
|                     .execute(context); | ||||
|                 .execute(context); | ||||
|                 match execute_result { | ||||
|                     Success => {} | ||||
|                     Failure => { | ||||
|  | @ -199,8 +200,14 @@ impl CommandExecute for CharGridCommand { | |||
| 
 | ||||
|                 if let Err(e) = context.font_renderer.render( | ||||
|                     char, | ||||
|                     &mut display, | ||||
|                     Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), | ||||
|                     &mut display | ||||
|                         .window_mut( | ||||
|                             tile_x * TILE_SIZE, | ||||
|                             tile_y * TILE_SIZE, | ||||
|                             TILE_SIZE, | ||||
|                             TILE_SIZE, | ||||
|                         ) | ||||
|                         .unwrap(), | ||||
|                 ) { | ||||
|                     error!( | ||||
|                         "stopping drawing text because char draw failed: {e}" | ||||
|  |  | |||
|  | @ -12,8 +12,11 @@ use pathfinder_geometry::{ | |||
|     transform2d::Transform2F, | ||||
|     vector::{vec2f, vec2i}, | ||||
| }; | ||||
| use servicepoint::{Bitmap, Grid, Origin, Pixels, TILE_SIZE}; | ||||
| use std::sync::{Mutex, MutexGuard}; | ||||
| use servicepoint::{Bitmap, GridMut, WindowMut, TILE_SIZE}; | ||||
| use std::{ | ||||
|     collections::HashMap, | ||||
|     sync::{Mutex, MutexGuard}, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| struct SendFont(Font); | ||||
|  | @ -32,6 +35,7 @@ pub struct FontRenderer8x8 { | |||
|     font: SendFont, | ||||
|     canvas: Mutex<Canvas>, | ||||
|     fallback_char: Option<u32>, | ||||
|     cache: Mutex<HashMap<char, Bitmap>>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, thiserror::Error)] | ||||
|  | @ -56,6 +60,7 @@ impl FontRenderer8x8 { | |||
|             font: SendFont(font), | ||||
|             fallback_char, | ||||
|             canvas: Mutex::new(canvas), | ||||
|             cache: Mutex::new(HashMap::new()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -74,9 +79,13 @@ impl FontRenderer8x8 { | |||
|     pub fn render( | ||||
|         &self, | ||||
|         char: char, | ||||
|         bitmap: &mut Bitmap, | ||||
|         offset: Origin<Pixels>, | ||||
|         target: &mut WindowMut<bool, Bitmap>, | ||||
|     ) -> Result<(), RenderError> { | ||||
|         let cache = &mut *self.cache.lock().unwrap(); | ||||
|         if let Some(drawn_char) = cache.get(&char) { | ||||
|             target.deref_assign(drawn_char); | ||||
|         } | ||||
| 
 | ||||
|         let glyph_id = self.get_glyph(char)?; | ||||
| 
 | ||||
|         let mut canvas = self.canvas.lock().unwrap(); | ||||
|  | @ -91,20 +100,21 @@ impl FontRenderer8x8 { | |||
|             RasterizationOptions::Bilevel, | ||||
|         )?; | ||||
| 
 | ||||
|         Self::copy_to_bitmap(canvas, bitmap, offset) | ||||
|         let mut bitmap = Bitmap::new(TILE_SIZE, TILE_SIZE).unwrap(); | ||||
|         Self::copy_to_bitmap(canvas, &mut bitmap)?; | ||||
|         target.deref_assign(&bitmap); | ||||
|         cache.insert(char, bitmap); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     fn copy_to_bitmap( | ||||
|         canvas: MutexGuard<Canvas>, | ||||
|         bitmap: &mut Bitmap, | ||||
|         offset: Origin<Pixels>, | ||||
|     ) -> Result<(), RenderError> { | ||||
|         for y in 0..TILE_SIZE { | ||||
|             for x in 0..TILE_SIZE { | ||||
|                 let canvas_val = canvas.pixels[x + y * TILE_SIZE] != 0; | ||||
|                 let bitmap_x = offset.x + x; | ||||
|                 let bitmap_y = offset.y + y; | ||||
|                 if !bitmap.set_optional(bitmap_x, bitmap_y, canvas_val) { | ||||
|                 if !bitmap.set_optional(x, y, canvas_val) { | ||||
|                     return Err(OutOfBounds(x, y)); | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ const PIXEL_HEIGHT_WITH_SPACERS: usize = | |||
|     PIXEL_HEIGHT + NUM_SPACERS * SPACER_HEIGHT; | ||||
| 
 | ||||
| const OFF_COLOR: u32 = u32::from_ne_bytes([0u8, 0, 0, 0]); | ||||
| const SPACER_COLOR: u32 = u32::from_ne_bytes([100u8, 100, 100, 0]); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum AppEvents { | ||||
|  | @ -61,7 +62,7 @@ impl<'t> Gui<'t> { | |||
|             if self.options.spacers && tile_y != 0 { | ||||
|                 // cannot just frame.skip(PIXEL_WIDTH as usize * SPACER_HEIGHT as usize) because of typing
 | ||||
|                 for _ in 0..PIXEL_WIDTH * SPACER_HEIGHT { | ||||
|                     frame.next().unwrap(); | ||||
|                     *frame.next().unwrap() = SPACER_COLOR; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter