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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::AttrIterator;
use crate::Attribute;
use glib::translate::*;

glib::wrapper! {
    /// The [`AttrList`][crate::AttrList] structure represents a list of attributes
    /// that apply to a section of text. The attributes are, in general,
    /// allowed to overlap in an arbitrary fashion, however, if the
    /// attributes are manipulated only through [`change()`][Self::change()],
    /// the overlap between properties will meet stricter criteria.
    ///
    /// Since the [`AttrList`][crate::AttrList] structure is stored as a linear list,
    /// it is not suitable for storing attributes for large amounts
    /// of text. In general, you should not use a single [`AttrList`][crate::AttrList]
    /// for more than one paragraph of text.
    #[derive(Debug)]
    pub struct AttrList(Shared<ffi::PangoAttrList>);

    match fn {
        ref => |ptr| ffi::pango_attr_list_ref(ptr),
        unref => |ptr| ffi::pango_attr_list_unref(ptr),
        type_ => || ffi::pango_attr_list_get_type(),
    }
}

impl AttrList {
    /// Create a new empty attribute list with a reference count of one.
    ///
    /// # Returns
    ///
    /// the newly allocated [`AttrList`][crate::AttrList],
    ///  which should be freed with `pango_attr_list_unref()`.
    #[doc(alias = "pango_attr_list_new")]
    pub fn new() -> AttrList {
        unsafe { from_glib_full(ffi::pango_attr_list_new()) }
    }

    /// Copy `self` and return an identical new list.
    ///
    /// # Returns
    ///
    /// the newly allocated [`AttrList`][crate::AttrList], with a
    ///  reference count of one, which should
    ///  be freed with `pango_attr_list_unref()`.
    ///  Returns [`None`] if `self` was [`None`].
    #[doc(alias = "pango_attr_list_copy")]
    pub fn copy(&self) -> Option<AttrList> {
        unsafe { from_glib_full(ffi::pango_attr_list_copy(self.to_glib_none().0)) }
    }

    /// Given a [`AttrList`][crate::AttrList] and callback function, removes any elements
    /// of `self` for which `func` returns [`true`] and inserts them into
    /// a new list.
    /// ## `func`
    /// callback function; returns [`true`]
    ///  if an attribute should be filtered out.
    ///
    /// # Returns
    ///
    /// the new [`AttrList`][crate::AttrList] or
    ///  [`None`] if no attributes of the given types were found.
    #[doc(alias = "pango_attr_list_filter")]
    pub fn filter<P: FnMut(&Attribute) -> bool>(&self, func: P) -> Option<AttrList> {
        let func_data: P = func;
        unsafe extern "C" fn func_func<P: FnMut(&Attribute) -> bool>(
            attribute: *mut ffi::PangoAttribute,
            user_data: glib::ffi::gpointer,
        ) -> glib::ffi::gboolean {
            let attribute = from_glib_borrow(attribute);
            let callback: *mut P = user_data as *const _ as usize as *mut P;
            let res = (*callback)(&attribute);
            res.into_glib()
        }
        let func = Some(func_func::<P> as _);
        let super_callback0: &P = &func_data;
        unsafe {
            from_glib_full(ffi::pango_attr_list_filter(
                self.to_glib_none().0,
                func,
                super_callback0 as *const _ as usize as *mut _,
            ))
        }
    }

    /// Gets a list of all attributes in `self`.
    ///
    /// # Returns
    ///
    ///
    ///  a list of all attributes in `self`. To free this value, call
    ///  `pango_attribute_destroy()` on each value and `g_slist_free()`
    ///  on the list.
    #[cfg(any(feature = "v1_44", feature = "dox"))]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_44")))]
    #[doc(alias = "pango_attr_list_get_attributes")]
    #[doc(alias = "get_attributes")]
    pub fn attributes(&self) -> Vec<Attribute> {
        unsafe {
            FromGlibPtrContainer::from_glib_full(ffi::pango_attr_list_get_attributes(
                self.to_glib_none().0,
            ))
        }
    }

    /// Create a iterator initialized to the beginning of the list.
    /// `self` must not be modified until this iterator is freed.
    ///
    /// # Returns
    ///
    /// the newly allocated [`AttrIterator`][crate::AttrIterator], which should
    ///  be freed with `pango_attr_iterator_destroy()`.
    #[doc(alias = "pango_attr_list_get_iterator")]
    #[doc(alias = "get_iterator")]
    pub fn iterator(&self) -> Option<AttrIterator> {
        unsafe { from_glib_full(ffi::pango_attr_list_get_iterator(self.to_glib_none().0)) }
    }

    /// This function opens up a hole in `self`, fills it in with attributes from
    /// the left, and then merges `other` on top of the hole.
    ///
    /// This operation is equivalent to stretching every attribute
    /// that applies at position `pos` in `self` by an amount `len`,
    /// and then calling [`change()`][Self::change()] with a copy
    /// of each attribute in `other` in sequence (offset in position by `pos`).
    ///
    /// This operation proves useful for, for instance, inserting
    /// a pre-edit string in the middle of an edit buffer.
    /// ## `other`
    /// another [`AttrList`][crate::AttrList]
    /// ## `pos`
    /// the position in `self` at which to insert `other`
    /// ## `len`
    /// the length of the spliced segment. (Note that this
    ///  must be specified since the attributes in `other`
    ///  may only be present at some subsection of this range)
    #[doc(alias = "pango_attr_list_splice")]
    pub fn splice(&self, other: &AttrList, pos: i32, len: i32) {
        unsafe {
            ffi::pango_attr_list_splice(self.to_glib_none().0, other.to_glib_none().0, pos, len);
        }
    }

    /// Update indices of attributes in `self` for
    /// a change in the text they refer to.
    ///
    /// The change that this function applies is
    /// removing `remove` bytes at position `pos`
    /// and inserting `add` bytes instead.
    ///
    /// Attributes that fall entirely in the
    /// (`pos`, `pos` + `remove`) range are removed.
    ///
    /// Attributes that start or end inside the
    /// (`pos`, `pos` + `remove`) range are shortened to
    /// reflect the removal.
    ///
    /// Attributes start and end positions are updated
    /// if they are behind `pos` + `remove`.
    /// ## `pos`
    /// the position of the change
    /// ## `remove`
    /// the number of removed bytes
    /// ## `add`
    /// the number of added bytes
    #[cfg(any(feature = "v1_44", feature = "dox"))]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_44")))]
    #[doc(alias = "pango_attr_list_update")]
    pub fn update(&self, pos: i32, remove: i32, add: i32) {
        unsafe {
            ffi::pango_attr_list_update(self.to_glib_none().0, pos, remove, add);
        }
    }
}

impl Default for AttrList {
    fn default() -> Self {
        Self::new()
    }
}