summaryrefslogtreecommitdiffstats
path: root/wgpu/src
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src')
-rw-r--r--wgpu/src/font.rs38
-rw-r--r--wgpu/src/lib.rs1
-rw-r--r--wgpu/src/renderer.rs134
-rw-r--r--wgpu/src/renderer/target.rs74
-rw-r--r--wgpu/src/renderer/widget.rs10
-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