Skip to content

Commit 112e777

Browse files
committed
macOS: use a subview, improve image handling
1 parent 44d1aba commit 112e777

File tree

1 file changed

+15
-18
lines changed

1 file changed

+15
-18
lines changed

src/cg.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
33
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
44
use core_graphics::color_space::CGColorSpace;
55
use core_graphics::data_provider::CGDataProvider;
6-
use core_graphics::geometry::CGSize;
76
use core_graphics::image::CGImage;
87

9-
use cocoa::base::id;
8+
use cocoa::base::{id, nil};
9+
use cocoa::appkit::{NSView, NSViewWidthSizable, NSViewHeightSizable};
1010
use cocoa::quartzcore::{CALayer, ContentsGravity};
1111
use foreign_types::ForeignType;
1212

13+
use std::sync::Arc;
14+
1315
pub struct CGImpl {
1416
layer: CALayer,
1517
}
@@ -18,19 +20,25 @@ impl CGImpl {
1820
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
1921
let view = handle.ns_view as id;
2022
let layer = CALayer::new();
23+
let subview: id = NSView::alloc(nil).initWithFrame_(view.frame());
2124
layer.set_contents_gravity(ContentsGravity::TopLeft);
22-
let _: () = msg_send![view, setLayer:layer.clone()];
25+
layer.set_needs_display_on_bounds_change(false);
26+
subview.setLayer(layer.id());
27+
subview.setAutoresizingMask_(NSViewWidthSizable | NSViewHeightSizable);
28+
29+
view.addSubview_(subview); // retains subview (+1) = 2
30+
let _: () = msg_send![subview, release]; // releases subview (-1) = 1
2331
Ok(Self{layer})
2432
}
2533
}
2634

2735
impl GraphicsContextImpl for CGImpl {
2836
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
2937
let color_space = CGColorSpace::create_device_rgb();
30-
let slice = std::slice::from_raw_parts(
38+
let data = std::slice::from_raw_parts(
3139
buffer.as_ptr() as *const u8,
32-
buffer.len() * 4);
33-
let data_provider = CGDataProvider::from_slice(slice);
40+
buffer.len() * 4).to_vec();
41+
let data_provider = CGDataProvider::from_buffer(Arc::new(data));
3442
let image = CGImage::new(
3543
width as usize,
3644
height as usize,
@@ -43,17 +51,6 @@ impl GraphicsContextImpl for CGImpl {
4351
false,
4452
kCGRenderingIntentDefault,
4553
);
46-
47-
let size = CGSize::new(width as f64, height as f64);
48-
let rep: id = msg_send![class!(NSCGImageRep), alloc];
49-
let rep: id = msg_send![rep, initWithCGImage:image.as_ptr() size:size];
50-
51-
let nsimage: id = msg_send![class!(NSImage), alloc];
52-
let nsimage: id = msg_send![nsimage, initWithSize:size];
53-
let _: () = msg_send![nsimage, addRepresentation:rep];
54-
let _: () = msg_send![rep, release];
55-
56-
self.layer.set_contents(nsimage);
57-
let _: () = msg_send![nsimage, release];
54+
self.layer.set_contents(image.as_ptr() as id);
5855
}
5956
}

0 commit comments

Comments
 (0)