From 112e77717994bbd7b0c63c755e4082ca4cc336a6 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Mon, 16 May 2022 10:16:50 -0700 Subject: [PATCH] macOS: use a subview, improve image handling --- src/cg.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/cg.rs b/src/cg.rs index 1f6d10c..77e4dff 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -3,13 +3,15 @@ use raw_window_handle::{HasRawWindowHandle, AppKitHandle}; use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault}; use core_graphics::color_space::CGColorSpace; use core_graphics::data_provider::CGDataProvider; -use core_graphics::geometry::CGSize; use core_graphics::image::CGImage; -use cocoa::base::id; +use cocoa::base::{id, nil}; +use cocoa::appkit::{NSView, NSViewWidthSizable, NSViewHeightSizable}; use cocoa::quartzcore::{CALayer, ContentsGravity}; use foreign_types::ForeignType; +use std::sync::Arc; + pub struct CGImpl { layer: CALayer, } @@ -18,8 +20,14 @@ impl CGImpl { pub unsafe fn new(handle: AppKitHandle) -> Result> { let view = handle.ns_view as id; let layer = CALayer::new(); + let subview: id = NSView::alloc(nil).initWithFrame_(view.frame()); layer.set_contents_gravity(ContentsGravity::TopLeft); - let _: () = msg_send![view, setLayer:layer.clone()]; + layer.set_needs_display_on_bounds_change(false); + subview.setLayer(layer.id()); + subview.setAutoresizingMask_(NSViewWidthSizable | NSViewHeightSizable); + + view.addSubview_(subview); // retains subview (+1) = 2 + let _: () = msg_send![subview, release]; // releases subview (-1) = 1 Ok(Self{layer}) } } @@ -27,10 +35,10 @@ impl CGImpl { impl GraphicsContextImpl for CGImpl { unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) { let color_space = CGColorSpace::create_device_rgb(); - let slice = std::slice::from_raw_parts( + let data = std::slice::from_raw_parts( buffer.as_ptr() as *const u8, - buffer.len() * 4); - let data_provider = CGDataProvider::from_slice(slice); + buffer.len() * 4).to_vec(); + let data_provider = CGDataProvider::from_buffer(Arc::new(data)); let image = CGImage::new( width as usize, height as usize, @@ -43,17 +51,6 @@ impl GraphicsContextImpl for CGImpl { false, kCGRenderingIntentDefault, ); - - let size = CGSize::new(width as f64, height as f64); - let rep: id = msg_send![class!(NSCGImageRep), alloc]; - let rep: id = msg_send![rep, initWithCGImage:image.as_ptr() size:size]; - - let nsimage: id = msg_send![class!(NSImage), alloc]; - let nsimage: id = msg_send![nsimage, initWithSize:size]; - let _: () = msg_send![nsimage, addRepresentation:rep]; - let _: () = msg_send![rep, release]; - - self.layer.set_contents(nsimage); - let _: () = msg_send![nsimage, release]; + self.layer.set_contents(image.as_ptr() as id); } }