Files
Graphite/node-graph/nodes/blending/src/lib.rs

86 lines
3.4 KiB
Rust

use core_types::attr;
use core_types::list::Item;
use core_types::registry::types::Percentage;
use core_types::{BlendMode, Color, Ctx};
use graphic_types::Graphic;
use graphic_types::Vector;
use graphic_types::raster_types::{CPU, GPU, Raster};
use vector_types::Gradient;
/// Applies the blend mode to the input graphics. Setting this allows for customizing how overlapping content is composited together.
#[node_macro::node(category("Blending"))]
fn blend_mode<T>(
_: impl Ctx,
/// The content that will be composited when rendering.
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)]
content: Item<T>,
/// The choice of equation that controls how brightness and color blends between overlapping pixels.
blend_mode: Item<BlendMode>,
) -> Item<T> {
let mut content = content;
let blend_mode = *blend_mode.element();
content.set_attr::<attr::BlendMode>(blend_mode);
content
}
/// Modifies the opacity and/or fill of the input graphics by multiplying the existing values by these percentages.
/// Opacity affects the transparency of the content (together with anything above which is clipped to it).
/// Fill affects the transparency of the content itself, independent of any content clipped to it.
#[node_macro::node(category("Blending"))]
fn opacity<T>(
_: impl Ctx,
/// The content that will be composited when rendering.
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)]
content: Item<T>,
/// Whether the *Opacity* property is enabled, multiplying the existing opacity by the chosen percentage.
#[widget(ParsedWidgetOverride::Hidden)]
#[default(true)]
has_opacity: Item<bool>,
/// How visible the content should be, including any content clipped to it.
/// Ranges from the default of 100% (fully opaque) to 0% (fully transparent).
#[widget(ParsedWidgetOverride::Custom = "optional_percentage")]
#[default(100.)]
opacity: Item<Percentage>,
/// Whether the *Fill* property is enabled, multiplying the existing fill by the chosen percentage.
#[widget(ParsedWidgetOverride::Hidden)]
has_fill: Item<bool>,
/// How visible the content should be, independent of any content clipped to it.
/// Ranges from 0% (fully transparent) to the default of 100% (fully opaque).
#[widget(ParsedWidgetOverride::Custom = "optional_percentage")]
#[default(100.)]
fill: Item<Percentage>,
) -> Item<T> {
let mut content = content;
let (has_opacity, opacity, has_fill, fill) = (*has_opacity.element(), *opacity.element(), *has_fill.element(), *fill.element());
if has_opacity {
let multiplied = content.attr_cloned_or_default::<attr::Opacity>() * (opacity / 100.);
content.set_attr::<attr::Opacity>(multiplied);
}
if has_fill {
let multiplied = content.attr_cloned_or_default::<attr::OpacityFill>() * (fill / 100.);
content.set_attr::<attr::OpacityFill>(multiplied);
}
content
}
/// Sets whether the input graphics inherit the alpha of the content beneath them, "clipping" them to that content.
#[node_macro::node(category("Blending"))]
fn clipping_mask<T>(
_: impl Ctx,
/// The content that will be composited when rendering.
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)]
content: Item<T>,
/// Whether the content inherits the alpha of the content beneath it.
clip: Item<bool>,
) -> Item<T> {
let mut content = content;
let clip = *clip.element();
content.set_attr::<attr::ClippingMask>(clip);
content
}