1
//! SVG Elements.
2

            
3
use markup5ever::{expanded_name, local_name, 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::layout::Layer;
38
use crate::marker::Marker;
39
use crate::node::*;
40
use crate::pattern::Pattern;
41
use crate::properties::{ComputedValues, SpecifiedValues};
42
use crate::rsvg_log;
43
use crate::session::Session;
44
use crate::shapes::{Circle, Ellipse, Line, Path, Polygon, Polyline, Rect};
45
use crate::structure::{ClipPath, Group, Link, Mask, NonRendering, Svg, Switch, Symbol, Use};
46
use crate::style::Style;
47
use crate::text::{TRef, TSpan, Text};
48
use crate::text2::Text2;
49
use crate::xml::Attributes;
50

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

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

            
77
    /// Create a layout object for the current element.
78
    ///
79
    /// This resolves property values, coordinates, lengths, etc. and produces a layout
80
    /// item for rendering.
81
    fn layout(
82
        &self,
83
        _node: &Node,
84
        _acquired_nodes: &mut AcquiredNodes<'_>,
85
        _cascaded: &CascadedValues<'_>,
86
        _viewport: &Viewport,
87
        _draw_ctx: &mut DrawingCtx,
88
        _clipping: bool,
89
    ) -> Result<Option<Layer>, InternalRenderingError> {
90
        Ok(None)
91
    }
92
}
93

            
94
/// Sets `dest` if `parse_result` is `Ok()`, otherwise just logs the error.
95
///
96
/// Implementations of the [`ElementTrait`] trait generally scan a list of attributes
97
/// for the ones they can handle, and parse their string values.  Per the SVG spec, an attribute
98
/// with an invalid value should be ignored, and it should fall back to the default value.
99
///
100
/// In librsvg, those default values are set in each element's implementation of the [`Default`] trait:
101
/// at element creation time, each element gets initialized to its `Default`, and then each attribute
102
/// gets parsed.  This function will set that attribute's value only if parsing was successful.
103
///
104
/// In case the `parse_result` is an error, this function will log an appropriate notice
105
/// via the [`Session`].
106
168223
pub fn set_attribute<T>(dest: &mut T, parse_result: Result<T, ElementError>, session: &Session) {
107
168223
    match parse_result {
108
168071
        Ok(v) => *dest = v,
109
152
        Err(e) => {
110
152
            // FIXME: this does not provide a clue of what was the problematic element.
111
152
            // We need tracking of the current parsing position to do that.
112
152
            rsvg_log!(session, "ignoring attribute with invalid value: {}", e);
113
        }
114
    }
115
168223
}
116

            
117
pub struct Element {
118
    element_name: QualName,
119
    attributes: Attributes,
120
    specified_values: SpecifiedValues,
121
    important_styles: HashSet<QualName>,
122
    values: ComputedValues,
123
    required_extensions: Option<RequiredExtensions>,
124
    required_features: Option<RequiredFeatures>,
125
    system_language: Option<SystemLanguage>,
126
    pub element_data: ElementData,
127
}
128

            
129
impl fmt::Display for Element {
130
38149160
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131
38149160
        write!(f, "{}", self.element_name().local)?;
132
38149160
        write!(f, " id={}", self.get_id().unwrap_or("None"))?;
133
38149160
        Ok(())
134
38149160
    }
