summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-05 19:22:51 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-05 19:22:51 +0200
commit5a5ca34b5fcab9266359d3f0885782969f8c058e (patch)
treef52480f601ed26b1ab0430a408227e44df717d7b /wgpu
parentae56edc8ccd3462766071cc00c12e92feccf1274 (diff)
downloadiced-5a5ca34b5fcab9266359d3f0885782969f8c058e.tar.gz
iced-5a5ca34b5fcab9266359d3f0885782969f8c058e.tar.bz2
iced-5a5ca34b5fcab9266359d3f0885782969f8c058e.zip
Modularize `iced_wgpu`
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/src/lib.rs359
-rw-r--r--wgpu/src/primitive.rs14
-rw-r--r--wgpu/src/renderer.rs167
-rw-r--r--wgpu/src/renderer/button.rs18
-rw-r--r--wgpu/src/renderer/checkbox.rs18
-rw-r--r--wgpu/src/renderer/column.rs22
-rw-r--r--wgpu/src/renderer/image.rs16
-rw-r--r--wgpu/src/renderer/radio.rs17
-rw-r--r--wgpu/src/renderer/row.rs22
-rw-r--r--wgpu/src/renderer/slider.rs17
-rw-r--r--wgpu/src/renderer/text.rs77
11 files changed, 394 insertions, 353 deletions
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index d8f727cd..9a2a336f 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -1,354 +1,7 @@
-use iced_native::{
- button, checkbox, column, image, radio, renderer::Debugger, row, slider,
- text, Button, Checkbox, Color, Column, Image, Layout, Node, Point, Radio,
- Rectangle, Row, Slider, Style, Text, Widget,
-};
+mod mouse_cursor;
+mod primitive;
+mod renderer;
-use raw_window_handle::HasRawWindowHandle;
-use wgpu::{
- Adapter, CommandEncoderDescriptor, Device, DeviceDescriptor, Extensions,
- Instance, Limits, PowerPreference, RequestAdapterOptions, Surface,
- SwapChain, SwapChainDescriptor, TextureFormat, TextureUsage,
-};
-use wgpu_glyph::{GlyphBrush, GlyphBrushBuilder, GlyphCruncher, Section};
-
-use std::f32;
-use std::{cell::RefCell, rc::Rc};
-
-pub struct Renderer {
- instance: Instance,
- surface: Surface,
- adapter: Adapter,
- device: Device,
- glyph_brush: Rc<RefCell<GlyphBrush<'static, ()>>>,
-}
-
-pub struct Target {
- width: u16,
- height: u16,
- swap_chain: SwapChain,
-}
-
-impl Renderer {
- pub fn new<W: HasRawWindowHandle>(window: &W) -> Self {
- let instance = Instance::new();
-
- let adapter = instance.request_adapter(&RequestAdapterOptions {
- power_preference: PowerPreference::LowPower,
- });
-
- let mut device = adapter.request_device(&DeviceDescriptor {
- extensions: Extensions {
- anisotropic_filtering: false,
- },
- limits: Limits { max_bind_groups: 1 },
- });
-
- let surface = instance.create_surface(window.raw_window_handle());
-
- let font: &[u8] =
- include_bytes!("../../examples/tour/resources/Roboto-Regular.ttf");
-
- let glyph_brush = GlyphBrushBuilder::using_font_bytes(font)
- .build(&mut device, TextureFormat::Bgra8UnormSrgb);
-
- Self {
- instance,
- surface,
- adapter,
- device,
- glyph_brush: Rc::new(RefCell::new(glyph_brush)),
- }
- }
-
- pub fn target(&self, width: u16, height: u16) -> Target {
- Target {
- 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,
- },
- ),
- }
- }
-
- pub fn draw(&mut self, target: &mut Target, primitive: &Primitive) {
- let frame = target.swap_chain.get_next_texture();
-
- let mut encoder = self
- .device
- .create_command_encoder(&CommandEncoderDescriptor { todo: 0 });
-
- let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
- attachment: &frame.view,
- resolve_target: None,
- load_op: wgpu::LoadOp::Clear,
- store_op: wgpu::StoreOp::Store,
- clear_color: wgpu::Color {
- r: 1.0,
- g: 1.0,
- b: 1.0,
- a: 1.0,
- },
- }],
- depth_stencil_attachment: None,
- });
-
- self.draw_primitive(primitive);
-
- self.glyph_brush
- .borrow_mut()
- .draw_queued(
- &mut self.device,
- &mut encoder,
- &frame.view,
- u32::from(target.width),
- u32::from(target.height),
- )
- .expect("Draw text");
-
- self.device.get_queue().submit(&[encoder.finish()]);
- }
-
- fn draw_primitive(&mut self, primitive: &Primitive) {
- match primitive {
- Primitive::None => {}
- Primitive::Group { primitives } => {
- for primitive in primitives {
- self.draw_primitive(primitive)
- }
- }
- Primitive::Text {
- content,
- bounds,
- size,
- } => self.glyph_brush.borrow_mut().queue(Section {
- text: &content,
- screen_position: (bounds.x, bounds.y),
- bounds: (bounds.width, bounds.height),
- scale: wgpu_glyph::Scale { x: *size, y: *size },
- ..Default::default()
- }),
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub enum Primitive {
- None,
- Group {
- primitives: Vec<Primitive>,
- },
- Text {
- content: String,
- bounds: Rectangle,
- size: f32,
- },
-}
-
-impl iced_native::Renderer for Renderer {
- type Primitive = Primitive;
-}
-
-impl column::Renderer for Renderer {
- fn draw<Message>(
- &mut self,
- column: &Column<'_, Message, Self>,
- layout: Layout<'_>,
- cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::Group {
- primitives: column
- .children
- .iter()
- .zip(layout.children())
- .map(|(child, layout)| {
- child.draw(self, layout, cursor_position)
- })
- .collect(),
- }
- }
-}
-
-impl row::Renderer for Renderer {
- fn draw<Message>(
- &mut self,
- row: &Row<'_, Message, Self>,
- layout: Layout<'_>,
- cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::Group {
- primitives: row
- .children
- .iter()
- .zip(layout.children())
- .map(|(child, layout)| {
- child.draw(self, layout, cursor_position)
- })
- .collect(),
- }
- }
-}
-
-impl text::Renderer for Renderer {
- fn node(&self, text: &Text) -> Node {
- let glyph_brush = self.glyph_brush.clone();
- let content = text.content.clone();
-
- // TODO: Investigate why stretch tries to measure this MANY times
- // with every ancestor's bounds.
- // Bug? Using the library wrong? I should probably open an issue on
- // the stretch repository.
- // I noticed that the first measure is the one that matters in
- // practice. Here, we use a RefCell to store the cached measurement.
- let measure = RefCell::new(None);
- let size = text.size.map(f32::from).unwrap_or(20.0);
-
- let style = Style::default().width(text.width);
-
- iced_native::Node::with_measure(style, move |bounds| {
- let mut measure = measure.borrow_mut();
-
- if measure.is_none() {
- let bounds = (
- match bounds.width {
- iced_native::Number::Undefined => f32::INFINITY,
- iced_native::Number::Defined(w) => w,
- },
- match bounds.height {
- iced_native::Number::Undefined => f32::INFINITY,
- iced_native::Number::Defined(h) => h,
- },
- );
-
- let text = Section {
- text: &content,
- scale: wgpu_glyph::Scale { x: size, y: size },
- bounds,
- ..Default::default()
- };
-
- let (width, height) = if let Some(bounds) =
- glyph_brush.borrow_mut().glyph_bounds(&text)
- {
- (bounds.width(), bounds.height())
- } else {
- (0.0, 0.0)
- };
-
- let size = iced_native::Size { width, height };
-
- // If the text has no width boundary we avoid caching as the
- // layout engine may just be measuring text in a row.
- if bounds.0 == f32::INFINITY {
- return size;
- } else {
- *measure = Some(size);
- }
- }
-
- measure.unwrap()
- })
- }
-
- fn draw(&mut self, text: &Text, layout: Layout<'_>) -> Self::Primitive {
- Primitive::Text {
- content: text.content.clone(),
- size: f32::from(text.size.unwrap_or(20)),
- bounds: layout.bounds(),
- }
- }
-}
-
-impl checkbox::Renderer for Renderer {
- fn node<Message>(&mut self, _checkbox: &Checkbox<Message>) -> Node {
- Node::new(Style::default())
- }
-
- fn draw<Message>(
- &mut self,
- _checkbox: &Checkbox<Message>,
- _layout: Layout<'_>,
- _cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::None
- }
-}
-
-impl radio::Renderer for Renderer {
- fn node<Message>(&mut self, _checkbox: &Radio<Message>) -> Node {
- Node::new(Style::default())
- }
-
- fn draw<Message>(
- &mut self,
- _radio: &Radio<Message>,
- _layout: Layout<'_>,
- _cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::None
- }
-}
-
-impl slider::Renderer for Renderer {
- fn node<Message>(&self, _slider: &Slider<Message>) -> Node {
- Node::new(Style::default())
- }
-
- fn draw<Message>(
- &mut self,
- _slider: &Slider<Message>,
- _layout: Layout<'_>,
- _cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::None
- }
-}
-
-impl image::Renderer<&str> for Renderer {
- fn node(&mut self, _image: &Image<&str>) -> Node {
- Node::new(Style::default())
- }
-
- fn draw(
- &mut self,
- _checkbox: &Image<&str>,
- _layout: Layout<'_>,
- ) -> Self::Primitive {
- Primitive::None
- }
-}
-
-impl button::Renderer for Renderer {
- fn node<Message>(&self, _button: &Button<Message>) -> Node {
- Node::new(Style::default())
- }
-
- fn draw<Message>(
- &mut self,
- _button: &Button<Message>,
- _layout: Layout<'_>,
- _cursor_position: Point,
- ) -> Self::Primitive {
- Primitive::None
- }
-}
-
-impl Debugger for Renderer {
- fn explain<Message>(
- &mut self,
- widget: &dyn Widget<Message, Self>,
- layout: Layout<'_>,
- cursor_position: Point,
- _color: Color,
- ) -> Self::Primitive {
- widget.draw(self, layout, cursor_position)
- }
-}
+pub use mouse_cursor::MouseCursor;
+pub use primitive::Primitive;
+pub use renderer::{Renderer, Target};
diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs
new file mode 100644
index 00000000..04b2e99f
--- /dev/null
+++ b/wgpu/src/primitive.rs
@@ -0,0 +1,14 @@
+use iced_native::Rectangle;
+
+#[derive(Debug, Clone)]
+pub enum Primitive {
+ None,
+ Group {
+ primitives: Vec<Primitive>,
+ },
+ Text {
+ content: String,
+ bounds: Rectangle,
+ size: f32,
+ },
+}
diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs
new file mode 100644
index 00000000..df8887e3
--- /dev/null
+++ b/wgpu/src/renderer.rs
@@ -0,0 +1,167 @@
+use crate::Primitive;
+use iced_native::{renderer::Debugger, Color, Layout, Point, Widget};
+
+use raw_window_handle::HasRawWindowHandle;
+use wgpu::{
+ Adapter, CommandEncoderDescriptor, Device, DeviceDescriptor, Extensions,
+ Instance, Limits, PowerPreference, RequestAdapterOptions, Surface,
+ SwapChain, SwapChainDescriptor, TextureFormat, TextureUsage,
+};
+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 slider;
+mod text;
+
+pub struct Renderer {
+ instance: Instance,
+ surface: Surface,
+ adapter: Adapter,
+ device: Device,
+ glyph_brush: Rc<RefCell<GlyphBrush<'static, ()>>>,
+}
+
+pub struct Target {
+ width: u16,
+ height: u16,
+ swap_chain: SwapChain,
+}
+
+impl Renderer {
+ pub fn new<W: HasRawWindowHandle>(window: &W) -> Self {
+ let instance = Instance::new();
+
+ let adapter = instance.request_adapter(&RequestAdapterOptions {
+ power_preference: PowerPreference::LowPower,
+ });
+
+ let mut device = adapter.request_device(&DeviceDescriptor {
+ extensions: Extensions {
+ anisotropic_filtering: false,
+ },
+ limits: Limits { max_bind_groups: 1 },
+ });
+
+ let surface = instance.create_surface(window.raw_window_handle());
+
+ // TODO: Think about font loading strategy
+ // Loading system fonts with fallback may be a good idea
+ let font: &[u8] =
+ include_bytes!("../../examples/tour/resources/Roboto-Regular.ttf");
+
+ let glyph_brush = GlyphBrushBuilder::using_font_bytes(font)
+ .build(&mut device, TextureFormat::Bgra8UnormSrgb);
+
+ Self {
+ instance,
+ surface,
+ adapter,
+ device,
+ glyph_brush: Rc::new(RefCell::new(glyph_brush)),
+ }
+ }
+
+ pub fn target(&self, width: u16, height: u16) -> Target {
+ Target {
+ 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,
+ },
+ ),
+ }
+ }
+
+ pub fn draw(&mut self, target: &mut Target, primitive: &Primitive) {
+ let frame = target.swap_chain.get_next_texture();
+
+ let mut encoder = self
+ .device
+ .create_command_encoder(&CommandEncoderDescriptor { todo: 0 });
+
+ let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+ color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
+ attachment: &frame.view,
+ resolve_target: None,
+ load_op: wgpu::LoadOp::Clear,
+ store_op: wgpu::StoreOp::Store,
+ clear_color: wgpu::Color {
+ r: 1.0,
+ g: 1.0,
+ b: 1.0,
+ a: 1.0,
+ },
+ }],
+ depth_stencil_attachment: None,
+ });
+
+ self.draw_primitive(primitive);
+
+ self.glyph_brush
+ .borrow_mut()
+ .draw_queued(
+ &mut self.device,
+ &mut encoder,
+ &frame.view,
+ u32::from(target.width),
+ u32::from(target.height),
+ )
+ .expect("Draw text");
+
+ self.device.get_queue().submit(&[encoder.finish()]);
+ }
+
+ fn draw_primitive(&mut self, primitive: &Primitive) {
+ match primitive {
+ Primitive::None => {}
+ Primitive::Group { primitives } => {
+ // TODO: Inspect a bit and regroup (?)
+ for primitive in primitives {
+ self.draw_primitive(primitive)
+ }
+ }
+ Primitive::Text {
+ content,
+ bounds,
+ size,
+ } => self.glyph_brush.borrow_mut().queue(Section {
+ text: &content,
+ screen_position: (bounds.x, bounds.y),
+ bounds: (bounds.width, bounds.height),
+ scale: wgpu_glyph::Scale { x: *size, y: *size },
+ ..Default::default()
+ }),
+ }
+ }
+}
+
+impl iced_native::Renderer for Renderer {
+ // TODO: Add `MouseCursor` here (?)
+ type Primitive = Primitive;
+}
+
+impl Debugger for Renderer {
+ fn explain<Message>(
+ &mut self,
+ widget: &dyn Widget<Message, Self>,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ _color: Color,
+ ) -> Self::Primitive {
+ // TODO: Include a bordered box to display layout bounds
+ widget.draw(self, layout, cursor_position)
+ }
+}
diff --git a/wgpu/src/renderer/button.rs b/wgpu/src/renderer/button.rs
new file mode 100644
index 00000000..24bc1de6
--- /dev/null
+++ b/wgpu/src/renderer/button.rs
@@ -0,0 +1,18 @@
+use crate::{Primitive, Renderer};
+use iced_native::{button, Button, Layout, Node, Point, Style};
+
+impl button::Renderer for Renderer {
+ fn node<Message>(&self, _button: &Button<Message>) -> Node {
+ Node::new(Style::default())
+ }
+
+ fn draw<Message>(
+ &mut self,
+ _button: &Button<Message>,
+ _layout: Layout<'_>,
+ _cursor_position: Point,
+ ) -> Self::Primitive {
+ // TODO
+ Primitive::None
+ }
+}
diff --git a/wgpu/src/renderer/checkbox.rs b/wgpu/src/renderer/checkbox.rs
new file mode 100644
index 00000000..c94a2157
--- /dev/null
+++ b/wgpu/src/renderer/checkbox.rs
@@ -0,0 +1,18 @@
+use crate::{Primitive, Renderer};
+use iced_native::{checkbox, Checkbox, Layout, Node, Point, Style};
+
+impl checkbox::Renderer for Renderer {
+ fn node<Message>(&mut self, _checkbox: &Checkbox<Message>) -> Node {
+ Node::new(Style::default())
+ }
+
+ fn draw<Message>(
+ &mut self,
+ _checkbox: &Checkbox<Message>,
+ _layout: Layout<'_>,
+ _cursor_position: Point,
+ ) -> Self::Primitive {
+ // TODO
+ Primitive::None
+ }
+}
diff --git a/wgpu/src/renderer/column.rs b/wgpu/src/renderer/column.rs
new file mode 100644
index 00000000..1b9adad6
--- /dev/null
+++ b/wgpu/src/renderer/column.rs
@@ -0,0 +1,22 @@
+use crate::{Primitive, Renderer};
+use iced_native::{column, Column, Layout, Point};
+
+impl column::Renderer for Renderer {
+ fn draw<Message>(
+ &mut self,
+ column: &Column<'_, Message, Self>,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Self::Primitive {
+ Primitive::Group {
+ primitives: column
+ .children
+ .iter()
+ .zip(layout.children())
+ .map(|(child, layout)| {
+ child.draw(self, layout, cursor_position)
+ })
+ .collect(),
+ }
+ }
+}
diff --git a/wgpu/src/renderer/image.rs b/wgpu/src/renderer/image.rs
new file mode 100644
index 00000000..6ff39d30
--- /dev/null
+++ b/wgpu/src/renderer/image.rs
@@ -0,0 +1,16 @@
+use crate::{Primitive, Renderer};
+use iced_native::{image, Image, Layout, Node, Style};
+
+impl image::Renderer<&str> for Renderer {
+ fn node(&mut self, _image: &Image<&str>) -> Node {
+ Node::new(Style::default())
+ }
+
+ fn draw(
+ &mut self,
+ _image: &Image<&str>,
+ _layout: Layout<'_>,
+ ) -> Self::Primitive {
+ Primitive::None
+ }
+}
diff --git a/wgpu/src/renderer/radio.rs b/wgpu/src/renderer/radio.rs
new file mode 100644
index 00000000..ce419ae0
--- /dev/null
+++ b/wgpu/src/renderer/radio.rs
@@ -0,0 +1,17 @@
+use crate::{Primitive, Renderer};
+use iced_native::{radio, Layout, Node, Point, Radio, Style};
+
+impl radio::Renderer for Renderer {
+ fn node<Message>(&mut self, _checkbox: &Radio<Message>) -> Node {
+ Node::new(Style::default())
+ }
+
+ fn draw<Message>(
+ &mut self,
+ _radio: &Radio<Message>,
+ _layout: Layout<'_>,
+ _cursor_position: Point,
+ ) -> Self::Primitive {
+ Primitive::None
+ }
+}
diff --git a/wgpu/src/renderer/row.rs b/wgpu/src/renderer/row.rs
new file mode 100644
index 00000000..be9e4ede
--- /dev/null
+++ b/wgpu/src/renderer/row.rs
@@ -0,0 +1,22 @@
+use crate::{Primitive, Renderer};
+use iced_native::{row, Layout, Point, Row};
+
+impl row::Renderer for Renderer {
+ fn draw<Message>(
+ &mut self,
+ row: &Row<'_, Message, Self>,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Self::Primitive {
+ Primitive::Group {
+ primitives: row
+ .children
+ .iter()
+ .zip(layout.children())
+ .map(|(child, layout)| {
+ child.draw(self, layout, cursor_position)
+ })
+ .collect(),
+ }
+ }
+}
diff --git a/wgpu/src/renderer/slider.rs b/wgpu/src/renderer/slider.rs
new file mode 100644
index 00000000..2e76022d
--- /dev/null
+++ b/wgpu/src/renderer/slider.rs
@@ -0,0 +1,17 @@
+use crate::{Primitive, Renderer};
+use iced_native::{slider, Layout, Node, Point, Slider, Style};
+
+impl slider::Renderer for Renderer {
+ fn node<Message>(&self, _slider: &Slider<Message>) -> Node {
+ Node::new(Style::default())
+ }
+
+ fn draw<Message>(
+ &mut self,
+ _slider: &Slider<Message>,
+ _layout: Layout<'_>,
+ _cursor_position: Point,
+ ) -> Self::Primitive {
+ Primitive::None
+ }
+}
diff --git a/wgpu/src/renderer/text.rs b/wgpu/src/renderer/text.rs
new file mode 100644
index 00000000..4434cc22
--- /dev/null
+++ b/wgpu/src/renderer/text.rs
@@ -0,0 +1,77 @@
+use crate::{Primitive, Renderer};
+use iced_native::{text, Layout, Node, Style, Text};
+
+use wgpu_glyph::{GlyphCruncher, Section};
+
+use std::cell::RefCell;
+use std::f32;
+
+impl text::Renderer for Renderer {
+ fn node(&self, text: &Text) -> Node {
+ let glyph_brush = self.glyph_brush.clone();
+ let content = text.content.clone();
+
+ // TODO: Investigate why stretch tries to measure this MANY times
+ // with every ancestor's bounds.
+ // Bug? Using the library wrong? I should probably open an issue on
+ // the stretch repository.
+ // I noticed that the first measure is the one that matters in
+ // practice. Here, we use a RefCell to store the cached measurement.
+ let measure = RefCell::new(None);
+ let size = text.size.map(f32::from).unwrap_or(20.0);
+
+ let style = Style::default().width(text.width);
+
+ iced_native::Node::with_measure(style, move |bounds| {
+ let mut measure = measure.borrow_mut();
+
+ if measure.is_none() {
+ let bounds = (
+ match bounds.width {
+ iced_native::Number::Undefined => f32::INFINITY,
+ iced_native::Number::Defined(w) => w,
+ },
+ match bounds.height {
+ iced_native::Number::Undefined => f32::INFINITY,
+ iced_native::Number::Defined(h) => h,
+ },
+ );
+
+ let text = Section {
+ text: &content,
+ scale: wgpu_glyph::Scale { x: size, y: size },
+ bounds,
+ ..Default::default()
+ };
+
+ let (width, height) = if let Some(bounds) =
+ glyph_brush.borrow_mut().glyph_bounds(&text)
+ {
+ (bounds.width(), bounds.height())
+ } else {
+ (0.0, 0.0)
+ };
+
+ let size = iced_native::Size { width, height };
+
+ // If the text has no width boundary we avoid caching as the
+ // layout engine may just be measuring text in a row.
+ if bounds.0 == f32::INFINITY {
+ return size;
+ } else {
+ *measure = Some(size);
+ }
+ }
+
+ measure.unwrap()
+ })
+ }
+
+ fn draw(&mut self, text: &Text, layout: Layout<'_>) -> Self::Primitive {
+ Primitive::Text {
+ content: text.content.clone(),
+ size: f32::from(text.size.unwrap_or(20)),
+ bounds: layout.bounds(),
+ }
+ }
+}