svg-filters & basic parser #15
5 changed files with 98 additions and 9 deletions
|
@ -3,7 +3,11 @@ use petgraph::{data::Build, prelude::NodeIndex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::nodes::primitives::{
|
types::nodes::primitives::{
|
||||||
blend::BlendMode, color_matrix::ColorMatrixType, component_transfer::TransferFn,
|
blend::BlendMode,
|
||||||
|
color_matrix::ColorMatrixType,
|
||||||
|
component_transfer::TransferFn,
|
||||||
|
displacement_map::Channel,
|
||||||
|
turbulence::{NoiseType, StitchTiles},
|
||||||
},
|
},
|
||||||
Node,
|
Node,
|
||||||
};
|
};
|
||||||
|
@ -152,4 +156,41 @@ impl FilterGraph {
|
||||||
pub fn flood_opaque(&mut self, flood_color: Color) -> NodeIndex {
|
pub fn flood_opaque(&mut self, flood_color: Color) -> NodeIndex {
|
||||||
self.dag.add_node(Node::flood_opaque(flood_color))
|
self.dag.add_node(Node::flood_opaque(flood_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn turbulence(
|
||||||
|
&mut self,
|
||||||
|
base_freq_x: f32,
|
||||||
|
base_freq_y: f32,
|
||||||
|
num_octaves: u16,
|
||||||
|
seed: u32,
|
||||||
|
stitch_tiles: StitchTiles,
|
||||||
|
noise_type: NoiseType,
|
||||||
|
) -> NodeIndex {
|
||||||
|
self.dag.add_node(Node::turbulence(
|
||||||
|
base_freq_x,
|
||||||
|
base_freq_y,
|
||||||
|
num_octaves,
|
||||||
|
seed,
|
||||||
|
stitch_tiles,
|
||||||
|
noise_type,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn displacement_map(
|
||||||
|
&mut self,
|
||||||
|
source_image: impl Into<NodeInput>,
|
||||||
|
displacement_map: impl Into<NodeInput>,
|
||||||
|
scale: f32,
|
||||||
|
x_channel: Channel,
|
||||||
|
y_channel: Channel,
|
||||||
|
) -> NodeIndex {
|
||||||
|
let node_idx = self
|
||||||
|
.dag
|
||||||
|
.add_node(Node::displacement_map(scale, x_channel, y_channel));
|
||||||
|
self.dag
|
||||||
|
.add_edge(self.resolve_input(source_image.into()), node_idx, ());
|
||||||
|
self.dag
|
||||||
|
.add_edge(self.resolve_input(displacement_map.into()), node_idx, ());
|
||||||
|
node_idx
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@ use self::{
|
||||||
color_matrix::{ColorMatrix, ColorMatrixType},
|
color_matrix::{ColorMatrix, ColorMatrixType},
|
||||||
component_transfer::{ComponentTransfer, TransferFn},
|
component_transfer::{ComponentTransfer, TransferFn},
|
||||||
composite::{Composite, CompositeOperator},
|
composite::{Composite, CompositeOperator},
|
||||||
|
displacement_map::{Channel, DisplacementMap},
|
||||||
flood::Flood,
|
flood::Flood,
|
||||||
gaussian_blur::GaussianBlur,
|
gaussian_blur::GaussianBlur,
|
||||||
offset::Offset,
|
offset::Offset,
|
||||||
|
turbulence::{NoiseType, StitchTiles, Turbulence},
|
||||||
FePrimitive,
|
FePrimitive,
|
||||||
},
|
},
|
||||||
standard_input::StandardInput,
|
standard_input::StandardInput,
|
||||||
|
@ -207,4 +209,29 @@ impl Node {
|
||||||
pub fn flood_opaque(flood_color: Color) -> Self {
|
pub fn flood_opaque(flood_color: Color) -> Self {
|
||||||
Self::flood(flood_color, 1.)
|
Self::flood(flood_color, 1.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn turbulence(
|
||||||
|
base_freq_x: f32,
|
||||||
|
base_freq_y: f32,
|
||||||
|
num_octaves: u16,
|
||||||
|
seed: u32,
|
||||||
|
stitch_tiles: StitchTiles,
|
||||||
|
noise_type: NoiseType,
|
||||||
|
) -> Self {
|
||||||
|
Self::simple(FePrimitive::Turbulence(Turbulence {
|
||||||
|
base_frequency: (base_freq_x, base_freq_y),
|
||||||
|
num_octaves,
|
||||||
|
seed,
|
||||||
|
stitch_tiles,
|
||||||
|
noise_type,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn displacement_map(scale: f32, x_channel: Channel, y_channel: Channel) -> Self {
|
||||||
|
Self::simple(FePrimitive::DisplacementMap(DisplacementMap {
|
||||||
|
scale,
|
||||||
|
x_channel_selector: x_channel,
|
||||||
|
y_channel_selector: y_channel,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl WriteElement for FePrimitive {
|
||||||
FePrimitive::Turbulence(el) => el.attrs(),
|
FePrimitive::Turbulence(el) => el.attrs(),
|
||||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||||
FePrimitive::DisplacementMap(_) => todo!(),
|
FePrimitive::DisplacementMap(el) => el.attrs(),
|
||||||
FePrimitive::Flood(el) => el.attrs(),
|
FePrimitive::Flood(el) => el.attrs(),
|
||||||
FePrimitive::Image(_) => todo!(),
|
FePrimitive::Image(_) => todo!(),
|
||||||
FePrimitive::Merge(_) => todo!(),
|
FePrimitive::Merge(_) => todo!(),
|
||||||
|
@ -111,7 +111,7 @@ impl WriteElement for FePrimitive {
|
||||||
FePrimitive::Turbulence(el) => el.tag_name(),
|
FePrimitive::Turbulence(el) => el.tag_name(),
|
||||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||||
FePrimitive::DisplacementMap(_) => todo!(),
|
FePrimitive::DisplacementMap(el) => el.tag_name(),
|
||||||
FePrimitive::Flood(el) => el.tag_name(),
|
FePrimitive::Flood(el) => el.tag_name(),
|
||||||
FePrimitive::Image(_) => todo!(),
|
FePrimitive::Image(_) => todo!(),
|
||||||
FePrimitive::Merge(_) => todo!(),
|
FePrimitive::Merge(_) => todo!(),
|
||||||
|
@ -138,7 +138,7 @@ impl WriteElement for FePrimitive {
|
||||||
FePrimitive::Offset(el) => el.element_writer(writer, common, inputs, output),
|
FePrimitive::Offset(el) => el.element_writer(writer, common, inputs, output),
|
||||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||||
FePrimitive::DisplacementMap(_) => todo!(),
|
FePrimitive::DisplacementMap(el) => el.element_writer(writer, common, inputs, output),
|
||||||
FePrimitive::Flood(el) => el.element_writer(writer, common, inputs, output),
|
FePrimitive::Flood(el) => el.element_writer(writer, common, inputs, output),
|
||||||
FePrimitive::Image(_) => todo!(),
|
FePrimitive::Image(_) => todo!(),
|
||||||
FePrimitive::Merge(_) => todo!(),
|
FePrimitive::Merge(_) => todo!(),
|
||||||
|
|
|
@ -1,13 +1,32 @@
|
||||||
|
use super::WriteElement;
|
||||||
|
|
||||||
/// [feDisplacementMap](https://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement)
|
/// [feDisplacementMap](https://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement)
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DisplacementMap {
|
pub struct DisplacementMap {
|
||||||
scale: f32,
|
pub scale: f32,
|
||||||
x_channel_selector: Channel,
|
pub x_channel_selector: Channel,
|
||||||
y_channel_selector: Channel,
|
pub y_channel_selector: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl WriteElement for DisplacementMap {
|
||||||
enum Channel {
|
fn attrs(&self) -> Vec<quick_xml::events::attributes::Attribute> {
|
||||||
|
let mut r = Vec::new();
|
||||||
|
gen_attrs![
|
||||||
|
r;
|
||||||
|
self.scale != 0. => b"scale": self.scale,
|
||||||
|
self.x_channel_selector != Channel::A => b"xChannelSelector": format!("{:?}", self.x_channel_selector),
|
||||||
|
self.y_channel_selector != Channel::A => b"yChannelSelector": format!("{:?}", self.y_channel_selector)
|
||||||
|
];
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tag_name(&self) -> &'static str {
|
||||||
|
"feDisplacementMap"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Channel {
|
||||||
A,
|
A,
|
||||||
R,
|
R,
|
||||||
G,
|
G,
|
||||||
|
|
|
@ -3,6 +3,8 @@ use csscolorparser::Color;
|
||||||
use super::WriteElement;
|
use super::WriteElement;
|
||||||
|
|
||||||
/// [feFlood](https://www.w3.org/TR/SVG11/filters.html#feFloodElement)
|
/// [feFlood](https://www.w3.org/TR/SVG11/filters.html#feFloodElement)
|
||||||
|
// NOTE: this doesn't work for some reason, but the examples from mdn don't either.
|
||||||
|
// might be a browser bug, def worth investigating
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Flood {
|
pub struct Flood {
|
||||||
pub flood_color: Color,
|
pub flood_color: Color,
|
||||||
|
|
Loading…
Reference in a new issue