diff --git a/src/font.rs b/src/font.rs index 2ac91b5..8218449 100644 --- a/src/font.rs +++ b/src/font.rs @@ -17,7 +17,8 @@ use image::{Pixel, RgbaImage}; pub struct Font { fonts: Vec, layout: RefCell, - scale: f32, + size: f32, + scale: i32, glyph_cache: RefCell)>>, } @@ -49,11 +50,16 @@ impl Font { Ok(Font { fonts: font_data, layout: RefCell::new(Layout::new(CoordinateSystem::PositiveYDown)), - scale: size, + size, + scale: 1, glyph_cache: RefCell::new(HashMap::new()), }) } + pub fn set_scale(&mut self, scale: i32) { + self.scale = scale; + } + fn render_glyph(&self, conf: GlyphRasterConfig) -> (Metrics, Vec) { let mut glyph_cache = self.glyph_cache.borrow_mut(); if let Some(bitmap) = glyph_cache.get(&conf) { @@ -90,7 +96,7 @@ impl Font { } layout.append( &self.fonts, - &TextStyle::new(&c.to_string(), self.scale, font_index), + &TextStyle::new(&c.to_string(), self.size * self.scale as f32, font_index), ); } diff --git a/src/gui.rs b/src/gui.rs index f952ffc..123bcc3 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,4 +1,5 @@ use smithay_client_toolkit::{ + get_surface_scale_factor, reexports::{ calloop, client::protocol::{ @@ -25,7 +26,7 @@ use smithay_clipboard::Clipboard; use log::*; use std::cell::Cell; -use std::io::{BufWriter, ErrorKind, Seek, SeekFrom, Write}; +use std::io::{BufWriter, ErrorKind, Seek, Write}; use std::rc::Rc; use image::{Pixel, Rgba, RgbaImage}; @@ -92,7 +93,7 @@ impl Surface { layer_surface.ack_configure(serial); next_render_event_handle.set(Some(RenderEvent::Configure { width, height })); } - (_, _) => {} + _ => todo!(), } }); @@ -108,11 +109,11 @@ impl Surface { } } - pub fn draw(&mut self, mut image: RgbaImage) -> Result<(), std::io::Error> { + pub fn draw(&mut self, mut image: RgbaImage, scale: i32) -> Result<(), std::io::Error> { if let Some(pool) = self.pools.pool() { - let stride = 4 * self.dimensions.0 as i32; - let width = self.dimensions.0 as i32; - let height = self.dimensions.1 as i32; + let width = self.dimensions.0 as i32 * scale; + let height = self.dimensions.1 as i32 * scale; + let stride = 4 * width; // First make sure the pool is the right size pool.resize((stride * height) as usize)?; @@ -125,7 +126,7 @@ impl Surface { }); // Write the color to all bytes of the pool - pool.seek(SeekFrom::Start(0))?; + pool.rewind()?; { let mut writer = BufWriter::new(&mut *pool); writer.write_all(image.as_raw())?; @@ -134,8 +135,7 @@ impl Surface { // Attach the buffer to the surface and mark the entire surface as damaged self.surface.attach(Some(&buffer), 0, 0); - self.surface - .damage_buffer(0, 0, width as i32, height as i32); + self.surface.damage_buffer(0, 0, width, height); // Finally, commit the surface self.surface.commit(); @@ -147,6 +147,14 @@ impl Surface { )) } } + + pub fn get_scale(&self) -> i32 { + get_surface_scale_factor(&self.surface) + } + + pub fn set_scale(&mut self, scale: i32) { + self.surface.set_buffer_scale(scale); + } } impl Drop for Surface { diff --git a/src/main.rs b/src/main.rs index d1f2122..ae9eb51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -157,7 +157,8 @@ async fn run() -> Result>, Box> { match surface.next_render_event.take() { Some(RenderEvent::Closed) => break, Some(RenderEvent::Configure { width, height }) => { - need_redraw = surface.set_dimensions(width, height); + need_redraw = true; + surface.set_dimensions(width, height); } None => {} } @@ -232,18 +233,26 @@ async fn run() -> Result>, Box> { if need_redraw { need_redraw = false; - let mut img = ImageBuffer::from_pixel( - surface.dimensions.0, - surface.dimensions.1, - config.colors.background.to_rgba(), + // adjust all components for Hidpi + let scale = surface.get_scale(); + surface.set_scale(scale); + font.set_scale(scale); + let (width, height) = ( + surface.dimensions.0 * scale as u32, + surface.dimensions.1 * scale as u32, ); + let padding = config.padding * scale as u32; + let font_size = config.font_size * scale as f32; + + let mut img = + ImageBuffer::from_pixel(width, height, config.colors.background.to_rgba()); let prompt_width = if !config.prompt.is_empty() { let (width, _) = font.render( &config.prompt, &config.colors.prompt, &mut img, - config.padding, - config.padding, + padding, + padding, ); width } else { @@ -256,20 +265,13 @@ async fn run() -> Result>, Box> { } else { &config.colors.text_query }; - font.render( - query, - color, - &mut img, - config.padding + prompt_width, - config.padding, - ); + font.render(query, color, &mut img, padding + prompt_width, padding); } - let spacer = (1.5 * config.font_size) as u32; - let max_entries = ((surface.dimensions.1 - 2 * config.padding - spacer) as f32 - / (config.font_size * 1.2)) as usize; + let spacer = (1.5 * font_size) as u32; + let max_entries = ((height - 2 * padding - spacer) as f32 / (font_size * 1.2)) as usize; let offset = if selection > (max_entries / 2) { - (selection - max_entries / 2) as usize + selection - max_entries / 2 } else { 0 }; @@ -289,15 +291,12 @@ async fn run() -> Result>, Box> { &matched.name, color, &mut img, - config.padding, - (config.padding - + spacer - + (i - offset) as u32 * (config.font_size * 1.2) as u32) - as u32, + padding, + padding + spacer + (i - offset) as u32 * (font_size * 1.2) as u32, ); } - match surface.draw(img) { + match surface.draw(img, scale) { Ok(_) => {} Err(e) => { error!("{}", e);