use std::{marker::PhantomData, mem};
use glib::{prelude::*, translate::*, GStr, GString};
use crate::{ffi, GlyphItem};
#[derive(Clone, Debug)]
pub struct GlyphItemIter<'item> {
inner: ffi::PangoGlyphItemIter,
text: GString,
item: PhantomData<&'item GlyphItem>,
}
impl<'item> StaticType for GlyphItemIter<'item> {
#[inline]
fn static_type() -> glib::Type {
unsafe { from_glib(ffi::pango_glyph_item_iter_get_type()) }
}
}
impl<'item> GlyphItemIter<'item> {
#[doc(alias = "pango_glyph_item_iter_init_start")]
pub fn new_start(glyph_item: &'item GlyphItem, text: &str) -> Result<Self, glib::BoolError> {
unsafe {
let mut iter = mem::MaybeUninit::zeroed();
let text = GString::from(text);
let res: bool = from_glib(ffi::pango_glyph_item_iter_init_start(
iter.as_mut_ptr(),
mut_override(glyph_item.to_glib_none().0),
text.as_ptr(),
));
if res {
Ok(Self {
inner: iter.assume_init(),
text,
item: PhantomData,
})
} else {
Err(glib::bool_error!("Failed to create glyph item iter"))
}
}
}
#[doc(alias = "pango_glyph_item_iter_init_end")]
pub fn new_end(glyph_item: &'item GlyphItem, text: &str) -> Result<Self, glib::BoolError> {
unsafe {
let mut iter = mem::MaybeUninit::zeroed();
let text = GString::from(text);
let res: bool = from_glib(ffi::pango_glyph_item_iter_init_end(
iter.as_mut_ptr(),
mut_override(glyph_item.to_glib_none().0),
text.as_ptr(),
));
if res {
Ok(Self {
inner: iter.assume_init(),
text,
item: PhantomData,
})
} else {
Err(glib::bool_error!("Failed to create glyph item iter"))
}
}
}
#[doc(alias = "pango_glyph_item_iter_next_cluster")]
pub fn next_cluster(&mut self) -> bool {
unsafe {
from_glib(ffi::pango_glyph_item_iter_next_cluster(
self.to_glib_none_mut().0,
))
}
}
#[doc(alias = "pango_glyph_item_iter_prev_cluster")]
pub fn prev_cluster(&mut self) -> bool {
unsafe {
from_glib(ffi::pango_glyph_item_iter_prev_cluster(
self.to_glib_none_mut().0,
))
}
}
#[inline]
pub fn glyph_item(&self) -> &'item GlyphItem {
unsafe { &*(&self.inner.glyph_item as *const _ as *const GlyphItem) }
}
#[inline]
pub fn text(&self) -> &GStr {
self.text.as_gstr()
}
#[inline]
pub fn start_glyph(&self) -> i32 {
self.inner.start_glyph
}
#[inline]
pub fn start_index(&self) -> i32 {
self.inner.start_index
}
#[inline]
pub fn start_char(&self) -> i32 {
self.inner.start_char
}
#[inline]
pub fn end_glyph(&self) -> i32 {
self.inner.end_glyph
}
#[inline]
pub fn end_index(&self) -> i32 {
self.inner.end_index
}
#[inline]
pub fn end_char(&self) -> i32 {
self.inner.end_char
}
}
impl<'item> IntoIterator for GlyphItemIter<'item> {
type Item = (i32, i32, i32, i32, i32, i32);
type IntoIter = GlyphItemIntoIter<'item>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
GlyphItemIntoIter(Some(self))
}
}
#[derive(Clone, Debug)]
#[repr(transparent)]
pub struct GlyphItemIntoIter<'item>(Option<GlyphItemIter<'item>>);
impl<'item> Iterator for GlyphItemIntoIter<'item> {
type Item = (i32, i32, i32, i32, i32, i32);
fn next(&mut self) -> Option<Self::Item> {
if let Some(iter) = &mut self.0 {
let values = (
iter.start_glyph(),
iter.start_index(),
iter.start_char(),
iter.end_glyph(),
iter.end_index(),
iter.end_char(),
);
if !iter.next_cluster() {
self.0 = None;
}
Some(values)
} else {
None
}
}
}
impl<'item> std::iter::FusedIterator for GlyphItemIntoIter<'item> {}
#[doc(hidden)]
impl<'a, 'item> ToGlibPtr<'a, *const ffi::PangoGlyphItemIter> for GlyphItemIter<'item>
where
'item: 'a,
{
type Storage = PhantomData<&'a Self>;
#[inline]
fn to_glib_none(&'a self) -> Stash<'a, *const ffi::PangoGlyphItemIter, Self> {
Stash(&self.inner, PhantomData)
}
}
#[doc(hidden)]
impl<'a, 'item> ToGlibPtrMut<'a, *mut ffi::PangoGlyphItemIter> for GlyphItemIter<'item>
where
'item: 'a,
{
type Storage = PhantomData<&'a mut Self>;
#[inline]
fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::PangoGlyphItemIter, Self> {
StashMut(&mut self.inner, PhantomData)
}
}