diff options
Diffstat (limited to 'renderer')
| -rw-r--r-- | renderer/Cargo.toml | 8 | ||||
| -rw-r--r-- | renderer/src/backend.rs | 4 | ||||
| -rw-r--r-- | renderer/src/geometry.rs (renamed from renderer/src/widget/canvas.rs) | 23 | ||||
| -rw-r--r-- | renderer/src/geometry/cache.rs (renamed from renderer/src/widget/canvas/cache.rs) | 2 | ||||
| -rw-r--r-- | renderer/src/lib.rs | 13 | ||||
| -rw-r--r-- | renderer/src/widget/qr_code.rs | 301 | 
6 files changed, 13 insertions, 338 deletions
diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index 429b55c2..189f5309 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -6,8 +6,7 @@ edition = "2021"  [features]  image = ["iced_wgpu/image", "iced_tiny_skia/image"]  svg = ["iced_wgpu/svg", "iced_tiny_skia/svg"] -canvas = ["iced_wgpu/canvas", "iced_tiny_skia/canvas"] -qr_code = ["canvas", "qrcode"] +geometry = ["iced_wgpu/geometry", "iced_tiny_skia/geometry"]  tracing = ["iced_wgpu/tracing"]  [dependencies] @@ -31,8 +30,3 @@ iced_wgpu = { version = "0.9", path = "../wgpu" }  [target.'cfg(target_arch = "wasm32")'.dependencies]  iced_wgpu = { version = "0.9", path = "../wgpu", features = ["webgl"] } - -[dependencies.qrcode] -version = "0.12" -optional = true -default-features = false diff --git a/renderer/src/backend.rs b/renderer/src/backend.rs index 6c0b4e5c..b0a409dc 100644 --- a/renderer/src/backend.rs +++ b/renderer/src/backend.rs @@ -1,4 +1,4 @@ -use crate::{Font, Geometry, Point, Size}; +use crate::{Font, Point, Size};  use iced_graphics::backend;  use iced_graphics::text; @@ -12,8 +12,6 @@ pub enum Backend {  }  impl iced_graphics::Backend for Backend { -    type Geometry = Geometry; -      fn trim_measurements(&mut self) {          match self {              Self::Wgpu(backend) => backend.trim_measurements(), diff --git a/renderer/src/widget/canvas.rs b/renderer/src/geometry.rs index 35c8fff9..e491ea73 100644 --- a/renderer/src/widget/canvas.rs +++ b/renderer/src/geometry.rs @@ -2,22 +2,13 @@ mod cache;  pub use cache::Cache; -pub use iced_native::widget::canvas::event::{self, Event}; -pub use iced_native::widget::canvas::fill::{self, Fill}; -pub use iced_native::widget::canvas::gradient::{self, Gradient}; -pub use iced_native::widget::canvas::path::{self, Path}; -pub use iced_native::widget::canvas::stroke::{self, Stroke}; -pub use iced_native::widget::canvas::{ -    Canvas, Cursor, LineCap, LineDash, LineJoin, Program, Renderer, Style, Text, -}; +pub use iced_graphics::geometry::*;  use crate::{Backend, Point, Rectangle, Size, Vector}; -pub use crate::Geometry; -  pub enum Frame { -    Wgpu(iced_wgpu::canvas::Frame), -    TinySkia(iced_tiny_skia::canvas::Frame), +    Wgpu(iced_wgpu::geometry::Frame), +    TinySkia(iced_tiny_skia::geometry::Frame),  }  macro_rules! delegate { @@ -33,10 +24,10 @@ impl Frame {      pub fn new<Theme>(renderer: &crate::Renderer<Theme>, size: Size) -> Self {          match renderer.backend() {              Backend::Wgpu(_) => { -                Frame::Wgpu(iced_wgpu::canvas::Frame::new(size)) +                Frame::Wgpu(iced_wgpu::geometry::Frame::new(size))              }              Backend::TinySkia(_) => { -                Frame::TinySkia(iced_tiny_skia::canvas::Frame::new(size)) +                Frame::TinySkia(iced_tiny_skia::geometry::Frame::new(size))              }          }      } @@ -131,10 +122,10 @@ impl Frame {      pub fn with_clip(&mut self, region: Rectangle, f: impl FnOnce(&mut Frame)) {          let mut frame = match self {              Self::Wgpu(_) => { -                Self::Wgpu(iced_wgpu::canvas::Frame::new(region.size())) +                Self::Wgpu(iced_wgpu::geometry::Frame::new(region.size()))              }              Self::TinySkia(_) => Self::TinySkia( -                iced_tiny_skia::canvas::Frame::new(region.size()), +                iced_tiny_skia::geometry::Frame::new(region.size()),              ),          }; diff --git a/renderer/src/widget/canvas/cache.rs b/renderer/src/geometry/cache.rs index 7d6b4811..1f1febdd 100644 --- a/renderer/src/widget/canvas/cache.rs +++ b/renderer/src/geometry/cache.rs @@ -1,4 +1,4 @@ -use crate::widget::canvas::{Frame, Geometry}; +use crate::geometry::{Frame, Geometry};  use crate::{Primitive, Renderer, Size};  use std::cell::RefCell; diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index d9c85e82..aae3322d 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -1,6 +1,8 @@ -pub mod widget;  pub mod window; +#[cfg(feature = "geometry")] +pub mod geometry; +  mod backend;  mod settings; @@ -19,12 +21,3 @@ pub use iced_graphics::{  /// [`iced`]: https://github.com/iced-rs/iced  pub type Renderer<Theme = iced_native::Theme> =      iced_graphics::Renderer<Backend, Theme>; - -#[derive(Debug, Clone)] -pub struct Geometry(pub(crate) Primitive); - -impl From<Geometry> for Primitive { -    fn from(geometry: Geometry) -> Self { -        geometry.0 -    } -} diff --git a/renderer/src/widget/qr_code.rs b/renderer/src/widget/qr_code.rs deleted file mode 100644 index aae4ec88..00000000 --- a/renderer/src/widget/qr_code.rs +++ /dev/null @@ -1,301 +0,0 @@ -//! Encode and display information in a QR code. -use crate::widget::canvas; -use crate::Renderer; - -use iced_graphics::renderer; - -use iced_native::layout; -use iced_native::widget::Tree; -use iced_native::{ -    Color, Element, Layout, Length, Point, Rectangle, Size, Vector, Widget, -}; -use thiserror::Error; - -const DEFAULT_CELL_SIZE: u16 = 4; -const QUIET_ZONE: usize = 2; - -/// A type of matrix barcode consisting of squares arranged in a grid which -/// can be read by an imaging device, such as a camera. -#[derive(Debug)] -pub struct QRCode<'a> { -    state: &'a State, -    dark: Color, -    light: Color, -    cell_size: u16, -} - -impl<'a> QRCode<'a> { -    /// Creates a new [`QRCode`] with the provided [`State`]. -    pub fn new(state: &'a State) -> Self { -        Self { -            cell_size: DEFAULT_CELL_SIZE, -            dark: Color::BLACK, -            light: Color::WHITE, -            state, -        } -    } - -    /// Sets both the dark and light [`Color`]s of the [`QRCode`]. -    pub fn color(mut self, dark: Color, light: Color) -> Self { -        self.dark = dark; -        self.light = light; -        self -    } - -    /// Sets the size of the squares of the grid cell of the [`QRCode`]. -    pub fn cell_size(mut self, cell_size: u16) -> Self { -        self.cell_size = cell_size; -        self -    } -} - -impl<'a, Message, Theme> Widget<Message, Renderer<Theme>> for QRCode<'a> { -    fn width(&self) -> Length { -        Length::Shrink -    } - -    fn height(&self) -> Length { -        Length::Shrink -    } - -    fn layout( -        &self, -        _renderer: &Renderer<Theme>, -        _limits: &layout::Limits, -    ) -> layout::Node { -        let side_length = (self.state.width + 2 * QUIET_ZONE) as f32 -            * f32::from(self.cell_size); - -        layout::Node::new(Size::new(side_length, side_length)) -    } - -    fn draw( -        &self, -        _state: &Tree, -        renderer: &mut Renderer<Theme>, -        _theme: &Theme, -        _style: &renderer::Style, -        layout: Layout<'_>, -        _cursor_position: Point, -        _viewport: &Rectangle, -    ) { -        use iced_native::Renderer as _; - -        let bounds = layout.bounds(); -        let side_length = self.state.width + 2 * QUIET_ZONE; - -        // Reuse cache if possible -        let geometry = -            self.state.cache.draw(renderer, bounds.size(), |frame| { -                // Scale units to cell size -                frame.scale(f32::from(self.cell_size)); - -                // Draw background -                frame.fill_rectangle( -                    Point::ORIGIN, -                    Size::new(side_length as f32, side_length as f32), -                    self.light, -                ); - -                // Avoid drawing on the quiet zone -                frame.translate(Vector::new( -                    QUIET_ZONE as f32, -                    QUIET_ZONE as f32, -                )); - -                // Draw contents -                self.state -                    .contents -                    .iter() -                    .enumerate() -                    .filter(|(_, value)| **value == qrcode::Color::Dark) -                    .for_each(|(index, _)| { -                        let row = index / self.state.width; -                        let column = index % self.state.width; - -                        frame.fill_rectangle( -                            Point::new(column as f32, row as f32), -                            Size::UNIT, -                            self.dark, -                        ); -                    }); -            }); - -        let translation = Vector::new(bounds.x, bounds.y); - -        renderer.with_translation(translation, |renderer| { -            renderer.draw_primitive(geometry.0); -        }); -    } -} - -impl<'a, Message, Theme> From<QRCode<'a>> -    for Element<'a, Message, Renderer<Theme>> -{ -    fn from(qr_code: QRCode<'a>) -> Self { -        Self::new(qr_code) -    } -} - -/// The state of a [`QRCode`]. -/// -/// It stores the data that will be displayed. -#[derive(Debug)] -pub struct State { -    contents: Vec<qrcode::Color>, -    width: usize, -    cache: canvas::Cache, -} - -impl State { -    /// Creates a new [`State`] with the provided data. -    /// -    /// This method uses an [`ErrorCorrection::Medium`] and chooses the smallest -    /// size to display the data. -    pub fn new(data: impl AsRef<[u8]>) -> Result<Self, Error> { -        let encoded = qrcode::QrCode::new(data)?; - -        Ok(Self::build(encoded)) -    } - -    /// Creates a new [`State`] with the provided [`ErrorCorrection`]. -    pub fn with_error_correction( -        data: impl AsRef<[u8]>, -        error_correction: ErrorCorrection, -    ) -> Result<Self, Error> { -        let encoded = qrcode::QrCode::with_error_correction_level( -            data, -            error_correction.into(), -        )?; - -        Ok(Self::build(encoded)) -    } - -    /// Creates a new [`State`] with the provided [`Version`] and -    /// [`ErrorCorrection`]. -    pub fn with_version( -        data: impl AsRef<[u8]>, -        version: Version, -        error_correction: ErrorCorrection, -    ) -> Result<Self, Error> { -        let encoded = qrcode::QrCode::with_version( -            data, -            version.into(), -            error_correction.into(), -        )?; - -        Ok(Self::build(encoded)) -    } - -    fn build(encoded: qrcode::QrCode) -> Self { -        let width = encoded.width(); -        let contents = encoded.into_colors(); - -        Self { -            contents, -            width, -            cache: canvas::Cache::new(), -        } -    } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -/// The size of a [`QRCode`]. -/// -/// The higher the version the larger the grid of cells, and therefore the more -/// information the [`QRCode`] can carry. -pub enum Version { -    /// A normal QR code version. It should be between 1 and 40. -    Normal(u8), - -    /// A micro QR code version. It should be between 1 and 4. -    Micro(u8), -} - -impl From<Version> for qrcode::Version { -    fn from(version: Version) -> Self { -        match version { -            Version::Normal(v) => qrcode::Version::Normal(i16::from(v)), -            Version::Micro(v) => qrcode::Version::Micro(i16::from(v)), -        } -    } -} - -/// The error correction level. -/// -/// It controls the amount of data that can be damaged while still being able -/// to recover the original information. -/// -/// A higher error correction level allows for more corrupted data. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ErrorCorrection { -    /// Low error correction. 7% of the data can be restored. -    Low, -    /// Medium error correction. 15% of the data can be restored. -    Medium, -    /// Quartile error correction. 25% of the data can be restored. -    Quartile, -    /// High error correction. 30% of the data can be restored. -    High, -} - -impl From<ErrorCorrection> for qrcode::EcLevel { -    fn from(ec_level: ErrorCorrection) -> Self { -        match ec_level { -            ErrorCorrection::Low => qrcode::EcLevel::L, -            ErrorCorrection::Medium => qrcode::EcLevel::M, -            ErrorCorrection::Quartile => qrcode::EcLevel::Q, -            ErrorCorrection::High => qrcode::EcLevel::H, -        } -    } -} - -/// An error that occurred when building a [`State`] for a [`QRCode`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)] -pub enum Error { -    /// The data is too long to encode in a QR code for the chosen [`Version`]. -    #[error( -        "The data is too long to encode in a QR code for the chosen version" -    )] -    DataTooLong, - -    /// The chosen [`Version`] and [`ErrorCorrection`] combination is invalid. -    #[error( -        "The chosen version and error correction level combination is invalid." -    )] -    InvalidVersion, - -    /// One or more characters in the provided data are not supported by the -    /// chosen [`Version`]. -    #[error( -        "One or more characters in the provided data are not supported by the \ -        chosen version" -    )] -    UnsupportedCharacterSet, - -    /// The chosen ECI designator is invalid. A valid designator should be -    /// between 0 and 999999. -    #[error( -        "The chosen ECI designator is invalid. A valid designator should be \ -        between 0 and 999999." -    )] -    InvalidEciDesignator, - -    /// A character that does not belong to the character set was found. -    #[error("A character that does not belong to the character set was found")] -    InvalidCharacter, -} - -impl From<qrcode::types::QrError> for Error { -    fn from(error: qrcode::types::QrError) -> Self { -        use qrcode::types::QrError; - -        match error { -            QrError::DataTooLong => Error::DataTooLong, -            QrError::InvalidVersion => Error::InvalidVersion, -            QrError::UnsupportedCharacterSet => Error::UnsupportedCharacterSet, -            QrError::InvalidEciDesignator => Error::InvalidEciDesignator, -            QrError::InvalidCharacter => Error::InvalidCharacter, -        } -    } -}  | 
