//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;
use objc2_core_foundation::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/coretext/cttypesetter?language=objc)
#[doc(alias = "CTTypesetterRef")]
#[repr(C)]
pub struct CTTypesetter {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl CTTypesetter {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"__CTTypesetter"> for CTTypesetter {}
);

unsafe impl ConcreteType for CTTypesetter {
    /// Returns the CFType of the typesetter object
    #[doc(alias = "CTTypesetterGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CTTypesetterGetTypeID() -> CFTypeID;
        }
        unsafe { CTTypesetterGetTypeID() }
    }
}

extern "C" {
    /// Allows layout requiring a potentially unbounded amount of work.
    ///
    /// Value must be a CFBooleanRef. Default is false for clients linked on or after macOS 10.14 or iOS 12.
    /// Proper Unicode layout of some text requires unreasonable effort;
    /// unless this option is set to kCFBooleanTrue such inputs will
    /// result in CTTypesetterCreateWithAttributedStringAndOptions
    /// returning NULL.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/coretext/kcttypesetteroptionallowunboundedlayout?language=objc)
    pub static kCTTypesetterOptionAllowUnboundedLayout: &'static CFString;
}

extern "C" {
    /// Disables bidi processing.
    ///
    /// Value must be a CFBooleanRef. Default is false.
    /// Normally, typesetting applies the Unicode Bidirectional
    /// Algorithm as described in UAX #9. If a typesetter is created
    /// with this option set to true, no directional reordering is
    /// performed and any directional control characters are ignored.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/coretext/kcttypesetteroptiondisablebidiprocessing?language=objc)
    #[deprecated = "Deprecated"]
    pub static kCTTypesetterOptionDisableBidiProcessing: &'static CFString;
}

extern "C" {
    /// Specifies the embedding level.
    ///
    /// Value must be a CFNumberRef. Default is unset. Normally,
    /// typesetting applies the Unicode Bidirectional Algorithm as
    /// described in UAX #9. If present, this specifies the embedding
    /// level and any directional control characters are ignored.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/coretext/kcttypesetteroptionforcedembeddinglevel?language=objc)
    pub static kCTTypesetterOptionForcedEmbeddingLevel: &'static CFString;
}

impl CTTypesetter {
    /// Creates an immutable typesetter object using an attributed
    /// string.
    ///
    ///
    /// The resultant typesetter can be used to create lines, perform
    /// line breaking, and do other contextual analysis based on the
    /// characters in the string.
    ///
    ///
    /// Parameter `string`: The CFAttributedStringRef that you want to typeset. This
    /// parameter must be filled in with a valid CFAttributedString.
    ///
    ///
    /// Returns: This function will return a reference to a CTTypesetter.
    #[doc(alias = "CTTypesetterCreateWithAttributedString")]
    #[inline]
    pub unsafe fn with_attributed_string(string: &CFAttributedString) -> CFRetained<CTTypesetter> {
        extern "C-unwind" {
            fn CTTypesetterCreateWithAttributedString(
                string: &CFAttributedString,
            ) -> Option<NonNull<CTTypesetter>>;
        }
        let ret = unsafe { CTTypesetterCreateWithAttributedString(string) };
        let ret =
            ret.expect("function was marked as returning non-null, but actually returned NULL");
        unsafe { CFRetained::from_raw(ret) }
    }

