diff options
-rw-r--r-- | core/src/rectangle.rs | 13 | ||||
-rw-r--r-- | native/src/renderer/windowed.rs | 9 | ||||
-rw-r--r-- | wgpu/src/renderer.rs | 53 | ||||
-rw-r--r-- | wgpu/src/renderer/target.rs | 16 | ||||
-rw-r--r-- | wgpu/src/transformation.rs | 5 | ||||
-rw-r--r-- | winit/src/application.rs | 74 |
6 files changed, 112 insertions, 58 deletions
diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index 95c2570c..c3191677 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -28,3 +28,16 @@ impl Rectangle<f32> { && point.y <= self.y + self.height } } + +impl std::ops::Mul<f32> for Rectangle<u32> { + type Output = Self; + + fn mul(self, scale: f32) -> Self { + Self { + x: (self.x as f32 * scale).round() as u32, + y: (self.y as f32 * scale).round() as u32, + width: (self.width as f32 * scale).round() as u32, + height: (self.height as f32 * scale).round() as u32, + } + } +} diff --git a/native/src/renderer/windowed.rs b/native/src/renderer/windowed.rs index 6e4ae611..6d0419d2 100644 --- a/native/src/renderer/windowed.rs +++ b/native/src/renderer/windowed.rs @@ -22,8 +22,15 @@ pub trait Target { window: &W, width: u16, height: u16, + dpi: f32, renderer: &Self::Renderer, ) -> Self; - fn resize(&mut self, width: u16, height: u16, renderer: &Self::Renderer); + fn resize( + &mut self, + width: u16, + height: u16, + dpi: f32, + renderer: &Self::Renderer, + ); } diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 060f07a3..7ac74e93 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -98,6 +98,7 @@ impl Renderer { log::debug!("Drawing"); let (width, height) = target.dimensions(); + let dpi = target.dpi(); let transformation = target.transformation(); let frame = target.next_frame(); @@ -137,7 +138,7 @@ impl Renderer { self.draw_overlay(overlay, &mut layers); for layer in layers { - self.flush(transformation, &layer, &mut encoder, &frame.view); + self.flush(dpi, transformation, &layer, &mut encoder, &frame.view); } self.queue.submit(&[encoder.finish()]); @@ -190,7 +191,10 @@ impl Renderer { layer.text.push(Section { text: &content, - screen_position: (x, y), + screen_position: ( + x - layer.offset.x as f32, + y - layer.offset.y as f32, + ), bounds: (bounds.width, bounds.height), scale: wgpu_glyph::Scale { x: *size, y: *size }, color: color.into_linear(), @@ -225,6 +229,7 @@ impl Renderer { background, border_radius, } => { + // TODO: Move some of this computations to the GPU (?) layer.quads.push(Quad { position: [ bounds.x - layer.offset.x as f32, @@ -234,7 +239,7 @@ impl Renderer { color: match background { Background::Color(color) => color.into_linear(), }, - border_radius: u32::from(*border_radius), + border_radius: *border_radius as u32, }); } Primitive::Image { path, bounds } => { @@ -308,16 +313,13 @@ impl Renderer { fn flush( &mut self, + dpi: f32, transformation: Transformation, layer: &Layer, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, ) { - let translated = transformation - * Transformation::translate( - -(layer.offset.x as f32), - -(layer.offset.y as f32), - ); + let bounds = layer.bounds * dpi; if layer.quads.len() > 0 { self.quad_pipeline.draw( @@ -325,18 +327,25 @@ impl Renderer { encoder, &layer.quads, transformation, - layer.bounds, + bounds, target, ); } if layer.images.len() > 0 { + let translated = transformation + * Transformation::scale(dpi, dpi) + * Transformation::translate( + -(layer.offset.x as f32), + -(layer.offset.y as f32), + ); + self.image_pipeline.draw( &mut self.device, encoder, &layer.images, translated, - layer.bounds, + bounds, target, ); } @@ -345,6 +354,20 @@ impl Renderer { let mut glyph_brush = self.glyph_brush.borrow_mut(); for text in layer.text.iter() { + // Target physical coordinates directly to avoid blurry text + let text = Section { + screen_position: ( + text.screen_position.0 * dpi, + text.screen_position.1 * dpi, + ), + bounds: (text.bounds.0 * dpi, text.bounds.1 * dpi), + scale: wgpu_glyph::Scale { + x: text.scale.x * dpi, + y: text.scale.y * dpi, + }, + ..*text + }; + glyph_brush.queue(text); } @@ -353,12 +376,12 @@ impl Renderer { &mut self.device, encoder, target, - translated.into(), + transformation.into(), wgpu_glyph::Region { - x: layer.bounds.x, - y: layer.bounds.y, - width: layer.bounds.width, - height: layer.bounds.height, + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height, }, ) .expect("Draw text"); diff --git a/wgpu/src/renderer/target.rs b/wgpu/src/renderer/target.rs index d9d05bf0..eeeb629a 100644 --- a/wgpu/src/renderer/target.rs +++ b/wgpu/src/renderer/target.rs @@ -6,6 +6,7 @@ pub struct Target { surface: wgpu::Surface, width: u16, height: u16, + dpi: f32, transformation: Transformation, swap_chain: wgpu::SwapChain, } @@ -15,6 +16,10 @@ impl Target { (self.width, self.height) } + pub fn dpi(&self) -> f32 { + self.dpi + } + pub fn transformation(&self) -> Transformation { self.transformation } @@ -31,6 +36,7 @@ impl iced_native::renderer::Target for Target { window: &W, width: u16, height: u16, + dpi: f32, renderer: &Renderer, ) -> Target { let surface = wgpu::Surface::create(window); @@ -41,14 +47,22 @@ impl iced_native::renderer::Target for Target { surface, width, height, + dpi, transformation: Transformation::orthographic(width, height), swap_chain, } } - fn resize(&mut self, width: u16, height: u16, renderer: &Renderer) { + fn resize( + &mut self, + width: u16, + height: u16, + dpi: f32, + renderer: &Renderer, + ) { self.width = width; self.height = height; + self.dpi = dpi; self.transformation = Transformation::orthographic(width, height); self.swap_chain = new_swap_chain(&self.surface, width, height, &renderer.device); diff --git a/wgpu/src/transformation.rs b/wgpu/src/transformation.rs index b0d14cc8..52165387 100644 --- a/wgpu/src/transformation.rs +++ b/wgpu/src/transformation.rs @@ -26,6 +26,11 @@ impl Transformation { pub fn translate(x: f32, y: f32) -> Transformation { Transformation(Mat4::from_translation(Vec3::new(x, y, 0.0))) } + + /// Creates a scale transformation. + pub fn scale(x: f32, y: f32) -> Transformation { + Transformation(Mat4::from_scale(Vec3::new(x, y, 0.0))) + } } impl Mul for Transformation { diff --git a/winit/src/application.rs b/winit/src/application.rs index 5d1aae38..3b908189 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -38,20 +38,19 @@ pub trait Application { .build(&event_loop) .expect("Open window"); - let mut size: Size = window - .inner_size() - .to_physical(window.hidpi_factor()) - .into(); - let mut new_size: Option<Size> = None; + let dpi = window.hidpi_factor(); + let mut size = window.inner_size(); + let mut new_size: Option<winit::dpi::LogicalSize> = None; let mut renderer = Self::Renderer::new(); - let mut target = <Self::Renderer as Windowed>::Target::new( - &window, - size.width, - size.height, - &renderer, - ); + let mut target = { + let (width, height) = to_physical(size, dpi); + + <Self::Renderer as Windowed>::Target::new( + &window, width, height, dpi as f32, &renderer, + ) + }; debug.layout_started(); let user_interface = UserInterface::build( @@ -134,7 +133,15 @@ pub trait Application { debug.render_started(); if let Some(new_size) = new_size.take() { - target.resize(new_size.width, new_size.height, &renderer); + let dpi = window.hidpi_factor(); + let (width, height) = to_physical(new_size, dpi); + + target.resize( + width, + height, + window.hidpi_factor() as f32, + &renderer, + ); size = new_size; } @@ -160,13 +167,9 @@ pub trait Application { .. } => match window_event { WindowEvent::CursorMoved { position, .. } => { - // TODO: Remove when renderer supports HiDPI - let physical_position = - position.to_physical(window.hidpi_factor()); - events.push(Event::Mouse(mouse::Event::CursorMoved { - x: physical_position.x as f32, - y: physical_position.y as f32, + x: position.x as f32, + y: position.y as f32, })); } WindowEvent::MouseInput { button, state, .. } => { @@ -190,15 +193,11 @@ pub trait Application { )); } winit::event::MouseScrollDelta::PixelDelta(position) => { - // TODO: Remove when renderer supports HiDPI - let physical_position = - position.to_physical(window.hidpi_factor()); - events.push(Event::Mouse( mouse::Event::WheelScrolled { delta: mouse::ScrollDelta::Pixels { - x: physical_position.x as f32, - y: physical_position.y as f32, + x: position.x as f32, + y: position.y as f32, }, }, )); @@ -235,8 +234,7 @@ pub trait Application { *control_flow = ControlFlow::Exit; } WindowEvent::Resized(size) => { - new_size = - Some(size.to_physical(window.hidpi_factor()).into()); + new_size = Some(size.into()); log::debug!("Resized: {:?}", new_size); } @@ -249,24 +247,18 @@ pub trait Application { } } -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -struct Size { - width: u16, - height: u16, -} +fn to_physical(size: winit::dpi::LogicalSize, dpi: f64) -> (u16, u16) { + let physical_size = size.to_physical(dpi); -impl From<winit::dpi::PhysicalSize> for Size { - fn from(physical_size: winit::dpi::PhysicalSize) -> Self { - Self { - width: physical_size.width.round() as u16, - height: physical_size.height.round() as u16, - } - } + ( + physical_size.width.round() as u16, + physical_size.height.round() as u16, + ) } fn document<'a, Application>( application: &'a mut Application, - size: Size, + size: winit::dpi::LogicalSize, debug: &mut Debug, ) -> Element<'a, Application::Message, Application::Renderer> where @@ -278,8 +270,8 @@ where debug.view_finished(); Column::new() - .width(Length::Units(size.width)) - .height(Length::Units(size.height)) + .width(Length::Units(size.width.round() as u16)) + .height(Length::Units(size.height.round() as u16)) .push(view) .into() } |