1//! Macos screen have a y axis that goings up from the bottom of the screen and
2//! an origin at the bottom left of the main display.
3mod dispatcher;
4mod display;
5mod display_link;
6mod events;
7
8#[cfg(not(feature = "macos-blade"))]
9mod metal_atlas;
10#[cfg(not(feature = "macos-blade"))]
11pub mod metal_renderer;
12
13#[cfg(not(feature = "macos-blade"))]
14use metal_renderer as renderer;
15
16#[cfg(feature = "macos-blade")]
17use crate::platform::blade as renderer;
18
19mod open_type;
20mod platform;
21mod text_system;
22mod window;
23mod window_appearance;
24
25use crate::{px, size, DevicePixels, Pixels, Size};
26use cocoa::{
27 base::{id, nil},
28 foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
29};
30
31use objc::runtime::{BOOL, NO, YES};
32use std::ops::Range;
33
34pub(crate) use dispatcher::*;
35pub(crate) use display::*;
36pub(crate) use display_link::*;
37pub(crate) use platform::*;
38pub(crate) use text_system::*;
39pub(crate) use window::*;
40
41trait BoolExt {
42 fn to_objc(self) -> BOOL;
43}
44
45impl BoolExt for bool {
46 fn to_objc(self) -> BOOL {
47 if self {
48 YES
49 } else {
50 NO
51 }
52 }
53}
54
55#[repr(C)]
56#[derive(Copy, Clone, Debug)]
57struct NSRange {
58 pub location: NSUInteger,
59 pub length: NSUInteger,
60}
61
62impl NSRange {
63 fn invalid() -> Self {
64 Self {
65 location: NSNotFound as NSUInteger,
66 length: 0,
67 }
68 }
69
70 fn is_valid(&self) -> bool {
71 self.location != NSNotFound as NSUInteger
72 }
73
74 fn to_range(self) -> Option<Range<usize>> {
75 if self.is_valid() {
76 let start = self.location as usize;
77 let end = start + self.length as usize;
78 Some(start..end)
79 } else {
80 None
81 }
82 }
83}
84
85impl From<Range<usize>> for NSRange {
86 fn from(range: Range<usize>) -> Self {
87 NSRange {
88 location: range.start as NSUInteger,
89 length: range.len() as NSUInteger,
90 }
91 }
92}
93
94unsafe impl objc::Encode for NSRange {
95 fn encode() -> objc::Encoding {
96 let encoding = format!(
97 "{{NSRange={}{}}}",
98 NSUInteger::encode().as_str(),
99 NSUInteger::encode().as_str()
100 );
101 unsafe { objc::Encoding::from_str(&encoding) }
102 }
103}
104
105unsafe fn ns_string(string: &str) -> id {
106 NSString::alloc(nil).init_str(string).autorelease()
107}
108
109impl From<NSSize> for Size<Pixels> {
110 fn from(value: NSSize) -> Self {
111 Size {
112 width: px(value.width as f32),
113 height: px(value.height as f32),
114 }
115 }
116}
117
118impl From<NSRect> for Size<Pixels> {
119 fn from(rect: NSRect) -> Self {
120 let NSSize { width, height } = rect.size;
121 size(width.into(), height.into())
122 }
123}
124
125impl From<NSRect> for Size<DevicePixels> {
126 fn from(rect: NSRect) -> Self {
127 let NSSize { width, height } = rect.size;
128 size(DevicePixels(width as i32), DevicePixels(height as i32))
129 }
130}