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