    /// Creates an immutable typesetter object using an attributed
    /// string and a dictionary of options.
    ///
    ///
    /// The resultant typesetter can be used to create lines, perform
    /// line breaking, and do other contextual analysis based on the
    /// characters in the string.
    ///
    ///
    /// Parameter `string`: The CFAttributedStringRef that you want to typeset. This
    /// parameter must be filled in with a valid CFAttributedString.
    ///
    ///
    /// Parameter `options`: A CFDictionary of typesetter options, or NULL if there are none.
    ///
    ///
    /// Returns: This function will return either a reference to a CTTypesetter
    /// or NULL if layout cannot be performed due to an attributed
    /// string that would require unreasonable effort.
    ///
    ///
    /// See also: kCTTypesetterOptionAllowUnboundedLayout
    ///
    /// # Safety
    ///
    /// `options` generics must be of the correct type.
    #[doc(alias = "CTTypesetterCreateWithAttributedStringAndOptions")]
    #[inline]
    pub unsafe fn with_attributed_string_and_options(
        string: &CFAttributedString,
        options: Option<&CFDictionary>,
    ) -> Option<CFRetained<CTTypesetter>> {
        extern "C-unwind" {
            fn CTTypesetterCreateWithAttributedStringAndOptions(
                string: &CFAttributedString,
                options: Option<&CFDictionary>,
            ) -> Option<NonNull<CTTypesetter>>;
        }
        let ret = unsafe { CTTypesetterCreateWithAttributedStringAndOptions(string, options) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// Creates an immutable line from the typesetter.
    ///
    ///
    /// The resultant line will consist of glyphs in the correct visual
    /// order, ready to draw.
    ///
    ///
    /// Parameter `typesetter`: The typesetter which the line will come from.
    ///
    ///
    /// Parameter `stringRange`: The string range which the line will be based on. If the length
    /// portion of range is set to 0, then the typesetter will continue
    /// to add glyphs to the line until it runs out of characters in the
    /// string. The location and length of the range must be within the
    /// bounds of the string, otherwise the call will fail.
    ///
    ///
    /// Parameter `offset`: The line position offset.
    ///
    ///
    /// Returns: This function will return a reference to a CTLine.
    #[doc(alias = "CTTypesetterCreateLineWithOffset")]
    #[cfg(feature = "CTLine")]
    #[inline]
    pub unsafe fn line_with_offset(
        &self,
        string_range: CFRange,
        offset: c_double,
    ) -> CFRetained<CTLine> {
        extern "C-unwind" {
            fn CTTypesetterCreateLineWithOffset(
                typesetter: &CTTypesetter,
                string_range: CFRange,
                offset: c_double,
            ) -> Option<NonNull<CTLine>>;
        }
        let ret = unsafe { CTTypesetterCreateLineWithOffset(self, string_range, offset) };
        let ret =
            ret.expect("function was marked as returning non-null, but actually returned NULL");
        unsafe { CFRetained::from_raw(ret) }
    }

    /// Equivalent to CTTypesetterCreateLineWithOffset with offset = 0.0.
    #[doc(alias = "CTTypesetterCreateLine")]
    #[cfg(feature = "CTLine")]
    #[inline]
    pub unsafe fn line(&self, string_range: CFRange) -> CFRetained<CTLine> {
        extern "C-unwind" {
            fn CTTypesetterCreateLine(
                typesetter: &CTTypesetter,
                string_range: CFRange,
            ) -> Option<NonNull<CTLine>>;
        }
        let ret = unsafe { CTTypesetterCreateLine(self, string_range) };
        let ret =
            ret.expect("function was marked as returning non-null, but actually returned NULL");
        unsafe { CFRetained::from_raw(ret) }
    }

    /// Suggests a contextual line break point based on the width
    /// provided.
    ///
    ///
    /// The line break can be triggered either by a hard break character
    /// in the stream or by filling the specified width with characters.
    ///
    ///
    /// Parameter `typesetter`: The typesetter which the line will come from.
    ///
    ///
    /// Parameter `startIndex`: The starting point for the line break calculations. The break
    /// calculations will include the character starting at startIndex.
    ///
    ///
    /// Parameter `width`: The requested line break width.
    ///
    ///
    /// Parameter `offset`: The line position offset.
    ///
    ///
    /// Returns: The value returned is a count of the characters from startIndex
    /// that would cause the line break. This value returned can be used
    /// to construct a character range for CTTypesetterCreateLine.
    #[doc(alias = "CTTypesetterSuggestLineBreakWithOffset")]
    #[inline]
    pub unsafe fn suggest_line_break_with_offset(
        &self,
        start_index: CFIndex,
        width: c_double,
        offset: c_double,
    ) -> CFIndex {
        extern "C-unwind" {
            fn CTTypesetterSuggestLineBreakWithOffset(
                typesetter: &CTTypesetter,
                start_index: CFIndex,
                width: c_double,
                offset: c_double,
            ) -> CFIndex;
        }
        unsafe { CTTypesetterSuggestLineBreakWithOffset(self, start_index, width, offset) }
    }

    /// Equivalent to CTTypesetterSuggestLineBreakWithOffset with offset = 0.0.
    #[doc(alias = "CTTypesetterSuggestLineBreak")]
    #[inline]
    pub unsafe fn suggest_line_break(&self, start_index: CFIndex, width: c_double) -> CFIndex {
        extern "C-unwind" {
            fn CTTypesetterSuggestLineBreak(
                typesetter: &CTTypesetter,
                start_index: CFIndex,
                width: c_double,
            ) -> CFIndex;
        }
        unsafe { CTTypesetterSuggestLineBreak(self, start_index, width) }
    }

    /// Suggests a cluster line break point based on the width provided.
    ///
    ///
    /// Suggests a typographic cluster line break point based on the width
    /// provided. This cluster break is similar to a character break,
    /// except that it will not break apart linguistic clusters. No other
    /// contextual analysis will be done. This can be used by the caller
    /// to implement a different line breaking scheme, such as
    /// hyphenation. Note that a typographic cluster break can also be
    /// triggered by a hard break character in the stream.
    ///
    ///
    /// Parameter `typesetter`: The typesetter which the line will come from.
    ///
    ///
    /// Parameter `startIndex`: The starting point for the typographic cluster break
    /// calculations. The break calculations will include the character
    /// starting at startIndex.
    ///
    ///
    /// Parameter `width`: The requested typographic cluster break width.
    ///
    ///
    /// Parameter `offset`: The line position offset.
    ///
    ///
    /// Returns: The value returned is a count of the characters from startIndex
    /// that would cause the cluster break. This value returned can be
    /// used to construct a character range for CTTypesetterCreateLine.
    #[doc(alias = "CTTypesetterSuggestClusterBreakWithOffset")]
    #[inline]
    pub unsafe fn suggest_cluster_break_with_offset(
        &self,
        start_index: CFIndex,
        width: c_double,
        offset: c_double,
    ) -> CFIndex {
        extern "C-unwind" {
            fn CTTypesetterSuggestClusterBreakWithOffset(
                typesetter: &CTTypesetter,
                start_index: CFIndex,
                width: c_double,
                offset: c_double,
            ) -> CFIndex;
        }
        unsafe { CTTypesetterSuggestClusterBreakWithOffset(self, start_index, width, offset) }
    }

    /// Equivalent to CTTypesetterSuggestClusterBreakWithOffset with offset = 0.0.
    #[doc(alias = "CTTypesetterSuggestClusterBreak")]
    #[inline]
    pub unsafe fn suggest_cluster_break(&self, start_index: CFIndex, width: c_double) -> CFIndex {
        extern "C-unwind" {
            fn CTTypesetterSuggestClusterBreak(
                typesetter: &CTTypesetter,
                start_index: CFIndex,
                width: c_double,
            ) -> CFIndex;
        }
        unsafe { CTTypesetterSuggestClusterBreak(self, start_index, width) }
    }
}

#[deprecated = "renamed to `CTTypesetter::with_attributed_string`"]
#[inline]
pub unsafe extern "C-unwind" fn CTTypesetterCreateWithAttributedString(
    string: &CFAttributedString,
) -> CFRetained<CTTypesetter> {
    extern "C-unwind" {
        fn CTTypesetterCreateWithAttributedString(
            string: &CFAttributedString,
        ) -> Option<NonNull<CTTypesetter>>;
    }
    let ret = unsafe { CTTypesetterCreateWithAttributedString(string) };
    let ret = ret.expect("function was marked as returning non-null, but actually returned NULL");
    unsafe { CFRetained::from_raw(ret) }
}

#[deprecated = "renamed to `CTTypesetter::with_attributed_string_and_options`"]
#[inline]
pub unsafe extern "C-unwind" fn CTTypesetterCreateWithAttributedStringAndOptions(
    string: &CFAttributedString,
    options: Option<&CFDictionary>,
) -> Option<CFRetained<CTTypesetter>> {
    extern "C-unwind" {
        fn CTTypesetterCreateWithAttributedStringAndOptions(
            string: &CFAttributedString,
            options: Option<&CFDictionary>,
        ) -> Option<NonNull<CTTypesetter>>;
    }
    let ret = unsafe { CTTypesetterCreateWithAttributedStringAndOptions(string, options) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[cfg(feature = "CTLine")]
#[deprecated = "renamed to `CTTypesetter::line_with_offset`"]
#[inline]
pub unsafe extern "C-unwind" fn CTTypesetterCreateLineWithOffset(
    typesetter: &CTTypesetter,
    string_range: CFRange,
    offset: c_double,
) -> CFRetained<CTLine> {
    extern "C-unwind" {
        fn CTTypesetterCreateLineWithOffset(
            typesetter: &CTTypesetter,
            string_range: CFRange,
            offset: c_double,
        ) -> Option<NonNull<CTLine>>;
    }
    let ret = unsafe { CTTypesetterCreateLineWithOffset(typesetter, string_range, offset) };
    let ret = ret.expect("function was marked as returning non-null, but actually returned NULL");
    unsafe { CFRetained::from_raw(ret) }
}

#[cfg(feature = "CTLine")]
#[deprecated = "renamed to `CTTypesetter::line`"]
#[inline]
pub unsafe extern "C-unwind" fn CTTypesetterCreateLine(
    typesetter: &CTTypesetter,
    string_range: CFRange,
) -> CFRetained<CTLine> {
    extern "C-unwind" {
        fn CTTypesetterCreateLine(
            typesetter: &CTTypesetter,
            string_range: CFRange,
        ) -> Option<NonNull<CTLine>>;
    }
    let ret = unsafe { CTTypesetterCreateLine(typesetter, string_range) };
    let ret = ret.expect("function was marked as returning non-null, but actually returned NULL");
    unsafe { CFRetained::from_raw(ret) }
}

extern "C-unwind" {
    #[deprecated = "renamed to `CTTypesetter::suggest_line_break_with_offset`"]
    pub fn CTTypesetterSuggestLineBreakWithOffset(
        typesetter: &CTTypesetter,
        start_index: CFIndex,
        width: c_double,
        offset: c_double,
    ) -> CFIndex;
}

extern "C-unwind" {
    #[deprecated = "renamed to `CTTypesetter::suggest_line_break`"]
    pub fn CTTypesetterSuggestLineBreak(
        typesetter: &CTTypesetter,
        start_index: CFIndex,
        width: c_double,
    ) -> CFIndex;
}

extern "C-unwind" {
    #[deprecated = "renamed to `CTTypesetter::suggest_cluster_break_with_offset`"]
    pub fn CTTypesetterSuggestClusterBreakWithOffset(
        typesetter: &CTTypesetter,
        start_index: CFIndex,
        width: c_double,
        offset: c_double,
    ) -> CFIndex;
}

extern "C-unwind" {
    #[deprecated = "renamed to `CTTypesetter::suggest_cluster_break`"]
    pub fn CTTypesetterSuggestClusterBreak(
        typesetter: &CTTypesetter,
        start_index: CFIndex,
        width: c_double,
    ) -> CFIndex;
}
