use CALayer for macOS backend
This commit is contained in:
parent
75216061b7
commit
ba3b823e1c
2 changed files with 25 additions and 29 deletions
|
|
@ -26,7 +26,9 @@ x11-dl = "2.19.1"
|
||||||
winapi = "0.3.9"
|
winapi = "0.3.9"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
cocoa = "0.24.0"
|
||||||
core-graphics = "0.22.3"
|
core-graphics = "0.22.3"
|
||||||
|
foreign-types = "0.3.0"
|
||||||
objc = "0.2.7"
|
objc = "0.2.7"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
|
@ -49,4 +51,4 @@ features = ["jpeg"]
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||||
# Turn rayon back on everywhere else; creating the separate entry resets the features to default.
|
# Turn rayon back on everywhere else; creating the separate entry resets the features to default.
|
||||||
image = "0.23.14"
|
image = "0.23.14"
|
||||||
rayon = "1.5.1"
|
rayon = "1.5.1"
|
||||||
|
|
|
||||||
50
src/cg.rs
50
src/cg.rs
|
|
@ -1,42 +1,30 @@
|
||||||
use crate::{GraphicsContextImpl, SoftBufferError};
|
use crate::{GraphicsContextImpl, SoftBufferError};
|
||||||
use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
|
use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
|
||||||
use objc::runtime::Object;
|
|
||||||
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
|
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
|
||||||
use core_graphics::color_space::CGColorSpace;
|
use core_graphics::color_space::CGColorSpace;
|
||||||
use core_graphics::context::CGContext;
|
|
||||||
use core_graphics::data_provider::CGDataProvider;
|
use core_graphics::data_provider::CGDataProvider;
|
||||||
use core_graphics::geometry::{CGPoint, CGSize, CGRect};
|
use core_graphics::geometry::CGSize;
|
||||||
use core_graphics::image::CGImage;
|
use core_graphics::image::CGImage;
|
||||||
use core_graphics::sys;
|
|
||||||
|
use cocoa::base::id;
|
||||||
|
use cocoa::quartzcore::CALayer;
|
||||||
|
use foreign_types::ForeignType;
|
||||||
|
|
||||||
pub struct CGImpl {
|
pub struct CGImpl {
|
||||||
view: *mut Object,
|
layer: CALayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CGImpl {
|
impl CGImpl {
|
||||||
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
|
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
|
||||||
let window = handle.ns_window as *mut Object;
|
let view = handle.ns_view as id;
|
||||||
let view = handle.ns_view as *mut Object;
|
let layer = CALayer::new();
|
||||||
let cls = class!(NSGraphicsContext);
|
let _: () = msg_send![view, setLayer:layer.clone()];
|
||||||
let graphics_context: *mut Object = msg_send![cls, graphicsContextWithWindow:window];
|
Ok(Self{layer})
|
||||||
if graphics_context.is_null() {
|
|
||||||
return Err(SoftBufferError::PlatformError(Some("Graphics context is null".into()), None));
|
|
||||||
}
|
|
||||||
let _: () = msg_send![cls, setCurrentContext:graphics_context];
|
|
||||||
Ok(
|
|
||||||
Self {
|
|
||||||
view,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicsContextImpl for CGImpl {
|
impl GraphicsContextImpl for CGImpl {
|
||||||
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
|
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
|
||||||
let cls = class!(NSGraphicsContext);
|
|
||||||
let graphics_context: *mut Object = msg_send![cls, currentContext];
|
|
||||||
let context_ptr: *mut sys::CGContext = msg_send![graphics_context, CGContext];
|
|
||||||
let context = CGContext::from_existing_context_ptr(context_ptr);
|
|
||||||
let color_space = CGColorSpace::create_device_rgb();
|
let color_space = CGColorSpace::create_device_rgb();
|
||||||
let slice = std::slice::from_raw_parts(
|
let slice = std::slice::from_raw_parts(
|
||||||
buffer.as_ptr() as *const u8,
|
buffer.as_ptr() as *const u8,
|
||||||
|
|
@ -54,11 +42,17 @@ impl GraphicsContextImpl for CGImpl {
|
||||||
false,
|
false,
|
||||||
kCGRenderingIntentDefault,
|
kCGRenderingIntentDefault,
|
||||||
);
|
);
|
||||||
let frame: CGRect = msg_send![self.view, frame];
|
|
||||||
// In Core Graphics, (0, 0) is bottom left, not top left
|
let size = CGSize::new(width as f64, height as f64);
|
||||||
let origin = CGPoint { x: 0f64, y: frame.size.height };
|
let rep: id = msg_send![class!(NSCGImageRep), alloc];
|
||||||
let size = CGSize { width: width as f64, height: -(height as f64) };
|
let rep: id = msg_send![rep, initWithCGImage:image.as_ptr() size:size];
|
||||||
let rect = CGRect { origin, size };
|
|
||||||
context.draw_image(rect, &image);
|
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue