1// Copyright 2018 the Resvg Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4//! SVG filter types.
5
6use strict_num::PositiveF32;
7
8use crate::{BlendMode, Color, Group, NonEmptyString, NonZeroF32, NonZeroRect, Opacity};
9
10/// A filter element.
11///
12/// `filter` element in the SVG.
13#[derive(Debug)]
14pub struct Filter {
15 pub(crate) id: NonEmptyString,
16 pub(crate) rect: NonZeroRect,
17 pub(crate) primitives: Vec<Primitive>,
18}
19
20impl Filter {
21 /// Element's ID.
22 ///
23 /// Taken from the SVG itself.
24 /// Used only during SVG writing. `resvg` doesn't rely on this property.
25 pub fn id(&self) -> &str {
26 self.id.get()
27 }
28
29 /// Filter region.
30 ///
31 /// `x`, `y`, `width` and `height` in the SVG.
32 pub fn rect(&self) -> NonZeroRect {
33 self.rect
34 }
35
36 /// A list of filter primitives.
37 pub fn primitives(&self) -> &[Primitive] {
38 &self.primitives
39 }
40}
41
42/// A filter primitive element.
43#[derive(Clone, Debug)]
44pub struct Primitive {
45 pub(crate) rect: NonZeroRect,
46 pub(crate) color_interpolation: ColorInterpolation,
47 pub(crate) result: String,
48 pub(crate) kind: Kind,
49}
50
51impl Primitive {
52 /// Filter subregion.
53 ///
54 /// `x`, `y`, `width` and `height` in the SVG.
55 pub fn rect(&self) -> NonZeroRect {
56 self.rect
57 }
58
59 /// Color interpolation mode.
60 ///
61 /// `color-interpolation-filters` in the SVG.
62 pub fn color_interpolation(&self) -> ColorInterpolation {
63 self.color_interpolation
64 }
65
66 /// Assigned name for this filter primitive.
67 ///
68 /// `result` in the SVG.
69 pub fn result(&self) -> &str {
70 &self.result
71 }
72
73 /// Filter primitive kind.
74 pub fn kind(&self) -> &Kind {
75 &self.kind
76 }
77}
78
79/// A filter kind.
80#[allow(missing_docs)]
81#[derive(Clone, Debug)]
82pub enum Kind {
83 Blend(Blend),
84 ColorMatrix(ColorMatrix),
85 ComponentTransfer(ComponentTransfer),
86 Composite(Composite),
87 ConvolveMatrix(ConvolveMatrix),
88 DiffuseLighting(DiffuseLighting),
89 DisplacementMap(DisplacementMap),
90 DropShadow(DropShadow),
91 Flood(Flood),
92 GaussianBlur(GaussianBlur),
93 Image(Image),
94 Merge(Merge),
95 Morphology(Morphology),
96 Offset(Offset),
97 SpecularLighting(SpecularLighting),
98 Tile(Tile),
99 Turbulence(Turbulence),
100}
101
102impl Kind {
103 /// Checks that `FilterKind` has a specific input.
104 pub fn has_input(&self, input: &Input) -> bool {
105 match self {
106 Kind::Blend(ref fe: &Blend) => fe.input1 == *input || fe.input2 == *input,
107 Kind::ColorMatrix(ref fe: &ColorMatrix) => fe.input == *input,
108 Kind::ComponentTransfer(ref fe: &ComponentTransfer) => fe.input == *input,
109 Kind::Composite(ref fe: &Composite) => fe.input1 == *input || fe.input2 == *input,
110 Kind::ConvolveMatrix(ref fe: &ConvolveMatrix) => fe.input == *input,
111 Kind::DiffuseLighting(ref fe: &DiffuseLighting) => fe.input == *input,
112 Kind::DisplacementMap(ref fe: &DisplacementMap) => fe.input1 == *input || fe.input2 == *input,
113 Kind::DropShadow(ref fe: &DropShadow) => fe.input == *input,
114 Kind::Flood(_) => false,
115 Kind::GaussianBlur(ref fe: &GaussianBlur) => fe.input == *input,
116 Kind::Image(_) => false,
117 Kind::Merge(ref fe: &Merge) => fe.inputs.iter().any(|i: &Input| i == input),
118 Kind::Morphology(ref fe: &Morphology) => fe.input == *input,
119 Kind::Offset(ref fe: &Offset) => fe.input == *input,
120 Kind::SpecularLighting(ref fe: &SpecularLighting) => fe.input == *input,
121 Kind::Tile(ref fe: &Tile) => fe.input == *input,
122 Kind::Turbulence(_) => false,
123 }
124 }
125}
126
127/// Identifies input for a filter primitive.
128#[allow(missing_docs)]
129#[derive(Clone, PartialEq, Debug)]
130pub enum Input {
131 SourceGraphic,
132 SourceAlpha,
133 Reference(String),
134}
135
136/// A color interpolation mode.
137///
138/// The default is `ColorInterpolation::LinearRGB`.
139#[allow(missing_docs)]
140#[derive(Clone, Copy, PartialEq, Debug, Default)]
141pub enum ColorInterpolation {
142 SRGB,
143 #[default]
144 LinearRGB,
145}
146
147/// A blend filter primitive.
148///
149/// `feBlend` element in the SVG.
150#[derive(Clone, Debug)]
151pub struct Blend {
152 pub(crate) input1: Input,
153 pub(crate) input2: Input,
154 pub(crate) mode: BlendMode,
155}
156
157impl Blend {
158 /// Identifies input for the given filter primitive.
159 ///
160 /// `in` in the SVG.
161 pub fn input1(&self) -> &Input {
162 &self.input1
163 }
164
165 /// Identifies input for the given filter primitive.
166 ///
167 /// `in2` in the SVG.
168 pub fn input2(&self) -> &Input {
169 &self.input2
170 }
171
172 /// A blending mode.
173 ///
174 /// `mode` in the SVG.
175 pub fn mode(&self) -> BlendMode {
176 self.mode
177 }
178}
179
180/// A color matrix filter primitive.
181///
182/// `feColorMatrix` element in the SVG.
183#[derive(Clone, Debug)]
184pub struct ColorMatrix {
185 pub(crate) input: Input,
186 pub(crate) kind: ColorMatrixKind,
187}
188
189impl ColorMatrix {
190 /// Identifies input for the given filter primitive.
191 ///
192 /// `in` in the SVG.
193 pub fn input(&self) -> &Input {
194 &self.input
195 }
196
197 /// A matrix kind.
198 ///
199 /// `type` in the SVG.
200 pub fn kind(&self) -> &ColorMatrixKind {
201 &self.kind
202 }
203}
204
205/// A color matrix filter primitive kind.
206#[derive(Clone, Debug)]
207#[allow(missing_docs)]
208pub enum ColorMatrixKind {
209 Matrix(Vec<f32>), // Guarantee to have 20 numbers.
210 Saturate(PositiveF32),
211 HueRotate(f32),
212 LuminanceToAlpha,
213}
214
215impl Default for ColorMatrixKind {
216 fn default() -> Self {
217 ColorMatrixKind::Matrix(vec![
218 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
219 0.0, 1.0, 0.0,
220 ])
221 }
222}
223
224/// A component-wise remapping filter primitive.
225///
226/// `feComponentTransfer` element in the SVG.
227#[derive(Clone, Debug)]
228pub struct ComponentTransfer {
229 pub(crate) input: Input,
230 pub(crate) func_r: TransferFunction,
231 pub(crate) func_g: TransferFunction,
232 pub(crate) func_b: TransferFunction,
233 pub(crate) func_a: TransferFunction,
234}
235
236impl ComponentTransfer {
237 /// Identifies input for the given filter primitive.
238 ///
239 /// `in` in the SVG.
240 pub fn input(&self) -> &Input {
241 &self.input
242 }
243
244 /// `feFuncR` in the SVG.
245 pub fn func_r(&self) -> &TransferFunction {
246 &self.func_r
247 }
248
249 /// `feFuncG` in the SVG.
250 pub fn func_g(&self) -> &TransferFunction {
251 &self.func_g
252 }
253
254 /// `feFuncB` in the SVG.
255 pub fn func_b(&self) -> &TransferFunction {
256 &self.func_b
257 }
258
259 /// `feFuncA` in the SVG.
260 pub fn func_a(&self) -> &TransferFunction {
261 &self.func_a
262 }
263}
264
265/// A transfer function used by `FeComponentTransfer`.
266///
267/// <https://www.w3.org/TR/SVG11/filters.html#transferFuncElements>
268#[derive(Clone, Debug)]
269pub enum TransferFunction {
270 /// Keeps a component as is.
271 Identity,
272
273 /// Applies a linear interpolation to a component.
274 ///
275 /// The number list can be empty.
276 Table(Vec<f32>),
277
278 /// Applies a step function to a component.
279 ///
280 /// The number list can be empty.
281 Discrete(Vec<f32>),
282
283 /// Applies a linear shift to a component.
284 #[allow(missing_docs)]
285 Linear { slope: f32, intercept: f32 },
286
287 /// Applies an exponential shift to a component.
288 #[allow(missing_docs)]
289 Gamma {
290 amplitude: f32,
291 exponent: f32,
292 offset: f32,
293 },
294}
295
296/// A composite filter primitive.
297///
298/// `feComposite` element in the SVG.
299#[derive(Clone, Debug)]
300pub struct Composite {
301 pub(crate) input1: Input,
302 pub(crate) input2: Input,
303 pub(crate) operator: CompositeOperator,
304}
305
306impl Composite {
307 /// Identifies input for the given filter primitive.
308 ///
309 /// `in` in the SVG.
310 pub fn input1(&self) -> &Input {
311 &self.input1
312 }
313
314 /// Identifies input for the given filter primitive.
315 ///
316 /// `in2` in the SVG.
317 pub fn input2(&self) -> &Input {
318 &self.input2
319 }
320
321 /// A compositing operation.
322 ///
323 /// `operator` in the SVG.
324 pub fn operator(&self) -> CompositeOperator {
325 self.operator
326 }
327}
328
329/// An images compositing operation.
330#[allow(missing_docs)]
331#[derive(Clone, Copy, PartialEq, Debug)]
332pub enum CompositeOperator {
333 Over,
334 In,
335 Out,
336 Atop,
337 Xor,
338 Arithmetic { k1: f32, k2: f32, k3: f32, k4: f32 },
339}
340
341/// A matrix convolution filter primitive.
342///
343/// `feConvolveMatrix` element in the SVG.
344#[derive(Clone, Debug)]
345pub struct ConvolveMatrix {
346 pub(crate) input: Input,
347 pub(crate) matrix: ConvolveMatrixData,
348 pub(crate) divisor: NonZeroF32,
349 pub(crate) bias: f32,
350 pub(crate) edge_mode: EdgeMode,
351 pub(crate) preserve_alpha: bool,
352}
353
354impl ConvolveMatrix {
355 /// Identifies input for the given filter primitive.
356 ///
357 /// `in` in the SVG.
358 pub fn input(&self) -> &Input {
359 &self.input
360 }
361
362 /// A convolve matrix.
363 pub fn matrix(&self) -> &ConvolveMatrixData {
364 &self.matrix
365 }
366
367 /// A matrix divisor.
368 ///
369 /// `divisor` in the SVG.
370 pub fn divisor(&self) -> NonZeroF32 {
371 self.divisor
372 }
373
374 /// A kernel matrix bias.
375 ///
376 /// `bias` in the SVG.
377 pub fn bias(&self) -> f32 {
378 self.bias
379 }
380
381 /// An edges processing mode.
382 ///
383 /// `edgeMode` in the SVG.
384 pub fn edge_mode(&self) -> EdgeMode {
385 self.edge_mode
386 }
387
388 /// An alpha preserving flag.
389 ///
390 /// `preserveAlpha` in the SVG.
391 pub fn preserve_alpha(&self) -> bool {
392 self.preserve_alpha
393 }
394}
395
396/// A convolve matrix representation.
397///
398/// Used primarily by [`ConvolveMatrix`].
399#[derive(Clone, Debug)]
400pub struct ConvolveMatrixData {
401 pub(crate) target_x: u32,
402 pub(crate) target_y: u32,
403 pub(crate) columns: u32,
404 pub(crate) rows: u32,
405 pub(crate) data: Vec<f32>,
406}
407
408impl ConvolveMatrixData {
409 /// Returns a matrix's X target.
410 ///
411 /// `targetX` in the SVG.
412 pub fn target_x(&self) -> u32 {
413 self.target_x
414 }
415
416 /// Returns a matrix's Y target.
417 ///
418 /// `targetY` in the SVG.
419 pub fn target_y(&self) -> u32 {
420 self.target_y
421 }
422
423 /// Returns a number of columns in the matrix.
424 ///
425 /// Part of the `order` attribute in the SVG.
426 pub fn columns(&self) -> u32 {
427 self.columns
428 }
429
430 /// Returns a number of rows in the matrix.
431 ///
432 /// Part of the `order` attribute in the SVG.
433 pub fn rows(&self) -> u32 {
434 self.rows
435 }
436
437 /// The actual matrix.
438 pub fn data(&self) -> &[f32] {
439 &self.data
440 }
441}
442
443impl ConvolveMatrixData {
444 /// Creates a new `ConvolveMatrixData`.
445 ///
446 /// Returns `None` when:
447 ///
448 /// - `columns` * `rows` != `data.len()`
449 /// - `target_x` >= `columns`
450 /// - `target_y` >= `rows`
451 pub(crate) fn new(
452 target_x: u32,
453 target_y: u32,
454 columns: u32,
455 rows: u32,
456 data: Vec<f32>,
457 ) -> Option<Self> {
458 if (columns * rows) as usize != data.len() || target_x >= columns || target_y >= rows {
459 return None;
460 }
461
462 Some(ConvolveMatrixData {
463 target_x,
464 target_y,
465 columns,
466 rows,
467 data,
468 })
469 }
470
471 /// Returns a matrix value at the specified position.
472 ///
473 /// # Panics
474 ///
475 /// - When position is out of bounds.
476 pub fn get(&self, x: u32, y: u32) -> f32 {
477 self.data[(y * self.columns + x) as usize]
478 }
479}
480
481/// An edges processing mode.
482#[allow(missing_docs)]
483#[derive(Clone, Copy, PartialEq, Debug)]
484pub enum EdgeMode {
485 None,
486 Duplicate,
487 Wrap,
488}
489
490/// A displacement map filter primitive.
491///
492/// `feDisplacementMap` element in the SVG.
493#[derive(Clone, Debug)]
494pub struct DisplacementMap {
495 pub(crate) input1: Input,
496 pub(crate) input2: Input,
497 pub(crate) scale: f32,
498 pub(crate) x_channel_selector: ColorChannel,
499 pub(crate) y_channel_selector: ColorChannel,
500}
501
502impl DisplacementMap {
503 /// Identifies input for the given filter primitive.
504 ///
505 /// `in` in the SVG.
506 pub fn input1(&self) -> &Input {
507 &self.input1
508 }
509
510 /// Identifies input for the given filter primitive.
511 ///
512 /// `in2` in the SVG.
513 pub fn input2(&self) -> &Input {
514 &self.input2
515 }
516
517 /// Scale factor.
518 ///
519 /// `scale` in the SVG.
520 pub fn scale(&self) -> f32 {
521 self.scale
522 }
523
524 /// Indicates a source color channel along the X-axis.
525 ///
526 /// `xChannelSelector` in the SVG.
527 pub fn x_channel_selector(&self) -> ColorChannel {
528 self.x_channel_selector
529 }
530
531 /// Indicates a source color channel along the Y-axis.
532 ///
533 /// `yChannelSelector` in the SVG.
534 pub fn y_channel_selector(&self) -> ColorChannel {
535 self.y_channel_selector
536 }
537}
538
539/// A color channel.
540#[allow(missing_docs)]
541#[derive(Clone, Copy, PartialEq, Debug)]
542pub enum ColorChannel {
543 R,
544 G,
545 B,
546 A,
547}
548
549/// A drop shadow filter primitive.
550///
551/// This is essentially `feGaussianBlur`, `feOffset` and `feFlood` joined together.
552///
553/// `feDropShadow` element in the SVG.
554#[derive(Clone, Debug)]
555pub struct DropShadow {
556 pub(crate) input: Input,
557 pub(crate) dx: f32,
558 pub(crate) dy: f32,
559 pub(crate) std_dev_x: PositiveF32,
560 pub(crate) std_dev_y: PositiveF32,
561 pub(crate) color: Color,
562 pub(crate) opacity: Opacity,
563}
564
565impl DropShadow {
566 /// Identifies input for the given filter primitive.
567 ///
568 /// `in` in the SVG.
569 pub fn input(&self) -> &Input {
570 &self.input
571 }
572
573 /// The amount to offset the input graphic along the X-axis.
574 pub fn dx(&self) -> f32 {
575 self.dx
576 }
577
578 /// The amount to offset the input graphic along the Y-axis.
579 pub fn dy(&self) -> f32 {
580 self.dy
581 }
582
583 /// A standard deviation along the X-axis.
584 ///
585 /// `stdDeviation` in the SVG.
586 pub fn std_dev_x(&self) -> PositiveF32 {
587 self.std_dev_x
588 }
589
590 /// A standard deviation along the Y-axis.
591 ///
592 /// `stdDeviation` in the SVG.
593 pub fn std_dev_y(&self) -> PositiveF32 {
594 self.std_dev_y
595 }
596
597 /// A flood color.
598 ///
599 /// `flood-color` in the SVG.
600 pub fn color(&self) -> Color {
601 self.color
602 }
603
604 /// A flood opacity.
605 ///
606 /// `flood-opacity` in the SVG.
607 pub fn opacity(&self) -> Opacity {
608 self.opacity
609 }
610}
611
612/// A flood filter primitive.
613///
614/// `feFlood` element in the SVG.
615#[derive(Clone, Copy, Debug)]
616pub struct Flood {
617 pub(crate) color: Color,
618 pub(crate) opacity: Opacity,
619}
620
621impl Flood {
622 /// A flood color.
623 ///
624 /// `flood-color` in the SVG.
625 pub fn color(&self) -> Color {
626 self.color
627 }
628
629 /// A flood opacity.
630 ///
631 /// `flood-opacity` in the SVG.
632 pub fn opacity(&self) -> Opacity {
633 self.opacity
634 }
635}
636
637/// A Gaussian blur filter primitive.
638///
639/// `feGaussianBlur` element in the SVG.
640#[derive(Clone, Debug)]
641pub struct GaussianBlur {
642 pub(crate) input: Input,
643 pub(crate) std_dev_x: PositiveF32,
644 pub(crate) std_dev_y: PositiveF32,
645}
646
647impl GaussianBlur {
648 /// Identifies input for the given filter primitive.
649 ///
650 /// `in` in the SVG.
651 pub fn input(&self) -> &Input {
652 &self.input
653 }
654
655 /// A standard deviation along the X-axis.
656 ///
657 /// `stdDeviation` in the SVG.
658 pub fn std_dev_x(&self) -> PositiveF32 {
659 self.std_dev_x
660 }
661
662 /// A standard deviation along the Y-axis.
663 ///
664 /// `stdDeviation` in the SVG.
665 pub fn std_dev_y(&self) -> PositiveF32 {
666 self.std_dev_y
667 }
668}
669
670/// An image filter primitive.
671///
672/// `feImage` element in the SVG.
673#[derive(Clone, Debug)]
674pub struct Image {
675 pub(crate) root: Group,
676}
677
678impl Image {
679 /// `feImage` children.
680 pub fn root(&self) -> &Group {
681 &self.root
682 }
683}
684
685/// A diffuse lighting filter primitive.
686///
687/// `feDiffuseLighting` element in the SVG.
688#[derive(Clone, Debug)]
689pub struct DiffuseLighting {
690 pub(crate) input: Input,
691 pub(crate) surface_scale: f32,
692 pub(crate) diffuse_constant: f32,
693 pub(crate) lighting_color: Color,
694 pub(crate) light_source: LightSource,
695}
696
697impl DiffuseLighting {
698 /// Identifies input for the given filter primitive.
699 ///
700 /// `in` in the SVG.
701 pub fn input(&self) -> &Input {
702 &self.input
703 }
704
705 /// A surface scale.
706 ///
707 /// `surfaceScale` in the SVG.
708 pub fn surface_scale(&self) -> f32 {
709 self.surface_scale
710 }
711
712 /// A diffuse constant.
713 ///
714 /// `diffuseConstant` in the SVG.
715 pub fn diffuse_constant(&self) -> f32 {
716 self.diffuse_constant
717 }
718
719 /// A lighting color.
720 ///
721 /// `lighting-color` in the SVG.
722 pub fn lighting_color(&self) -> Color {
723 self.lighting_color
724 }
725
726 /// A light source.
727 pub fn light_source(&self) -> LightSource {
728 self.light_source
729 }
730}
731
732/// A specular lighting filter primitive.
733///
734/// `feSpecularLighting` element in the SVG.
735#[derive(Clone, Debug)]
736pub struct SpecularLighting {
737 pub(crate) input: Input,
738 pub(crate) surface_scale: f32,
739 pub(crate) specular_constant: f32,
740 pub(crate) specular_exponent: f32,
741 pub(crate) lighting_color: Color,
742 pub(crate) light_source: LightSource,
743}
744
745impl SpecularLighting {
746 /// Identifies input for the given filter primitive.
747 ///
748 /// `in` in the SVG.
749 pub fn input(&self) -> &Input {
750 &self.input
751 }
752
753 /// A surface scale.
754 ///
755 /// `surfaceScale` in the SVG.
756 pub fn surface_scale(&self) -> f32 {
757 self.surface_scale
758 }
759
760 /// A specular constant.
761 ///
762 /// `specularConstant` in the SVG.
763 pub fn specular_constant(&self) -> f32 {
764 self.specular_constant
765 }
766
767 /// A specular exponent.
768 ///
769 /// Should be in 1..128 range.
770 ///
771 /// `specularExponent` in the SVG.
772 pub fn specular_exponent(&self) -> f32 {
773 self.specular_exponent
774 }
775
776 /// A lighting color.
777 ///
778 /// `lighting-color` in the SVG.
779 pub fn lighting_color(&self) -> Color {
780 self.lighting_color
781 }
782
783 /// A light source.
784 pub fn light_source(&self) -> LightSource {
785 self.light_source
786 }
787}
788
789/// A light source kind.
790#[allow(missing_docs)]
791#[derive(Clone, Copy, Debug)]
792pub enum LightSource {
793 DistantLight(DistantLight),
794 PointLight(PointLight),
795 SpotLight(SpotLight),
796}
797
798/// A distant light source.
799///
800/// `feDistantLight` element in the SVG.
801#[derive(Clone, Copy, Debug)]
802pub struct DistantLight {
803 /// Direction angle for the light source on the XY plane (clockwise),
804 /// in degrees from the x axis.
805 ///
806 /// `azimuth` in the SVG.
807 pub azimuth: f32,
808
809 /// Direction angle for the light source from the XY plane towards the z axis, in degrees.
810 ///
811 /// `elevation` in the SVG.
812 pub elevation: f32,
813}
814
815/// A point light source.
816///
817/// `fePointLight` element in the SVG.
818#[derive(Clone, Copy, Debug)]
819pub struct PointLight {
820 /// X location for the light source.
821 ///
822 /// `x` in the SVG.
823 pub x: f32,
824
825 /// Y location for the light source.
826 ///
827 /// `y` in the SVG.
828 pub y: f32,
829
830 /// Z location for the light source.
831 ///
832 /// `z` in the SVG.
833 pub z: f32,
834}
835
836/// A spot light source.
837///
838/// `feSpotLight` element in the SVG.
839#[derive(Clone, Copy, Debug)]
840pub struct SpotLight {
841 /// X location for the light source.
842 ///
843 /// `x` in the SVG.
844 pub x: f32,
845
846 /// Y location for the light source.
847 ///
848 /// `y` in the SVG.
849 pub y: f32,
850
851 /// Z location for the light source.
852 ///
853 /// `z` in the SVG.
854 pub z: f32,
855
856 /// X point at which the light source is pointing.
857 ///
858 /// `pointsAtX` in the SVG.
859 pub points_at_x: f32,
860
861 /// Y point at which the light source is pointing.
862 ///
863 /// `pointsAtY` in the SVG.
864 pub points_at_y: f32,
865
866 /// Z point at which the light source is pointing.
867 ///
868 /// `pointsAtZ` in the SVG.
869 pub points_at_z: f32,
870
871 /// Exponent value controlling the focus for the light source.
872 ///
873 /// `specularExponent` in the SVG.
874 pub specular_exponent: PositiveF32,
875
876 /// A limiting cone which restricts the region where the light is projected.
877 ///
878 /// `limitingConeAngle` in the SVG.
879 pub limiting_cone_angle: Option<f32>,
880}
881
882/// A merge filter primitive.
883///
884/// `feMerge` element in the SVG.
885#[derive(Clone, Debug)]
886pub struct Merge {
887 pub(crate) inputs: Vec<Input>,
888}
889
890impl Merge {
891 /// List of input layers that should be merged.
892 ///
893 /// List of `feMergeNode`'s in the SVG.
894 pub fn inputs(&self) -> &[Input] {
895 &self.inputs
896 }
897}
898
899/// A morphology filter primitive.
900///
901/// `feMorphology` element in the SVG.
902#[derive(Clone, Debug)]
903pub struct Morphology {
904 pub(crate) input: Input,
905 pub(crate) operator: MorphologyOperator,
906 pub(crate) radius_x: PositiveF32,
907 pub(crate) radius_y: PositiveF32,
908}
909
910impl Morphology {
911 /// Identifies input for the given filter primitive.
912 ///
913 /// `in` in the SVG.
914 pub fn input(&self) -> &Input {
915 &self.input
916 }
917
918 /// A filter operator.
919 ///
920 /// `operator` in the SVG.
921 pub fn operator(&self) -> MorphologyOperator {
922 self.operator
923 }
924
925 /// A filter radius along the X-axis.
926 ///
927 /// A value of zero disables the effect of the given filter primitive.
928 ///
929 /// `radius` in the SVG.
930 pub fn radius_x(&self) -> PositiveF32 {
931 self.radius_x
932 }
933
934 /// A filter radius along the Y-axis.
935 ///
936 /// A value of zero disables the effect of the given filter primitive.
937 ///
938 /// `radius` in the SVG.
939 pub fn radius_y(&self) -> PositiveF32 {
940 self.radius_y
941 }
942}
943
944/// A morphology operation.
945#[allow(missing_docs)]
946#[derive(Clone, Copy, PartialEq, Debug)]
947pub enum MorphologyOperator {
948 Erode,
949 Dilate,
950}
951
952/// An offset filter primitive.
953///
954/// `feOffset` element in the SVG.
955#[derive(Clone, Debug)]
956pub struct Offset {
957 pub(crate) input: Input,
958 pub(crate) dx: f32,
959 pub(crate) dy: f32,
960}
961
962impl Offset {
963 /// Identifies input for the given filter primitive.
964 ///
965 /// `in` in the SVG.
966 pub fn input(&self) -> &Input {
967 &self.input
968 }
969
970 /// The amount to offset the input graphic along the X-axis.
971 pub fn dx(&self) -> f32 {
972 self.dx
973 }
974
975 /// The amount to offset the input graphic along the Y-axis.
976 pub fn dy(&self) -> f32 {
977 self.dy
978 }
979}
980
981/// A tile filter primitive.
982///
983/// `feTile` element in the SVG.
984#[derive(Clone, Debug)]
985pub struct Tile {
986 pub(crate) input: Input,
987}
988
989impl Tile {
990 /// Identifies input for the given filter primitive.
991 ///
992 /// `in` in the SVG.
993 pub fn input(&self) -> &Input {
994 &self.input
995 }
996}
997
998/// A turbulence generation filter primitive.
999///
1000/// `feTurbulence` element in the SVG.
1001#[derive(Clone, Copy, Debug)]
1002pub struct Turbulence {
1003 pub(crate) base_frequency_x: PositiveF32,
1004 pub(crate) base_frequency_y: PositiveF32,
1005 pub(crate) num_octaves: u32,
1006 pub(crate) seed: i32,
1007 pub(crate) stitch_tiles: bool,
1008 pub(crate) kind: TurbulenceKind,
1009}
1010
1011impl Turbulence {
1012 /// Identifies the base frequency for the noise function.
1013 ///
1014 /// `baseFrequency` in the SVG.
1015 pub fn base_frequency_x(&self) -> PositiveF32 {
1016 self.base_frequency_x
1017 }
1018
1019 /// Identifies the base frequency for the noise function.
1020 ///
1021 /// `baseFrequency` in the SVG.
1022 pub fn base_frequency_y(&self) -> PositiveF32 {
1023 self.base_frequency_y
1024 }
1025
1026 /// Identifies the number of octaves for the noise function.
1027 ///
1028 /// `numOctaves` in the SVG.
1029 pub fn num_octaves(&self) -> u32 {
1030 self.num_octaves
1031 }
1032
1033 /// The starting number for the pseudo random number generator.
1034 ///
1035 /// `seed` in the SVG.
1036 pub fn seed(&self) -> i32 {
1037 self.seed
1038 }
1039
1040 /// Smooth transitions at the border of tiles.
1041 ///
1042 /// `stitchTiles` in the SVG.
1043 pub fn stitch_tiles(&self) -> bool {
1044 self.stitch_tiles
1045 }
1046
1047 /// Indicates whether the filter primitive should perform a noise or turbulence function.
1048 ///
1049 /// `type` in the SVG.
1050 pub fn kind(&self) -> TurbulenceKind {
1051 self.kind
1052 }
1053}
1054
1055/// A turbulence kind for the `feTurbulence` filter.
1056#[allow(missing_docs)]
1057#[derive(Clone, Copy, PartialEq, Debug)]
1058pub enum TurbulenceKind {
1059 FractalNoise,
1060 Turbulence,
1061}
1062