1
//! SVG Elements.
2

            
3
use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
4
use std::collections::{HashMap, HashSet};
5
use std::fmt;
6
use std::sync::OnceLock;
7

            
8
use crate::accept_language::UserLanguage;
9
use crate::bbox::BoundingBox;
10
use crate::cond::{RequiredExtensions, RequiredFeatures, SystemLanguage};
11
use crate::css::{Declaration, Origin};
12
use crate::document::AcquiredNodes;
13
use crate::drawing_ctx::{DrawingCtx, Viewport};
14
use crate::error::*;
15
use crate::filter::Filter;
16
use crate::filters::{
17
    blend::FeBlend,
18
    color_matrix::FeColorMatrix,
19
    component_transfer::{FeComponentTransfer, FeFuncA, FeFuncB, FeFuncG, FeFuncR},
20
    composite::FeComposite,
21
    convolve_matrix::FeConvolveMatrix,
22
    displacement_map::FeDisplacementMap,
23
    drop_shadow::FeDropShadow,
24
    flood::FeFlood,
25
    gaussian_blur::FeGaussianBlur,
26
    image::FeImage,
27
    lighting::{FeDiffuseLighting, FeDistantLight, FePointLight, FeSpecularLighting, FeSpotLight},
28
    merge::{FeMerge, FeMergeNode},
29
    morphology::FeMorphology,
30
    offset::FeOffset,
31
    tile::FeTile,
32
    turbulence::FeTurbulence,
33
    FilterEffect,
34
};
35
use crate::gradient::{LinearGradient, RadialGradient, Stop};
36
use crate::image::Image;
37
use crate::marker::Marker;
38
use crate::node::*;
39
use crate::pattern::Pattern;
40
use crate::properties::{ComputedValues, SpecifiedValues};
41
use crate::rsvg_log;
42
use crate::session::Session;
43
use crate::shapes::{Circle, Ellipse, Line, Path, Polygon, Polyline, Rect};
44
use crate::structure::{ClipPath, Group, Link, Mask, NonRendering, Svg, Switch, Symbol, Use};
45
use crate::style::Style;
46
use crate::text::{TRef, TSpan, Text};
47
use crate::xml::Attributes;
48

            
49
pub trait ElementTrait {
50
    /// Sets per-element attributes.
51
    ///
52
    /// Each element is supposed to iterate the `attributes`, and parse any ones it needs.
53
    /// SVG specifies that unknown attributes should be ignored, and known attributes with invalid
54
    /// values should be ignored so that the attribute ends up with its "initial value".
55
    ///
56
    /// You can use the [`set_attribute`] function to do that.
57
1015735
    fn set_attributes(&mut self, _attributes: &Attributes, _session: &Session) {}
58

            
59
    /// Draw an element.
60
    ///
61
    /// Each element is supposed to draw itself as needed.
62
680
    fn draw(
63
        &self,
64
        _node: &Node,
65
        _acquired_nodes: &mut AcquiredNodes<'_>,
66
        _cascaded: &CascadedValues<'_>,
67
        _viewport: &Viewport,
68
        draw_ctx: &mut DrawingCtx,
69
        _clipping: bool,
70
    ) -> Result<BoundingBox, InternalRenderingError> {
71
        // by default elements don't draw themselves
72
680
        Ok(draw_ctx.empty_bbox())
73
680
    }
74
}
75

            
76
/// Sets `dest` if `parse_result` is `Ok()`, otherwise just logs the error.
77
///
78
/// Implementations of the [`ElementTrait`] trait generally scan a list of attributes
79
/// for the ones they can handle, and parse their string values.  Per the SVG spec, an attribute
80
/// with an invalid value should be ignored, and it should fall back to the default value.
81
///
82
/// In librsvg, those default values are set in each element's implementation of the [`Default`] trait:
83
/// at element creation time, each element gets initialized to its `Default`, and then each attribute
84
/// gets parsed.  This function will set that attribute's value only if parsing was successful.
85
///
86
/// In case the `parse_result` is an error, this function will log an appropriate notice
87
/// via the [`Session`].
88
8065
pub fn set_attribute<T>(dest: &mut T, parse_result: Result<T, ElementError>, session: &Session) {
89
8065
    match parse_result {
90
8062
        Ok(v) => *dest = v,
91
3
        Err(e) => {
92
            // FIXME: this does not provide a clue of what was the problematic element.
93
            // We need tracking of the current parsing position to do that.
94
3
            rsvg_log!(session, "ignoring attribute with invalid value: {}", e);
95
3
        }
96
    }
97
8065
}
98

            
99
pub struct Element {
100
    element_name: QualName,
101
    attributes: Attributes,
102
    specified_values: SpecifiedValues,
103
    important_styles: HashSet<QualName>,
104
    values: ComputedValues,
105
    required_extensions: Option<RequiredExtensions>,
106
    required_features: Option<RequiredFeatures>,
107
    system_language: Option<SystemLanguage>,
108
    pub element_data: ElementData,
109
}
110

            
111
impl fmt::Display for Element {
112
2005799
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113
2005799
        write!(f, "{}", self.element_name().local)?;
114
2005799
        write!(f, " id={}", self.get_id().unwrap_or("None"))?;
115
2005799
        Ok(())
116
2005799
    }
