From 58e277d6c96942ab19b5160bdced010247e59530 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 3 Apr 2023 18:57:57 -0700 Subject: [PATCH] Use `NonZeroU32` for arguments to `Surface::resize` --- README.md | 8 +++++++- examples/animation.rs | 8 +++++++- examples/fruit.rs | 8 +++++++- examples/libxcb.rs | 8 +++++++- examples/rectangle.rs | 8 +++++++- examples/winit.rs | 8 +++++++- examples/winit_wrong_sized_buffer.rs | 6 +++++- src/cg.rs | 7 ++++--- src/error.rs | 6 +++++- src/lib.rs | 5 +++-- src/orbital.rs | 8 ++++---- src/wayland/mod.rs | 24 ++++++++++++++---------- src/web.rs | 10 +++++++++- src/win32.rs | 16 ++++++++-------- src/x11.rs | 20 ++++++++++++++------ 15 files changed, 108 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index e96e4026..135342b9 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ For now, the priority for new platforms is: Example == ```rust,no_run +use std::num::NonZeroU32; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -72,7 +73,12 @@ fn main() { let size = window.inner_size(); (size.width, size.height) }; - surface.resize(width, height).unwrap(); + surface + .resize( + NonZeroU32::new(width).unwrap(), + NonZeroU32::new(height).unwrap(), + ) + .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); for index in 0..(width * height) { diff --git a/examples/animation.rs b/examples/animation.rs index ddb9e1d0..f729a395 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -2,6 +2,7 @@ use instant::Instant; #[cfg(not(target_arch = "wasm32"))] use rayon::prelude::*; use std::f64::consts::PI; +use std::num::NonZeroU32; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -49,7 +50,12 @@ fn main() { let frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)]; - surface.resize(width, height).unwrap(); + surface + .resize( + NonZeroU32::new(width).unwrap(), + NonZeroU32::new(height).unwrap(), + ) + .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); buffer.copy_from_slice(frame); buffer.present().unwrap(); diff --git a/examples/fruit.rs b/examples/fruit.rs index 7c19928c..7e28e89c 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -1,4 +1,5 @@ use image::GenericImageView; +use std::num::NonZeroU32; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -35,7 +36,12 @@ fn main() { match event { Event::RedrawRequested(window_id) if window_id == window.id() => { - surface.resize(fruit.width(), fruit.height()).unwrap(); + surface + .resize( + NonZeroU32::new(fruit.width()).unwrap(), + NonZeroU32::new(fruit.height()).unwrap(), + ) + .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); let width = fruit.width() as usize; diff --git a/examples/libxcb.rs b/examples/libxcb.rs index 54e74b1e..4ea97b01 100644 --- a/examples/libxcb.rs +++ b/examples/libxcb.rs @@ -3,6 +3,7 @@ #[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))] mod example { use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle}; + use std::num::NonZeroU32; use x11rb::{ connection::Connection, protocol::{ @@ -98,7 +99,12 @@ mod example { match event { Event::Expose(_) => { // Draw a width x height red rectangle. - surface.resize(width.into(), height.into()).unwrap(); + surface + .resize( + NonZeroU32::new(width.into()).unwrap(), + NonZeroU32::new(height.into()).unwrap(), + ) + .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); buffer.fill(RED); buffer.present().unwrap(); diff --git a/examples/rectangle.rs b/examples/rectangle.rs index a8d1d6f5..5443d3b9 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -1,3 +1,4 @@ +use std::num::NonZeroU32; use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -57,7 +58,12 @@ fn main() { }; // Resize surface if needed - surface.resize(width, height).unwrap(); + surface + .resize( + NonZeroU32::new(width).unwrap(), + NonZeroU32::new(height).unwrap(), + ) + .unwrap(); // Draw something in the window let mut buffer = surface.buffer_mut().unwrap(); diff --git a/examples/winit.rs b/examples/winit.rs index 48b9d481..18aa2784 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -1,3 +1,4 @@ +use std::num::NonZeroU32; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -33,7 +34,12 @@ fn main() { (size.width, size.height) }; - surface.resize(width, height).unwrap(); + surface + .resize( + NonZeroU32::new(width).unwrap(), + NonZeroU32::new(height).unwrap(), + ) + .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); for index in 0..(width * height) { diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 017361bd..09aff57b 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -1,3 +1,4 @@ +use std::num::NonZeroU32; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; @@ -32,7 +33,10 @@ fn main() { match event { Event::RedrawRequested(window_id) if window_id == window.id() => { surface - .resize(BUFFER_WIDTH as u32, BUFFER_HEIGHT as u32) + .resize( + NonZeroU32::new(BUFFER_WIDTH as u32).unwrap(), + NonZeroU32::new(BUFFER_HEIGHT as u32).unwrap(), + ) .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); diff --git a/src/cg.rs b/src/cg.rs index 110848ba..fce628d6 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -12,6 +12,7 @@ use cocoa::base::{id, nil}; use cocoa::quartzcore::{transaction, CALayer, ContentsGravity}; use foreign_types::ForeignType; +use std::num::NonZeroU32; use std::sync::Arc; struct Buffer(Vec); @@ -56,9 +57,9 @@ impl CGImpl { }) } - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { - self.width = width; - self.height = height; + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { + self.width = width.get(); + self.height = height.get(); Ok(()) } diff --git a/src/error.rs b/src/error.rs index 03ec6d3e..f84c649d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use std::error::Error; +use std::num::NonZeroU32; use thiserror::Error; #[derive(Error, Debug)] @@ -29,7 +30,10 @@ pub enum SoftBufferError { IncompleteDisplayHandle, #[error("Surface size {width}x{height} out of range for backend.")] - SizeOutOfRange { width: u32, height: u32 }, + SizeOutOfRange { + width: NonZeroU32, + height: NonZeroU32, + }, #[error("Platform error")] PlatformError(Option, Option>), diff --git a/src/lib.rs b/src/lib.rs index fbc379f5..f7dadf63 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ mod error; mod util; use std::marker::PhantomData; +use std::num::NonZeroU32; use std::ops; #[cfg(any(wayland_platform, x11_platform))] use std::rc::Rc; @@ -76,7 +77,7 @@ macro_rules! make_dispatch { } impl SurfaceDispatch { - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { match self { $( $(#[$attr])* @@ -297,7 +298,7 @@ impl Surface { /// in the upper-left corner of the window. It is recommended in most production use cases /// to have the buffer fill the entire window. Use your windowing library to find the size /// of the window. - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { self.surface_impl.resize(width, height) } diff --git a/src/orbital.rs b/src/orbital.rs index 35b79bd4..f999b6a9 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -1,5 +1,5 @@ use raw_window_handle::OrbitalWindowHandle; -use std::{cmp, slice, str}; +use std::{cmp, num::NonZeroU32, slice, str}; use crate::SoftBufferError; @@ -68,9 +68,9 @@ impl OrbitalImpl { }) } - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { - self.width = width; - self.height = height; + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { + self.width = width.get(); + self.height = height.get(); Ok(()) } diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 9814b750..2b95fd6f 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -1,6 +1,10 @@ use crate::{error::unwrap, util, SoftBufferError}; use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle}; -use std::{cell::RefCell, num::NonZeroI32, rc::Rc}; +use std::{ + cell::RefCell, + num::{NonZeroI32, NonZeroU32}, + rc::Rc, +}; use wayland_client::{ backend::{Backend, ObjectId}, globals::{registry_queue_init, GlobalListContents}, @@ -77,11 +81,11 @@ impl WaylandImpl { }) } - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { self.size = Some( (|| { - let width = NonZeroI32::new(i32::try_from(width).ok()?)?; - let height = NonZeroI32::new(i32::try_from(height).ok()?)?; + let width = NonZeroI32::try_from(width).ok()?; + let height = NonZeroI32::try_from(height).ok()?; Some((width, height)) })() .ok_or(SoftBufferError::SizeOutOfRange { width, height })?, @@ -109,20 +113,20 @@ impl WaylandImpl { } // Resize, if buffer isn't large enough - back.resize(width.into(), height.into()); + back.resize(width.get(), height.get()); } else { // Allocate front and back buffer self.buffers = Some(( WaylandBuffer::new( &self.display.shm, - width.into(), - height.into(), + width.get(), + height.get(), &self.display.qh, ), WaylandBuffer::new( &self.display.shm, - width.into(), - height.into(), + width.get(), + height.get(), &self.display.qh, ), )); @@ -177,7 +181,7 @@ impl<'a> BufferImpl<'a> { imp.surface.damage(0, 0, i32::MAX, i32::MAX); } else { // Introduced in version 4, it is an error to use this request in version 3 or lower. - imp.surface.damage_buffer(0, 0, width.into(), height.into()); + imp.surface.damage_buffer(0, 0, width.get(), height.get()); } imp.surface.commit(); diff --git a/src/web.rs b/src/web.rs index a3c9068f..49df5e79 100644 --- a/src/web.rs +++ b/src/web.rs @@ -11,6 +11,7 @@ use web_sys::ImageData; use crate::SoftBufferError; use std::convert::TryInto; +use std::num::NonZeroU32; /// Display implementation for the web platform. /// @@ -96,7 +97,14 @@ impl WebImpl { } /// Resize the canvas to the given dimensions. - pub(crate) fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub(crate) fn resize( + &mut self, + width: NonZeroU32, + height: NonZeroU32, + ) -> Result<(), SoftBufferError> { + let width = width.get(); + let height = height.get(); + self.buffer.resize(total_len(width, height), 0); self.canvas.set_width(width); self.canvas.set_height(height); diff --git a/src/win32.rs b/src/win32.rs index f1b6dba6..8d9a3501 100644 --- a/src/win32.rs +++ b/src/win32.rs @@ -7,7 +7,7 @@ use raw_window_handle::Win32WindowHandle; use std::io; use std::mem; -use std::num::NonZeroI32; +use std::num::{NonZeroI32, NonZeroU32}; use std::ptr::{self, NonNull}; use std::slice; @@ -47,8 +47,8 @@ impl Buffer { let bitmap_info = BitmapInfo { bmi_header: Gdi::BITMAPINFOHEADER { biSize: mem::size_of::() as u32, - biWidth: width.into(), - biHeight: -i32::from(height), + biWidth: width.get(), + biHeight: -height.get(), biPlanes: 1, biBitCount: 32, biCompression: Gdi::BI_BITFIELDS, @@ -164,10 +164,10 @@ impl Win32Impl { }) } - pub fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { let (width, height) = (|| { - let width = NonZeroI32::new(i32::try_from(width).ok()?)?; - let height = NonZeroI32::new(i32::try_from(height).ok()?)?; + let width = NonZeroI32::new(i32::try_from(width.get()).ok()?)?; + let height = NonZeroI32::new(i32::try_from(height.get()).ok()?)?; Some((width, height)) })() .ok_or(SoftBufferError::SizeOutOfRange { width, height })?; @@ -215,8 +215,8 @@ impl<'a> BufferImpl<'a> { imp.dc, 0, 0, - buffer.width.into(), - buffer.height.into(), + buffer.width.get(), + buffer.height.get(), buffer.dc, 0, 0, diff --git a/src/x11.rs b/src/x11.rs index cf8e2b24..1f5386f7 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -9,7 +9,7 @@ use crate::{util, SoftBufferError}; use nix::libc::{shmat, shmctl, shmdt, shmget, IPC_PRIVATE, IPC_RMID}; use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle}; use std::ptr::{null_mut, NonNull}; -use std::{fmt, io, mem, rc::Rc}; +use std::{fmt, io, mem, num::NonZeroU32, rc::Rc}; use x11_dl::xlib::Display; use x11_dl::xlib_xcb::Xlib_xcb; @@ -230,7 +230,11 @@ impl X11Impl { } /// Resize the internal buffer to the given width and height. - pub(crate) fn resize(&mut self, width: u32, height: u32) -> Result<(), SoftBufferError> { + pub(crate) fn resize( + &mut self, + width: NonZeroU32, + height: NonZeroU32, + ) -> Result<(), SoftBufferError> { log::trace!( "resize: window={:X}, size={}x{}", self.window, @@ -240,12 +244,16 @@ impl X11Impl { // Width and height should fit in u16. let width: u16 = width + .get() .try_into() .or(Err(SoftBufferError::SizeOutOfRange { width, height }))?; - let height: u16 = height.try_into().or(Err(SoftBufferError::SizeOutOfRange { - width: width.into(), - height, - }))?; + let height: u16 = height + .get() + .try_into() + .or(Err(SoftBufferError::SizeOutOfRange { + width: NonZeroU32::new(width.into()).unwrap(), + height, + }))?; if width != self.width || height != self.height { self.buffer