135
}
136

            
137
/// Parsed contents of an element node in the DOM.
138
///
139
/// This enum uses `Box<Foo>` in order to make each variant the size of
140
/// a pointer.
141
pub enum ElementData {
142
    Circle(Box<Circle>),
143
    ClipPath(Box<ClipPath>),
144
    Ellipse(Box<Ellipse>),
145
    Filter(Box<Filter>),
146
    Group(Box<Group>),
147
    Image(Box<Image>),
148
    Line(Box<Line>),
149
    LinearGradient(Box<LinearGradient>),
150
    Link(Box<Link>),
151
    Marker(Box<Marker>),
152
    Mask(Box<Mask>),
153
    NonRendering(Box<NonRendering>),
154
    Path(Box<Path>),
155
    Pattern(Box<Pattern>),
156
    Polygon(Box<Polygon>),
157
    Polyline(Box<Polyline>),
158
    RadialGradient(Box<RadialGradient>),
159
    Rect(Box<Rect>),
160
    Stop(Box<Stop>),
161
    Style(Box<Style>),
162
    Svg(Box<Svg>),
163
    Switch(Box<Switch>),
164
    Symbol(Box<Symbol>),
165
    Text(Box<Text>),
166
    Text2(Box<Text2>),
167
    TRef(Box<TRef>),
168
    TSpan(Box<TSpan>),
169
    Use(Box<Use>),
170

            
171
    // Filter primitives, these start with "Fe" as element names are e.g. "feBlend"
172
    FeBlend(Box<FeBlend>),
173
    FeColorMatrix(Box<FeColorMatrix>),
174
    FeComponentTransfer(Box<FeComponentTransfer>),
175
    FeComposite(Box<FeComposite>),
176
    FeConvolveMatrix(Box<FeConvolveMatrix>),
177
    FeDiffuseLighting(Box<FeDiffuseLighting>),
178
    FeDisplacementMap(Box<FeDisplacementMap>),
179
    FeDistantLight(Box<FeDistantLight>),
180
    FeDropShadow(Box<FeDropShadow>),
181
    FeFlood(Box<FeFlood>),
182
    FeFuncA(Box<FeFuncA>),
183
    FeFuncB(Box<FeFuncB>),
184
    FeFuncG(Box<FeFuncG>),
185
    FeFuncR(Box<FeFuncR>),
186
    FeGaussianBlur(Box<FeGaussianBlur>),
187
    FeImage(Box<FeImage>),
188
    FeMerge(Box<FeMerge>),
189
    FeMergeNode(Box<FeMergeNode>),
190
    FeMorphology(Box<FeMorphology>),
191
    FeOffset(Box<FeOffset>),
192
    FePointLight(Box<FePointLight>),
193
    FeSpecularLighting(Box<FeSpecularLighting>),
194
    FeSpotLight(Box<FeSpotLight>),
195
    FeTile(Box<FeTile>),
196
    FeTurbulence(Box<FeTurbulence>),
197
}
198

            
199
#[rustfmt::skip]
200
19365133
fn get_element_creators() -> &'static HashMap<&'static str, (ElementDataCreateFn, ElementCreateFlags)> {
201
    use ElementCreateFlags::*;
202

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

            
294
108809
        creators_table.into_iter().map(|(n, c, f)| (n, (c, f))).collect()
295
19365133
    })
