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
137
138
139
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::RenderNodeType;
use glib::object::IsA;
use glib::translate::*;
use std::mem;

glib::wrapper! {
    /// A render node drawing a set of glyphs.
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    #[doc(alias = "GskTextNode")]
    pub struct TextNode(Shared<ffi::GskTextNode>);

    match fn {
        ref => |ptr| ffi::gsk_render_node_ref(ptr as *mut ffi::GskRenderNode),
        unref => |ptr| ffi::gsk_render_node_unref(ptr as *mut ffi::GskRenderNode),
    }
}

define_render_node!(
    TextNode,
    ffi::GskTextNode,
    ffi::gsk_text_node_get_type,
    RenderNodeType::TextNode
);

impl TextNode {
    /// Creates a render node that renders the given glyphs.
    ///
    /// Note that `color` may not be used if the font contains
    /// color glyphs.
    /// ## `font`
    /// the [`pango::Font`][crate::pango::Font] containing the glyphs
    /// ## `glyphs`
    /// the [`pango::GlyphString`][crate::pango::GlyphString] to render
    /// ## `color`
    /// the foreground color to render with
    /// ## `offset`
    /// offset of the baseline
    ///
    /// # Returns
    ///
    /// a new [`RenderNode`][crate::RenderNode]
    #[doc(alias = "gsk_text_node_new")]
    pub fn new<P: IsA<pango::Font>>(
        font: &P,
        glyphs: &mut pango::GlyphString,
        color: &gdk::RGBA,
        offset: &graphene::Point,
    ) -> Option<Self> {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_full(ffi::gsk_text_node_new(
                font.as_ref().to_glib_none().0,
                glyphs.to_glib_none_mut().0,
                color.to_glib_none().0,
                offset.to_glib_none().0,
            ))
        }
    }

    /// Retrieves the color used by the text `self`.
    ///
    /// # Returns
    ///
    /// the text color
    #[doc(alias = "gsk_text_node_get_color")]
    #[doc(alias = "get_color")]
    pub fn color(&self) -> Option<gdk::RGBA> {
        unsafe { from_glib_none(ffi::gsk_text_node_get_color(self.to_glib_none().0)) }
    }

    /// Returns the font used by the text `self`.
    ///
    /// # Returns
    ///
    /// the font
    #[doc(alias = "gsk_text_node_get_font")]
    #[doc(alias = "get_font")]
    pub fn font(&self) -> Option<pango::Font> {
        unsafe { from_glib_none(ffi::gsk_text_node_get_font(self.to_glib_none().0)) }
    }

    /// Retrieves the glyph information in the `self`.
    ///
    /// # Returns
    ///
    /// the glyph information
    #[doc(alias = "gsk_text_node_get_glyphs")]
    #[doc(alias = "get_glyphs")]
    pub fn glyphs(&self) -> Vec<pango::GlyphInfo> {
        unsafe {
            let mut n_glyphs = mem::MaybeUninit::uninit();
            let ret = FromGlibContainer::from_glib_none_num(
                ffi::gsk_text_node_get_glyphs(self.to_glib_none().0, n_glyphs.as_mut_ptr()),
                n_glyphs.assume_init() as usize,
            );
            ret
        }
    }

    /// Retrieves the number of glyphs in the text node.
    ///
    /// # Returns
    ///
    /// the number of glyphs
    #[doc(alias = "gsk_text_node_get_num_glyphs")]
    #[doc(alias = "get_num_glyphs")]
    pub fn num_glyphs(&self) -> u32 {
        unsafe { ffi::gsk_text_node_get_num_glyphs(self.to_glib_none().0) }
    }

    /// Retrieves the offset applied to the text.
    ///
    /// # Returns
    ///
    /// a point with the horizontal and vertical offsets
    #[doc(alias = "gsk_text_node_get_offset")]
    #[doc(alias = "get_offset")]
    pub fn offset(&self) -> Option<graphene::Point> {
        unsafe { from_glib_none(ffi::gsk_text_node_get_offset(self.to_glib_none().0)) }
    }

    #[doc(alias = "gsk_text_node_has_color_glyphs")]
    #[cfg(any(feature = "v4_2", feature = "dox"))]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "v4_2")))]
    // rustdoc-stripper-ignore-next
    //
    // Due to https://gitlab.gnome.org/GNOME/gtk/-/issues/3675 this function wasn't properly
    // exported in 4.0.0 and so requires 4.1.2 at least for it to work properly.
    /// Checks whether the text `self` has color glyphs.
    ///
    /// # Returns
    ///
    /// [`true`] if the text node has color glyphs
    pub fn has_color_glyphs(&self) -> bool {
        unsafe { from_glib(ffi::gsk_text_node_has_color_glyphs(self.to_glib_none().0)) }
    }
}