core_text/
framesetter.rs

1// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10use super::frame::{CTFrame, CTFrameRef};
11use core_foundation::attributed_string::CFAttributedStringRef;
12use core_foundation::base::{CFRange, CFTypeID, TCFType};
13use core_foundation::dictionary::CFDictionaryRef;
14use core_foundation::{declare_TCFType, impl_CFTypeDescription, impl_TCFType};
15use core_graphics::geometry::CGSize;
16use core_graphics::path::{CGPath, CGPathRef};
17use foreign_types::{ForeignType, ForeignTypeRef};
18use std::ptr::null;
19
20#[repr(C)]
21pub struct __CTFramesetter(core::ffi::c_void);
22
23pub type CTFramesetterRef = *const __CTFramesetter;
24
25declare_TCFType! {
26    CTFramesetter, CTFramesetterRef
27}
28impl_TCFType!(CTFramesetter, CTFramesetterRef, CTFramesetterGetTypeID);
29impl_CFTypeDescription!(CTFramesetter);
30
31impl CTFramesetter {
32    pub fn new_with_attributed_string(string: CFAttributedStringRef) -> Self {
33        unsafe {
34            let ptr = CTFramesetterCreateWithAttributedString(string);
35            CTFramesetter::wrap_under_create_rule(ptr)
36        }
37    }
38
39    pub fn create_frame(&self, string_range: CFRange, path: &CGPathRef) -> CTFrame {
40        unsafe {
41            let ptr = CTFramesetterCreateFrame(
42                self.as_concrete_TypeRef(),
43                string_range,
44                path.as_ptr(),
45                null(),
46            );
47
48            CTFrame::wrap_under_create_rule(ptr)
49        }
50    }
51
52    /// Suggest an appropriate frame size for displaying a text range.
53    ///
54    /// Returns a tuple containing an appropriate size (that should be smaller
55    /// than the provided constraints) as well as the range of text that fits in
56    /// this frame.
57    pub fn suggest_frame_size_with_constraints(
58        &self,
59        string_range: CFRange,
60        frame_attributes: CFDictionaryRef,
61        constraints: CGSize,
62    ) -> (CGSize, CFRange) {
63        unsafe {
64            let mut fit_range = CFRange::init(0, 0);
65            let size = CTFramesetterSuggestFrameSizeWithConstraints(
66                self.as_concrete_TypeRef(),
67                string_range,
68                frame_attributes,
69                constraints,
70                &mut fit_range,
71            );
72            (size, fit_range)
73        }
74    }
75}
76
77#[cfg_attr(feature = "link", link(name = "CoreText", kind = "framework"))]
78extern "C" {
79    fn CTFramesetterGetTypeID() -> CFTypeID;
80    fn CTFramesetterCreateWithAttributedString(string: CFAttributedStringRef) -> CTFramesetterRef;
81    fn CTFramesetterCreateFrame(
82        framesetter: CTFramesetterRef,
83        string_range: CFRange,
84        path: *mut <CGPath as ForeignType>::CType,
85        attributes: *const core::ffi::c_void,
86    ) -> CTFrameRef;
87    fn CTFramesetterSuggestFrameSizeWithConstraints(
88        framesetter: CTFramesetterRef,
89        string_range: CFRange,
90        frame_attributes: CFDictionaryRef,
91        constraints: CGSize,
92        fitRange: *mut CFRange,
93    ) -> CGSize;
94}