softbuffer/src/cg.rs

61 lines
2.1 KiB
Rust
Raw Normal View History

2022-12-22 10:09:47 -08:00
use crate::SwBufError;
2022-12-22 12:35:18 -08:00
use core_graphics::base::{
kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault,
};
2022-01-19 11:59:43 +09:00
use core_graphics::color_space::CGColorSpace;
use core_graphics::data_provider::CGDataProvider;
use core_graphics::image::CGImage;
2022-12-22 12:35:18 -08:00
use raw_window_handle::AppKitWindowHandle;
2022-04-24 07:31:19 -07:00
2022-12-22 12:35:18 -08:00
use cocoa::appkit::{NSView, NSViewHeightSizable, NSViewWidthSizable, NSWindow};
use cocoa::base::{id, nil};
use cocoa::quartzcore::{CALayer, ContentsGravity};
2022-04-24 07:31:19 -07:00
use foreign_types::ForeignType;
2022-01-19 11:59:43 +09:00
use std::sync::Arc;
pub struct CGImpl {
2022-04-24 07:31:19 -07:00
layer: CALayer,
}
2022-01-19 11:59:43 +09:00
impl CGImpl {
pub unsafe fn new(handle: AppKitWindowHandle) -> Result<Self, SwBufError> {
let window = handle.ns_window as id;
2022-04-24 07:31:19 -07:00
let view = handle.ns_view as id;
let layer = CALayer::new();
2022-12-23 04:19:41 +01:00
unsafe {
let subview: id = NSView::alloc(nil).initWithFrame_(NSView::frame(view));
layer.set_contents_gravity(ContentsGravity::TopLeft);
layer.set_needs_display_on_bounds_change(false);
layer.set_contents_scale(window.backingScaleFactor());
subview.setLayer(layer.id());
subview.setAutoresizingMask_(NSViewWidthSizable | NSViewHeightSizable);
2022-12-23 04:19:41 +01:00
view.addSubview_(subview); // retains subview (+1) = 2
let _: () = msg_send![subview, release]; // releases subview (-1) = 1
}
2022-12-22 12:35:18 -08:00
Ok(Self { layer })
2022-01-19 11:59:43 +09:00
}
2022-12-22 10:09:47 -08:00
pub(crate) unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
2022-01-19 11:59:43 +09:00
let color_space = CGColorSpace::create_device_rgb();
2022-12-22 12:35:18 -08:00
let data =
2022-12-23 04:19:41 +01:00
unsafe { std::slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len() * 4) }
.to_vec();
let data_provider = CGDataProvider::from_buffer(Arc::new(data));
2022-01-19 11:59:43 +09:00
let image = CGImage::new(
width as usize,
height as usize,
8,
32,
(width * 4) as usize,
&color_space,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
&data_provider,
false,
kCGRenderingIntentDefault,
);
2022-12-23 04:19:41 +01:00
unsafe { self.layer.set_contents(image.as_ptr() as id) };
2022-01-19 11:59:43 +09:00
}
}