Skip to content

Commit

Permalink
mac: use a subview, improve image handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lunixbochs committed May 16, 2022
1 parent 44d1aba commit 30aacf9
Showing 1 changed file with 15 additions and 18 deletions.
33 changes: 15 additions & 18 deletions src/cg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -18,19 +20,25 @@ impl CGImpl {
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
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})
}
}

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,
Expand All @@ -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);
}
}

0 comments on commit 30aacf9

Please sign in to comment.