Skip to content

Commit 55f5c79

Browse files
authored
Merge pull request #1 from sanxiyn/core-graphics
Add macOS support using Core Graphics
2 parents a23b7f9 + f5b18e8 commit 55f5c79

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ x11-dl = "2.19.1"
1616
[target.'cfg(target_os = "windows")'.dependencies]
1717
winapi = "0.3.9"
1818

19+
[target.'cfg(target_os = "macos")'.dependencies]
20+
core-graphics = "0.22.3"
21+
objc = "0.2.7"
22+
1923
[dev-dependencies]
2024
winit = "0.26.1"
2125
image = "0.23.14"

src/cg.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use crate::{GraphicsContextImpl, SoftBufferError};
2+
use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
3+
use objc::runtime::Object;
4+
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
5+
use core_graphics::color_space::CGColorSpace;
6+
use core_graphics::context::CGContext;
7+
use core_graphics::data_provider::CGDataProvider;
8+
use core_graphics::geometry::{CGPoint, CGSize, CGRect};
9+
use core_graphics::image::CGImage;
10+
use core_graphics::sys;
11+
12+
pub struct CGImpl {
13+
view: *mut Object,
14+
}
15+
16+
impl CGImpl {
17+
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
18+
let window = handle.ns_window as *mut Object;
19+
let view = handle.ns_view as *mut Object;
20+
let cls = class!(NSGraphicsContext);
21+
let graphics_context: *mut Object = msg_send![cls, graphicsContextWithWindow:window];
22+
if graphics_context.is_null() {
23+
return Err(SoftBufferError::PlatformError(Some("Graphics context is null".into()), None));
24+
}
25+
let _: () = msg_send![cls, setCurrentContext:graphics_context];
26+
Ok(
27+
Self {
28+
view,
29+
}
30+
)
31+
}
32+
}
33+
34+
impl GraphicsContextImpl for CGImpl {
35+
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
36+
let cls = class!(NSGraphicsContext);
37+
let graphics_context: *mut Object = msg_send![cls, currentContext];
38+
let context_ptr: *mut sys::CGContext = msg_send![graphics_context, CGContext];
39+
let context = CGContext::from_existing_context_ptr(context_ptr);
40+
let color_space = CGColorSpace::create_device_rgb();
41+
let slice = std::slice::from_raw_parts(
42+
buffer.as_ptr() as *const u8,
43+
buffer.len() * 4);
44+
let data_provider = CGDataProvider::from_slice(slice);
45+
let image = CGImage::new(
46+
width as usize,
47+
height as usize,
48+
8,
49+
32,
50+
(width * 4) as usize,
51+
&color_space,
52+
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
53+
&data_provider,
54+
false,
55+
kCGRenderingIntentDefault,
56+
);
57+
let frame: CGRect = msg_send![self.view, frame];
58+
// In Core Graphics, (0, 0) is bottom left, not top left
59+
let origin = CGPoint { x: 0f64, y: frame.size.height };
60+
let size = CGSize { width: width as f64, height: -(height as f64) };
61+
let rect = CGRect { origin, size };
62+
context.draw_image(rect, &image);
63+
}
64+
}

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
#![doc = include_str!("../README.md")]
22

3+
#[cfg(target_os = "macos")]
4+
#[macro_use]
5+
extern crate objc;
6+
37
#[cfg(target_os = "windows")]
48
mod win32;
9+
#[cfg(target_os = "macos")]
10+
mod cg;
511
#[cfg(target_os = "linux")]
612
mod x11;
713

@@ -32,6 +38,8 @@ impl<W: HasRawWindowHandle> GraphicsContext<W> {
3238
RawWindowHandle::Xlib(xlib_handle) => Box::new(x11::X11Impl::new(xlib_handle)?),
3339
#[cfg(target_os = "windows")]
3440
RawWindowHandle::Win32(win32_handle) => Box::new(win32::Win32Impl::new(&win32_handle)?),
41+
#[cfg(target_os = "macos")]
42+
RawWindowHandle::AppKit(appkit_handle) => Box::new(cg::CGImpl::new(appkit_handle)?),
3543
unimplemented_handle_type => return Err(SoftBufferError::UnsupportedPlatform {
3644
window,
3745
human_readable_platform_name: window_handle_type_name(&unimplemented_handle_type),

0 commit comments

Comments
 (0)