296
19365133
}
297

            
298
impl Element {
299
    /// Takes an XML element name and consumes a list of attribute/value pairs to create an [`Element`].
300
    ///
301
    /// This operation does not fail.  Unknown element names simply produce a [`NonRendering`]
302
    /// element.
303
19460494
    pub fn new(session: &Session, name: &QualName, mut attributes: Attributes) -> Element {
304
19460494
        let (create_fn, flags): (ElementDataCreateFn, ElementCreateFlags) = if name.ns == ns!(svg) {
305
19365133
            match get_element_creators().get(name.local.as_ref()) {
306
                // hack in the SVG namespace for supported element names
307
19332396
                Some(&(create_fn, flags)) => (create_fn, flags),
308

            
309
                // Whenever we encounter a element name we don't understand, represent it as a
310
                // non-rendering element.  This is like a group, but it doesn't do any rendering
311
                // of children.  The effect is that we will ignore all children of unknown elements.
312
32737
                None => (create_non_rendering, ElementCreateFlags::Default),
313
            }
314
        } else {
315
95361
            (create_non_rendering, ElementCreateFlags::Default)
316
        };
317

            
318
19460494
        if flags == ElementCreateFlags::IgnoreClass {
319
3602
            attributes.clear_class();
320
19456892
        };
321

            
322
19460494
        let element_data = create_fn(session, &attributes);
323
19460494

            
324
19460494
        let mut e = Self {
325
19460494
            element_name: name.clone(),
326
19460494
            attributes,
327
19460494
            specified_values: Default::default(),
328
19460494
            important_styles: Default::default(),
329
19460494
            values: Default::default(),
330
19460494
            required_extensions: Default::default(),
331
19460494
            required_features: Default::default(),
332
19460494
            system_language: Default::default(),
333
19460494
            element_data,
334
19460494
        };
335
19460494

            
336
19460494
        e.set_conditional_processing_attributes(session);
337
19460494
        e.set_presentation_attributes(session);
338
19460494

            
339
19460494
        e
340
19460494
    }
341

            
342
53883883
    pub fn element_name(&self) -> &QualName {
343
53883883
        &self.element_name
344
53883883
    }
345

            
346
8664
    pub fn get_attributes(&self) -> &Attributes {
347
8664
        &self.attributes
348
8664
    }
349

            
350
57628713
    pub fn get_id(&self) -> Option<&str> {
351
57628713
        self.attributes.get_id()
352
57628713
    }
353

            
354
17483
    pub fn get_class(&self) -> Option<&str> {
355
17483
        self.attributes.get_class()
356
17483
    }
357

            
358
458363
    pub fn inherit_xml_lang(&mut self, parent: Option<Node>) {
359
458363
        self.specified_values
360
458363
            .inherit_xml_lang(&mut self.values, parent);
361
458363
    }
362

            
363
27920564
    pub fn get_specified_values(&self) -> &SpecifiedValues {
364
27920564
        &self.specified_values
365
27920564
    }
366

            
367
21017400
    pub fn get_computed_values(&self) -> &ComputedValues {
368
21017400
        &self.values
369
21017400
    }
370

            
371
458363
    pub fn set_computed_values(&mut self, values: &ComputedValues) {
372
458363
        self.values = values.clone();
373
458363
    }
374

            
375
361
    pub fn get_cond(&self, user_language: &UserLanguage) -> bool {
376
361
        self.required_extensions
377
361
            .as_ref()
378
361
            .map(|v| v.eval())
379
361
            .unwrap_or(true)
380
342
            && self
381
342
                .required_features
382
342
                .as_ref()
383
342
                .map(|v| v.eval())
384
342
                .unwrap_or(true)
385
323
            && self
386
323
                .system_language
387
323
                .as_ref()
388
323
                .map(|v| v.eval(user_language))
389
323
                .unwrap_or(true)
390
361
    }
391

            
392
19460494
    fn set_conditional_processing_attributes(&mut self, session: &Session) {
393
19460547
        for (attr, value) in self.attributes.iter() {
394
1707289
            match attr.expanded() {
395
19
                expanded_name!("", "requiredExtensions") => {
396
19
                    self.required_extensions = Some(RequiredExtensions::from_attribute(value));
397
19
                }
398

            
399
38
                expanded_name!("", "requiredFeatures") => {
400
38
                    self.required_features = Some(RequiredFeatures::from_attribute(value));
401
38
                }
402

            
403
247
                expanded_name!("", "systemLanguage") => {
404
247
                    self.system_language = Some(SystemLanguage::from_attribute(value, session));
405
247
                }
406

            
407
1706985
                _ => {}
408
            }
409
        }
410
19460494
    }
411

            
412
    /// Hands the `attrs` to the node's state, to apply the presentation attributes.
413
19460494
    fn set_presentation_attributes(&mut self, session: &Session) {
414
19460494
        self.specified_values
415
19460494
            .parse_presentation_attributes(session, &self.attributes);
416
19460494
    }
417

            
418
    // Applies a style declaration to the node's specified_values
419
67488
    pub fn apply_style_declaration(&mut self, declaration: &Declaration, origin: Origin) {
420
67488
        self.specified_values.set_property_from_declaration(
421
67488
            declaration,
422
67488
            origin,
423
67488
            &mut self.important_styles,
424
67488
        );
425
67488
    }
426

            
427
    /// Applies CSS styles from the "style" attribute
428
458363
    pub fn set_style_attribute(&mut self, session: &Session) {
429
458363
        let style = self
430
458363
            .attributes
431
458363
            .iter()
432
1599996
            .find(|(attr, _)| attr.expanded() == expanded_name!("", "style"))
433
458363
            .map(|(_, value)| value);
434

            
435
458363
        if let Some(style) = style {
436
96273
            self.specified_values.parse_style_declarations(
437
96273
                style,
438
96273
                Origin::Author,
439
96273
                &mut self.important_styles,
440
96273
                session,
441
96273
            );
442
362090
        }
443
458363
    }
444

            
445
    #[rustfmt::skip]
446
15592
    pub fn as_filter_effect(&self) -> Option<&dyn FilterEffect> {
447
        use ElementData::*;
448

            
449
15592
        match &self.element_data {
450
306
            FeBlend(fe) =>              Some(&**fe),
451
532
            FeColorMatrix(fe) =>        Some(&**fe),
452
532
            FeComponentTransfer(fe) =>  Some(&**fe),
453
1444
            FeComposite(fe) =>          Some(&**fe),
454
1216
            FeConvolveMatrix(fe) =>     Some(&**fe),
455
1824
            FeDiffuseLighting(fe) =>    Some(&**fe),
456
78
            FeDisplacementMap(fe) =>    Some(&**fe),
457
38
            FeDropShadow(fe) =>         Some(&**fe),
458
1216
            FeFlood(fe) =>              Some(&**fe),
459
1564
            FeGaussianBlur(fe) =>       Some(&**fe),
460
2584
            FeImage(fe) =>              Some(&**fe),
461
800
            FeMerge(fe) =>              Some(&**fe),
462
190
            FeMorphology(fe) =>         Some(&**fe),
463
874
            FeOffset(fe) =>             Some(&**fe),
464
1482
            FeSpecularLighting(fe) =>   Some(&**fe),
465
76
            FeTile(fe) =>               Some(&**fe),
466
760
            FeTurbulence(fe) =>         Some(&**fe),
467
76
            _ => None,
468
        }
469
15592
    }
470

            
471
    /// Returns whether an element of a particular type is only accessed by reference
472
    // from other elements' attributes.  The element could in turn cause other nodes
473
    // to get referenced, potentially causing reference cycles.
474
19019592
    pub fn is_accessed_by_reference(&self) -> bool {
475
        use ElementData::*;
476

            
477
9504807
        matches!(
478
19019592
            self.element_data,
479
            ClipPath(_)
480
                | Filter(_)
481
                | LinearGradient(_)
482
                | Marker(_)
483
                | Mask(_)
484
                | Pattern(_)
485
                | RadialGradient(_)
486
        )
487
19019592
    }
488

            
489
    /// The main drawing function for elements.
490
37242451
    pub fn draw(
491
37242451
        &self,
492
37242451
        node: &Node,
493
37242451
        acquired_nodes: &mut AcquiredNodes<'_>,
494
37242451
        cascaded: &CascadedValues<'_>,
495
37242451
        viewport: &Viewport,
496
37242451
        draw_ctx: &mut DrawingCtx,
497
37242451
        clipping: bool,
498
37242451
    ) -> Result<BoundingBox, InternalRenderingError> {
499
37242451
        let values = cascaded.get();
500
37242451
        if values.is_displayed() {
501
37202380
            self.element_data
502
37202380
                .draw(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
503
        } else {
504
40071
            Ok(viewport.empty_bbox())
505
        }
506
37242451
    }
507

            
508
    /// The main layout function for elements.
509
4
    pub fn layout(
510
4
        &self,
511
4
        node: &Node,
512
4
        acquired_nodes: &mut AcquiredNodes<'_>,
513
4
        cascaded: &CascadedValues<'_>,
514
4
        viewport: &Viewport,
515
4
        draw_ctx: &mut DrawingCtx,
516
4
        clipping: bool,
517
4
    ) -> Result<Option<Layer>, InternalRenderingError> {
518
4
        let values = cascaded.get();
519
4
        if values.is_displayed() {
520
4
            self.element_data
521
4
                .layout(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
522
        } else {
523
            Ok(None)
524
        }
525
4
    }
526
}
527

            
528
impl ElementData {
529
    /// Dispatcher for the draw method of concrete element implementations.
530
    #[rustfmt::skip]
531
37202380
    fn draw(
532
37202380
        &self,
533
37202380
        node: &Node,
534
37202380
        acquired_nodes: &mut AcquiredNodes<'_>,
535
37202380
        cascaded: &CascadedValues<'_>,
536
37202380
        viewport: &Viewport,
537
37202380
        draw_ctx: &mut DrawingCtx,
538
37202380
        clipping: bool,
539
37202380
    ) -> Result<BoundingBox, InternalRenderingError> {
540
        use ElementData::*;
541

            
542
37202380
        let data: &dyn ElementTrait = match self {
543
4826
            Circle(d) =>               &**d,
544
            ClipPath(d) =>             &**d,
545
399
            Ellipse(d) =>              &**d,
546
665
            Filter(d) =>               &**d,
547
9611359
            Group(d) =>                &**d,
548
2109
            Image(d) =>                &**d,
549
2508
            Line(d) =>                 &**d,
550
            LinearGradient(d) =>       &**d,
551
57
            Link(d) =>                 &**d,
552
            Marker(d) =>               &**d,
553
            Mask(d) =>                 &**d,
554
12312
            NonRendering(d) =>         &**d,
555
30818
            Path(d) =>                 &**d,
556
            Pattern(d) =>              &**d,
557
646
            Polygon(d) =>              &**d,
558
779
            Polyline(d) =>             &**d,
559
            RadialGradient(d) =>       &**d,
560
17989219
            Rect(d) =>                 &**d,
561
            Stop(d) =>                 &**d,
562
            Style(d) =>                &**d,
563
21641
            Svg(d) =>                  &**d,
564
190
            Switch(d) =>               &**d,
565
            Symbol(d) =>               &**d,
566
17556
            Text(d) =>                 &**d,
567
            Text2(d) =>                 &**d,
568
            TRef(d) =>                 &**d,
569
            TSpan(d) =>                &**d,
570
9507296
            Use(d) =>                  &**d,
571

            
572
            FeBlend(d) =>              &**d,
573
            FeColorMatrix(d) =>        &**d,
574
            FeComponentTransfer(d) =>  &**d,
575
            FeComposite(d) =>          &**d,
576
            FeConvolveMatrix(d) =>     &**d,
577
            FeDiffuseLighting(d) =>    &**d,
578
            FeDisplacementMap(d) =>    &**d,
579
            FeDistantLight(d) =>       &**d,
580
            FeDropShadow(d) =>         &**d,
581
            FeFlood(d) =>              &**d,
582
            FeFuncA(d) =>              &**d,
583
            FeFuncB(d) =>              &**d,
584
            FeFuncG(d) =>              &**d,
585
            FeFuncR(d) =>              &**d,
586
            FeGaussianBlur(d) =>       &**d,
587
            FeImage(d) =>              &**d,
588
            FeMerge(d) =>              &**d,
589
            FeMergeNode(d) =>          &**d,
590
            FeMorphology(d) =>         &**d,
591
            FeOffset(d) =>             &**d,
592
            FePointLight(d) =>         &**d,
593
            FeSpecularLighting(d) =>   &**d,
594
            FeSpotLight(d) =>          &**d,
595
            FeTile(d) =>               &**d,
596
            FeTurbulence(d) =>         &**d,
597
        };
598

            
599
37202380
        data.draw(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
600
37202380
    }
601

            
602
    /// Dispatcher for the layout method of concrete element implementations.
603
    #[rustfmt::skip]
604
4
    fn layout(
605
4
        &self,
606
4
        node: &Node,
607
4
        acquired_nodes: &mut AcquiredNodes<'_>,
608
4
        cascaded: &CascadedValues<'_>,
609
4
        viewport: &Viewport,
610
4
        draw_ctx: &mut DrawingCtx,
611
4
        clipping: bool,
612
4
    ) -> Result<Option<Layer>, InternalRenderingError> {
613
        use ElementData::*;
614

            
615
4
        let data: &dyn ElementTrait = match self {
616
            Circle(d) =>               &**d,
617
            ClipPath(d) =>             &**d,
618
            Ellipse(d) =>              &**d,
619
            Filter(d) =>               &**d,
620
2
            Group(d) =>                &**d,
621
            Image(d) =>                &**d,
622
            Line(d) =>                 &**d,
623
            LinearGradient(d) =>       &**d,
624
            Link(d) =>                 &**d,
625
            Marker(d) =>               &**d,
626
            Mask(d) =>                 &**d,
627
            NonRendering(d) =>         &**d,
628
            Path(d) =>                 &**d,
629
            Pattern(d) =>              &**d,
630
            Polygon(d) =>              &**d,
631
            Polyline(d) =>             &**d,
632
            RadialGradient(d) =>       &**d,
633
2
            Rect(d) =>                 &**d,
634
            Stop(d) =>                 &**d,
635
            Style(d) =>                &**d,
636
            Svg(d) =>                  &**d,
637
            Switch(d) =>               &**d,
638
            Symbol(d) =>               &**d,
639
            Text(d) =>                 &**d,
640
            Text2(d) =>                 &**d,
641
            TRef(d) =>                 &**d,
642
            TSpan(d) =>                &**d,
643
            Use(d) =>                  &**d,
644

            
645
            FeBlend(d) =>              &**d,
646
            FeColorMatrix(d) =>        &**d,
647
            FeComponentTransfer(d) =>  &**d,
648
            FeComposite(d) =>          &**d,
649
            FeConvolveMatrix(d) =>     &**d,
650
            FeDiffuseLighting(d) =>    &**d,
651
            FeDisplacementMap(d) =>    &**d,
652
            FeDistantLight(d) =>       &**d,
653
            FeDropShadow(d) =>         &**d,
654
            FeFlood(d) =>              &**d,
655
            FeFuncA(d) =>              &**d,
656
            FeFuncB(d) =>              &**d,
657
            FeFuncG(d) =>              &**d,
658
            FeFuncR(d) =>              &**d,
659
            FeGaussianBlur(d) =>       &**d,
660
            FeImage(d) =>              &**d,
661
            FeMerge(d) =>              &**d,
662
            FeMergeNode(d) =>          &**d,
663
            FeMorphology(d) =>         &**d,
664
            FeOffset(d) =>             &**d,
665
            FePointLight(d) =>         &**d,
666
            FeSpecularLighting(d) =>   &**d,
667
            FeSpotLight(d) =>          &**d,
668
            FeTile(d) =>               &**d,
669
            FeTurbulence(d) =>         &**d,
670
        };
671

            
672
4
        data.layout(node, acquired_nodes, cascaded, viewport, draw_ctx, clipping)
673
4
    }
674
}
675

            
676
macro_rules! e {
677
    ($name:ident, $element_type:ident) => {
678
19460494
        pub fn $name(session: &Session, attributes: &Attributes) -> ElementData {
679
19460494
            let mut payload = Box::<$element_type>::default();
680
19460494
            payload.set_attributes(attributes, session);
681
19460494

            
682
19460494
            ElementData::$element_type(payload)
683
19460494
        }
684
    };
685
}
686

            
687
#[rustfmt::skip]
688
mod creators {
689
    use super::*;
690

            
691
    e!(create_circle,                   Circle);
692
    e!(create_clip_path,                ClipPath);
693
    e!(create_defs,                     NonRendering);
694
    e!(create_ellipse,                  Ellipse);
695
    e!(create_fe_blend,                 FeBlend);
696
    e!(create_fe_color_matrix,          FeColorMatrix);
697
    e!(create_fe_component_transfer,    FeComponentTransfer);
698
    e!(create_fe_func_a,                FeFuncA);
699
    e!(create_fe_func_b,                FeFuncB);
700
    e!(create_fe_func_g,                FeFuncG);
701
    e!(create_fe_func_r,                FeFuncR);
702
    e!(create_fe_composite,             FeComposite);
703
    e!(create_fe_convolve_matrix,       FeConvolveMatrix);
704
    e!(create_fe_diffuse_lighting,      FeDiffuseLighting);
705
    e!(create_fe_displacement_map,      FeDisplacementMap);
706
    e!(create_fe_distant_light,         FeDistantLight);
707
    e!(create_fe_drop_shadow,           FeDropShadow);
708
    e!(create_fe_flood,                 FeFlood);
709
    e!(create_fe_gaussian_blur,         FeGaussianBlur);
710
    e!(create_fe_image,                 FeImage);
711
    e!(create_fe_merge,                 FeMerge);
712
    e!(create_fe_merge_node,            FeMergeNode);
713
    e!(create_fe_morphology,            FeMorphology);
714
    e!(create_fe_offset,                FeOffset);
715
    e!(create_fe_point_light,           FePointLight);
716
    e!(create_fe_specular_lighting,     FeSpecularLighting);
717
    e!(create_fe_spot_light,            FeSpotLight);
718
    e!(create_fe_tile,                  FeTile);
719
    e!(create_fe_turbulence,            FeTurbulence);
720
    e!(create_filter,                   Filter);
721
    e!(create_group,                    Group);
722
    e!(create_image,                    Image);
723
    e!(create_line,                     Line);
724
    e!(create_linear_gradient,          LinearGradient);
725
    e!(create_link,                     Link);
726
    e!(create_marker,                   Marker);
727
    e!(create_mask,                     Mask);
728
    e!(create_non_rendering,            NonRendering);
729
    e!(create_path,                     Path);
730
    e!(create_pattern,                  Pattern);
731
    e!(create_polygon,                  Polygon);
732
    e!(create_polyline,                 Polyline);
733
    e!(create_radial_gradient,          RadialGradient);
734
    e!(create_rect,                     Rect);
735
    e!(create_stop,                     Stop);
736
    e!(create_style,                    Style);
737
    e!(create_svg,                      Svg);
738
    e!(create_switch,                   Switch);
739
    e!(create_symbol,                   Symbol);
740
    e!(create_text,                     Text);
741
    e!(create_text2,                    Text2);
742
    e!(create_tref,                     TRef);
743
    e!(create_tspan,                    TSpan);
744
    e!(create_use,                      Use);
745

            
746
    /* Hack to make multiImage sort-of work
747
     *
748
     * disabled for now, as markup5ever doesn't have local names for
749
     * multiImage, subImage, subImageRef.  Maybe we can just... create them ourselves?
750
     *
751
     * Is multiImage even in SVG2?
752
     */
753
    /*
754
    e!(create_multi_image,              Switch);
755
    e!(create_sub_image,                Group);
756
    e!(create_sub_image_ref,            Image);
757
    */
758
}
759

            
760
use creators::*;
761

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

            
764
#[derive(Copy, Clone, PartialEq)]
765
enum ElementCreateFlags {
766
    Default,
767
    IgnoreClass,
768
}
769

            
770
static ELEMENT_CREATORS: OnceLock<
771
    HashMap<&'static str, (ElementDataCreateFn, ElementCreateFlags)>,
772
> = OnceLock::new();