1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::Analysis;
use crate::GlyphString;
use crate::Item;
#[cfg(any(feature = "v1_44", feature = "dox"))]
use crate::ShapeFlags;
use glib::translate::*;
use std::ptr;

/// From a list of items in logical order and the associated
/// directional levels, produce a list in visual order.
/// The original list is unmodified.
/// ## `logical_items`
/// a `GList` of [`Item`][crate::Item] in logical order.
///
/// # Returns
///
/// a `GList`
///  of [`Item`][crate::Item] structures in visual order.
///
/// (Please open a bug if you use this function.
///  It is not a particularly convenient interface, and the code
///  is duplicated elsewhere in Pango for that reason.)
#[doc(alias = "pango_reorder_items")]
pub fn reorder_items(logical_items: &[&Item]) -> Vec<Item> {
    unsafe {
        let stash_vec: Vec<_> = logical_items
            .iter()
            .rev()
            .map(|v| v.to_glib_none())
            .collect();
        let mut list: *mut glib::ffi::GList = ptr::null_mut();
        for stash in &stash_vec {
            list = glib::ffi::g_list_prepend(list, Ptr::to(stash.0));
        }

        FromGlibPtrContainer::from_glib_full(ffi::pango_reorder_items(list))
    }
}

/// Given a segment of text and the corresponding
/// [`Analysis`][crate::Analysis] structure returned from [`itemize()`][crate::itemize()],
/// convert the characters into glyphs. You may also pass
/// in only a substring of the item from [`itemize()`][crate::itemize()].
///
/// This is similar to [`shape()`][crate::shape()], except it also can optionally take
/// the full paragraph text as input, which will then be used to perform
/// certain cross-item shaping interactions. If you have access to the broader
/// text of which `item_text` is part of, provide the broader text as
/// `paragraph_text`. If `paragraph_text` is [`None`], item text is used instead.
/// ## `item_text`
/// valid UTF-8 text to shape.
/// ## `item_length`
/// the length (in bytes) of `item_text`. -1 means nul-terminated text.
/// ## `paragraph_text`
/// text of the paragraph (see details). May be [`None`].
/// ## `paragraph_length`
/// the length (in bytes) of `paragraph_text`. -1 means nul-terminated text.
/// ## `analysis`
/// [`Analysis`][crate::Analysis] structure from [`itemize()`][crate::itemize()].
/// ## `glyphs`
/// glyph string in which to store results.
#[doc(alias = "pango_shape_full")]
pub fn shape_full(
    item_text: &str,
    paragraph_text: Option<&str>,
    analysis: &Analysis,
    glyphs: &mut GlyphString,
) {
    let paragraph_length = match paragraph_text {
        Some(s) => s.len(),
        None => 0,
    } as i32;
    let paragraph_text = paragraph_text.to_glib_none();
    let item_length = item_text.len() as i32;
    unsafe {
        ffi::pango_shape_full(
            item_text.to_glib_none().0,
            item_length,
            paragraph_text.0,
            paragraph_length,
            analysis.to_glib_none().0,
            glyphs.to_glib_none_mut().0,
        );
    }
}

/// Given a segment of text and the corresponding
/// [`Analysis`][crate::Analysis] structure returned from [`itemize()`][crate::itemize()],
/// convert the characters into glyphs. You may also pass
/// in only a substring of the item from [`itemize()`][crate::itemize()].
///
/// This is similar to `pango_shape_full()`, except it also takes
/// flags that can influence the shaping process.
/// ## `item_text`
/// valid UTF-8 text to shape
/// ## `item_length`
/// the length (in bytes) of `item_text`.
///  -1 means nul-terminated text.
/// ## `paragraph_text`
/// text of the paragraph (see details).
///  May be [`None`].
/// ## `paragraph_length`
/// the length (in bytes) of `paragraph_text`.
///  -1 means nul-terminated text.
/// ## `analysis`
/// [`Analysis`][crate::Analysis] structure from [`itemize()`][crate::itemize()]
/// ## `glyphs`
/// glyph string in which to store results
/// ## `flags`
/// flags influencing the shaping process
#[cfg(any(feature = "v1_44", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_44")))]
#[doc(alias = "pango_shape_with_flags")]
pub fn shape_with_flags(
    item_text: &str,
    paragraph_text: Option<&str>,
    analysis: &Analysis,
    glyphs: &mut GlyphString,
    flags: ShapeFlags,
) {
    let item_length = item_text.len() as i32;
    let paragraph_length = paragraph_text.map(|t| t.len() as i32).unwrap_or_default();
    unsafe {
        ffi::pango_shape_with_flags(
            item_text.to_glib_none().0,
            item_length,
            paragraph_text.to_glib_none().0,
            paragraph_length,
            analysis.to_glib_none().0,
            glyphs.to_glib_none_mut().0,
            flags.into_glib(),
        );
    }
}