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

Commit

Permalink
Implement functions, returning iterator, for GlyphItem instead of typ…
Browse files Browse the repository at this point in the history
…e GlyphItemIter
  • Loading branch information
EPashkin committed Sep 27, 2019
1 parent 3a70ef0 commit 21ca84e
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ status = "generate"

[[object]]
name = "Pango.GlyphItemIter"
#need manual getters
status = "manual"
#need manual iterator implementation
status = "ignored"

[[object]]
name = "Pango.Layout"
Expand Down
148 changes: 141 additions & 7 deletions src/glyph_item_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use glib::translate::*;
use pango_sys;
use GlyphItem;

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

impl GlyphItemIter {
pub fn init_end(glyph_item: &mut GlyphItem) -> Option<GlyphItemIter> {
pub fn init_end(glyph_item: &GlyphItem, text: &str) -> Option<GlyphItemIter> {
unsafe {
let mut iter = GlyphItemIter::uninitialized();
let ret = from_glib(pango_sys::pango_glyph_item_iter_init_end(
iter.to_glib_none_mut().0,
glyph_item.to_glib_none_mut().0,
//Text seems ignored and item's used
"".to_glib_none().0,
mut_override(glyph_item.to_glib_none().0),
text.to_glib_none().0,
));
if ret {
Some(iter)
Expand All @@ -37,13 +37,13 @@ impl GlyphItemIter {
}
}

pub fn init_start(glyph_item: &mut GlyphItem) -> Option<GlyphItemIter> {
pub fn init_start(glyph_item: &GlyphItem, text: &str) -> Option<GlyphItemIter> {
unsafe {
let mut iter = GlyphItemIter::uninitialized();
let ret = from_glib(pango_sys::pango_glyph_item_iter_init_start(
iter.to_glib_none_mut().0,
glyph_item.to_glib_none_mut().0,
"".to_glib_none().0,
mut_override(glyph_item.to_glib_none().0),
text.to_glib_none().0,
));
if ret {
Some(iter)
Expand Down Expand Up @@ -92,4 +92,138 @@ impl GlyphItemIter {
pub fn end_glyph(&self) -> i32 {
self.0.end_glyph
}

pub fn into_data(&self) -> GlyphItemIteratorData {
GlyphItemIteratorData {
start_glyph: self.0.start_glyph,
end_glyph: self.0.end_glyph,
start_index: self.0.start_index as usize,
end_index: self.0.end_index as usize,
start_char: self.0.start_char as usize,
end_char: self.0.end_char as usize,
}
}
}

pub struct GlyphItemIteratorData {
pub start_glyph: i32,
pub start_index: usize,
pub start_char: usize,

pub end_glyph: i32,
pub end_index: usize,
pub end_char: usize,
}

pub struct GlyphItemIterator<'a> {
item: &'a GlyphItem,
text: &'a str,
is_reverse: bool,
iter: Option<GlyphItemIter>,
}

impl<'a> GlyphItemIterator<'a> {
#[inline(always)]
fn new_start(item: &'a GlyphItem, text: &'a str) -> GlyphItemIterator<'a> {
GlyphItemIterator {
item,
text,
is_reverse: false,
iter: None,
}
}

#[inline(always)]
fn new_end(item: &'a GlyphItem, text: &'a str) -> GlyphItemIterator<'a> {
GlyphItemIterator {
item,
text,
is_reverse: true,
iter: None,
}
}
}

impl GlyphItem {
pub fn iter<'a>(
&'a self,
text: &'a str,
) -> impl DoubleEndedIterator<Item = GlyphItemIteratorData> + 'a {
GlyphItemIterator::new_start(self, text)
}

pub fn riter<'a>(
&'a self,
text: &'a str,
) -> impl DoubleEndedIterator<Item = GlyphItemIteratorData> + 'a {
GlyphItemIterator::new_end(self, text)
}
}

impl<'a> Iterator for GlyphItemIterator<'a> {
type Item = GlyphItemIteratorData;

fn next(&mut self) -> Option<Self::Item> {
if let Some(ref mut iter) = self.iter {
if self.is_reverse {
if iter.prev_cluster() {
Some(iter.into_data())
} else {
None
}
} else {
if iter.next_cluster() {
Some(iter.into_data())
} else {
None
}
}
} else {
let iter = if self.is_reverse {
GlyphItemIter::init_end(self.item, self.text)
} else {
GlyphItemIter::init_start(self.item, self.text)
};
if let Some(iter) = iter {
let data = iter.into_data();
self.iter = Some(iter);
Some(data)
} else {
None
}
}
}
}

impl<'a> DoubleEndedIterator for GlyphItemIterator<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(ref mut iter) = self.iter {
if self.is_reverse {
if iter.next_cluster() {
Some(iter.into_data())
} else {
None
}
} else {
if iter.prev_cluster() {
Some(iter.into_data())
} else {
None
}
}
} else {
let iter = if self.is_reverse {
GlyphItemIter::init_start(self.item, self.text)
} else {
GlyphItemIter::init_end(self.item, self.text)
};
if let Some(iter) = iter {
let data = iter.into_data();
self.iter = Some(iter);
Some(data)
} else {
None
}
}
}
}
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ pub mod attribute;
pub mod font_description;
mod functions;
mod glyph_item_iter;
pub use glyph_item_iter::GlyphItemIter;
pub mod gravity;
pub mod item;
pub mod language;
Expand Down

0 comments on commit 21ca84e

Please sign in to comment.