1
1
use crate :: { GraphicsContextImpl , SoftBufferError } ;
2
2
use raw_window_handle:: { HasRawWindowHandle , AppKitHandle } ;
3
- use objc:: runtime:: Object ;
4
3
use core_graphics:: base:: { kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault} ;
5
4
use core_graphics:: color_space:: CGColorSpace ;
6
- use core_graphics:: context:: CGContext ;
7
5
use core_graphics:: data_provider:: CGDataProvider ;
8
- use core_graphics:: geometry:: { CGPoint , CGSize , CGRect } ;
6
+ use core_graphics:: geometry:: CGSize ;
9
7
use core_graphics:: image:: CGImage ;
10
- use core_graphics:: sys;
8
+
9
+ use cocoa:: base:: id;
10
+ use cocoa:: quartzcore:: CALayer ;
11
+ use foreign_types:: ForeignType ;
11
12
12
13
pub struct CGImpl {
13
- view : * mut Object ,
14
+ layer : CALayer ,
14
15
}
15
16
16
17
impl CGImpl {
17
18
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
- )
19
+ let view = handle. ns_view as id ;
20
+ let layer = CALayer :: new ( ) ;
21
+ let _: ( ) = msg_send ! [ view, setLayer: layer. clone( ) ] ;
22
+ Ok ( Self { layer} )
31
23
}
32
24
}
33
25
34
26
impl GraphicsContextImpl for CGImpl {
35
27
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
28
let color_space = CGColorSpace :: create_device_rgb ( ) ;
41
29
let slice = std:: slice:: from_raw_parts (
42
30
buffer. as_ptr ( ) as * const u8 ,
@@ -54,11 +42,17 @@ impl GraphicsContextImpl for CGImpl {
54
42
false ,
55
43
kCGRenderingIntentDefault,
56
44
) ;
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) ;
45
+
46
+ let size = CGSize :: new ( width as f64 , height as f64 ) ;
47
+ let rep: id = msg_send ! [ class!( NSCGImageRep ) , alloc] ;
48
+ let rep: id = msg_send ! [ rep, initWithCGImage: image. as_ptr( ) size: size] ;
49
+
50
+ let nsimage: id = msg_send ! [ class!( NSImage ) , alloc] ;
51
+ let nsimage: id = msg_send ! [ nsimage, initWithSize: size] ;
52
+ let _: ( ) = msg_send ! [ nsimage, addRepresentation: rep] ;
53
+ let _: ( ) = msg_send ! [ rep, release] ;
54
+
55
+ self . layer . set_contents ( nsimage) ;
56
+ let _: ( ) = msg_send ! [ nsimage, release] ;
63
57
}
64
58
}
0 commit comments