Add macOS support using Core Graphics
This commit is contained in:
parent
a23b7f9876
commit
7ff0d65793
3 changed files with 67 additions and 0 deletions
|
|
@ -16,6 +16,10 @@ x11-dl = "2.19.1"
|
|||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = "0.3.9"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-graphics = "0.22.3"
|
||||
objc = "0.2.7"
|
||||
|
||||
[dev-dependencies]
|
||||
winit = "0.26.1"
|
||||
image = "0.23.14"
|
||||
55
src/cg.rs
Normal file
55
src/cg.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use crate::{GraphicsContextImpl, SoftBufferError};
|
||||
use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
|
||||
use objc::runtime::Object;
|
||||
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
|
||||
use core_graphics::color_space::CGColorSpace;
|
||||
use core_graphics::context::CGContext;
|
||||
use core_graphics::data_provider::CGDataProvider;
|
||||
use core_graphics::geometry::{CGPoint, CGSize, CGRect};
|
||||
use core_graphics::image::CGImage;
|
||||
use core_graphics::sys;
|
||||
|
||||
pub struct CGImpl;
|
||||
|
||||
impl CGImpl {
|
||||
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
|
||||
let window = handle.ns_window as *mut Object;
|
||||
let cls = class!(NSGraphicsContext);
|
||||
let graphics_context: *mut Object = msg_send![cls, graphicsContextWithWindow:window];
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
impl GraphicsContextImpl for CGImpl {
|
||||
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 slice = std::slice::from_raw_parts(
|
||||
buffer.as_ptr() as *const u8,
|
||||
buffer.len() * 4);
|
||||
let data_provider = CGDataProvider::from_slice(slice);
|
||||
let image = CGImage::new(
|
||||
width as usize,
|
||||
height as usize,
|
||||
8,
|
||||
32,
|
||||
(width * 4) as usize,
|
||||
&color_space,
|
||||
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
|
||||
&data_provider,
|
||||
false,
|
||||
kCGRenderingIntentDefault,
|
||||
);
|
||||
let origin = CGPoint { x: 0f64, y: 0f64 };
|
||||
let size = CGSize { width: width as f64, height: height as f64 };
|
||||
let rect = CGRect { origin, size };
|
||||
context.draw_image(rect, &image);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[macro_use]
|
||||
extern crate objc;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win32;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod cg;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod x11;
|
||||
|
||||
|
|
@ -32,6 +38,8 @@ impl<W: HasRawWindowHandle> GraphicsContext<W> {
|
|||
RawWindowHandle::Xlib(xlib_handle) => Box::new(x11::X11Impl::new(xlib_handle)?),
|
||||
#[cfg(target_os = "windows")]
|
||||
RawWindowHandle::Win32(win32_handle) => Box::new(win32::Win32Impl::new(&win32_handle)?),
|
||||
#[cfg(target_os = "macos")]
|
||||
RawWindowHandle::AppKit(appkit_handle) => Box::new(cg::CGImpl::new(appkit_handle)?),
|
||||
unimplemented_handle_type => return Err(SoftBufferError::UnsupportedPlatform {
|
||||
window,
|
||||
human_readable_platform_name: window_handle_type_name(&unimplemented_handle_type),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue