Skip to content
This repository was archived by the owner on Jun 8, 2021. It is now read-only.

Commit 21ca84e

Browse files
committed
Implement functions, returning iterator, for GlyphItem instead of type GlyphItemIter
1 parent 3a70ef0 commit 21ca84e

File tree

3 files changed

+143
-10
lines changed

3 files changed

+143
-10
lines changed

Gir.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ status = "generate"
210210

211211
[[object]]
212212
name = "Pango.GlyphItemIter"
213-
#need manual getters
214-
status = "manual"
213+
#need manual iterator implementation
214+
status = "ignored"
215215

216216
[[object]]
217217
name = "Pango.Layout"

src/glyph_item_iter.rs

+141-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use glib::translate::*;
66
use pango_sys;
77
use GlyphItem;
88

9+
//Note: This type not exported
910
glib_wrapper! {
1011
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1112
pub struct GlyphItemIter(Boxed<pango_sys::PangoGlyphItemIter>);
@@ -20,14 +21,13 @@ glib_wrapper! {
2021
}
2122

2223
impl GlyphItemIter {
23-
pub fn init_end(glyph_item: &mut GlyphItem) -> Option<GlyphItemIter> {
24+
pub fn init_end(glyph_item: &GlyphItem, text: &str) -> Option<GlyphItemIter> {
2425
unsafe {
2526
let mut iter = GlyphItemIter::uninitialized();
2627
let ret = from_glib(pango_sys::pango_glyph_item_iter_init_end(
2728
iter.to_glib_none_mut().0,
28-
glyph_item.to_glib_none_mut().0,
29-
//Text seems ignored and item's used
30-
"".to_glib_none().0,
29+
mut_override(glyph_item.to_glib_none().0),
30+
text.to_glib_none().0,
3131
));
3232
if ret {
3333
Some(iter)
@@ -37,13 +37,13 @@ impl GlyphItemIter {
3737
}
3838
}
3939

40-
pub fn init_start(glyph_item: &mut GlyphItem) -> Option<GlyphItemIter> {
40+
pub fn init_start(glyph_item: &GlyphItem, text: &str) -> Option<GlyphItemIter> {
4141
unsafe {
4242
let mut iter = GlyphItemIter::uninitialized();
4343
let ret = from_glib(pango_sys::pango_glyph_item_iter_init_start(
4444
iter.to_glib_none_mut().0,
45-
glyph_item.to_glib_none_mut().0,
46-
"".to_glib_none().0,
45+
mut_override(glyph_item.to_glib_none().0),
46+
text.to_glib_none().0,
4747
));
4848
if ret {
4949
Some(iter)
@@ -92,4 +92,138 @@ impl GlyphItemIter {
9292
pub fn end_glyph(&self) -> i32 {
9393
self.0.end_glyph
9494
}
95+
96+
pub fn into_data(&self) -> GlyphItemIteratorData {
97+
GlyphItemIteratorData {
98+
start_glyph: self.0.start_glyph,
99+
end_glyph: self.0.end_glyph,
100+
start_index: self.0.start_index as usize,
101+
end_index: self.0.end_index as usize,
102+
start_char: self.0.start_char as usize,
103+
end_char: self.0.end_char as usize,
104+
}
105+
}
106+
}
107+
108+
pub struct GlyphItemIteratorData {
109+
pub start_glyph: i32,
110+
pub start_index: usize,
111+
pub start_char: usize,
112+
113+
pub end_glyph: i32,
114+
pub end_index: usize,
115+
pub end_char: usize,
116+
}
117+
118+
pub struct GlyphItemIterator<'a> {
119+
item: &'a GlyphItem,
120+
text: &'a str,
121+
is_reverse: bool,
122+
iter: Option<GlyphItemIter>,
123+
}
124+
125+
impl<'a> GlyphItemIterator<'a> {
126+
#[inline(always)]
127+
fn new_start(item: &'a GlyphItem, text: &'a str) -> GlyphItemIterator<'a> {
128+
GlyphItemIterator {
129+
item,
130+
text,
131+
is_reverse: false,
132+
iter: None,
133+
}
134+
}
135+
136+
#[inline(always)]
137+
fn new_end(item: &'a GlyphItem, text: &'a str) -> GlyphItemIterator<'a> {
138+
GlyphItemIterator {
139+
item,
140+
text,
141+
is_reverse: true,
142+
iter: None,
143+
}
144+
}
145+
}
146+
147+
impl GlyphItem {
148+
pub fn iter<'a>(
149+
&'a self,
150+
text: &'a str,
151+
) -> impl DoubleEndedIterator<Item = GlyphItemIteratorData> + 'a {
152+
GlyphItemIterator::new_start(self, text)
153+
}
154+
155+
pub fn riter<'a>(
156+
&'a self,
157+
text: &'a str,
158+
) -> impl DoubleEndedIterator<Item = GlyphItemIteratorData> + 'a {
159+
GlyphItemIterator::new_end(self, text)
160+
}
161+
}
162+
163+
impl<'a> Iterator for GlyphItemIterator<'a> {
164+
type Item = GlyphItemIteratorData;
165+
166+
fn next(&mut self) -> Option<Self::Item> {
167+
if let Some(ref mut iter) = self.iter {
168+
if self.is_reverse {
169+
if iter.prev_cluster() {
170+
Some(iter.into_data())
171+
} else {
172+
None
173+
}
174+
} else {
175+
if iter.next_cluster() {
176+
Some(iter.into_data())
177+
} else {
178+
None
179+
}
180+
}
181+
} else {
182+
let iter = if self.is_reverse {
183+
GlyphItemIter::init_end(self.item, self.text)
184+
} else {
185+
GlyphItemIter::init_start(self.item, self.text)
186+
};
187+
if let Some(iter) = iter {
188+
let data = iter.into_data();
189+
self.iter = Some(iter);
190+
Some(data)
191+
} else {
192+
None
193+
}
194+
}
195+
}
196+
}
197+
198+
impl<'a> DoubleEndedIterator for GlyphItemIterator<'a> {
199+
fn next_back(&mut self) -> Option<Self::Item> {
200+
if let Some(ref mut iter) = self.iter {
201+
if self.is_reverse {
202+
if iter.next_cluster() {
203+
Some(iter.into_data())
204+
} else {
205+
None
206+
}
207+
} else {
208+
if iter.prev_cluster() {
209+
Some(iter.into_data())
210+
} else {
211+
None
212+
}
213+
}
214+
} else {
215+
let iter = if self.is_reverse {
216+
GlyphItemIter::init_start(self.item, self.text)
217+
} else {
218+
GlyphItemIter::init_end(self.item, self.text)
219+
};
220+
if let Some(iter) = iter {
221+
let data = iter.into_data();
222+
self.iter = Some(iter);
223+
Some(data)
224+
} else {
225+
None
226+
}
227+
}
228+
}
95229
}

src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ pub mod attribute;
3939
pub mod font_description;
4040
mod functions;
4141
mod glyph_item_iter;
42-
pub use glyph_item_iter::GlyphItemIter;
4342
pub mod gravity;
4443
pub mod item;
4544
pub mod language;

0 commit comments

Comments
 (0)