diff options
Diffstat (limited to 'wgpu/src')
-rw-r--r-- | wgpu/src/font.rs | 38 | ||||
-rw-r--r-- | wgpu/src/lib.rs | 1 | ||||
-rw-r--r-- | wgpu/src/renderer.rs | 134 | ||||
-rw-r--r-- | wgpu/src/renderer/target.rs | 74 | ||||
-rw-r--r-- | wgpu/src/renderer/widget.rs | 10 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/button.rs (renamed from wgpu/src/renderer/button.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/checkbox.rs (renamed from wgpu/src/renderer/checkbox.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/column.rs (renamed from wgpu/src/renderer/column.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/image.rs (renamed from wgpu/src/renderer/image.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/radio.rs (renamed from wgpu/src/renderer/radio.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/row.rs (renamed from wgpu/src/renderer/row.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/scrollable.rs (renamed from wgpu/src/renderer/scrollable.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/slider.rs (renamed from wgpu/src/renderer/slider.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/text.rs (renamed from wgpu/src/renderer/text.rs) | 0 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/text_input.rs (renamed from wgpu/src/renderer/text_input.rs) | 0 |
15 files changed, 189 insertions, 68 deletions
diff --git a/wgpu/src/font.rs b/wgpu/src/font.rs new file mode 100644 index 00000000..9bba9b22 --- /dev/null +++ b/wgpu/src/font.rs @@ -0,0 +1,38 @@ +pub use font_kit::family_name::FamilyName as Family; + +pub struct Source { + raw: font_kit::source::SystemSource, +} + +impl Source { + pub fn new() -> Self { + Source { + raw: font_kit::source::SystemSource::new(), + } + } + + pub fn load(&self, families: &[Family]) -> Vec<u8> { + let font = self + .raw + .select_best_match( + families, + &font_kit::properties::Properties::default(), + ) + .expect("Find font"); + + match font { + font_kit::handle::Handle::Path { path, .. } => { + use std::io::Read; + + let mut buf = Vec::new(); + let mut reader = std::fs::File::open(path).expect("Read font"); + let _ = reader.read_to_end(&mut buf); + + buf + } + font_kit::handle::Handle::Memory { bytes, .. } => { + bytes.as_ref().clone() + } + } + } +} diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 01dc4c20..f504897d 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1,3 +1,4 @@ +mod font; mod image; mod primitive; mod quad; diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index ca4cbb58..f8b546b3 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -1,32 +1,24 @@ -use crate::{quad, Image, Primitive, Quad, Transformation}; +use crate::{font, quad, Image, Primitive, Quad, Transformation}; use iced_native::{ renderer::Debugger, renderer::Windowed, Background, Color, Layout, MouseCursor, Point, Rectangle, Vector, Widget, }; -use raw_window_handle::HasRawWindowHandle; use wgpu::{ Adapter, BackendBit, CommandEncoderDescriptor, Device, DeviceDescriptor, - Extensions, Limits, PowerPreference, Queue, RequestAdapterOptions, Surface, - SwapChain, SwapChainDescriptor, TextureFormat, TextureUsage, + Extensions, Limits, PowerPreference, Queue, RequestAdapterOptions, + TextureFormat, }; use wgpu_glyph::{GlyphBrush, GlyphBrushBuilder, Section}; use std::{cell::RefCell, rc::Rc}; -mod button; -mod checkbox; -mod column; -mod image; -mod radio; -mod row; -mod scrollable; -mod slider; -mod text; -mod text_input; +mod target; +mod widget; + +pub use target::Target; pub struct Renderer { - surface: Surface, device: Device, queue: Queue, quad_pipeline: quad::Pipeline, @@ -35,13 +27,6 @@ pub struct Renderer { glyph_brush: Rc<RefCell<GlyphBrush<'static, ()>>>, } -pub struct Target { - width: u16, - height: u16, - transformation: Transformation, - swap_chain: SwapChain, -} - pub struct Layer<'a> { bounds: Rectangle<u32>, offset: Vector<u32>, @@ -63,7 +48,7 @@ impl<'a> Layer<'a> { } impl Renderer { - fn new<W: HasRawWindowHandle>(window: &W) -> Self { + fn new() -> Self { let adapter = Adapter::request(&RequestAdapterOptions { power_preference: PowerPreference::LowPower, backends: BackendBit::all(), @@ -77,21 +62,21 @@ impl Renderer { limits: Limits { max_bind_groups: 2 }, }); - let surface = Surface::create(window); + // TODO: Font customization + let font_source = font::Source::new(); + let sans_serif_font = font_source.load(&[font::Family::SansSerif]); + let mono_font = font_source.load(&[font::Family::Monospace]); - // TODO: Think about font loading strategy - // Loading system fonts with fallback may be a good idea - let font: &[u8] = - include_bytes!("../../examples/resources/Roboto-Regular.ttf"); - - let glyph_brush = GlyphBrushBuilder::using_font_bytes(font) - .build(&mut device, TextureFormat::Bgra8UnormSrgb); + let glyph_brush = GlyphBrushBuilder::using_fonts_bytes(vec![ + sans_serif_font, + mono_font, + ]) + .build(&mut device, TextureFormat::Bgra8UnormSrgb); let quad_pipeline = quad::Pipeline::new(&mut device); let image_pipeline = crate::image::Pipeline::new(&mut device); Self { - surface, device, queue, quad_pipeline, @@ -101,32 +86,17 @@ impl Renderer { } } - fn target(&self, width: u16, height: u16) -> Target { - Target { - width, - height, - transformation: Transformation::orthographic(width, height), - swap_chain: self.device.create_swap_chain( - &self.surface, - &SwapChainDescriptor { - usage: TextureUsage::OUTPUT_ATTACHMENT, - format: TextureFormat::Bgra8UnormSrgb, - width: u32::from(width), - height: u32::from(height), - present_mode: wgpu::PresentMode::Vsync, - }, - ), - } - } - - fn draw( + fn draw<T: AsRef<str>>( &mut self, (primitive, mouse_cursor): &(Primitive, MouseCursor), + overlay: &[T], target: &mut Target, ) -> MouseCursor { log::debug!("Drawing"); - let frame = target.swap_chain.get_next_texture(); + let (width, height) = target.dimensions(); + let transformation = target.transformation(); + let frame = target.next_frame(); let mut encoder = self .device @@ -154,21 +124,17 @@ impl Renderer { Rectangle { x: 0, y: 0, - width: u32::from(target.width), - height: u32::from(target.height), + width: u32::from(width), + height: u32::from(height), }, Vector::new(0, 0), )); self.draw_primitive(primitive, &mut layers); + self.draw_overlay(overlay, &mut layers); for layer in layers { - self.flush( - target.transformation, - &layer, - &mut encoder, - &frame.view, - ); + self.flush(transformation, &layer, &mut encoder, &frame.view); } self.queue.submit(&[encoder.finish()]); @@ -302,6 +268,41 @@ impl Renderer { } } + fn draw_overlay<'a, T: AsRef<str>>( + &mut self, + lines: &'a [T], + layers: &mut Vec<Layer<'a>>, + ) { + let first = layers.first().unwrap(); + let mut overlay = Layer::new(first.bounds, 0); + + let font_id = + wgpu_glyph::FontId(self.glyph_brush.borrow().fonts().len() - 1); + let scale = wgpu_glyph::Scale { x: 20.0, y: 20.0 }; + + for (i, line) in lines.iter().enumerate() { + overlay.text.push(Section { + text: line.as_ref(), + screen_position: (11.0, 11.0 + 25.0 * i as f32), + color: [0.9, 0.9, 0.9, 1.0], + scale, + font_id, + ..Section::default() + }); + + overlay.text.push(Section { + text: line.as_ref(), + screen_position: (10.0, 10.0 + 25.0 * i as f32), + color: [0.0, 0.0, 0.0, 1.0], + scale, + font_id, + ..Section::default() + }); + } + + layers.push(overlay); + } + fn flush( &mut self, transformation: Transformation, @@ -369,20 +370,17 @@ impl iced_native::Renderer for Renderer { impl Windowed for Renderer { type Target = Target; - fn new<W: HasRawWindowHandle>(window: &W) -> Self { - Self::new(window) - } - - fn target(&self, width: u16, height: u16) -> Target { - self.target(width, height) + fn new() -> Self { + Self::new() } - fn draw( + fn draw<T: AsRef<str>>( &mut self, output: &Self::Output, + overlay: &[T], target: &mut Target, ) -> MouseCursor { - self.draw(output, target) + self.draw(output, overlay, target) } } diff --git a/wgpu/src/renderer/target.rs b/wgpu/src/renderer/target.rs new file mode 100644 index 00000000..d9d05bf0 --- /dev/null +++ b/wgpu/src/renderer/target.rs @@ -0,0 +1,74 @@ +use crate::{Renderer, Transformation}; + +use raw_window_handle::HasRawWindowHandle; + +pub struct Target { + surface: wgpu::Surface, + width: u16, + height: u16, + transformation: Transformation, + swap_chain: wgpu::SwapChain, +} + +impl Target { + pub fn dimensions(&self) -> (u16, u16) { + (self.width, self.height) + } + + pub fn transformation(&self) -> Transformation { + self.transformation + } + + pub fn next_frame(&mut self) -> wgpu::SwapChainOutput { + self.swap_chain.get_next_texture() + } +} + +impl iced_native::renderer::Target for Target { + type Renderer = Renderer; + + fn new<W: HasRawWindowHandle>( + window: &W, + width: u16, + height: u16, + renderer: &Renderer, + ) -> Target { + let surface = wgpu::Surface::create(window); + let swap_chain = + new_swap_chain(&surface, width, height, &renderer.device); + + Target { + surface, + width, + height, + transformation: Transformation::orthographic(width, height), + swap_chain, + } + } + + fn resize(&mut self, width: u16, height: u16, renderer: &Renderer) { + self.width = width; + self.height = height; + self.transformation = Transformation::orthographic(width, height); + self.swap_chain = + new_swap_chain(&self.surface, width, height, &renderer.device); + } +} + +fn new_swap_chain( + surface: &wgpu::Surface, + width: u16, + height: u16, + device: &wgpu::Device, +) -> wgpu::SwapChain { + device.create_swap_chain( + &surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: wgpu::TextureFormat::Bgra8UnormSrgb, + width: u32::from(width), + height: u32::from(height), + present_mode: wgpu::PresentMode::Vsync, + }, + ) +} diff --git a/wgpu/src/renderer/widget.rs b/wgpu/src/renderer/widget.rs new file mode 100644 index 00000000..52410bee --- /dev/null +++ b/wgpu/src/renderer/widget.rs @@ -0,0 +1,10 @@ +mod button; +mod checkbox; +mod column; +mod image; +mod radio; +mod row; +mod scrollable; +mod slider; +mod text; +mod text_input; diff --git a/wgpu/src/renderer/button.rs b/wgpu/src/renderer/widget/button.rs index ad2186d6..ad2186d6 100644 --- a/wgpu/src/renderer/button.rs +++ b/wgpu/src/renderer/widget/button.rs diff --git a/wgpu/src/renderer/checkbox.rs b/wgpu/src/renderer/widget/checkbox.rs index ea7a4c0b..ea7a4c0b 100644 --- a/wgpu/src/renderer/checkbox.rs +++ b/wgpu/src/renderer/widget/checkbox.rs diff --git a/wgpu/src/renderer/column.rs b/wgpu/src/renderer/widget/column.rs index cac6da77..cac6da77 100644 --- a/wgpu/src/renderer/column.rs +++ b/wgpu/src/renderer/widget/column.rs diff --git a/wgpu/src/renderer/image.rs b/wgpu/src/renderer/widget/image.rs index 0e312706..0e312706 100644 --- a/wgpu/src/renderer/image.rs +++ b/wgpu/src/renderer/widget/image.rs diff --git a/wgpu/src/renderer/radio.rs b/wgpu/src/renderer/widget/radio.rs index 97b4f70e..97b4f70e 100644 --- a/wgpu/src/renderer/radio.rs +++ b/wgpu/src/renderer/widget/radio.rs diff --git a/wgpu/src/renderer/row.rs b/wgpu/src/renderer/widget/row.rs index bbfef9a1..bbfef9a1 100644 --- a/wgpu/src/renderer/row.rs +++ b/wgpu/src/renderer/widget/row.rs diff --git a/wgpu/src/renderer/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index 360759a5..360759a5 100644 --- a/wgpu/src/renderer/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs diff --git a/wgpu/src/renderer/slider.rs b/wgpu/src/renderer/widget/slider.rs index 4ae3abc4..4ae3abc4 100644 --- a/wgpu/src/renderer/slider.rs +++ b/wgpu/src/renderer/widget/slider.rs diff --git a/wgpu/src/renderer/text.rs b/wgpu/src/renderer/widget/text.rs index 82f75f09..82f75f09 100644 --- a/wgpu/src/renderer/text.rs +++ b/wgpu/src/renderer/widget/text.rs diff --git a/wgpu/src/renderer/text_input.rs b/wgpu/src/renderer/widget/text_input.rs index cff8bf23..cff8bf23 100644 --- a/wgpu/src/renderer/text_input.rs +++ b/wgpu/src/renderer/widget/text_input.rs |