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
use babl::ObjectType;
use glib::translate::*;
use crate::{BlitFlags, Node, Rectangle};
impl Node {
/// Render a rectangular region from a node.
/// ## `scale`
/// the scale to render at 1.0 is default, other values changes the
/// width/height of the sampled region.
/// ## `roi`
/// the rectangle to render from the node, the coordinate system used is
/// coordinates after scale has been applied.
/// ## `format`
/// the `BablFormat` desired.
/// ## `destination_buf`
/// a memory buffer large enough to contain the data, can be
/// left as NULL when forcing a rendering of a region.
/// ## `rowstride`
/// rowstride in bytes, or GEGL_AUTO_ROWSTRIDE to compute the
/// rowstride based on the width and bytes per pixel for the specified format.
/// ## `flags`
/// an or'ed combination of GEGL_BLIT_DEFAULT, GEGL_BLIT_CACHE and
/// GEGL_BLIT_DIRTY. if cache is enabled, a cache will be set up for subsequent
/// requests of image data from this node. By passing in GEGL_BLIT_DIRTY the
/// function will return with the latest rendered results in the cache without
/// regard to wheter the regions has been rendered or not.
#[doc(alias = "gegl_node_blit")]
pub fn blit(
&self,
scale: f64,
roi: &Rectangle,
format: &babl::Format,
destination_buf: Option<&mut [u8]>,
rowstride: i32,
flags: BlitFlags,
) {
if destination_buf.is_some() {
assert!(
(format.bytes_per_pixel() * roi.width() * roi.height()) as usize
<= destination_buf.as_ref().unwrap().len()
);
}
unsafe {
ffi::gegl_node_blit(
self.to_glib_none().0,
scale,
roi.to_glib_none().0,
format.inner(),
destination_buf
.map(|buf| buf.as_ptr() as *mut std::ffi::c_void)
.unwrap_or_else(std::ptr::null_mut),
rowstride,
flags.bits(),
)
}
}
/// Creates a new processing node that performs the specified operation with
/// a NULL terminated list of key/value pairs for initial parameter values
/// configuring the operation. Usually the first pair should be "operation"
/// and the type of operation to be associated. If no operation is provided
/// the node doesn't have an initial operation and can be used to construct
/// a subgraph with special middle-man routing nodes created with
/// `gegl_node_get_output_proxy` and `gegl_node_get_input_proxy`.
/// ## `first_property_name`
/// the first property name
///
/// # Returns
///
/// A newly created [`Node`][crate::Node]. The node will be destroyed by the parent.
/// Calling g_object_unref on a node will cause the node to be dropped by the
/// parent. (You may also add additional references using
/// g_object_ref/g_object_unref, but in general relying on the parents reference
/// counting is easiest.)
#[doc(alias = "gegl_node_new_child")]
#[must_use]
pub fn new_child(
&self,
operation: Option<&str>,
props: &[(&str, glib::Value)],
) -> Option<Node> {
operation
.and_then(|operation| self.create_child(operation))
.or_else(|| self.add_child(&Node::new()))
.map(|node| {
for prop in props {
node.set_property(prop.0, &prop.1)
}
node
})
}
/// Synthetic sugar for linking a chain of nodes with "input"->"output". The
/// list is NULL terminated.
/// ## `first_sink`
/// the first consumer of data.
#[doc(alias = "gegl_node_link_many")]
pub fn link_many(&self, dests: &[&Self]) {
let mut source = self;
for dest in dests {
source.link(&dest);
source = dest;
}
}
/// Returns the position and dimensions of a rectangle spanning the area
/// defined by a node.
#[doc(alias = "get_bounding_box")]
pub fn bounding_box(&self) -> Rectangle {
unsafe {
Rectangle {
inner: ffi::gegl_node_get_bounding_box(self.to_glib_none().0),
}
}
}
}