1use std::{marker::PhantomData, mem};
4
5use glib::{GStr, GString, prelude::*, translate::*};
6
7use crate::{GlyphItem, ffi};
8
9#[derive(Clone, Debug)]
18pub struct GlyphItemIter<'item> {
19 inner: ffi::PangoGlyphItemIter,
20 text: GString,
21 item: PhantomData<&'item GlyphItem>,
22}
23
24impl StaticType for GlyphItemIter<'_> {
25 #[inline]
26 fn static_type() -> glib::Type {
27 unsafe { from_glib(ffi::pango_glyph_item_iter_get_type()) }
28 }
29}
30
31impl<'item> GlyphItemIter<'item> {
32 #[doc(alias = "pango_glyph_item_iter_init_start")]
33 pub fn new_start(glyph_item: &'item GlyphItem, text: &str) -> Result<Self, glib::BoolError> {
34 unsafe {
35 let mut iter = mem::MaybeUninit::zeroed();
36 let text = GString::from(text);
37 let res: bool = from_glib(ffi::pango_glyph_item_iter_init_start(
38 iter.as_mut_ptr(),
39 mut_override(glyph_item.to_glib_none().0),
40 text.as_ptr(),
41 ));
42
43 if res {
44 Ok(Self {
45 inner: iter.assume_init(),
46 text,
47 item: PhantomData,
48 })
49 } else {
50 Err(glib::bool_error!("Failed to create glyph item iter"))
51 }
52 }
53 }
54
55 #[doc(alias = "pango_glyph_item_iter_init_end")]
56 pub fn new_end(glyph_item: &'item GlyphItem, text: &str) -> Result<Self, glib::BoolError> {
57 unsafe {
58 let mut iter = mem::MaybeUninit::zeroed();
59 let text = GString::from(text);
60 let res: bool = from_glib(ffi::pango_glyph_item_iter_init_end(
61 iter.as_mut_ptr(),
62 mut_override(glyph_item.to_glib_none().0),
63 text.as_ptr(),
64 ));
65
66 if res {
67 Ok(Self {
68 inner: iter.assume_init(),
69 text,
70 item: PhantomData,
71 })
72 } else {
73 Err(glib::bool_error!("Failed to create glyph item iter"))
74 }
75 }
76 }
77
78 #[doc(alias = "pango_glyph_item_iter_next_cluster")]
79 pub fn next_cluster(&mut self) -> bool {
80 unsafe {
81 from_glib(ffi::pango_glyph_item_iter_next_cluster(
82 self.to_glib_none_mut().0,
83 ))
84 }
85 }
86
87 #[doc(alias = "pango_glyph_item_iter_prev_cluster")]
88 pub fn prev_cluster(&mut self) -> bool {
89 unsafe {
90 from_glib(ffi::pango_glyph_item_iter_prev_cluster(
91 self.to_glib_none_mut().0,
92 ))
93 }
94 }
95
96 #[inline]
97 pub fn glyph_item(&self) -> &'item GlyphItem {
98 unsafe { &*(&self.inner.glyph_item as *const _ as *const GlyphItem) }
99 }
100 #[inline]
101 pub fn text(&self) -> &GStr {
102 self.text.as_gstr()
103 }
104 #[inline]
105 pub fn start_glyph(&self) -> i32 {
106 self.inner.start_glyph
107 }
108 #[inline]
109 pub fn start_index(&self) -> i32 {
110 self.inner.start_index
111 }
112 #[inline]
113 pub fn start_char(&self) -> i32 {
114 self.inner.start_char
115 }
116 #[inline]
117 pub fn end_glyph(&self) -> i32 {
118 self.inner.end_glyph
119 }
120 #[inline]
121 pub fn end_index(&self) -> i32 {
122 self.inner.end_index
123 }
124 #[inline]
125 pub fn end_char(&self) -> i32 {
126 self.inner.end_char
127 }
128}
129
130impl<'item> IntoIterator for GlyphItemIter<'item> {
131 type Item = (i32, i32, i32, i32, i32, i32);
132 type IntoIter = GlyphItemIntoIter<'item>;
133 #[inline]
134 fn into_iter(self) -> Self::IntoIter {
135 GlyphItemIntoIter(Some(self))
136 }
137}
138
139#[derive(Clone, Debug)]
140#[repr(transparent)]
141pub struct GlyphItemIntoIter<'item>(Option<GlyphItemIter<'item>>);
142
143impl Iterator for GlyphItemIntoIter<'_> {
144 type Item = (i32, i32, i32, i32, i32, i32);
145 fn next(&mut self) -> Option<Self::Item> {
146 if let Some(iter) = &mut self.0 {
147 let values = (
148 iter.start_glyph(),
149 iter.start_index(),
150 iter.start_char(),
151 iter.end_glyph(),
152 iter.end_index(),
153 iter.end_char(),
154 );
155 if !iter.next_cluster() {
156 self.0 = None;
157 }
158 Some(values)
159 } else {
160 None
161 }
162 }
163}
164
165impl std::iter::FusedIterator for GlyphItemIntoIter<'_> {}
166
167#[doc(hidden)]
168impl<'a, 'item> ToGlibPtr<'a, *const ffi::PangoGlyphItemIter> for GlyphItemIter<'item>
169where
170 'item: 'a,
171{
172 type Storage = PhantomData<&'a Self>;
173 #[inline]
174 fn to_glib_none(&'a self) -> Stash<'a, *const ffi::PangoGlyphItemIter, Self> {
175 Stash(&self.inner, PhantomData)
176 }
177}
178
179#[doc(hidden)]
180impl<'a, 'item> ToGlibPtrMut<'a, *mut ffi::PangoGlyphItemIter> for GlyphItemIter<'item>
181where
182 'item: 'a,
183{
184 type Storage = PhantomData<&'a mut Self>;
185 #[inline]
186 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::PangoGlyphItemIter, Self> {
187 StashMut(&mut self.inner, PhantomData)
188 }
189}