1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::os::raw::c_void;
use core_foundation::base::{CFRange, CFTypeID, TCFType};
use core_foundation::array::{CFArrayRef, CFArray};
use core_graphics::context::{CGContext, CGContextRef};
use core_graphics::geometry::CGPoint;
use core_graphics::path::{CGPath, SysCGPathRef};
use foreign_types::{ForeignType, ForeignTypeRef};
use crate::line::CTLine;
#[repr(C)]
pub struct __CTFrame(c_void);
pub type CTFrameRef = *const __CTFrame;
declare_TCFType! {
CTFrame, CTFrameRef
}
impl_TCFType!(CTFrame, CTFrameRef, CTFrameGetTypeID);
impl_CFTypeDescription!(CTFrame);
impl CTFrame {
pub fn get_path(&self) -> CGPath {
unsafe {
CGPath::from_ptr(CTFrameGetPath(self.as_concrete_TypeRef())).clone()
}
}
pub fn get_lines(&self) -> Vec<CTLine> {
unsafe {
let array_ref = CTFrameGetLines(self.as_concrete_TypeRef());
let array: CFArray<CTLine> = CFArray::wrap_under_get_rule(array_ref);
array.iter().map(|l| CTLine::wrap_under_get_rule(l.as_concrete_TypeRef())).collect()
}
}
pub fn get_line_origins(&self, range: impl Into<Option<CFRange>>) -> Vec<CGPoint> {
let range = range.into().unwrap_or_else(|| CFRange::init(0, 0));
let len = match range.length {
0 => unsafe {
let array_ref = CTFrameGetLines(self.as_concrete_TypeRef());
let array: CFArray<CTLine> = CFArray::wrap_under_get_rule(array_ref);
array.len() - range.location
}
n => n,
};
let len = len.max(0) as usize;
let mut out = vec![CGPoint::new(0., 0.); len];
unsafe {
CTFrameGetLineOrigins(self.as_concrete_TypeRef(), range, out.as_mut_ptr());
}
out
}
pub fn draw(&self, context: &CGContextRef) {
unsafe {
CTFrameDraw(self.as_concrete_TypeRef(), context.as_ptr());
}
}
}
#[link(name = "CoreText", kind = "framework")]
extern {
fn CTFrameGetTypeID() -> CFTypeID;
fn CTFrameGetLines(frame: CTFrameRef) -> CFArrayRef;
fn CTFrameDraw(frame: CTFrameRef, context: *mut <CGContext as ForeignType>::CType);
fn CTFrameGetLineOrigins(frame: CTFrameRef, range: CFRange, origins: *mut CGPoint);
fn CTFrameGetPath(frame: CTFrameRef) -> SysCGPathRef;
}