@@ -6,6 +6,7 @@ use glib::translate::*;
6
6
use pango_sys;
7
7
use GlyphItem ;
8
8
9
+ //Note: This type not exported
9
10
glib_wrapper ! {
10
11
#[ derive( Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
11
12
pub struct GlyphItemIter ( Boxed <pango_sys:: PangoGlyphItemIter >) ;
@@ -20,14 +21,13 @@ glib_wrapper! {
20
21
}
21
22
22
23
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 > {
24
25
unsafe {
25
26
let mut iter = GlyphItemIter :: uninitialized ( ) ;
26
27
let ret = from_glib ( pango_sys:: pango_glyph_item_iter_init_end (
27
28
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 ,
31
31
) ) ;
32
32
if ret {
33
33
Some ( iter)
@@ -37,13 +37,13 @@ impl GlyphItemIter {
37
37
}
38
38
}
39
39
40
- pub fn init_start ( glyph_item : & mut GlyphItem ) -> Option < GlyphItemIter > {
40
+ pub fn init_start ( glyph_item : & GlyphItem , text : & str ) -> Option < GlyphItemIter > {
41
41
unsafe {
42
42
let mut iter = GlyphItemIter :: uninitialized ( ) ;
43
43
let ret = from_glib ( pango_sys:: pango_glyph_item_iter_init_start (
44
44
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 ,
47
47
) ) ;
48
48
if ret {
49
49
Some ( iter)
@@ -92,4 +92,138 @@ impl GlyphItemIter {
92
92
pub fn end_glyph ( & self ) -> i32 {
93
93
self . 0 . end_glyph
94
94
}
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
+ }
95
229
}
0 commit comments