117
}
118

            
119
/// Parsed contents of an element node in the DOM.
120
///
121
/// This enum uses `Box<Foo>` in order to make each variant the size of
122
/// a pointer.
123
pub enum ElementData {
124
    Circle(Box<Circle>),
125
    ClipPath(Box<ClipPath>),
126
    Ellipse(Box<Ellipse>),
127
    Filter(Box<Filter>),
128
    Group(Box<Group>),
129
    Image(Box<Image>),
130
    Line(Box<Line>),
131
    LinearGradient(Box<LinearGradient>),
132
    Link(Box<Link>),
133
    Marker(Box<Marker>),
134
    Mask(Box<Mask>),
135
    NonRendering(Box<NonRendering>),
136
    Path(Box<Path>),
137
    Pattern(Box<Pattern>),
138
    Polygon(Box<Polygon>),
139
    Polyline(Box<Polyline>),
140
    RadialGradient(Box<RadialGradient>),
141
    Rect(Box<Rect>),
142
    Stop(Box<Stop>),
143
    Style(Box<Style>),
144
    Svg(Box<Svg>),
145
    Switch(Box<Switch>),
146
    Symbol(Box<Symbol>),
147
    Text(Box<Text>),
148
    TRef(Box<TRef>),
149
    TSpan(Box<TSpan>),
150
    Use(Box<Use>),
151

            
152
    // Filter primitives, these start with "Fe" as element names are e.g. "feBlend"
153
    FeBlend(Box<FeBlend>),
154
    FeColorMatrix(Box<FeColorMatrix>),
155
    FeComponentTransfer(Box<FeComponentTransfer>),
156
    FeComposite(Box<FeComposite>),
157
    FeConvolveMatrix(Box<FeConvolveMatrix>),
158
    FeDiffuseLighting(Box<FeDiffuseLighting>),
159
    FeDisplacementMap(Box<FeDisplacementMap>),
160
    FeDistantLight(Box<FeDistantLight>),
161
    FeDropShadow(Box<FeDropShadow>),
162
    FeFlood(Box<FeFlood>),
163
    FeFuncA(Box<FeFuncA>),
164
    FeFuncB(Box<FeFuncB>),
165
    FeFuncG(Box<FeFuncG>),
166
    FeFuncR(Box<FeFuncR>),
167
    FeGaussianBlur(Box<FeGaussianBlur>),
168
    FeImage(Box<FeImage>),
169
    FeMerge(Box<FeMerge>),
170
    FeMergeNode(Box<FeMergeNode>),
171
    FeMorphology(Box<FeMorphology>),
172
    FeOffset(Box<FeOffset>),
173
    FePointLight(Box<FePointLight>),
174
    FeSpecularLighting(Box<FeSpecularLighting>),
175
    FeSpotLight(Box<FeSpotLight>),
176
    FeTile(Box<FeTile>),
177
    FeTurbulence(Box<FeTurbulence>),
178
}
179

            
180
#[rustfmt::skip]
181
1017188
fn get_element_creators() -> &'static HashMap<&'static str, (ElementDataCreateFn, ElementCreateFlags)> {
182
    use ElementCreateFlags::*;
183

            
184
1017300
    ELEMENT_CREATORS.get_or_init(|| {
185
        // Lines in comments are elements that we don't support.
186
224
        let creators_table: Vec<(&str, ElementDataCreateFn, ElementCreateFlags)> = vec![
187
            // name, supports_class, create_fn
188
112
            ("a",                   create_link,                  Default),
189
            /* ("altGlyph",         ), */
190
            /* ("altGlyphDef",      ), */
191
            /* ("altGlyphItem",     ), */
192
            /* ("animate",          ), */
193
            /* ("animateColor",     ), */
194
            /* ("animateMotion",    ), */
195
            /* ("animateTransform", ), */
196
112
            ("circle",              create_circle,                Default),
197
112
            ("clipPath",            create_clip_path,             Default),
198
            /* ("color-profile",    ), */
199
            /* ("cursor",           ), */
200
112
            ("defs",                create_defs,                  Default),
201
            /* ("desc",             ), */
202
112
            ("ellipse",             create_ellipse,               Default),
203
112
            ("feBlend",             create_fe_blend,              Default),
204
112
            ("feColorMatrix",       create_fe_color_matrix,       Default),
205
112
            ("feComponentTransfer", create_fe_component_transfer, Default),
206
112
            ("feComposite",         create_fe_composite,          Default),
207
112
            ("feConvolveMatrix",    create_fe_convolve_matrix,    Default),
208
112
            ("feDiffuseLighting",   create_fe_diffuse_lighting,   Default),
209
112
            ("feDisplacementMap",   create_fe_displacement_map,   Default),
210
112
            ("feDistantLight",      create_fe_distant_light,      IgnoreClass),
211
112
            ("feDropShadow",        create_fe_drop_shadow,        Default),
212
112
            ("feFuncA",             create_fe_func_a,             IgnoreClass),
213
112
            ("feFuncB",             create_fe_func_b,             IgnoreClass),
214
112
            ("feFuncG",             create_fe_func_g,             IgnoreClass),
215
112
            ("feFuncR",             create_fe_func_r,             IgnoreClass),
216
112
            ("feFlood",             create_fe_flood,              Default),
217
112
            ("feGaussianBlur",      create_fe_gaussian_blur,      Default),
218
112
            ("feImage",             create_fe_image,              Default),
219
112
            ("feMerge",             create_fe_merge,              Default),
220
112
            ("feMergeNode",         create_fe_merge_node,         IgnoreClass),
221
112
            ("feMorphology",        create_fe_morphology,         Default),
222
112
            ("feOffset",            create_fe_offset,             Default),
223
112
            ("fePointLight",        create_fe_point_light,        IgnoreClass),
224
112
            ("feSpecularLighting",  create_fe_specular_lighting,  Default),
225
112
            ("feSpotLight",         create_fe_spot_light,         IgnoreClass),
226
112
            ("feTile",              create_fe_tile,               Default),
227
112
            ("feTurbulence",        create_fe_turbulence,         Default),
228
112
            ("filter",              create_filter,                Default),
229
            /* ("font",             ), */
230
            /* ("font-face",        ), */
231
            /* ("font-face-format", ), */
232
            /* ("font-face-name",   ), */
233
            /* ("font-face-src",    ), */
234
            /* ("font-face-uri",    ), */
235
            /* ("foreignObject",    ), */
236
112
            ("g",                   create_group,                 Default),
237
            /* ("glyph",            ), */
238
            /* ("glyphRef",         ), */
239
            /* ("hkern",            ), */
240
112
            ("image",               create_image,                 Default),
241
112
            ("line",                create_line,                  Default),
242
112
            ("linearGradient",      create_linear_gradient,       Default),
243
112
            ("marker",              create_marker,                Default),
244
112
            ("mask",                create_mask,                  Default),
245
            /* ("metadata",         ), */
246
            /* ("missing-glyph",    ), */
247
            /* ("mpath",            ), */
248
            /* ("multiImage",       ), */
249
112
            ("path",                create_path,                  Default),
250
112
            ("pattern",             create_pattern,               Default),
251
112
            ("polygon",             create_polygon,               Default),
252
112
            ("polyline",            create_polyline,              Default),
253
112
            ("radialGradient",      create_radial_gradient,       Default),
254
112
            ("rect",                create_rect,                  Default),
255
            /* ("script",           ), */
256
            /* ("set",              ), */
257
112
            ("stop",                create_stop,                  Default),
258
112
            ("style",               create_style,                 IgnoreClass),
259
            /* ("subImage",         ), */
260
            /* ("subImageRef",      ), */
261
112
            ("svg",                 create_svg,                   Default),
262
112
            ("switch",              create_switch,                Default),
263
112
            ("symbol",              create_symbol,                Default),
264
112
            ("text",                create_text,                  Default),
265
            /* ("textPath",         ), */
266
            /* ("title",            ), */
267
112
            ("tref",                create_tref,                  Default),
268
112
            ("tspan",               create_tspan,                 Default),
269
112
            ("use",                 create_use,                   Default),
270
            /* ("view",             ), */
271
            /* ("vkern",            ), */
272
        ];
273

            
274
5936
        creators_table.into_iter().map(|(n, c, f)| (n, (c, f))).collect()
275
112
    })
276
1017188
}
277

            
278
impl Element {
279
    /// Takes an XML element name and consumes a list of attribute/value pairs to create an [`Element`].
280
    ///
281
    /// This operation does not fail.  Unknown element names simply produce a [`NonRendering`]
282
    /// element.
283
1022251
    pub fn new(session: &Session, name: &QualName, mut attributes: Attributes) -> Element {
284
2039461
        let (create_fn, flags): (ElementDataCreateFn, ElementCreateFlags) = if name.ns == ns!(svg) {
285
1017214
            match get_element_creators().get(name.local.as_ref()) {
286
                // hack in the SVG namespace for supported element names
287
1015482
                Some(&(create_fn, flags)) => (create_fn, flags),
288

            
289
                // Whenever we encounter a element name we don't understand, represent it as a
290
                // non-rendering element.  This is like a group, but it doesn't do any rendering
291
                // of children.  The effect is that we will ignore all children of unknown elements.
292
1728
                None => (create_non_rendering, ElementCreateFlags::Default),
293
            }
294
        } else {
295
5066
            (create_non_rendering, ElementCreateFlags::Default)
296
        };
297

            
298
1022276
        if flags == ElementCreateFlags::IgnoreClass {
299
197
            attributes.clear_class();
300
        };
301

            
302
1022274
        let element_data = create_fn(session, &attributes);
303

            
304
1022359
        let mut e = Self {
305
1022215
            element_name: name.clone(),
306
1022215
            attributes,
307
1022215
            specified_values: Default::default(),
308
1022215
            important_styles: Default::default(),
309
1022215
            values: Default::default(),
310
1022363
            required_extensions: Default::default(),
311
1022293
            required_features: Default::default(),
312
1022291
            system_language: Default::default(),
313
1022359
            element_data,
314
        };
315

            
316
1022359
        e.set_conditional_processing_attributes(session);
317
1022287
        e.set_presentation_attributes(session);
318

            
319
1022215
        e
320
1022215
    }
321

            
322
2747198
    pub fn element_name(&self) -> &QualName {
323
2747198
        &self.element_name
324
2747198
    }
325

            
326
456
    pub fn get_attributes(&self) -> &Attributes {
327
456
        &self.attributes
328
456
    }
329

            
330
3023615
    pub fn get_id(&self) -> Option<&str> {
331
3023615
        self.attributes.get_id()
332
3023615
    }
333

            
334
924
    pub fn get_class(&self) -> Option<&str> {
335
924
        self.attributes.get_class()
336
924
    }
337

            
338
22229
    pub fn inherit_xml_lang(&mut self, parent: Option<Node>) {
339
22229
        self.specified_values
340
22229
            .inherit_xml_lang(&mut self.values, parent);
341
22229
    }
342

            
343
1467044
    pub fn get_specified_values(&self) -> &SpecifiedValues {
344
        &self.specified_values
345
1467044
    }
346

            
347
1104463
    pub fn get_computed_values(&self) -> &ComputedValues {
348
1104463
        &self.values
349
1104463
    }
350

            
351
22236
    pub fn set_computed_values(&mut self, values: &ComputedValues) {
352
22236
        self.values = values.clone();
353
22236
    }
354

            
355
19
    pub fn get_cond(&self, user_language: &UserLanguage) -> bool {
356
20
        self.required_extensions
357
            .as_ref()
358
1
            .map(|v| v.eval())
359
            .unwrap_or(true)
360
18
            && self
361
                .required_features
362
                .as_ref()
363
2
                .map(|v| v.eval())
364
                .unwrap_or(true)
365
34
            && self
366
                .system_language
367
                .as_ref()
368
28
                .map(|v| v.eval(user_language))
369
                .unwrap_or(true)
370
19
    }
371

            
372
1022287
    fn set_conditional_processing_attributes(&mut self, session: &Session) {
373
1111489
        for (attr, value) in self.attributes.iter() {
374
89202
            match attr.expanded() {
375
1
                expanded_name!("", "requiredExtensions") => {
376
1
                    self.required_extensions = Some(RequiredExtensions::from_attribute(value));
377
                }
378

            
379
2
                expanded_name!("", "requiredFeatures") => {
380
2
                    self.required_features = Some(RequiredFeatures::from_attribute(value));
381
                }
382

            
383
13
                expanded_name!("", "systemLanguage") => {
384
13
                    self.system_language = Some(SystemLanguage::from_attribute(value, session));
385
                }
386

            
387
                _ => {}
388
            }
389
89202
        }
390
1022287
    }
391

            
392
    /// Hands the `attrs` to the node's state, to apply the presentation attributes.
393
1022288
    fn set_presentation_attributes(&mut self, session: &Session) {
394
1022288
        self.specified_values
395
1022288
            .parse_presentation_attributes(session, &self.attributes);
396
1022288
    }
397

            
398
    // Applies a style declaration to the node's specified_values
399
3454
    pub fn apply_style_declaration(&mut self, declaration: &Declaration, origin: Origin) {
400
3454
        self.specified_values.set_property_from_declaration(
401
            declaration,
402
            origin,
403
3454
            &mut self.important_styles,
404
        );
405
3454
    }
406

            
407
    /// Applies CSS styles from the "style" attribute
408
22229
    pub fn set_style_attribute(&mut self, session: &Session) {
409
22229
        let style = self
410
            .attributes
411
            .iter()
412
83450
            .find(|(attr, _)| attr.expanded() == expanded_name!("", "style"))
413
5217
            .map(|(_, value)| value);
414

            
415
22229
        if let Some(style) = style {
416
5213
            self.specified_values.parse_style_declarations(
417
                style,
418
5213
                Origin::Author,
419
5213
                &mut self.important_styles,
420
                session,
421
            );
422
        }
423
22229
    }
424

            
425
    #[rustfmt::skip]
426
816
    pub fn as_filter_effect(&self) -> Option<&dyn FilterEffect> {
427
        use ElementData::*;
428

            
429
816
        match &self.element_data {
430
16
            FeBlend(fe) =>              Some(&**fe),
431
28
            FeColorMatrix(fe) =>        Some(&**fe),
432
28
            FeComponentTransfer(fe) =>  Some(&**fe),
433
76
            FeComposite(fe) =>          Some(&**fe),
434
64
            FeConvolveMatrix(fe) =>     Some(&**fe),
435
96
            FeDiffuseLighting(fe) =>    Some(&**fe),
436
4
            FeDisplacementMap(fe) =>    Some(&**fe),
437
2
            FeDropShadow(fe) =>         Some(&**fe),
438
64
            FeFlood(fe) =>              Some(&**fe),
439
82
            FeGaussianBlur(fe) =>       Some(&**fe),
440
134
            FeImage(fe) =>              Some(&**fe),
441
42
            FeMerge(fe) =>              Some(&**fe),
442
10
            FeMorphology(fe) =>         Some(&**fe),
443
46
            FeOffset(fe) =>             Some(&**fe),
444
78
            FeSpecularLighting(fe) =>   Some(&**fe),
445
4
            FeTile(fe) =>               Some(&**fe),
446
38
            FeTurbulence(fe) =>         Some(&**fe),
447
4
            _ => None,
448
        }
449
816
    }
450

            
451
    /// Returns whether an element of a particular type is only accessed by reference
452
    // from other elements' attributes.  The element could in turn cause other nodes
453
    // to get referenced, potentially causing reference cycles.
454
1001010
    pub fn is_accessed_by_reference(&self) -> bool {
455
        use ElementData::*;
456

            
457
1001010
        matches!(
458
1001010
            self.element_data,
459
            ClipPath(_)
460
                | Filter(_)
461
                | LinearGradient(_)
462
                | Marker(_)
463
                | Mask(_)
464
                | Pattern(_)
465
                | RadialGradient(_)
466
        )
467
1001010
    }
468

            
469
    /// The main drawing function for elements.
470
1957659
    pub fn draw(
471
        &self,
472
        node: &Node,
473
        acquired_nodes: &mut AcquiredNodes<'_>,
474
        cascaded: &CascadedValues<'_>,
475
        viewport: &Viewport,
476
        draw_ctx: &mut DrawingCtx,
477
        clipping: bool,
478
    ) -> Result<BoundingBox, InternalRenderingError> {
479
1957659
        let values = cascaded.get();
480
1957659
        if values.is_displayed() {
481
1955552
            self.element_data
482
                .draw(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
483
        } else {
484
2107
            Ok(draw_ctx.empty_bbox())
485
        }
486
1957659
    }
487
}
488

            
489
impl ElementData {
490
    /// Dispatcher for the draw method of concrete element implementations.
491
    #[rustfmt::skip]
492
1956977
    fn draw(
493
        &self,
494
        node: &Node,
495
        acquired_nodes: &mut AcquiredNodes<'_>,
496
        cascaded: &CascadedValues<'_>,
497
        viewport: &Viewport,
498
        draw_ctx: &mut DrawingCtx,
499
        clipping: bool,
500
    ) -> Result<BoundingBox, InternalRenderingError> {
501
        use ElementData::*;
502

            
503
3913954
        let data: &dyn ElementTrait = match self {
504
254
            Circle(d) =>               &**d,
505
            ClipPath(d) =>             &**d,
506
21
            Ellipse(d) =>              &**d,
507
32
            Filter(d) =>               &**d,
508
505546
            Group(d) =>                &**d,
509
111
            Image(d) =>                &**d,
510
129
            Line(d) =>                 &**d,
511
            LinearGradient(d) =>       &**d,
512
3
            Link(d) =>                 &**d,
513
            Marker(d) =>               &**d,
514
            Mask(d) =>                 &**d,
515
649
            NonRendering(d) =>         &**d,
516
1652
            Path(d) =>                 &**d,
517
            Pattern(d) =>              &**d,
518
34
            Polygon(d) =>              &**d,
519
41
            Polyline(d) =>             &**d,
520
            RadialGradient(d) =>       &**d,
521
946297
            Rect(d) =>                 &**d,
522
            Stop(d) =>                 &**d,
523
            Style(d) =>                &**d,
524
1119
            Svg(d) =>                  &**d,
525
10
            Switch(d) =>               &**d,
526
            Symbol(d) =>               &**d,
527
914
            Text(d) =>                 &**d,
528
            TRef(d) =>                 &**d,
529
            TSpan(d) =>                &**d,
530
500165
            Use(d) =>                  &**d,
531

            
532
            FeBlend(d) =>              &**d,
533
            FeColorMatrix(d) =>        &**d,
534
            FeComponentTransfer(d) =>  &**d,
535
            FeComposite(d) =>          &**d,
536
            FeConvolveMatrix(d) =>     &**d,
537
            FeDiffuseLighting(d) =>    &**d,
538
            FeDisplacementMap(d) =>    &**d,
539
            FeDistantLight(d) =>       &**d,
540
            FeDropShadow(d) =>         &**d,
541
            FeFlood(d) =>              &**d,
542
            FeFuncA(d) =>              &**d,
543
            FeFuncB(d) =>              &**d,
544
            FeFuncG(d) =>              &**d,
545
            FeFuncR(d) =>              &**d,
546
            FeGaussianBlur(d) =>       &**d,
547
            FeImage(d) =>              &**d,
548
            FeMerge(d) =>              &**d,
549
            FeMergeNode(d) =>          &**d,
550
            FeMorphology(d) =>         &**d,
551
            FeOffset(d) =>             &**d,
552
            FePointLight(d) =>         &**d,
553
            FeSpecularLighting(d) =>   &**d,
554
            FeSpotLight(d) =>          &**d,
555
            FeTile(d) =>               &**d,
556
            FeTurbulence(d) =>         &**d,
557
        };
558

            
559
1956977
        data.draw(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
560
1956977
    }
561
}
562

            
563
macro_rules! e {
564
    ($name:ident, $element_type:ident) => {
565
1022281
        pub fn $name(session: &Session, attributes: &Attributes) -> ElementData {
566
1022281
            let mut payload = Box::<$element_type>::default();
567
1022281
            payload.set_attributes(attributes, session);
568

            
569
1022281
            ElementData::$element_type(payload)
570
1022281
        }
571
    };
572
}
573

            
574
#[rustfmt::skip]
575
mod creators {
576
    use super::*;
577

            
578
    e!(create_circle,                   Circle);
579
    e!(create_clip_path,                ClipPath);
580
    e!(create_defs,                     NonRendering);
581
    e!(create_ellipse,                  Ellipse);
582
    e!(create_fe_blend,                 FeBlend);
583
    e!(create_fe_color_matrix,          FeColorMatrix);
584
    e!(create_fe_component_transfer,    FeComponentTransfer);
585
    e!(create_fe_func_a,                FeFuncA);
586
    e!(create_fe_func_b,                FeFuncB);
587
    e!(create_fe_func_g,                FeFuncG);
588
    e!(create_fe_func_r,                FeFuncR);
589
    e!(create_fe_composite,             FeComposite);
590
    e!(create_fe_convolve_matrix,       FeConvolveMatrix);
591
    e!(create_fe_diffuse_lighting,      FeDiffuseLighting);
592
    e!(create_fe_displacement_map,      FeDisplacementMap);
593
    e!(create_fe_distant_light,         FeDistantLight);
594
    e!(create_fe_drop_shadow,           FeDropShadow);
595
    e!(create_fe_flood,                 FeFlood);
596
    e!(create_fe_gaussian_blur,         FeGaussianBlur);
597
    e!(create_fe_image,                 FeImage);
598
    e!(create_fe_merge,                 FeMerge);
599
    e!(create_fe_merge_node,            FeMergeNode);
600
    e!(create_fe_morphology,            FeMorphology);
601
    e!(create_fe_offset,                FeOffset);
602
    e!(create_fe_point_light,           FePointLight);
603
    e!(create_fe_specular_lighting,     FeSpecularLighting);
604
    e!(create_fe_spot_light,            FeSpotLight);
605
    e!(create_fe_tile,                  FeTile);
606
    e!(create_fe_turbulence,            FeTurbulence);
607
    e!(create_filter,                   Filter);
608
    e!(create_group,                    Group);
609
    e!(create_image,                    Image);
610
    e!(create_line,                     Line);
611
    e!(create_linear_gradient,          LinearGradient);
612
    e!(create_link,                     Link);
613
    e!(create_marker,                   Marker);
614
    e!(create_mask,                     Mask);
615
    e!(create_non_rendering,            NonRendering);
616
    e!(create_path,                     Path);
617
    e!(create_pattern,                  Pattern);
618
    e!(create_polygon,                  Polygon);
619
    e!(create_polyline,                 Polyline);
620
    e!(create_radial_gradient,          RadialGradient);
621
    e!(create_rect,                     Rect);
622
    e!(create_stop,                     Stop);
623
    e!(create_style,                    Style);
624
    e!(create_svg,                      Svg);
625
    e!(create_switch,                   Switch);
626
    e!(create_symbol,                   Symbol);
627
    e!(create_text,                     Text);
628
    e!(create_tref,                     TRef);
629
    e!(create_tspan,                    TSpan);
630
    e!(create_use,                      Use);
631

            
632
    /* Hack to make multiImage sort-of work
633
     *
634
     * disabled for now, as markup5ever doesn't have local names for
635
     * multiImage, subImage, subImageRef.  Maybe we can just... create them ourselves?
636
     *
637
     * Is multiImage even in SVG2?
638
     */
639
    /*
640
    e!(create_multi_image,              Switch);
641
    e!(create_sub_image,                Group);
642
    e!(create_sub_image_ref,            Image);
643
    */
644
}
645

            
646
use creators::*;
647

            
648
type ElementDataCreateFn = fn(session: &Session, attributes: &Attributes) -> ElementData;
649

            
650
1022247
#[derive(Copy, Clone, PartialEq)]
651
enum ElementCreateFlags {
652
    Default,
653
    IgnoreClass,
654
}
655

            
656
static ELEMENT_CREATORS: OnceLock<
657
    HashMap<&'static str, (ElementDataCreateFn, ElementCreateFlags)>,
658
> = OnceLock::new();