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::os::raw::c_void;
19use std::ptr::null;
20
21#[repr(C)]
22pub struct __CTFramesetter(c_void);
23
24pub type CTFramesetterRef = *const __CTFramesetter;
25
26declare_TCFType! {
27    CTFramesetter, CTFramesetterRef
28}
29impl_TCFType!(CTFramesetter, CTFramesetterRef, CTFramesetterGetTypeID);
30impl_CFTypeDescription!(CTFramesetter);
31
32impl CTFramesetter {
33    pub fn new_with_attributed_string(string: CFAttributedStringRef) -> Self {
34        unsafe {
35            let ptr = CTFramesetterCreateWithAttributedString(string);
36            CTFramesetter::wrap_under_create_rule(ptr)
37        }
38    }
39
40    pub fn create_frame(&self, string_range: CFRange, path: &CGPathRef) -> CTFrame {
41        unsafe {
42            let ptr = CTFramesetterCreateFrame(
43                self.as_concrete_TypeRef(),
44                string_range,
45                path.as_ptr(),
46                null(),
47            );
48
49            CTFrame::wrap_under_create_rule(ptr)
50        }
51    }
52
53    /// Suggest an appropriate frame size for displaying a text range.
54    ///
55    /// Returns a tuple containing an appropriate size (that should be smaller
56    /// than the provided constraints) as well as the range of text that fits in
57    /// this frame.
58    pub fn suggest_frame_size_with_constraints(
59        &self,
60        string_range: CFRange,
61        frame_attributes: CFDictionaryRef,
62        constraints: CGSize,
63    ) -> (CGSize, CFRange) {
64        unsafe {
65            let mut fit_range = CFRange::init(0, 0);
66            let size = CTFramesetterSuggestFrameSizeWithConstraints(
67                self.as_concrete_TypeRef(),
68                string_range,
69                frame_attributes,
70                constraints,
71                &mut fit_range,
72            );
73            (size, fit_range)
74        }
75    }
76}
77
78#[cfg_attr(feature = "link", link(name = "CoreText", kind = "framework"))]
79extern "C" {
80    fn CTFramesetterGetTypeID() -> CFTypeID;
81    fn CTFramesetterCreateWithAttributedString(string: CFAttributedStringRef) -> CTFramesetterRef;
82    fn CTFramesetterCreateFrame(
83        framesetter: CTFramesetterRef,
84        string_range: CFRange,
85        path: *mut <CGPath as ForeignType>::CType,
86        attributes: *const c_void,
87    ) -> CTFrameRef;
88    fn CTFramesetterSuggestFrameSizeWithConstraints(
89        framesetter: CTFramesetterRef,
90        string_range: CFRange,
91        frame_attributes: CFDictionaryRef,
92        constraints: CGSize,
93        fitRange: *mut CFRange,
94    ) -> CGSize;
95}